diff options
author | Paul Mackerras <paulus@samba.org> | 2006-08-30 06:10:47 (GMT) |
---|---|---|
committer | Paul Mackerras <paulus@samba.org> | 2006-08-30 06:10:47 (GMT) |
commit | 467c37801c453849a2fe243c3226476ee3985868 (patch) | |
tree | b1e9dedf59ff9144945cb711a96274f4ca9bce62 /arch | |
parent | e0d872d536bb93335d5905b09fe374a163486d43 (diff) | |
download | linux-467c37801c453849a2fe243c3226476ee3985868.tar.xz |
[POWERPC] Fix irq enable/disable in smp_generic_take_timebase
Eran Ben-Avi <eranpublic@yahoo.com> pointed out that the arch/ppc version
of smp_generic_take_timebase disables interrupts on entry but exits without
restoring them. However, both it and the arch/powerpc version have another
problem, which is that they use local_irq_disable/enable rather than
local_irq_save/restore, and they are called with interrupts disabled.
This fixes both problems; it changes a return to a break in the arch/ppc
version, and changes both versions to use local_irq_save/restore.
Signed-off-by: Paul Mackerras <paulus@samba.org>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/powerpc/kernel/smp-tbsync.c | 5 | ||||
-rw-r--r-- | arch/ppc/kernel/smp-tbsync.c | 7 |
2 files changed, 7 insertions, 5 deletions
diff --git a/arch/powerpc/kernel/smp-tbsync.c b/arch/powerpc/kernel/smp-tbsync.c index f19e2e0..de59c6c 100644 --- a/arch/powerpc/kernel/smp-tbsync.c +++ b/arch/powerpc/kernel/smp-tbsync.c @@ -45,8 +45,9 @@ void __devinit smp_generic_take_timebase(void) { int cmd; u64 tb; + unsigned long flags; - local_irq_disable(); + local_irq_save(flags); while (!running) barrier(); rmb(); @@ -70,7 +71,7 @@ void __devinit smp_generic_take_timebase(void) set_tb(tb >> 32, tb & 0xfffffffful); enter_contest(tbsync->mark, -1); } - local_irq_enable(); + local_irq_restore(flags); } static int __devinit start_contest(int cmd, long offset, int num) diff --git a/arch/ppc/kernel/smp-tbsync.c b/arch/ppc/kernel/smp-tbsync.c index 1576758..d0cf3f8 100644 --- a/arch/ppc/kernel/smp-tbsync.c +++ b/arch/ppc/kernel/smp-tbsync.c @@ -47,8 +47,9 @@ void __devinit smp_generic_take_timebase( void ) { int cmd, tbl, tbu; + unsigned long flags; - local_irq_disable(); + local_irq_save(flags); while( !running ) ; rmb(); @@ -64,7 +65,7 @@ smp_generic_take_timebase( void ) tbu = tbsync->tbu; tbsync->ack = 0; if( cmd == kExit ) - return; + break; if( cmd == kSetAndTest ) { while( tbsync->handshake ) @@ -77,7 +78,7 @@ smp_generic_take_timebase( void ) } enter_contest( tbsync->mark, -1 ); } - local_irq_enable(); + local_irq_restore(flags); } static int __devinit |