lkml.org 
[lkml]   [2010]   [Sep]   [2]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    /
    Date
    From
    SubjectRe: [PATCH] PM: Prevent waiting forever on asynchronous resume after abort
    On Wed, 1 Sep 2010, Colin Cross wrote:

    > Only wait on a parent device during resume if the parent device is
    > suspended.
    >
    > Consider three drivers, A, B, and C. The parent of A is C, and C
    > has async_suspend set. On boot, C->power.completion is initialized
    > to 0.
    >
    > During the first suspend:
    > suspend_devices_and_enter(...)
    > dpm_resume(...)
    > device_suspend(A)
    > device_suspend(B) returns error, aborts suspend
    > dpm_resume_end(...)
    > dpm_resume(...)
    > device_resume(A)
    > dpm_wait(A->parent == C)
    > wait_for_completion(C->power.completion)
    >
    > The wait_for_completion will never complete, because
    > complete_all(C->power.completion) will only be called from
    > device_suspend(C) or device_resume(C), neither of which is called
    > if suspend is aborted before C.

    This would work okay if C->power.completion had been initialized to the
    completed state during boot, right?

    > After a successful suspend->resume cycle, where B doesn't abort
    > suspend, C->power.completion is left in the completed state by the
    > call to device_resume(C), and the same call path will work if B
    > aborts suspend.
    >
    > Signed-off-by: Colin Cross <ccross@android.com>
    > ---
    > drivers/base/power/main.c | 3 ++-
    > 1 files changed, 2 insertions(+), 1 deletions(-)
    >
    > diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c
    > index cb784a0..e159910 100644
    > --- a/drivers/base/power/main.c
    > +++ b/drivers/base/power/main.c
    > @@ -526,7 +526,8 @@ static int device_resume(struct device *dev, pm_message_t state, bool async)
    > TRACE_DEVICE(dev);
    > TRACE_RESUME(0);
    >
    > - dpm_wait(dev->parent, async);
    > + if (dev->parent && dev->parent->power.status >= DPM_OFF)
    > + dpm_wait(dev->parent, async);
    > device_lock(dev);
    >
    > dev->power.status = DPM_RESUMING;

    I think it would be better to change device_pm_init() and add a
    complete_all().

    Alan Stern



    \
     
     \ /
      Last update: 2010-09-02 15:53    [W:0.022 / U:61.112 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site