inconsistent lock state
Arjan van de Ven
arjan at fenrus.demon.nl
Sun Jul 30 19:21:44 UTC 2006
> It is filled as #200500
This looks like a USB serial deadlock:
usb_serial_generic_write() does
spin_lock(&port->lock);
without disabling interrupts
a second place it gets called is from ppp_async_push() like this:
[<f9324478>] usb_serial_generic_write+0x79/0x23d [usbserial]
[<f9322531>] serial_write+0x8a/0x99 [usbserial]
[<f933729c>] ppp_async_push+0xa7/0x3b3 [ppp_async]
[<f93375da>] ppp_async_send+0x32/0x3d [ppp_async]
[<f932f071>] ppp_channel_push+0x3a/0x94 [ppp_generic]
[<f9330395>] ppp_write+0xd5/0xe1 [ppp_generic]
[<c0471f23>] vfs_write+0xab/0x157
[<c0472568>] sys_write+0x3b/0x60
where ppp_async_push() first takes ap->xmit_lock for _bh() safeness.
now... ppp_async_push is also called from softirq context
[<f9337224>] ppp_async_push+0x2f/0x3b3 [ppp_async]
[<f9337aea>] ppp_async_process+0x48/0x5b [ppp_async]
[<c04294b4>] tasklet_action+0x65/0xca
so what can happen is this:
cpu 0 is calling usb_serial_generic_write() from user context "raw"
and takes the port->lock
cpu 1 is calling the 2nd trace above (sys_write) and hits the ppp_async_push()
which takes the ap->xmit_lock
cpu 1 then goes into usb_serial_generic_write() obviously, and tries to get the port->lock,
but this spins because cpu 0 is holding this lock
cpu 0 now hits an irq, which then triggers a softirq to happen (third trace) which
calls ppp_async_push() which tries to take the ap->xmit_lock. Which is held by cpu 1
and so cpu 0 goes to spin and wait
and.. we have deadlock.
Pete: Does this explanation sound reasonable and correct ?
More information about the devel
mailing list