[RFC PATCH 0/4] ACPI: processor: thermal: Recompute the frequency cap when boost changes
From: Hugo Sales
Date: Sun Nov 01 2026 - 14:00:50 EST
thermal_req is a fixed fraction of policy->cpuinfo.max_freq, computed
only when the cooling state is written, so it keeps the boost state of
that moment. The ACPI thermal zone writes step 0 on every resume, and
step 0 caps at cpuinfo.max_freq, so if boost was off at suspend, turning
it on after resume leaves the CPUs at their base clock. Steps 1 to 3 go
stale the same way
Ashton A. sent a one-line fix for the resume case, which stops step 0
from setting a cap. It fixes the resume case on my laptop, and my
Tested-by is in that thread:
https://lore.kernel.org/all/20261028-acpi-thermal-stale-limit-v1-1-4b0ab3230f01@xxxxxxxxxxxxxxxx/
That patch is small, easy to backport and enough to fix the biggest
issue. This series applies on its own to bleeding-edge and fixes the
resume case and steps 1 to 3 by recomputing the cap when boost changes,
so please take one or the other, not both
Before d15ce412737a the CPUFREQ_ADJUST notifier recomputed the cap on
every policy update. This series brings that back without letting a
notifier touch the policy:
1. cpufreq core: a CPUFREQ_UPDATE_CPUINFO policy notifier event, sent
from policy_set_boost() after ->set_boost(). That covers
amd-pstate, cppc_cpufreq and the cpufreq_boost_set_sw() drivers
2. intel_pstate: send it from __intel_pstate_update_max_freq(), since
no_turbo and HWP capability changes don't go through ->set_boost()
3. processor_thermal: factor out the thermal_req update
4. processor_thermal: recompute thermal_req on the new event, from the
step each request was last set to, under a mutex shared with
cpufreq_set_cur_state() and the request add and remove
Step 0 still sets a cap here, and patch 4 recomputes it with the other
steps, so the resume case needs no special case
The freq QoS notifiers can't do this. They fire only when the aggregate
limit changes, and while the thermal cap is below both maximums,
turning boost on moves boost_freq_req without moving the aggregate
I also looked at basing the steps on a fixed reference frequency, the
way cpufreq_cooling uses absolute table frequencies. There is no generic
way to read the boost maximum while boost is off (amd-pstate and cppc
keep it in driver data), and with boost off step 1 would often not
throttle at all
Rafael, Viresh, which do you prefer? This series adds a cpufreq event
with one user. If that isn't worth it, I'm happy to drop it and keep my
Tested-by on Ashton's patch
Tested on my laptop (Ryzen 9 5980HS, amd-pstate-epp) with the series
backported to 7.3. With boost off and cooling state 1, cpu0's
scaling_max_freq is 2640800, 80% of 3301000. Turning boost on raises it
to 3879405, 80% of 4849257, and turning boost off brings it back down.
Step 2 follows boost the same way, and at step 0 turning boost on gives
the full 4849257. Toggling boost while writing cooling states on all 16
CPUs left nothing in the kernel log, on a kernel without lockdep
Patch 1 changes Documentation/cpu-freq/core.rst only. Its zh_CN and
zh_TW translations need the same update from someone who can review
them
Hugo Sales (4):
cpufreq: Add a CPUFREQ_UPDATE_CPUINFO policy notifier event
cpufreq: intel_pstate: Send CPUFREQ_UPDATE_CPUINFO on max_freq changes
ACPI: processor: thermal: Factor out the thermal_req update
ACPI: processor: thermal: Recompute the frequency cap when boost
changes
Documentation/cpu-freq/core.rst | 9 +++--
drivers/acpi/processor_driver.c | 2 ++
drivers/acpi/processor_thermal.c | 58 ++++++++++++++++++++++++++------
drivers/cpufreq/cpufreq.c | 16 +++++++++
drivers/cpufreq/intel_pstate.c | 8 ++++-
include/acpi/processor.h | 4 +++
include/linux/cpufreq.h | 2 ++
7 files changed, 85 insertions(+), 14 deletions(-)
base-commit: 5854d2ce4b0b9ccb37b154319d8283bad889a694
--
2.56.0