![]() | |||||||||||||
Messages in this thread Patch in this message |
Vivek noted that many places call note_interrupt() without desc->lock being held. Since note_interrupt() which tries to unlock this lock to handle spurious interrupts accodring to http://kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=f72fa707604c015a6625e80f269506032d5430dc Looking at note_interrupt() I found that desc->lock IS required in this function but all the places that call note_interrupt() lock it after the call. One exception from this rule is __do_IRQ(). So I move spin_lock(&desc->lock); before calling note_interrupt() in all places. Signed-off-bt: Pavel Emelianov <xemul@openvz.org> --- ./kernel/irq/chip.c.noteintfix 2006-11-21 11:27:18.000000000 +0300 +++ ./kernel/irq/chip.c 2006-11-21 11:48:18.000000000 +0300 @@ -281,10 +281,11 @@ handle_simple_irq(unsigned int irq, stru 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); desc->status &= ~IRQ_INPROGRESS; out_unlock: spin_unlock(&desc->lock); @@ -330,10 +331,11 @@ handle_level_irq(unsigned int irq, struc 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); desc->status &= ~IRQ_INPROGRESS; if (!(desc->status & IRQ_DISABLED) && desc->chip->unmask) desc->chip->unmask(irq); @@ -381,10 +383,11 @@ handle_fasteoi_irq(unsigned int irq, str 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); desc->status &= ~IRQ_INPROGRESS; out: desc->chip->eoi(irq); @@ -460,10 +463,12 @@ handle_edge_irq(unsigned int irq, struct desc->status &= ~IRQ_PENDING; 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); } while ((desc->status & (IRQ_PENDING | IRQ_DISABLED)) == IRQ_PENDING); @@ -483,6 +488,7 @@ out_unlock: void fastcall handle_percpu_irq(unsigned int irq, struct irq_desc *desc) { + unsigned long flags; irqreturn_t action_ret; kstat_this_cpu.irqs[irq]++; @@ -491,8 +497,11 @@ handle_percpu_irq(unsigned int irq, stru desc->chip->ack(irq); action_ret = handle_IRQ_event(irq, desc->action); - if (!noirqdebug) + if (!noirqdebug) { + spin_lock_irqsave(&desc->lock, flags); note_interrupt(irq, desc, action_ret); + spin_unlock_irqrestore(&desc->lock, flags); + } if (desc->chip->eoi) desc->chip->eoi(irq); | ||||||||||||
| Last update: 2006-11-21 08:57 [from the cache] ©2003-2008 | |||||||||||||