Don't call "note_interrupt()" with irq descriptor lock held
authorLinus Torvalds <torvalds@woody.osdl.org>
Wed, 22 Nov 2006 17:32:06 +0000 (09:32 -0800)
committerLinus Torvalds <torvalds@woody.osdl.org>
Wed, 22 Nov 2006 17:32:06 +0000 (09:32 -0800)
This reverts commit f72fa707604c015a6625e80f269506032d5430dc, and solves
the problem that it tried to fix by simply making "__do_IRQ()" call the
note_interrupt() function without the lock held, the way everybody else
does.

It should be noted that all interrupt handling code must never allow the
descriptor actors to be entered "recursively" (that's why we do all the
magic IRQ_PENDING stuff in the first place), so there actually is
exclusion at that much higher level, even in the absense of locking.

Acked-by: Vivek Goyal <vgoyal@in.ibm.com>
Acked-by:Pavel Emelianov <xemul@openvz.org>
Cc: Andrew Morton <akpm@osdl.org>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Adrian Bunk <bunk@stusta.de>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
kernel/irq/handle.c
kernel/irq/spurious.c

index 42aa6f1a3f0f95e7dce8be2480ab5d209c881db3..a681912bc89a10388e6a4eeecd44dfe05416aff9 100644 (file)
@@ -231,10 +231,10 @@ fastcall unsigned int __do_IRQ(unsigned int irq)
                spin_unlock(&desc->lock);
 
                action_ret = handle_IRQ_event(irq, action);
-
-               spin_lock(&desc->lock);
                if (!noirqdebug)
                        note_interrupt(irq, desc, action_ret);
+
+               spin_lock(&desc->lock);
                if (likely(!(desc->status & IRQ_PENDING)))
                        break;
                desc->status &= ~IRQ_PENDING;
index 9c7e2e4c1fe717ef0f309eed0163a2d28a6cd5a7..543ea2e5ad9301944ab520303bd7fe84e4e92f88 100644 (file)
@@ -147,11 +147,7 @@ void note_interrupt(unsigned int irq, struct irq_desc *desc,
        if (unlikely(irqfixup)) {
                /* Don't punish working computers */
                if ((irqfixup == 2 && irq == 0) || action_ret == IRQ_NONE) {
-                       int ok;
-
-                       spin_unlock(&desc->lock);
-                       ok = misrouted_irq(irq);
-                       spin_lock(&desc->lock);
+                       int ok = misrouted_irq(irq);
                        if (action_ret == IRQ_NONE)
                                desc->irqs_unhandled -= ok;
                }