History

[PATCH] fix scaled & unscaled cputime accounting

The utimescaled / stimescaled fields in the task structure and the global cpustat should be set on all architectures. On s390 the calls to account_user_time_scaled and account_system_time_scaled never have been added. In addition system time that is accounted as guest time to the user time of a process is accounted to the scaled system time instead of the scaled user time. To fix the bugs and to prevent future forgetfulness this patch merges account_system_time_scaled into account_system_time and account_user_time_scaled into account_user_time.

Martin Schwidefsky committed 17 years ago

Commit 457533a1 parent 6a94cb77 files · +37 −56Browse files

Unified · Split

7 files
  1. arch/ia64/kernel/time.c +4 −8
  2. arch/powerpc/kernel/time.c +2 −5
  3. arch/s390/kernel/vtime.c +5 −5
  4. include/linux/kernel_stat.h +2 −4
  5. kernel/sched.c +16 −25
  6. kernel/time/tick-sched.c +3 −2
  7. kernel/timer.c +5 −7
arch/ia64/kernel/time.c+4−8
@@ -93,13 +93,11 @@ void ia64_account_on_switch(struct task_struct *prev, struct task_struct *next) · 92 unmodified lines
9393 now = ia64_get_itc();
9494
9595 delta_stime = cycle_to_cputime(pi->ac_stime + (now - pi->ac_stamp));
96− account_system_time(prev, 0, delta_stime);
97− account_system_time_scaled(prev, delta_stime);
96+ account_system_time(prev, 0, delta_stime, delta_stime);
9897
9998 if (pi->ac_utime) {
10099 delta_utime = cycle_to_cputime(pi->ac_utime);
101− account_user_time(prev, delta_utime);
102− account_user_time_scaled(prev, delta_utime);
100+ account_user_time(prev, delta_utime, delta_utime);
103101 }
104102
105103 pi->ac_stamp = ni->ac_stamp = now;
@@ -122,8 +120,7 @@ void account_system_vtime(struct task_struct *tsk) · 16 unmodified lines
122120 now = ia64_get_itc();
123121
124122 delta_stime = cycle_to_cputime(ti->ac_stime + (now - ti->ac_stamp));
125− account_system_time(tsk, 0, delta_stime);
126− account_system_time_scaled(tsk, delta_stime);
123+ account_system_time(tsk, 0, delta_stime, delta_stime);
127124 ti->ac_stime = 0;
128125
129126 ti->ac_stamp = now;
@@ -143,8 +140,7 @@ void account_process_tick(struct task_struct *p, int user_tick) · 13 unmodified lines
143140
144141 if (ti->ac_utime) {
145142 delta_utime = cycle_to_cputime(ti->ac_utime);
146− account_user_time(p, delta_utime);
147− account_user_time_scaled(p, delta_utime);
143+ account_user_time(p, delta_utime, delta_utime);
148144 ti->ac_utime = 0;
149145 }
150146 }
arch/powerpc/kernel/time.c+2−5
@@ -256,8 +256,7 @@ void account_system_vtime(struct task_struct *tsk) · 255 unmodified lines
256256 delta += sys_time;
257257 get_paca()->system_time = 0;
258258 }
259− account_system_time(tsk, 0, delta);
260− account_system_time_scaled(tsk, deltascaled);
259+ account_system_time(tsk, 0, delta, deltascaled);
261260 per_cpu(cputime_last_delta, smp_processor_id()) = delta;
262261 per_cpu(cputime_scaled_last_delta, smp_processor_id()) = deltascaled;
263262 local_irq_restore(flags);
@@ -275,10 +274,8 @@ void account_process_tick(struct task_struct *tsk, int user_tick) · 11 unmodified lines
275274
276275 utime = get_paca()->user_time;
277276 get_paca()->user_time = 0;
278− account_user_time(tsk, utime);
279−
280277 utimescaled = cputime_to_scaled(utime);
281− account_user_time_scaled(tsk, utimescaled);
278+ account_user_time(tsk, utime, utimescaled);
282279 }
283280
284281 /*
arch/s390/kernel/vtime.c+5−5
@@ -50,12 +50,12 @@ void account_process_tick(struct task_struct *tsk, int user_tick) · 49 unmodified lines
5050 rcu_user_flag = cputime != 0;
5151 S390_lowcore.user_timer -= cputime << 12;
5252 S390_lowcore.steal_clock -= cputime << 12;
53− account_user_time(tsk, cputime);
53+ account_user_time(tsk, cputime, cputime);
5454
5555 cputime = S390_lowcore.system_timer >> 12;
5656 S390_lowcore.system_timer -= cputime << 12;
5757 S390_lowcore.steal_clock -= cputime << 12;
58− account_system_time(tsk, HARDIRQ_OFFSET, cputime);
58+ account_system_time(tsk, HARDIRQ_OFFSET, cputime, cputime);
5959
6060 cputime = S390_lowcore.steal_clock;
6161 if ((__s64) cputime > 0) {
@@ -82,12 +82,12 @@ void account_vtime(struct task_struct *tsk) · 20 unmodified lines
8282 cputime = S390_lowcore.user_timer >> 12;
8383 S390_lowcore.user_timer -= cputime << 12;
8484 S390_lowcore.steal_clock -= cputime << 12;
85− account_user_time(tsk, cputime);
85+ account_user_time(tsk, cputime, cputime);
8686
8787 cputime = S390_lowcore.system_timer >> 12;
8888 S390_lowcore.system_timer -= cputime << 12;
8989 S390_lowcore.steal_clock -= cputime << 12;
90− account_system_time(tsk, 0, cputime);
90+ account_system_time(tsk, 0, cputime, cputime);
9191 }
9292
9393 /*
@@ -107,7 +107,7 @@ void account_system_vtime(struct task_struct *tsk) · 13 unmodified lines
107107 cputime = S390_lowcore.system_timer >> 12;
108108 S390_lowcore.system_timer -= cputime << 12;
109109 S390_lowcore.steal_clock -= cputime << 12;
110− account_system_time(tsk, 0, cputime);
110+ account_system_time(tsk, 0, cputime, cputime);
111111 }
112112 EXPORT_SYMBOL_GPL(account_system_vtime);
113113
include/linux/kernel_stat.h+2−4
@@ -79,10 +79,8 @@ static inline unsigned int kstat_irqs(unsigned int irq) · 78 unmodified lines
7979 }
8080
8181 extern unsigned long long task_delta_exec(struct task_struct *);
82−extern void account_user_time(struct task_struct *, cputime_t);
83−extern void account_user_time_scaled(struct task_struct *, cputime_t);
84−extern void account_system_time(struct task_struct *, int, cputime_t);
85−extern void account_system_time_scaled(struct task_struct *, cputime_t);
82+extern void account_user_time(struct task_struct *, cputime_t, cputime_t);
83+extern void account_system_time(struct task_struct *, int, cputime_t, cputime_t);
8684 extern void account_steal_time(struct task_struct *, cputime_t);
8785
8886 #endif /* _LINUX_KERNEL_STAT_H */
kernel/sched.c+16−25
@@ -4080,13 +4080,17 @@ unsigned long long task_delta_exec(struct task_struct *p) · 4079 unmodified lines
40804080 * Account user cpu time to a process.
40814081 * @p: the process that the cpu time gets accounted to
40824082 * @cputime: the cpu time spent in user space since the last update
4083+ * @cputime_scaled: cputime scaled by cpu frequency
40834084 */
4084−void account_user_time(struct task_struct *p, cputime_t cputime)
4085+void account_user_time(struct task_struct *p, cputime_t cputime,
4086+ cputime_t cputime_scaled)
40854087 {
40864088 struct cpu_usage_stat *cpustat = &kstat_this_cpu.cpustat;
40874089 cputime64_t tmp;
40884090
4091+ /* Add user time to process. */
40894092 p->utime = cputime_add(p->utime, cputime);
4093+ p->utimescaled = cputime_add(p->utimescaled, cputime_scaled);
40904094 account_group_user_time(p, cputime);
40914095
40924096 /* Add user time to cpustat. */
@@ -4103,51 +4107,49 @@ void account_user_time(struct task_struct *p, cputime_t cputime) · 10 unmodified lines
41034107 * Account guest cpu time to a process.
41044108 * @p: the process that the cpu time gets accounted to
41054109 * @cputime: the cpu time spent in virtual machine since the last update
4110+ * @cputime_scaled: cputime scaled by cpu frequency
41064111 */
4107−static void account_guest_time(struct task_struct *p, cputime_t cputime)
4112+static void account_guest_time(struct task_struct *p, cputime_t cputime,
4113+ cputime_t cputime_scaled)
41084114 {
41094115 cputime64_t tmp;
41104116 struct cpu_usage_stat *cpustat = &kstat_this_cpu.cpustat;
41114117
41124118 tmp = cputime_to_cputime64(cputime);
41134119
4120+ /* Add guest time to process. */
41144121 p->utime = cputime_add(p->utime, cputime);
4122+ p->utimescaled = cputime_add(p->utimescaled, cputime_scaled);
41154123 account_group_user_time(p, cputime);
41164124 p->gtime = cputime_add(p->gtime, cputime);
41174125
4126+ /* Add guest time to cpustat. */
41184127 cpustat->user = cputime64_add(cpustat->user, tmp);
41194128 cpustat->guest = cputime64_add(cpustat->guest, tmp);
41204129 }
41214130
4122−/*
4123− * Account scaled user cpu time to a process.
4124− * @p: the process that the cpu time gets accounted to
4125− * @cputime: the cpu time spent in user space since the last update
4126− */
4127−void account_user_time_scaled(struct task_struct *p, cputime_t cputime)
4128−{
4129− p->utimescaled = cputime_add(p->utimescaled, cputime);
4130−}
4131−
41324131 /*
41334132 * Account system cpu time to a process.
41344133 * @p: the process that the cpu time gets accounted to
41354134 * @hardirq_offset: the offset to subtract from hardirq_count()
41364135 * @cputime: the cpu time spent in kernel space since the last update
4136+ * @cputime_scaled: cputime scaled by cpu frequency
41374137 */
41384138 void account_system_time(struct task_struct *p, int hardirq_offset,
4139− cputime_t cputime)
4139+ cputime_t cputime, cputime_t cputime_scaled)
41404140 {
41414141 struct cpu_usage_stat *cpustat = &kstat_this_cpu.cpustat;
41424142 struct rq *rq = this_rq();
41434143 cputime64_t tmp;
41444144
41454145 if ((p->flags & PF_VCPU) && (irq_count() - hardirq_offset == 0)) {
4146− account_guest_time(p, cputime);
4146+ account_guest_time(p, cputime, cputime_scaled);
41474147 return;
41484148 }
41494149
4150+ /* Add system time to process. */
41504151 p->stime = cputime_add(p->stime, cputime);
4152+ p->stimescaled = cputime_add(p->stimescaled, cputime_scaled);
41514153 account_group_system_time(p, cputime);
41524154
41534155 /* Add system time to cpustat. */
@@ -4166,17 +4168,6 @@ void account_system_time(struct task_struct *p, int hardirq_offset, · 12 unmodified lines
41664168 acct_update_integrals(p);
41674169 }
41684170
4169−/*
4170− * Account scaled system cpu time to a process.
4171− * @p: the process that the cpu time gets accounted to
4172− * @hardirq_offset: the offset to subtract from hardirq_count()
4173− * @cputime: the cpu time spent in kernel space since the last update
4174− */
4175−void account_system_time_scaled(struct task_struct *p, cputime_t cputime)
4176−{
4177− p->stimescaled = cputime_add(p->stimescaled, cputime);
4178−}
4179−
41804171 /*
41814172 * Account for involuntary wait time.
41824173 * @p: the process from which the cpu time has been stolen
kernel/time/tick-sched.c+3−2
@@ -420,6 +420,7 @@ void tick_nohz_restart_sched_tick(void) · 419 unmodified lines
420420 int cpu = smp_processor_id();
421421 struct tick_sched *ts = &per_cpu(tick_cpu_sched, cpu);
422422 unsigned long ticks;
423+ cputime_t cputime;
423424 ktime_t now;
424425
425426 local_irq_disable();
@@ -452,8 +453,8 @@ void tick_nohz_restart_sched_tick(void) · 26 unmodified lines
452453 */
453454 if (ticks && ticks < LONG_MAX) {
454455 add_preempt_count(HARDIRQ_OFFSET);
455− account_system_time(current, HARDIRQ_OFFSET,
456− jiffies_to_cputime(ticks));
456+ cputime = jiffies_to_cputime(ticks);
457+ account_system_time(current, HARDIRQ_OFFSET, cputime, cputime);
457458 sub_preempt_count(HARDIRQ_OFFSET);
458459 }
459460
kernel/timer.c+5−7
@@ -1023,13 +1023,11 @@ void account_process_tick(struct task_struct *p, int user_tick) · 1022 unmodified lines
10231023 {
10241024 cputime_t one_jiffy = jiffies_to_cputime(1);
10251025
1026− if (user_tick) {
1027− account_user_time(p, one_jiffy);
1028− account_user_time_scaled(p, cputime_to_scaled(one_jiffy));
1029− } else {
1030− account_system_time(p, HARDIRQ_OFFSET, one_jiffy);
1031− account_system_time_scaled(p, cputime_to_scaled(one_jiffy));
1032− }
1026+ if (user_tick)
1027+ account_user_time(p, one_jiffy, cputime_to_scaled(one_jiffy));
1028+ else
1029+ account_system_time(p, HARDIRQ_OFFSET, one_jiffy,
1030+ cputime_to_scaled(one_jiffy));
10331031 }
10341032 #endif
10351033