SMP core changes for powerpc
-----BEGIN PGP SIGNATURE----- iQJHBAABCgAxFiEEQp8+kY+LLUocC4bMphj1TA10mKEFAmTDdHMTHHRnbHhAbGlu dXRyb25peC5kZQAKCRCmGPVMDXSYoawDEACf7tZeCfwnkEVzBO45mKujBstQyV+v yATR7YRFG3Li9VaRP/rOrFxh+UPM2YbvQCgcT2BECl5gkBm7j/jgTiL47atN5VCo Sg9fDzjkf6+A1ac62kriQT0EyhYYN/V6DxByhqSLvxev9626ge93wBKmChohGOgj j66PEg5z+Luw9aTdyKm3cEuXGYyCmdWTgZ6z4f4VI+rVBXFUMiZl28eMlLH+eyVM +ntkDoNw00TqypSrcSr8WEzJc3SNAqUsLOW+Mogm4AJK8sKeFtdkjCLFDcV1dLmZ 9Ak8OxeQGNhh538yCLYiNDu57xpQffS4E2t+Pusv8ZHc6ww5J8vsPq3p9323LbyF FXcREHM8W5cKLdy4hzqeqKx2YK4shquYXH10WIbVQXqbxMUD5wGCYuQTS12V+QW0 1Ut48/RS3a6kaKvX475enFrR/wQNSTJkM+ajFSGY3eSNp9v9EmTepw3aY8RXw+Gr QRxCuM4MgaUazJ0RtbjbzSRK2r8MObj+aurfvMQZGFmkkw0DiUZNOnb5VPZSrqb+ laNQKKAdG99NlTNyvLSSgYTX+FM0AbqKVWnIO4b+3wMvYxfiENKDWVzdQWksNz6U J5j7qDqZQ45kEow0Xn0lKxz1zKdcJLZPFjExrgYkRTaRp7VwcQ8st2Lbj1XVk7Wr wqXouAvhBSqWEA== =jF0X -----END PGP SIGNATURE----- Merge tag 'smp-core-for-ppc-23-07-28' of https://git.kernel.org/pub/scm/linux/kernel/git/tip/tip into topic/cpu-smt SMP core changes for powerpc
This commit is contained in:
commit
d82e6762b0
|
@ -555,6 +555,7 @@ Description: Control Symmetric Multi Threading (SMT)
|
||||||
================ =========================================
|
================ =========================================
|
||||||
"on" SMT is enabled
|
"on" SMT is enabled
|
||||||
"off" SMT is disabled
|
"off" SMT is disabled
|
||||||
|
"<N>" SMT is enabled with N threads per core.
|
||||||
"forceoff" SMT is force disabled. Cannot be changed.
|
"forceoff" SMT is force disabled. Cannot be changed.
|
||||||
"notsupported" SMT is not supported by the CPU
|
"notsupported" SMT is not supported by the CPU
|
||||||
"notimplemented" SMT runtime toggling is not
|
"notimplemented" SMT runtime toggling is not
|
||||||
|
|
|
@ -34,6 +34,9 @@ config ARCH_HAS_SUBPAGE_FAULTS
|
||||||
config HOTPLUG_SMT
|
config HOTPLUG_SMT
|
||||||
bool
|
bool
|
||||||
|
|
||||||
|
config SMT_NUM_THREADS_DYNAMIC
|
||||||
|
bool
|
||||||
|
|
||||||
# Selected by HOTPLUG_CORE_SYNC_DEAD or HOTPLUG_CORE_SYNC_FULL
|
# Selected by HOTPLUG_CORE_SYNC_DEAD or HOTPLUG_CORE_SYNC_FULL
|
||||||
config HOTPLUG_CORE_SYNC
|
config HOTPLUG_CORE_SYNC
|
||||||
bool
|
bool
|
||||||
|
|
|
@ -136,10 +136,11 @@ static inline int topology_max_smt_threads(void)
|
||||||
return __max_smt_threads;
|
return __max_smt_threads;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#include <linux/cpu_smt.h>
|
||||||
|
|
||||||
int topology_update_package_map(unsigned int apicid, unsigned int cpu);
|
int topology_update_package_map(unsigned int apicid, unsigned int cpu);
|
||||||
int topology_update_die_map(unsigned int dieid, unsigned int cpu);
|
int topology_update_die_map(unsigned int dieid, unsigned int cpu);
|
||||||
int topology_phys_to_logical_pkg(unsigned int pkg);
|
int topology_phys_to_logical_pkg(unsigned int pkg);
|
||||||
bool topology_smt_supported(void);
|
|
||||||
|
|
||||||
extern struct cpumask __cpu_primary_thread_mask;
|
extern struct cpumask __cpu_primary_thread_mask;
|
||||||
#define cpu_primary_thread_mask ((const struct cpumask *)&__cpu_primary_thread_mask)
|
#define cpu_primary_thread_mask ((const struct cpumask *)&__cpu_primary_thread_mask)
|
||||||
|
@ -162,7 +163,6 @@ static inline int topology_phys_to_logical_pkg(unsigned int pkg) { return 0; }
|
||||||
static inline int topology_max_die_per_package(void) { return 1; }
|
static inline int topology_max_die_per_package(void) { return 1; }
|
||||||
static inline int topology_max_smt_threads(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_is_primary_thread(unsigned int cpu) { return true; }
|
||||||
static inline bool topology_smt_supported(void) { return false; }
|
|
||||||
#endif /* !CONFIG_SMP */
|
#endif /* !CONFIG_SMP */
|
||||||
|
|
||||||
static inline void arch_fix_phys_package_id(int num, u32 slot)
|
static inline void arch_fix_phys_package_id(int num, u32 slot)
|
||||||
|
|
|
@ -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: ");
|
||||||
|
|
|
@ -326,14 +326,6 @@ static void notrace start_secondary(void *unused)
|
||||||
cpu_startup_entry(CPUHP_AP_ONLINE_IDLE);
|
cpu_startup_entry(CPUHP_AP_ONLINE_IDLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* topology_smt_supported - Check whether SMT is supported by the CPUs
|
|
||||||
*/
|
|
||||||
bool topology_smt_supported(void)
|
|
||||||
{
|
|
||||||
return smp_num_siblings > 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* topology_phys_to_logical_pkg - Map a physical package id to a logical
|
* topology_phys_to_logical_pkg - Map a physical package id to a logical
|
||||||
* @phys_pkg: The physical package id to map
|
* @phys_pkg: The physical package id to map
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
#include <linux/compiler.h>
|
#include <linux/compiler.h>
|
||||||
#include <linux/cpumask.h>
|
#include <linux/cpumask.h>
|
||||||
#include <linux/cpuhotplug.h>
|
#include <linux/cpuhotplug.h>
|
||||||
|
#include <linux/cpu_smt.h>
|
||||||
|
|
||||||
struct device;
|
struct device;
|
||||||
struct device_node;
|
struct device_node;
|
||||||
|
@ -204,30 +205,6 @@ void cpuhp_report_idle_dead(void);
|
||||||
static inline void cpuhp_report_idle_dead(void) { }
|
static inline void cpuhp_report_idle_dead(void) { }
|
||||||
#endif /* #ifdef CONFIG_HOTPLUG_CPU */
|
#endif /* #ifdef CONFIG_HOTPLUG_CPU */
|
||||||
|
|
||||||
enum cpuhp_smt_control {
|
|
||||||
CPU_SMT_ENABLED,
|
|
||||||
CPU_SMT_DISABLED,
|
|
||||||
CPU_SMT_FORCE_DISABLED,
|
|
||||||
CPU_SMT_NOT_SUPPORTED,
|
|
||||||
CPU_SMT_NOT_IMPLEMENTED,
|
|
||||||
};
|
|
||||||
|
|
||||||
#if defined(CONFIG_SMP) && defined(CONFIG_HOTPLUG_SMT)
|
|
||||||
extern enum cpuhp_smt_control cpu_smt_control;
|
|
||||||
extern void cpu_smt_disable(bool force);
|
|
||||||
extern void cpu_smt_check_topology(void);
|
|
||||||
extern bool cpu_smt_possible(void);
|
|
||||||
extern int cpuhp_smt_enable(void);
|
|
||||||
extern int cpuhp_smt_disable(enum cpuhp_smt_control ctrlval);
|
|
||||||
#else
|
|
||||||
# define cpu_smt_control (CPU_SMT_NOT_IMPLEMENTED)
|
|
||||||
static inline void cpu_smt_disable(bool force) { }
|
|
||||||
static inline void cpu_smt_check_topology(void) { }
|
|
||||||
static inline bool cpu_smt_possible(void) { return false; }
|
|
||||||
static inline int cpuhp_smt_enable(void) { return 0; }
|
|
||||||
static inline int cpuhp_smt_disable(enum cpuhp_smt_control ctrlval) { return 0; }
|
|
||||||
#endif
|
|
||||||
|
|
||||||
extern bool cpu_mitigations_off(void);
|
extern bool cpu_mitigations_off(void);
|
||||||
extern bool cpu_mitigations_auto_nosmt(void);
|
extern bool cpu_mitigations_auto_nosmt(void);
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,33 @@
|
||||||
|
/* SPDX-License-Identifier: GPL-2.0 */
|
||||||
|
#ifndef _LINUX_CPU_SMT_H_
|
||||||
|
#define _LINUX_CPU_SMT_H_
|
||||||
|
|
||||||
|
enum cpuhp_smt_control {
|
||||||
|
CPU_SMT_ENABLED,
|
||||||
|
CPU_SMT_DISABLED,
|
||||||
|
CPU_SMT_FORCE_DISABLED,
|
||||||
|
CPU_SMT_NOT_SUPPORTED,
|
||||||
|
CPU_SMT_NOT_IMPLEMENTED,
|
||||||
|
};
|
||||||
|
|
||||||
|
#if defined(CONFIG_SMP) && defined(CONFIG_HOTPLUG_SMT)
|
||||||
|
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_set_num_threads(unsigned int num_threads,
|
||||||
|
unsigned int max_threads);
|
||||||
|
extern bool cpu_smt_possible(void);
|
||||||
|
extern int cpuhp_smt_enable(void);
|
||||||
|
extern int cpuhp_smt_disable(enum cpuhp_smt_control ctrlval);
|
||||||
|
#else
|
||||||
|
# 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_set_num_threads(unsigned int num_threads,
|
||||||
|
unsigned int max_threads) { }
|
||||||
|
static inline bool cpu_smt_possible(void) { return false; }
|
||||||
|
static inline int cpuhp_smt_enable(void) { return 0; }
|
||||||
|
static inline int cpuhp_smt_disable(enum cpuhp_smt_control ctrlval) { return 0; }
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* _LINUX_CPU_SMT_H_ */
|
142
kernel/cpu.c
142
kernel/cpu.c
|
@ -592,7 +592,10 @@ static void lockdep_release_cpus_lock(void)
|
||||||
void __weak arch_smt_update(void) { }
|
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)
|
||||||
{
|
{
|
||||||
|
@ -606,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)
|
||||||
{
|
{
|
||||||
if (!topology_smt_supported())
|
WARN_ON(!num_threads || (num_threads > max_threads));
|
||||||
|
|
||||||
|
if (max_threads == 1)
|
||||||
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)
|
||||||
|
@ -625,9 +645,23 @@ static int __init smt_cmdline_disable(char *str)
|
||||||
}
|
}
|
||||||
early_param("nosmt", smt_cmdline_disable);
|
early_param("nosmt", smt_cmdline_disable);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* For Archicture supporting partial SMT states check if the thread is allowed.
|
||||||
|
* Otherwise this has already been checked through cpu_smt_max_threads when
|
||||||
|
* setting the SMT level.
|
||||||
|
*/
|
||||||
|
static inline bool cpu_smt_thread_allowed(unsigned int cpu)
|
||||||
|
{
|
||||||
|
#ifdef CONFIG_SMT_NUM_THREADS_DYNAMIC
|
||||||
|
return topology_smt_thread_allowed(cpu);
|
||||||
|
#else
|
||||||
|
return true;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
static inline bool cpu_smt_allowed(unsigned int cpu)
|
static inline bool cpu_smt_allowed(unsigned int cpu)
|
||||||
{
|
{
|
||||||
if (cpu_smt_control == CPU_SMT_ENABLED)
|
if (cpu_smt_control == CPU_SMT_ENABLED && cpu_smt_thread_allowed(cpu))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
if (topology_is_primary_thread(cpu))
|
if (topology_is_primary_thread(cpu))
|
||||||
|
@ -650,22 +684,8 @@ bool cpu_smt_possible(void)
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(cpu_smt_possible);
|
EXPORT_SYMBOL_GPL(cpu_smt_possible);
|
||||||
|
|
||||||
static inline bool cpuhp_smt_aware(void)
|
|
||||||
{
|
|
||||||
return topology_smt_supported();
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline const struct cpumask *cpuhp_get_primary_thread_mask(void)
|
|
||||||
{
|
|
||||||
return cpu_primary_thread_mask;
|
|
||||||
}
|
|
||||||
#else
|
#else
|
||||||
static inline bool cpu_smt_allowed(unsigned int cpu) { return true; }
|
static inline bool cpu_smt_allowed(unsigned int cpu) { return true; }
|
||||||
static inline bool cpuhp_smt_aware(void) { return false; }
|
|
||||||
static inline const struct cpumask *cpuhp_get_primary_thread_mask(void)
|
|
||||||
{
|
|
||||||
return cpu_present_mask;
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static inline enum cpuhp_state
|
static inline enum cpuhp_state
|
||||||
|
@ -1793,6 +1813,16 @@ static int __init parallel_bringup_parse_param(char *arg)
|
||||||
}
|
}
|
||||||
early_param("cpuhp.parallel", parallel_bringup_parse_param);
|
early_param("cpuhp.parallel", parallel_bringup_parse_param);
|
||||||
|
|
||||||
|
static inline bool cpuhp_smt_aware(void)
|
||||||
|
{
|
||||||
|
return cpu_smt_max_threads > 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline const struct cpumask *cpuhp_get_primary_thread_mask(void)
|
||||||
|
{
|
||||||
|
return cpu_primary_thread_mask;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* On architectures which have enabled parallel bringup this invokes all BP
|
* On architectures which have enabled parallel bringup this invokes all BP
|
||||||
* prepare states for each of the to be onlined APs first. The last state
|
* prepare states for each of the to be onlined APs first. The last state
|
||||||
|
@ -2626,6 +2656,12 @@ int cpuhp_smt_disable(enum cpuhp_smt_control ctrlval)
|
||||||
for_each_online_cpu(cpu) {
|
for_each_online_cpu(cpu) {
|
||||||
if (topology_is_primary_thread(cpu))
|
if (topology_is_primary_thread(cpu))
|
||||||
continue;
|
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 && cpu_smt_thread_allowed(cpu))
|
||||||
|
continue;
|
||||||
ret = cpu_down_maps_locked(cpu, CPUHP_OFFLINE);
|
ret = cpu_down_maps_locked(cpu, CPUHP_OFFLINE);
|
||||||
if (ret)
|
if (ret)
|
||||||
break;
|
break;
|
||||||
|
@ -2660,6 +2696,8 @@ int cpuhp_smt_enable(void)
|
||||||
/* Skip online CPUs and CPUs on offline nodes */
|
/* Skip online CPUs and CPUs on offline nodes */
|
||||||
if (cpu_online(cpu) || !node_online(cpu_to_node(cpu)))
|
if (cpu_online(cpu) || !node_online(cpu_to_node(cpu)))
|
||||||
continue;
|
continue;
|
||||||
|
if (!cpu_smt_thread_allowed(cpu))
|
||||||
|
continue;
|
||||||
ret = _cpu_up(cpu, 0, CPUHP_ONLINE);
|
ret = _cpu_up(cpu, 0, CPUHP_ONLINE);
|
||||||
if (ret)
|
if (ret)
|
||||||
break;
|
break;
|
||||||
|
@ -2838,20 +2876,19 @@ static const struct attribute_group cpuhp_cpu_root_attr_group = {
|
||||||
|
|
||||||
#ifdef CONFIG_HOTPLUG_SMT
|
#ifdef CONFIG_HOTPLUG_SMT
|
||||||
|
|
||||||
|
static bool cpu_smt_num_threads_valid(unsigned int threads)
|
||||||
|
{
|
||||||
|
if (IS_ENABLED(CONFIG_SMT_NUM_THREADS_DYNAMIC))
|
||||||
|
return threads >= 1 && threads <= cpu_smt_max_threads;
|
||||||
|
return threads == 1 || threads == cpu_smt_max_threads;
|
||||||
|
}
|
||||||
|
|
||||||
static ssize_t
|
static ssize_t
|
||||||
__store_smt_control(struct device *dev, struct device_attribute *attr,
|
__store_smt_control(struct device *dev, struct device_attribute *attr,
|
||||||
const char *buf, size_t count)
|
const char *buf, size_t count)
|
||||||
{
|
{
|
||||||
int ctrlval, ret;
|
int ctrlval, ret, num_threads, orig_threads;
|
||||||
|
bool force_off;
|
||||||
if (sysfs_streq(buf, "on"))
|
|
||||||
ctrlval = CPU_SMT_ENABLED;
|
|
||||||
else if (sysfs_streq(buf, "off"))
|
|
||||||
ctrlval = CPU_SMT_DISABLED;
|
|
||||||
else if (sysfs_streq(buf, "forceoff"))
|
|
||||||
ctrlval = CPU_SMT_FORCE_DISABLED;
|
|
||||||
else
|
|
||||||
return -EINVAL;
|
|
||||||
|
|
||||||
if (cpu_smt_control == CPU_SMT_FORCE_DISABLED)
|
if (cpu_smt_control == CPU_SMT_FORCE_DISABLED)
|
||||||
return -EPERM;
|
return -EPERM;
|
||||||
|
@ -2859,21 +2896,39 @@ __store_smt_control(struct device *dev, struct device_attribute *attr,
|
||||||
if (cpu_smt_control == CPU_SMT_NOT_SUPPORTED)
|
if (cpu_smt_control == CPU_SMT_NOT_SUPPORTED)
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
|
|
||||||
|
if (sysfs_streq(buf, "on")) {
|
||||||
|
ctrlval = CPU_SMT_ENABLED;
|
||||||
|
num_threads = cpu_smt_max_threads;
|
||||||
|
} else if (sysfs_streq(buf, "off")) {
|
||||||
|
ctrlval = CPU_SMT_DISABLED;
|
||||||
|
num_threads = 1;
|
||||||
|
} else if (sysfs_streq(buf, "forceoff")) {
|
||||||
|
ctrlval = CPU_SMT_FORCE_DISABLED;
|
||||||
|
num_threads = 1;
|
||||||
|
} else if (kstrtoint(buf, 10, &num_threads) == 0) {
|
||||||
|
if (num_threads == 1)
|
||||||
|
ctrlval = CPU_SMT_DISABLED;
|
||||||
|
else if (cpu_smt_num_threads_valid(num_threads))
|
||||||
|
ctrlval = CPU_SMT_ENABLED;
|
||||||
|
else
|
||||||
|
return -EINVAL;
|
||||||
|
} else {
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
ret = lock_device_hotplug_sysfs();
|
ret = lock_device_hotplug_sysfs();
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
if (ctrlval != cpu_smt_control) {
|
orig_threads = cpu_smt_num_threads;
|
||||||
switch (ctrlval) {
|
cpu_smt_num_threads = num_threads;
|
||||||
case CPU_SMT_ENABLED:
|
|
||||||
ret = cpuhp_smt_enable();
|
force_off = ctrlval != cpu_smt_control && ctrlval == CPU_SMT_FORCE_DISABLED;
|
||||||
break;
|
|
||||||
case CPU_SMT_DISABLED:
|
if (num_threads > orig_threads)
|
||||||
case CPU_SMT_FORCE_DISABLED:
|
ret = cpuhp_smt_enable();
|
||||||
ret = cpuhp_smt_disable(ctrlval);
|
else if (num_threads < orig_threads || force_off)
|
||||||
break;
|
ret = cpuhp_smt_disable(ctrlval);
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
unlock_device_hotplug();
|
unlock_device_hotplug();
|
||||||
return ret ? ret : count;
|
return ret ? ret : count;
|
||||||
|
@ -2901,6 +2956,17 @@ static ssize_t control_show(struct device *dev,
|
||||||
{
|
{
|
||||||
const char *state = smt_states[cpu_smt_control];
|
const char *state = smt_states[cpu_smt_control];
|
||||||
|
|
||||||
|
#ifdef CONFIG_HOTPLUG_SMT
|
||||||
|
/*
|
||||||
|
* If SMT is enabled but not all threads are enabled then show the
|
||||||
|
* number of threads. If all threads are enabled show "on". Otherwise
|
||||||
|
* show the state name.
|
||||||
|
*/
|
||||||
|
if (cpu_smt_control == CPU_SMT_ENABLED &&
|
||||||
|
cpu_smt_num_threads != cpu_smt_max_threads)
|
||||||
|
return sysfs_emit(buf, "%d\n", cpu_smt_num_threads);
|
||||||
|
#endif
|
||||||
|
|
||||||
return snprintf(buf, PAGE_SIZE - 2, "%s\n", state);
|
return snprintf(buf, PAGE_SIZE - 2, "%s\n", state);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue