Linux CPU Frequency Scaling

Last update: 2022-10-30 03:35:16 +0800 +0800
tags: Cpufreq | Kernel | Linux
Available translations: 日本語 / 中文(简体) / 中文(繁體)

Modern processors expose performance states that trade execution capacity against power and heat. Linux presents those controls through CPUFreq. “Frequency” remains in the interface for compatibility, although hardware-managed Intel HWP and AMD CPPC operate on performance requests rather than a discrete clock table.

CPUFreq’s Three Layers #

CPUFreq consists of:

  1. The core, which owns policy objects and the common sysfs interface.
  2. Governors, which convert workload demand into performance requests.
  3. Scaling drivers, which translate requests into platform-specific register, firmware, or hardware operations.

Only one struct cpufreq_driver can be registered at a time. The driver must therefore handle every CPU for which CPUFreq is available; heterogeneous systems still use policy objects to represent different control domains.

The scheduler-driven schedutil governor receives utilization updates on events such as task enqueue, dequeue, and scheduler ticks. It derives a capacity request and invokes the driver directly or through deferred work, depending on whether the driver supports a fast transition. Other generic governors include performance, powersave, ondemand, conservative, and userspace, but the set depends on the kernel configuration and loaded modules.

Policies Represent Hardware Control Domains #

struct cpufreq_policy represents the logical CPUs whose performance control interface is shared. A policy may cover one logical CPU or several CPUs that cannot be controlled independently. The core keeps a policy pointer for every CPU; pointers for CPUs in one hardware domain refer to the same object.

When a driver initializes a new policy, its ->init() callback supplies:

  • the related CPU mask;
  • hardware minimum and maximum frequencies;
  • a table of operating frequencies, when the hardware uses a discrete table;
  • transition properties and driver capabilities.

The core then attaches a governor and calls its ->init() and ->start() operations. Starting a scheduler-aware governor installs per-CPU utilization callbacks. A driver with its own selection algorithm can instead implement ->setpolicy() and bypass generic governors. CPU hotplug can deactivate a policy when its last CPU goes offline and reactivate it later without changing the underlying control-domain model.

Inspecting and Controlling a Policy #

Each policy appears under /sys/devices/system/cpu/cpufreq/policyX/. related_cpus lists every logical CPU in the domain, including offline CPUs, while affected_cpus lists its online members.

Useful attributes include:

AttributeMeaning
scaling_driverRegistered driver serving the policy
scaling_available_governorsGovernors, or driver algorithms in active intel_pstate mode
scaling_governorCurrent governor or algorithm; writable
cpuinfo_min_freq, cpuinfo_max_freqHardware limits in kHz
scaling_min_freq, scaling_max_freqWritable policy limits in kHz
scaling_cur_freqCurrent policy frequency reported or estimated by the driver/core
cpuinfo_cur_freqHardware-derived current frequency, when supported

scaling_cur_freq is not necessarily an instantaneous measurement. On many systems it is the last requested P-state; selected x86 drivers can provide a more representative value, but hardware may change performance between observations. scaling_available_frequencies can be absent when a driver exposes a continuous range.

Read a policy before changing it:

bash
policy=/sys/devices/system/cpu/cpufreq/policy0
grep . "$policy"/{related_cpus,scaling_driver,scaling_available_governors,scaling_governor}
grep . "$policy"/{cpuinfo_min_freq,cpuinfo_max_freq,scaling_min_freq,scaling_max_freq}

echo schedutil | sudo tee "$policy/scaling_governor"
echo 1800000 | sudo tee "$policy/scaling_max_freq"

Limits apply to the whole policy, not just to the CPU number in the directory name. The kernel rejects a minimum above the maximum and a maximum below the minimum.

Intel and AMD P-State Drivers #

intel_pstate supports many, but not every, Sandy Bridge and later Intel processor. Driver selection is not unconditional: hardware support, firmware, kernel configuration, and command-line options can cause another driver to bind.

  • In active mode, sysfs reports intel_pstate. The driver supplies performance and powersave algorithms instead of generic governors. With Intel Hardware-Managed P-states (HWP, marketed as Speed Shift), hardware selects performance within software limits and energy-performance hints. Without HWP, the driver runs its selection algorithm from scheduler utilization callbacks.
  • In passive mode, sysfs reports intel_cpufreq. Generic governors such as schedutil choose requests, and intel_pstate acts as a regular scaling driver.

amd_pstate uses ACPI Collaborative Processor Performance Control (CPPC), whose abstract performance scale is finer-grained than legacy ACPI P-state tables.

  • Passive/guided operation works with generic CPUFreq governors and sends minimum, maximum, and desired performance requests.
  • Active EPP operation, shown as amd-pstate-epp in driver documentation and controlled by the platform’s supported mode, lets hardware make more of the selection based on an Energy Performance Preference.

If the platform lacks a usable ACPI _CPC description, initialization can fall back to acpi-cpufreq. Current mode selection and available attributes depend on the running kernel, so inspect sysfs rather than inferring the driver from the CPU vendor.

Boost, Thermal Limits, and Measurement #

Boost is permission to use performance above the nominal sustainable range; it is not a guaranteed clock. Package power limits, active-core count, firmware policy, temperature, and cooling determine whether hardware can honor the request. Global boost controls may appear under /sys/devices/system/cpu/cpufreq/, while intel_pstate/no_turbo and driver-specific AMD attributes expose related controls on supported systems.

CPUFreq limits are therefore requests bounded by additional control loops. Thermal cooling devices and firmware can throttle below a requested value, and idle CPUs can enter sleep states independently of CPUFreq.

For measurement, sample hardware feedback over an interval instead of repeatedly reading one sysfs file:

bash
turbostat --interval 1
perf stat -a -e msr/aperf/,msr/mperf/ -- sleep 5

APERF/MPERF-based tools estimate delivered average frequency while a CPU is active. Combine frequency with workload throughput, package power, and thermal data because a higher reported clock does not alone establish higher useful performance.

References #

Comments

Read or comment on GitHub (sign-in required to comment)