Chapter 7: Laptop CPU Governors and TLP

Linux’s power management infrastructure is layered and comprehensive — but out of the box, many distributions are configured for performance rather than battery life. This chapter covers the CPU frequency scaling system and TLP, the most impactful tools for laptop power optimization.


7.1 The Linux CPU Frequency Scaling Architecture

Linux manages CPU frequency through the cpufreq subsystem, which has two layers:

Driver layer: Hardware-specific driver that communicates with the CPU frequency hardware.

Governor layer: Algorithm that selects the operating frequency (or P-state) based on system load.

The active driver and governor are visible at:

cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_driver
cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor

7.2 Governor Comparison

Governor Description Best For
performance Always runs at maximum frequency AC power, benchmarking
powersave Always runs at minimum frequency Maximum battery saving, light tasks
ondemand Scales aggressively based on load Legacy; replaced by schedutil
conservative Scales gradually based on load Legacy; smoother than ondemand
schedutil Uses scheduler load signal (PELT) Modern default; best balance

schedutil is the recommended governor for battery use. It uses the scheduler’s existing CPU load estimates (Per-Entity Load Tracking) instead of polling the CPU — which means more accurate frequency selection with lower overhead. On kernels 5.10+, it is the default on most distributions.

To set the governor for all CPUs:

import pathlib

def set_governor(gov: str):
    for p in pathlib.Path("/sys/devices/system/cpu").glob("cpu[0-9]*/cpufreq/scaling_governor"):
        p.write_text(gov)

set_governor("powersave")  # or "schedutil"

The full script with governor reading and setting is in code/governor_control.py.


7.3 intel_pstate and Hardware P-States (HWP)

On modern Intel CPUs, intel_pstate operates in active mode by default, where the hardware manages P-state transitions autonomously guided by the Energy Performance Preference (EPP) hint. The governor (typically powersave under intel_pstate) sets the EPP.

Key sysfs knobs:

# Disable turbo boost (reduces max frequency, lowers power under sustained load)
echo 1 > /sys/devices/system/cpu/intel_pstate/no_turbo

# Set min/max performance as % of max frequency
echo 20 > /sys/devices/system/cpu/intel_pstate/min_perf_pct
echo 80 > /sys/devices/system/cpu/intel_pstate/max_perf_pct

# Set energy performance preference (per-CPU)
echo "balance_power" > /sys/devices/system/cpu/cpu0/cpufreq/energy_performance_preference

EPP values from least to most power-saving: performancebalance_performancebalance_powerpower.

Under HWP active mode, TLP sets EPP automatically based on power source (AC vs battery). This is the most effective configuration for most laptops.


7.4 TLP: The Configuration File

TLP is a daemon that applies a comprehensive set of power settings at boot and when the power source changes (AC → battery, battery → AC). Install:

sudo apt install tlp tlp-rdw  # Debian/Ubuntu
sudo systemctl enable --now tlp

The configuration file is /etc/tlp.conf. Key sections:

CPU:

CPU_SCALING_GOVERNOR_ON_BAT=powersave
CPU_ENERGY_PERF_POLICY_ON_BAT=balance_power
CPU_BOOST_ON_BAT=0          # disable turbo on battery

Disk:

DISK_APM_LEVEL_ON_BAT=128   # aggressive power management
DISK_SPINDOWN_TIMEOUT_ON_BAT=60   # seconds before spindown

PCIe:

PCIE_ASPM_ON_BAT=powersupersave  # aggressive ASPM
RUNTIME_PM_ON_BAT=on             # enable runtime PM for PCIe devices

WiFi:

WIFI_PWR_ON_BAT=on   # enable WiFi power saving (may add latency)

USB:

USB_AUTOSUSPEND=1    # autosuspend idle USB devices

After editing, apply immediately without rebooting:

sudo tlp start
sudo tlp-stat -s    # verify active settings

7.5 Battery Charge Thresholds

Keeping a Li-Ion battery permanently at 100% accelerates degradation. Electrochemical stress at high SoC causes the SEI (solid electrolyte interphase) layer to grow, permanently reducing capacity.

Most studies recommend keeping Li-Ion between 20% and 80% SoC for maximum cycle life. TLP supports charge thresholds for ThinkPad, some Dell, ASUS, and LG laptops:

# ThinkPad example: start charging at 20%, stop at 80%
START_CHARGE_THRESH_BAT0=20
STOP_CHARGE_THRESH_BAT0=80

For ThinkPads this is written to the embedded controller via the thinkpad_acpi kernel module. For other brands, check tlp-stat -b to see which battery features are supported on your hardware.


7.6 PCIe ASPM

Active State Power Management (ASPM) allows PCIe links to enter low-power states (L0s, L1, L1.2) when idle. It can save 0.5–2 W on a laptop with WiFi, NVMe SSD, and discrete GPU.

Check negotiated ASPM state:

lspci -vvv | grep -i aspm

If ASPM is disabled (shown as ASPM Disabled or L0s Not Supported), TLP’s PCIE_ASPM_ON_BAT=powersupersave may enable it for supported devices. For devices that report ASPM capable but with it disabled, add the kernel parameter pcie_aspm=force to GRUB — but be aware this can cause stability issues on hardware with broken ASPM implementations.


7.7 Verifying Your Changes

After configuring TLP:

sudo tlp-stat -s       # overall TLP status
sudo tlp-stat -b       # battery info and thresholds
sudo tlp-stat -p       # CPU frequency and governor
sudo powertop          # before/after power estimate comparison
upower -d              # battery discharge rate

The Energy rate field in upower -d output gives you the current draw in watts. Run this before and after applying TLP to quantify the improvement.


← Chapter 6: Embedded Peripheral Management Table of Contents Chapter 8: Laptop Display, Suspend, and Wakeup →