Re: Problem: Possible deadlock for 2.4 SMP systems

From: Paul Fulghum
Date: Thu Feb 16 2006 - 14:53:10 EST


Gerard Snitselaar wrote:
What appears to happen is cpu0 calls cli() in
shutdown() (drivers/char/serial.c), grabbing global_irq_lock.
Meanwhile cpu1 sets IRQ_INPROGRESS, and eventually calls
handle_IRQ_event() and spins on global_irq_lock in irq_enter().
CPU0 calls free_irq() and eventually gets to the point where
it spins while IRQ_INPROGRESS is set. Since cpu0 is holding
global_irq_lock, cpu1 can't do its work and clear IRQ_INPROGRESS.

From looking at irq.c (2.4.31) I guess that calling free_irq()
on SMP after cli() is not safe because of the race you describe.

I read somewhere that global_irq_lock is deprecated, so is there
something that the serial driver should be doing instead of cli()
and restore_flags() in shutdown()?

shutdown() seems a little backwards:
it calls free_irq(), then it disables device interrupts.

One way of handling this may be to move the code
block (the if statement after 'Free the IRQ' comment)
that calls free_irq() to after the restore_flags().

At that point, the device is no longer generating
interrupts and has been removed from the IRQ_ports
list so the ISR will not touch the device instance
and free_irq() can finish safely.

--
Paul Fulghum
Microgate Systems, Ltd.
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/