public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
From: Greg KH <greg@kroah.com>
To: linux-kernel@vger.kernel.org
Cc: Alan Stern <stern@rowland.harvard.edu>,
	Greg Kroah-Hartman <gregkh@suse.de>
Subject: [PATCH 45/47] Driver core: Fix potential deadlock in driver core
Date: Mon, 25 Sep 2006 22:38:05 -0700	[thread overview]
Message-ID: <115924922922-git-send-email-greg@kroah.com> (raw)
In-Reply-To: <1159249226922-git-send-email-greg@kroah.com>

From: Alan Stern <stern@rowland.harvard.edu>

There is a potential deadlock in the driver core.  It boils down to
the fact that bus_remove_device() calls klist_remove() instead of
klist_del(), thereby waiting until the reference count of the
klist_node in the bus's klist of devices drops to 0.  The refcount
can't reach 0 so long as a modprobe process is trying to bind a new
driver to the device being removed, by calling __driver_attach().  The
problem is that __driver_attach() tries to acquire the device's
parent's semaphore, but the caller of bus_remove_device() is quite
likely to own that semaphore already.

It isn't sufficient just to replace klist_remove() with klist_del().
Doing so runs the risk that the device would remain on the bus's klist
of devices for some time, and so could be bound to another driver even
after it was unregistered.  What's needed is a new way to distinguish
whether or not a device is registered, based on a criterion other than
whether its klist_node is linked into the bus's klist of devices.  That
way driver binding can fail when the device is unregistered, even if
it is still linked into the klist.

This patch (as782) implements the solution, by adding a new bitflag to
indiate when a struct device is registered, by testing the flag before
allowing a driver to bind a device, and by changing the definition of
the device_is_registered() inline.

Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
---
 drivers/base/bus.c     |    8 ++++++--
 drivers/base/dd.c      |    2 ++
 include/linux/device.h |    3 ++-
 3 files changed, 10 insertions(+), 3 deletions(-)

diff --git a/drivers/base/bus.c b/drivers/base/bus.c
index aa685a2..636af53 100644
--- a/drivers/base/bus.c
+++ b/drivers/base/bus.c
@@ -392,6 +392,7 @@ out:
  *	bus_attach_device - add device to bus
  *	@dev:	device tried to attach to a driver
  *
+ *	- Add device to bus's list of devices.
  *	- Try to attach to driver.
  */
 int bus_attach_device(struct device * dev)
@@ -400,11 +401,13 @@ int bus_attach_device(struct device * de
 	int ret = 0;
 
 	if (bus) {
+		dev->is_registered = 1;
 		ret = device_attach(dev);
 		if (ret >= 0) {
 			klist_add_tail(&dev->knode_bus, &bus->klist_devices);
 			ret = 0;
-		}
+		} else
+			dev->is_registered = 0;
 	}
 	return ret;
 }
@@ -425,7 +428,8 @@ void bus_remove_device(struct device * d
 		sysfs_remove_link(&dev->kobj, "bus");
 		sysfs_remove_link(&dev->bus->devices.kobj, dev->bus_id);
 		device_remove_attrs(dev->bus, dev);
-		klist_remove(&dev->knode_bus);
+		dev->is_registered = 0;
+		klist_del(&dev->knode_bus);
 		pr_debug("bus %s: remove device %s\n", dev->bus->name, dev->bus_id);
 		device_release_driver(dev);
 		put_bus(dev->bus);
diff --git a/drivers/base/dd.c b/drivers/base/dd.c
index 319a73b..b5f43c3 100644
--- a/drivers/base/dd.c
+++ b/drivers/base/dd.c
@@ -162,6 +162,8 @@ int driver_probe_device(struct device_dr
 	struct task_struct *probe_task;
 	int ret = 0;
 
+	if (!device_is_registered(dev))
+		return -ENODEV;
 	if (drv->bus->match && !drv->bus->match(dev, drv))
 		goto done;
 
diff --git a/include/linux/device.h b/include/linux/device.h
index 74246ef..662e6a1 100644
--- a/include/linux/device.h
+++ b/include/linux/device.h
@@ -329,6 +329,7 @@ struct device {
 
 	struct kobject kobj;
 	char	bus_id[BUS_ID_SIZE];	/* position on parent bus */
+	unsigned		is_registered:1;
 	struct device_attribute uevent_attr;
 	struct device_attribute *devt_attr;
 
@@ -381,7 +382,7 @@ dev_set_drvdata (struct device *dev, voi
 
 static inline int device_is_registered(struct device *dev)
 {
-	return klist_node_attached(&dev->knode_bus);
+	return dev->is_registered;
 }
 
 /*
-- 
1.4.2.1


  reply	other threads:[~2006-09-26  5:42 UTC|newest]

Thread overview: 72+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2006-09-26  5:37 [GIT PATCH] Driver Core patches for 2.6.18 Greg KH
2006-09-26  5:37 ` [PATCH 1/47] Documentation/ABI: devfs is not obsolete, but removed! Greg KH
2006-09-26  5:37   ` [PATCH 2/47] deprecate PHYSDEV* keys Greg KH
2006-09-26  5:37     ` [PATCH 3/47] class_device_create(): make fmt argument 'const char *' Greg KH
2006-09-26  5:37       ` [PATCH 4/47] device_create(): " Greg KH
2006-09-26  5:37         ` [PATCH 5/47] Driver core: add const to class_create Greg KH
2006-09-26  5:37           ` [PATCH 6/47] sysfs: Make poll behaviour consistent Greg KH
2006-09-26  5:37             ` [PATCH 7/47] Debugfs: kernel-doc fixes for debugfs Greg KH
2006-09-26  5:37               ` [PATCH 8/47] SYSFS: allow sysfs_create_link to create symlinks in the root of sysfs Greg KH
2006-09-26  5:37                 ` [PATCH 9/47] Suspend infrastructure cleanup and extension Greg KH
2006-09-26  5:37                   ` [PATCH 10/47] Suspend changes for PCI core Greg KH
2006-09-26  5:37                     ` [PATCH 11/47] make suspend quieter Greg KH
2006-09-26  5:37                       ` [PATCH 12/47] fix broken/dubious driver suspend() methods Greg KH
2006-09-26  5:37                         ` [PATCH 13/47] PM: define PM_EVENT_PRETHAW Greg KH
2006-09-26  5:37                           ` [PATCH 14/47] PM: PCI and IDE handle PM_EVENT_PRETHAW Greg KH
2006-09-26  5:37                             ` [PATCH 15/47] PM: video drivers and PM_EVENT_PRETHAW Greg KH
2006-09-26  5:37                               ` [PATCH 16/47] PM: USB HCDs use PM_EVENT_PRETHAW Greg KH
2006-09-26  5:37                                 ` [PATCH 17/47] PM: issue PM_EVENT_PRETHAW Greg KH
2006-09-26  5:37                                   ` [PATCH 18/47] updated Documentation/power/devices.txt Greg KH
2006-09-26  5:37                                     ` [PATCH 19/47] PM: update docs for writing .../power/state Greg KH
2006-09-26  5:37                                       ` [PATCH 20/47] PM: add kconfig option for deprecated .../power/state files Greg KH
2006-09-26  5:37                                         ` [PATCH 21/47] PM: schedule /sys/devices/.../power/state for removal Greg KH
2006-09-26  5:37                                           ` [PATCH 22/47] PM: no suspend_prepare() phase Greg KH
2006-09-26  5:37                                             ` [PATCH 23/47] PM: add /sys/power documentation to Documentation/ABI Greg KH
2006-09-26  5:37                                               ` [PATCH 24/47] PM: device_suspend/resume may sleep Greg KH
2006-09-26  5:37                                                 ` [PATCH 25/47] PM: platform_bus and late_suspend/early_resume Greg KH
2006-09-26  5:37                                                   ` [PATCH 26/47] Driver core: add groups support to struct device Greg KH
2006-09-26  5:37                                                     ` [PATCH 27/47] Driver core: allow devices in classes to have no parent Greg KH
2006-09-26  5:37                                                       ` [PATCH 28/47] Driver core: add ability for classes to handle devices properly Greg KH
2006-09-26  5:37                                                         ` [PATCH 29/47] Driver core: add device_rename function Greg KH
2006-09-26  5:37                                                           ` [PATCH 30/47] Driver core: create devices/virtual/ tree Greg KH
2006-09-26  5:37                                                             ` [PATCH 31/47] Class: add support for class interfaces for devices Greg KH
2006-09-26  5:37                                                               ` [PATCH 32/47] Driver core: add ability for devices to create and remove bin files Greg KH
2006-09-26  5:37                                                                 ` [PATCH 33/47] kobject: must_check fixes Greg KH
2006-09-26  5:37                                                                   ` [PATCH 34/47] sysfs_remove_bin_file: no return value, dump_stack on error Greg KH
2006-09-26  5:37                                                                     ` [PATCH 35/47] Driver core: fix comments in drivers/base/power/resume.c Greg KH
2006-09-26  5:37                                                                       ` [PATCH 36/47] Driver core: fixed add_bind_files() definition Greg KH
2006-09-26  5:37                                                                         ` [PATCH 37/47] add __must_check to device management code Greg KH
2006-09-26  5:37                                                                           ` [PATCH 38/47] add CONFIG_ENABLE_MUST_CHECK Greg KH
2006-09-26  5:37                                                                             ` [PATCH 39/47] v4l-dev2: handle __must_check Greg KH
2006-09-26  5:38                                                                               ` [PATCH 40/47] drivers/base: Platform notify needs to occur before drivers attach to the device Greg KH
2006-09-26  5:38                                                                                 ` [PATCH 41/47] drivers/base: check errors Greg KH
2006-09-26  5:38                                                                                   ` [PATCH 42/47] sysfs: add proper sysfs_init() prototype Greg KH
2006-09-26  5:38                                                                                     ` [PATCH 43/47] Driver Core: add ability for drivers to do a threaded probe Greg KH
2006-09-26  5:38                                                                                       ` [PATCH 44/47] PCI: enable driver multi-threaded probe Greg KH
2006-09-26  5:38                                                                                         ` Greg KH [this message]
2006-09-26  5:38                                                                                           ` [PATCH 46/47] Driver core: Remove unneeded routines from driver core Greg KH
2006-09-26  5:38                                                                                             ` [PATCH 47/47] Driver core: Don't call put methods while holding a spinlock Greg KH
2006-09-27 18:51                                                                                         ` [PATCH 44/47] PCI: enable driver multi-threaded probe Olaf Hering
2006-09-29 23:32                                                                                           ` Greg KH
2006-09-30  6:07                                                                                             ` Olaf Hering
2006-09-26 17:23                                                                                   ` [PATCH 41/47] drivers/base: check errors Dmitry Torokhov
2006-09-27  4:33                                                                                     ` Greg KH
2006-09-26 13:24                                                             ` [PATCH 30/47] Driver core: create devices/virtual/ tree Dmitry Torokhov
2006-09-26 13:41                                                               ` Greg KH
2006-09-26 13:51                                                                 ` Dmitry Torokhov
2006-09-26 14:26                                                                   ` Greg KH
2006-09-26 17:15                                                                     ` Dmitry Torokhov
2006-09-26 13:20                                                     ` [PATCH 26/47] Driver core: add groups support to struct device Dmitry Torokhov
2006-09-26 13:46                                                       ` Greg KH
2006-09-26 14:01                                                         ` Dmitry Torokhov
2006-09-26 14:23                                                           ` Greg KH
2006-09-26 17:10                                                             ` Dmitry Torokhov
2006-09-27 14:40                                                             ` Pavel Machek
2006-09-26 15:18                                                         ` Marcel Holtmann
2006-09-26 12:34 ` [GIT PATCH] Driver Core patches for 2.6.18 Mike Galbraith
2006-09-26 20:39   ` Greg KH
2006-09-27  8:47     ` Mike Galbraith
2006-09-27  6:58       ` Rafael J. Wysocki
2006-09-27 10:48         ` Mike Galbraith
2006-09-27 13:03           ` Mike Galbraith
2006-09-27 11:42             ` Rafael J. Wysocki

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=115924922922-git-send-email-greg@kroah.com \
    --to=greg@kroah.com \
    --cc=gregkh@suse.de \
    --cc=linux-kernel@vger.kernel.org \
    --cc=stern@rowland.harvard.edu \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox