Android vs. Maemo power management: static vs. dynamic

Some of you might have heard about Google’s Android team proposal to introduce wakelocks (aka suspend-blockers) to the Linux kernel. While there was a real issue being solved in the kernel side, the benefits on the user-space side were dubious at best, and after a huge discussion, they finally didn’t get in.

During this discussions the dynamic and static power management were described and discussed at length, and there was a bit of talk about Maemo(MeeGo) vs Android approaches to power management, but there was so much more than that.

Some people have problems with the battery on Android devices, for some people it’s just fine, some people have problems with the Maemo, other don’t, so in general; your mileage might vary. But given the extremely different approaches, it’s easy to see in which cases you would have better luck with Maemo, and in which with Android–Although I do think it’s obvious which approach is superior, but I am biased.

An interesting achievement was shared by Thiago Maciera, who managed to get ‘5 days and a couple of minutes‘ out of the Nokia N9 while traveling, and actually using it–and let’s remember this is a 1450 mAh battery. Some Android users might have trouble believing this, but hopefully this blog post would explain what’s going on.

So lets go ahead and explore the two approaches.

Dynamic Power Management

Perhaps the simplest way to imagine dynamic power management, is the gears of a manual transmission car. You go up and down depending on how much power does the system actually needs.

In some hardware, such as OMAP chips, it’s possible to have quite a lot of fine control on the power states of quite a lot of devices, plus different operating power points on the different cores. For example, it might be possible to have some devices, such as the display on, and active, some other devices partially off, like speaker, and other completely off, like USB. And based on the status of the whole system, whole blocks can be powered off, other with low voltage levels, etc.

Linux has a framework to deal properly with this kind of hardware, the runtime power management, that originally came from the embedded world, and a lot from OMAP development, but is now available to everyone.

The idea is very simple; devices should sleep as much as possible. This means that if you have a sound device that needs chunks of 100ms, and the system is not doing anything else but playing sound, then most of the devices go to sleep, even the CPU, and the CPU is only waken up when it needs to write data for the audio device. Even better is to configure the sound device for chunks of 1 second, so the system can sleep even more.

Obviously, some co-operation between kernel and user-space is needed. Say, if you have an instant messenger program that needs to do work every minute, and a mail program that is configured to check mail every 10 minutes, you would want them to do work at the same time when they align at every 10 minutes. This is sometimes called IP heartbeat; the system wakes up for a beat, and then immediately goes back to sleep. And there are kernel facilities as well, such as range timers.

All this is possible thanks to very small latencies required for devices to go to sleep and wakeup, and have intermediary modes (e.g. on, inactive, retention, off), so, for example a device might be able to go to inactive mode in 1ms, retention in 2ms, and off in 5ms (totally invented numbers). Again, the more sleep, the better. Obviously, this is impossible on x86 chips, which have huge latencies–at least right now, and it’s something Intel is probably trying to improve effusively. All these latencies are known by the runtime pm framework in the kernel, and based on that it and the usage, it figures out what is the lowest power state possible without breaking things.

Note I’m not a power management expert, but you cant watch a colleague of mine explain the OMAP 3 power-managment on this video:

Advanced Power Management for OMAP3

And there’s plenty of more resources.

Update: That was the wrong link, here are the resources.

Static Power Management

Static power management has two modes: on and off. That’s it.

OK, that’s not exactly the case in general, but it is in the Android context; the system is either suspended, or active, and it’s easy to know in which mode you are; if the screen is on, it’s active, and if it’s off; it’ is suspended (ideally).

There’s really not much more than that. The complexity comes from the problem of when to suspend; you might have turned off the display, but there might be a system service that still needs to do work, so this service grabs a suspend blocker which, as the name suggests, prevents the system from suspending (until the lock is released). This introduces a problem; a rouge program might grab a ‘suspend blocker’ and never release it, which means your phone will never suspend, and thus the battery would drain rather quickly. So, some security mechanisms are introduced to grant permissions selectively to use suspend blockers.

And moreover, Android developers found race conditions in the suspend sequences in certain situations that were rather nasty (e.g. the system tries to suspend at the same time the user clicks a button, and the system never wakes up again), and these were acknowledged as real issues that would happen on all systems (including PC’s and servers, albeit rarely, because they don’t suspend so often), and got fixed (or at least they tried).

Versus

First of all, it’s important to know that if you have dynamic pm working perfectly, you reach exactly the same voltage usage than static pm, so in ideal cases they both behave exactly the same.

The problem is that it’s really hard for dynamic pm to reach that ideal case, in reality systems are able to sleep for certain periods of time, after which they are woken up, often times unnecessarily, and as I already explained; that’s not good. So the goal of a dynamic pm system is to increase those periods of time as much as possible, thus maximizing battery life. But there’s a point of diminished returns (read this or this for expert explanations), so, if the system manages to sleep 1s in average, there’s really not much more to gain if it sleeps 2s, or even 10s. These goals were quite difficult to achieve in the past (not these, I invented those numbers), but not so much any more thanks to several mechanisms that have been introduced and implemented through the years. So it’s fair to say that the sweet spot of dynamic pm has been achieved.

This means that today a system that has been fine-tuned for dynamic pm can reach reach a decent battery life compared to one that uses static pm in most circumstances. But for some use-cases, say, you leave your phone on your desk and you don’t use it at all, static pm would allow it to stay alive for weeks, or even months, while dynamic pm can’t possibly achieve that any time soon. Hopefully you would agree, that nobody cares about those use-cases were you are not actually using the device.

And of course, you only need one application behaving badly and waking up the system constantly, and the battery life is screwed. So in essence, dynamic pm is hard to achieve.

Android developers argued that was one of the main reasons to go for static pm; it’s easier to achieve, specially if you want to support a lot of third party applications (Android Market) without compromising battery life. While this makes sense, I wasn’t convinced by this argument; you still can have one application that is behaving badly (grabbing suspend blockers the whole time), and while permissions should help, the application might still request the permission, and the user grant it (who reads incomprehensible warnings before clicking ‘Yes’ anyway?).

So, both can get screwed by bad apps (although it’s likely that it’s harder in the static pm case, albeit not that much).

But actually, you can have both static and dynamic power management, and in fact, Android does. But that doesn’t mean Android automatically wins, as I explained, the system needs to be fine-tuned for dynamic pm, and that has never been a focus of Android (there’s no API’s or frameworks for that, etc.). So, for example, a Nokia N9 phone might be able to sleep 1s in average, while an Android phone 100ms (when not suspended). This means when you are actually using the device (the screen is on), chances are, a system fine-tuned for dynamic pm (Nokia N9) would consume less battery, than an Android device.

That is the main difference between the two. tl;dr: dynamic pm is better for active usage.

So, if Android developers want to improve the battery usage while on active usage (which I assume is what the users want), they need to fine-tune the system for dynamic pm, and thus sleep as much as possible, hopefully reaching the sweet spot. But wait a second… If Android is using dynamic pm anyway, and they tune the system to the point of diminishing returns; there is not need for static pm. Right? Well, that’s my thinking, but I didn’t manage to make Android developers realize that in the discussion.

Plus, there’s a bunch of other reasons while static pm is not palatable for non-Android systems (aka. typical Linux systems), but I won’t go into those details.

Nokia’s bet was on dynamic, Google’s bet was on static, and in the end we agreed to disagree, but I think it’s clear from the outcome in real-world situations who was right–N9 users experiencing more than one day of normal usage, and even more than two. Sadly, only Nokia N9 users would manage to experience dynamic pm in full glory (at the moment).

Upstream

But not all is lost, and this in my opinion is the most important aspect. Dynamic pm lives on the Linux kernel mainline through the runtime power management API. This is not a Nokia invention that will die with the Nokia N9; it’s a collaborative effort where Nokia, TI, and other companies worked together, and now not only benefits OMAP, but other embedded chips, and even non-embedded ones. Being upstream means it’s good, and it has been blessed by many parties, and has gone through many iterations, and finally it probably doesn’t look like the original OMAP SRF code at all. Sooner or later your phone (if you don’t have an N9) will benefit from this effort, and it might even be an Android phone, your netbook (if not already benefiting in some way), and even your PC.

Android’s suspend blockers are not upstream, and it’s quite unlikely that they will ever be, or that you would see them used in any system other than Android, and there’s good reasons for that. Matthew Garrett did an excellent job of summarizing what went wrong with the story of suspend blockers on his presentation ‘Android/Linux kernel: Lessons learned’, but unfortunately the Linux foundation seems to be doing a poor job of providing those videos (I cannot watch them any more, even though I registered, and they haven’t been helpful through email conversations).

Update: I managed to get the video from the Linux Foundation and pushed it to YouTube:

Here is part of the discussion on LKML, if you want to read it for some strange reason. WARNING; it’s huge.

Advertisement

10 Responses to Android vs. Maemo power management: static vs. dynamic

  1. Brian Swetland says:

    Android power management is highly dynamic. Devices are powered down when not in use, whether or not the screen is on. CPUs are parked in the lowest possible power states when idle (including full powerdown if the architecture allows for it).

    Android *further* shifts into full suspend which allows even lower power states (depending on architecture, kernel thread activity,e tc), whenever possible. Wakelocks allow us to know when it’s safe to go into that lowest power state, achieving additional power savings.

    In short, it’s easy to get confused by the names of things. It’d be interesting to look at power consumption graphs measured at the battery for comparable workloads on different architectures (that’s how we look at overall power use).

  2. FelipeC says:

    +Brian Swetland

    Nice to see you here. Yes, as I said, Android does use dynamic pm, which is part of Linux upstream, and yes, devices power down selectively, thanks to all the kernel infrastructure.

    The key is, as you said; “when not in use”. So, the trick is to wake them up as less as possible, and Android API’s don’t seem to do anything to try to achieve that, like IP heartbeat, or ranged timers.

    Android *further* shifts into full suspend which allows even lower power states (depending on architecture, kernel thread activity,e tc)

    In the huge discussion in LKML it was agreed that there’s no difference between suspend and idle; they both drive the system to exactly the same voltage usage. This, of course, on the relevant architectures (e.g. OMAP and others, not x86).

    In short, it’s easy to get confused by the names of things.

    The names of things don’t matter, both suspend and idle mechanisms do exactly the same in the end. You participated in that discussion, so you should know that. I can dig down the exact comments from kernel experts where this was agreed by everyone if you want.

    It’d be interesting to look at power consumption graphs measured at the battery for comparable workloads on different architectures (that’s how we look at overall power use).

    You mean when the screen is off, and thus static pm enters into the picture. When the screen is on, the system is not suspended, and thus only dynamic pm is active, and thus the system that has been better fine-tuned for dynamic pm would perform better.

  3. javispedro says:

    Great article.

    Ignoring that I don’t think “opportunistic suspend” is the panacea to all the power management problems that plague this world, I just don’t see why the Android folks need the userspace wakelocks interface.

    All the pieces required to implement a fully-userspace ‘suspendd’ daemon that implements both wakelocks and aggressive suspend on its own — and potentially more tasks such as heartbeat service, etc. — are already there. Even webOS seemingly has a ‘powerd’ daemon that does the aggressive suspending, on the TouchPad at least: Snapdragon SoC, where dynamic PM doesn’t seem to be as effective as on TI OMAP.

    Considering that it can be fully done in userspace, that it does not have performance requirements and that it smells as a “policy” thing from a mile, I don’t understand why this wakelock interface is still being debated….

    The entire concept of suspending might make sense on x86, where the BIOS/APM/ACPI/whatever usually declares several predefined power states and provides proprietary bios calls/ACPI code/whatever to switch between them and implicitly configure all devices as appropriate.
    On ARM, there is no such firmware, so why artificially introduce this “static” suspended state again? Dynamic PM can and should be used to run all of the devices to the appropriate power saving configurations.

    And by the way, fanoush from TMO tested that a N810 with stock firmware could last up to the 30 days idling (no wi-fi, no bt, no radios). The N810 did not use aggressive suspending either, so that’s also quite an impressive number :)

  4. FelipeC says:

    +javispedro

    I just don’t see why the Android folks need the userspace wakelocks interface.

    Very true, that point was also brought in the huge discussion.

    I don’t understand why this wakelock interface is still being debated….

    It’s not, AFAIK, I just took a long time to get around to write this post, and I was reminded by the nice results we are getting from the N9. Last I checked the issues that required changes in the kernel side are done single a long time, but in a different way, and they should be able to port all the wakelock stuff in their drivers to the new upstream API, and the user-space stuff can be managed entirely in user-space. But nobody from Android has had time to actually do that.

    And by the way, fanoush from TMO tested that a N810 with stock firmware could last up to the 30 days idling (no wi-fi, no bt, no radios). The N810 did not use aggressive suspending either, so that’s also quite an impressive number :)

    Indeed, somebody from Nokia mentioned something similar when he forgot his device on his desk for weeks and still had a lot of battery. But I don’t really think most people care about those use-cases :P

  5. Jed says:

    Excellent write-up, thanks for this!

  6. I had always thought tickless kernels achieved the maximum possible power savings. (I’m a zero-knowledge person in this area.) Am I confusing aspects of power-savings?

    Also, who does the timer interrupt to the CPU, if the CPU is asleep? Is it a separate circuit?

  7. FelipeC says:

    +Octavio Alvarez

    A tickless kernel achieves the maximum possible power savings if nothing is running. And assuming all the devices have properly implemented the dynamic pm routines of course. The trick is to get nothing running as much time as possible.

    Yes, there’s a separate circuit to wake up other devices. At least in OMAP 3 it’s called the wake-up domain.

  8. alvarezp says:

    I would love to see a “hall of shame” for power-consuming applications and devices. I’d like to know what, in my laptop is the most power-consuming application, particularly if nothing else is running.

    Also, I wonder how much power-hungry the Linux kernel is itself. I wonder who wins if I leave Windows with the least amount of services enabled, with the least graphic options enabled vs. a CLI-only Linux distribution vs. a bare-minimum graphical Linux installation with nothing running (in the same laptop).

  9. alvarezp says:

    Oh, forgot a comment: it does not matter how low the voltage of the CPU gets. You can use the same voltage for two different operations and use different electric *current*. That’s what matters.

  10. David Weinehall says:

    @Alvarezp: a good tool to find culprits is powertop.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.

Join 42 other followers