diff options
Diffstat (limited to 'mm/memory_hotplug.c')
-rw-r--r-- | mm/memory_hotplug.c | 21 |
1 files changed, 17 insertions, 4 deletions
diff --git a/mm/memory_hotplug.c b/mm/memory_hotplug.c index 380aef45c2cf..2047465cd27c 100644 --- a/mm/memory_hotplug.c +++ b/mm/memory_hotplug.c | |||
@@ -26,6 +26,7 @@ | |||
26 | #include <linux/migrate.h> | 26 | #include <linux/migrate.h> |
27 | #include <linux/page-isolation.h> | 27 | #include <linux/page-isolation.h> |
28 | #include <linux/pfn.h> | 28 | #include <linux/pfn.h> |
29 | #include <linux/suspend.h> | ||
29 | 30 | ||
30 | #include <asm/tlbflush.h> | 31 | #include <asm/tlbflush.h> |
31 | 32 | ||
@@ -485,14 +486,18 @@ int __ref add_memory(int nid, u64 start, u64 size) | |||
485 | struct resource *res; | 486 | struct resource *res; |
486 | int ret; | 487 | int ret; |
487 | 488 | ||
489 | lock_system_sleep(); | ||
490 | |||
488 | res = register_memory_resource(start, size); | 491 | res = register_memory_resource(start, size); |
492 | ret = -EEXIST; | ||
489 | if (!res) | 493 | if (!res) |
490 | return -EEXIST; | 494 | goto out; |
491 | 495 | ||
492 | if (!node_online(nid)) { | 496 | if (!node_online(nid)) { |
493 | pgdat = hotadd_new_pgdat(nid, start); | 497 | pgdat = hotadd_new_pgdat(nid, start); |
498 | ret = -ENOMEM; | ||
494 | if (!pgdat) | 499 | if (!pgdat) |
495 | return -ENOMEM; | 500 | goto out; |
496 | new_pgdat = 1; | 501 | new_pgdat = 1; |
497 | } | 502 | } |
498 | 503 | ||
@@ -515,7 +520,8 @@ int __ref add_memory(int nid, u64 start, u64 size) | |||
515 | BUG_ON(ret); | 520 | BUG_ON(ret); |
516 | } | 521 | } |
517 | 522 | ||
518 | return ret; | 523 | goto out; |
524 | |||
519 | error: | 525 | error: |
520 | /* rollback pgdat allocation and others */ | 526 | /* rollback pgdat allocation and others */ |
521 | if (new_pgdat) | 527 | if (new_pgdat) |
@@ -523,6 +529,8 @@ error: | |||
523 | if (res) | 529 | if (res) |
524 | release_memory_resource(res); | 530 | release_memory_resource(res); |
525 | 531 | ||
532 | out: | ||
533 | unlock_system_sleep(); | ||
526 | return ret; | 534 | return ret; |
527 | } | 535 | } |
528 | EXPORT_SYMBOL_GPL(add_memory); | 536 | EXPORT_SYMBOL_GPL(add_memory); |
@@ -759,6 +767,8 @@ int offline_pages(unsigned long start_pfn, | |||
759 | if (!test_pages_in_a_zone(start_pfn, end_pfn)) | 767 | if (!test_pages_in_a_zone(start_pfn, end_pfn)) |
760 | return -EINVAL; | 768 | return -EINVAL; |
761 | 769 | ||
770 | lock_system_sleep(); | ||
771 | |||
762 | zone = page_zone(pfn_to_page(start_pfn)); | 772 | zone = page_zone(pfn_to_page(start_pfn)); |
763 | node = zone_to_nid(zone); | 773 | node = zone_to_nid(zone); |
764 | nr_pages = end_pfn - start_pfn; | 774 | nr_pages = end_pfn - start_pfn; |
@@ -766,7 +776,7 @@ int offline_pages(unsigned long start_pfn, | |||
766 | /* set above range as isolated */ | 776 | /* set above range as isolated */ |
767 | ret = start_isolate_page_range(start_pfn, end_pfn); | 777 | ret = start_isolate_page_range(start_pfn, end_pfn); |
768 | if (ret) | 778 | if (ret) |
769 | return ret; | 779 | goto out; |
770 | 780 | ||
771 | arg.start_pfn = start_pfn; | 781 | arg.start_pfn = start_pfn; |
772 | arg.nr_pages = nr_pages; | 782 | arg.nr_pages = nr_pages; |
@@ -844,6 +854,7 @@ repeat: | |||
844 | writeback_set_ratelimit(); | 854 | writeback_set_ratelimit(); |
845 | 855 | ||
846 | memory_notify(MEM_OFFLINE, &arg); | 856 | memory_notify(MEM_OFFLINE, &arg); |
857 | unlock_system_sleep(); | ||
847 | return 0; | 858 | return 0; |
848 | 859 | ||
849 | failed_removal: | 860 | failed_removal: |
@@ -853,6 +864,8 @@ failed_removal: | |||
853 | /* pushback to free area */ | 864 | /* pushback to free area */ |
854 | undo_isolate_page_range(start_pfn, end_pfn); | 865 | undo_isolate_page_range(start_pfn, end_pfn); |
855 | 866 | ||
867 | out: | ||
868 | unlock_system_sleep(); | ||
856 | return ret; | 869 | return ret; |
857 | } | 870 | } |
858 | 871 | ||