deadlock between g_event and a thread on removing a device.
Kohji Okuno
okuno.kohji at jp.panasonic.com
Fri Jan 18 05:45:49 UTC 2013
Hi,
When I removed a device (ex. /dev/da0), I have encounterd a
dead-lock between ``g_event'' thread and a thread that is opening
device file (I call this thread as A).
Would you refer the following?
When the device is removed between dev_refthread() and g_dev_open(),
thread A incremented dev->si_threadcount, but can't acquire
topology_lock.
On the other hand, g_event is waiting to set dev->si_threadcount to 0
with topology_lock.
Regards,
Kohji Okuno
<<< Thread A >>>
...
devfs_open()
{
...
dsw = dev_refthread(dev, &ref); <= increment dev->si_threadcount
...
error = dsw->d_open(...); <= call g_dev_open()
...
dev_relthread(dev, ref); <= decrement dev->si_threadcount
}
g_dev_open()
{
...
g_topology_lock(); <= Thread A couldn't acquire
... topology_lock.
}
<<< g_event >>>
g_run_events()
{
...
g_topology_lock(); <= g_event acuired topology_lock here.
...
one_event()
...
}
one_event()
g_orphan_register()
g_dev_orphan()
destroy_dev()
destroy_dev()
destroy_devl()
{
...
while (dev->si_threadcount != 0) { <= this count was incremented by Thread A
/* Use unique dummy wait ident */
msleep(&csw, &devmtx, PRIBIO, "devdrn", hz / 10);
}
...
}
More information about the freebsd-current
mailing list