SysadminNews

AMD P-State Patches Lift 1% Low Frame Rates by 31.8%

On this page
  1. The problem is a thread that is busy and keeps napping
  2. What the patch does about it
  3. Reading the two numbers
  4. What we would check before caring
  5. Status
  6. Sources and further reading

A patch series posted to the Linux kernel mailing list adds an option called epp_boost to the amd_pstate driver, and the measured result is one of the better numbers we have seen from a scheduling tweak. On a Valve Steam Deck running the Civilization VI benchmark, 1% low frame rates improve by 31.8% and the p99 frame time by 4.1%. The mechanism is small: sample each core's busy time at most every 10 ms, and if a core is at least half busy, pin its energy performance preference to performance until 300 ms pass with no further activity. It is not merged yet, and the shape of workload it helps is not only gaming.

The short answer

David Vernet, a Linux kernel engineer at Meta, has posted patches adding an epp_boost option to the amd_pstate driver. Enabled with amd_pstate.epp_boost=1, it samples each core's C0 residency at most once every 10 ms, sets that core's energy performance preference to performance when the sample shows it at least 50% busy, and restores the previous request after 300 ms without another busy sample. On a Valve Steam Deck, the Civilization VI benchmark gains 31.8% in 1% low frame rates and 4.1% in p99 frame time. The series is under review and has not been merged.

31.8%better 1% low frame rates on a Steam Deck
10 msmaximum sampling interval per core
300 mshow long a boost is held after the last busy sample
Answer card: proposed amd_pstate epp_boost patches sample each core every 10 ms, pin the energy performance preference to performance when a core is at least 50% busy, and hold it for 300 ms, improving 1% low frame rates by 31.8% on a Steam Deck.
The proposal in one card. Source: the patch series posted to the Linux kernel mailing list, July 2026. PNG

Most frequency scaling patches arrive with a number in the low single digits and a long argument about whether the number is real. This one arrived with 31.8%, which is the kind of figure that makes you check what was measured before you get interested.

The problem is a thread that is busy and keeps napping

The default arrangement on modern AMD hardware hands a lot of authority to the processor. The kernel's amd_pstate driver, running in its active mode, does not pick a frequency directly. It passes the hardware a hint, the energy performance preference, and the hardware decides. That division of labour is deliberate and it usually works well, because the silicon can react faster than any kernel loop.

It works less well for one specific shape of workload. David Vernet, a kernel engineer at Meta, describes it in the cover letter: a workload dominated by one mostly busy thread that takes frequent short sleeps can fare poorly under this strategy. The thread does real work, blocks for a moment, wakes up and needs to be fast immediately. A balanced preference sees the sleeps and settles down. By the time it has ramped back up, the frame, or the request, is already late.

Games hit this constantly, which is why the benchmark is a game. So does a great deal of software that has nothing to do with graphics.

What the patch does about it

Terminal figure showing how to read the current AMD P-State operating mode and the per CPU energy performance preference from sysfs, along with the list of available preference values.
What to check on your own machine before deciding whether any of this applies to you. PNG

The mechanism is deliberately small. Turn it on with the amd_pstate.epp_boost=1 kernel parameter and an update util hook starts sampling. For each core it reads C0 residency, the share of time the core spent executing rather than idling, at most once every 10 ms. If a sample comes back showing the core at least 50% busy, the driver writes performance into that core's EPP field. The boost is then held until 300 ms pass with no further busy sample, at which point the previous request is put back.

That is the whole idea. It is per core rather than global, which is what keeps it from being equivalent to simply setting every CPU to performance and accepting the power cost. Cores that are genuinely idle stay in a balanced policy. Cores carrying the busy thread get pinned high, and stay pinned across the short sleeps that would otherwise let them drop.

Reading the two numbers

The Civilization VI benchmark on a Steam Deck gains 31.8% in 1% low frame rates. The p99 frame time gains 4.1%.

Both figures come from the same run, and the distance between them is informative rather than contradictory. 1% lows are the worst hundredth of frames, the ones most likely to have landed on a core that had just woken up at a low clock. That is precisely the population the boost is designed to rescue, so a large gain there and a modest one at the ninety ninth percentile is what a working mechanism should look like. A patch that moved every percentile by the same amount would be more suspicious, not less.

The caveat is the usual one. This is one game, on one handheld, on Van Gogh silicon. Nobody has published a server workload, a compile, or a desktop session measured the same way.

What we would check before caring

If you run AMD hardware and latency spikes are a live complaint, three things are worth knowing before the patch lands anywhere near you.

First, which driver mode you are actually in. amd_pstate has active, guided and passive modes, and the EPP hint only exists in the active one. Reading /sys/devices/system/cpu/amd_pstate/status tells you where you stand.

Second, what your current preference is. Each CPU exposes energy_performance_preference under /sys/devices/system/cpu/cpuN/cpufreq/, with the accepted values listed alongside it in energy_performance_available_preferences. If yours already says performance everywhere, this patch has nothing to give you and you have already paid its power bill.

Third, whether your problem has the right shape. The boost helps a thread that alternates between busy and briefly idle. It does nothing for a thread that is saturated continuously, because that thread already keeps the frequency high on its own.

Status

The series is on the kernel mailing list and under review. It has not been merged, no target release has been named, and per core hooks that run every 10 ms tend to attract careful questions about overhead before they go anywhere. Treat it as a proposal with an unusually good benchmark attached, and check back when a maintainer has weighed in.

Sources and further reading

Frequently asked questions

What is EPP, and why does it matter for latency?

EPP stands for energy performance preference. It is a hint the operating system passes to the processor's own hardware controller, telling it how far to lean toward performance versus power saving when it picks a frequency. On AMD systems running amd_pstate in active mode, the value lives in a sysfs file per CPU and accepts names such as performance, balance_performance, balance_power and power. The hardware still makes the final decision, which is the point of the design, but the hint changes how eagerly it ramps up. When the hint sits in a balanced position, a core that has just woken from a short sleep spends time climbing back to a useful frequency, and that climb is exactly what a latency sensitive workload feels.

What do the proposed patches actually change?

They add a module parameter, amd_pstate.epp_boost, that turns on a per core sampling loop. An update util hook reads each core's C0 residency, meaning the fraction of time it spent actually executing rather than idle, at most once every 10 ms. If a sample shows the core at least 50% busy, the driver writes performance into that core's EPP field. It then holds that setting until 300 ms elapse without another busy sample, at which point the previous request is restored. Nothing else about frequency selection changes. It is a targeted answer to one failure mode rather than a new governor.

Are the benchmark numbers from a real workload?

They come from the Civilization VI benchmark running on a Valve Steam Deck, which uses AMD's Van Gogh silicon. The headline figure is a 31.8% improvement in 1% low frame rates, with p99 frame time improving 4.1%. The gap between those two numbers is worth reading carefully. 1% lows describe the worst hundredth of frames, which is where a slow frequency ramp shows up most clearly, so a large gain there and a smaller one at p99 is consistent with the mechanism doing what it claims. It is one game on one handheld, so treat it as a strong signal rather than a general figure.

Does this only help gaming?

Gaming is where it was measured, not where the pattern ends. The developer describes the problem case as a workload dominated by one mostly busy thread that takes frequent short sleeps. That description also fits an interactive shell session, a request handler that blocks briefly on a socket or a disk, a build system waiting on a compiler subprocess, and a good deal of desktop software. Any of those can sit in the same trap: busy enough to need a high frequency, idle often enough that a balanced policy keeps dropping back down. Whether the gain is as large elsewhere is an open question that nobody has published numbers for.

Can I get any of this today without patching a kernel?

Partly. You cannot get the automatic per core boosting, because that is the new code. You can inspect and change the EPP hint yourself right now on a machine running amd_pstate in active mode, by reading and writing the energy_performance_preference file under each CPU in sysfs. Setting it to performance across the board is the blunt version of what the patch does selectively, and it costs you idle power everywhere rather than only on busy cores. On a plugged in workstation that trade is often acceptable. On a battery powered handheld it is precisely the trade the patch series exists to avoid.