mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [PATCH] cpufreq: Use a non-boost reference frequency for pressure calculation
@ 2026-09-15  6:57 Jianyong Wu
  2026-09-15  9:32 ` Hongyan Xia
  0 siblings, 1 reply; 3+ messages in thread
From: Jianyong Wu @ 2026-09-15  6:57 UTC (permalink / raw)
  To: rafael, viresh.kumar, kprateek.nayak, vincent.guittot
  Cc: linux-pm, linux-kernel, ray.huang, mario.limonciello, perry.yuan,
	zhanjie9, zhenglifeng1, pierre.gondois, sumitg,
	srinivas.pandruvada, lenb, hongyan.xia, zhongqiu.han, wujianyong,
	jianyong.wu, wangfengyu, zhongyuan, huangsj

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. On
some systems using acpi-cpufreq, cpuinfo.max_freq includes boost while
the frequency table only contains non-boost frequencies. Consequently,
cpufreq pressure remains nonzero even without an additional frequency
limit.

Furthermore, drivers may update cpuinfo.max_freq when boost is enabled
or disabled. With a fixed policy limit below the maximum non-boost
frequency, this changes the pressure reference and hence the reported
pressure, although the non-boost frequency limit remains unchanged.

Add max_sustainable_freq to struct cpufreq_cpuinfo to provide a reference
frequency excluding boost. Populate it from the nominal frequency in
amd-pstate and cppc_cpufreq, the maximum non-turbo frequency in
intel_pstate, and the highest frequency-table entry in acpi-cpufreq.

Use this value when arch_scale_freq_ref() returns zero. Preserve the
existing cpuinfo.max_freq fallback for drivers that leave the new field
at zero.

Tested with acpi-cpufreq, intel_pstate, and amd-pstate in active and
passive modes. With no additional frequency limit, pressure is zero.
With a fixed limit below the non-boost reference frequency, pressure
remains unchanged across boost transitions.

Fixes: d2d5c129d07e ("cpufreq: Make cpufreq_update_pressure() fall back to cpuinfo.max_freq")
Signed-off-by: Jianyong Wu <wujianyong@hygon.cn>
---
The earlier fix was incorrect and has been abandoned. This patch takes
a different approach.

Previous discussion: https://lore.kernel.org/all/SI2PR04MB4931A8BA0EF213B0238BD9E4E3BD2@SI2PR04MB4931.apcprd04.prod.outlook.com/

 drivers/cpufreq/acpi-cpufreq.c | 3 +++
 drivers/cpufreq/amd-pstate.c   | 2 ++
 drivers/cpufreq/cppc_cpufreq.c | 3 ++-
 drivers/cpufreq/cpufreq.c      | 4 +++-
 drivers/cpufreq/intel_pstate.c | 2 ++
 include/linux/cpufreq.h        | 2 ++
 6 files changed, 14 insertions(+), 2 deletions(-)

diff --git a/drivers/cpufreq/acpi-cpufreq.c b/drivers/cpufreq/acpi-cpufreq.c
index 21639d9ac753..e7b22456ebb8 100644
--- a/drivers/cpufreq/acpi-cpufreq.c
+++ b/drivers/cpufreq/acpi-cpufreq.c
@@ -856,6 +856,9 @@ static int acpi_cpufreq_cpu_init(struct cpufreq_policy *policy)
 	}
 	freq_table[valid_states].frequency = CPUFREQ_TABLE_END;
 
+	/* Init max sustainable cpu frequency */
+	policy->cpuinfo.max_sustainable_freq = freq_table[0].frequency;
+
 	max_boost_ratio = get_max_boost_ratio(cpu, &nominal_freq);
 	if (max_boost_ratio) {
 		unsigned int freq = nominal_freq;
diff --git a/drivers/cpufreq/amd-pstate.c b/drivers/cpufreq/amd-pstate.c
index 3a6b4b224a66..6fc28bb1499b 100644
--- a/drivers/cpufreq/amd-pstate.c
+++ b/drivers/cpufreq/amd-pstate.c
@@ -1085,6 +1085,7 @@ static int amd_pstate_cpu_init(struct cpufreq_policy *policy)
 						perf.lowest_perf);
 	policy->cpuinfo.max_freq = cpudata->max_freq;
 
+	policy->cpuinfo.max_sustainable_freq = cpudata->nominal_freq;
 	policy->driver_data = cpudata;
 	ret = amd_pstate_cppc_enable(policy);
 	if (ret)
@@ -1912,6 +1913,7 @@ static int amd_pstate_epp_cpu_init(struct cpufreq_policy *policy)
 	policy->cpuinfo.min_freq = perf_to_freq(perf, cpudata->nominal_freq,
 						perf.lowest_perf);
 	policy->cpuinfo.max_freq = cpudata->max_freq;
+	policy->cpuinfo.max_sustainable_freq = cpudata->nominal_freq;
 	policy->driver_data = cpudata;
 
 	ret = amd_pstate_cppc_enable(policy);
diff --git a/drivers/cpufreq/cppc_cpufreq.c b/drivers/cpufreq/cppc_cpufreq.c
index 6fe0e972952a..f803fcdca483 100644
--- a/drivers/cpufreq/cppc_cpufreq.c
+++ b/drivers/cpufreq/cppc_cpufreq.c
@@ -682,7 +682,8 @@ static int cppc_cpufreq_cpu_init(struct cpufreq_policy *policy)
 	policy->cpuinfo.min_freq = cppc_perf_to_khz(caps, caps->lowest_perf);
 	policy->cpuinfo.max_freq = cppc_perf_to_khz(caps, policy->boost_enabled ?
 						    caps->highest_perf : caps->nominal_perf);
-
+	policy->cpuinfo.max_sustainable_freq =
+		cppc_perf_to_khz(caps, caps->nominal_perf);
 	policy->transition_delay_us = cppc_cpufreq_get_transition_delay_us(cpu);
 	policy->shared_type = cpu_data->shared_type;
 
diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c
index b898b6544069..c1d54a22265d 100644
--- a/drivers/cpufreq/cpufreq.c
+++ b/drivers/cpufreq/cpufreq.c
@@ -2587,7 +2587,9 @@ static void cpufreq_update_pressure(struct cpufreq_policy *policy)
 	cpu = cpumask_first(policy->related_cpus);
 	max_freq = arch_scale_freq_ref(cpu);
 	if (!max_freq)
-		max_freq = policy->cpuinfo.max_freq;
+		max_freq = policy->cpuinfo.max_sustainable_freq ?
+				 policy->cpuinfo.max_sustainable_freq :
+				 policy->cpuinfo.max_freq;
 
 	capped_freq = policy->max;
 
diff --git a/drivers/cpufreq/intel_pstate.c b/drivers/cpufreq/intel_pstate.c
index 6e984c114d96..daef7e99fead 100644
--- a/drivers/cpufreq/intel_pstate.c
+++ b/drivers/cpufreq/intel_pstate.c
@@ -1474,6 +1474,7 @@ static void __intel_pstate_update_max_freq(struct cpufreq_policy *policy,
 
 	policy->cpuinfo.max_freq = READ_ONCE(global.no_turbo) ?
 			cpudata->pstate.max_freq : cpudata->pstate.turbo_freq;
+	policy->cpuinfo.max_sustainable_freq = cpudata->pstate.max_freq;
 
 	refresh_frequency_limits(policy);
 }
@@ -3052,6 +3053,7 @@ static int __intel_pstate_cpu_init(struct cpufreq_policy *policy)
 	policy->cpuinfo.min_freq = cpu->pstate.min_freq;
 	policy->cpuinfo.max_freq = READ_ONCE(global.no_turbo) ?
 			cpu->pstate.max_freq : cpu->pstate.turbo_freq;
+	policy->cpuinfo.max_sustainable_freq = cpu->pstate.max_freq;
 
 	intel_pstate_init_acpi_perf_limits(policy);
 
diff --git a/include/linux/cpufreq.h b/include/linux/cpufreq.h
index ae9d1ce4f49c..aa3f60a167be 100644
--- a/include/linux/cpufreq.h
+++ b/include/linux/cpufreq.h
@@ -45,6 +45,8 @@ enum cpufreq_table_sorting {
 struct cpufreq_cpuinfo {
 	unsigned int		max_freq;
 	unsigned int		min_freq;
+	/* Maximum sustainable frequency excluding boost, or 0 if unknown. */
+	unsigned int		max_sustainable_freq;
 
 	/* in 10^(-9) s = nanoseconds */
 	unsigned int		transition_latency;
-- 
2.34.1



^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2026-09-15 12:46 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-09-15  6:57 [PATCH] cpufreq: Use a non-boost reference frequency for pressure calculation Jianyong Wu
2026-09-15  9:32 ` Hongyan Xia
2026-09-15 12:46   ` Jianyong Wu

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®