According to the comment of free_area_init(), its main goal is to initialise all pg_data_t and zone data. However, sparse_init() and memmap_init() are aimed at allocating vmemmap pages and initializing struct page respectively, which differs from the goal of free_area_init(). Therefore, it is reasonable to move them out of free_area_init().
Call sparse_init() after free_area_init() to guarantee that zone data structures are available when sparse_init() executes. This change is a prerequisite for integrating vmemmap initialization steps and allows sparse_init() to safely access zone information if needed (e.g. HVO case). Also, move hugetlb reservation functions (hugetlb_cma_reserve() and hugetlb_bootmem_alloc()) to be after free_area_init(). This allows hugetlb reservation to access zone information to ensure that contiguous pages are not allocated across zone boundaries, which simplifies the hugetlb code. So this is a preparation for subsequent changes. Signed-off-by: Muchun Song <[email protected]> --- mm/mm_init.c | 15 ++++++++------- mm/sparse.c | 3 --- 2 files changed, 8 insertions(+), 10 deletions(-) diff --git a/mm/mm_init.c b/mm/mm_init.c index 5ca4503e7622..72604d02a853 100644 --- a/mm/mm_init.c +++ b/mm/mm_init.c @@ -1807,7 +1807,6 @@ static void __init free_area_init(void) bool descending; arch_zone_limits_init(max_zone_pfn); - sparse_init(); start_pfn = PHYS_PFN(memblock_start_of_DRAM()); descending = arch_has_descending_max_zone_pfns(); @@ -1896,11 +1895,7 @@ static void __init free_area_init(void) } } - for_each_node_state(nid, N_MEMORY) - sparse_vmemmap_init_nid_late(nid); - calc_nr_kernel_pages(); - memmap_init(); /* disable hash distribution for systems with a single node */ fixup_hashdist(); @@ -2669,10 +2664,16 @@ void __init __weak mem_init(void) void __init mm_core_init_early(void) { - hugetlb_cma_reserve(); - hugetlb_bootmem_alloc(); + int nid; free_area_init(); + /* Zone data structures are available from here. */ + hugetlb_cma_reserve(); + hugetlb_bootmem_alloc(); + sparse_init(); + for_each_node_state(nid, N_MEMORY) + sparse_vmemmap_init_nid_late(nid); + memmap_init(); } /* diff --git a/mm/sparse.c b/mm/sparse.c index c7f91dc2e5b5..5fe0a7e66775 100644 --- a/mm/sparse.c +++ b/mm/sparse.c @@ -406,9 +406,6 @@ void __init sparse_init(void) pnum_begin = first_present_section_nr(); nid_begin = sparse_early_nid(__nr_to_section(pnum_begin)); - /* Setup pageblock_order for HUGETLB_PAGE_SIZE_VARIABLE */ - set_pageblock_order(); - for_each_present_section_nr(pnum_begin + 1, pnum_end) { int nid = sparse_early_nid(__nr_to_section(pnum_end)); -- 2.20.1
