On this page

cpufreq and cpuidle

Coverage: cpufreq governors → CPU idle states (C-states) → cpuidle governor → P-state drivers (intel_pstate/amd-pstate) → schedutil → Energy Efficiency Kernel versions: 2.6 ~ 6.x

cpufreq: Dynamic Frequency Scaling

Governors

// drivers/cpufreq/
// Each governor is an independent policy module:

// performance: Always highest frequency (P0) → Peak performance, zero latency, high power consumption
// powersave:   Always lowest frequency → Maximum power saving, low performance
// schedutil:   Scheduler-driven frequency selection → Current default (5.x+)
// ondemand:    On-demand frequency scaling (based on CPU utilization sampling) → Legacy default, laggy response
// conservative: Gradual frequency scaling (similar to ondemand but smoother)

schedutil: Scheduler-Driven

// kernel/sched/cpufreq_schedutil.c
// Frequency is driven directly by CFS PELT util signal:

// Every scheduler tick:
//   util = cpu_util_cfs(rq)  // Current CPU's CFS utilization
//   next_freq = 1.25 * util * max_freq / capacity
//   → Set cpufreq to next_freq

// Advantages:
//   - Scheduler knows CPU load directly → No need for independent sampling
//   - Response latency is much lower than ondemand (in scheduler path, not in independent timer)
//   - Integrated with EAS (Energy Aware Scheduling)

Drivers: intel_pstate / amd-pstate

// drivers/cpufreq/intel_pstate.c
// intel_pstate: P-state management for Intel CPUs (Sandy Bridge+)
//   Provides: internal governor (powersave / performance)
//   Writes directly to MSR (IA32_PERF_CTL) → No ACPI needed

// drivers/cpufreq/amd-pstate.c
// amd_pstate: P-state management for AMD CPUs (Zen2+)
//   Three modes: active (CPPC), guided, passive

// Check current:
cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_driver

cpuidle: CPU Idle State Management

C-states

Deeper sleep levels → More power saving + Longer wake-up latency:

C0: Active (running)
C1: HLT/MWAIT → Stop execution, ~1μs wake-up
C1E: Enhanced C1 → Downclock + C1
C2: Clock stop → ~3μs
C3: Cache flush → ~20μs
C6: Core power down → ~50μs
C7: Deeper power down (IVB+) → ~100μs

CPU automatically transitions between these states (hardware managed)
The kernel selects which C-state to enter via the cpuidle framework

Cpuidle Governor

// drivers/cpuidle/governors/menu.c
// menu governor (default):
//   Predicts based on historical idle duration → Selects C-state
//   Predictors: Recent idle duration, repetitive pattern detection, next timer event

// drivers/cpuidle/governors/teo.c
// TEO (Timer Events Oriented):
//   Newer governor → Selects based on intervals of recent timer events
//   More accurate than menu (especially for bursty workloads)

Energy Efficient Scheduling (EAS)

EAS (Energy Aware Scheduling, ARM):
  Scheduler considers energy efficiency when selecting a CPU:
    → Prefer CPUs already awake (avoid waking from deep C-state)
    → Select CPUs with sufficient remaining capacity (avoid frequency scaling up)
    → Select CPUs in the same cluster (shared cache)

  Integrates schedutil + cpuidle → Unified decision for scheduling, frequency, and C-state

Debugging

# cpufreq information
cpupower frequency-info
cat /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor

# C-state usage statistics
cpupower idle-info
cat /sys/devices/system/cpu/cpu0/cpuidle/state*/{name,usage,time,above,below}

# Power statistics (Intel RAPL)
cat /sys/class/powercap/intel-rapl/intel-rapl:0/energy_uj

# turbostat: Real-time frequency and C-state
turbostat --quiet --show PkgWatt,CorWatt,CPU%c1,CPU%c6 1

References

  • Source Code: drivers/cpufreq/, drivers/cpuidle/, kernel/sched/cpufreq_schedutil.c
  • Kernel Documentation: Documentation/admin-guide/pm/

Keywords: cpufreq, schedutil, intel_pstate, C-state, cpuidle, EAS, turbostat, P-state