summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--kernel/cpu.c26
1 files changed, 24 insertions, 2 deletions
diff --git a/kernel/cpu.c b/kernel/cpu.c
index 5a00ebdf98c6..d79e24df2420 100644
--- a/kernel/cpu.c
+++ b/kernel/cpu.c
@@ -1979,6 +1979,15 @@ static void cpuhp_offline_cpu_device(unsigned int cpu)
kobject_uevent(&dev->kobj, KOBJ_OFFLINE);
}
+static void cpuhp_online_cpu_device(unsigned int cpu)
+{
+ struct device *dev = get_cpu_device(cpu);
+
+ dev->offline = false;
+ /* Tell user space about the state change */
+ kobject_uevent(&dev->kobj, KOBJ_ONLINE);
+}
+
static int cpuhp_smt_disable(enum cpuhp_smt_control ctrlval)
{
int cpu, ret = 0;
@@ -2011,11 +2020,24 @@ static int cpuhp_smt_disable(enum cpuhp_smt_control ctrlval)
return ret;
}
-static void cpuhp_smt_enable(void)
+static int cpuhp_smt_enable(void)
{
+ int cpu, ret = 0;
+
cpu_maps_update_begin();
cpu_smt_control = CPU_SMT_ENABLED;
+ for_each_present_cpu(cpu) {
+ /* Skip online CPUs and CPUs on offline nodes */
+ if (cpu_online(cpu) || !node_online(cpu_to_node(cpu)))
+ continue;
+ ret = _cpu_up(cpu, 0, CPUHP_ONLINE);
+ if (ret)
+ break;
+ /* See comment in cpuhp_smt_disable() */
+ cpuhp_online_cpu_device(cpu);
+ }
cpu_maps_update_done();
+ return ret;
}
static ssize_t
@@ -2046,7 +2068,7 @@ store_smt_control(struct device *dev, struct device_attribute *attr,
if (ctrlval != cpu_smt_control) {
switch (ctrlval) {
case CPU_SMT_ENABLED:
- cpuhp_smt_enable();
+ ret = cpuhp_smt_enable();
break;
case CPU_SMT_DISABLED:
case CPU_SMT_FORCE_DISABLED: