multiple interface test case
Roman Kagan
rkagan at mail.ru
Wed Apr 13 01:11:52 EDT 2005
On Tue, Apr 12, 2005 at 11:56:22PM +0400, Roman Kagan wrote:
> To make my point clear: list_for_each_safe() seems to be safe only
> w.r.t. the deletion of the current entry. However, in our
> multi-interface scenario, we start with device_release_driver() for the
> first interface on the drv->devices list, and then (through
> drv->remove(), which calls disconnect(), which calls
> usb_driver_release_interface() for other interfaces) we call
> device_release_driver() for other interfaces and empty the drv->devices
> list, while list_for_each_safe() has already cached the (now invalid)
> next entry, and thus goes into an infinite loop.
The appended patch fixes it for me (written for 2.6.12-rc2, applied to
and run on 2.6.11). I'm not yet fluent with klists so it'll take longer
to cook up one for -mm.
Still I wonder for how long it was there, because every
usb_driver_release_interface() during rmmod should have revealed that
problem.
Cheers,
Roman.
--- linux-2.6.12-rc2/drivers/base/bus.c.orig 2005-03-18 04:34:06.000000000 +0300
+++ linux-2.6.12-rc2/drivers/base/bus.c 2005-04-13 08:45:48.000000000 +0400
@@ -405,9 +405,8 @@ void device_release_driver(struct device
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);
+ while (!list_empty(&drv->devices)) {
+ struct device * dev = container_of(drv->devices.next, struct device, driver_list);
device_release_driver(dev);
}
}
More information about the Usbatm
mailing list