Dog Days

Last week (at the time of writing), we were hit by a bad heat wave and, while none of my computers crashed or caught fire, it was clear that they were operating well outside their usual comfort zone. The first thing to do is of course to use well designed cases that provide adequate cooling (not like the compaq 6400NX). The second is to use all the advanced power management features available—whether it’s SpeedStep, Cool’n’Quiet, or PowerNow!. You enable it from your computer’s BIOS and usually the operating system takes over when you boot.

Changing dynamically the CPU’s (and other devices?) speed (and therefore power consumption) to respond on demand to the user or system tasks is quite a good policy for desktops and servers (that’s why it defaults to “ondemand” on Ubuntu) but it may not be what you want for your laptop or netbook. For a netbook, setting the power policies to “powersave” will keep the CPUs into low gear and extend significantly battery life. The thing is, Ubuntu doesn’t let you set the default policy easily.

Normally, once SpeedStep (or Cool’n’Quiet or PowerNow!) is enabled from the BIOS, Ubuntu loads the right kernel modules, enables policies and sets the reasonable “ondemand” policy as default. However, if you want the default policy to be “powersave”, you’re in for quite a bit of hacking, and you might not want to alter system-wide configuration anyway.

After reading a couple of tutorials—most of them outdated and useless with Lucid Lynx—I decided that I set policy from normal userspace. Quite so, after reading how to add a “folder” in gconf-editor to add a couple of power-management key that are ignored anyway, it was quite clear for me that this sub-system is too poorly documented (*gasp* *shock!*) to hack the permanent configuration of my netbook (or any other machine, for that matter).

So here’s my fix.

First, there’s the command line utility cpufreq-selector that allows the user to change the current power policy and/or frequency for a given CPU—not all CPUs at the same time, that’d be too easy! As far as I am concerned, setting the explicit CPU frequency is a lot of trouble since you have to enumerate the supported frequencies and pick the lowest. Alternatively, it suffice to set the policy to “powersave” and this will yield the same result: the target CPU shifts into low gears and stays in low gears regardless of load.

You still have to enumerate the CPUs, but that’s easy. You can do that by parsing /proc/cpuinfo in the /proc pseudo-filesystem. Something like grep processor /proc/cpuinfo | wc -l will give you the number of (logical) processors. The command grep processor /proc/cpuinfo | cut -d: -f 2 will give you the CPU numbers. Either way, not too hard to get.

The next thing you may want to do is to detect the state of the AC adaptor. If the computer is not running on batteries, it may not be necessary to keep it shifted in low gears. The command cut -d: -f 2 /proc/acpi/ac_adapter/ACAD/state | sed s/\ //g will return the status of the AC adaptor. Probably only the value off-line is of interest.

Now, you know the number of CPUs you have, whether or not the AC is plugged in, and you know how to change policy using cpufreq-selector. The only thing left to do is to add a bit of glue-code and you have yourself a nice power-management script.

You probably want to keep yourself informed of the policy changes. In Gnome, you use libnotify to make OSD-like message appear on the desktop, blended in the look-and-feel of the interface. You have to install the libnotify-bin to use notify-send, the command-line utility to send notifications to the desktop. You will need the acpi package that saves you lots of trouble for detecting hardware power status. You just have to:

sudo apt-get install libnotify-bin acpi

The icon you want displayed with the power policy change is customizable and conveniently abstracted through the folder /usr/share/notify-osd/icons/gnome/scalable/status/, which links to the theme-dependent icon. So the complete script looks like:

#!/bin/bash

# this script detects whether the AC is
# plugged or if running on batteries (once,
# at login) and sets power policies to either
# ondemand or powersave

sleep 90 # time for desktop elements to load and 
         # cpufreq-applet to load its defaults

# enumerate found CPUs
cpus=$( grep processor /proc/cpuinfo | cut -d: -f 2 )

ac_state=$(acpi -a | cut -d: -f 2 )

# if ac_state not available,
# it will default to "ondemand"
# (which is acceptable?)
#
if [[ "$ac_state" =~ "off-line" ]]
then
 # running on batteries
 governor=powersave
 icon=notification-power-disconnected
else
 # running on plugged AC
 governor=ondemand
 icon=notification-gpm-ac-adapter
fi

# set governor for each CPU
#
for cpu in ${cpus[@]}
do
 cpufreq-selector -c $cpu -g $governor
done

notify-send \
    --urgency="low" \
    --category="device" \
    --icon=${icon} \
    "CPU Scaling policy set to ${governor}"

You can either set it to run periodically or have it run once at login. You can add the script using the system→Preferences→Startup Application dialog. It will let you add the script and it will be launched automagically at logon.

Notice the sleep 90 command at the beginning of the script. Why is this thing there? If you’re using the Gnome Cpu Frequency Applets (the thingies that display and let you change policies and CPU speeds), they will load some time after login. The delay is necessarily system-specific: Gnome launches the desktops, applications start, applets are loaded, etc. But that’s not quite the main problem. It’s that the applets just don’t care what policies you want. They just reset to “ondemand” on start-up, but after a while. I don’t know why they’re doing this, but they seem to be waiting 30 seconds or so before resetting the policy to “ondemand”, regardless of what was your last choice of policy. The script therefore has to wait long enough for these applets instances to do their stuff and set the policy to “powersave” (or “ondemand”, if you’re plugged in).

On my Dell Mini 10v, using “powersave” stretches battery life quite a bit. With the larger battery, I can get a bit more than 6 hours of actually doing stuff. Using “ondemand,” battery life seems to be around 4 hours, while doing essentially the same stuff. Of course, that’s not very accurately measured, but you do feel the difference.

*
* *

While my primary goal on my netbook is to stretch battery life as much as possible (with the appreciable side-effect of not roasting my nuts); you may want to use the same script (or a modification of your own) to keep your desktops and servers cooler on dog days. On my AMD64 box, having the CPU run ondemand makes the computer run a good 10°C cooler with no noticeable loss of performance. After all, using the “ondemand” policy will have your CPU kick in high gears depending on work load. If you start doing stuff, compiling for example, the CPU will jump back to maximum speed after a very short delay (0.1s?).

One Response to Dog Days

  1. […] a previous post, I discussed how to set the default power policy with Linux (Ubuntu) by detecting the battery/power […]

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 )

Google+ photo

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

Connecting to %s

%d bloggers like this: