lkml.org 
[lkml]   [2019]   [Jan]   [28]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH AUTOSEL 4.14 070/170] driver core: Move async_synchronize_full call
    Date
    From: Alexander Duyck <alexander.h.duyck@linux.intel.com>

    [ Upstream commit c37d721c68ad88925ba0e72f6e14acb829a8c6bb ]

    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>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
    Signed-off-by: Sasha Levin <sashal@kernel.org>
    ---
    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 55fc31f6fe7f..d928cc6d0638 100644
    --- a/drivers/base/dd.c
    +++ b/drivers/base/dd.c
    @@ -813,9 +813,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)
    @@ -920,6 +917,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)) {
    --
    2.19.1
    \
     
     \ /
      Last update: 2019-01-28 17:15    [W:4.118 / U:0.352 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site