Re: [PATCH v2 1/2] arch_topology: seed capacity_freq_ref with boost-aware max freq

From: Vincent Guittot

Date: Fri Sep 18 2026 - 09:58:26 EST


On Fri, 18 Sept 2026 at 15:34, Rafael J. Wysocki (Intel)
<rafael@xxxxxxxxxx> wrote:
>
> On Fri, Sep 18, 2026 at 2:36 PM Vincent Guittot
> <vincent.guittot@xxxxxxxxxx> wrote:
> >
> > On Fri, 18 Sept 2026 at 14:05, Rafael J. Wysocki (Intel)
> > <rafael@xxxxxxxxxx> wrote:
> > >
> > > On Fri, Sep 18, 2026 at 8:24 AM Vincent Guittot
> > > <vincent.guittot@xxxxxxxxxx> wrote:
> > > >
> > > > On Thu, 17 Sept 2026 at 21:07, Rafael J. Wysocki (Intel)
> > > > <rafael@xxxxxxxxxx> wrote:
> > > > >
> > > > > On Tue, Sep 8, 2026 at 10:31 AM Ananthu C V <ananthu.cv@xxxxxxxxxxxxxxxx> wrote:
> > > > > >
> > > > > > capacity_freq_ref, the per-CPU frequency-invariance reference used by
> > > > > > schedutil, is seeded from policy->cpuinfo.max_freq at policy creation.
> > > > > > If boost frequencies are filtered out of the frequency table because
> > > > > > boost isn't yet enabled at boot, max_freq only reflects the non-boost
> > > > > > ceiling, so capacity_freq_ref never learns about boost frequencies for
> > > > > > the policy's lifetime. Enabling boost later raises policy->max, but
> > > > > > capacity_freq_ref stays stale, leaving schedutil unable to scale
> > > > > > utilization or target a frequency above the non-boost maximum.
> > > > > >
> > > > > > Track the highest frequency in the table regardless of boost state
> > > > > > (max_table_freq) and seed capacity_freq_ref with max(cpuinfo.max_freq,
> > > > > > max_table_freq), so the invariance reference is boost-aware from boot
> > > > > > regardless of whether boost is currently enabled. Runtime enforcement,
> > > > > > still handled by policy->max, is unaffected.
> > > > > >
> > > > > > Suggested-by: Vincent Guittot <vincent.guittot@xxxxxxxxxx>
> > > > > > Signed-off-by: Ananthu C V <ananthu.cv@xxxxxxxxxxxxxxxx>
> > > > > > ---
> > > > > > drivers/base/arch_topology.c | 3 ++-
> > > > > > drivers/cpufreq/freq_table.c | 6 ++++++
> > > > > > include/linux/cpufreq.h | 1 +
> > > > > > 3 files changed, 9 insertions(+), 1 deletion(-)
> > > > > >
> > > > > > diff --git a/drivers/base/arch_topology.c b/drivers/base/arch_topology.c
> > > > > > index 8c5e47c28d9a..da94f77441da 100644
> > > > > > --- a/drivers/base/arch_topology.c
> > > > > > +++ b/drivers/base/arch_topology.c
> > > > > > @@ -404,7 +404,8 @@ init_cpu_capacity_callback(struct notifier_block *nb,
> > > > > > cpumask_andnot(cpus_to_visit, cpus_to_visit, policy->related_cpus);
> > > > > >
> > > > > > for_each_cpu(cpu, policy->related_cpus) {
> > > > > > - per_cpu(capacity_freq_ref, cpu) = policy->cpuinfo.max_freq;
> > > > > > + per_cpu(capacity_freq_ref, cpu) = max(policy->cpuinfo.max_freq,
> > > > > > + policy->cpuinfo.max_table_freq);
> > > > >
> > > > > So isn't capacity_freq_ref supposed to correspond to the CPU capacity
> > > > > returned by arch_scale_cpu_capacity()?
> > > >
> > > > capacity_freq_ref is the frequency that has been used when computing
> > > > the capacity at boot
> > >
> > > I get it, and so it is what I wrote above: The frequency of the CPU
> > > when running at the arch_scale_cpu_capacity() performance level.
> > > Isn't it?
> >
> > Original it was not strictly tight to arch_scale_cpu_capacity but to a
> > ref capacity but it ended up being arch_scale_cpu_capacity
>
> OK
>
> > >
> > > > and it should not change at runtime wether the
> > > > boost is enabled or not, otherwise you will have some fluctuation on
> > > > the system capacity that will create issue with PELT and scheduler
> > >
> > > So the capacity should be constant and consequently, capacity_freq_ref
> > > should be constant.
> > >
> > > Also, if boost is not enabled when capacity_freq_ref is set and there
> > > are frequency levels marked as "boost" in the table, it cannot be the
> > > maximum frequency in the table because that's not what is used for
> > > computing the capacity.
> >
> > I'm not sure I follow your last point above. It's not because boost
> > isn't enabled at boot time that we can't the highest boost OPP in the
> > table as a ref freq to compute arch_scale_cpu_capacity. In this case,
> > the CPU will have a pressure on its capacity until the boost is
> > enabled. Do I miss something ?
>
> Well, I'm not sure if my understanding is correct.
>
> Suppose that the cpufreq driver has a frequency table which is
> processed by cpufreq_table_validate_and_sort(), right after the
> driver's ->init() has returned.
>
> That function calls cpufreq_frequency_table_cpuinfo() for the first
> time and policy->cpuinfo.max_freq is set. However, if boost is not
> enabled (that is, cpufreq_boost_enabled() returns false or
> policy->boost_enabled is false), it only takes frequency table entries
> without CPUFREQ_BOOST_FREQ into account, so policy->cpuinfo.max_freq
> is one of those frequencies.
>
> I would think that the CPU capacity has already been set at this point
> and now the question arises whether or not it corresponds to
> policy->cpuinfo.max_freq because that is what is assumed by
> init_cpu_capacity_callback() invoked subsequently (via the
> cpufreq_policy_notifier_list chain).

init_cpu_capacity_callback() will normalize the capacity of all CPUs
once all cpufreq drivers have been probed and it will then trigger a
rebuild of the sched domain with these final CPUs' capacity

>
> The $subject patch seems to suggest that the answer is "no" and the
> capacity really corresponds to the highest frequency in the table
> which may be flagged with CPUFREQ_BOOST_FREQ. Is that always the case
> though and if not, then how can we tell?
>
> > Can the boost OPP be added later?
>
> Not really. It is already there in the frequency table, but the
> question is if that's the capacity OPP. I guess we need to assume so?

okay, I was just to confirm that this can't happen

>
> > We keep taking the max between freq table and cpuinfo.max_freq fo the
> > case where the boost freq is not listed is the freq table or there
> > isno freq table. Or there is another way to get teh boost freq in thsi
> > later case ?
>
> No, I think it's the only way.
>
> So init_cpu_capacity_callback() should find the highest frequency in
> the table (regardless of whether or not the "boost" flag is set) and
> set capacity_freq_ref to that one for each CPU UUIC.

yes

>
> That's roughly what the patch does, but it can get away without adding
> a new field to struct cpufreq_policy.

Yes, That was my point: we don't need a new field to find the highest
frequency in the table (including Boost OPP)

Thanks

>
> And the changelog needs to be rewritten to tell the true story.