cpu/hotplug: Create SMT sysfs interface for all arches
Make the /sys/devices/system/cpu/smt/* files available on all arches, so user space has a consistent way to detect whether SMT is enabled. The 'control' file now shows 'notimplemented' for architectures which don't yet have CONFIG_HOTPLUG_SMT. [ tglx: Make notimplemented a real state ] Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com> Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Cc: Andrea Arcangeli <aarcange@redhat.com> Cc: Waiman Long <longman@redhat.com> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Jiri Kosina <jikos@kernel.org> Link: https://lkml.kernel.org/r/469c2b98055f2c41e75748e06447d592a64080c9.1553635520.git.jpoimboe@redhat.com
This commit is contained in:
parent
79a3aaa7b8
commit
de7b77e5bb
|
@ -511,10 +511,12 @@ Description: Control Symetric Multi Threading (SMT)
|
||||||
control: Read/write interface to control SMT. Possible
|
control: Read/write interface to control SMT. Possible
|
||||||
values:
|
values:
|
||||||
|
|
||||||
"on" SMT is enabled
|
"on" SMT is enabled
|
||||||
"off" SMT is disabled
|
"off" SMT is disabled
|
||||||
"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
|
||||||
|
implemented for the architecture
|
||||||
|
|
||||||
If control status is "forceoff" or "notsupported" writes
|
If control status is "forceoff" or "notsupported" writes
|
||||||
are rejected.
|
are rejected.
|
||||||
|
|
|
@ -175,6 +175,7 @@ enum cpuhp_smt_control {
|
||||||
CPU_SMT_DISABLED,
|
CPU_SMT_DISABLED,
|
||||||
CPU_SMT_FORCE_DISABLED,
|
CPU_SMT_FORCE_DISABLED,
|
||||||
CPU_SMT_NOT_SUPPORTED,
|
CPU_SMT_NOT_SUPPORTED,
|
||||||
|
CPU_SMT_NOT_IMPLEMENTED,
|
||||||
};
|
};
|
||||||
|
|
||||||
#if defined(CONFIG_SMP) && defined(CONFIG_HOTPLUG_SMT)
|
#if defined(CONFIG_SMP) && defined(CONFIG_HOTPLUG_SMT)
|
||||||
|
@ -182,7 +183,7 @@ extern enum cpuhp_smt_control cpu_smt_control;
|
||||||
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_check_topology(void);
|
||||||
#else
|
#else
|
||||||
# define cpu_smt_control (CPU_SMT_ENABLED)
|
# define cpu_smt_control (CPU_SMT_NOT_IMPLEMENTED)
|
||||||
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_check_topology(void) { }
|
||||||
#endif
|
#endif
|
||||||
|
|
64
kernel/cpu.c
64
kernel/cpu.c
|
@ -2033,19 +2033,6 @@ static const struct attribute_group cpuhp_cpu_root_attr_group = {
|
||||||
|
|
||||||
#ifdef CONFIG_HOTPLUG_SMT
|
#ifdef CONFIG_HOTPLUG_SMT
|
||||||
|
|
||||||
static const char *smt_states[] = {
|
|
||||||
[CPU_SMT_ENABLED] = "on",
|
|
||||||
[CPU_SMT_DISABLED] = "off",
|
|
||||||
[CPU_SMT_FORCE_DISABLED] = "forceoff",
|
|
||||||
[CPU_SMT_NOT_SUPPORTED] = "notsupported",
|
|
||||||
};
|
|
||||||
|
|
||||||
static ssize_t
|
|
||||||
show_smt_control(struct device *dev, struct device_attribute *attr, char *buf)
|
|
||||||
{
|
|
||||||
return snprintf(buf, PAGE_SIZE - 2, "%s\n", smt_states[cpu_smt_control]);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void cpuhp_offline_cpu_device(unsigned int cpu)
|
static void cpuhp_offline_cpu_device(unsigned int cpu)
|
||||||
{
|
{
|
||||||
struct device *dev = get_cpu_device(cpu);
|
struct device *dev = get_cpu_device(cpu);
|
||||||
|
@ -2116,9 +2103,10 @@ static int cpuhp_smt_enable(void)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
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;
|
||||||
|
|
||||||
|
@ -2156,14 +2144,44 @@ store_smt_control(struct device *dev, struct device_attribute *attr,
|
||||||
unlock_device_hotplug();
|
unlock_device_hotplug();
|
||||||
return ret ? ret : count;
|
return ret ? ret : count;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#else /* !CONFIG_HOTPLUG_SMT */
|
||||||
|
static ssize_t
|
||||||
|
__store_smt_control(struct device *dev, struct device_attribute *attr,
|
||||||
|
const char *buf, size_t count)
|
||||||
|
{
|
||||||
|
return -ENODEV;
|
||||||
|
}
|
||||||
|
#endif /* CONFIG_HOTPLUG_SMT */
|
||||||
|
|
||||||
|
static const char *smt_states[] = {
|
||||||
|
[CPU_SMT_ENABLED] = "on",
|
||||||
|
[CPU_SMT_DISABLED] = "off",
|
||||||
|
[CPU_SMT_FORCE_DISABLED] = "forceoff",
|
||||||
|
[CPU_SMT_NOT_SUPPORTED] = "notsupported",
|
||||||
|
[CPU_SMT_NOT_IMPLEMENTED] = "notimplemented",
|
||||||
|
};
|
||||||
|
|
||||||
|
static ssize_t
|
||||||
|
show_smt_control(struct device *dev, struct device_attribute *attr, char *buf)
|
||||||
|
{
|
||||||
|
const char *state = smt_states[cpu_smt_control];
|
||||||
|
|
||||||
|
return snprintf(buf, PAGE_SIZE - 2, "%s\n", state);
|
||||||
|
}
|
||||||
|
|
||||||
|
static ssize_t
|
||||||
|
store_smt_control(struct device *dev, struct device_attribute *attr,
|
||||||
|
const char *buf, size_t count)
|
||||||
|
{
|
||||||
|
return __store_smt_control(dev, attr, buf, count);
|
||||||
|
}
|
||||||
static DEVICE_ATTR(control, 0644, show_smt_control, store_smt_control);
|
static DEVICE_ATTR(control, 0644, show_smt_control, store_smt_control);
|
||||||
|
|
||||||
static ssize_t
|
static ssize_t
|
||||||
show_smt_active(struct device *dev, struct device_attribute *attr, char *buf)
|
show_smt_active(struct device *dev, struct device_attribute *attr, char *buf)
|
||||||
{
|
{
|
||||||
bool active = topology_max_smt_threads() > 1;
|
return snprintf(buf, PAGE_SIZE - 2, "%d\n", sched_smt_active());
|
||||||
|
|
||||||
return snprintf(buf, PAGE_SIZE - 2, "%d\n", active);
|
|
||||||
}
|
}
|
||||||
static DEVICE_ATTR(active, 0444, show_smt_active, NULL);
|
static DEVICE_ATTR(active, 0444, show_smt_active, NULL);
|
||||||
|
|
||||||
|
@ -2179,21 +2197,17 @@ static const struct attribute_group cpuhp_smt_attr_group = {
|
||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
static int __init cpu_smt_state_init(void)
|
static int __init cpu_smt_sysfs_init(void)
|
||||||
{
|
{
|
||||||
return sysfs_create_group(&cpu_subsys.dev_root->kobj,
|
return sysfs_create_group(&cpu_subsys.dev_root->kobj,
|
||||||
&cpuhp_smt_attr_group);
|
&cpuhp_smt_attr_group);
|
||||||
}
|
}
|
||||||
|
|
||||||
#else
|
|
||||||
static inline int cpu_smt_state_init(void) { return 0; }
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static int __init cpuhp_sysfs_init(void)
|
static int __init cpuhp_sysfs_init(void)
|
||||||
{
|
{
|
||||||
int cpu, ret;
|
int cpu, ret;
|
||||||
|
|
||||||
ret = cpu_smt_state_init();
|
ret = cpu_smt_sysfs_init();
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
|
@ -2214,7 +2228,7 @@ static int __init cpuhp_sysfs_init(void)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
device_initcall(cpuhp_sysfs_init);
|
device_initcall(cpuhp_sysfs_init);
|
||||||
#endif
|
#endif /* CONFIG_SYSFS && CONFIG_HOTPLUG_CPU */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* cpu_bit_bitmap[] is a special, "compressed" data structure that
|
* cpu_bit_bitmap[] is a special, "compressed" data structure that
|
||||||
|
|
Loading…
Reference in New Issue