[PATCH v3 1/2] arch_topology: seed capacity_freq_ref with highest available frequency

From: Ananthu C V

Date: Tue Sep 29 2026 - 07:40:47 EST


capacity_freq_ref, the per-CPU frequency-invariance reference used by
schedutil, is seeded from policy->cpuinfo.max_freq at policy creation.
If boost isn't enabled yet at boot, max_freq reflects only 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.

Seed capacity_freq_ref with the highest available frequency regardless
of whether boost is 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 ++-
include/linux/cpufreq.h | 13 +++++++++++++
2 files changed, 15 insertions(+), 1 deletion(-)

diff --git a/drivers/base/arch_topology.c b/drivers/base/arch_topology.c
index 8c5e47c28d9a..92966be712d5 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,
+ cpufreq_frequency_table_max(policy));
freq_inv_set_max_ratio(cpu,
per_cpu(capacity_freq_ref, cpu) * HZ_PER_KHZ);
}
diff --git a/include/linux/cpufreq.h b/include/linux/cpufreq.h
index 35ce665edfd8..f048c925fd98 100644
--- a/include/linux/cpufreq.h
+++ b/include/linux/cpufreq.h
@@ -1107,6 +1107,19 @@ static inline int cpufreq_frequency_table_target(struct cpufreq_policy *policy,
return idx;
}

+static inline unsigned int cpufreq_frequency_table_max(struct cpufreq_policy *policy)
+{
+ int idx;
+
+ if (!policy->freq_table)
+ return policy->cpuinfo.max_freq;
+
+ idx = cpufreq_frequency_table_target(policy, UINT_MAX, 0, UINT_MAX,
+ CPUFREQ_RELATION_H);
+
+ return policy->freq_table[idx].frequency;
+}
+
static inline int cpufreq_table_count_valid_entries(const struct cpufreq_policy *policy)
{
struct cpufreq_frequency_table *pos;

--
2.43.0