The patch titled
driver-core-fix-bus_rescan_devices-race 2
has been added to the -mm tree. Its filename is
driver-core-fix-bus_rescan_devices-race-2.patch
Patches currently in -mm which might be from [EMAIL PROTECTED] are
driver-core-fix-bus_rescan_devices-race-2.patch
yenta-make-topic95-bridges-work-with-16bit-cards.patch
pcmcia-cs-fix-possible-missed-wakeup.patch
fix-pcmcia_request_irq-for-multifunction-card.patch
pcmcia-yenta-avoid-pci-write-posting-problem.patch
yenta-auto-tune-ene-bridges-for-cb-cards.patch
pcmcia-yenta-dont-mess-with-bridge-control-register.patch
From: Daniel Ritz <[EMAIL PROTECTED]>
bus_rescan_devices_helper() does not hold the dev->sem when it checks for
!dev->driver(). device_attach() holds the sem, but calls again
device_bind_driver() even when dev->driver is set.
What happens is that a first device_attach() call (module insertion time)
is on the way binding the device to a driver. Another thread calls
bus_rescan_devices(). Now when bus_rescan_devices_helper() checks for
dev->driver it is still NULL 'cos the the prior device_attach() is not yet
finished. But as soon as the first one releases the dev->sem the second
device_attach() tries to rebind the already bound device again.
device_bind_driver() does this blindly which leads to a corrupt
driver->klist_devices list (the device links itself, the head points to the
device). Later a call to device_release_driver() sets dev->driver to NULL
and breaks the link it has to itself on knode_driver. Rmmoding the driver
later calls driver_detach() which leads to an endless loop 'cos the list
head in klist_devices still points to the device. And since dev->driver is
NULL it's stuck with the same device forever. Boom. And rmmod hangs.
Very easy to reproduce with new-style pcmcia and a 16bit card. Just loop
modprobe <pcmcia-modules> ;cardctl eject; rmmod <card driver, pcmcia
modules>.
Easiest fix is to check if the device is already bound to a driver in
device_bind_driver(). This avoids the double binding.
Signed-off-by: Daniel Ritz <[EMAIL PROTECTED]>
Signed-off-by: Andrew Morton <[EMAIL PROTECTED]>
---
drivers/base/dd.c | 3 +++
1 files changed, 3 insertions(+)
diff -puN drivers/base/dd.c~driver-core-fix-bus_rescan_devices-race-2
drivers/base/dd.c
--- devel/drivers/base/dd.c~driver-core-fix-bus_rescan_devices-race-2
2005-08-30 12:13:53.000000000 -0700
+++ devel-akpm/drivers/base/dd.c 2005-08-30 12:13:53.000000000 -0700
@@ -40,6 +40,9 @@
*/
void device_bind_driver(struct device * dev)
{
+ if (klist_node_attached(&dev->knode_driver))
+ return;
+
pr_debug("bound device '%s' to driver '%s'\n",
dev->bus_id, dev->driver->name);
klist_add_tail(&dev->knode_driver, &dev->driver->klist_devices);
_
-
To unsubscribe from this list: send the line "unsubscribe mm-commits" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at http://vger.kernel.org/majordomo-info.html