Message ID | 154345153162.18040.15354788106932190561.stgit@ahduyck-desk1.amr.corp.intel.com (mailing list archive) |
---|---|
State | Superseded |
Headers | show |
Series | Add NUMA aware async_schedule calls | expand |
On Wed, Nov 28, 2018 at 04:32:11PM -0800, Alexander Duyck wrote: > Move the async_synchronize_full call out of __device_release_driver and > into driver_detach. > > The idea behind this is that the async_synchronize_full call will only > guarantee that any existing async operations are flushed. This doesn't do > anything to guarantee that a hotplug event that may occur while we are > doing the release of the driver will not be asynchronously scheduled. > > By moving this into the driver_detach path we can avoid potential deadlocks > as we aren't holding the device lock at this point and we should not have > the driver we want to flush loaded so the flush will take care of any > asynchronous events the driver we are detaching might have scheduled. > > Fixes: 765230b5f084 ("driver-core: add asynchronous probing support for drivers") > Reviewed-by: Bart Van Assche <bvanassche@acm.org> > Reviewed-by: Dan Williams <dan.j.williams@intel.com> > Signed-off-by: Alexander Duyck <alexander.h.duyck@linux.intel.com> Reviewed-by: Luis Chamberlain <mcgrof@kernel.org> Luis > --- > drivers/base/dd.c | 6 +++--- > 1 file changed, 3 insertions(+), 3 deletions(-) > > diff --git a/drivers/base/dd.c b/drivers/base/dd.c > index 689ac9dc6d81..88713f182086 100644 > --- a/drivers/base/dd.c > +++ b/drivers/base/dd.c > @@ -931,9 +931,6 @@ static void __device_release_driver(struct device *dev, struct device *parent) > > drv = dev->driver; > if (drv) { > - if (driver_allows_async_probing(drv)) > - async_synchronize_full(); > - > while (device_links_busy(dev)) { > device_unlock(dev); > if (parent) > @@ -1039,6 +1036,9 @@ void driver_detach(struct device_driver *drv) > struct device_private *dev_prv; > struct device *dev; > > + if (driver_allows_async_probing(drv)) > + async_synchronize_full(); > + > for (;;) { > spin_lock(&drv->p->klist_devices.k_lock); > if (list_empty(&drv->p->klist_devices.k_list)) { >
diff --git a/drivers/base/dd.c b/drivers/base/dd.c index 689ac9dc6d81..88713f182086 100644 --- a/drivers/base/dd.c +++ b/drivers/base/dd.c @@ -931,9 +931,6 @@ static void __device_release_driver(struct device *dev, struct device *parent) drv = dev->driver; if (drv) { - if (driver_allows_async_probing(drv)) - async_synchronize_full(); - while (device_links_busy(dev)) { device_unlock(dev); if (parent) @@ -1039,6 +1036,9 @@ void driver_detach(struct device_driver *drv) struct device_private *dev_prv; struct device *dev; + if (driver_allows_async_probing(drv)) + async_synchronize_full(); + for (;;) { spin_lock(&drv->p->klist_devices.k_lock); if (list_empty(&drv->p->klist_devices.k_list)) {