[PATCH] s390: cputime misaccounting

finish_arch_switch needs to update the user cpu time as well, not just the
system cpu time. Otherwise the partial user cpu time of a process that is
stored in the lowcore will be (mis-)accounted to the next process.

Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>

authored by Martin Schwidefsky and committed by Linus Torvalds 1f1c12af bcc13265

+30 -8
+1 -1
arch/s390/kernel/time.c
··· 214 214 #endif 215 215 216 216 #ifdef CONFIG_VIRT_CPU_ACCOUNTING 217 - account_user_vtime(current); 217 + account_tick_vtime(current); 218 218 #else 219 219 while (ticks--) 220 220 update_process_times(user_mode(regs));
+26 -1
arch/s390/kernel/vtime.c
··· 32 32 * Update process times based on virtual cpu times stored by entry.S 33 33 * to the lowcore fields user_timer, system_timer & steal_clock. 34 34 */ 35 - void account_user_vtime(struct task_struct *tsk) 35 + void account_tick_vtime(struct task_struct *tsk) 36 36 { 37 37 cputime_t cputime; 38 38 __u64 timer, clock; ··· 70 70 rcu_check_callbacks(smp_processor_id(), rcu_user_flag); 71 71 scheduler_tick(); 72 72 run_posix_cpu_timers(tsk); 73 + } 74 + 75 + /* 76 + * Update process times based on virtual cpu times stored by entry.S 77 + * to the lowcore fields user_timer, system_timer & steal_clock. 78 + */ 79 + void account_vtime(struct task_struct *tsk) 80 + { 81 + cputime_t cputime; 82 + __u64 timer; 83 + 84 + timer = S390_lowcore.last_update_timer; 85 + asm volatile (" STPT %0" /* Store current cpu timer value */ 86 + : "=m" (S390_lowcore.last_update_timer) ); 87 + S390_lowcore.system_timer += timer - S390_lowcore.last_update_timer; 88 + 89 + cputime = S390_lowcore.user_timer >> 12; 90 + S390_lowcore.user_timer -= cputime << 12; 91 + S390_lowcore.steal_clock -= cputime << 12; 92 + account_user_time(tsk, cputime); 93 + 94 + cputime = S390_lowcore.system_timer >> 12; 95 + S390_lowcore.system_timer -= cputime << 12; 96 + S390_lowcore.steal_clock -= cputime << 12; 97 + account_system_time(tsk, 0, cputime); 73 98 } 74 99 75 100 /*
+3 -2
include/asm-s390/system.h
··· 115 115 } 116 116 117 117 #ifdef CONFIG_VIRT_CPU_ACCOUNTING 118 - extern void account_user_vtime(struct task_struct *); 118 + extern void account_vtime(struct task_struct *); 119 + extern void account_tick_vtime(struct task_struct *); 119 120 extern void account_system_vtime(struct task_struct *); 120 121 #endif 121 122 122 123 #define finish_arch_switch(prev) do { \ 123 124 set_fs(current->thread.mm_segment); \ 124 - account_system_vtime(prev); \ 125 + account_vtime(prev); \ 125 126 } while (0) 126 127 127 128 #define nop() __asm__ __volatile__ ("nop")
-4
include/linux/hardirq.h
··· 93 93 struct task_struct; 94 94 95 95 #ifndef CONFIG_VIRT_CPU_ACCOUNTING 96 - static inline void account_user_vtime(struct task_struct *tsk) 97 - { 98 - } 99 - 100 96 static inline void account_system_vtime(struct task_struct *tsk) 101 97 { 102 98 }