aboutsummaryrefslogtreecommitdiffstats
path: root/mm/memory_hotplug.c
diff options
context:
space:
mode:
Diffstat (limited to 'mm/memory_hotplug.c')
-rw-r--r--mm/memory_hotplug.c21
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
519error: 525error:
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
532out:
533 unlock_system_sleep();
526 return ret; 534 return ret;
527} 535}
528EXPORT_SYMBOL_GPL(add_memory); 536EXPORT_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
849failed_removal: 860failed_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
867out:
868 unlock_system_sleep();
856 return ret; 869 return ret;
857} 870}
858 871