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>
{
int cmd;
u64 tb;
+ unsigned long flags;
- local_irq_disable();
+ local_irq_save(flags);
while (!running)
barrier();
rmb();
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)
smp_generic_take_timebase( void )
{
int cmd, tbl, tbu;
+ unsigned long flags;
- local_irq_disable();
+ local_irq_save(flags);
while( !running )
;
rmb();
tbu = tbsync->tbu;
tbsync->ack = 0;
if( cmd == kExit )
- return;
+ break;
if( cmd == kSetAndTest ) {
while( tbsync->handshake )
}
enter_contest( tbsync->mark, -1 );
}
- local_irq_enable();
+ local_irq_restore(flags);
}
static int __devinit