* [PATCH v3 0/4] cpufreq: intel_pstate: A fix and some cleanups
@ 2026-06-24 17:32 Rafael J. Wysocki
2026-06-24 17:33 ` [PATCH v3 1/4] cpufreq: intel_pstate: Fix setting minimum P-state at init time Rafael J. Wysocki
` (4 more replies)
0 siblings, 5 replies; 6+ messages in thread
From: Rafael J. Wysocki @ 2026-06-24 17:32 UTC (permalink / raw)
To: Linux PM; +Cc: LKML, Srinivas Pandruvada, Doug Smythies
Hi,
This replaces
https://lore.kernel.org/linux-pm/6005456.DvuYhMxLoT@rafael.j.wysocki/
and drops the most significant change in it which was making intel_pstate
set cpuinfo_min_freq to a lower value with HWP enabled. That change
went too far and needs to be reconsidered.
The other changes in the series, and in particular the fix in the first
patch, are useful and will facilitate further improvements, so here
they go.
This series is independent of
https://lore.kernel.org/linux-pm/6286434.lOV4Wx5bFT@rafael.j.wysocki/
and applies to Linux 7.1.
Thanks!
^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH v3 1/4] cpufreq: intel_pstate: Fix setting minimum P-state at init time
2026-06-24 17:32 [PATCH v3 0/4] cpufreq: intel_pstate: A fix and some cleanups Rafael J. Wysocki
@ 2026-06-24 17:33 ` Rafael J. Wysocki
2026-06-24 17:34 ` [PATCH v3 2/4] cpufreq: intel_pstate: Introduce intel_pstate_update_freq_limits() Rafael J. Wysocki
` (3 subsequent siblings)
4 siblings, 0 replies; 6+ messages in thread
From: Rafael J. Wysocki @ 2026-06-24 17:33 UTC (permalink / raw)
To: Linux PM; +Cc: LKML, Srinivas Pandruvada, Doug Smythies
From: "Rafael J. Wysocki" <rafael.j.wysocki@intel.com>
If HWP is enabled, writes to MSR_IA32_PERF_CTL have no effect,
so intel_pstate_get_cpu_pstates() should not attempt to call
intel_pstate_set_min_pstate() to set the minimum P-state for the
given CPU in that case.
Accordingly, remove the intel_pstate_set_min_pstate()
call from intel_pstate_get_cpu_pstates() and make both
intel_pstate_cpu_init() and intel_cpufreq_cpu_init() call
that function in their non-HWP code paths.
The HWP code path in intel_pstate_cpu_init() does not need to update
the current P-state of the CPU directly at all because it is taken
care of the processor automatically, but the HWP code path of
intel_cpufreq_cpu_init() should update it in principle to
initialize the DESIRED_PERF field in MSR_HWP_REQUEST. For this
purpose, make it call intel_cpufreq_hwp_update() and pass
the minimum P-state limit to it as the current target value along
with the current minimum and maximum limits.
Fixes: f6ebbcf08f37 ("cpufreq: intel_pstate: Implement passive mode with HWP enabled")
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
---
drivers/cpufreq/intel_pstate.c | 19 +++++++++++--------
1 file changed, 11 insertions(+), 8 deletions(-)
diff --git a/drivers/cpufreq/intel_pstate.c b/drivers/cpufreq/intel_pstate.c
index 1f093e346430..95e41e975c45 100644
--- a/drivers/cpufreq/intel_pstate.c
+++ b/drivers/cpufreq/intel_pstate.c
@@ -2354,8 +2354,6 @@ static void intel_pstate_get_cpu_pstates(struct cpudata *cpu)
if (pstate_funcs.get_vid)
pstate_funcs.get_vid(cpu);
-
- intel_pstate_set_min_pstate(cpu);
}
/*
@@ -3062,6 +3060,7 @@ static int __intel_pstate_cpu_init(struct cpufreq_policy *policy)
static int intel_pstate_cpu_init(struct cpufreq_policy *policy)
{
int ret = __intel_pstate_cpu_init(policy);
+ struct cpudata *cpu;
if (ret)
return ret;
@@ -3072,11 +3071,11 @@ static int intel_pstate_cpu_init(struct cpufreq_policy *policy)
*/
policy->policy = CPUFREQ_POLICY_POWERSAVE;
- if (hwp_active) {
- struct cpudata *cpu = all_cpu_data[policy->cpu];
-
+ cpu = all_cpu_data[policy->cpu];
+ if (hwp_active)
cpu->epp_cached = intel_pstate_get_epp(cpu, 0);
- }
+ else
+ intel_pstate_set_min_pstate(cpu);
return 0;
}
@@ -3300,8 +3299,6 @@ static int intel_cpufreq_cpu_init(struct cpufreq_policy *policy)
return ret;
policy->cpuinfo.transition_latency = INTEL_CPUFREQ_TRANSITION_LATENCY;
- /* This reflects the intel_pstate_get_cpu_pstates() setting. */
- policy->cur = policy->cpuinfo.min_freq;
req = kzalloc_objs(*req, 2);
if (!req) {
@@ -3322,9 +3319,15 @@ static int intel_cpufreq_cpu_init(struct cpufreq_policy *policy)
WRITE_ONCE(cpu->hwp_req_cached, value);
cpu->epp_cached = intel_pstate_get_epp(cpu, value);
+
+ intel_cpufreq_hwp_update(cpu, cpu->pstate.min_pstate,
+ cpu->pstate.max_pstate,
+ cpu->pstate.min_pstate, false);
} else {
policy->transition_delay_us = INTEL_CPUFREQ_TRANSITION_DELAY;
+ intel_pstate_set_min_pstate(cpu);
}
+ policy->cur = policy->cpuinfo.min_freq;
freq = DIV_ROUND_UP(cpu->pstate.turbo_freq * global.min_perf_pct, 100);
--
2.51.0
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH v3 2/4] cpufreq: intel_pstate: Introduce intel_pstate_update_freq_limits()
2026-06-24 17:32 [PATCH v3 0/4] cpufreq: intel_pstate: A fix and some cleanups Rafael J. Wysocki
2026-06-24 17:33 ` [PATCH v3 1/4] cpufreq: intel_pstate: Fix setting minimum P-state at init time Rafael J. Wysocki
@ 2026-06-24 17:34 ` Rafael J. Wysocki
2026-06-24 17:35 ` [PATCH v3 3/4] cpufreq: intel_pstate: Consolidate frequency values computation Rafael J. Wysocki
` (2 subsequent siblings)
4 siblings, 0 replies; 6+ messages in thread
From: Rafael J. Wysocki @ 2026-06-24 17:34 UTC (permalink / raw)
To: Linux PM; +Cc: LKML, Srinivas Pandruvada, Doug Smythies
From: "Rafael J. Wysocki" <rafael.j.wysocki@intel.com>
Introduce a new helper function, intel_pstate_update_freq_limits(),
for updating the max and turbo frequency values for the given CPU after
updating the corresponding P-states.
Use it in intel_pstate_get_hwp_cap() and intel_pstate_get_cpu_pstates(),
in the latter case instead of the direct updates of the max and turbo
frequency values in intel_pstate_hybrid_hwp_adjust().
No intentional functional impact.
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
---
drivers/cpufreq/intel_pstate.c | 36 +++++++++++++++++-----------------
1 file changed, 18 insertions(+), 18 deletions(-)
diff --git a/drivers/cpufreq/intel_pstate.c b/drivers/cpufreq/intel_pstate.c
index 95e41e975c45..e143c80a3215 100644
--- a/drivers/cpufreq/intel_pstate.c
+++ b/drivers/cpufreq/intel_pstate.c
@@ -587,11 +587,6 @@ static void intel_pstate_hybrid_hwp_adjust(struct cpudata *cpu)
hwp_is_hybrid = true;
- cpu->pstate.turbo_freq = rounddown(cpu->pstate.turbo_pstate * scaling,
- perf_ctl_scaling);
- cpu->pstate.max_freq = rounddown(cpu->pstate.max_pstate * scaling,
- perf_ctl_scaling);
-
freq = perf_ctl_max_phys * perf_ctl_scaling;
cpu->pstate.max_pstate_physical = intel_pstate_freq_to_hwp(cpu, freq);
@@ -1183,6 +1178,22 @@ static bool hybrid_clear_max_perf_cpu(void)
return ret;
}
+static void intel_pstate_update_freq_limits(struct cpudata *cpu)
+{
+ int scaling = cpu->pstate.scaling;
+ unsigned int turbo_freq = cpu->pstate.turbo_pstate * scaling;
+ unsigned int max_freq = cpu->pstate.max_pstate * scaling;
+ int perf_ctl_scaling = cpu->pstate.perf_ctl_scaling;
+
+ if (scaling != perf_ctl_scaling) {
+ turbo_freq = rounddown(turbo_freq, perf_ctl_scaling);
+ max_freq = rounddown(max_freq, perf_ctl_scaling);
+ }
+
+ cpu->pstate.turbo_freq = turbo_freq;
+ cpu->pstate.max_freq = max_freq;
+}
+
static void __intel_pstate_get_hwp_cap(struct cpudata *cpu)
{
u64 cap;
@@ -1195,20 +1206,8 @@ static void __intel_pstate_get_hwp_cap(struct cpudata *cpu)
static void intel_pstate_get_hwp_cap(struct cpudata *cpu)
{
- int scaling = cpu->pstate.scaling;
-
__intel_pstate_get_hwp_cap(cpu);
-
- cpu->pstate.max_freq = cpu->pstate.max_pstate * scaling;
- cpu->pstate.turbo_freq = cpu->pstate.turbo_pstate * scaling;
- if (scaling != cpu->pstate.perf_ctl_scaling) {
- int perf_ctl_scaling = cpu->pstate.perf_ctl_scaling;
-
- cpu->pstate.max_freq = rounddown(cpu->pstate.max_freq,
- perf_ctl_scaling);
- cpu->pstate.turbo_freq = rounddown(cpu->pstate.turbo_freq,
- perf_ctl_scaling);
- }
+ intel_pstate_update_freq_limits(cpu);
}
static void hybrid_update_capacity(struct cpudata *cpu)
@@ -2329,6 +2328,7 @@ static void intel_pstate_get_cpu_pstates(struct cpudata *cpu)
if (pstate_funcs.get_cpu_scaling) {
cpu->pstate.scaling = pstate_funcs.get_cpu_scaling(cpu->cpu);
intel_pstate_hybrid_hwp_adjust(cpu);
+ intel_pstate_update_freq_limits(cpu);
} else {
cpu->pstate.scaling = perf_ctl_scaling;
}
--
2.51.0
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH v3 3/4] cpufreq: intel_pstate: Consolidate frequency values computation
2026-06-24 17:32 [PATCH v3 0/4] cpufreq: intel_pstate: A fix and some cleanups Rafael J. Wysocki
2026-06-24 17:33 ` [PATCH v3 1/4] cpufreq: intel_pstate: Fix setting minimum P-state at init time Rafael J. Wysocki
2026-06-24 17:34 ` [PATCH v3 2/4] cpufreq: intel_pstate: Introduce intel_pstate_update_freq_limits() Rafael J. Wysocki
@ 2026-06-24 17:35 ` Rafael J. Wysocki
2026-06-24 17:36 ` [PATCH v3 4/4] cpufreq: intel_pstate: Move two functions closer to callers Rafael J. Wysocki
2026-06-30 4:21 ` [PATCH v3 0/4] cpufreq: intel_pstate: A fix and some cleanups Doug Smythies
4 siblings, 0 replies; 6+ messages in thread
From: Rafael J. Wysocki @ 2026-06-24 17:35 UTC (permalink / raw)
To: Linux PM; +Cc: LKML, Srinivas Pandruvada, Doug Smythies
From: "Rafael J. Wysocki" <rafael.j.wysocki@intel.com>
Update intel_pstate_get_cpu_pstates() to use
intel_pstate_update_freq_limits() for computing the max and
turbo frequency values in all cases, including non-hybrid HWP
and HWP disabled.
No intentional functional impact.
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
---
drivers/cpufreq/intel_pstate.c | 12 +++---------
1 file changed, 3 insertions(+), 9 deletions(-)
diff --git a/drivers/cpufreq/intel_pstate.c b/drivers/cpufreq/intel_pstate.c
index e143c80a3215..edc90ecb0b00 100644
--- a/drivers/cpufreq/intel_pstate.c
+++ b/drivers/cpufreq/intel_pstate.c
@@ -590,13 +590,11 @@ static void intel_pstate_hybrid_hwp_adjust(struct cpudata *cpu)
freq = perf_ctl_max_phys * perf_ctl_scaling;
cpu->pstate.max_pstate_physical = intel_pstate_freq_to_hwp(cpu, freq);
- freq = cpu->pstate.min_pstate * perf_ctl_scaling;
- cpu->pstate.min_freq = freq;
/*
* Cast the min P-state value retrieved via pstate_funcs.get_min() to
* the effective range of HWP performance levels.
*/
- cpu->pstate.min_pstate = intel_pstate_freq_to_hwp(cpu, freq);
+ cpu->pstate.min_pstate = intel_pstate_freq_to_hwp(cpu, cpu->pstate.min_freq);
}
static bool turbo_is_disabled(void)
@@ -2320,6 +2318,7 @@ static void intel_pstate_get_cpu_pstates(struct cpudata *cpu)
cpu->pstate.max_pstate_physical = pstate_funcs.get_max_physical(cpu->cpu);
cpu->pstate.min_pstate = pstate_funcs.get_min(cpu->cpu);
+ cpu->pstate.min_freq = cpu->pstate.min_pstate * perf_ctl_scaling;
cpu->pstate.perf_ctl_scaling = perf_ctl_scaling;
if (hwp_active && !hwp_mode_bdw) {
@@ -2328,7 +2327,6 @@ static void intel_pstate_get_cpu_pstates(struct cpudata *cpu)
if (pstate_funcs.get_cpu_scaling) {
cpu->pstate.scaling = pstate_funcs.get_cpu_scaling(cpu->cpu);
intel_pstate_hybrid_hwp_adjust(cpu);
- intel_pstate_update_freq_limits(cpu);
} else {
cpu->pstate.scaling = perf_ctl_scaling;
}
@@ -2343,11 +2341,7 @@ static void intel_pstate_get_cpu_pstates(struct cpudata *cpu)
cpu->pstate.turbo_pstate = pstate_funcs.get_turbo(cpu->cpu);
}
- if (cpu->pstate.scaling == perf_ctl_scaling) {
- cpu->pstate.min_freq = cpu->pstate.min_pstate * perf_ctl_scaling;
- cpu->pstate.max_freq = cpu->pstate.max_pstate * perf_ctl_scaling;
- cpu->pstate.turbo_freq = cpu->pstate.turbo_pstate * perf_ctl_scaling;
- }
+ intel_pstate_update_freq_limits(cpu);
if (pstate_funcs.get_aperf_mperf_shift)
cpu->aperf_mperf_shift = pstate_funcs.get_aperf_mperf_shift();
--
2.51.0
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH v3 4/4] cpufreq: intel_pstate: Move two functions closer to callers
2026-06-24 17:32 [PATCH v3 0/4] cpufreq: intel_pstate: A fix and some cleanups Rafael J. Wysocki
` (2 preceding siblings ...)
2026-06-24 17:35 ` [PATCH v3 3/4] cpufreq: intel_pstate: Consolidate frequency values computation Rafael J. Wysocki
@ 2026-06-24 17:36 ` Rafael J. Wysocki
2026-06-30 4:21 ` [PATCH v3 0/4] cpufreq: intel_pstate: A fix and some cleanups Doug Smythies
4 siblings, 0 replies; 6+ messages in thread
From: Rafael J. Wysocki @ 2026-06-24 17:36 UTC (permalink / raw)
To: Linux PM; +Cc: LKML, Srinivas Pandruvada, Doug Smythies
From: "Rafael J. Wysocki" <rafael.j.wysocki@intel.com>
Move intel_pstate_set_pstate() and intel_pstate_set_min_pstate() that
are not used on systems with HWP enabled, closer to their first
callers.
No intentional functional impact.
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
---
drivers/cpufreq/intel_pstate.c | 36 +++++++++++++++++-----------------
1 file changed, 18 insertions(+), 18 deletions(-)
diff --git a/drivers/cpufreq/intel_pstate.c b/drivers/cpufreq/intel_pstate.c
index edc90ecb0b00..25ef2848eebf 100644
--- a/drivers/cpufreq/intel_pstate.c
+++ b/drivers/cpufreq/intel_pstate.c
@@ -2294,24 +2294,6 @@ static int hwp_get_cpu_scaling(int cpu)
return intel_pstate_cppc_get_scaling(cpu);
}
-static void intel_pstate_set_pstate(struct cpudata *cpu, int pstate)
-{
- trace_cpu_frequency(pstate * cpu->pstate.scaling, cpu->cpu);
- cpu->pstate.current_pstate = pstate;
- /*
- * Generally, there is no guarantee that this code will always run on
- * the CPU being updated, so force the register update to run on the
- * right CPU.
- */
- wrmsrq_on_cpu(cpu->cpu, MSR_IA32_PERF_CTL,
- pstate_funcs.get_val(cpu, pstate));
-}
-
-static void intel_pstate_set_min_pstate(struct cpudata *cpu)
-{
- intel_pstate_set_pstate(cpu, cpu->pstate.min_pstate);
-}
-
static void intel_pstate_get_cpu_pstates(struct cpudata *cpu)
{
int perf_ctl_scaling = pstate_funcs.get_scaling();
@@ -2874,6 +2856,19 @@ static void intel_pstate_update_perf_limits(struct cpudata *cpu,
cpu->min_perf_ratio);
}
+static void intel_pstate_set_pstate(struct cpudata *cpu, int pstate)
+{
+ trace_cpu_frequency(pstate * cpu->pstate.scaling, cpu->cpu);
+ cpu->pstate.current_pstate = pstate;
+ /*
+ * Generally, there is no guarantee that this code will always run on
+ * the CPU being updated, so force the register update to run on the
+ * right CPU.
+ */
+ wrmsrq_on_cpu(cpu->cpu, MSR_IA32_PERF_CTL,
+ pstate_funcs.get_val(cpu, pstate));
+}
+
static int intel_pstate_set_policy(struct cpufreq_policy *policy)
{
struct cpudata *cpu;
@@ -2961,6 +2956,11 @@ static int intel_pstate_verify_policy(struct cpufreq_policy_data *policy)
return 0;
}
+static void intel_pstate_set_min_pstate(struct cpudata *cpu)
+{
+ intel_pstate_set_pstate(cpu, cpu->pstate.min_pstate);
+}
+
static int intel_cpufreq_cpu_offline(struct cpufreq_policy *policy)
{
struct cpudata *cpu = all_cpu_data[policy->cpu];
--
2.51.0
^ permalink raw reply related [flat|nested] 6+ messages in thread
* RE: [PATCH v3 0/4] cpufreq: intel_pstate: A fix and some cleanups
2026-06-24 17:32 [PATCH v3 0/4] cpufreq: intel_pstate: A fix and some cleanups Rafael J. Wysocki
` (3 preceding siblings ...)
2026-06-24 17:36 ` [PATCH v3 4/4] cpufreq: intel_pstate: Move two functions closer to callers Rafael J. Wysocki
@ 2026-06-30 4:21 ` Doug Smythies
4 siblings, 0 replies; 6+ messages in thread
From: Doug Smythies @ 2026-06-30 4:21 UTC (permalink / raw)
To: 'Rafael J. Wysocki'
Cc: 'LKML', 'Srinivas Pandruvada', Doug Smythies,
'Linux PM'
Hi Rafael,
On 2026.06.24 10:32 Rafael wrote:
> Hi,
>
> This replaces
>
> https://lore.kernel.org/linux-pm/6005456.DvuYhMxLoT@rafael.j.wysocki/
>
> and drops the most significant change in it which was making intel_pstate
> set cpuinfo_min_freq to a lower value with HWP enabled. That change
> went too far and needs to be reconsidered.
>
> The other changes in the series, and in particular the fix in the first
> patch, are useful and will facilitate further improvements, so here
> they go.
I tested this patch set a little. It seems okay.
... Doug
>
> This series is independent of
>
> https://lore.kernel.org/linux-pm/6286434.lOV4Wx5bFT@rafael.j.wysocki/
>
> and applies to Linux 7.1.
>
> Thanks!
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2026-06-30 4:21 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-06-24 17:32 [PATCH v3 0/4] cpufreq: intel_pstate: A fix and some cleanups Rafael J. Wysocki
2026-06-24 17:33 ` [PATCH v3 1/4] cpufreq: intel_pstate: Fix setting minimum P-state at init time Rafael J. Wysocki
2026-06-24 17:34 ` [PATCH v3 2/4] cpufreq: intel_pstate: Introduce intel_pstate_update_freq_limits() Rafael J. Wysocki
2026-06-24 17:35 ` [PATCH v3 3/4] cpufreq: intel_pstate: Consolidate frequency values computation Rafael J. Wysocki
2026-06-24 17:36 ` [PATCH v3 4/4] cpufreq: intel_pstate: Move two functions closer to callers Rafael J. Wysocki
2026-06-30 4:21 ` [PATCH v3 0/4] cpufreq: intel_pstate: A fix and some cleanups Doug Smythies
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox