public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH] driver core: check bus->match without holding device lock(v2)
@ 2009-01-21 15:27 tom.leiming
  2009-01-21 15:59 ` Cornelia Huck
  2009-04-10 15:31 ` Andreas Schwab
  0 siblings, 2 replies; 4+ messages in thread
From: tom.leiming @ 2009-01-21 15:27 UTC (permalink / raw)
  To: kay.sievers, greg; +Cc: cornelia.huck, linux-kernel, arjan, Ming Lei

From: Ming Lei <tom.leiming@gmail.com>

This patch moves bus->match out from driver_probe_device and
does not hold device lock to check the match between a device
and a driver.

The idea has been verified by the commit 6cd495860901,
which leads to a faster boot. But the commit 6cd495860901 has
the following drawbacks: 1),only does the quick check in
the path of __driver_attach->driver_probe_device, not in other
paths; 2),for a matched device and driver, check the same match
twice. It is a waste of cpu ,especially for some drivers with long
device id table (eg. usb-storage driver).

This patch adds a helper of driver_match_device to check the match
in all paths, and testes the match only once.

Signed-off-by: Ming Lei <tom.leiming@gmail.com>
---
 drivers/base/base.h |    5 +++++
 drivers/base/bus.c  |    2 +-
 drivers/base/dd.c   |   19 +++++++------------
 3 files changed, 13 insertions(+), 13 deletions(-)

diff --git a/drivers/base/base.h b/drivers/base/base.h
index 0a5f055..e2599ba 100644
--- a/drivers/base/base.h
+++ b/drivers/base/base.h
@@ -86,6 +86,11 @@ extern void bus_remove_driver(struct device_driver *drv);
 
 extern void driver_detach(struct device_driver *drv);
 extern int driver_probe_device(struct device_driver *drv, struct device *dev);
+static inline int driver_match_device(struct device_driver *drv,
+				      struct device *dev)
+{
+	return drv->bus->match && drv->bus->match(dev, drv);
+}
 
 extern void sysdev_shutdown(void);
 extern int sysdev_suspend(pm_message_t state);
diff --git a/drivers/base/bus.c b/drivers/base/bus.c
index 83f32b8..8547b78 100644
--- a/drivers/base/bus.c
+++ b/drivers/base/bus.c
@@ -198,7 +198,7 @@ static ssize_t driver_bind(struct device_driver *drv,
 	int err = -ENODEV;
 
 	dev = bus_find_device_by_name(bus, NULL, buf);
-	if (dev && dev->driver == NULL) {
+	if (dev && dev->driver == NULL && driver_match_device(drv, dev)) {
 		if (dev->parent)	/* Needed for USB */
 			down(&dev->parent->sem);
 		down(&dev->sem);
diff --git a/drivers/base/dd.c b/drivers/base/dd.c
index 315bed8..9b721d3 100644
--- a/drivers/base/dd.c
+++ b/drivers/base/dd.c
@@ -172,14 +172,8 @@ int driver_probe_done(void)
  * @drv: driver to bind a device to
  * @dev: device to try to bind to the driver
  *
- * First, we call the bus's match function, if one present, which should
- * compare the device IDs the driver supports with the device IDs of the
- * device. Note we don't do this ourselves because we don't know the
- * format of the ID structures, nor what is to be considered a match and
- * what is not.
- *
- * This function returns 1 if a match is found, -ENODEV if the device is
- * not registered, and 0 otherwise.
+ * This function returns -ENODEV if the device is not registered,
+ * 1 if the device is bound sucessfully and 0 otherwise.
  *
  * This function must be called with @dev->sem held.  When called for a
  * USB interface, @dev->parent->sem must be held as well.
@@ -190,21 +184,22 @@ int driver_probe_device(struct device_driver *drv, struct device *dev)
 
 	if (!device_is_registered(dev))
 		return -ENODEV;
-	if (drv->bus->match && !drv->bus->match(dev, drv))
-		goto done;
 
 	pr_debug("bus: '%s': %s: matched device %s with driver %s\n",
 		 drv->bus->name, __func__, dev_name(dev), drv->name);
 
 	ret = really_probe(dev, drv);
 
-done:
 	return ret;
 }
 
 static int __device_attach(struct device_driver *drv, void *data)
 {
 	struct device *dev = data;
+
+	if (!driver_match_device(drv, dev))
+		return 0;
+
 	return driver_probe_device(drv, dev);
 }
 
@@ -257,7 +252,7 @@ static int __driver_attach(struct device *dev, void *data)
 	 * is an error.
 	 */
 
-	if (drv->bus->match && !drv->bus->match(dev, drv))
+	if (!driver_match_device(drv, dev))
 		return 0;
 
 	if (dev->parent)	/* Needed for USB */
-- 
1.6.0


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* Re: [PATCH] driver core: check bus->match without holding device lock(v2)
  2009-01-21 15:27 [PATCH] driver core: check bus->match without holding device lock(v2) tom.leiming
@ 2009-01-21 15:59 ` Cornelia Huck
  2009-04-10 15:31 ` Andreas Schwab
  1 sibling, 0 replies; 4+ messages in thread
From: Cornelia Huck @ 2009-01-21 15:59 UTC (permalink / raw)
  To: tom.leiming; +Cc: kay.sievers, greg, linux-kernel, arjan, Ming Lei

On Wed, 21 Jan 2009 23:27:47 +0800,
tom.leiming@gmail.com wrote:

> From: Ming Lei <tom.leiming@gmail.com>
> 
> This patch moves bus->match out from driver_probe_device and
> does not hold device lock to check the match between a device
> and a driver.
> 
> The idea has been verified by the commit 6cd495860901,
> which leads to a faster boot. But the commit 6cd495860901 has
> the following drawbacks: 1),only does the quick check in
> the path of __driver_attach->driver_probe_device, not in other
> paths; 2),for a matched device and driver, check the same match
> twice. It is a waste of cpu ,especially for some drivers with long
> device id table (eg. usb-storage driver).
> 
> This patch adds a helper of driver_match_device to check the match
> in all paths, and testes the match only once.
> 
> Signed-off-by: Ming Lei <tom.leiming@gmail.com>
> ---
>  drivers/base/base.h |    5 +++++
>  drivers/base/bus.c  |    2 +-
>  drivers/base/dd.c   |   19 +++++++------------
>  3 files changed, 13 insertions(+), 13 deletions(-)

The patch looks fine to me, and it seems to work well on my s390 LPAR.

Acked-by: Cornelia Huck <cornelia.huck@de.ibm.com>

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH] driver core: check bus->match without holding device lock(v2)
  2009-01-21 15:27 [PATCH] driver core: check bus->match without holding device lock(v2) tom.leiming
  2009-01-21 15:59 ` Cornelia Huck
@ 2009-04-10 15:31 ` Andreas Schwab
  2009-04-11  1:52   ` Ming Lei
  1 sibling, 1 reply; 4+ messages in thread
From: Andreas Schwab @ 2009-04-10 15:31 UTC (permalink / raw)
  To: tom.leiming; +Cc: kay.sievers, greg, cornelia.huck, linux-kernel, arjan

tom.leiming@gmail.com writes:

> +static inline int driver_match_device(struct device_driver *drv,
> +				      struct device *dev)
> +{
> +	return drv->bus->match && drv->bus->match(dev, drv);
> +}

This logic is wrong.  !(a && !b) <=> !a || b, not a && b

A bus that does not have a match function now never matches, whereas
previously it would always match.  This breaks aoa-soundbus.

Andreas.
---
driver core: Fix logic in driver_match_device

A bus that does not have a match function always matches.  This fixes
49b420a13ff9 ("driver core: check bus->match without holding device
lock").

Signed-off-by: Andreas Schwab <schwab@linux-m68k.org>
---
 drivers/base/base.h |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/base/base.h b/drivers/base/base.h
index ddc9749..087e911 100644
--- a/drivers/base/base.h
+++ b/drivers/base/base.h
@@ -115,7 +115,7 @@ extern int driver_probe_device(struct device_driver *drv, struct device *dev);
 static inline int driver_match_device(struct device_driver *drv,
 				      struct device *dev)
 {
-	return drv->bus->match && drv->bus->match(dev, drv);
+	return !drv->bus->match || drv->bus->match(dev, drv);
 }
 
 extern void sysdev_shutdown(void);

-- 
Andreas Schwab, schwab@linux-m68k.org
GPG Key fingerprint = 58CA 54C7 6D53 942B 1756  01D3 44D5 214B 8276 4ED5
"And now for something completely different."

^ permalink raw reply related	[flat|nested] 4+ messages in thread

* Re: [PATCH] driver core: check bus->match without holding device  lock(v2)
  2009-04-10 15:31 ` Andreas Schwab
@ 2009-04-11  1:52   ` Ming Lei
  0 siblings, 0 replies; 4+ messages in thread
From: Ming Lei @ 2009-04-11  1:52 UTC (permalink / raw)
  To: Andreas Schwab; +Cc: kay.sievers, greg, cornelia.huck, linux-kernel, arjan

2009/4/10 Andreas Schwab <schwab@linux-m68k.org>:
> diff --git a/drivers/base/base.h b/drivers/base/base.h
> index ddc9749..087e911 100644
> --- a/drivers/base/base.h
> +++ b/drivers/base/base.h
> @@ -115,7 +115,7 @@ extern int driver_probe_device(struct device_driver *drv, struct device *dev);
>  static inline int driver_match_device(struct device_driver *drv,
>                                      struct device *dev)
>  {
> -       return drv->bus->match && drv->bus->match(dev, drv);
> +       return !drv->bus->match || drv->bus->match(dev, drv);
>  }

A similar patch has been in greg's tree:

http://www.kernel.org/pub/linux/kernel/people/gregkh/gregkh-2.6/patches/driver-core.current/driver-core-fix-driver_match_device.patch

Thanks!

-- 
Lei Ming

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2009-04-11  1:52 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-01-21 15:27 [PATCH] driver core: check bus->match without holding device lock(v2) tom.leiming
2009-01-21 15:59 ` Cornelia Huck
2009-04-10 15:31 ` Andreas Schwab
2009-04-11  1:52   ` Ming Lei

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox