Powerd
Introduction
powerd is a user-level power manager for the XO-1 and XO-1.5 laptops. powerd implements the policy decisions surrounding putting the system into idle-suspend or sleep states, dimming or blanking the screen, shutting down after extended inactivity, etc. Input to powerd's decisions include the laptop's lid and ebook switches, system wakeup events, and the activity levels of the cpu, the camera, the network, and the user.
Configuration is flexible, and is documented both in the powerd script (installed as /usr/sbin/powerd) and in the (text-based) configuration file (/etc/powerd/powerd.conf).
The git repository for powerd is here: http://dev.laptop.org/git/users/pgf/powerd
Design goals
- Fully support XO power saving capabilities, including:
- system in S3 with display active
- wake-on-wlan, and keeping autonomous mesh active during S3
- No X11 dependency, including for the (minimal) splash-screen UI.
- Minimal hal/udev/dbus dependency (largely because of the author's background is in the embedded world, but also simply to reduce unnecessary dependencies).
Operation
- Events are communicated to the daemon via a named pipe.
- User "idleness" is indicated by 4 events: 3 successive idle events, and an "active again" event. These events are provided by an ancillary system daemon which already monitors all user input in order to support other XO-specific keyboard features. (This daemon is known as "kbdshim".)
- The three configurable user-idle timers can be configured to dim the screen, turn off the screen, and enter S3 state, in any order (well, "dim" after "screen off" doesn't make much sense). Three different sets of timers are selected, depending on whether the laptop is externally powered, is on battery, or is being used in "ebook" configuration.
- A fourth timer allows for automatic shutdown when the system has been suspended for "long enough".
- The major power inputs -- battery levels, external power insertion, the power button, lid switch, ebook-mode switch -- are also communicated by events.
- Wakeups can come from all the usual sources -- keyboard, lid, power subsystem, wlan, etc. Due to hardware limitations, USB ports are unpowered during suspend, and can't cause wakeups.
- A "hard" suspend can be forced with the power button or by closing the lid. When in this state, those are the only two configured wakeup events.
Inhibiting suspend
- Applications inhibit suspend by creating pid-named files, or by touching the modtime on a single well-known file -- either will work. powerd will refuse to do an automatic suspend if any pid-named files exist, or if the touch-file has been touched recently enough. (Abandoned pid-named files are detected and removed, so programs can be wrapped with "touch $$; exec foo" to make them suspend-inhibiting.)
- In addition, suspend can be inhibited by:
- the presence of certain USB devices (by class, vendor, or product ID)
- elevated CPU activity
- camera in use
- I/O on console virtual terminals (mostly a developer convenience)
- network activity (certain classes of traffic, as detected by custom iptables rules)
Current behavior
- Current default configuration (on XO-1.5) is fairly aggressive, and puts the system to sleep, leaving the display active, if there has been no user input after 15 seconds. The display will wake and dim after 3 minutes of inactivity, and will wake again and blank after 7 minutes. The system will shut down after sleeping for 4 hours, unless on external power.
- Suspend won't occur if certain types of network traffic have been seen within the previous 5 seconds. (Most outgoing, and some incoming packets.)
- Suspend won't occur if the CPU is more than 15% utilized. Many of the XO's important applications are user-created animations (written in Scratch or Etoys), or user-created music, etc. It's important not to interrupt those when in progress.
Logging
To facilitate power optimization, most power-affecting events are logged. Mechanisms to retrieve these logs remotely have been considered, but nothing has been implemented. (Logs are requested directly from the user when problematic laptops are reported in the field.)
Experience
- Rarely, but definitely, the system will behave incorrectlye due to race conditions between suspend and wakeup event race -- i.e., a wakeup will be lost if it arrives just as the system is going to sleep. Since most wakeups are user-initiated, usually this just means an extra keystroke. Missed wlan wakeups are worse. The race is narrowed as much as possible by rechecking the input queue as late as possible, but obviously any kernel mechanism(s) which helped close this hole would help.
- The inhibit heuristics are simple, but simplistic: staying awake because the cpu is "busy", or because TCP traffic has been seen in the 5 seconds prior to suspend, are both error prone decisions. Few apps have been made suspend-aware -- if more of that were done, the accuracy of the heuristics wouldn't be as critical.
- Since suspends usually happen with an expected wakeup time, they are invoked via "rtcwake -m mem". This makes rtc wakeups unavailable for other applications. XO 1.5 has an additional wakeup timer implemented in the EC, which could potentially be used instead.
- With the support of a few small helper daemons (that handle user and power input monitoring) which are written in C, powerd is implemented in bourne shell, 99% of which is POSIX compliant. (The use of the -t option to the read builtin is the one exception.) There's no doubt that there are some tasks that would be better implemented in a different language, but there's something to be said for fast prototyping and ease of maintenance. The use of shell also makes one more part of the laptop "transparent", which fits with its educational role.
Documentation
Full documentation for powerd is contained in the source script itself, here: http://dev.laptop.org/git/users/pgf/powerd/tree/powerd