aboutsummaryrefslogtreecommitdiffstats
path: root/mm/page_alloc.c
diff options
context:
space:
mode:
authorPavel Tatashin <pasha.tatashin@oracle.com>2018-10-26 18:09:40 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2018-10-26 19:38:10 -0400
commita9a9e77fbf2784ae2694696eb772419c0a96159e (patch)
treeb97a5fe8a29e6d5b32967ab13fe7ac96422c21f0 /mm/page_alloc.c
parentd3035be4ce2345d98633a45f93a74e526e94b802 (diff)
mm: move mirrored memory specific code outside of memmap_init_zone
memmap_init_zone, is getting complex, because it is called from different contexts: hotplug, and during boot, and also because it must handle some architecture quirks. One of them is mirrored memory. Move the code that decides whether to skip mirrored memory outside of memmap_init_zone, into a separate function. [pasha.tatashin@oracle.com: uninline overlap_memmap_init()] Link: http://lkml.kernel.org/r/20180726193509.3326-4-pasha.tatashin@oracle.com Link: http://lkml.kernel.org/r/20180724235520.10200-4-pasha.tatashin@oracle.com Signed-off-by: Pavel Tatashin <pasha.tatashin@oracle.com> Reviewed-by: Oscar Salvador <osalvador@suse.de> Cc: Pasha Tatashin <Pavel.Tatashin@microsoft.com> Cc: Abdul Haleem <abdhalee@linux.vnet.ibm.com> Cc: Baoquan He <bhe@redhat.com> Cc: Daniel Jordan <daniel.m.jordan@oracle.com> Cc: Dan Williams <dan.j.williams@intel.com> Cc: Dave Hansen <dave.hansen@intel.com> Cc: David Rientjes <rientjes@google.com> Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org> Cc: Ingo Molnar <mingo@kernel.org> Cc: Jan Kara <jack@suse.cz> Cc: Jérôme Glisse <jglisse@redhat.com> Cc: Kirill A. Shutemov <kirill.shutemov@linux.intel.com> Cc: Michael Ellerman <mpe@ellerman.id.au> Cc: Michal Hocko <mhocko@suse.com> Cc: Souptick Joarder <jrdr.linux@gmail.com> Cc: Steven Sistare <steven.sistare@oracle.com> Cc: Vlastimil Babka <vbabka@suse.cz> Cc: Wei Yang <richard.weiyang@gmail.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
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);