Tune Intel CPU Energy Policy Safely with x86_energy_perf_policy
You will read the current Intel energy and performance policy, then make one scoped change to EPB or HWP EPP and verify it. The utility writes processor Model Specific Registers directly, so a typo can change the behaviour of a whole machine without leaving a configuration file to review.
The route
Jump straight to the step you need, or tick off Done means at the end.
This guide uses x86_energy_perf_policy from linux-tools-common version 6.8.0-142.142, as installed on the reference system. Allow about fifteen minutes. You need an Intel processor exposing the relevant MSRs, the matching kernel tools package, and root access for every invocation. The examples use CPU 0 where a per-CPU test is useful; replace it only after checking your own topology.
Safety boundary
The examples first read state. The EPB, EPP, HWP limit and turbo examples change live processor policy. Do not test them during a latency-sensitive workload or on a host where a performance change could interrupt a service. Save the read-only output before writing anything.
1. Check the installed tool and kernel match
First confirm the command path and package version. These checks are ordinary and read-only:
$ command -v x86_energy_perf_policy
/usr/bin/x86_energy_perf_policy
$ dpkg-query -W -f='${Package} ${Version}\n' linux-tools-common
linux-tools-common 6.8.0-142.142
$ uname -r
6.8.0-139-generic
The package version and running kernel version do not have to be textually identical, but the wrapper must find a versioned binary for the running kernel. On this reference host it does not: the wrapper exits with status 2 and suggests linux-tools-6.8.0-139-generic. Install the matching package through your normal system-management process, then rerun the checks. Do not mistake the wrapper's warning for a CPU policy result.
Checkpoint: continue only when x86_energy_perf_policy --version reaches the real binary and prints its version. The command runs as root according to the installed manual:
$ sudo x86_energy_perf_policy --version
x86_energy_perf_policy version 6.8.0
The exact version text is host-specific. Treat the version you see as authoritative for later automation.
2. Read the current policy
Run the command without a write request. This needs elevated privileges because the utility reads the CPU MSR device:
$ sudo x86_energy_perf_policy
cpu0: EPB 6
cpu0: HWP_REQ: min 6 max 35 des 0 epp 128 window 0x0 (0*10^0us) use_pkg 0
cpu0: HWP_CAP: low 1 eff 8 guar 27 high 35
cpu1: EPB 6
cpu1: HWP_REQ: min 6 max 35 des 0 epp 128 window 0x0 (0*10^0us) use_pkg 0
cpu1: HWP_CAP: low 1 eff 8 guar 27 high 35
Your CPU count and numbers will differ. EPB is the older energy-performance bias hint. HWP EPP is the preference used by newer Hardware P-states. The capability line gives the processor's supported range, while the request line shows the current per-CPU request. A read can show EPB even when HWP is the more relevant control.
Record this output. Also check the CPU list before selecting a scope:
$ lscpu -e=CPU,CORE,SOCKET,NODE
CPU CORE SOCKET NODE
0 0 0 0
1 1 0 0
Package scope and CPU scope are not interchangeable. EPB may be shared by all CPUs in a processor package on some implementations. HWP requests are per CPU, while the package request can provide a package-wide default.
3. Pick a policy value
Use one of the named values rather than guessing a numeric MSR value. The installed manual maps them as follows:
| Value | EPB | EPP | Use |
|---|---|---|---|
performance | 0 | 0 | Prioritise performance |
balance-performance | 4 | 128 | Prefer performance with some efficiency |
normal or default | 6 | 128 | Moderate preference |
balance-power | 8 | 192 | Balance power and performance |
power | 15 | 255 | Prioritise energy efficiency |
The manual calls balance-power the default value. That does not mean every machine starts with it: firmware, the kernel driver and earlier userspace changes can affect what you read. The word normal is a synonym for default, not a request to restore firmware settings.
4. Change one CPU's HWP preference
For a reversible, narrow test, set HWP EPP on CPU 0. This is a live policy change and requires root:
$ sudo x86_energy_perf_policy --cpu 0 --hwp-epp balance-performance
$ sudo x86_energy_perf_policy --cpu 0
cpu0: EPB 6
cpu0: HWP_REQ: min 6 max 35 des 0 epp 128 window 0x0 (0*10^0us) use_pkg 0
cpu0: HWP_CAP: low 1 eff 8 guar 27 high 35
Updates are silent by default. The second command is the checkpoint: confirm the requested EPP value and compare it with the saved baseline. If HWP is not available or enabled, the read or write will report an error instead of making HWP work by itself.
To undo this example, write the value you recorded before the change. If the baseline was EPP 192, for example:
$ sudo x86_energy_perf_policy --cpu 0 --hwp-epp 192
$ sudo x86_energy_perf_policy --cpu 0
Numeric EPP values are MSR values from 0 to 255. Named values are easier to review and portable across the policy mapping, so use a number only when you have a documented reason.
5. Apply EPB when HWP is not your control
On a system using EPB, set the bias for a deliberately chosen CPU or package. This example changes CPU 0 only:
$ sudo x86_energy_perf_policy --cpu 0 --epb power
$ sudo x86_energy_perf_policy --cpu 0
Because some processors share EPB within a package, the visible effect may extend beyond CPU 0. If that matters, use package scope explicitly after checking the package list:
$ sudo x86_energy_perf_policy --pkg 0 --epb balance-power
$ sudo x86_energy_perf_policy --pkg 0
Do not assume the package option is a harmless alias for --cpu all. It writes the package MSR and may establish a package default that interacts with per-CPU HWP requests.
6. Leave HWP limits and turbo alone unless you have a measured reason
The utility can write HWP minimum, maximum and desired performance fields. The values for --hwp-min, --hwp-max and --hwp-desired are in units of 100 MHz, so 12 means 1200 MHz. A default limit comes from the processor's capability MSR. These fields affect the operating range, not just a preference label.
--hwp-desired and --hwp-window are marked experimental by the manual. The tool also has --force, which writes without bounds checking. Do not combine it with a copied value from an unrelated processor. If a workload requires a frequency cap, capture the original request and test the exact limit during a maintenance window.
The --turbo-enable 0 option disables turbo mode, while --turbo-enable 1 enables it. This is a machine-wide performance and power decision, not a troubleshooting shortcut. The safest undo is the previously recorded value, followed by a fresh read. Enabling HWP with --hwp-enable 1 is more consequential: once enabled, the manual says a system reset is required to disable HWP.
7. Avoid races with the CPU frequency driver
The utility and intel_pstate can access the same MSRs. The manual warns that there is no locking or coordination when HWP limit fields are changed while intel_pstate sysfs attributes are also using them. Do not run a userspace loop that repeatedly writes these fields while a power-management service is changing them.
For a persistent policy, first identify the kernel driver and its documented interface:
$ cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_driver
intel_pstate
$ cat /sys/devices/system/cpu/cpu0/cpufreq/energy_performance_preference
balance_performance
The paths may be absent on a system without that cpufreq interface. Current kernel documentation describes the sysfs preference as another way to expose EPP or EPB. Choose one owner for a persistent setting and verify it after boot; otherwise a service or driver can overwrite a direct MSR change.
Done means
- The tool resolves to a binary matching the running kernel, and its version was recorded.
- A root read captured the current EPB, HWP request and capability values.
- The CPU or package scope was chosen from actual topology, not guessed.
- Any write used a named policy value or a documented, measured numeric limit.
- A second read confirmed the change, and the old value is available for undo.
- You avoided
--force, experimental desired-frequency fields and turbo changes unless a maintenance plan covers them.