Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1763674AbZAUP2P (ORCPT ); Wed, 21 Jan 2009 10:28:15 -0500 Received: (majordomo@vger.kernel.org) by vger.kernel.org id S1755708AbZAUP16 (ORCPT ); Wed, 21 Jan 2009 10:27:58 -0500 Received: from ti-out-0910.google.com ([209.85.142.184]:55969 "EHLO ti-out-0910.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1755676AbZAUP15 (ORCPT ); Wed, 21 Jan 2009 10:27:57 -0500 DomainKey-Signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=from:to:cc:subject:date:message-id:x-mailer; b=hu9Ft3n3UAlDcpnoWxaBfuxpAMqzRoR9LbEKDzt1F6AqkgY+mIVPxDG6Z1zVv7wuBK Ex9IvhpniKPKU27zQLBo2q/WQKKwLdxuhaMzw7DY/nMqcLfnMXCDER8M0hsBSzQ9iqeL SSfuwm5DQRsmEJin1/KqsC53k1kYFEMQzCqcM= From: tom.leiming@gmail.com To: kay.sievers@vrfy.org, greg@kroah.com Cc: cornelia.huck@de.ibm.com, linux-kernel@vger.kernel.org, arjan@linux.intel.com, Ming Lei Subject: [PATCH] driver core: check bus->match without holding device lock(v2) Date: Wed, 21 Jan 2009 23:27:47 +0800 Message-Id: <1232551667-4829-1-git-send-email-tom.leiming@gmail.com> X-Mailer: git-send-email 1.6.0 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 4046 Lines: 117 From: Ming Lei 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 --- 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 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/