mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [PATCH 1/2] genirq: Fix the possible synchronize_irq() wait-forever
@ 2014-02-10  8:13 Chuansheng Liu
  2014-02-10  8:13 ` [PATCH 2/2] genirq: Fix one typo chasnge Chuansheng Liu
  2014-02-10  8:58 ` [PATCH 1/2] genirq: Fix the possible synchronize_irq() wait-forever Thomas Gleixner
  0 siblings, 2 replies; 14+ messages in thread
From: Chuansheng Liu @ 2014-02-10  8:13 UTC (permalink / raw)
  To: tglx; +Cc: linux-kernel, Chuansheng Liu, xiaoming wang

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.wang@intel.com>
Signed-off-by: Chuansheng Liu <chuansheng.liu@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


^ permalink raw reply	[flat|nested] 14+ messages in thread

end of thread, other threads:[~2014-02-21 13:05 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-02-10  8:13 [PATCH 1/2] genirq: Fix the possible synchronize_irq() wait-forever Chuansheng Liu
2014-02-10  8:13 ` [PATCH 2/2] genirq: Fix one typo chasnge Chuansheng Liu
2014-02-19 16:27   ` [tip:irq/core] genirq: Update the a comment typo tip-bot for Chuansheng Liu
2014-02-10  8:58 ` [PATCH 1/2] genirq: Fix the possible synchronize_irq() wait-forever Thomas Gleixner
2014-02-20  0:34   ` Liu, Chuansheng
2014-02-20 12:52     ` Thomas Gleixner
2014-02-21  0:53       ` Liu, Chuansheng
2014-02-21 10:33         ` Thomas Gleixner
2014-02-21 11:01           ` Liu, Chuansheng
2014-02-21 11:10             ` Thomas Gleixner
2014-02-21 11:26               ` Liu, Chuansheng
2014-02-21 11:52                 ` Thomas Gleixner
2014-02-21 12:29                   ` Liu, Chuansheng
2014-02-21 13:05                     ` Thomas Gleixner

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

Powered by JetHome