[<prev] [next>] [<thread-prev] [day] [month] [year] [list]
Message-Id: <20260123114756.1617527-1-tianyaxiong@kylinos.cn>
Date: Fri, 23 Jan 2026 19:47:56 +0800
From: Yaxiong Tian <tianyaxiong@...inos.cn>
To: tglx@...nel.org,
mingo@...hat.com,
bp@...en8.de,
dave.hansen@...ux.intel.com,
x86@...nel.org,
hpa@...or.com,
srinivas.pandruvada@...ux.intel.com,
lenb@...nel.org,
rafael@...nel.org,
viresh.kumar@...aro.org,
ricardo.neri-calderon@...ux.intel.com
Cc: linux-kernel@...r.kernel.org,
linux-pm@...r.kernel.org,
Yaxiong Tian <tianyaxiong@...inos.cn>
Subject: [PATCH 3/3] cpufreq: intel_pstate: Enable toggling cpu_capacity_scaling on hybrid platforms during SMT transitions
Users can disable SMT (Simultaneous Multi-Threading) via
/sys/devices/system/cpu/smt, meaning that CPU hybrid capabilities
and related features like EAS (Energy Aware Scheduling) may become
dynamically eligible. This implies that when an SMT transition
occurs,the system may no longer be considered hybrid, rendering the
original configurations incorrect.
To address this issue, note that SMT transitions are accompanied
by cpufreq online/offline operations, allowing conditional checks
within this path. Specifically:
When SMT transitions from off → on, cpufreq online operations
occur. If hybrid settings were previously applied, disable-related
operations should be performed.
When SMT transitions from on → off, cpufreq offline operations
occur. If the system meets hybrid conditions at this point,
enable-related operations should be performed.
Fixes: 929ebc93ccaa ("cpufreq: intel_pstate: Set asymmetric CPU capacity on hybrid systems")
Signed-off-by: Yaxiong Tian <tianyaxiong@...inos.cn>
---
drivers/cpufreq/intel_pstate.c | 60 ++++++++++++++++++++++++++++++++++
1 file changed, 60 insertions(+)
diff --git a/drivers/cpufreq/intel_pstate.c b/drivers/cpufreq/intel_pstate.c
index 76fb79b8068a..fad25aa4b5f8 100644
--- a/drivers/cpufreq/intel_pstate.c
+++ b/drivers/cpufreq/intel_pstate.c
@@ -1234,6 +1234,59 @@ static void hybrid_update_capacity(struct cpudata *cpu)
mutex_unlock(&hybrid_capacity_lock);
}
+static bool hybrid_need_enable_cpu_capacity_scaling(void)
+{
+ guard(mutex)(&hybrid_capacity_lock);
+
+ if (!hybrid_max_perf_cpu && hwp_is_hybrid &&
+ !no_cas && !sched_smt_active())
+ return true;
+ else
+ return false;
+}
+
+static bool hybrid_need_disable_cpu_capacity_scaling(void)
+{
+ guard(mutex)(&hybrid_capacity_lock);
+
+ if (hybrid_max_perf_cpu && sched_smt_active()) {
+ hybrid_max_perf_cpu = NULL;
+ return true;
+ } else {
+ return false;
+ }
+}
+
+static void hybrid_enable_cpu_capacity_scaling_work_fn(struct work_struct *work)
+{
+ if (arch_enable_hybrid_capacity_scale()) {
+ hybrid_refresh_cpu_capacity_scaling();
+ /*
+ * Disabling ITMT causes sched domains to be rebuilt to disable asym
+ * packing and enable asym capacity and EAS.
+ */
+ sched_clear_itmt_support();
+
+ }
+}
+
+static void hybrid_disable_cpu_capacity_scaling_work_fn(struct work_struct *work)
+{
+ unsigned int cpu;
+
+ arch_disable_hybrid_capacity_scale();
+ for_each_possible_cpu(cpu)
+ topology_set_cpu_scale(cpu, arch_scale_cpu_capacity(cpu));
+
+ /* Heterogeneous CPUs have different capabilities, therefore enable
+ * ITMT when SMT is active.
+ */
+ sched_set_itmt_support();
+}
+
+static DECLARE_WORK(hybrid_enable_work, hybrid_enable_cpu_capacity_scaling_work_fn);
+static DECLARE_WORK(hybrid_disable_work, hybrid_disable_cpu_capacity_scaling_work_fn);
+
static void intel_pstate_hwp_set(unsigned int cpu)
{
struct cpudata *cpu_data = all_cpu_data[cpu];
@@ -2967,6 +3020,10 @@ static int intel_cpufreq_cpu_offline(struct cpufreq_policy *policy)
intel_pstate_exit_perf_limits(policy);
+ if (unlikely(hybrid_need_enable_cpu_capacity_scaling()))
+ schedule_work(&hybrid_enable_work);
+
+
return 0;
}
@@ -2974,6 +3031,9 @@ static int intel_pstate_cpu_online(struct cpufreq_policy *policy)
{
struct cpudata *cpu = all_cpu_data[policy->cpu];
+ if (unlikely(hybrid_need_disable_cpu_capacity_scaling()))
+ schedule_work(&hybrid_disable_work);
+
pr_debug("CPU %d going online\n", cpu->cpu);
intel_pstate_init_acpi_perf_limits(policy);
--
2.25.1
Powered by blists - more mailing lists