lkml.org 
[lkml]   [2016]   [Nov]   [1]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    SubjectRe: [PATCH v2 2/2] PM / sleep: don't suspend parent when async child suspend_{noirq,late} fails
    Hi Rafael,

    On Tue, Nov 01, 2016 at 05:25:39AM +0100, Rafael J. Wysocki wrote:
    > On Thursday, October 27, 2016 09:05:34 AM Brian Norris wrote:
    > > diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c
    > > index c58563581345..eaf6b53463a5 100644
    > > --- a/drivers/base/power/main.c
    > > +++ b/drivers/base/power/main.c
    > > @@ -1040,6 +1040,9 @@ static int __device_suspend_noirq(struct device *dev, pm_message_t state, bool a
    > >
    > > dpm_wait_for_children(dev, async);
    > >
    > > + if (async_error)
    > > + goto Complete;
    > > +
    >
    > This is a second chech for async_error in this routine and is the first one
    > really needed after adding this?

    Maybe not? I confess I'm not 100% sure on all the reasons for the code
    structure as-is, but it looks like we're trying to catch pending wakeups
    early, and because that procedure utilizes 'async_error' to stash the
    -EBUSY, it seemingly makes sense to check if it's non-zero before
    overwriting it.

    But then, that's all kind of racy, since there can be multiple writers
    to that variable, no? So it can't matter *that* much if we clobber the
    error, as long as we abort somewhere.

    Anyway, maybe it's best if dpm_wait_for_children() just moves to be
    first thing in this function (after the tracepoints). That seems just as
    correct to me, and shouldn't waste any additional time suspending
    devices for a failed system suspend attempt -- as long as we're still
    catching wakeups before we suspend the current device. (That also
    incidentally matches the structure of __device_suspend() more closely.
    Why did this all get out of sync (pun unintended) when copied from the
    suspend() to the suspend_{late,noirq}() phase?)

    All in all, the short response is that I wrote the smallest patch that
    fixes the bug, AFAICT. But actually I think the above would be both
    shorter and better. I'll give that a go.

    > > if (dev->pm_domain) {
    > > info = "noirq power domain ";
    > > callback = pm_noirq_op(&dev->pm_domain->ops, state);
    > > @@ -1187,6 +1190,9 @@ static int __device_suspend_late(struct device *dev, pm_message_t state, bool as
    > >
    > > dpm_wait_for_children(dev, async);
    > >
    > > + if (async_error)
    > > + goto Complete;
    > > +
    >
    > Same question.

    Same answer :)

    Brian

    > > if (dev->pm_domain) {
    > > info = "late power domain ";
    > > callback = pm_late_early_op(&dev->pm_domain->ops, state);
    > >
    >
    > Thanks,
    > Rafael
    >

    \
     
     \ /
      Last update: 2016-11-01 06:23    [W:3.745 / U:0.008 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site