summaryrefslogtreecommitdiffstats
path: root/kernel/kexec.c
diff options
context:
space:
mode:
authorPavel Emelianov <xemul@openvz.org>2006-11-10 12:27:56 -0800
committerLinus Torvalds <torvalds@g5.osdl.org>2006-11-13 07:40:43 -0800
commitf72fa707604c015a6625e80f269506032d5430dc (patch)
treed7701d7a0e6fef020e78f690041486a052bc9bb3 /kernel/kexec.c
parent0130b0b32ee53dc7add773fcea984f6a26ef1da3 (diff)
downloadlinux-f72fa707604c015a6625e80f269506032d5430dc.tar.gz
linux-f72fa707604c015a6625e80f269506032d5430dc.tar.bz2
linux-f72fa707604c015a6625e80f269506032d5430dc.zip
[PATCH] Fix misrouted interrupts deadlocks
While testing kernel on machine with "irqpoll" option I've caught such a lockup: __do_IRQ() spin_lock(&desc->lock); desc->chip->ack(); /* IRQ is ACKed */ note_interrupt() misrouted_irq() handle_IRQ_event() if (...) local_irq_enable_in_hardirq(); /* interrupts are enabled from now */ ... __do_IRQ() /* same IRQ we've started from */ spin_lock(&desc->lock); /* LOCKUP */ Looking at misrouted_irq() code I've found that a potential deadlock like this can also take place: 1CPU: __do_IRQ() spin_lock(&desc->lock); /* irq = A */ misrouted_irq() for (i = 1; i < NR_IRQS; i++) { spin_lock(&desc->lock); /* irq = B */ if (desc->status & IRQ_INPROGRESS) { 2CPU: __do_IRQ() spin_lock(&desc->lock); /* irq = B */ misrouted_irq() for (i = 1; i < NR_IRQS; i++) { spin_lock(&desc->lock); /* irq = A */ if (desc->status & IRQ_INPROGRESS) { As the second lock on both CPUs is taken before checking that this irq is being handled in another processor this may cause a deadlock. This issue is only theoretical. I propose the attached patch to fix booth problems: when trying to handle misrouted IRQ active desc->lock may be unlocked. Acked-by: Ingo Molnar <mingo@redhat.com> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'kernel/kexec.c')
0 files changed, 0 insertions, 0 deletions