diff options
-rw-r--r-- | drivers/base/cpu.c | 25 |
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); | |||
25 | static DEFINE_PER_CPU(struct device *, cpu_sys_devices); | 25 | static DEFINE_PER_CPU(struct device *, cpu_sys_devices); |
26 | 26 | ||
27 | #ifdef CONFIG_HOTPLUG_CPU | 27 | #ifdef CONFIG_HOTPLUG_CPU |
28 | static 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 | |||
28 | static ssize_t show_online(struct device *dev, | 37 | static 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; |