[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>
This commit is contained in:
Родитель
e0d872d536
Коммит
467c37801c
|
@ -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)
|
||||||
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
|
||||||
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 )
|
||||||
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 )
|
||||||
}
|
}
|
||||||
enter_contest( tbsync->mark, -1 );
|
enter_contest( tbsync->mark, -1 );
|
||||||
}
|
}
|
||||||
local_irq_enable();
|
local_irq_restore(flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int __devinit
|
static int __devinit
|
||||||
|
|
Загрузка…
Ссылка в новой задаче