multiple interface test case
Roman Kagan
rkagan at mail.ru
Tue Apr 12 14:08:56 EDT 2005
On Tue, Apr 12, 2005 at 07:07:46PM +0200, Duncan Sands wrote:
> Hi Roman, with latest -mm it hangs here:
>
> void driver_unregister(struct device_driver * drv)
> {
> bus_remove_driver(drv);
> wait_for_completion(&drv->unloaded); <=== waits for ever
> }
>
> The completion happens when driver_release is called.
> Just how this gets called isn't too clear to me, but
> presumably it happens automagically when the driver
> refcount drops to zero. The driver refcount gets
> down to 1 only.
I'm looking at 2.6.12-rc2, and here's what I see:
in drivers/base/bus.c:
void device_release_driver(struct device * dev)
{
struct device_driver * drv = dev->driver;
if (drv) {
sysfs_remove_link(&drv->kobj, kobject_name(&dev->kobj));
sysfs_remove_link(&dev->kobj, "driver");
list_del_init(&dev->driver_list);
device_detach_shutdown(dev);
if (drv->remove)
drv->remove(dev);
dev->driver = NULL;
}
}
static void driver_detach(struct device_driver * drv)
{
struct list_head * entry, * next;
list_for_each_safe(entry, next, &drv->devices) {
struct device * dev = container_of(entry, struct device, driver_list);
device_release_driver(dev);
}
}
void bus_remove_driver(struct device_driver * drv)
{
if (drv->bus) {
driver_remove_attrs(drv->bus, drv);
down_write(&drv->bus->subsys.rwsem);
pr_debug("bus %s: remove driver %s\n", drv->bus->name, drv->name);
driver_detach(drv);
up_write(&drv->bus->subsys.rwsem);
module_remove_driver(drv);
kobject_unregister(&drv->kobj);
put_bus(drv->bus);
}
}
in kernel/module.c:
void module_remove_driver(struct device_driver *drv)
{
if (!drv)
return;
sysfs_remove_link(&drv->kobj, "module");
}
When modprobe hangs, the "driver" links in sysfs directories for the
interfaces are already gone, meaning that device_release_driver() has
been called for each interface, but the "module" link in the driver
directory is still there, so module_remove_driver() hasn't been reached
yet. Can't it be that list_for_each_safe() is not that safe against
removal of the entries inside the loop body?
Still trying,
Roman.
More information about the Usbatm
mailing list