summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Gleixner <tglx@linutronix.de>2009-08-12 18:32:08 +0200
committerThomas Gleixner <tglx@linutronix.de>2009-08-15 22:59:41 +0200
commitb46fe5710dee18042a0f333e3709cd7af79acd97 (patch)
tree2edfb0f921e926938ffecb27c7a15768904751b4
parent570f410b475b45462197d09ddca25e47616da5ac (diff)
downloadlwn-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.c12
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.