From: Roman Kagan Date: Wed, 13 Apr 2005 17:40:17 +0000 (+0400) Subject: [PATCH] drivers/base/bus.c: fix iteration in driver_detach() X-Git-Tag: v2.6.12-rc4~133^2 X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=b2d84f078a8be40f5ae3b4d2ac001e2a7f45fe4f;p=linux-2.6 [PATCH] drivers/base/bus.c: fix iteration in driver_detach() With 2.6.11 and 2.6.12-rc2 (and perhaps a few versions before) usb drivers for multi-interface devices, which do usb_driver_release_interface() in their disconnect(), make rmmod hang. It turns out to be due to a bug in drivers/base/bus.c:driver_detach(), that iterates over the list of attached devices with list_for_each_safe() under an assumption that device_release_driver() only releases the current device, while it may also call device_release_driver() for other devices on the same list. The following patch fixes it. Please consider applying. Signed-off-by: Roman Kagan Signed-off-by: Greg Kroah-Hartman --- diff --git a/drivers/base/bus.c b/drivers/base/bus.c index f4fa27315f..2b3902c867 100644 --- a/drivers/base/bus.c +++ b/drivers/base/bus.c @@ -405,9 +405,8 @@ void device_release_driver(struct device * dev) 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); } }