Skip to content

Commit

Permalink
[PATCH] stop_machine() vs. synchronous IPI send deadlock
Browse files Browse the repository at this point in the history
This fixes deadlock of stop_machine() vs.  synchronous IPI send.  The
problem is that stop_machine() disables interrupts before disabling
preemption on other CPUs.  So if another CPU is preempted and then calls
something like flush_tlb_all() it will deadlock with CPU doing
stop_machine() and which can't process IPI due to disabled IRQs.

I changed stop_machine() to do the same things exactly as it does on other
CPUs, i.e.  it should disable preemption first on _all_ CPUs including
itself and only after that disable IRQs.

Signed-off-by: Kirill Korotaev <[email protected]>
Cc: Rusty Russell <[email protected]>
Cc: "Andrey Savochkin" <[email protected]>
Signed-off-by: Andrew Morton <[email protected]>
Signed-off-by: Linus Torvalds <[email protected]>
Kirill Korotaev authored and Linus Torvalds committed Nov 14, 2005
1 parent c5b6097 commit 4557398
Showing 1 changed file with 3 additions and 3 deletions.
6 changes: 3 additions & 3 deletions kernel/stop_machine.c
Original file line number Diff line number Diff line change
@@ -119,13 +119,12 @@ static int stop_machine(void)
return ret;
}

/* Don't schedule us away at this point, please. */
local_irq_disable();

/* Now they are all started, make them hold the CPUs, ready. */
preempt_disable();
stopmachine_set_state(STOPMACHINE_PREPARE);

/* Make them disable irqs. */
local_irq_disable();
stopmachine_set_state(STOPMACHINE_DISABLE_IRQ);

return 0;
@@ -135,6 +134,7 @@ static void restart_machine(void)
{
stopmachine_set_state(STOPMACHINE_EXIT);
local_irq_enable();
preempt_enable_no_resched();
}

struct stop_machine_data

0 comments on commit 4557398

Please sign in to comment.