ARM: fix rcu stalls on SMP platforms

We can stall RCU processing on SMP platforms if a CPU sits in its idle
loop for a long time.  This happens because we don't call irq_enter()
and irq_exit() around generic_smp_call_function_interrupt() and
friends.  Add the necessary calls, and remove the one from within
ipi_timer(), so that they're all in a common place.

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
This commit is contained in:
Russell King 2012-01-19 15:20:58 +00:00
Родитель 94ae0275d7
Коммит 7deabca0ac
1 изменённых файлов: 8 добавлений и 2 удалений

Просмотреть файл

@ -443,9 +443,7 @@ static DEFINE_PER_CPU(struct clock_event_device, percpu_clockevent);
static void ipi_timer(void) static void ipi_timer(void)
{ {
struct clock_event_device *evt = &__get_cpu_var(percpu_clockevent); struct clock_event_device *evt = &__get_cpu_var(percpu_clockevent);
irq_enter();
evt->event_handler(evt); evt->event_handler(evt);
irq_exit();
} }
#ifdef CONFIG_GENERIC_CLOCKEVENTS_BROADCAST #ifdef CONFIG_GENERIC_CLOCKEVENTS_BROADCAST
@ -548,7 +546,9 @@ void handle_IPI(int ipinr, struct pt_regs *regs)
switch (ipinr) { switch (ipinr) {
case IPI_TIMER: case IPI_TIMER:
irq_enter();
ipi_timer(); ipi_timer();
irq_exit();
break; break;
case IPI_RESCHEDULE: case IPI_RESCHEDULE:
@ -556,15 +556,21 @@ void handle_IPI(int ipinr, struct pt_regs *regs)
break; break;
case IPI_CALL_FUNC: case IPI_CALL_FUNC:
irq_enter();
generic_smp_call_function_interrupt(); generic_smp_call_function_interrupt();
irq_exit();
break; break;
case IPI_CALL_FUNC_SINGLE: case IPI_CALL_FUNC_SINGLE:
irq_enter();
generic_smp_call_function_single_interrupt(); generic_smp_call_function_single_interrupt();
irq_exit();
break; break;
case IPI_CPU_STOP: case IPI_CPU_STOP:
irq_enter();
ipi_cpu_stop(cpu); ipi_cpu_stop(cpu);
irq_exit();
break; break;
default: default: