[PATCH 06/10] cpu/SMT: Create topology_smt_thread_allowed()
From: Laurent Dufour <hidden>
Date: 2023-06-15 15:47:55
Also in:
linux-arch, lkml
Subsystem:
cpu hotplug, the rest, x86 architecture (32-bit and 64-bit) · Maintainers:
Thomas Gleixner, Peter Zijlstra, Linus Torvalds, Ingo Molnar, Borislav Petkov, Dave Hansen
From: Michael Ellerman <mpe@ellerman.id.au> A subsequent patch will enable partial SMT states, ie. when not all SMT threads are brought online. To support that, add an arch helper which checks whether a given CPU is allowed to be brought online depending on how many SMT threads are currently enabled. Call the helper from cpu_smt_enable(), and cpu_smt_allowed() when SMT is enabled, to check if the particular thread should be onlined. Notably, also call it from cpu_smt_disable() if CPU_SMT_ENABLED, to allow offlining some threads to move from a higher to lower number of threads online. Signed-off-by: Michael Ellerman <mpe@ellerman.id.au> --- arch/x86/include/asm/topology.h | 2 ++ arch/x86/kernel/smpboot.c | 15 +++++++++++++++ kernel/cpu.c | 10 +++++++++- 3 files changed, 26 insertions(+), 1 deletion(-)
diff --git a/arch/x86/include/asm/topology.h b/arch/x86/include/asm/topology.h
index 232df5ffab34..4696d4566cb5 100644
--- a/arch/x86/include/asm/topology.h
+++ b/arch/x86/include/asm/topology.h@@ -144,6 +144,7 @@ int topology_phys_to_logical_pkg(unsigned int pkg); int topology_phys_to_logical_die(unsigned int die, unsigned int cpu); bool topology_is_primary_thread(unsigned int cpu); bool topology_smt_threads_supported(unsigned int threads); +bool topology_smt_thread_allowed(unsigned int cpu); #else #define topology_max_packages() (1) static inline int
@@ -157,6 +158,7 @@ static inline int topology_max_die_per_package(void) { return 1; } static inline int topology_max_smt_threads(void) { return 1; } static inline bool topology_is_primary_thread(unsigned int cpu) { return true; } static inline bool topology_smt_threads_supported(unsigned int threads) { return false; } +static inline bool topology_smt_thread_allowed(unsigned int cpu) { return false; } #endif static inline void arch_fix_phys_package_id(int num, u32 slot)
diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c
index d163ef55577b..cfae55c2d1b0 100644
--- a/arch/x86/kernel/smpboot.c
+++ b/arch/x86/kernel/smpboot.c@@ -290,6 +290,21 @@ bool topology_smt_threads_supported(unsigned int threads) return threads == 1 || threads == smp_num_siblings; } +/** + * topology_smt_thread_allowed - When enabling SMT check whether this particular + * CPU thread is allowed to be brought online. + * @cpu: CPU to check + */ +bool topology_smt_thread_allowed(unsigned int cpu) +{ + /* + * No extra logic s required here to support different thread values + * because threads will always == 1 or smp_num_siblings because of + * topology_smt_threads_supported(). + */ + return true; +} + /** * topology_phys_to_logical_pkg - Map a physical package id to a logical *
diff --git a/kernel/cpu.c b/kernel/cpu.c
index e354af92b2b8..ae2fa26a5b63 100644
--- a/kernel/cpu.c
+++ b/kernel/cpu.c@@ -468,7 +468,7 @@ early_param("nosmt", smt_cmdline_disable); static inline bool cpu_smt_allowed(unsigned int cpu) { - if (cpu_smt_control == CPU_SMT_ENABLED) + if (cpu_smt_control == CPU_SMT_ENABLED && topology_smt_thread_allowed(cpu)) return true; if (topology_is_primary_thread(cpu))
@@ -2283,6 +2283,12 @@ int cpuhp_smt_disable(enum cpuhp_smt_control ctrlval) for_each_online_cpu(cpu) { if (topology_is_primary_thread(cpu)) continue; + /* + * Disable can be called with CPU_SMT_ENABLED when changing + * from a higher to lower number of SMT threads per core. + */ + if (ctrlval == CPU_SMT_ENABLED && topology_smt_thread_allowed(cpu)) + continue; ret = cpu_down_maps_locked(cpu, CPUHP_OFFLINE); if (ret) break;
@@ -2317,6 +2323,8 @@ int cpuhp_smt_enable(void) /* Skip online CPUs and CPUs on offline nodes */ if (cpu_online(cpu) || !node_online(cpu_to_node(cpu))) continue; + if (!topology_smt_thread_allowed(cpu)) + continue; ret = _cpu_up(cpu, 0, CPUHP_ONLINE); if (ret) break;
--
2.41.0