Commit 761b1d26df542fd5eb348837351e4d2f3bc7bffe

Authored by Hidetoshi Seto
Committed by Ingo Molnar
1 parent ffd44db5f0

sched: Fix granularity of task_u/stime()

Originally task_s/utime() were designed to return clock_t but
later changed to return cputime_t by following commit:

  commit efe567fc8281661524ffa75477a7c4ca9b466c63
  Author: Christian Borntraeger <borntraeger@de.ibm.com>
  Date:   Thu Aug 23 15:18:02 2007 +0200

It only changed the type of return value, but not the
implementation. As the result the granularity of task_s/utime()
is still that of clock_t, not that of cputime_t.

So using task_s/utime() in __exit_signal() makes values
accumulated to the signal struct to be rounded and coarse
grained.

This patch removes casts to clock_t in task_u/stime(), to keep
granularity of cputime_t over the calculation.

v2:
  Use div_u64() to avoid error "undefined reference to `__udivdi3`"
  on some 32bit systems.

Signed-off-by: Hidetoshi Seto <seto.hidetoshi@jp.fujitsu.com>
Acked-by: Peter Zijlstra <peterz@infradead.org>
Cc: xiyou.wangcong@gmail.com
Cc: Spencer Candland <spencer@bluehost.com>
Cc: Oleg Nesterov <oleg@redhat.com>
Cc: Stanislaw Gruszka <sgruszka@redhat.com>
LKML-Reference: <4AFB9029.9000208@jp.fujitsu.com>
Signed-off-by: Ingo Molnar <mingo@elte.hu>

Showing 1 changed file with 13 additions and 9 deletions Side-by-side Diff

... ... @@ -5156,41 +5156,45 @@
5156 5156 return p->stime;
5157 5157 }
5158 5158 #else
  5159 +
  5160 +#ifndef nsecs_to_cputime
  5161 +# define nsecs_to_cputime(__nsecs) \
  5162 + msecs_to_cputime(div_u64((__nsecs), NSEC_PER_MSEC))
  5163 +#endif
  5164 +
5159 5165 cputime_t task_utime(struct task_struct *p)
5160 5166 {
5161   - clock_t utime = cputime_to_clock_t(p->utime),
5162   - total = utime + cputime_to_clock_t(p->stime);
  5167 + cputime_t utime = p->utime, total = utime + p->stime;
5163 5168 u64 temp;
5164 5169  
5165 5170 /*
5166 5171 * Use CFS's precise accounting:
5167 5172 */
5168   - temp = (u64)nsec_to_clock_t(p->se.sum_exec_runtime);
  5173 + temp = (u64)nsecs_to_cputime(p->se.sum_exec_runtime);
5169 5174  
5170 5175 if (total) {
5171 5176 temp *= utime;
5172 5177 do_div(temp, total);
5173 5178 }
5174   - utime = (clock_t)temp;
  5179 + utime = (cputime_t)temp;
5175 5180  
5176   - p->prev_utime = max(p->prev_utime, clock_t_to_cputime(utime));
  5181 + p->prev_utime = max(p->prev_utime, utime);
5177 5182 return p->prev_utime;
5178 5183 }
5179 5184  
5180 5185 cputime_t task_stime(struct task_struct *p)
5181 5186 {
5182   - clock_t stime;
  5187 + cputime_t stime;
5183 5188  
5184 5189 /*
5185 5190 * Use CFS's precise accounting. (we subtract utime from
5186 5191 * the total, to make sure the total observed by userspace
5187 5192 * grows monotonically - apps rely on that):
5188 5193 */
5189   - stime = nsec_to_clock_t(p->se.sum_exec_runtime) -
5190   - cputime_to_clock_t(task_utime(p));
  5194 + stime = nsecs_to_cputime(p->se.sum_exec_runtime) - task_utime(p);
5191 5195  
5192 5196 if (stime >= 0)
5193   - p->prev_stime = max(p->prev_stime, clock_t_to_cputime(stime));
  5197 + p->prev_stime = max(p->prev_stime, stime);
5194 5198  
5195 5199 return p->prev_stime;
5196 5200 }