aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/linux/memory_hotplug.h1
-rw-r--r--kernel/cpu.c25
-rw-r--r--mm/memory_hotplug.c23
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
205extern int mem_online_node(int nid);
205extern int add_memory(int nid, u64 start, u64 size); 206extern int add_memory(int nid, u64 start, u64 size);
206extern int arch_add_memory(int nid, u64 start, u64 size); 207extern int arch_add_memory(int nid, u64 start, u64 size);
207extern int remove_memory(u64 start, u64 size); 208extern 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:
326int __cpuinit cpu_up(unsigned int cpu) 326int __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 */
488int 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
503out:
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 */
486int __ref add_memory(int nid, u64 start, u64 size) 509int __ref add_memory(int nid, u64 start, u64 size)
487{ 510{