[POWERPC] Fix irq enable/disable in smp_generic_take_timebase
authorPaul Mackerras <paulus@samba.org>
Wed, 30 Aug 2006 06:10:47 +0000 (16:10 +1000)
committerPaul Mackerras <paulus@samba.org>
Wed, 30 Aug 2006 06:10:47 +0000 (16:10 +1000)
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>
arch/powerpc/kernel/smp-tbsync.c
arch/ppc/kernel/smp-tbsync.c

index f19e2e0e61e7b6635e69efc1b91458cf4805ebac..de59c6c31a5b81f1cc3f28ff12af611d4b558df5 100644 (file)
@@ -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)
index 1576758debaf1cdee7b9f3b091dc1cbf983dd34c..d0cf3f86931dbffae1aa6c0b182722be1376b089 100644 (file)
@@ -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