All of lore.kernel.org
 help / color / mirror / Atom feed
From: Jason Gunthorpe <jgg@nvidia.com>
To: Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
	kvm@vger.kernel.org, "Rafael J. Wysocki" <rafael@kernel.org>
Subject: [PATCH 03/10] driver core: Flow the return code from ->probe() through to sysfs bind
Date: Mon,  7 Jun 2021 21:55:45 -0300	[thread overview]
Message-ID: <3-v1-324b2038f212+1041f1-vfio3a_jgg@nvidia.com> (raw)
In-Reply-To: <0-v1-324b2038f212+1041f1-vfio3a_jgg@nvidia.com>

Currently really_probe() returns 1 on success and 0 if the probe() call
fails. This return code arrangement is designed to be useful for
__device_attach_driver() which is walking the device list and trying every
driver. 0 means to keep trying.

However, it is not useful for the other places that call through to
really_probe() that do actually want to see the probe() return code.

For instance bind_store() would be better to return the actual error code
from the driver's probe method, not discarding it and returning -ENODEV.

Reorganize things so that really_probe() always returns an error code on
failure and 0 on success. Move the special code for device list walking
into the walker callback __device_attach_driver() and trigger it based on
an output flag from really_probe(). Update the rest of the API surface to
return a normal -ERR or 0 on success.

Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
---
 drivers/base/bus.c |  6 +----
 drivers/base/dd.c  | 61 ++++++++++++++++++++++++++++++----------------
 2 files changed, 41 insertions(+), 26 deletions(-)

diff --git a/drivers/base/bus.c b/drivers/base/bus.c
index 36d0c654ea6124..03591f82251302 100644
--- a/drivers/base/bus.c
+++ b/drivers/base/bus.c
@@ -212,13 +212,9 @@ static ssize_t bind_store(struct device_driver *drv, const char *buf,
 	dev = bus_find_device_by_name(bus, NULL, buf);
 	if (dev && dev->driver == NULL && driver_match_device(drv, dev)) {
 		err = device_driver_attach(drv, dev);
-
-		if (err > 0) {
+		if (!err) {
 			/* success */
 			err = count;
-		} else if (err == 0) {
-			/* driver didn't accept device */
-			err = -ENODEV;
 		}
 	}
 	put_device(dev);
diff --git a/drivers/base/dd.c b/drivers/base/dd.c
index c1a92cff159873..7fb58e6219b255 100644
--- a/drivers/base/dd.c
+++ b/drivers/base/dd.c
@@ -513,7 +513,13 @@ static ssize_t state_synced_show(struct device *dev,
 }
 static DEVICE_ATTR_RO(state_synced);
 
-static int really_probe(struct device *dev, struct device_driver *drv)
+enum {
+	/* Set on output if the -ERR has come from a probe() function */
+	PROBEF_DRV_FAILED = 1 << 0,
+};
+
+static int really_probe(struct device *dev, struct device_driver *drv,
+			unsigned int *flags)
 {
 	int ret = -EPROBE_DEFER;
 	int local_trigger_count = atomic_read(&deferred_trigger_count);
@@ -574,12 +580,16 @@ static int really_probe(struct device *dev, struct device_driver *drv)
 
 	if (dev->bus->probe) {
 		ret = dev->bus->probe(dev);
-		if (ret)
+		if (ret) {
+			*flags |= PROBEF_DRV_FAILED;
 			goto probe_failed;
+		}
 	} else if (drv->probe) {
 		ret = drv->probe(dev);
-		if (ret)
+		if (ret) {
+			*flags |= PROBEF_DRV_FAILED;
 			goto probe_failed;
+		}
 	}
 
 	if (device_add_groups(dev, drv->dev_groups)) {
@@ -621,7 +631,6 @@ static int really_probe(struct device *dev, struct device_driver *drv)
 		dev->pm_domain->sync(dev);
 
 	driver_bound(dev);
-	ret = 1;
 	pr_debug("bus: '%s': %s: bound device %s to driver %s\n",
 		 drv->bus->name, __func__, dev_name(dev), drv->name);
 	goto done;
@@ -656,7 +665,7 @@ static int really_probe(struct device *dev, struct device_driver *drv)
 		/* Driver requested deferred probing */
 		dev_dbg(dev, "Driver %s requests probe deferral\n", drv->name);
 		driver_deferred_probe_add_trigger(dev, local_trigger_count);
-		goto done;
+		break;
 	case -ENODEV:
 	case -ENXIO:
 		pr_debug("%s: probe of %s rejects match %d\n",
@@ -667,11 +676,6 @@ static int really_probe(struct device *dev, struct device_driver *drv)
 		pr_warn("%s: probe of %s failed with error %d\n",
 			drv->name, dev_name(dev), ret);
 	}
-	/*
-	 * Ignore errors returned by ->probe so that the next driver can try
-	 * its luck.
-	 */
-	ret = 0;
 done:
 	atomic_dec(&probe_count);
 	wake_up_all(&probe_waitqueue);
@@ -681,13 +685,14 @@ static int really_probe(struct device *dev, struct device_driver *drv)
 /*
  * For initcall_debug, show the driver probe time.
  */
-static int really_probe_debug(struct device *dev, struct device_driver *drv)
+static int really_probe_debug(struct device *dev, struct device_driver *drv,
+			      unsigned int *flags)
 {
 	ktime_t calltime, rettime;
 	int ret;
 
 	calltime = ktime_get();
-	ret = really_probe(dev, drv);
+	ret = really_probe(dev, drv, flags);
 	rettime = ktime_get();
 	pr_debug("probe of %s returned %d after %lld usecs\n",
 		 dev_name(dev), ret, ktime_us_delta(rettime, calltime));
@@ -732,17 +737,18 @@ EXPORT_SYMBOL_GPL(wait_for_device_probe);
  * driver_probe_device - attempt to bind device & driver together
  * @drv: driver to bind a device to
  * @dev: device to try to bind to the driver
+ * @flags: PROBEF flags input/output
  *
  * This function returns -ENODEV if the device is not registered, -EBUSY if it
- * already has a driver, and 1 if the device is bound successfully and 0
- * otherwise.
+ * already has a driver,  and 0 if the device is bound successfully.
  *
  * This function must be called with @dev lock held.  When called for a
  * USB interface, @dev->parent lock must be held as well.
  *
  * If the device has a parent, runtime-resume the parent before driver probing.
  */
-static int driver_probe_device(struct device_driver *drv, struct device *dev)
+static int driver_probe_device(struct device_driver *drv, struct device *dev,
+			       unsigned int *flags)
 {
 	int ret = 0;
 
@@ -761,9 +767,9 @@ static int driver_probe_device(struct device_driver *drv, struct device *dev)
 
 	pm_runtime_barrier(dev);
 	if (initcall_debug)
-		ret = really_probe_debug(dev, drv);
+		ret = really_probe_debug(dev, drv, flags);
 	else
-		ret = really_probe(dev, drv);
+		ret = really_probe(dev, drv, flags);
 	pm_request_idle(dev);
 
 	if (dev->parent)
@@ -847,6 +853,7 @@ static int __device_attach_driver(struct device_driver *drv, void *_data)
 	struct device_attach_data *data = _data;
 	struct device *dev = data->dev;
 	bool async_allowed;
+	int flags = 0;
 	int ret;
 
 	ret = driver_match_device(drv, dev);
@@ -870,7 +877,17 @@ static int __device_attach_driver(struct device_driver *drv, void *_data)
 	if (data->check_async && async_allowed != data->want_async)
 		return 0;
 
-	return driver_probe_device(drv, dev);
+	ret = driver_probe_device(drv, dev, &flags);
+	if (ret) {
+		/*
+		 * Ignore errors returned by ->probe so that the next driver can
+		 * try its luck.
+		 */
+		if (flags & PROBEF_DRV_FAILED)
+			return 0;
+		return ret;
+	}
+	return 1;
 }
 
 static void __device_attach_async_helper(void *_dev, async_cookie_t cookie)
@@ -1026,10 +1043,11 @@ static void __device_driver_unlock(struct device *dev, struct device *parent)
  * @dev: Device to attach it to
  *
  * Manually attach driver to a device. Will acquire both @dev lock and
- * @dev->parent lock if needed.
+ * @dev->parent lock if needed. Returns 0 on success, -ERR on failure.
  */
 int device_driver_attach(struct device_driver *drv, struct device *dev)
 {
+	unsigned int flags = 0;
 	int ret = 0;
 
 	__device_driver_lock(dev, dev->parent);
@@ -1039,7 +1057,7 @@ int device_driver_attach(struct device_driver *drv, struct device *dev)
 	 * just skip the driver probe call.
 	 */
 	if (!dev->driver)
-		ret = driver_probe_device(drv, dev);
+		ret = driver_probe_device(drv, dev, &flags);
 
 	__device_driver_unlock(dev, dev->parent);
 
@@ -1050,11 +1068,12 @@ static void __driver_attach_async_helper(void *_dev, async_cookie_t cookie)
 {
 	struct device *dev = _dev;
 	struct device_driver *drv;
+	unsigned int flags = 0;
 	int ret;
 
 	__device_driver_lock(dev, dev->parent);
 	drv = dev->p->async_driver;
-	ret = driver_probe_device(drv, dev);
+	ret = driver_probe_device(drv, dev, &flags);
 	__device_driver_unlock(dev, dev->parent);
 
 	dev_dbg(dev, "driver %s async attach completed: %d\n", drv->name, ret);
-- 
2.31.1


  parent reply	other threads:[~2021-06-08  0:55 UTC|newest]

Thread overview: 55+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-06-08  0:55 [PATCH 00/10] Allow mdev drivers to directly create the vfio_device Jason Gunthorpe
2021-06-08  0:55 ` [Intel-gfx] " Jason Gunthorpe
2021-06-08  0:55 ` [PATCH 01/10] driver core: Do not continue searching for drivers if deferred probe is used Jason Gunthorpe
2021-06-08  5:51   ` Christoph Hellwig
2021-06-08  6:44   ` Greg Kroah-Hartman
2021-06-08 12:16     ` Jason Gunthorpe
2021-06-08 13:13       ` Greg Kroah-Hartman
2021-06-08 13:53         ` Jason Gunthorpe
2021-06-08  7:35   ` Greg Kroah-Hartman
2021-06-08 12:17     ` Jason Gunthorpe
2021-06-08  0:55 ` [PATCH 02/10] driver core: Pull required checks into driver_probe_device() Jason Gunthorpe
2021-06-08  5:59   ` Christoph Hellwig
2021-06-08 12:21     ` Jason Gunthorpe
2021-06-08  0:55 ` Jason Gunthorpe [this message]
2021-06-08  6:07   ` [PATCH 03/10] driver core: Flow the return code from ->probe() through to sysfs bind Christoph Hellwig
2021-06-08 23:53     ` Jason Gunthorpe
2021-06-08  6:47   ` Greg Kroah-Hartman
2021-06-08 12:30     ` Jason Gunthorpe
2021-06-08 13:16       ` Greg Kroah-Hartman
2021-06-08 14:03         ` Jason Gunthorpe
2021-06-08  0:55 ` [PATCH 04/10] driver core: Don't return EPROBE_DEFER to userspace during " Jason Gunthorpe
2021-06-08  6:14   ` Christoph Hellwig
2021-06-08  7:37   ` Greg Kroah-Hartman
2021-06-08  0:55 ` [PATCH 05/10] driver core: Export device_driver_attach() Jason Gunthorpe
2021-06-08  6:19   ` Christoph Hellwig
2021-06-08 12:33     ` Jason Gunthorpe
2021-06-08  0:55 ` [PATCH 06/10] vfio/mdev: Remove CONFIG_VFIO_MDEV_DEVICE Jason Gunthorpe
2021-06-08  0:55   ` [Intel-gfx] " Jason Gunthorpe
2021-06-08  6:20   ` Christoph Hellwig
2021-06-08  6:20     ` [Intel-gfx] " Christoph Hellwig
2021-06-11 12:40   ` Cornelia Huck
2021-06-11 12:40     ` [Intel-gfx] " Cornelia Huck
2021-06-14 12:35     ` Jason Gunthorpe
2021-06-14 12:35       ` [Intel-gfx] " Jason Gunthorpe
2021-06-14 12:35       ` Jason Gunthorpe
2021-06-08  0:55 ` [PATCH 07/10] vfio/mdev: Allow the mdev_parent_ops to specify the device driver to bind Jason Gunthorpe
2021-06-08  6:21   ` Christoph Hellwig
2021-06-08  0:55 ` [PATCH 08/10] vfio/mtty: Convert to use vfio_register_group_dev() Jason Gunthorpe
2021-06-08  0:55 ` [PATCH 09/10] vfio/mdpy: " Jason Gunthorpe
2021-06-08  0:55 ` [PATCH 10/10] vfio/mbochs: " Jason Gunthorpe
2021-06-08  6:22 ` [PATCH 00/10] Allow mdev drivers to directly create the vfio_device Christoph Hellwig
2021-06-08  6:22   ` [Intel-gfx] " Christoph Hellwig
2021-06-14 14:34 ` Kirti Wankhede
2021-06-14 14:34   ` [Intel-gfx] " Kirti Wankhede
2021-06-14 14:34   ` Kirti Wankhede
2021-06-14 14:36   ` Jason Gunthorpe
2021-06-14 14:36     ` [Intel-gfx] " Jason Gunthorpe
2021-06-14 14:36     ` Jason Gunthorpe
2021-06-14 15:08 Allow mdev drivers to directly create the vfio_device (v2 / alternative) Christoph Hellwig
2021-06-14 15:08 ` [PATCH 03/10] driver core: Flow the return code from ->probe() through to sysfs bind Christoph Hellwig
2021-06-15  5:18   ` Greg Kroah-Hartman
2021-06-15  5:18     ` Greg Kroah-Hartman
2021-06-15 10:31   ` Cornelia Huck
2021-06-15 10:31     ` Cornelia Huck
2021-06-15 13:35 Allow mdev drivers to directly create the vfio_device (v3) Christoph Hellwig
2021-06-15 13:35 ` [PATCH 03/10] driver core: Flow the return code from ->probe() through to sysfs bind Christoph Hellwig
2021-06-17 14:22 Allow mdev drivers to directly create the vfio_device (v4) Christoph Hellwig
2021-06-17 14:22 ` [PATCH 03/10] driver core: Flow the return code from ->probe() through to sysfs bind Christoph Hellwig

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=3-v1-324b2038f212+1041f1-vfio3a_jgg@nvidia.com \
    --to=jgg@nvidia.com \
    --cc=gregkh@linuxfoundation.org \
    --cc=kvm@vger.kernel.org \
    --cc=rafael@kernel.org \
    --subject='Re: [PATCH 03/10] driver core: Flow the return code from ->probe() through to sysfs bind' \
    /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

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.