Nehalem CPU Power State
Recently I re-installed Arch Linux after a several year hiatus. One of the hiccups in coming back was that I'm no longer running the latest and greatest hardware. My CPU (Nehalem) is power managed with the acpi_cpufreq
module while the latest and greatest processors are using a new p-states based driver. It seems like the defaults for acpi_cpufreq
are not what they were several years ago! Previously, acpi_cpufreq
loaded several frequency governors; on the latest install only two governors were available, ondemand
and performance
. For temperature & noise reasons it is also nice to run the powersave
governor. Additionally, according to nearly every resource on the web, it should be possible to quickly change governors with cpupower -c all frequency-set -g $governor
. Unfortunately, this was not working on my old hardware. This post describes how to get powersave
back and get around the inability of cpupower
to change the governor.
Loading the powersave
module
By default, this installation only provided the ondemand
and performance
governors. In order to set the governor to powersave
, the cpufreq_powersave
module needed to load on boot. This was trivial to do by creating /etc/modules-load.d/cpufreq_powersave.conf
and adding the single line:
cpufreq_powersave
lsmod
verifies the modules load on boot.
Change file permissions on boot
In order for a non-root user to alter the cpufrequency governor the permissions on /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor
need to be changed. Ideally this happens automatically on boot. The following systemd service changes the file permissions on all of the scaling_governor
files to 646
which allows the owner (root) and all others (nonroot) to have rw
permission.
Save the the unit as /usr/lib/systemd/system/scaling_governor.service
and run systemctl enable scaling_governor.service
.
[Unit]
Description=Allow non root to set scaling_governor
[Service]
Type=oneshot
EnvironmentFile=/etc/default/cpupower
ExecStart=/usr/bin/chmod 646 /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor
RemainAfterExit=yes
[Install]
WantedBy=multi-user.target
Toggling script
With the cpufreq_powersave
module loaded and rw
permissions on all of the scaling_governors
, it's possible to quickly change the governor with a bash one-liner
echo $governor | tee /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor > /dev/null
The cpu*
makes the change on all cores of the processor
I would like to change the governor very quickly with a single hotkey so the following script toggles the governor every time it runs from powersave
-> ondemand
-> performance
. I'm running in an i3/dunst environment, so notify-send
is used to popup a small notification that the governor has changed.
#!/bin/bash
# Toggle through powersave/ondemand/performance governors
current=`cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor`
case $current in
'powersave')
echo ondemand | tee /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor > /dev/null
notify-send "CPU FREQUENCY" "ondemand set"
;;
'ondemand')
echo performance | tee /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor > /dev/null
notify-send "CPU FREQUENCY" "performance set"
;;
'performance')
echo powersave | tee /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor > /dev/null
notify-send "CPU FREQUENCY" "powersave set"
;;
esac
# vim:set ts=2 sw=2 ft=sh et:
In .config/i3/config
the script is tied to F8 with the following line:
bindcode 74 exec /path/to/script/toggle_governor
Verify everything is working
Running cpupower frequency-info
will display the active governor. Alternatively, it's possible to watch the frequency in something like i7z
; if the governor is set to performance
the frequencies should be near the maximum state of the processor.
Was this information useful? Consider using my Amazon Affilliate URL as a way of saying thanks. I'll receive a small portion of your purchases made within the next 24 hours.