diff options
author | Thomas Gleixner <tglx@linutronix.de> | 2009-08-12 18:32:08 +0200 |
---|---|---|
committer | Thomas Gleixner <tglx@linutronix.de> | 2009-08-15 22:59:41 +0200 |
commit | b46fe5710dee18042a0f333e3709cd7af79acd97 (patch) | |
tree | 2edfb0f921e926938ffecb27c7a15768904751b4 | |
parent | 570f410b475b45462197d09ddca25e47616da5ac (diff) | |
download | lwn-b46fe5710dee18042a0f333e3709cd7af79acd97.tar.gz lwn-b46fe5710dee18042a0f333e3709cd7af79acd97.zip |
genirq: Cleanup forced threading bits when handler thread terminates
When a handler thread terminates then the forced_thread_active bit
might be still set. Cleanup and unmask the interrupt if this is the
last thread which blocked the unmask.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
-rw-r--r-- | kernel/irq/manage.c | 12 |
1 files changed, 12 insertions, 0 deletions
diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c index df69993d6030..e4a6ba9786bf 100644 --- a/kernel/irq/manage.c +++ b/kernel/irq/manage.c @@ -537,6 +537,14 @@ static void preempt_hardirq_setup(struct irqaction *new) new->thread_fn = new->handler; new->handler = preempt_hardirq_handler; } + +static inline void +preempt_hardirq_cleanup(struct irq_desc *desc, struct irqaction *action) +{ + clear_bit(IRQTF_RUNTHREAD, &action->thread_flags); + preempt_hardirq_thread_done(desc, action); +} + #else static inline void preempt_hardirq_setup(struct irqaction *new) { } static inline int @@ -544,6 +552,8 @@ preempt_hardirq_thread_done(struct irq_desc *d, struct irqaction *a) { return 0; } +static inline void +preempt_hardirq_cleanup(struct irq_desc *d, struct irqaction *a) { } #endif static int @@ -639,6 +649,8 @@ static int irq_thread(void *data) wake_up(&desc->wait_for_threads); } + preempt_hardirq_cleanup(desc, action); + /* * Clear irqaction. Otherwise exit_irq_thread() would make * fuzz about an active irq thread going into nirvana. |