diff options
author | Sebastian Ott <sebott@linux.vnet.ibm.com> | 2011-04-12 13:05:37 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2011-04-22 20:06:29 -0400 |
commit | 8497d6a21c4b17052e868bd53a74c82b557a6c46 (patch) | |
tree | f20b4098f8811a0dc7790a26150c969e5ae2ae80 /drivers/base/dd.c | |
parent | fc2711992b8601c20b7cc078f533e55c3106fbd4 (diff) |
driver-core: fix race between device_register and driver_register
When a device is registered to a bus it will be a) added to the list
of devices of the bus and b) bind to a driver (if one matches). As a
result of a driver being registered at this bus between a) and b) this
device could already be bound to a driver. This leads to a warning
and incorrect refcounting.
To fix this add a check to device_attach to identify an already bound
device.
Signed-off-by: Sebastian Ott <sebott@linux.vnet.ibm.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/base/dd.c')
-rw-r--r-- | drivers/base/dd.c | 5 |
1 files changed, 5 insertions, 0 deletions
diff --git a/drivers/base/dd.c b/drivers/base/dd.c index da57ee9d63fe..7e9219b02796 100644 --- a/drivers/base/dd.c +++ b/drivers/base/dd.c | |||
@@ -245,6 +245,10 @@ int device_attach(struct device *dev) | |||
245 | 245 | ||
246 | device_lock(dev); | 246 | device_lock(dev); |
247 | if (dev->driver) { | 247 | if (dev->driver) { |
248 | if (klist_node_attached(&dev->p->knode_driver)) { | ||
249 | ret = 1; | ||
250 | goto out_unlock; | ||
251 | } | ||
248 | ret = device_bind_driver(dev); | 252 | ret = device_bind_driver(dev); |
249 | if (ret == 0) | 253 | if (ret == 0) |
250 | ret = 1; | 254 | ret = 1; |
@@ -257,6 +261,7 @@ int device_attach(struct device *dev) | |||
257 | ret = bus_for_each_drv(dev->bus, NULL, dev, __device_attach); | 261 | ret = bus_for_each_drv(dev->bus, NULL, dev, __device_attach); |
258 | pm_runtime_put_sync(dev); | 262 | pm_runtime_put_sync(dev); |
259 | } | 263 | } |
264 | out_unlock: | ||
260 | device_unlock(dev); | 265 | device_unlock(dev); |
261 | return ret; | 266 | return ret; |
262 | } | 267 | } |