diff options
-rw-r--r-- | include/linux/memory_hotplug.h | 1 | ||||
-rw-r--r-- | kernel/cpu.c | 25 | ||||
-rw-r--r-- | mm/memory_hotplug.c | 23 |
3 files changed, 49 insertions, 0 deletions
diff --git a/include/linux/memory_hotplug.h b/include/linux/memory_hotplug.h index 35b07b773e6c..864035fb8f8a 100644 --- a/include/linux/memory_hotplug.h +++ b/include/linux/memory_hotplug.h | |||
@@ -202,6 +202,7 @@ static inline int is_mem_section_removable(unsigned long pfn, | |||
202 | } | 202 | } |
203 | #endif /* CONFIG_MEMORY_HOTREMOVE */ | 203 | #endif /* CONFIG_MEMORY_HOTREMOVE */ |
204 | 204 | ||
205 | extern int mem_online_node(int nid); | ||
205 | extern int add_memory(int nid, u64 start, u64 size); | 206 | extern int add_memory(int nid, u64 start, u64 size); |
206 | extern int arch_add_memory(int nid, u64 start, u64 size); | 207 | extern int arch_add_memory(int nid, u64 start, u64 size); |
207 | extern int remove_memory(u64 start, u64 size); | 208 | extern int remove_memory(u64 start, u64 size); |
diff --git a/kernel/cpu.c b/kernel/cpu.c index 545777574779..a3fbcc0a0abc 100644 --- a/kernel/cpu.c +++ b/kernel/cpu.c | |||
@@ -326,6 +326,12 @@ out_notify: | |||
326 | int __cpuinit cpu_up(unsigned int cpu) | 326 | int __cpuinit cpu_up(unsigned int cpu) |
327 | { | 327 | { |
328 | int err = 0; | 328 | int err = 0; |
329 | |||
330 | #ifdef CONFIG_MEMORY_HOTPLUG | ||
331 | int nid; | ||
332 | pg_data_t *pgdat; | ||
333 | #endif | ||
334 | |||
329 | if (!cpu_possible(cpu)) { | 335 | if (!cpu_possible(cpu)) { |
330 | printk(KERN_ERR "can't online cpu %d because it is not " | 336 | printk(KERN_ERR "can't online cpu %d because it is not " |
331 | "configured as may-hotadd at boot time\n", cpu); | 337 | "configured as may-hotadd at boot time\n", cpu); |
@@ -336,6 +342,25 @@ int __cpuinit cpu_up(unsigned int cpu) | |||
336 | return -EINVAL; | 342 | return -EINVAL; |
337 | } | 343 | } |
338 | 344 | ||
345 | #ifdef CONFIG_MEMORY_HOTPLUG | ||
346 | nid = cpu_to_node(cpu); | ||
347 | if (!node_online(nid)) { | ||
348 | err = mem_online_node(nid); | ||
349 | if (err) | ||
350 | return err; | ||
351 | } | ||
352 | |||
353 | pgdat = NODE_DATA(nid); | ||
354 | if (!pgdat) { | ||
355 | printk(KERN_ERR | ||
356 | "Can't online cpu %d due to NULL pgdat\n", cpu); | ||
357 | return -ENOMEM; | ||
358 | } | ||
359 | |||
360 | if (pgdat->node_zonelists->_zonerefs->zone == NULL) | ||
361 | build_all_zonelists(); | ||
362 | #endif | ||
363 | |||
339 | cpu_maps_update_begin(); | 364 | cpu_maps_update_begin(); |
340 | 365 | ||
341 | if (cpu_hotplug_disabled) { | 366 | if (cpu_hotplug_disabled) { |
diff --git a/mm/memory_hotplug.c b/mm/memory_hotplug.c index be211a582930..85eb4d342ac5 100644 --- a/mm/memory_hotplug.c +++ b/mm/memory_hotplug.c | |||
@@ -482,6 +482,29 @@ static void rollback_node_hotadd(int nid, pg_data_t *pgdat) | |||
482 | } | 482 | } |
483 | 483 | ||
484 | 484 | ||
485 | /* | ||
486 | * called by cpu_up() to online a node without onlined memory. | ||
487 | */ | ||
488 | int mem_online_node(int nid) | ||
489 | { | ||
490 | pg_data_t *pgdat; | ||
491 | int ret; | ||
492 | |||
493 | lock_system_sleep(); | ||
494 | pgdat = hotadd_new_pgdat(nid, 0); | ||
495 | if (pgdat) { | ||
496 | ret = -ENOMEM; | ||
497 | goto out; | ||
498 | } | ||
499 | node_set_online(nid); | ||
500 | ret = register_one_node(nid); | ||
501 | BUG_ON(ret); | ||
502 | |||
503 | out: | ||
504 | unlock_system_sleep(); | ||
505 | return ret; | ||
506 | } | ||
507 | |||
485 | /* we are OK calling __meminit stuff here - we have CONFIG_MEMORY_HOTPLUG */ | 508 | /* we are OK calling __meminit stuff here - we have CONFIG_MEMORY_HOTPLUG */ |
486 | int __ref add_memory(int nid, u64 start, u64 size) | 509 | int __ref add_memory(int nid, u64 start, u64 size) |
487 | { | 510 | { |