[PATCH v2 2/2] cpufreq: fix schedutil not returning to non-boost freq when boost is disabled
From: Ananthu C V
Date: Tue Sep 08 2026 - 04:35:37 EST
Commit 538b0188da46 ("cpufreq: ACPI: Set cpuinfo.max_freq directly if
max boost is known") introduced a guard for cpuinfo max updates to only
increase, to preserve driver-set values above the freq table maximum,
causing cpuinfo max to be stuck at boost frequency even when boost is
disabled.
Unconditionally track the highest non-boost frequency (max_base_freq)
in the freq table. When a freq table is available, use max_table_freq/
max_base_freq instead of cpuinfo->max_freq to control boost values, so
the value can decrease again when boost is disabled.
Fixes: 538b0188da46 ("cpufreq: ACPI: Set cpuinfo.max_freq directly if max boost is known")
Signed-off-by: Ananthu C V <ananthu.cv@xxxxxxxxxxxxxxxx>
---
drivers/cpufreq/cpufreq.c | 14 +++++++++++++-
drivers/cpufreq/freq_table.c | 5 +++++
include/linux/cpufreq.h | 1 +
3 files changed, 19 insertions(+), 1 deletion(-)
diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c
index 0d0df986fa3d..a13e72711597 100644
--- a/drivers/cpufreq/cpufreq.c
+++ b/drivers/cpufreq/cpufreq.c
@@ -574,6 +574,7 @@ static ssize_t show_local_boost(struct cpufreq_policy *policy, char *buf)
static int policy_set_boost(struct cpufreq_policy *policy, bool enable)
{
+ unsigned int max_freq;
int ret;
if (policy->boost_enabled == enable)
@@ -587,7 +588,18 @@ static int policy_set_boost(struct cpufreq_policy *policy, bool enable)
return ret;
}
- ret = freq_qos_update_request(&policy->boost_freq_req, policy->cpuinfo.max_freq);
+ if (policy->freq_table) {
+ max_freq = enable ? policy->cpuinfo.max_table_freq :
+ policy->cpuinfo.max_base_freq;
+
+ if (!max_freq)
+ /* when the freq table contains only boost frequencies */
+ max_freq = policy->cpuinfo.max_table_freq;
+ } else {
+ max_freq = policy->cpuinfo.max_freq;
+ }
+
+ ret = freq_qos_update_request(&policy->boost_freq_req, max_freq);
if (ret < 0) {
policy->boost_enabled = !policy->boost_enabled;
cpufreq_driver->set_boost(policy, policy->boost_enabled);
diff --git a/drivers/cpufreq/freq_table.c b/drivers/cpufreq/freq_table.c
index 4984142dc08a..7e183e16162d 100644
--- a/drivers/cpufreq/freq_table.c
+++ b/drivers/cpufreq/freq_table.c
@@ -34,6 +34,7 @@ int cpufreq_frequency_table_cpuinfo(struct cpufreq_policy *policy)
unsigned int min_freq = ~0;
unsigned int max_freq = 0;
unsigned int max_table_freq = 0;
+ unsigned int max_base_freq = 0;
unsigned int freq, i;
cpufreq_for_each_valid_entry_idx(pos, table, i) {
@@ -42,6 +43,9 @@ int cpufreq_frequency_table_cpuinfo(struct cpufreq_policy *policy)
if (freq > max_table_freq)
max_table_freq = freq;
+ if (!(pos->flags & CPUFREQ_BOOST_FREQ) && freq > max_base_freq)
+ max_base_freq = freq;
+
if ((!cpufreq_boost_enabled() || !policy->boost_enabled)
&& (pos->flags & CPUFREQ_BOOST_FREQ))
continue;
@@ -62,6 +66,7 @@ int cpufreq_frequency_table_cpuinfo(struct cpufreq_policy *policy)
policy->cpuinfo.max_freq = max_freq;
policy->cpuinfo.max_table_freq = max_table_freq;
+ policy->cpuinfo.max_base_freq = max_base_freq;
if (min_freq == ~0)
return -EINVAL;
diff --git a/include/linux/cpufreq.h b/include/linux/cpufreq.h
index 3f3b1380251a..419c71ccff7c 100644
--- a/include/linux/cpufreq.h
+++ b/include/linux/cpufreq.h
@@ -46,6 +46,7 @@ struct cpufreq_cpuinfo {
unsigned int max_freq;
unsigned int min_freq;
unsigned int max_table_freq; /* Highest valid frequency in the table */
+ unsigned int max_base_freq; /* Highest non-boost frequency in the table */
/* in 10^(-9) s = nanoseconds */
unsigned int transition_latency;
--
2.43.0