On Mon, 2018-10-15 at 08:09 -0700, Alexander Duyck wrote:
+static void __driver_attach_async_helper(void *_dev, async_cookie_t cookie)
+{
+ struct device *dev = _dev;
+
+ __device_driver_lock(dev, dev->parent);
+
+ /*
+ * If someone attempted to bind a driver either successfully or
+ * unsuccessfully before we got here we should just skip the driver
+ * probe call.
+ */
+ if (!dev->driver) {
+ struct device_driver *drv = dev_get_drvdata(dev);
+
+ if (drv)
+ driver_probe_device(drv, dev);
+ }
+
+ __device_driver_unlock(dev, dev->parent);
+
+ put_device(dev);
+
+ dev_dbg(dev, "async probe completed\n");
+}
+
static int __driver_attach(struct device *dev, void *data)
{
struct device_driver *drv = data;
@@ -945,6 +971,25 @@ static int __driver_attach(struct device *dev, void *data)
return ret;
} /* ret > 0 means positive match */
+ if (driver_allows_async_probing(drv)) {
+ /*
+ * Instead of probing the device synchronously we will
+ * probe it asynchronously to allow for more parallelism.
+ *
+ * We only take the device lock here in order to guarantee
+ * that the dev->driver and driver_data fields are protected
+ */
+ dev_dbg(dev, "scheduling asynchronous probe\n");
+ device_lock(dev);
+ if (!dev->driver) {
+ get_device(dev);
+ dev_set_drvdata(dev, drv);
+ async_schedule(__driver_attach_async_helper, dev);
+ }
+ device_unlock(dev);
+ return 0;
+ }
+
device_driver_attach(drv, dev);
What prevents that the driver pointer becomes invalid after async_schedule() has
been called and before __driver_attach_async_helper() is called? I think we need
protection against concurrent driver_unregister() and __driver_attach_async_helper()
calls. I'm not sure whether that is possible without introducing a new mutex.
Thanks,
Bart.