There is below race between irq handler and irq thread: irq handler irq thread
irq_wake_thread() irq_thread() set bit RUNTHREAD ... clear bit RUNTHREAD thread_fn() [A]test_and_decrease thread_active [B]increase thread_active If action A is before action B, after that the thread_active will be always > 0, and for synchronize_irq() calling, which will be waiting there forever. Here put the increasing thread-active before setting bit RUNTHREAD, which can resolve such race. Signed-off-by: xiaoming wang <xiaoming.w...@intel.com> Signed-off-by: Chuansheng Liu <chuansheng....@intel.com> --- kernel/irq/handle.c | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/kernel/irq/handle.c b/kernel/irq/handle.c index 131ca17..5f9fbb7 100644 --- a/kernel/irq/handle.c +++ b/kernel/irq/handle.c @@ -65,7 +65,7 @@ static void irq_wake_thread(struct irq_desc *desc, struct irqaction *action) * Wake up the handler thread for this action. If the * RUNTHREAD bit is already set, nothing to do. */ - if (test_and_set_bit(IRQTF_RUNTHREAD, &action->thread_flags)) + if (test_bit(IRQTF_RUNTHREAD, &action->thread_flags)) return; /* @@ -126,6 +126,25 @@ static void irq_wake_thread(struct irq_desc *desc, struct irqaction *action) */ atomic_inc(&desc->threads_active); + /* + * set the RUNTHREAD bit after increasing the threads_active, + * it can avoid the below race: + * irq handler irq thread in case it is in + * running state + * + * set RUNTHREAD bit + * clear the RUNTHREAD bit + *... thread_fn() + * + * due to threads_active==0, + * no waking up wait_for_threads + * + * threads_active ++ + * After that, the threads_active will be always > 0, which + * will block the synchronize_irq(). + */ + set_bit(IRQTF_RUNTHREAD, &action->thread_flags); + wake_up_process(action->thread); } -- 1.9.rc0 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/