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 | { |
