* [PATCH] cpufreq: cppc: discard out-of-range delivered_perf samples
@ 2026-05-01 16:32 Breno Leitao
2026-05-01 17:41 ` Jeremy Linton
0 siblings, 1 reply; 3+ messages in thread
From: Breno Leitao @ 2026-05-01 16:32 UTC (permalink / raw)
To: Rafael J. Wysocki, Viresh Kumar, Jie Zhan, Lifeng Zheng,
Pierre Gondois, Sumit Gupta
Cc: linux-pm, linux-kernel, dcostantino, pjaroszynski, Al.Grant,
linux-arm-kernel, kernel-team, Breno Leitao
cppc_cpufreq_get_rate() derives delivered_perf as:
delivered_perf = reference_perf * delta_delivered / delta_reference
over a short udelay()-bounded window between two cppc_get_perf_ctrs()
calls. Per-read latency jitter on the underlying CPC register access
can skew the ratio, occasionally producing delivered_perf >
highest_perf. cppc_perf_to_khz() then linearly extrapolates above
(nominal_perf, nominal_freq), so the value reported via
/sys/.../cpufreq/cpuinfo_cur_freq exceeds cpuinfo_max_freq.
Observed on an arm64 host (governor=performance,
cpuinfo_max_freq=3339 MHz): 15 back-to-back reads returned values
between 2997 and 4230 MHz.
Treat an out-of-range sample as invalid and reuse the existing
out_invalid_counters fallback, which returns the platform's
desired_perf. This keeps cpuinfo_cur_freq within
[0, cpuinfo_max_freq] without reporting a value the hardware did
not deliver.
Signed-off-by: Breno Leitao <leitao@debian.org>
---
drivers/cpufreq/cppc_cpufreq.c | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/drivers/cpufreq/cppc_cpufreq.c b/drivers/cpufreq/cppc_cpufreq.c
index 7e7f9dfb7a24c..dd92aa2bca464 100644
--- a/drivers/cpufreq/cppc_cpufreq.c
+++ b/drivers/cpufreq/cppc_cpufreq.c
@@ -814,6 +814,14 @@ static unsigned int cppc_cpufreq_get_rate(unsigned int cpu)
if (!delivered_perf)
goto out_invalid_counters;
+ /*
+ * Sampling jitter on the CPC counter pair can produce
+ * delivered_perf > highest_perf, which cppc_perf_to_khz() would
+ * extrapolate to a frequency above cpuinfo_max_freq. Discard.
+ */
+ if (delivered_perf > cpu_data->perf_caps.highest_perf)
+ goto out_invalid_counters;
+
return cppc_perf_to_khz(&cpu_data->perf_caps, delivered_perf);
out_invalid_counters:
---
base-commit: 26fd6bff2c050196005312d1d306889220952a99
change-id: 20260501-cur_freq-fix-d569cf1d1052
Best regards,
--
Breno Leitao <leitao@debian.org>
^ permalink raw reply related [flat|nested] 3+ messages in thread* Re: [PATCH] cpufreq: cppc: discard out-of-range delivered_perf samples
2026-05-01 16:32 [PATCH] cpufreq: cppc: discard out-of-range delivered_perf samples Breno Leitao
@ 2026-05-01 17:41 ` Jeremy Linton
2026-05-05 12:52 ` Breno Leitao
0 siblings, 1 reply; 3+ messages in thread
From: Jeremy Linton @ 2026-05-01 17:41 UTC (permalink / raw)
To: Breno Leitao, Rafael J. Wysocki, Viresh Kumar, Jie Zhan,
Lifeng Zheng, Pierre Gondois, Sumit Gupta
Cc: linux-pm, linux-kernel, dcostantino, pjaroszynski, Al.Grant,
linux-arm-kernel, kernel-team
Hi,
On 5/1/26 11:32 AM, Breno Leitao wrote:
> cppc_cpufreq_get_rate() derives delivered_perf as:
>
> delivered_perf = reference_perf * delta_delivered / delta_reference
>
> over a short udelay()-bounded window between two cppc_get_perf_ctrs()
> calls. Per-read latency jitter on the underlying CPC register access
> can skew the ratio, occasionally producing delivered_perf >
> highest_perf. cppc_perf_to_khz() then linearly extrapolates above
> (nominal_perf, nominal_freq), so the value reported via
> /sys/.../cpufreq/cpuinfo_cur_freq exceeds cpuinfo_max_freq.
>
> Observed on an arm64 host (governor=performance,
> cpuinfo_max_freq=3339 MHz): 15 back-to-back reads returned values
> between 2997 and 4230 MHz.
>
> Treat an out-of-range sample as invalid and reuse the existing
> out_invalid_counters fallback, which returns the platform's
> desired_perf. This keeps cpuinfo_cur_freq within
> [0, cpuinfo_max_freq] without reporting a value the hardware did
> not deliver.
>
> Signed-off-by: Breno Leitao <leitao@debian.org>
> ---
> drivers/cpufreq/cppc_cpufreq.c | 8 ++++++++
> 1 file changed, 8 insertions(+)
>
> diff --git a/drivers/cpufreq/cppc_cpufreq.c b/drivers/cpufreq/cppc_cpufreq.c
> index 7e7f9dfb7a24c..dd92aa2bca464 100644
> --- a/drivers/cpufreq/cppc_cpufreq.c
> +++ b/drivers/cpufreq/cppc_cpufreq.c
> @@ -814,6 +814,14 @@ static unsigned int cppc_cpufreq_get_rate(unsigned int cpu)
> if (!delivered_perf)
> goto out_invalid_counters;
>
> + /*
> + * Sampling jitter on the CPC counter pair can produce
> + * delivered_perf > highest_perf, which cppc_perf_to_khz() would
> + * extrapolate to a frequency above cpuinfo_max_freq. Discard.
> + */
> + if (delivered_perf > cpu_data->perf_caps.highest_perf)
> + goto out_invalid_counters;
> +
A little jitter over, is probably expected. If that is what is happening
then clamping to highest_perf makes sense instead. But then, this is
really a sampling problem so does it go away if you double the udelay
slightly. Maybe the udelay value should be proportional to the
reference_perf value?
> return cppc_perf_to_khz(&cpu_data->perf_caps, delivered_perf);
>
> out_invalid_counters:
>
> ---
> base-commit: 26fd6bff2c050196005312d1d306889220952a99
> change-id: 20260501-cur_freq-fix-d569cf1d1052
>
> Best regards,
> --
> Breno Leitao <leitao@debian.org>
>
>
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [PATCH] cpufreq: cppc: discard out-of-range delivered_perf samples
2026-05-01 17:41 ` Jeremy Linton
@ 2026-05-05 12:52 ` Breno Leitao
0 siblings, 0 replies; 3+ messages in thread
From: Breno Leitao @ 2026-05-05 12:52 UTC (permalink / raw)
To: Jeremy Linton
Cc: Rafael J. Wysocki, Viresh Kumar, Jie Zhan, Lifeng Zheng,
Pierre Gondois, Sumit Gupta, linux-pm, linux-kernel, dcostantino,
pjaroszynski, Al.Grant, linux-arm-kernel, kernel-team
Hello Jeremy,
On Fri, May 01, 2026 at 12:41:45PM -0500, Jeremy Linton wrote:
> A little jitter over, is probably expected. If that is what is happening
> then clamping to highest_perf makes sense instead.
Based on my analysis of the code, interrupts appear to remain enabled
during the delay, which could introduce significant jitter if an IRQ
fires during that window.
I'd be interested in testing this under an IRQ storm to quantify the
actual impact on the measurements.
> But then, this is really
> a sampling problem so does it go away if you double the udelay slightly.
> Maybe the udelay value should be proportional to the reference_perf value?
That's a reasonable approach. What would you suggest for the
implementation?
I considered making it a kernel or module parameter, but I'm not certain
that's the best solution, since the "user" might not know what to
set/use.
Thanks for your review,
--breno
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2026-05-05 12:52 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-05-01 16:32 [PATCH] cpufreq: cppc: discard out-of-range delivered_perf samples Breno Leitao
2026-05-01 17:41 ` Jeremy Linton
2026-05-05 12:52 ` Breno Leitao
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox