Pavel Emelianov f72fa70760 [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>
2006-11-13 07:40:43 -08:00
..
2006-11-03 12:27:58 -08:00
2006-10-06 08:53:39 -07:00
2006-09-11 13:32:30 -04:00
2006-10-04 08:31:21 -04:00
2006-09-29 09:18:12 -07:00
2006-10-10 15:37:23 -07:00
2006-10-03 08:03:41 -07:00
2006-10-28 11:30:54 -07:00
2006-11-13 07:40:43 -08:00
2006-11-03 12:27:58 -08:00
2006-03-26 08:57:03 -08:00
2006-09-29 09:18:15 -07:00
2006-10-02 07:57:23 -07:00
2006-07-03 15:27:04 -07:00
2006-09-30 01:47:55 +02:00
2006-11-03 12:27:58 -08:00
2006-09-29 09:18:12 -07:00
2005-04-16 15:20:36 -07:00
2006-10-01 00:39:27 -07:00
2006-04-19 16:27:18 -07:00
2006-07-10 13:24:25 -07:00