From: Prashant Malani pmalani@google.com
[ Upstream commit 0a1416a49e63c320f6e6c1c8d07e1b58c0d4a3f3 ]
AMU counters on certain CPPC-based platforms tend to yield inaccurate delivered performance measurements on systems that are idle/mostly idle. This results in an inaccurate frequency being stored by cpufreq in its policy structure when the CPU is brought online. [1]
Consequently, if the userspace governor tries to set the frequency to a new value, there is a possibility that it would be the erroneous value stored earlier. In such a scenario, cpufreq would assume that the requested frequency has already been set and return early, resulting in the correct/new frequency request never making it to the hardware.
Since the operating frequency is liable to this sort of inconsistency, mark the CPPC driver with CPUFREQ_NEED_UPDATE_LIMITS so that it is always invoked when a target frequency update is requested.
Link: https://lore.kernel.org/linux-pm/20250619000925.415528-3-pmalani@google.com/ [1] Suggested-by: Rafael J. Wysocki rafael.j.wysocki@intel.com Signed-off-by: Prashant Malani pmalani@google.com Acked-by: Viresh Kumar viresh.kumar@linaro.org Link: https://patch.msgid.link/20250722055611.130574-2-pmalani@google.com Signed-off-by: Rafael J. Wysocki rafael.j.wysocki@intel.com Signed-off-by: Sasha Levin sashal@kernel.org ---
LLM Generated explanations, may be completely bogus:
**Backport Status: YES**
This commit should be backported to stable kernel trees. Here's my extensive analysis:
## Code Change Analysis
The change is minimal and focused - it only adds the `CPUFREQ_NEED_UPDATE_LIMITS` flag to the cppc_cpufreq_driver struct:
```c - .flags = CPUFREQ_CONST_LOOPS, + .flags = CPUFREQ_CONST_LOOPS | CPUFREQ_NEED_UPDATE_LIMITS, ```
This single-line change modifies the driver flags in drivers/cpufreq/cppc_cpufreq.c:928.
## Bug Being Fixed
The commit addresses a real bug where:
1. **AMU counters on CPPC platforms provide inaccurate measurements** when systems are idle/mostly idle 2. **This causes cpufreq to store incorrect frequency values** in its policy structure during CPU online 3. **Userspace frequency changes fail silently** because cpufreq's early return optimization (`if (target_freq == policy->cur)`) prevents the hardware from receiving the correct frequency request
The bug manifests as userspace being unable to set CPU frequencies correctly on affected CPPC platforms, which is a functional regression that impacts power management and performance.
## Why This Qualifies for Stable
1. **Fixes a real bug**: The issue prevents proper CPU frequency scaling on CPPC-based platforms, affecting power management functionality
2. **Minimal risk**: The change is extremely small (one flag addition) and well-contained to the CPPC driver
3. **Clear fix semantics**: The `CPUFREQ_NEED_UPDATE_LIMITS` flag is an established mechanism (introduced in commit 1c534352f47f) specifically designed for this scenario where drivers need frequency updates even when target_freq == policy->cur
4. **Similar precedent**: Other cpufreq drivers (intel_pstate, amd- pstate) already use this flag for similar reasons, showing it's a proven solution
5. **No architectural changes**: This doesn't introduce new features or change kernel architecture - it simply ensures the driver behaves correctly
6. **Recent related fixes**: The git history shows ongoing work to fix CPPC feedback counter issues (e.g., commit c47195631960), indicating this is part of stabilizing CPPC functionality
## Impact Assessment
- **Affected systems**: CPPC-based platforms with AMU counters that exhibit the idle measurement issue - **Risk**: Very low - the flag only bypasses an optimization when needed, forcing frequency updates to reach hardware - **Testing**: The change has been acked by the cpufreq maintainer (Viresh Kumar) and suggested by the PM subsystem maintainer (Rafael J. Wysocki)
The commit follows stable tree rules by fixing an important bug with minimal changes and low regression risk.
drivers/cpufreq/cppc_cpufreq.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/cpufreq/cppc_cpufreq.c b/drivers/cpufreq/cppc_cpufreq.c index b7c688a5659c..c8e63c7aa9a3 100644 --- a/drivers/cpufreq/cppc_cpufreq.c +++ b/drivers/cpufreq/cppc_cpufreq.c @@ -925,7 +925,7 @@ static struct freq_attr *cppc_cpufreq_attr[] = { };
static struct cpufreq_driver cppc_cpufreq_driver = { - .flags = CPUFREQ_CONST_LOOPS, + .flags = CPUFREQ_CONST_LOOPS | CPUFREQ_NEED_UPDATE_LIMITS, .verify = cppc_verify_policy, .target = cppc_cpufreq_set_target, .get = cppc_cpufreq_get_rate,