The shared tail vmemmap page allocated in vmemmap_get_tail() used to be
left uninitialized, because memmap_init_range() would later overwrite
it.  That forced users such as HugeTLB to defer the initialization to
their own setup paths.

Now that memmap_init_range() skips shared tail vmemmap pages, initialize
them immediately in vmemmap_get_tail() with init_compound_tail()
instead.

This moves the initialization to the point where the shared tail page is
allocated and avoids relying on deferred handling in individual users.
The remaining deferred initialization in HugeTLB will be removed once it
switches to the section compound page order mechanism.

Signed-off-by: Muchun Song <[email protected]>
---
 mm/sparse-vmemmap.c | 11 ++---------
 1 file changed, 2 insertions(+), 9 deletions(-)

diff --git a/mm/sparse-vmemmap.c b/mm/sparse-vmemmap.c
index 39529245d790..60d5330a8399 100644
--- a/mm/sparse-vmemmap.c
+++ b/mm/sparse-vmemmap.c
@@ -328,18 +328,11 @@ static __meminit struct page *vmemmap_get_tail(unsigned 
int order, struct zone *
        if (tail)
                return tail;
 
-       /*
-        * Only allocate the page, but do not initialize it.
-        *
-        * Any initialization done here will be overwritten by memmap_init().
-        *
-        * hugetlb_vmemmap_init() will take care of initialization after
-        * memmap_init().
-        */
-
        p = vmemmap_alloc_block_zero(PAGE_SIZE, node);
        if (!p)
                return NULL;
+       for (int i = 0; i < PAGE_SIZE / sizeof(struct page); i++)
+               init_compound_tail(p + i, NULL, order, zone);
 
        tail = virt_to_page(p);
        zone->vmemmap_tails[idx] = tail;
-- 
2.54.0


Reply via email to