aboutsummaryrefslogtreecommitdiffstats
path: root/mm/page_alloc.c
diff options
context:
space:
mode:
Diffstat (limited to 'mm/page_alloc.c')
-rw-r--r--mm/page_alloc.c71
1 files changed, 33 insertions, 38 deletions
diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index db1ff4ac0cc6..c26d3152f9ba 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -5450,6 +5450,30 @@ void __ref build_all_zonelists(pg_data_t *pgdat)
5450#endif 5450#endif
5451} 5451}
5452 5452
5453/* If zone is ZONE_MOVABLE but memory is mirrored, it is an overlapped init */
5454static bool __meminit
5455overlap_memmap_init(unsigned long zone, unsigned long *pfn)
5456{
5457#ifdef CONFIG_HAVE_MEMBLOCK_NODE_MAP
5458 static struct memblock_region *r;
5459
5460 if (mirrored_kernelcore && zone == ZONE_MOVABLE) {
5461 if (!r || *pfn >= memblock_region_memory_end_pfn(r)) {
5462 for_each_memblock(memory, r) {
5463 if (*pfn < memblock_region_memory_end_pfn(r))
5464 break;
5465 }
5466 }
5467 if (*pfn >= memblock_region_memory_base_pfn(r) &&
5468 memblock_is_mirror(r)) {
5469 *pfn = memblock_region_memory_end_pfn(r);
5470 return true;
5471 }
5472 }
5473#endif
5474 return false;
5475}
5476
5453/* 5477/*
5454 * Initially all pages are reserved - free ones are freed 5478 * Initially all pages are reserved - free ones are freed
5455 * up by free_all_bootmem() once the early boot process is 5479 * up by free_all_bootmem() once the early boot process is
@@ -5459,12 +5483,8 @@ void __meminit memmap_init_zone(unsigned long size, int nid, unsigned long zone,
5459 unsigned long start_pfn, enum memmap_context context, 5483 unsigned long start_pfn, enum memmap_context context,
5460 struct vmem_altmap *altmap) 5484 struct vmem_altmap *altmap)
5461{ 5485{
5462 unsigned long end_pfn = start_pfn + size; 5486 unsigned long pfn, end_pfn = start_pfn + size;
5463 unsigned long pfn;
5464 struct page *page; 5487 struct page *page;
5465#ifdef CONFIG_HAVE_MEMBLOCK_NODE_MAP
5466 struct memblock_region *r = NULL, *tmp;
5467#endif
5468 5488
5469 if (highest_memmap_pfn < end_pfn - 1) 5489 if (highest_memmap_pfn < end_pfn - 1)
5470 highest_memmap_pfn = end_pfn - 1; 5490 highest_memmap_pfn = end_pfn - 1;
@@ -5492,39 +5512,17 @@ void __meminit memmap_init_zone(unsigned long size, int nid, unsigned long zone,
5492 * There can be holes in boot-time mem_map[]s handed to this 5512 * There can be holes in boot-time mem_map[]s handed to this
5493 * function. They do not exist on hotplugged memory. 5513 * function. They do not exist on hotplugged memory.
5494 */ 5514 */
5495 if (context != MEMMAP_EARLY) 5515 if (context == MEMMAP_EARLY) {
5496 goto not_early; 5516 if (!early_pfn_valid(pfn))
5497
5498 if (!early_pfn_valid(pfn))
5499 continue;
5500 if (!early_pfn_in_nid(pfn, nid))
5501 continue;
5502
5503#ifdef CONFIG_HAVE_MEMBLOCK_NODE_MAP
5504 /*
5505 * Check given memblock attribute by firmware which can affect
5506 * kernel memory layout. If zone==ZONE_MOVABLE but memory is
5507 * mirrored, it's an overlapped memmap init. skip it.
5508 */
5509 if (mirrored_kernelcore && zone == ZONE_MOVABLE) {
5510 if (!r || pfn >= memblock_region_memory_end_pfn(r)) {
5511 for_each_memblock(memory, tmp)
5512 if (pfn < memblock_region_memory_end_pfn(tmp))
5513 break;
5514 r = tmp;
5515 }
5516 if (pfn >= memblock_region_memory_base_pfn(r) &&
5517 memblock_is_mirror(r)) {
5518 /* already initialized as NORMAL */
5519 pfn = memblock_region_memory_end_pfn(r);
5520 continue; 5517 continue;
5521 } 5518 if (!early_pfn_in_nid(pfn, nid))
5519 continue;
5520 if (overlap_memmap_init(zone, &pfn))
5521 continue;
5522 if (defer_init(nid, pfn, end_pfn))
5523 break;
5522 } 5524 }
5523#endif
5524 if (defer_init(nid, pfn, end_pfn))
5525 break;
5526 5525
5527not_early:
5528 page = pfn_to_page(pfn); 5526 page = pfn_to_page(pfn);
5529 __init_single_page(page, pfn, zone, nid); 5527 __init_single_page(page, pfn, zone, nid);
5530 if (context == MEMMAP_HOTPLUG) 5528 if (context == MEMMAP_HOTPLUG)
@@ -5541,9 +5539,6 @@ not_early:
5541 * can be created for invalid pages (for alignment) 5539 * can be created for invalid pages (for alignment)
5542 * check here not to call set_pageblock_migratetype() against 5540 * check here not to call set_pageblock_migratetype() against
5543 * pfn out of zone. 5541 * pfn out of zone.
5544 *
5545 * Please note that MEMMAP_HOTPLUG path doesn't clear memmap
5546 * because this is done early in sparse_add_one_section
5547 */ 5542 */
5548 if (!(pfn & (pageblock_nr_pages - 1))) { 5543 if (!(pfn & (pageblock_nr_pages - 1))) {
5549 set_pageblock_migratetype(page, MIGRATE_MOVABLE); 5544 set_pageblock_migratetype(page, MIGRATE_MOVABLE);