Fixing noise on Ubuntu Hardy 8.04, aka setting max_cstate

Not security related at all, but it took me so much time to figure this out, I want to share this with the world!

I own a Lenovo Thinkpad T60 that I like very much. There is one annoyance, and that is that when on battery, the laptop produces a high pitched noise when idle. It turns out that this has something to do with the ACPI state. States of C3 and higher made my laptop produce the noise. In Ubuntu Gutsy 7.10 there was a simple solution. I could force the laptop to never use anything higher that C2. That was done like this:

echo “2” > /sys/module/processor/parameters/max_cstate

And everyone was happy! Noise gone, battery life still decent. All was good. Until I upgraded to Hardy. Hardy uses kernel 2.6.24, and for some reason the sysfs interface has been removed. So there is no way to set the max_cstate on the fly. See here for the bug report.

In theory the ‘processor’ module should be able to take an option ‘max_cstate=2’. But setting this option didn’t seem to work. It took some time to figure out why, but the reason is simple. The ‘processor’ module is in the initrd image, and is loaded before /etc/modprobe.d/options is inspected. Luckily, the solution is simple:

Add the following line to your /etc/modprobe.d/options file:

options processor max_cstate=2

Then update the initrd image using the following command:

sudo update-initramfs -u

The initrd image is now updated to include the option. Then reboot. Verify if it works:

$ cat /proc/acpi/processor/CPU0/power |grep max_cstate
max_cstate:              C2

Success! Again, no more noise…

Update 21st of March 2010 for Ubuntu Karmic 9.10. The solution for this for Karmic was posted by Markus in the comments below, I’m replicating it here for convenience. Thanks Markus!

Karmic introduces the new grub2 so there isn’t any menu.lst anymore. In grub2 some things (like default kernel options) are done in /etc/default/grub, so you have to edit this file:

sudo pico /etc/default/grub

search for a line GRUB_CMDLINE_LINUX=”” and change to (or add if it doesn’t exist):

GRUB_CMDLINE_LINUX=”processor.max_cstate=2″

press STRG+x and y to save and exit and execute the grub update:

sudo update-grub

After a reboot the max cstate should then be C2!