diff options
-rw-r--r-- | include/linux/memory_hotplug.h | 6 | ||||
-rw-r--r-- | mm/memory_hotplug.c | 4 |
2 files changed, 10 insertions, 0 deletions
diff --git a/include/linux/memory_hotplug.h b/include/linux/memory_hotplug.h index 31c237a00c48..12b9eb5a36c3 100644 --- a/include/linux/memory_hotplug.h +++ b/include/linux/memory_hotplug.h | |||
@@ -161,6 +161,12 @@ extern void register_page_bootmem_info_node(struct pglist_data *pgdat); | |||
161 | extern void put_page_bootmem(struct page *page); | 161 | extern void put_page_bootmem(struct page *page); |
162 | #endif | 162 | #endif |
163 | 163 | ||
164 | /* | ||
165 | * Lock for memory hotplug guarantees 1) all callbacks for memory hotplug | ||
166 | * notifier will be called under this. 2) offline/online/add/remove memory | ||
167 | * will not run simultaneously. | ||
168 | */ | ||
169 | |||
164 | void lock_memory_hotplug(void); | 170 | void lock_memory_hotplug(void); |
165 | void unlock_memory_hotplug(void); | 171 | void unlock_memory_hotplug(void); |
166 | 172 | ||
diff --git a/mm/memory_hotplug.c b/mm/memory_hotplug.c index 2c6523af5473..83163c096a75 100644 --- a/mm/memory_hotplug.c +++ b/mm/memory_hotplug.c | |||
@@ -407,6 +407,7 @@ int online_pages(unsigned long pfn, unsigned long nr_pages) | |||
407 | int ret; | 407 | int ret; |
408 | struct memory_notify arg; | 408 | struct memory_notify arg; |
409 | 409 | ||
410 | lock_memory_hotplug(); | ||
410 | arg.start_pfn = pfn; | 411 | arg.start_pfn = pfn; |
411 | arg.nr_pages = nr_pages; | 412 | arg.nr_pages = nr_pages; |
412 | arg.status_change_nid = -1; | 413 | arg.status_change_nid = -1; |
@@ -419,6 +420,7 @@ int online_pages(unsigned long pfn, unsigned long nr_pages) | |||
419 | ret = notifier_to_errno(ret); | 420 | ret = notifier_to_errno(ret); |
420 | if (ret) { | 421 | if (ret) { |
421 | memory_notify(MEM_CANCEL_ONLINE, &arg); | 422 | memory_notify(MEM_CANCEL_ONLINE, &arg); |
423 | unlock_memory_hotplug(); | ||
422 | return ret; | 424 | return ret; |
423 | } | 425 | } |
424 | /* | 426 | /* |
@@ -443,6 +445,7 @@ int online_pages(unsigned long pfn, unsigned long nr_pages) | |||
443 | printk(KERN_DEBUG "online_pages %lx at %lx failed\n", | 445 | printk(KERN_DEBUG "online_pages %lx at %lx failed\n", |
444 | nr_pages, pfn); | 446 | nr_pages, pfn); |
445 | memory_notify(MEM_CANCEL_ONLINE, &arg); | 447 | memory_notify(MEM_CANCEL_ONLINE, &arg); |
448 | unlock_memory_hotplug(); | ||
446 | return ret; | 449 | return ret; |
447 | } | 450 | } |
448 | 451 | ||
@@ -467,6 +470,7 @@ int online_pages(unsigned long pfn, unsigned long nr_pages) | |||
467 | 470 | ||
468 | if (onlined_pages) | 471 | if (onlined_pages) |
469 | memory_notify(MEM_ONLINE, &arg); | 472 | memory_notify(MEM_ONLINE, &arg); |
473 | unlock_memory_hotplug(); | ||
470 | 474 | ||
471 | return 0; | 475 | return 0; |
472 | } | 476 | } |