Commit 467c3780 authored by Paul Mackerras's avatar Paul Mackerras

[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: default avatarPaul Mackerras <paulus@samba.org>
parent e0d872d5
...@@ -45,8 +45,9 @@ void __devinit smp_generic_take_timebase(void) ...@@ -45,8 +45,9 @@ void __devinit smp_generic_take_timebase(void)
{ {
int cmd; int cmd;
u64 tb; u64 tb;
unsigned long flags;
local_irq_disable(); local_irq_save(flags);
while (!running) while (!running)
barrier(); barrier();
rmb(); rmb();
...@@ -70,7 +71,7 @@ void __devinit smp_generic_take_timebase(void) ...@@ -70,7 +71,7 @@ void __devinit smp_generic_take_timebase(void)
set_tb(tb >> 32, tb & 0xfffffffful); set_tb(tb >> 32, tb & 0xfffffffful);
enter_contest(tbsync->mark, -1); enter_contest(tbsync->mark, -1);
} }
local_irq_enable(); local_irq_restore(flags);
} }
static int __devinit start_contest(int cmd, long offset, int num) static int __devinit start_contest(int cmd, long offset, int num)
......
...@@ -47,8 +47,9 @@ void __devinit ...@@ -47,8 +47,9 @@ void __devinit
smp_generic_take_timebase( void ) smp_generic_take_timebase( void )
{ {
int cmd, tbl, tbu; int cmd, tbl, tbu;
unsigned long flags;
local_irq_disable(); local_irq_save(flags);
while( !running ) while( !running )
; ;
rmb(); rmb();
...@@ -64,7 +65,7 @@ smp_generic_take_timebase( void ) ...@@ -64,7 +65,7 @@ smp_generic_take_timebase( void )
tbu = tbsync->tbu; tbu = tbsync->tbu;
tbsync->ack = 0; tbsync->ack = 0;
if( cmd == kExit ) if( cmd == kExit )
return; break;
if( cmd == kSetAndTest ) { if( cmd == kSetAndTest ) {
while( tbsync->handshake ) while( tbsync->handshake )
...@@ -77,7 +78,7 @@ smp_generic_take_timebase( void ) ...@@ -77,7 +78,7 @@ smp_generic_take_timebase( void )
} }
enter_contest( tbsync->mark, -1 ); enter_contest( tbsync->mark, -1 );
} }
local_irq_enable(); local_irq_restore(flags);
} }
static int __devinit static int __devinit
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment