diff options
author | KOSAKI Motohiro <kosaki.motohiro@jp.fujitsu.com> | 2010-12-02 17:31:19 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2010-12-02 17:51:15 -0500 |
commit | 20d6c96b5f1cad5c5da4641945ec17a1d9a1afc8 (patch) | |
tree | 38168dc87d58fd924adb3aaca540cd23ad1246bf /mm | |
parent | 4fe65cab844e6d3d7d310e66a501d5e7242ecb54 (diff) |
mem-hotplug: introduce {un}lock_memory_hotplug()
Presently hwpoison is using lock_system_sleep() to prevent a race with
memory hotplug. However lock_system_sleep() is a no-op if
CONFIG_HIBERNATION=n. Therefore we need a new lock.
Signed-off-by: KOSAKI Motohiro <kosaki.motohiro@jp.fujitsu.com>
Cc: Andi Kleen <andi@firstfloor.org>
Cc: Kamezawa Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com>
Suggested-by: Hugh Dickins <hughd@google.com>
Acked-by: Hugh Dickins <hughd@google.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'mm')
-rw-r--r-- | mm/memory-failure.c | 8 | ||||
-rw-r--r-- | mm/memory_hotplug.c | 31 |
2 files changed, 28 insertions, 11 deletions
diff --git a/mm/memory-failure.c b/mm/memory-failure.c index 124324134ff6..46ab2c044b0e 100644 --- a/mm/memory-failure.c +++ b/mm/memory-failure.c | |||
@@ -51,6 +51,7 @@ | |||
51 | #include <linux/slab.h> | 51 | #include <linux/slab.h> |
52 | #include <linux/swapops.h> | 52 | #include <linux/swapops.h> |
53 | #include <linux/hugetlb.h> | 53 | #include <linux/hugetlb.h> |
54 | #include <linux/memory_hotplug.h> | ||
54 | #include "internal.h" | 55 | #include "internal.h" |
55 | 56 | ||
56 | int sysctl_memory_failure_early_kill __read_mostly = 0; | 57 | int sysctl_memory_failure_early_kill __read_mostly = 0; |
@@ -1230,11 +1231,10 @@ static int get_any_page(struct page *p, unsigned long pfn, int flags) | |||
1230 | return 1; | 1231 | return 1; |
1231 | 1232 | ||
1232 | /* | 1233 | /* |
1233 | * The lock_system_sleep prevents a race with memory hotplug, | 1234 | * The lock_memory_hotplug prevents a race with memory hotplug. |
1234 | * because the isolation assumes there's only a single user. | ||
1235 | * This is a big hammer, a better would be nicer. | 1235 | * This is a big hammer, a better would be nicer. |
1236 | */ | 1236 | */ |
1237 | lock_system_sleep(); | 1237 | lock_memory_hotplug(); |
1238 | 1238 | ||
1239 | /* | 1239 | /* |
1240 | * Isolate the page, so that it doesn't get reallocated if it | 1240 | * Isolate the page, so that it doesn't get reallocated if it |
@@ -1264,7 +1264,7 @@ static int get_any_page(struct page *p, unsigned long pfn, int flags) | |||
1264 | ret = 1; | 1264 | ret = 1; |
1265 | } | 1265 | } |
1266 | unset_migratetype_isolate(p); | 1266 | unset_migratetype_isolate(p); |
1267 | unlock_system_sleep(); | 1267 | unlock_memory_hotplug(); |
1268 | return ret; | 1268 | return ret; |
1269 | } | 1269 | } |
1270 | 1270 | ||
diff --git a/mm/memory_hotplug.c b/mm/memory_hotplug.c index 9260314a221e..2c6523af5473 100644 --- a/mm/memory_hotplug.c +++ b/mm/memory_hotplug.c | |||
@@ -34,6 +34,23 @@ | |||
34 | 34 | ||
35 | #include "internal.h" | 35 | #include "internal.h" |
36 | 36 | ||
37 | DEFINE_MUTEX(mem_hotplug_mutex); | ||
38 | |||
39 | void lock_memory_hotplug(void) | ||
40 | { | ||
41 | mutex_lock(&mem_hotplug_mutex); | ||
42 | |||
43 | /* for exclusive hibernation if CONFIG_HIBERNATION=y */ | ||
44 | lock_system_sleep(); | ||
45 | } | ||
46 | |||
47 | void unlock_memory_hotplug(void) | ||
48 | { | ||
49 | unlock_system_sleep(); | ||
50 | mutex_unlock(&mem_hotplug_mutex); | ||
51 | } | ||
52 | |||
53 | |||
37 | /* add this memory to iomem resource */ | 54 | /* add this memory to iomem resource */ |
38 | static struct resource *register_memory_resource(u64 start, u64 size) | 55 | static struct resource *register_memory_resource(u64 start, u64 size) |
39 | { | 56 | { |
@@ -493,7 +510,7 @@ int mem_online_node(int nid) | |||
493 | pg_data_t *pgdat; | 510 | pg_data_t *pgdat; |
494 | int ret; | 511 | int ret; |
495 | 512 | ||
496 | lock_system_sleep(); | 513 | lock_memory_hotplug(); |
497 | pgdat = hotadd_new_pgdat(nid, 0); | 514 | pgdat = hotadd_new_pgdat(nid, 0); |
498 | if (pgdat) { | 515 | if (pgdat) { |
499 | ret = -ENOMEM; | 516 | ret = -ENOMEM; |
@@ -504,7 +521,7 @@ int mem_online_node(int nid) | |||
504 | BUG_ON(ret); | 521 | BUG_ON(ret); |
505 | 522 | ||
506 | out: | 523 | out: |
507 | unlock_system_sleep(); | 524 | unlock_memory_hotplug(); |
508 | return ret; | 525 | return ret; |
509 | } | 526 | } |
510 | 527 | ||
@@ -516,7 +533,7 @@ int __ref add_memory(int nid, u64 start, u64 size) | |||
516 | struct resource *res; | 533 | struct resource *res; |
517 | int ret; | 534 | int ret; |
518 | 535 | ||
519 | lock_system_sleep(); | 536 | lock_memory_hotplug(); |
520 | 537 | ||
521 | res = register_memory_resource(start, size); | 538 | res = register_memory_resource(start, size); |
522 | ret = -EEXIST; | 539 | ret = -EEXIST; |
@@ -563,7 +580,7 @@ error: | |||
563 | release_memory_resource(res); | 580 | release_memory_resource(res); |
564 | 581 | ||
565 | out: | 582 | out: |
566 | unlock_system_sleep(); | 583 | unlock_memory_hotplug(); |
567 | return ret; | 584 | return ret; |
568 | } | 585 | } |
569 | EXPORT_SYMBOL_GPL(add_memory); | 586 | EXPORT_SYMBOL_GPL(add_memory); |
@@ -791,7 +808,7 @@ static int offline_pages(unsigned long start_pfn, | |||
791 | if (!test_pages_in_a_zone(start_pfn, end_pfn)) | 808 | if (!test_pages_in_a_zone(start_pfn, end_pfn)) |
792 | return -EINVAL; | 809 | return -EINVAL; |
793 | 810 | ||
794 | lock_system_sleep(); | 811 | lock_memory_hotplug(); |
795 | 812 | ||
796 | zone = page_zone(pfn_to_page(start_pfn)); | 813 | zone = page_zone(pfn_to_page(start_pfn)); |
797 | node = zone_to_nid(zone); | 814 | node = zone_to_nid(zone); |
@@ -880,7 +897,7 @@ repeat: | |||
880 | writeback_set_ratelimit(); | 897 | writeback_set_ratelimit(); |
881 | 898 | ||
882 | memory_notify(MEM_OFFLINE, &arg); | 899 | memory_notify(MEM_OFFLINE, &arg); |
883 | unlock_system_sleep(); | 900 | unlock_memory_hotplug(); |
884 | return 0; | 901 | return 0; |
885 | 902 | ||
886 | failed_removal: | 903 | failed_removal: |
@@ -891,7 +908,7 @@ failed_removal: | |||
891 | undo_isolate_page_range(start_pfn, end_pfn); | 908 | undo_isolate_page_range(start_pfn, end_pfn); |
892 | 909 | ||
893 | out: | 910 | out: |
894 | unlock_system_sleep(); | 911 | unlock_memory_hotplug(); |
895 | return ret; | 912 | return ret; |
896 | } | 913 | } |
897 | 914 | ||