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


Reply via email to