How Linux Manages CPU Frequency with cpufreq
The Linux operating system dynamically adjusts processor clock speeds to balance computing performance and power consumption through a dedicated framework known as the cpufreq subsystem. This article examines the internal architecture of the cpufreq subsystem, detailing how the kernel core, hardware-specific scaling drivers, and policy governors interact to regulate CPU frequencies in response to system workload demands and power constraints.
The Architecture of the cpufreq Subsystem
The cpufreq subsystem operates via a modular architecture divided into three primary layers: the cpufreq core, scaling drivers, and scaling governors. This separation allows Linux to support diverse processor architectures while applying standardized power management policies.
- The cpufreq Core: The core acts as the central
mediator. It provides a standardized internal API for drivers and
governors, maintains state data, and exposes an interface to user space
through the
/sys/devices/system/cpu/cpu*/cpufreq/virtual filesystem. - Scaling Drivers: Drivers provide the hardware-specific communication layer. They interface directly with the CPU or platform firmware to read supported frequency states (P-states) and instruct the hardware to transition between them.
- Scaling Governors: Governors implement the decision-making logic. They monitor system load or integrate directly with the task scheduler to determine the optimal frequency for a given moment, requesting frequency changes from the core.
CPU Frequency Scaling Drivers
Scaling drivers translate generic requests into architecture-specific hardware commands:
- Generic Drivers (e.g.,
acpi-cpufreq): These drivers rely on standard ACPI tables provided by the system firmware to read available frequency steps and trigger transitions. They are widely compatible across x86 hardware but may offer slower transition times compared to modern vendor-tailored solutions. - Modern Hardware Drivers (e.g.,
intel_pstate,amd-pstate): Modern processors often manage frequency selection autonomously using internal microcode. Drivers likeintel_pstateandamd-pstateleverage hardware-managed P-states (HWP/CPPC), allowing the processor itself to scale frequencies rapidly based on autonomous metrics or explicit kernel hints.
cpufreq Governors and Policy Logic
Governors determine how aggressively the kernel scales frequency based on workload:
- schedutil: The default governor in modern Linux
distributions. It integrates directly with the Completely Fair Scheduler
(CFS) / Earliest Eligible Virtual Deadline First (EEVDF) scheduler.
Instead of relying on periodic CPU utilization samples, it uses runqueue
utilization metrics (
PELT—Per-Entity Load Tracking) to adjust frequencies immediately when tasks wake up or migrate. - performance: Locks the CPU to the highest available frequency within the permitted operating range, prioritizing maximum throughput at the cost of higher power draw.
- powersave: Operates the CPU at the lowest supported
frequency. On systems running modern drivers like
intel_pstate, this governor often delegates autonomous frequency scaling to the processor's energy-performance preference (EPP) mechanism rather than truly locking the CPU to its minimum frequency. - ondemand: A legacy governor that periodically checks CPU utilization. If the load exceeds a defined threshold, it jumps directly to the maximum frequency, subsequently stepping down as the load diminishes.
- conservative: Similar to
ondemand, but steps through intermediate frequencies gradually rather than jumping immediately to the highest frequency, aiming for smoother transitions.
User Space Monitoring and Configuration
Administrators can inspect and configure cpufreq settings at runtime
through the sysfs filesystem. Under
/sys/devices/system/cpu/cpuX/cpufreq/, key files
include:
scaling_available_governors: Lists the compiled-in governors available for selection.scaling_governor: Shows or sets the active governor for the CPU core.scaling_cur_freq: Displays the current operating frequency in kilohertz.scaling_min_freqandscaling_max_freq: Enforce absolute lower and upper bounds on frequency transitions, allowing fine-grained control over thermal limits and energy usage.