diff options
author | Dave Hansen <haveblue@us.ibm.com> | 2005-10-29 18:16:53 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2005-10-29 21:40:44 -0700 |
commit | bdc8cb984576ab5b550c8b24c6fa111a873503e3 (patch) | |
tree | f94548988874caa10d770e6e65bc50c925abf825 /mm | |
parent | 208d54e5513c0c02d85af0990901354c74364d5c (diff) | |
download | linux-3.10-bdc8cb984576ab5b550c8b24c6fa111a873503e3.tar.gz linux-3.10-bdc8cb984576ab5b550c8b24c6fa111a873503e3.tar.bz2 linux-3.10-bdc8cb984576ab5b550c8b24c6fa111a873503e3.zip |
[PATCH] memory hotplug locking: zone span seqlock
See the "fixup bad_range()" patch for more information, but this actually
creates a the lock to protect things making assumptions about a zone's size
staying constant at runtime.
Signed-off-by: Dave Hansen <haveblue@us.ibm.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'mm')
-rw-r--r-- | mm/page_alloc.c | 19 |
1 files changed, 14 insertions, 5 deletions
diff --git a/mm/page_alloc.c b/mm/page_alloc.c index 32fad6d2320..817635f2ab6 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c @@ -33,6 +33,7 @@ #include <linux/sysctl.h> #include <linux/cpu.h> #include <linux/cpuset.h> +#include <linux/memory_hotplug.h> #include <linux/nodemask.h> #include <linux/vmalloc.h> @@ -80,12 +81,19 @@ unsigned long __initdata nr_all_pages; static int page_outside_zone_boundaries(struct zone *zone, struct page *page) { - if (page_to_pfn(page) >= zone->zone_start_pfn + zone->spanned_pages) - return 1; - if (page_to_pfn(page) < zone->zone_start_pfn) - return 1; + int ret = 0; + unsigned seq; + unsigned long pfn = page_to_pfn(page); - return 0; + do { + seq = zone_span_seqbegin(zone); + if (pfn >= zone->zone_start_pfn + zone->spanned_pages) + ret = 1; + else if (pfn < zone->zone_start_pfn) + ret = 1; + } while (zone_span_seqretry(zone, seq)); + + return ret; } static int page_is_consistent(struct zone *zone, struct page *page) @@ -1980,6 +1988,7 @@ static void __init free_area_init_core(struct pglist_data *pgdat, zone->name = zone_names[j]; spin_lock_init(&zone->lock); spin_lock_init(&zone->lru_lock); + zone_seqlock_init(zone); zone->zone_pgdat = pgdat; zone->free_pages = 0; |