diff options
Diffstat (limited to 'kernel/irq/handle.c')
| -rw-r--r-- | kernel/irq/handle.c | 14 | 
1 files changed, 13 insertions, 1 deletions
diff --git a/kernel/irq/handle.c b/kernel/irq/handle.c index 470d08c82bb..6ff84e6a954 100644 --- a/kernel/irq/handle.c +++ b/kernel/irq/handle.c @@ -60,7 +60,7 @@ static void irq_wake_thread(struct irq_desc *desc, struct irqaction *action)  	 * device interrupt, so no irq storm is lurking. If the  	 * RUNTHREAD bit is already set, nothing to do.  	 */ -	if (test_bit(IRQTF_DIED, &action->thread_flags) || +	if ((action->thread->flags & PF_EXITING) ||  	    test_and_set_bit(IRQTF_RUNTHREAD, &action->thread_flags))  		return; @@ -110,6 +110,18 @@ static void irq_wake_thread(struct irq_desc *desc, struct irqaction *action)  	 * threads_oneshot untouched and runs the thread another time.  	 */  	desc->threads_oneshot |= action->thread_mask; + +	/* +	 * We increment the threads_active counter in case we wake up +	 * the irq thread. The irq thread decrements the counter when +	 * it returns from the handler or in the exit path and wakes +	 * up waiters which are stuck in synchronize_irq() when the +	 * active count becomes zero. synchronize_irq() is serialized +	 * against this code (hard irq handler) via IRQS_INPROGRESS +	 * like the finalize_oneshot() code. See comment above. +	 */ +	atomic_inc(&desc->threads_active); +  	wake_up_process(action->thread);  }  |