aboutsummaryrefslogtreecommitdiffstats
path: root/arch/ppc
diff options
context:
space:
mode:
authorPaul Mackerras <paulus@samba.org>2006-08-30 02:10:47 -0400
committerPaul Mackerras <paulus@samba.org>2006-08-30 02:10:47 -0400
commit467c37801c453849a2fe243c3226476ee3985868 (patch)
treeb1e9dedf59ff9144945cb711a96274f4ca9bce62 /arch/ppc
parente0d872d536bb93335d5905b09fe374a163486d43 (diff)
[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/ppc')
-rw-r--r--arch/ppc/kernel/smp-tbsync.c7
1 files changed, 4 insertions, 3 deletions
diff --git a/arch/ppc/kernel/smp-tbsync.c b/arch/ppc/kernel/smp-tbsync.c
index 1576758debaf..d0cf3f86931d 100644
--- a/arch/ppc/kernel/smp-tbsync.c
+++ b/arch/ppc/kernel/smp-tbsync.c
@@ -47,8 +47,9 @@ void __devinit
47smp_generic_take_timebase( void ) 47smp_generic_take_timebase( void )
48{ 48{
49 int cmd, tbl, tbu; 49 int cmd, tbl, tbu;
50 unsigned long flags;
50 51
51 local_irq_disable(); 52 local_irq_save(flags);
52 while( !running ) 53 while( !running )
53 ; 54 ;
54 rmb(); 55 rmb();
@@ -64,7 +65,7 @@ smp_generic_take_timebase( void )
64 tbu = tbsync->tbu; 65 tbu = tbsync->tbu;
65 tbsync->ack = 0; 66 tbsync->ack = 0;
66 if( cmd == kExit ) 67 if( cmd == kExit )
67 return; 68 break;
68 69
69 if( cmd == kSetAndTest ) { 70 if( cmd == kSetAndTest ) {
70 while( tbsync->handshake ) 71 while( tbsync->handshake )
@@ -77,7 +78,7 @@ smp_generic_take_timebase( void )
77 } 78 }
78 enter_contest( tbsync->mark, -1 ); 79 enter_contest( tbsync->mark, -1 );
79 } 80 }
80 local_irq_enable(); 81 local_irq_restore(flags);
81} 82}
82 83
83static int __devinit 84static int __devinit