public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
From: Cornelia Huck <cornelia.huck@de.ibm.com>
To: tom.leiming@gmail.com
Cc: kay.sievers@vrfy.org, greg@kroah.com,
	linux-kernel@vger.kernel.org, arjan@linux.intel.com,
	Ming Lei <tom.leiming@gmail.com>
Subject: Re: [PATCH] driver core: check bus->match without holding device lock
Date: Tue, 20 Jan 2009 15:21:08 +0100	[thread overview]
Message-ID: <20090120152108.032405b2@gondolin> (raw)
In-Reply-To: <1232458448-4412-1-git-send-email-tom.leiming@gmail.com>

On Tue, 20 Jan 2009 21:34:08 +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).

I agree with the goal of that patch, as it essentially cleanly
seperates the quick check (->match) from the deeper probing (->probe).

> 
> 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/bus.c     |    8 +++++++-
>  drivers/base/dd.c      |   19 +++++++------------
>  include/linux/device.h |    6 ++++++
>  3 files changed, 20 insertions(+), 13 deletions(-)
> 
> diff --git a/drivers/base/bus.c b/drivers/base/bus.c
> index 83f32b8..c570d16 100644
> --- a/drivers/base/bus.c
> +++ b/drivers/base/bus.c
> @@ -199,6 +199,12 @@ static ssize_t driver_bind(struct device_driver *drv,
> 
>  	dev = bus_find_device_by_name(bus, NULL, buf);
>  	if (dev && dev->driver == NULL) {
> +
> +		if (!driver_match_device(drv, dev)) {
> +			err = 0;
> +			goto not_match;
> +		}
> +

This looks too complicated, I'd just change the if to
	if (dev && dev->driver == NULL && driver_match_device(drv,dev))

>  		if (dev->parent)	/* Needed for USB */
>  			down(&dev->parent->sem);
>  		down(&dev->sem);
> @@ -206,7 +212,7 @@ static ssize_t driver_bind(struct device_driver *drv,
>  		up(&dev->sem);
>  		if (dev->parent)
>  			up(&dev->parent->sem);
> -
> +not_match:
>  		if (err > 0) {
>  			/* success */
>  			err = count;
> diff --git a/drivers/base/dd.c b/drivers/base/dd.c
> index 315bed8..61f32db 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,
> + * and 0 otherwise.

This is incorrect, really_probe() still returns 1 if the device could
be bound.

>   *
>   * 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 */
> diff --git a/include/linux/device.h b/include/linux/device.h
> index 45e5b19..3c61315 100644
> --- a/include/linux/device.h
> +++ b/include/linux/device.h
> @@ -466,6 +466,12 @@ static inline int device_is_registered(struct device *dev)
>  	return dev->kobj.state_in_sysfs;
>  }
> 
> +static inline int driver_match_device(struct device_driver *drv,
> +				      struct device *dev)
> +{
> +	return drv->bus->match && drv->bus->match(dev, drv);
> +}
> +

This should go into drivers/base/base.h instead, as no code outside the
driver core should use it.

>  void driver_init(void);
> 
>  /*

  reply	other threads:[~2009-01-20 14:21 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2009-01-20 13:34 [PATCH] driver core: check bus->match without holding device lock tom.leiming
2009-01-20 14:21 ` Cornelia Huck [this message]
2009-01-21 15:00   ` Ming Lei
2009-03-24 23:46 ` Guennadi Liakhovetski
2009-03-25  1:15   ` Ming Lei
2009-03-25  7:29     ` Guennadi Liakhovetski
2009-03-25 10:13       ` Ming Lei
2009-03-25 10:23         ` Guennadi Liakhovetski
2009-03-25 15:15           ` Ming Lei
2009-03-26 15:46             ` Ming Lei

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=20090120152108.032405b2@gondolin \
    --to=cornelia.huck@de.ibm.com \
    --cc=arjan@linux.intel.com \
    --cc=greg@kroah.com \
    --cc=kay.sievers@vrfy.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=tom.leiming@gmail.com \
    /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