CPU frequency governors on servers
5 min read
A file server here spent several years running every build, scrub and resilver at 1.2 GHz on hardware rated for 2.5 GHz. Nothing was throttling it, nothing was overheating, and the machine reported its full clock range the whole time. The cause was one line in a hand-rolled kernel config:
CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE=y
The userspace governor does not scale. It holds whatever frequency was last
written to scaling_setspeed, and on that box nothing ever wrote one, so the
cores sat at the minimum P-state forever. One write to scaling_governor and
busy cores climbed to 2.3 GHz.
This is a failure mode that hides well, because every individual number the system reports is correct. It is worth knowing how the pieces fit together.
Three layers decide your clock speed
Only one of them is the kernel governor, and it is often not the one in charge.
The driver is the bottom layer. Check it first:
cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_driver
intel_pstateis the active mode of Intel's driver. The kernel hands a performance hint to the CPU and the hardware picks the actual P-state. Onlyperformanceandpowersaveare offered as governors here, and they are not the generic governors of the same name.intel_cpufreqis the same driver in passive mode: it registers as an ordinary cpufreq driver, so the full generic governor list becomes available.acpi-cpufreqis the generic ACPI driver, used on older Intel parts and on AMD withoutamd-pstate.
The governor is the policy on top of the driver:
cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor
cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_available_governors
performance pins to the maximum, powersave to the minimum, schedutil
drives frequency from the scheduler's own utilisation signal, ondemand and
conservative are the older sampling governors (aggressive and gradual
respectively), and userspace does nothing but obey scaling_setspeed.
The trap is that powersave means two different things. Under active
intel_pstate it is the normal, sensible choice: the hardware still boosts
under load, and "powersave" only describes the hint. Under acpi-cpufreq or
intel_cpufreq it is a hard floor, and you get the same symptom as the
userspace bug.
The firmware is the ceiling nothing in Linux can raise. Dell's System
Profile setting (Performance, Performance per Watt (OS), Dense Configuration)
can cap the range the OS ever sees. cpuinfo_max_freq is where that shows up:
if it reads lower than the part's rated turbo, argue with the BIOS, not the
kernel.
Which governor for which role
From a small mixed fleet, the rules that have held up:
- Router, firewall, anything latency-sensitive:
performance. A two-core Celeron G4900 routing four networks has nothing to gain from scaling and everything to lose from the ramp-up delay on the first packet of an idle flow. Consistency beats a few watts. - File and backup servers with bursty load:
schedutil, orondemandif you are on a kernel old enough to lack it. These machines idle most of the day and then want every megahertz for a scrub or a world rebuild.schedutilreacts on the scheduler's timescale rather than a sampling interval, so the climb is effectively immediate. - Hypervisors on modern Xeons: leave
intel_pstatein active mode withpowersaveand stop fiddling. On a Xeon Gold 5222 the hardware's own P-state selection is better informed than anything the kernel can infer through a virtualisation layer. userspace: only forcpupower frequency-set -f, thermal experiments, or benchmarking at a fixed clock. Never as a boot default.
Where the default actually comes from
Three places, in the order they take effect.
The kernel config sets the boot default through CONFIG_CPU_FREQ_DEFAULT_GOV_*.
Only one is set, and it must name a governor built in (=y), not modular: a
governor compiled as a module cannot be the boot default. On a Gentoo box with
CONFIG_IKCONFIG_PROC you can read the running kernel's answer directly:
zcat /proc/config.gz | grep -E '^#?\s*CONFIG_CPU_FREQ_(DEFAULT_)?GOV'
# CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set
CONFIG_CPU_FREQ_DEFAULT_GOV_SCHEDUTIL=y
CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
CONFIG_CPU_FREQ_GOV_ONDEMAND=y
Userland then gets a say: sys-power/cpupower or cpufrequtils as an init
service, an /etc/local.d/*.start script on OpenRC, or tuned and
power-profiles-daemon on systemd distributions. Whatever runs last wins.
That matters, because a wrong kernel default does not require a rebuild. On the affected server the complete fix was a local.d one-liner, applied at the next boot and immediately by hand:
for g in /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor; do
echo schedutil > "$g"
done
Correct the CONFIG_CPU_FREQ_DEFAULT_GOV_* symbol at the next kernel build you
were going to do anyway. Do not schedule a reboot for this.
Checking a fleet, and spotting the bug
One line per host tells you nearly everything:
cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_{driver,governor}
grep MHz /proc/cpuinfo | sort | uniq -c
intel_cpufreq
schedutil
4 cpu MHz : 1200.000
8 cpu MHz : 2294.000
The tell is not a low reading. It is every core reading exactly
cpuinfo_min_freq, to the decimal, on a machine that is demonstrably busy.
Idle cores at the floor are normal and correct. Twelve cores pegged at the
floor during a compile means the governor is not scaling at all, and the two
usual causes are userspace with nothing driving it and powersave under a
non-intel_pstate driver.
Confirm the fix by watching the same file while something loads the box. Start a kernel build or a scrub, then:
watch -n1 'grep MHz /proc/cpuinfo | sort -u'
Busy cores should sit near cpuinfo_max_freq and idle ones near
cpuinfo_min_freq, with the readings moving as work lands on different cores.
Both bounds are in the same directory:
cat /sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_{min,max}_freq
1200000
2500000
If the busy figure never approaches the second number, you have either a governor that is not scaling or a firmware profile that is holding the ceiling down. The sysfs files tell you which, and they were telling you the whole time.