diff options
author | Wen Congyang <wency@cn.fujitsu.com> | 2012-12-11 19:01:01 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-12-11 20:22:23 -0500 |
commit | 6dcd73d7011ba9046f9b98e7f7c9d958f5810e6b (patch) | |
tree | e2cc08839a13745a21ade3d5ab22d8f8836ace80 /mm/memory_hotplug.c | |
parent | 3ac19f8efe26451cacac31d0be34fa9c51114c2a (diff) |
memory-hotplug: allocate zone's pcp before onlining pages
We use __free_page() to put a page to buddy system when onlining pages.
__free_page() will store NR_FREE_PAGES in zone's pcp.vm_stat_diff, so we
should allocate zone's pcp before onlining pages, otherwise we will lose
some free pages.
[mhocko@suse.cz: make zone_pcp_reset independent of MEMORY_HOTREMOVE]
Signed-off-by: Wen Congyang <wency@cn.fujitsu.com>
Cc: David Rientjes <rientjes@google.com>
Cc: Jiang Liu <liuj97@gmail.com>
Cc: Len Brown <len.brown@intel.com>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Christoph Lameter <cl@linux.com>
Cc: Minchan Kim <minchan.kim@gmail.com>
Cc: KOSAKI Motohiro <kosaki.motohiro@jp.fujitsu.com>
Cc: Yasuaki Ishimatsu <isimatu.yasuaki@jp.fujitsu.com>
Cc: Dave Hansen <dave@linux.vnet.ibm.com>
Cc: Mel Gorman <mel@csn.ul.ie>
Signed-off-by: Michal Hocko <mhocko@suse.cz>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'mm/memory_hotplug.c')
-rw-r--r-- | mm/memory_hotplug.c | 8 |
1 files changed, 6 insertions, 2 deletions
diff --git a/mm/memory_hotplug.c b/mm/memory_hotplug.c index 0095d156324a..ec2f199cc5f7 100644 --- a/mm/memory_hotplug.c +++ b/mm/memory_hotplug.c | |||
@@ -498,12 +498,16 @@ int __ref online_pages(unsigned long pfn, unsigned long nr_pages) | |||
498 | * So, zonelist must be updated after online. | 498 | * So, zonelist must be updated after online. |
499 | */ | 499 | */ |
500 | mutex_lock(&zonelists_mutex); | 500 | mutex_lock(&zonelists_mutex); |
501 | if (!populated_zone(zone)) | 501 | if (!populated_zone(zone)) { |
502 | need_zonelists_rebuild = 1; | 502 | need_zonelists_rebuild = 1; |
503 | build_all_zonelists(NULL, zone); | ||
504 | } | ||
503 | 505 | ||
504 | ret = walk_system_ram_range(pfn, nr_pages, &onlined_pages, | 506 | ret = walk_system_ram_range(pfn, nr_pages, &onlined_pages, |
505 | online_pages_range); | 507 | online_pages_range); |
506 | if (ret) { | 508 | if (ret) { |
509 | if (need_zonelists_rebuild) | ||
510 | zone_pcp_reset(zone); | ||
507 | mutex_unlock(&zonelists_mutex); | 511 | mutex_unlock(&zonelists_mutex); |
508 | printk(KERN_DEBUG "online_pages [mem %#010llx-%#010llx] failed\n", | 512 | printk(KERN_DEBUG "online_pages [mem %#010llx-%#010llx] failed\n", |
509 | (unsigned long long) pfn << PAGE_SHIFT, | 513 | (unsigned long long) pfn << PAGE_SHIFT, |
@@ -519,7 +523,7 @@ int __ref online_pages(unsigned long pfn, unsigned long nr_pages) | |||
519 | if (onlined_pages) { | 523 | if (onlined_pages) { |
520 | node_set_state(zone_to_nid(zone), N_HIGH_MEMORY); | 524 | node_set_state(zone_to_nid(zone), N_HIGH_MEMORY); |
521 | if (need_zonelists_rebuild) | 525 | if (need_zonelists_rebuild) |
522 | build_all_zonelists(NULL, zone); | 526 | build_all_zonelists(NULL, NULL); |
523 | else | 527 | else |
524 | zone_pcp_update(zone); | 528 | zone_pcp_update(zone); |
525 | } | 529 | } |