aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/irq/handle.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/irq/handle.c')
-rw-r--r--kernel/irq/handle.c28
1 files changed, 22 insertions, 6 deletions
diff --git a/kernel/irq/handle.c b/kernel/irq/handle.c
index 470d08c82bbe..bdb180325551 100644
--- a/kernel/irq/handle.c
+++ b/kernel/irq/handle.c
@@ -54,14 +54,18 @@ static void warn_no_thread(unsigned int irq, struct irqaction *action)
54static void irq_wake_thread(struct irq_desc *desc, struct irqaction *action) 54static void irq_wake_thread(struct irq_desc *desc, struct irqaction *action)
55{ 55{
56 /* 56 /*
57 * Wake up the handler thread for this action. In case the 57 * In case the thread crashed and was killed we just pretend that
58 * thread crashed and was killed we just pretend that we 58 * we handled the interrupt. The hardirq handler has disabled the
59 * handled the interrupt. The hardirq handler has disabled the 59 * device interrupt, so no irq storm is lurking.
60 * device interrupt, so no irq storm is lurking. If the 60 */
61 if (action->thread->flags & PF_EXITING)
62 return;
63
64 /*
65 * Wake up the handler thread for this action. If the
61 * RUNTHREAD bit is already set, nothing to do. 66 * RUNTHREAD bit is already set, nothing to do.
62 */ 67 */
63 if (test_bit(IRQTF_DIED, &action->thread_flags) || 68 if (test_and_set_bit(IRQTF_RUNTHREAD, &action->thread_flags))
64 test_and_set_bit(IRQTF_RUNTHREAD, &action->thread_flags))
65 return; 69 return;
66 70
67 /* 71 /*
@@ -110,6 +114,18 @@ static void irq_wake_thread(struct irq_desc *desc, struct irqaction *action)
110 * threads_oneshot untouched and runs the thread another time. 114 * threads_oneshot untouched and runs the thread another time.
111 */ 115 */
112 desc->threads_oneshot |= action->thread_mask; 116 desc->threads_oneshot |= action->thread_mask;
117
118 /*
119 * We increment the threads_active counter in case we wake up
120 * the irq thread. The irq thread decrements the counter when
121 * it returns from the handler or in the exit path and wakes
122 * up waiters which are stuck in synchronize_irq() when the
123 * active count becomes zero. synchronize_irq() is serialized
124 * against this code (hard irq handler) via IRQS_INPROGRESS
125 * like the finalize_oneshot() code. See comment above.
126 */
127 atomic_inc(&desc->threads_active);
128
113 wake_up_process(action->thread); 129 wake_up_process(action->thread);
114} 130}
115 131