| From 6d83f94db95cfe65d2a6359cccdf61cf087c2598 Mon Sep 17 00:00:00 2001 |
| From: Thomas Gleixner <tglx@linutronix.de> |
| Date: Fri, 18 Feb 2011 23:27:23 +0100 |
| Subject: genirq: Disable the SHIRQ_DEBUG call in request_threaded_irq for now |
| |
| From: Thomas Gleixner <tglx@linutronix.de> |
| |
| commit 6d83f94db95cfe65d2a6359cccdf61cf087c2598 upstream. |
| |
| With CONFIG_SHIRQ_DEBUG=y we call a newly installed interrupt handler |
| in request_threaded_irq(). |
| |
| The original implementation (commit a304e1b8) called the handler |
| _BEFORE_ it was installed, but that caused problems with handlers |
| calling disable_irq_nosync(). See commit 377bf1e4. |
| |
| It's braindead in the first place to call disable_irq_nosync in shared |
| handlers, but .... |
| |
| Moving this call after we installed the handler looks innocent, but it |
| is very subtle broken on SMP. |
| |
| Interrupt handlers rely on the fact, that the irq core prevents |
| reentrancy. |
| |
| Now this debug call violates that promise because we run the handler |
| w/o the IRQ_INPROGRESS protection - which we cannot apply here because |
| that would result in a possibly forever masked interrupt line. |
| |
| A concurrent real hardware interrupt on a different CPU results in |
| handler reentrancy and can lead to complete wreckage, which was |
| unfortunately observed in reality and took a fricking long time to |
| debug. |
| |
| Leave the code here for now. We want this debug feature, but that's |
| not easy to fix. We really should get rid of those |
| disable_irq_nosync() abusers and remove that function completely. |
| |
| Signed-off-by: Thomas Gleixner <tglx@linutronix.de> |
| Cc: Anton Vorontsov <avorontsov@ru.mvista.com> |
| Cc: David Woodhouse <dwmw2@infradead.org> |
| Cc: Arjan van de Ven <arjan@infradead.org> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> |
| |
| --- |
| kernel/irq/manage.c | 2 +- |
| 1 file changed, 1 insertion(+), 1 deletion(-) |
| |
| --- a/kernel/irq/manage.c |
| +++ b/kernel/irq/manage.c |
| @@ -1097,7 +1097,7 @@ int request_threaded_irq(unsigned int ir |
| if (retval) |
| kfree(action); |
| |
| -#ifdef CONFIG_DEBUG_SHIRQ |
| +#ifdef CONFIG_DEBUG_SHIRQ_FIXME |
| if (!retval && (irqflags & IRQF_SHARED)) { |
| /* |
| * It's a shared IRQ -- the driver ought to be prepared for it |