aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/base/cpu.c25
1 files changed, 23 insertions, 2 deletions
diff --git a/drivers/base/cpu.c b/drivers/base/cpu.c
index d8c7f3ee6e19..3d48fc887ef4 100644
--- a/drivers/base/cpu.c
+++ b/drivers/base/cpu.c
@@ -25,6 +25,15 @@ EXPORT_SYMBOL_GPL(cpu_subsys);
25static DEFINE_PER_CPU(struct device *, cpu_sys_devices); 25static DEFINE_PER_CPU(struct device *, cpu_sys_devices);
26 26
27#ifdef CONFIG_HOTPLUG_CPU 27#ifdef CONFIG_HOTPLUG_CPU
28static void change_cpu_under_node(struct cpu *cpu,
29 unsigned int from_nid, unsigned int to_nid)
30{
31 int cpuid = cpu->dev.id;
32 unregister_cpu_under_node(cpuid, from_nid);
33 register_cpu_under_node(cpuid, to_nid);
34 cpu->node_id = to_nid;
35}
36
28static ssize_t show_online(struct device *dev, 37static ssize_t show_online(struct device *dev,
29 struct device_attribute *attr, 38 struct device_attribute *attr,
30 char *buf) 39 char *buf)
@@ -39,17 +48,29 @@ static ssize_t __ref store_online(struct device *dev,
39 const char *buf, size_t count) 48 const char *buf, size_t count)
40{ 49{
41 struct cpu *cpu = container_of(dev, struct cpu, dev); 50 struct cpu *cpu = container_of(dev, struct cpu, dev);
51 int cpuid = cpu->dev.id;
52 int from_nid, to_nid;
42 ssize_t ret; 53 ssize_t ret;
43 54
44 cpu_hotplug_driver_lock(); 55 cpu_hotplug_driver_lock();
45 switch (buf[0]) { 56 switch (buf[0]) {
46 case '0': 57 case '0':
47 ret = cpu_down(cpu->dev.id); 58 ret = cpu_down(cpuid);
48 if (!ret) 59 if (!ret)
49 kobject_uevent(&dev->kobj, KOBJ_OFFLINE); 60 kobject_uevent(&dev->kobj, KOBJ_OFFLINE);
50 break; 61 break;
51 case '1': 62 case '1':
52 ret = cpu_up(cpu->dev.id); 63 from_nid = cpu_to_node(cpuid);
64 ret = cpu_up(cpuid);
65
66 /*
67 * When hot adding memory to memoryless node and enabling a cpu
68 * on the node, node number of the cpu may internally change.
69 */
70 to_nid = cpu_to_node(cpuid);
71 if (from_nid != to_nid)
72 change_cpu_under_node(cpu, from_nid, to_nid);
73
53 if (!ret) 74 if (!ret)
54 kobject_uevent(&dev->kobj, KOBJ_ONLINE); 75 kobject_uevent(&dev->kobj, KOBJ_ONLINE);
55 break; 76 break;