From: Arve Hjønnevåg on
2010/5/28 Alan Cox <alan(a)lxorguk.ukuu.org.uk>:
>> This is a much harder question to answer that what we need to use
>> opportunistic suspend. The question we ask is more like this: "Is all
>> important work complete?". In the simplest case these can be the same,
>
> I don't believe you can answer that question without telepathy and a
> crystal ball.
>
But we have answered this question.

> The application doesn't know because it has no idea how to balance
> conflicting resource demands or to infer the users requirements and
> wishes. Most apps will misbehave anyway.
>
> The OS doesn't know because it cannot tell what the app wants
>
> So at best you have a heuristic.
>
>> What happens if the user presses the button right before you set QoS
>> of 'user apps' to �QS_NONE?
>
> Read down a paragraph.
>
>> To me it looks like this solution would result in this sequence which
>> may ignore the button press:
>> �� � � �Button pushed
>> �� � � �Button driver sets QoS of app it wakes to QS_ABOVESUSPEND
>> �� � � �Set QoS of 'user apps' to QS_NONE
>>
>>
>> > � � � �That would I think solve the reliable wakeup case although
>> > � � � �drivers raising a QoS parameter is a bit unusual in the kernel.
>> > � � � �That would at least however be specific to a few Android drivers
>> > � � � �and maybe a tiny amount of shared driver stuff so probably not
>> > � � � �unacceptable. (wake_up_pri(&queue, priority); isn't going to
>> > � � � �kill anyone is it - especially if it usually ignores the
>> > � � � �priority argument)
>>
>> Why is "wake_up_pri(&queue, priority)" more acceptable than "suspend_block(..."?
>
> We keep it kernel side
> It expresses policy and wishes rather than enforcing a behaviour.
>
> What for example does "suspend_block" mean on a virtual machine ?
>
> I would prefer "priority" was some kind of resource constraint model
> instead but I'm just trying to think how to be absolutely minimally
> invasible at this point.
>
>> What happens if the button press happend before this line:
>> > � � � �count2 = tasks to QS_NONE | QS_NOTCHANGED
>> > � � � �Screen off
>> > � � � � � � � � � � � � � � � � � � � �Button Press
>> > � � � � � � � � � � � � � � � � � � � �task to QS_ABOVESUSPEND
>> > � � � �count = tasks that are QS_NOTCHANGED to QS_NONE
>> >
>> > � � � �if (count != count2) {
>> > � � � � � � � �Stuff happened ... rethink
>> > � � � �}
>> >
>> > That is still a bit weird and wonderful but all the logic is in the right
>> > places. The special magic remains in the Android policy code and in the
>> > kernel specifics for Android.
>> >
>> > Thoughts ?
>>
>> I don't think it works. Also, it does not seem much less invasive than
>> suspend blockers.
>
> "I don't think it works" isn't that helpful. I don't think it works
> because .. would help me a lot more.

Did you miss this:
>> What happens if the button press happend before this line:
>> > � � � �count2 = tasks to QS_NONE | QS_NOTCHANGED

As far as I can tell this is the same race I described where you just
told me to read down a paragraph.

--
Arve Hj�nnev�g
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo(a)vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
From: Alan Cox on
> > My laptop behaves in
> > that way if for example the battery is almost flat. Your suspend blocker
> > would cause me to lose all my work with a flat battery. This is another
> > example of why the application must not be the policy manager.
> >
>
> You can still force suspend when the battery gets low.

So now we need suspend blocker blockers - as I predicted.

> > In the normal case in the PC world outside of corner cases like flat
> > batteries the answer is really simple. The laptop suspend to RAM
> > on idle intervals set in the BIOS and the like are sufficient that
> > progress will have been made before it considers going back to sleep
> > again. Right now its about ten seconds in each direction plus other costs
> > (wear on LCD backlight, disc parking etc).
> >
>
> I'm not sure what you are trying to say here. Are you saying your
> laptop enters S3 from idle?

If I have an alarm set on my laptop it will wake up when the alarm goes
off. Once it has woken up it will not go back to suspend (except for
something libe a battery event) until a timeout has elapsed that began
when the laptop woke up.

This in the laptop work solves the problem of making progress. On a
laptop power budget, with laptop constraints on suspend (both physical
cycle limits of hardware and performance) this works fine.

If I suspend/resume my laptop every time I have a 30 second idle gap I
will need a new laptop much sooner than makes me happy.

I don't claim this is true for a typical mobile phone obviously.

Alan
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo(a)vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
From: Arve Hjønnevåg on
2010/5/28 Alan Cox <alan(a)lxorguk.ukuu.org.uk>:
>> > My laptop behaves in
>> > that way if for example the battery is almost flat. Your suspend blocker
>> > would cause me to lose all my work with a flat battery. This is another
>> > example of why the application must not be the policy manager.
>> >
>>
>> You can still force suspend when the battery gets low.
>
> So now we need suspend blocker blockers - as I predicted.

Forced suspend is still supported. No new API is needed if you really
want to force suspend.

>
>> > In the normal case in the PC world outside of corner cases like flat
>> > batteries the answer is really simple. The laptop suspend to RAM
>> > on idle intervals set in the BIOS and the like are sufficient that
>> > progress will have been made before it considers going back to sleep
>> > again. Right now its about ten seconds in each direction plus other costs
>> > (wear on LCD backlight, disc parking etc).
>> >
>>
>> I'm not sure what you are trying to say here. Are you saying your
>> laptop enters S3 from idle?
>
> If I have an alarm set on my laptop it will wake up when the alarm goes
> off. Once it has woken up it will not go back to suspend (except for
> something libe a battery event) until a timeout has elapsed that began
> when the laptop woke up.
>

I think you are missing the point. It works fine if the alarm caused
the wakeup, but if you had just used your system and your inactivity
timeout expired just as your alarm goes off, the alarm will not wake
the system, nor does it prevent it from suspending.

> This in the laptop work solves the problem of making progress. On a
> laptop power budget, with laptop constraints on suspend (both physical
> cycle limits of hardware and performance) this works fine.
>
> If I suspend/resume my laptop every time I have a 30 second idle gap I
> will need a new laptop much sooner than makes me happy.
>

Then don't set your inactivity timeout to 30 seconds. I don't see how
this is relevant.

> I don't claim this is true for a typical mobile phone obviously.
>
The only difference on the phone is that we have way more wakeup
events which makes the race conditions more visible. The race exist on
your laptop as well.

--
Arve Hj�nnev�g
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo(a)vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
From: Arve Hjønnevåg on
2010/5/28 Florian Mickler <florian(a)mickler.org>:
> On Fri, 28 May 2010 02:18:06 -0700
> Arve Hj�nnev�g <arve(a)android.com> wrote:
>
>> > IMO, the whole concept is defining 2 modes of operation:
>> >
>> > 1. user interacts with the device (at least one suspend block active)
>> > 2. user doesn't interact with the device (zero suspend block active)
>>
>> That is a somewhat odd way of looking at it. Yes we have two modes of
>> operation, but an active suspend blocker does not mean that the user
>> is interacting with the device. The way we use it, the "main" suspend
>> blocker is active when the user interacts with the device (controlled
>> by writing to /sys/power/state). All other suspend blockers are used
>> to prevent suspend when user space has decided that the user is not
>> interacting with the device. This includes blocking suspend in the
>> kernel on key events which means the user actually is interacting with
>> the device, even if user-space has not realized it yet. For other
>> events, like an incoming phone call, we block suspend and make some
>> noise with the hope that the user will start interacting with the
>> device.
>
> Damn. I just want to put some abstract notion around this approach to
> power saving.
>
> But one could say instead of "direct" interaction, that every time a
> suspend blocker is taken it is "on behalf of the user"?
>
> So if a suspend blocker is taken, because a download is in progress,
> it is on behalf of (direct, or indirect) user interaction.
>
> If a suspend blocker is taken, because a key-press has to trickle up to
> userspace, it is because of the user.
>
> If a call comes in, a suspend blocker is taken, because the user wants
> to receive incomming calls.
>
> So suspend blockers are always a hint to the kernel, that the action is
> "on behalf of the user" and it is therefore ok to not suspend the
> device?
>

We also use suspend blockers for work that is not visible to the user.
The battery driver on the Nexus One wakes up periodically while
charging to monitor the battery temperature and turn down the charge
current if it gets too hot.

>>
>> >
>> > In case 1. the device wants _everything_ sheduled as normal (and save
>> > maximum possible power, i.e. runtime pm with every technology available
>> > now).
>> >
>> > In case 2. we want nothing sheduled (and save maximum possible power,
>> > i.e. suspend)
>> >
>> OK.
>
> Good. I got this right at least.
>
>>
>> > And now, every application and every kernel driver annotates (on behalve
>> > of the user) if it (possibly) interacts with the user.
>> >
>>
>> Applications that interact with the user do not normally need to block
>> suspend. The user interacting with the device blocks suspend (just
>> like with your desktop screen saver). Not every kernel driver needs to
>> be annotated either, only potential wakeup events need to be
>> annotated.
>
> The applications interacting with the user rely on other parts of
> the system to block suspend then.
>
> So it is (in general) not the application which determines if the user
> interacts, but other sources (like input-drivers) and possible a
> timeout?
>

The user-space framework decides if the device is in an interactive
mode or not (on Android phones the screen is off when it is not
interactive). Input driver need to block suspend so the user-space
framework gets the event when it is not already in interactive mode.

>>
>> > (Is this really the problematic bit, that userspace is giving
>> > the kernel hints? Or is it that the hints are called "blocker"?)
>> >
>> > We can only enter mode 2, if _nothing_ (claims) to interact with the
>> > user.
>> >
>>
>> If nothing blocks suspend. The reason to block suspend does not have
>> to be direct user interaction.
>
> But couldn't you say, that the suspend blockers are always due to the
> user? Or is this too narrow? �I mean we talk about a device here. And
> the device's purpose is it to serve the user. So it might be better to
> say: suspend blockers annotate if a task is needed to fullfill the
> devices purpose?
>
I think it is more useful to say that suspend blockers annotate that
some event needs to be processed even if the device is currently not
in an interactive mode.

> It is an easy to understand concept if one says, the device suspends if
> it has nothing to do to further the cause.
>
>
> I really want to get to a well expressed definition. suspend blockers
> block suspend. Shure. Buy why?
>
>>
>> > To integrate this with the current way of doing things, i gathered it
>> > needs to be implemented as an idle-state that does the suspend()-call?
>> >
>>
>> I think it is better no not confuse this with idle. Since initiating
>> suspend will cause the system to become not-idle, I don't think is is
>> beneficial to initiate suspend from idle.
>
> I'm not shure. But then again, i'm not too familiar with the kernel. It
> sounds like it could save some duplication of effort to integrate
> suspend into the idle-framework. "Purpose-fulness" could be just
> another measure of "idle".
>

To me idle means that no threads are ready to run and no interrupts are pending.

>
>>
>> > Attributes of the idle states could be smth like this:
>> >
>> > c3
>> > � � � �cost-to-transition-to-this-state: X
>> > � � � �powersavings-per-time: Y
>> > � � � �expected time we stay in this state: relative short, there is a
>> > � � � � � � � �timer sheduled
>> > � � � �suspend-blockers: ignored
>> >
>> > suspend
>> > � � � �cost-to-transition-to-this-state: depends, how much drivers to
>> > � � � �suspend, how much processes to freeze, how much state to save
>> > � � � �powersavings-per-time: Y
>> > � � � �expected time we stay in this state: long, independent of
>> > � � � � � � � �sheduled timers
>> > � � � �suspend-blockers: must not be activated
>> >
>> >
>> > Now all transitions and opportunistic suspend could be handled by the
>> > same algorithms.
>> >
>> > Would this work?
>> >
>>
>> I'm not sure what you mean.
>
> Yeah. It's a "little bit" handwavy.
>
> But the concept I have in mind:
>
> � � � �int what_good_would_it_be_to_go_into_this_state( state )
> � � � �{
> � � � � � � � �/*
>
> � � � � � � � �cur_state = get_current_state();
> � � � � � � � �benefit = ( get_power_per_time(cur_state)
> � � � � � � � � � � � �- get_power_per_time(state) ) *
> � � � � � � � � � � � �get_expected_time_we_stay_there( state );
> � � � � � � � �cost = get_transition_cost(cur_state,state);
> � � � � � � � �return benefit-cost;
>
> � � � � � � � �*/
> � � � �}
>
> and a constraint function:
>
> � � � �bool is_this_state_possible( state )
> � � � �{
> � � � � � � � �/*
>
> � � � � � � � �ret = true;
> � � � � � � � �cur_latency_requirement = get_cur_latency_req();
> � � � � � � � �ret &= (cur_latency_requirement >=state_latency_guaranty( state ) );
> � � � � � � � �ret &= (some other QOS thingy);
>
> � � � � � � � �return ret;
> � � � � � � � �*/
> � � � �}
>
> And now, a loop would enter the state which has the biggest score and
> is possible at the time.
>
> Afaik this is already implemented for c-states in the cpu_idle drivers?
>

I don't think we can plug suspend in as a cpu idle state. 1. we want
to suspend even the cpu is not idle. 2. starting suspend will cause
the cpu to not be idle.

--
Arve Hj�nnev�g
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo(a)vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
From: Matthew Garrett on
On Fri, May 28, 2010 at 10:37:13AM +0100, Alan Cox wrote:

> The other vendors appear to be managing nicely without magic blockers. I
> conjecture therefore there are other solutions.

Actually, no. A badly behaved application will kill the N900's battery
life. Nobody else has "managed nicely" - they've just made life harder
for application developers and users, which may have something to do
with the relative levels of market adoption of Maemo and Android. I'm
not aware of any form of resource management framework in MeeGo either,
so as far as I know it'll have exactly the same problem.

--
Matthew Garrett | mjg59(a)srcf.ucam.org
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo(a)vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/