Re: [RFD] Automatic suspend

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Saturday 21 February 2009, Arve Hjønnevåg wrote:
> On Fri, Feb 20, 2009 at 3:57 PM, Rafael J. Wysocki <rjw@xxxxxxx> wrote:
> > On Saturday 21 February 2009, Arve Hjønnevåg wrote:
> >> On Fri, Feb 20, 2009 at 7:56 AM, Rafael J. Wysocki <rjw@xxxxxxx> wrote:
> >> > On Friday 20 February 2009, Arve Hjønnevåg wrote:
> >> >> On Fri, Feb 20, 2009 at 2:49 AM, Rafael J. Wysocki <rjw@xxxxxxx> wrote:
> >> >> > On Friday 20 February 2009, Arve Hjønnevåg wrote:
> >> >> >> On Thu, Feb 19, 2009 at 2:08 PM, Alan Stern <stern@xxxxxxxxxxxxxxxxxxx> wrote:
> >> >> >> >> > It might have to be platform-specific.  The Android people seem to have a
> >> >> >> >> > pretty good idea of what criteria will work for them.
> >> >> >> >>
> >> >> >> >> I'd really like to know in what situations Androind is supposed to suspend
> >> >> >> >> automatically.
> >> >> >> >
> >> >> >> > It might be better to ask in what situations Android is _not_ supposed
> >> >> >> > to sleep automatically.  In other words, in what situations is a
> >> >> >> > wakelock acquired?  Since the whole system is only a phone, this
> >> >> >> > question should have a reasonably well-defined answer.
> >> >> >>
> >> >> >> On an android phone, any code that needs to run when the screen is off
> >> >> >> must hold a wakelock (directly or indirectly). In general if an
> >> >> >> application or the system is processing an event that may cause a user
> >> >> >> notification (new email, incoming phone call, alarm, etc.) it needs to
> >> >> >> prevent suspend. But, we also use wakelocks to upload stats or
> >> >> >> download system updates in the background, and for media player or
> >> >> >> (gps) data logging applications.
> >> >> >
> >> >> > All of this doesn't seem to require wakelocks acuired from kernel space.
> >> >> > What do you need those wakelocks for?
> >> >>
> >> >> Most events do not originate in user-space. Alarms start in our alarm
> >> >> driver which locks a wakelock when its timer interrupt occurs. This
> >> >> wakelock stays locked until the user-space alarm manager calls the
> >> >> driver to wait for the next alarm. I've described how input events are
> >> >> handled before. Without kernel wakelocks, if the user space power
> >> >> manager had already turned off the screen and decided to suspend right
> >> >> before a wakeup key is pressed, then that key could sit in the
> >> >> in-kernel input queue until another key is pressed. Even if the
> >> >> user-space thread read the key event before being frozen, it cannot
> >> >> abort the suspend operation that was already started.
> >> >
> >> > OK, so what about the following approach:
> >> >
> >> > * Keep the decision making logic (power manager etc.) in user space.  Reasons:
> >> >  - It may be arbitrarily complicated
> >> >  - It may include such things as s2ram quirks or hal quirks needed for some
> >> >    graphics adapters
> >>
> >> I don't using wakelocks in any different in this respect. When user
> >> space decides that it is ok for the kernel to suspend it should have
> >> performed all theses steps in both cases.
> >
> > If automatic suspend is to be started by the kernel, you have to make sure
> > that at least one wakelock is held until these steps are completed.  That may
> > be somewhat tricky in general.
> 
> That is not tricky. If your code holds a wakelock, then at least one
> wakelock is held.

I meant, if one task releases its wakelock and another one takes a wakelock,
you have to make sure there's no window between those events.  Of course,
you can have a single task holding a wakelock all the time and releasing it
when it makes sure everything is ready, but then it would act as a user space
power manager anyway.

> >> > * Have a per-process (per-task or per-thread group, but the former would be
> >> >  easier IMO) "I_do_not_want_automatic_suspend_to_occur" flag.
> >>
> >> A per-process (thread group) flag allows wakelocks to be implemented
> >> in a user space library. A per-thread flag does not. However, I don't
> >> see much benefit in tying this to a process instead of using a file
> >> descriptor.
> >
> > Using a flag would allow us to remove the window between checking the
> > wakelocks and freezing tasks (in principle a task may take a wakelock just
> > before it's frozen).
> 
> You can check if there are wakelocks held from the same spot as you
> check your flag.

That would be _much_ more complicated and much less efficient (browsing a list
vs checking a flag).  And it would require additional locking if it's to be
done in a non-racy way.

> >> > * Add a new callback, say ->acknowledge(), to the set of each driver's PM
> >> >  operations, that will be called to check if the driver has anything against
> >> >  automatic suspend (true - suspend can happen right now, false - suspend can't
> >> >  happen).
> >> >
> >> > * Introduce /sys/power/sleep that will work like /sys/power/state, but:
> >> >  - First, it will call ->acknowledge() for each driver (via bus types) to
> >> >    check if any of them wants to postpone the suspend (this will prevent tasks
> >> >    from being frozen unnecessarily if it is known in advance that the suspend
> >> >    should not happen at the moment).
> >> >  - Next, it will check the "I_do_not_want_automatic_suspend_to_occur" flag
> >> >    of each process and the suspend will be aborted if it is true for any of
> >> >    them (quite frankly, I think that should be integrated with the freezer,
> >> >    in particular the tasks that have TIF_FREEZE set shouldn't be able to set
> >> >    this flag and it should be checked in the freezer loop for every task with
> >> >    TIF_FREEZE unset).
> >> >  - Next, it will proceed with suspending just like /sys/power/state does (the
> >> >    drivers that missed the opportunity to abort the suspend by returning
> >> >    'false' from ->acknowledge() can still abort the suspend by failing their
> >> >    ->suspend() routines).
> >> >
> >> > Then, the decision making logic will be able to use /sys/power/sleep whenever
> >> > it wishes to and the kernel will be able to refuse to suspend if it's not
> >> > desirable at the moment.
> >> >
> >> > It seems to be flexible enough to me.
> >>
> >> This seems flexible enough to avoid race conditions, but it forces the
> >> user space power manager to poll when the kernel refuse suspend.
> >
> > And if the kernel is supposed to start automatic suspend, it has to monitor
> > all of the wakelocks.  IMO, it's better to allow the power manager to poll the
> > kernel if it refuses to suspend.
> 
> What is better about polling in userspace?

One kernel thread less, for example?

> >> Also, like my original wakelock patches, it breaks sleep requests through
> >> /sys/power/state when there are input events queued.
> >
> > The idea is to have both /sys/power/state and /sys/power/sleep at the same
> > time, where /sys/power/state will work just like it does right now.  Sure,
> > there must be mutual exclusion between the two, but that's a matter of
> > implementation IMO.
> 
> If you want to only prevent suspend though one interface, you have to
> also pass information to the driver about its suspend hook is being
> called so it can conditionally return -EBUSY. The wakelock interface
> requires less code in each driver.

Well, I don't think so.  Moreover, it requires you to spread wakelocks all
over the place if you don't use the timeouted ones which, let's face it, is
hardly acceptable.

Thanks,
Rafael
_______________________________________________
linux-pm mailing list
linux-pm@xxxxxxxxxxxxxxxxxxxxxxxxxx
https://lists.linux-foundation.org/mailman/listinfo/linux-pm


[Index of Archives]     [Linux ACPI]     [Netdev]     [Ethernet Bridging]     [Linux Wireless]     [CPU Freq]     [Kernel Newbies]     [Fedora Kernel]     [Security]     [Linux for Hams]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux RAID]     [Linux Admin]     [Samba]

  Powered by Linux