aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/irq
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@woody.osdl.org>2006-11-22 12:32:06 -0500
committerLinus Torvalds <torvalds@woody.osdl.org>2006-11-22 12:32:06 -0500
commitb42172fc7b569a0ef2b0fa38d71382969074c0e2 (patch)
tree2fe6141c936421d339a9443a6ad6af4dd4d2386b /kernel/irq
parent0f9005a6f7a82f4aacbd72f7b92322a8ca1c3f97 (diff)
Don't call "note_interrupt()" with irq descriptor lock held
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>
Diffstat (limited to 'kernel/irq')
-rw-r--r--kernel/irq/handle.c4
-rw-r--r--kernel/irq/spurious.c6
2 files changed, 3 insertions, 7 deletions
diff --git a/kernel/irq/handle.c b/kernel/irq/handle.c
index 42aa6f1a3f0f..a681912bc89a 100644
--- a/kernel/irq/handle.c
+++ b/kernel/irq/handle.c
@@ -231,10 +231,10 @@ fastcall unsigned int __do_IRQ(unsigned int irq)
231 spin_unlock(&desc->lock); 231 spin_unlock(&desc->lock);
232 232
233 action_ret = handle_IRQ_event(irq, action); 233 action_ret = handle_IRQ_event(irq, action);
234
235 spin_lock(&desc->lock);
236 if (!noirqdebug) 234 if (!noirqdebug)
237 note_interrupt(irq, desc, action_ret); 235 note_interrupt(irq, desc, action_ret);
236
237 spin_lock(&desc->lock);
238 if (likely(!(desc->status & IRQ_PENDING))) 238 if (likely(!(desc->status & IRQ_PENDING)))
239 break; 239 break;
240 desc->status &= ~IRQ_PENDING; 240 desc->status &= ~IRQ_PENDING;
diff --git a/kernel/irq/spurious.c b/kernel/irq/spurious.c
index 9c7e2e4c1fe7..543ea2e5ad93 100644
--- a/kernel/irq/spurious.c
+++ b/kernel/irq/spurious.c
@@ -147,11 +147,7 @@ void note_interrupt(unsigned int irq, struct irq_desc *desc,
147 if (unlikely(irqfixup)) { 147 if (unlikely(irqfixup)) {
148 /* Don't punish working computers */ 148 /* Don't punish working computers */
149 if ((irqfixup == 2 && irq == 0) || action_ret == IRQ_NONE) { 149 if ((irqfixup == 2 && irq == 0) || action_ret == IRQ_NONE) {
150 int ok; 150 int ok = misrouted_irq(irq);
151
152 spin_unlock(&desc->lock);
153 ok = misrouted_irq(irq);
154 spin_lock(&desc->lock);
155 if (action_ret == IRQ_NONE) 151 if (action_ret == IRQ_NONE)
156 desc->irqs_unhandled -= ok; 152 desc->irqs_unhandled -= ok;
157 } 153 }