diff options
author | Heiko Carstens <heiko.carstens@de.ibm.com> | 2009-01-23 10:40:25 -0500 |
---|---|---|
committer | Heiko Carstens <heiko.carstens@de.ibm.com> | 2009-01-23 10:40:28 -0500 |
commit | f9a2f797fcde5a4aa818bd3ca8584fd1197e9c15 (patch) | |
tree | 66f91a2bcb556bd260572f8986a4d9c7d24e8b83 /arch/s390/kernel/vtime.c | |
parent | e9a4e9d563ea643d305b5fe83031d7deca311db3 (diff) |
[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 <heiko.carstens@de.ibm.com>
Diffstat (limited to 'arch/s390/kernel/vtime.c')
-rw-r--r-- | arch/s390/kernel/vtime.c | 4 |
1 files changed, 4 insertions, 0 deletions
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); | |||
516 | */ | 516 | */ |
517 | void init_cpu_vtimer(void) | 517 | void init_cpu_vtimer(void) |
518 | { | 518 | { |
519 | struct thread_info *ti = current_thread_info(); | ||
519 | struct vtimer_queue *vq; | 520 | struct vtimer_queue *vq; |
520 | 521 | ||
522 | S390_lowcore.user_timer = ti->user_timer; | ||
523 | S390_lowcore.system_timer = ti->system_timer; | ||
524 | |||
521 | /* kick the virtual timer */ | 525 | /* kick the virtual timer */ |
522 | asm volatile ("STCK %0" : "=m" (S390_lowcore.last_update_clock)); | 526 | asm volatile ("STCK %0" : "=m" (S390_lowcore.last_update_clock)); |
523 | asm volatile ("STPT %0" : "=m" (S390_lowcore.last_update_timer)); | 527 | asm volatile ("STPT %0" : "=m" (S390_lowcore.last_update_timer)); |