diff options
Diffstat (limited to 'mm/memory_hotplug.c')
| -rw-r--r-- | mm/memory_hotplug.c | 24 |
1 files changed, 19 insertions, 5 deletions
diff --git a/mm/memory_hotplug.c b/mm/memory_hotplug.c index 821dee596377..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 | ||
| @@ -447,7 +448,8 @@ int online_pages(unsigned long pfn, unsigned long nr_pages) | |||
| 447 | } | 448 | } |
| 448 | #endif /* CONFIG_MEMORY_HOTPLUG_SPARSE */ | 449 | #endif /* CONFIG_MEMORY_HOTPLUG_SPARSE */ |
| 449 | 450 | ||
| 450 | static pg_data_t *hotadd_new_pgdat(int nid, u64 start) | 451 | /* we are OK calling __meminit stuff here - we have CONFIG_MEMORY_HOTPLUG */ |
| 452 | static pg_data_t __ref *hotadd_new_pgdat(int nid, u64 start) | ||
| 451 | { | 453 | { |
| 452 | struct pglist_data *pgdat; | 454 | struct pglist_data *pgdat; |
| 453 | unsigned long zones_size[MAX_NR_ZONES] = {0}; | 455 | unsigned long zones_size[MAX_NR_ZONES] = {0}; |
| @@ -484,14 +486,18 @@ int __ref add_memory(int nid, u64 start, u64 size) | |||
| 484 | struct resource *res; | 486 | struct resource *res; |
| 485 | int ret; | 487 | int ret; |
| 486 | 488 | ||
| 489 | lock_system_sleep(); | ||
| 490 | |||
| 487 | res = register_memory_resource(start, size); | 491 | res = register_memory_resource(start, size); |
| 492 | ret = -EEXIST; | ||
| 488 | if (!res) | 493 | if (!res) |
| 489 | return -EEXIST; | 494 | goto out; |
| 490 | 495 | ||
| 491 | if (!node_online(nid)) { | 496 | if (!node_online(nid)) { |
| 492 | pgdat = hotadd_new_pgdat(nid, start); | 497 | pgdat = hotadd_new_pgdat(nid, start); |
| 498 | ret = -ENOMEM; | ||
| 493 | if (!pgdat) | 499 | if (!pgdat) |
| 494 | return -ENOMEM; | 500 | goto out; |
| 495 | new_pgdat = 1; | 501 | new_pgdat = 1; |
| 496 | } | 502 | } |
| 497 | 503 | ||
| @@ -514,7 +520,8 @@ int __ref add_memory(int nid, u64 start, u64 size) | |||
| 514 | BUG_ON(ret); | 520 | BUG_ON(ret); |
| 515 | } | 521 | } |
| 516 | 522 | ||
| 517 | return ret; | 523 | goto out; |
| 524 | |||
| 518 | error: | 525 | error: |
| 519 | /* rollback pgdat allocation and others */ | 526 | /* rollback pgdat allocation and others */ |
| 520 | if (new_pgdat) | 527 | if (new_pgdat) |
| @@ -522,6 +529,8 @@ error: | |||
| 522 | if (res) | 529 | if (res) |
| 523 | release_memory_resource(res); | 530 | release_memory_resource(res); |
| 524 | 531 | ||
| 532 | out: | ||
| 533 | unlock_system_sleep(); | ||
| 525 | return ret; | 534 | return ret; |
| 526 | } | 535 | } |
| 527 | EXPORT_SYMBOL_GPL(add_memory); | 536 | EXPORT_SYMBOL_GPL(add_memory); |
| @@ -758,6 +767,8 @@ int offline_pages(unsigned long start_pfn, | |||
| 758 | if (!test_pages_in_a_zone(start_pfn, end_pfn)) | 767 | if (!test_pages_in_a_zone(start_pfn, end_pfn)) |
| 759 | return -EINVAL; | 768 | return -EINVAL; |
| 760 | 769 | ||
| 770 | lock_system_sleep(); | ||
| 771 | |||
| 761 | zone = page_zone(pfn_to_page(start_pfn)); | 772 | zone = page_zone(pfn_to_page(start_pfn)); |
| 762 | node = zone_to_nid(zone); | 773 | node = zone_to_nid(zone); |
| 763 | nr_pages = end_pfn - start_pfn; | 774 | nr_pages = end_pfn - start_pfn; |
| @@ -765,7 +776,7 @@ int offline_pages(unsigned long start_pfn, | |||
| 765 | /* set above range as isolated */ | 776 | /* set above range as isolated */ |
| 766 | ret = start_isolate_page_range(start_pfn, end_pfn); | 777 | ret = start_isolate_page_range(start_pfn, end_pfn); |
| 767 | if (ret) | 778 | if (ret) |
| 768 | return ret; | 779 | goto out; |
| 769 | 780 | ||
| 770 | arg.start_pfn = start_pfn; | 781 | arg.start_pfn = start_pfn; |
| 771 | arg.nr_pages = nr_pages; | 782 | arg.nr_pages = nr_pages; |
| @@ -843,6 +854,7 @@ repeat: | |||
| 843 | writeback_set_ratelimit(); | 854 | writeback_set_ratelimit(); |
| 844 | 855 | ||
| 845 | memory_notify(MEM_OFFLINE, &arg); | 856 | memory_notify(MEM_OFFLINE, &arg); |
| 857 | unlock_system_sleep(); | ||
| 846 | return 0; | 858 | return 0; |
| 847 | 859 | ||
| 848 | failed_removal: | 860 | failed_removal: |
| @@ -852,6 +864,8 @@ failed_removal: | |||
| 852 | /* pushback to free area */ | 864 | /* pushback to free area */ |
| 853 | undo_isolate_page_range(start_pfn, end_pfn); | 865 | undo_isolate_page_range(start_pfn, end_pfn); |
| 854 | 866 | ||
| 867 | out: | ||
| 868 | unlock_system_sleep(); | ||
| 855 | return ret; | 869 | return ret; |
| 856 | } | 870 | } |
| 857 | 871 | ||
