All of lore.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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.