@@ -25,6 +25,15 @@ EXPORT_SYMBOL_GPL(cpu_subsys);
25
25
static DEFINE_PER_CPU (struct device * , cpu_sys_devices ) ;
26
26
27
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
37
static ssize_t show_online (struct device * dev ,
29
38
struct device_attribute * attr ,
30
39
char * buf )
@@ -39,17 +48,29 @@ static ssize_t __ref store_online(struct device *dev,
39
48
const char * buf , size_t count )
40
49
{
41
50
struct cpu * cpu = container_of (dev , struct cpu , dev );
51
+ int cpuid = cpu -> dev .id ;
52
+ int from_nid , to_nid ;
42
53
ssize_t ret ;
43
54
44
55
cpu_hotplug_driver_lock ();
45
56
switch (buf [0 ]) {
46
57
case '0' :
47
- ret = cpu_down (cpu -> dev . id );
58
+ ret = cpu_down (cpuid );
48
59
if (!ret )
49
60
kobject_uevent (& dev -> kobj , KOBJ_OFFLINE );
50
61
break ;
51
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
74
if (!ret )
54
75
kobject_uevent (& dev -> kobj , KOBJ_ONLINE );
55
76
break ;
0 commit comments