From f9a2f797fcde5a4aa818bd3ca8584fd1197e9c15 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Fri, 23 Jan 2009 16:40:25 +0100 Subject: [PATCH] [S390] cputime: fix lowcore initialization on cpu hotplug On (initial) cpu hotplug the lowcore values for user_timer and system_timer don't get initialized like they would get on each process schedule. On initial start of secondary cpus this leads to the situation where per thread user/system_timer values are larger than the corresponding contents of the lowcore. When later calculating time spent in user/system context the result can be negative. So for cpu hotplug we should manually initialize lowcore values. Fixes this bug: Kernel BUG at 000ec080 [verbose debug info unavailable] fixpoint divide exception: 0009 [#1] PREEMPT SMP Modules linked in: CPU: 10 Not tainted 2.6.28 #4 Process sysctl (pid: 975, task: 3fa752e0, ksp: 3fbebca0) Krnl PSW : 070c1000 800ec080 (show_stat+0x390/0x5fc) R:0 T:1 IO:1 EX:1 Key:0 M:1 W:0 P:0 AS:0 CC:1 PM:0 Krnl GPRS: 7fffffff fefc7ce5 3faec080 003879ae 00000001 01388000 7fffffff 01388000 00000000 00000000 0049ad50 3fbebcf8 01388000 002f51a8 800ec1fe 3fbebcf8 Krnl Code: 800ec076: 9001b188 stm %r0,%r1,392(%r11) 800ec07a: 9801b0c0 lm %r0,%r1,192(%r11) 800ec07e: 1d05 dr %r0,%r5 >800ec080: 9001b0c0 stm %r0,%r1,192(%r11) 800ec084: 5860b0c4 l %r6,196(%r11) 800ec088: 1806 lr %r0,%r6 800ec08a: 8c800001 srdl %r8,1 800ec08e: 1d87 dr %r8,%r7 Call Trace: ([<00000000000ec1ee>] show_stat+0x4fe/0x5fc) [<00000000000c13e8>] seq_read+0xc4/0x3ac [<00000000000e4796>] proc_reg_read+0x6e/0x9c [<00000000000a6a44>] vfs_read+0x78/0x100 [<00000000000a6ba8>] sys_read+0x40/0x80 [<00000000000234a8>] sysc_do_restart+0x1a/0x1e Signed-off-by: Heiko Carstens --- arch/s390/kernel/vtime.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/arch/s390/kernel/vtime.c b/arch/s390/kernel/vtime.c index 2fb36e462194..ecf0304e61c1 100644 --- a/arch/s390/kernel/vtime.c +++ b/arch/s390/kernel/vtime.c @@ -516,8 +516,12 @@ EXPORT_SYMBOL(del_virt_timer); */ void init_cpu_vtimer(void) { + struct thread_info *ti = current_thread_info(); struct vtimer_queue *vq; + S390_lowcore.user_timer = ti->user_timer; + S390_lowcore.system_timer = ti->system_timer; + /* kick the virtual timer */ asm volatile ("STCK %0" : "=m" (S390_lowcore.last_update_clock)); asm volatile ("STPT %0" : "=m" (S390_lowcore.last_update_timer));