lkml.org 
[lkml]   [2012]   [Jun]   [19]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patches in this message
    /
    From
    Subject[PATCH] PM: Prevent waiting forever on asynchronous suspend after abort
    Date
    __device_suspend() must always send a completion. Otherwise, parent
    devices will wait forever.

    Commit 1e2ef05b, "PM: Limit race conditions between runtime PM and
    system sleep (v2)", introduced a regression by short-circuiting the
    complete_all() for certain error cases.

    This patch fixes the bug by always signalling a completion.

    Addresses http://crosbug.com/31972

    Tested by injecting an abort via the following patch:

    diff --git a/drivers/usb/core/hcd-pci.c b/drivers/usb/core/hcd-pci.c
    index a004db3..e5a6fce 100644
    --- a/drivers/usb/core/hcd-pci.c
    +++ b/drivers/usb/core/hcd-pci.c
    @@ -21,6 +21,7 @@
    #include <linux/pci.h>
    #include <linux/usb.h>
    #include <linux/usb/hcd.h>
    +#include <linux/string.h>

    #include <asm/io.h>
    #include <asm/irq.h>
    @@ -477,6 +478,8 @@ static int resume_common(struct device *dev, int event)

    static int hcd_pci_suspend(struct device *dev)
    {
    + if (!strcmp("0000:00:1d.3", dev_name(dev)))
    + return -EBUSY;
    return suspend_common(dev, device_may_wakeup(dev));
    }

    Signed-off-by: Mandeep Singh Baines <msb@chromium.org>
    Cc: Rafael J. Wysocki <rjw@sisk.pl>
    Cc: linux-pm@vger.kernel.org
    Cc: stable@kernel.org
    Cc: Pavel Machek <pavel@ucw.cz>
    Cc: Len Brown <len.brown@intel.com>
    Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
    Cc: Kevin Hilman <khilman@ti.com>
    Cc: Alan Stern <stern@rowland.harvard.edu>
    Cc: Colin Cross <ccross@android.com>
    Cc: Sameer Nanda <snanda@chromium.org>
    Cc: Olof Johansson <olofj@chromium.org>
    ---
    drivers/base/power/main.c | 6 ++++--
    1 files changed, 4 insertions(+), 2 deletions(-)
    diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c
    index e0fb5b0..9cb845e 100644
    --- a/drivers/base/power/main.c
    +++ b/drivers/base/power/main.c
    @@ -1031,7 +1031,7 @@ static int __device_suspend(struct device *dev, pm_message_t state, bool async)
    dpm_wait_for_children(dev, async);

    if (async_error)
    - return 0;
    + goto Complete;

    pm_runtime_get_noresume(dev);
    if (pm_runtime_barrier(dev) && device_may_wakeup(dev))
    @@ -1040,7 +1040,7 @@ static int __device_suspend(struct device *dev, pm_message_t state, bool async)
    if (pm_wakeup_pending()) {
    pm_runtime_put_sync(dev);
    async_error = -EBUSY;
    - return 0;
    + goto Complete;
    }

    device_lock(dev);
    @@ -1097,6 +1097,8 @@ static int __device_suspend(struct device *dev, pm_message_t state, bool async)
    }

    device_unlock(dev);
    +
    + Complete:
    complete_all(&dev->power.completion);

    if (error) {
    --
    1.7.3.4


    \
     
     \ /
      Last update: 2012-06-20 04:41    [W:0.075 / U:33.264 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site