Re: [PATCH v2 3/7] drivers/base: Probe devices concurrently if requested by the driver

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On 10/17/2018 5:54 PM, Dan Williams wrote:
On Wed, Oct 17, 2018 at 4:41 PM Bart Van Assche <bvanassche@xxxxxxx> wrote:

Instead of probing devices sequentially in the PROBE_PREFER_ASYNCHRONOUS
mode, scan devices concurrently. This helps when the wall clock time for
a single probe is significantly above the CPU time needed for a single
probe, e.g. when scanning SCSI LUNs over a storage network.

Alex had a similar patch here [1] that I don't think has been accepted
yet, in any event some collaboration is needed:

[1]: https://lkml.org/lkml/2018/9/27/14

The patch set referenced is a little out of date. The latest set is:
https://lore.kernel.org/lkml/20181015150305.29520.86363.stgit@localhost.localdomain/

I'm also not quite sure what the point of this patch is. I don't think it is doing what it says it is doing. From what I can tell it is just allowing the driver init code to ignore if the driver wants to be probed asynchronously or not. Further comments inline below.



Cc: Lee Duncan <lduncan@xxxxxxxx>
Cc: Hannes Reinecke <hare@xxxxxxxx>
Cc: Luis Chamberlain <mcgrof@xxxxxxxxxx>
Cc: Johannes Thumshirn <jthumshirn@xxxxxxx>
Cc: Christoph Hellwig <hch@xxxxxx>
Cc: Greg Kroah-Hartman <gregkh@xxxxxxxxxxxxxxxxxxx>
Cc: Dan Williams <dan.j.williams@xxxxxxxxx>
Signed-off-by: Bart Van Assche <bvanassche@xxxxxxx>
---
  drivers/base/bus.c |  3 +--
  drivers/base/dd.c  | 49 ++++++++++++++++++++++++++++++++++++++++++++++
  2 files changed, 50 insertions(+), 2 deletions(-)

diff --git a/drivers/base/bus.c b/drivers/base/bus.c
index 8bfd27ec73d6..18ca1178821f 100644
--- a/drivers/base/bus.c
+++ b/drivers/base/bus.c
@@ -696,8 +696,7 @@ int bus_add_driver(struct device_driver *drv)

  out_unregister:
         kobject_put(&priv->kobj);
-       /* drv->p is freed in driver_release()  */
-       drv->p = NULL;
+
  out_put_bus:
         bus_put(bus);
         return error;
diff --git a/drivers/base/dd.c b/drivers/base/dd.c
index 033382421351..f8d645aa09be 100644
--- a/drivers/base/dd.c
+++ b/drivers/base/dd.c
@@ -27,6 +27,7 @@
  #include <linux/async.h>
  #include <linux/pm_runtime.h>
  #include <linux/pinctrl/devinfo.h>
+#include <linux/slab.h>

  #include "base.h"
  #include "power/power.h"
@@ -691,6 +692,49 @@ int driver_probe_device(struct device_driver *drv, struct device *dev)
         return ret;
  }

+struct driver_and_dev {
+       struct device_driver    *drv;
+       struct device           *dev;
+};
+
+static void __driver_probe_device_async(void *data, async_cookie_t cookie)
+{
+       struct driver_and_dev *dd = data;
+       struct device_driver *drv = dd->drv;
+       struct device *dev = dd->dev;
+
+       device_lock(dev);
+       driver_probe_device(drv, dev);
+       device_unlock(dev);
+       kobject_put(&drv->p->kobj);
+       module_put(drv->owner);
+       kfree(dd);
+}
+
+static void driver_probe_device_async(struct device_driver *drv,
+                                     struct device *dev)
+{
+       struct driver_and_dev *dd;
+
+       if (!try_module_get(drv->owner))
+               return;
+       dd = kmalloc(sizeof(*dd), GFP_KERNEL);
+       if (!dd) {
+               /* If out of memory, scan synchronously. */
+               device_lock(dev);
+               driver_probe_device(drv, dev);
+               device_unlock(dev);
+               module_put(drv->owner);
+               return;
+       }
+       *dd = (struct driver_and_dev){
+               .drv = drv,
+               .dev = dev,
+       };
+       kobject_get(&drv->p->kobj);
+       async_schedule(__driver_probe_device_async, dd);
+}
+

So this piece is similar to what I had, but the functionality is being used in a completely different spot. I'm not entirely convinced this isn't redundant.

  bool driver_allows_async_probing(struct device_driver *drv)
  {
         switch (drv->probe_type) {
@@ -777,6 +821,11 @@ static int __device_attach_driver(struct device_driver *drv, void *_data)
         if (data->check_async && async_allowed != data->want_async)
                 return 0;

+       if (data->check_async) {
+               driver_probe_device_async(drv, dev);
+               return 0;
+       }
+

So this code path assumes the driver is already loaded before the device is added, and from what I can tell it looks like it is forcing everything to asynchronously probe isn't it? Wasn't that the purpose of the async_allowed != data->want_async check?

Also this seems redundant since the return 0 case here is supposed to have us attach the device asynchronously. So it seems like we are just adding another layer of aysnc init. It seems like the most direct way of doing this would be to just force data->want_async to always be true by passing that instead of false in device_attach?

         return driver_probe_device(drv, dev);
  }

--
2.19.1.568.g152ad8e336-goog




[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [SCSI Target Devel]     [Linux SCSI Target Infrastructure]     [Kernel Newbies]     [IDE]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux ATA RAID]     [Linux IIO]     [Samba]     [Device Mapper]

  Powered by Linux