Skip to content

Commit

Permalink
Driver core: fix race in __device_release_driver
Browse files Browse the repository at this point in the history
This patch (as1013) was suggested by David Woodhouse; it fixes a race
in the driver core.  If a device is unregistered at the same time as
its driver is unloaded, the driver's code pages may be unmapped while
the remove method is still running.  The calls to get_driver() and
put_driver() were intended to prevent this, but they don't work if the
driver's module count has already dropped to 0.

Instead, the patch keeps the device on the driver's list until after
the remove method has returned.  This forces the necessary
synchronization to occur.

Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
Signed-off-by: David Woodhouse <dwmw2@infradead.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
  • Loading branch information
Alan Stern authored and Greg Kroah-Hartman committed Jan 25, 2008
1 parent c8e90d8 commit ef2c517
Showing 1 changed file with 2 additions and 3 deletions.
5 changes: 2 additions & 3 deletions drivers/base/dd.c
Original file line number Diff line number Diff line change
Expand Up @@ -289,11 +289,10 @@ static void __device_release_driver(struct device * dev)
{
struct device_driver * drv;

drv = get_driver(dev->driver);
drv = dev->driver;
if (drv) {
driver_sysfs_remove(dev);
sysfs_remove_link(&dev->kobj, "driver");
klist_remove(&dev->knode_driver);

if (dev->bus)
blocking_notifier_call_chain(&dev->bus->p->bus_notifier,
Expand All @@ -306,7 +305,7 @@ static void __device_release_driver(struct device * dev)
drv->remove(dev);
devres_release_all(dev);
dev->driver = NULL;
put_driver(drv);
klist_remove(&dev->knode_driver);
}
}

Expand Down

0 comments on commit ef2c517

Please sign in to comment.