Commit 447ae4ac authored by Michael Ellerman's avatar Michael Ellerman Committed by Thomas Gleixner

cpu/SMT: Store the current/max number of threads

Some architectures allow partial SMT states at boot time, ie. when not all
SMT threads are brought online.

To support that the SMT code needs to know the maximum number of SMT
threads, and also the currently configured number.

The architecture code knows the max number of threads, so have the
architecture code pass that value to cpu_smt_set_num_threads(). Note that
although topology_max_smt_threads() exists, it is not configured early
enough to be used here. As architecture, like PowerPC, allows the threads
number to be set through the kernel command line, also pass that value.

[ ldufour: Slightly reword the commit message ]
[ ldufour: Rename cpu_smt_check_topology and add a num_threads argument ]
Signed-off-by: default avatarMichael Ellerman <mpe@ellerman.id.au>
Signed-off-by: default avatarLaurent Dufour <ldufour@linux.ibm.com>
Signed-off-by: default avatarThomas Gleixner <tglx@linutronix.de>
Tested-by: default avatarZhang Rui <rui.zhang@intel.com>
Link: https://lore.kernel.org/r/20230705145143.40545-5-ldufour@linux.ibm.com
parent c53361ce
...@@ -2317,7 +2317,7 @@ void __init arch_cpu_finalize_init(void) ...@@ -2317,7 +2317,7 @@ void __init arch_cpu_finalize_init(void)
* identify_boot_cpu() initialized SMT support information, let the * identify_boot_cpu() initialized SMT support information, let the
* core code know. * core code know.
*/ */
cpu_smt_check_topology(); cpu_smt_set_num_threads(smp_num_siblings, smp_num_siblings);
if (!IS_ENABLED(CONFIG_SMP)) { if (!IS_ENABLED(CONFIG_SMP)) {
pr_info("CPU: "); pr_info("CPU: ");
......
...@@ -12,15 +12,19 @@ enum cpuhp_smt_control { ...@@ -12,15 +12,19 @@ enum cpuhp_smt_control {
#if defined(CONFIG_SMP) && defined(CONFIG_HOTPLUG_SMT) #if defined(CONFIG_SMP) && defined(CONFIG_HOTPLUG_SMT)
extern enum cpuhp_smt_control cpu_smt_control; extern enum cpuhp_smt_control cpu_smt_control;
extern unsigned int cpu_smt_num_threads;
extern void cpu_smt_disable(bool force); extern void cpu_smt_disable(bool force);
extern void cpu_smt_check_topology(void); extern void cpu_smt_set_num_threads(unsigned int num_threads,
unsigned int max_threads);
extern bool cpu_smt_possible(void); extern bool cpu_smt_possible(void);
extern int cpuhp_smt_enable(void); extern int cpuhp_smt_enable(void);
extern int cpuhp_smt_disable(enum cpuhp_smt_control ctrlval); extern int cpuhp_smt_disable(enum cpuhp_smt_control ctrlval);
#else #else
# define cpu_smt_control (CPU_SMT_NOT_IMPLEMENTED) # define cpu_smt_control (CPU_SMT_NOT_IMPLEMENTED)
# define cpu_smt_num_threads 1
static inline void cpu_smt_disable(bool force) { } static inline void cpu_smt_disable(bool force) { }
static inline void cpu_smt_check_topology(void) { } static inline void cpu_smt_set_num_threads(unsigned int num_threads,
unsigned int max_threads) { }
static inline bool cpu_smt_possible(void) { return false; } static inline bool cpu_smt_possible(void) { return false; }
static inline int cpuhp_smt_enable(void) { return 0; } static inline int cpuhp_smt_enable(void) { return 0; }
static inline int cpuhp_smt_disable(enum cpuhp_smt_control ctrlval) { return 0; } static inline int cpuhp_smt_disable(enum cpuhp_smt_control ctrlval) { return 0; }
......
...@@ -594,6 +594,8 @@ void __weak arch_smt_update(void) { } ...@@ -594,6 +594,8 @@ void __weak arch_smt_update(void) { }
#ifdef CONFIG_HOTPLUG_SMT #ifdef CONFIG_HOTPLUG_SMT
enum cpuhp_smt_control cpu_smt_control __read_mostly = CPU_SMT_ENABLED; enum cpuhp_smt_control cpu_smt_control __read_mostly = CPU_SMT_ENABLED;
static unsigned int cpu_smt_max_threads __ro_after_init;
unsigned int cpu_smt_num_threads __read_mostly = UINT_MAX;
void __init cpu_smt_disable(bool force) void __init cpu_smt_disable(bool force)
{ {
...@@ -607,16 +609,33 @@ void __init cpu_smt_disable(bool force) ...@@ -607,16 +609,33 @@ void __init cpu_smt_disable(bool force)
pr_info("SMT: disabled\n"); pr_info("SMT: disabled\n");
cpu_smt_control = CPU_SMT_DISABLED; cpu_smt_control = CPU_SMT_DISABLED;
} }
cpu_smt_num_threads = 1;
} }
/* /*
* The decision whether SMT is supported can only be done after the full * The decision whether SMT is supported can only be done after the full
* CPU identification. Called from architecture code. * CPU identification. Called from architecture code.
*/ */
void __init cpu_smt_check_topology(void) void __init cpu_smt_set_num_threads(unsigned int num_threads,
unsigned int max_threads)
{ {
WARN_ON(!num_threads || (num_threads > max_threads));
if (!topology_smt_supported()) if (!topology_smt_supported())
cpu_smt_control = CPU_SMT_NOT_SUPPORTED; cpu_smt_control = CPU_SMT_NOT_SUPPORTED;
cpu_smt_max_threads = max_threads;
/*
* If SMT has been disabled via the kernel command line or SMT is
* not supported, set cpu_smt_num_threads to 1 for consistency.
* If enabled, take the architecture requested number of threads
* to bring up into account.
*/
if (cpu_smt_control != CPU_SMT_ENABLED)
cpu_smt_num_threads = 1;
else if (num_threads < cpu_smt_num_threads)
cpu_smt_num_threads = num_threads;
} }
static int __init smt_cmdline_disable(char *str) static int __init smt_cmdline_disable(char *str)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment