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.
Unified · Split
| @@ -93,13 +93,11 @@ void ia64_account_on_switch(struct task_struct *prev, struct task_struct *next) · 92 unmodified lines | ||
| 93 | 93 | now = ia64_get_itc(); |
| 94 | 94 | |
| 95 | 95 | 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); | |
| 98 | 97 | |
| 99 | 98 | if (pi->ac_utime) { |
| 100 | 99 | 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); | |
| 103 | 101 | } |
| 104 | 102 | |
| 105 | 103 | pi->ac_stamp = ni->ac_stamp = now; |
| @@ -122,8 +120,7 @@ void account_system_vtime(struct task_struct *tsk) · 16 unmodified lines | ||
| 122 | 120 | now = ia64_get_itc(); |
| 123 | 121 | |
| 124 | 122 | 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); | |
| 127 | 124 | ti->ac_stime = 0; |
| 128 | 125 | |
| 129 | 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 | 141 | if (ti->ac_utime) { |
| 145 | 142 | 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); | |
| 148 | 144 | ti->ac_utime = 0; |
| 149 | 145 | } |
| 150 | 146 | } |
| @@ -256,8 +256,7 @@ void account_system_vtime(struct task_struct *tsk) · 255 unmodified lines | ||
| 256 | 256 | delta += sys_time; |
| 257 | 257 | get_paca()->system_time = 0; |
| 258 | 258 | } |
| 259 | − account_system_time(tsk, 0, delta); | |
| 260 | − account_system_time_scaled(tsk, deltascaled); | |
| 259 | + account_system_time(tsk, 0, delta, deltascaled); | |
| 261 | 260 | per_cpu(cputime_last_delta, smp_processor_id()) = delta; |
| 262 | 261 | per_cpu(cputime_scaled_last_delta, smp_processor_id()) = deltascaled; |
| 263 | 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 | 275 | utime = get_paca()->user_time; |
| 277 | 276 | get_paca()->user_time = 0; |
| 278 | − account_user_time(tsk, utime); | |
| 279 | − | |
| 280 | 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 | /* |
| @@ -50,12 +50,12 @@ void account_process_tick(struct task_struct *tsk, int user_tick) · 49 unmodified lines | ||
| 50 | 50 | rcu_user_flag = cputime != 0; |
| 51 | 51 | S390_lowcore.user_timer -= cputime << 12; |
| 52 | 52 | S390_lowcore.steal_clock -= cputime << 12; |
| 53 | − account_user_time(tsk, cputime); | |
| 53 | + account_user_time(tsk, cputime, cputime); | |
| 54 | 54 | |
| 55 | 55 | cputime = S390_lowcore.system_timer >> 12; |
| 56 | 56 | S390_lowcore.system_timer -= cputime << 12; |
| 57 | 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 | 60 | cputime = S390_lowcore.steal_clock; |
| 61 | 61 | if ((__s64) cputime > 0) { |
| @@ -82,12 +82,12 @@ void account_vtime(struct task_struct *tsk) · 20 unmodified lines | ||
| 82 | 82 | cputime = S390_lowcore.user_timer >> 12; |
| 83 | 83 | S390_lowcore.user_timer -= cputime << 12; |
| 84 | 84 | S390_lowcore.steal_clock -= cputime << 12; |
| 85 | − account_user_time(tsk, cputime); | |
| 85 | + account_user_time(tsk, cputime, cputime); | |
| 86 | 86 | |
| 87 | 87 | cputime = S390_lowcore.system_timer >> 12; |
| 88 | 88 | S390_lowcore.system_timer -= cputime << 12; |
| 89 | 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 | 107 | cputime = S390_lowcore.system_timer >> 12; |
| 108 | 108 | S390_lowcore.system_timer -= cputime << 12; |
| 109 | 109 | S390_lowcore.steal_clock -= cputime << 12; |
| 110 | − account_system_time(tsk, 0, cputime); | |
| 110 | + account_system_time(tsk, 0, cputime, cputime); | |
| 111 | 111 | } |
| 112 | 112 | EXPORT_SYMBOL_GPL(account_system_vtime); |
| 113 | 113 | |
| @@ -79,10 +79,8 @@ static inline unsigned int kstat_irqs(unsigned int irq) · 78 unmodified lines | ||
| 79 | 79 | } |
| 80 | 80 | |
| 81 | 81 | 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); | |
| 86 | 84 | extern void account_steal_time(struct task_struct *, cputime_t); |
| 87 | 85 | |
| 88 | 86 | #endif /* _LINUX_KERNEL_STAT_H */ |
| @@ -4080,13 +4080,17 @@ unsigned long long task_delta_exec(struct task_struct *p) · 4079 unmodified lines | ||
| 4080 | 4080 | * Account user cpu time to a process. |
| 4081 | 4081 | * @p: the process that the cpu time gets accounted to |
| 4082 | 4082 | * @cputime: the cpu time spent in user space since the last update |
| 4083 | + * @cputime_scaled: cputime scaled by cpu frequency | |
| 4083 | 4084 | */ |
| 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) | |
| 4085 | 4087 | { |
| 4086 | 4088 | struct cpu_usage_stat *cpustat = &kstat_this_cpu.cpustat; |
| 4087 | 4089 | cputime64_t tmp; |
| 4088 | 4090 | |
| 4091 | + /* Add user time to process. */ | |
| 4089 | 4092 | p->utime = cputime_add(p->utime, cputime); |
| 4093 | + p->utimescaled = cputime_add(p->utimescaled, cputime_scaled); | |
| 4090 | 4094 | account_group_user_time(p, cputime); |
| 4091 | 4095 | |
| 4092 | 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 | 4107 | * Account guest cpu time to a process. |
| 4104 | 4108 | * @p: the process that the cpu time gets accounted to |
| 4105 | 4109 | * @cputime: the cpu time spent in virtual machine since the last update |
| 4110 | + * @cputime_scaled: cputime scaled by cpu frequency | |
| 4106 | 4111 | */ |
| 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) | |
| 4108 | 4114 | { |
| 4109 | 4115 | cputime64_t tmp; |
| 4110 | 4116 | struct cpu_usage_stat *cpustat = &kstat_this_cpu.cpustat; |
| 4111 | 4117 | |
| 4112 | 4118 | tmp = cputime_to_cputime64(cputime); |
| 4113 | 4119 | |
| 4120 | + /* Add guest time to process. */ | |
| 4114 | 4121 | p->utime = cputime_add(p->utime, cputime); |
| 4122 | + p->utimescaled = cputime_add(p->utimescaled, cputime_scaled); | |
| 4115 | 4123 | account_group_user_time(p, cputime); |
| 4116 | 4124 | p->gtime = cputime_add(p->gtime, cputime); |
| 4117 | 4125 | |
| 4126 | + /* Add guest time to cpustat. */ | |
| 4118 | 4127 | cpustat->user = cputime64_add(cpustat->user, tmp); |
| 4119 | 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 | − */ | |
| 4127 | −void 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 | 4132 | * Account system cpu time to a process. |
| 4134 | 4133 | * @p: the process that the cpu time gets accounted to |
| 4135 | 4134 | * @hardirq_offset: the offset to subtract from hardirq_count() |
| 4136 | 4135 | * @cputime: the cpu time spent in kernel space since the last update |
| 4136 | + * @cputime_scaled: cputime scaled by cpu frequency | |
| 4137 | 4137 | */ |
| 4138 | 4138 | void 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 | 4141 | struct cpu_usage_stat *cpustat = &kstat_this_cpu.cpustat; |
| 4142 | 4142 | struct rq *rq = this_rq(); |
| 4143 | 4143 | cputime64_t tmp; |
| 4144 | 4144 | |
| 4145 | 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 | 4147 | return; |
| 4148 | 4148 | } |
| 4149 | 4149 | |
| 4150 | + /* Add system time to process. */ | |
| 4150 | 4151 | p->stime = cputime_add(p->stime, cputime); |
| 4152 | + p->stimescaled = cputime_add(p->stimescaled, cputime_scaled); | |
| 4151 | 4153 | account_group_system_time(p, cputime); |
| 4152 | 4154 | |
| 4153 | 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 | 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 | − */ | |
| 4175 | −void 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 | 4172 | * Account for involuntary wait time. |
| 4182 | 4173 | * @p: the process from which the cpu time has been stolen |
| @@ -420,6 +420,7 @@ void tick_nohz_restart_sched_tick(void) · 419 unmodified lines | ||
| 420 | 420 | int cpu = smp_processor_id(); |
| 421 | 421 | struct tick_sched *ts = &per_cpu(tick_cpu_sched, cpu); |
| 422 | 422 | unsigned long ticks; |
| 423 | + cputime_t cputime; | |
| 423 | 424 | ktime_t now; |
| 424 | 425 | |
| 425 | 426 | local_irq_disable(); |
| @@ -452,8 +453,8 @@ void tick_nohz_restart_sched_tick(void) · 26 unmodified lines | ||
| 452 | 453 | */ |
| 453 | 454 | if (ticks && ticks < LONG_MAX) { |
| 454 | 455 | 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); | |
| 457 | 458 | sub_preempt_count(HARDIRQ_OFFSET); |
| 458 | 459 | } |
| 459 | 460 | |
| @@ -1023,13 +1023,11 @@ void account_process_tick(struct task_struct *p, int user_tick) · 1022 unmodified lines | ||
| 1023 | 1023 | { |
| 1024 | 1024 | cputime_t one_jiffy = jiffies_to_cputime(1); |
| 1025 | 1025 | |
| 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)); | |
| 1033 | 1031 | } |
| 1034 | 1032 | #endif |
| 1035 | 1033 | |