From d801e75f14ad5bc8dc4e43204bc0265c447719c2 Mon Sep 17 00:00:00 2001 From: "Isaac J. Manjarres" Date: Tue, 30 Mar 2021 00:01:36 -0700 Subject: [PATCH] mm, page_alloc: Initialize subsection maps for non-NUMA systems Subsection maps are only initialized for NUMA systems when they invoke free_areas_init(). Not initializing the subsection maps with memory that exists at boot can cause the memmap for a section to be freed when memory for a subsection within that section is hot-added and then hot-removed, which is not correct behavior, as pfn_valid() will always fail for any memory within the section, since it no longer has a memmap. Thus, initialize subsection maps for non-NUMA systems as well. Change-Id: I8a0633f9b8634d9df7bb88bfbb6f4c306a277e0c Signed-off-by: Isaac J. Manjarres --- mm/page_alloc.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/mm/page_alloc.c b/mm/page_alloc.c index be578d0d1b69..97e12b0980c9 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c @@ -7032,6 +7032,8 @@ void __init free_area_init_node(int nid, unsigned long *zones_size, pg_data_t *pgdat = NODE_DATA(nid); unsigned long start_pfn = 0; unsigned long end_pfn = 0; + u64 i; + phys_addr_t start, end; /* pg_data_t should be reset to zero when it's allocated */ WARN_ON(pgdat->nr_zones || pgdat->kswapd_classzone_idx); @@ -7045,6 +7047,10 @@ void __init free_area_init_node(int nid, unsigned long *zones_size, (u64)start_pfn << PAGE_SHIFT, end_pfn ? ((u64)end_pfn << PAGE_SHIFT) - 1 : 0); #else + for_each_mem_range(i, &memblock.memory, NULL, nid, MEMBLOCK_NONE, + &start, &end, NULL) + subsection_map_init((unsigned long)start >> PAGE_SHIFT, + (unsigned long)(end - start) >> PAGE_SHIFT); start_pfn = node_start_pfn; #endif calculate_node_totalpages(pgdat, start_pfn, end_pfn,