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
93 now = ia64_get_itc();93 now = ia64_get_itc();
94 94
95 delta_stime = cycle_to_cputime(pi->ac_stime + (now - pi->ac_stamp));95 delta_stime = cycle_to_cputime(pi->ac_stime + (now - pi->ac_stamp));
96 account_system_time(prev, 0, delta_stime);96 account_system_time(prev, 0, delta_stime, delta_stime);
97 account_system_time_scaled(prev, delta_stime);
98 97
99 if (pi->ac_utime) {98 if (pi->ac_utime) {
100 delta_utime = cycle_to_cputime(pi->ac_utime);99 delta_utime = cycle_to_cputime(pi->ac_utime);
101 account_user_time(prev, delta_utime);100 account_user_time(prev, delta_utime, delta_utime);
102 account_user_time_scaled(prev, delta_utime);
103 }101 }
104 102
105 pi->ac_stamp = ni->ac_stamp = now;103 pi->ac_stamp = ni->ac_stamp = now;
@@ -122,8 +120,7 @@ void account_system_vtime(struct task_struct *tsk) · 16 unmodified lines
122 now = ia64_get_itc();120 now = ia64_get_itc();
123 121
124 delta_stime = cycle_to_cputime(ti->ac_stime + (now - ti->ac_stamp));122 delta_stime = cycle_to_cputime(ti->ac_stime + (now - ti->ac_stamp));
125 account_system_time(tsk, 0, delta_stime);123 account_system_time(tsk, 0, delta_stime, delta_stime);
126 account_system_time_scaled(tsk, delta_stime);
127 ti->ac_stime = 0;124 ti->ac_stime = 0;
128 125
129 ti->ac_stamp = now;126 ti->ac_stamp = now;
@@ -143,8 +140,7 @@ void account_process_tick(struct task_struct *p, int user_tick) · 13 unmodified lines
143 140
144 if (ti->ac_utime) {141 if (ti->ac_utime) {
145 delta_utime = cycle_to_cputime(ti->ac_utime);142 delta_utime = cycle_to_cputime(ti->ac_utime);
146 account_user_time(p, delta_utime);143 account_user_time(p, delta_utime, delta_utime);
147 account_user_time_scaled(p, delta_utime);
148 ti->ac_utime = 0;144 ti->ac_utime = 0;
149 }145 }
150}146}
arch/powerpc/kernel/time.c+2−5
@@ -256,8 +256,7 @@ void account_system_vtime(struct task_struct *tsk) · 255 unmodified lines
256 delta += sys_time;256 delta += sys_time;
257 get_paca()->system_time = 0;257 get_paca()->system_time = 0;
258 }258 }
259 account_system_time(tsk, 0, delta);259 account_system_time(tsk, 0, delta, deltascaled);
260 account_system_time_scaled(tsk, deltascaled);
261 per_cpu(cputime_last_delta, smp_processor_id()) = delta;260 per_cpu(cputime_last_delta, smp_processor_id()) = delta;
262 per_cpu(cputime_scaled_last_delta, smp_processor_id()) = deltascaled;261 per_cpu(cputime_scaled_last_delta, smp_processor_id()) = deltascaled;
263 local_irq_restore(flags);262 local_irq_restore(flags);
@@ -275,10 +274,8 @@ void account_process_tick(struct task_struct *tsk, int user_tick) · 11 unmodified lines
275 274
276 utime = get_paca()->user_time;275 utime = get_paca()->user_time;
277 get_paca()->user_time = 0;276 get_paca()->user_time = 0;
278 account_user_time(tsk, utime);
279
280 utimescaled = cputime_to_scaled(utime);277 utimescaled = cputime_to_scaled(utime);
281 account_user_time_scaled(tsk, utimescaled);278 account_user_time(tsk, utime, utimescaled);
282}279}
283 280
284/*281/*
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
50 rcu_user_flag = cputime != 0;50 rcu_user_flag = cputime != 0;
51 S390_lowcore.user_timer -= cputime << 12;51 S390_lowcore.user_timer -= cputime << 12;
52 S390_lowcore.steal_clock -= cputime << 12;52 S390_lowcore.steal_clock -= cputime << 12;
53 account_user_time(tsk, cputime);53 account_user_time(tsk, cputime, cputime);
54 54
55 cputime = S390_lowcore.system_timer >> 12;55 cputime = S390_lowcore.system_timer >> 12;
56 S390_lowcore.system_timer -= cputime << 12;56 S390_lowcore.system_timer -= cputime << 12;
57 S390_lowcore.steal_clock -= cputime << 12;57 S390_lowcore.steal_clock -= cputime << 12;
58 account_system_time(tsk, HARDIRQ_OFFSET, cputime);58 account_system_time(tsk, HARDIRQ_OFFSET, cputime, cputime);
59 59
60 cputime = S390_lowcore.steal_clock;60 cputime = S390_lowcore.steal_clock;
61 if ((__s64) cputime > 0) {61 if ((__s64) cputime > 0) {
@@ -82,12 +82,12 @@ void account_vtime(struct task_struct *tsk) · 20 unmodified lines
82 cputime = S390_lowcore.user_timer >> 12;82 cputime = S390_lowcore.user_timer >> 12;
83 S390_lowcore.user_timer -= cputime << 12;83 S390_lowcore.user_timer -= cputime << 12;
84 S390_lowcore.steal_clock -= cputime << 12;84 S390_lowcore.steal_clock -= cputime << 12;
85 account_user_time(tsk, cputime);85 account_user_time(tsk, cputime, cputime);
86 86
87 cputime = S390_lowcore.system_timer >> 12;87 cputime = S390_lowcore.system_timer >> 12;
88 S390_lowcore.system_timer -= cputime << 12;88 S390_lowcore.system_timer -= cputime << 12;
89 S390_lowcore.steal_clock -= cputime << 12;89 S390_lowcore.steal_clock -= cputime << 12;
90 account_system_time(tsk, 0, cputime);90 account_system_time(tsk, 0, cputime, cputime);
91}91}
92 92
93/*93/*
@@ -107,7 +107,7 @@ void account_system_vtime(struct task_struct *tsk) · 13 unmodified lines
107 cputime = S390_lowcore.system_timer >> 12;107 cputime = S390_lowcore.system_timer >> 12;
108 S390_lowcore.system_timer -= cputime << 12;108 S390_lowcore.system_timer -= cputime << 12;
109 S390_lowcore.steal_clock -= cputime << 12;109 S390_lowcore.steal_clock -= cputime << 12;
110 account_system_time(tsk, 0, cputime);110 account_system_time(tsk, 0, cputime, cputime);
111}111}
112EXPORT_SYMBOL_GPL(account_system_vtime);112EXPORT_SYMBOL_GPL(account_system_vtime);
113 113
include/linux/kernel_stat.h+2−4
@@ -79,10 +79,8 @@ static inline unsigned int kstat_irqs(unsigned int irq) · 78 unmodified lines
79}79}
80 80
81extern unsigned long long task_delta_exec(struct task_struct *);81extern unsigned long long task_delta_exec(struct task_struct *);
82extern void account_user_time(struct task_struct *, cputime_t);82extern void account_user_time(struct task_struct *, cputime_t, cputime_t);
83extern void account_user_time_scaled(struct task_struct *, cputime_t);83extern void account_system_time(struct task_struct *, int, cputime_t, cputime_t);
84extern void account_system_time(struct task_struct *, int, cputime_t);
85extern void account_system_time_scaled(struct task_struct *, cputime_t);
86extern void account_steal_time(struct task_struct *, cputime_t);84extern void account_steal_time(struct task_struct *, cputime_t);
87 85
88#endif /* _LINUX_KERNEL_STAT_H */86#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
4080 * Account user cpu time to a process.4080 * Account user cpu time to a process.
4081 * @p: the process that the cpu time gets accounted to4081 * @p: the process that the cpu time gets accounted to
4082 * @cputime: the cpu time spent in user space since the last update4082 * @cputime: the cpu time spent in user space since the last update
4083 * @cputime_scaled: cputime scaled by cpu frequency
4083 */4084 */
4084void account_user_time(struct task_struct *p, cputime_t cputime)4085void account_user_time(struct task_struct *p, cputime_t cputime,
4086 cputime_t cputime_scaled)
4085{4087{
4086 struct cpu_usage_stat *cpustat = &kstat_this_cpu.cpustat;4088 struct cpu_usage_stat *cpustat = &kstat_this_cpu.cpustat;
4087 cputime64_t tmp;4089 cputime64_t tmp;
4088 4090
4091 /* Add user time to process. */
4089 p->utime = cputime_add(p->utime, cputime);4092 p->utime = cputime_add(p->utime, cputime);
4093 p->utimescaled = cputime_add(p->utimescaled, cputime_scaled);
4090 account_group_user_time(p, cputime);4094 account_group_user_time(p, cputime);
4091 4095
4092 /* Add user time to cpustat. */4096 /* Add user time to cpustat. */
@@ -4103,51 +4107,49 @@ void account_user_time(struct task_struct *p, cputime_t cputime) · 10 unmodified lines
4103 * Account guest cpu time to a process.4107 * Account guest cpu time to a process.
4104 * @p: the process that the cpu time gets accounted to4108 * @p: the process that the cpu time gets accounted to
4105 * @cputime: the cpu time spent in virtual machine since the last update4109 * @cputime: the cpu time spent in virtual machine since the last update
4110 * @cputime_scaled: cputime scaled by cpu frequency
4106 */4111 */
4107static void account_guest_time(struct task_struct *p, cputime_t cputime)4112static void account_guest_time(struct task_struct *p, cputime_t cputime,
4113 cputime_t cputime_scaled)
4108{4114{
4109 cputime64_t tmp;4115 cputime64_t tmp;
4110 struct cpu_usage_stat *cpustat = &kstat_this_cpu.cpustat;4116 struct cpu_usage_stat *cpustat = &kstat_this_cpu.cpustat;
4111 4117
4112 tmp = cputime_to_cputime64(cputime);4118 tmp = cputime_to_cputime64(cputime);
4113 4119
4120 /* Add guest time to process. */
4114 p->utime = cputime_add(p->utime, cputime);4121 p->utime = cputime_add(p->utime, cputime);
4122 p->utimescaled = cputime_add(p->utimescaled, cputime_scaled);
4115 account_group_user_time(p, cputime);4123 account_group_user_time(p, cputime);
4116 p->gtime = cputime_add(p->gtime, cputime);4124 p->gtime = cputime_add(p->gtime, cputime);
4117 4125
4126 /* Add guest time to cpustat. */
4118 cpustat->user = cputime64_add(cpustat->user, tmp);4127 cpustat->user = cputime64_add(cpustat->user, tmp);
4119 cpustat->guest = cputime64_add(cpustat->guest, tmp);4128 cpustat->guest = cputime64_add(cpustat->guest, tmp);
4120}4129}
4121 4130
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 */
4127void account_user_time_scaled(struct task_struct *p, cputime_t cputime)
4128{
4129 p->utimescaled = cputime_add(p->utimescaled, cputime);
4130}
4131
4132/*4131/*
4133 * Account system cpu time to a process.4132 * Account system cpu time to a process.
4134 * @p: the process that the cpu time gets accounted to4133 * @p: the process that the cpu time gets accounted to
4135 * @hardirq_offset: the offset to subtract from hardirq_count()4134 * @hardirq_offset: the offset to subtract from hardirq_count()
4136 * @cputime: the cpu time spent in kernel space since the last update4135 * @cputime: the cpu time spent in kernel space since the last update
4136 * @cputime_scaled: cputime scaled by cpu frequency
4137 */4137 */
4138void account_system_time(struct task_struct *p, int hardirq_offset,4138void account_system_time(struct task_struct *p, int hardirq_offset,
4139 cputime_t cputime)4139 cputime_t cputime, cputime_t cputime_scaled)
4140{4140{
4141 struct cpu_usage_stat *cpustat = &kstat_this_cpu.cpustat;4141 struct cpu_usage_stat *cpustat = &kstat_this_cpu.cpustat;
4142 struct rq *rq = this_rq();4142 struct rq *rq = this_rq();
4143 cputime64_t tmp;4143 cputime64_t tmp;
4144 4144
4145 if ((p->flags & PF_VCPU) && (irq_count() - hardirq_offset == 0)) {4145 if ((p->flags & PF_VCPU) && (irq_count() - hardirq_offset == 0)) {
4146 account_guest_time(p, cputime);4146 account_guest_time(p, cputime, cputime_scaled);
4147 return;4147 return;
4148 }4148 }
4149 4149
4150 /* Add system time to process. */
4150 p->stime = cputime_add(p->stime, cputime);4151 p->stime = cputime_add(p->stime, cputime);
4152 p->stimescaled = cputime_add(p->stimescaled, cputime_scaled);
4151 account_group_system_time(p, cputime);4153 account_group_system_time(p, cputime);
4152 4154
4153 /* Add system time to cpustat. */4155 /* Add system time to cpustat. */
@@ -4166,17 +4168,6 @@ void account_system_time(struct task_struct *p, int hardirq_offset, · 12 unmodified lines
4166 acct_update_integrals(p);4168 acct_update_integrals(p);
4167}4169}
4168 4170
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 */
4175void account_system_time_scaled(struct task_struct *p, cputime_t cputime)
4176{
4177 p->stimescaled = cputime_add(p->stimescaled, cputime);
4178}
4179
4180/*4171/*
4181 * Account for involuntary wait time.4172 * Account for involuntary wait time.
4182 * @p: the process from which the cpu time has been stolen4173 * @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
420 int cpu = smp_processor_id();420 int cpu = smp_processor_id();
421 struct tick_sched *ts = &per_cpu(tick_cpu_sched, cpu);421 struct tick_sched *ts = &per_cpu(tick_cpu_sched, cpu);
422 unsigned long ticks;422 unsigned long ticks;
423 cputime_t cputime;
423 ktime_t now;424 ktime_t now;
424 425
425 local_irq_disable();426 local_irq_disable();
@@ -452,8 +453,8 @@ void tick_nohz_restart_sched_tick(void) · 26 unmodified lines
452 */453 */
453 if (ticks && ticks < LONG_MAX) {454 if (ticks && ticks < LONG_MAX) {
454 add_preempt_count(HARDIRQ_OFFSET);455 add_preempt_count(HARDIRQ_OFFSET);
455 account_system_time(current, HARDIRQ_OFFSET,456 cputime = jiffies_to_cputime(ticks);
456 jiffies_to_cputime(ticks));457 account_system_time(current, HARDIRQ_OFFSET, cputime, cputime);
457 sub_preempt_count(HARDIRQ_OFFSET);458 sub_preempt_count(HARDIRQ_OFFSET);
458 }459 }
459 460
kernel/timer.c+5−7
@@ -1023,13 +1023,11 @@ void account_process_tick(struct task_struct *p, int user_tick) · 1022 unmodified lines
1023{1023{
1024 cputime_t one_jiffy = jiffies_to_cputime(1);1024 cputime_t one_jiffy = jiffies_to_cputime(1);
1025 1025
1026 if (user_tick) {1026 if (user_tick)
1027 account_user_time(p, one_jiffy);1027 account_user_time(p, one_jiffy, cputime_to_scaled(one_jiffy));
1028 account_user_time_scaled(p, cputime_to_scaled(one_jiffy));1028 else
1029 } else {1029 account_system_time(p, HARDIRQ_OFFSET, one_jiffy,
1030 account_system_time(p, HARDIRQ_OFFSET, one_jiffy);1030 cputime_to_scaled(one_jiffy));
1031 account_system_time_scaled(p, cputime_to_scaled(one_jiffy));
1032 }
1033}1031}
1034#endif1032#endif
1035 1033