Re: [PATCH] cpufreq: Use a non-boost reference frequency for pressure calculation
From: Rafael J. Wysocki
Date: Fri Sep 18 2026 - 14:19:57 EST
On Friday, September 18, 2026 6:08:49 AM Central European Summer Time Jianyong Wu wrote:
> Hi Rafael,
>
> >
> > On Sep 18, 2026, at 01:38, Rafael J. Wysocki (Intel) <rafael@xxxxxxxxxx> wrote:
> > On Tue, Sep 15, 2026 at 9:03 AM Jianyong Wu <wujianyong@xxxxxxxx> wrote:
> >>
> >> Commit d2d5c129d07e ("cpufreq: Make cpufreq_update_pressure() fall
> >> back to cpuinfo.max_freq") introduced cpuinfo.max_freq as the reference
> >> frequency for cpufreq pressure when arch_scale_freq_ref() returns zero.
> >>
> >> However, cpuinfo.max_freq may include boost frequencies and therefore
> >> does not necessarily represent the maximum sustainable frequency.
> >
> > And then it really matters what is sustainable and for how long.
>
> I think it's confusing to say "sustainable freq" in cpufreq part. I mean the maximum
> cpu frequency below boost here. For acpi-cpufreq, it’s P0. For amd-pstate, it’s
> nominal frequency. But I can't find a better word.
>
> >
> >> On some systems using acpi-cpufreq, cpuinfo.max_freq includes boost while
> >> the frequency table only contains non-boost frequencies.
> >
> > In which case selecting freq_table[0] may give the processor a license
> > to go to the turbo (or boost) frequency range.
>
> Yeah, selecting freq_table[0] may also mean cpu can go to boost frequency.
> But the value doesn't denote that. freq_table[0] is assigned to policy->max which
> is compared with policy->cpuinfo.max_freq. The difference between them makes
> the cpu pressure which is not intended.
>
> >
> >> Consequently, cpufreq pressure remains nonzero even without an additional
> >> frequency limit.
> >
> > So when and where does this matter?
>
> I test it on amd, intel and hygon box. Once acpi-cpufreq is used, the unexpected
> cpu pressure appears when there is no cpu frequency capped and boost is enabled.
>
> The wrong cpu pressure affects load balancing. For example, Cache aware
> scheduling wants to aggregate task in a LLC using 50% of the whole LLC capacity.
> Before commit d2d5c129d07e, everything is OK. But with that commit and using
> acpi-cpufreq and with boost on, cache aware scheduling can’t aggregate
> task to occupy 50% of the LLC by default as the cpu capacity in the LLC is reduced.
So actually the problem is that now the pressure is applied when it is not
expected to be applied in general.
Clearly, the scheduler assumes that the pressure will be zero when
arch_scale_freq_ref() is zero and the commit in question violates that
assumption.
This actually has a little to do with boost and making it depend on boost
doesn't really help. In fact, the reason for making the change was some
inadequate behavior when intel_pstate ran with asym capacity, so something
like the patch below (completely untested) can be used to limit the scope
of it to the case in question.
Can you please check if it helps?
Ricardo, can you please test this one too?
Thanks!
---
drivers/cpufreq/cpufreq.c | 4 ++--
drivers/cpufreq/intel_pstate.c | 12 ++++++++++++
include/linux/cpufreq.h | 3 +++
3 files changed, 17 insertions(+), 2 deletions(-)
--- a/drivers/cpufreq/cpufreq.c
+++ b/drivers/cpufreq/cpufreq.c
@@ -2590,8 +2590,8 @@ static void cpufreq_update_pressure(stru
cpu = cpumask_first(policy->related_cpus);
max_freq = arch_scale_freq_ref(cpu);
- if (!max_freq)
- max_freq = policy->cpuinfo.max_freq;
+ if (!max_freq && cpufreq_driver->scale_freq_ref)
+ max_freq = cpufreq_driver->scale_freq_ref(policy);
capped_freq = policy->max;
--- a/drivers/cpufreq/intel_pstate.c
+++ b/drivers/cpufreq/intel_pstate.c
@@ -1135,6 +1135,16 @@ static bool hybrid_clear_max_perf_cpu(vo
return ret;
}
+static unsigned int intel_pstate_scale_freq_ref(struct cpufreq_policy *policy)
+{
+ struct cpudata *cpu = all_cpu_data[policy->cpu];
+
+ if (cpu && cpu->capacity_perf)
+ return policy->cpuinfo.max_freq;
+
+ return 0;
+}
+
static void intel_pstate_update_freq_limits(struct cpudata *cpu)
{
int scaling = cpu->pstate.scaling;
@@ -3088,6 +3098,7 @@ static struct cpufreq_driver intel_pstat
.offline = intel_pstate_cpu_offline,
.online = intel_pstate_cpu_online,
.update_limits = intel_pstate_update_limits,
+ .scale_freq_ref = intel_pstate_scale_freq_ref,
.name = "intel_pstate",
};
@@ -3411,6 +3422,7 @@ static struct cpufreq_driver intel_cpufr
.suspend = intel_cpufreq_suspend,
.resume = intel_pstate_resume,
.update_limits = intel_pstate_update_limits,
+ .scale_freq_ref = intel_pstate_scale_freq_ref,
.name = "intel_cpufreq",
};
--- a/include/linux/cpufreq.h
+++ b/include/linux/cpufreq.h
@@ -420,6 +420,9 @@ struct cpufreq_driver {
/* Will be called after the driver is fully initialized */
void (*ready)(struct cpufreq_policy *policy);
+ /* Return the capacity reference frequency for policy. */
+ unsigned int (*scale_freq_ref)(struct cpufreq_policy *policy);
+
struct freq_attr **attr;
/* platform specific boost support code */