Re: [PATCH 04/17] mm/mm_init: skip initializing shared vmemmap tail pages

From: Mike Rapoport

Date: Thu Jul 09 2026 - 06:50:45 EST


Hi Muchun,

Below are some preliminary comments, I'm planning to spend more time on
review next week.

On Thu, Jul 02, 2026 at 05:38:08PM +0800, Muchun Song wrote:
> memmap_init_range() initializes every struct page in the target range.
> For compound pages with vmemmap optimization, the tail struct pages are
> backed by a shared vmemmap page.
>
> Initializing those tail struct pages would overwrite the shared
> vmemmap page contents, so users such as HugeTLB have to open-code
> follow-up handling to restore the metadata afterwards.
>
> Use the section's compound page order to detect struct pages that fall
> into the shared tail vmemmap range and skip their initialization in
> memmap_init_range(). Still initialize the pageblock migratetypes for
> the skipped range so the surrounding setup remains intact.
>
> This is a preparatory change for consolidating handling across users of
> vmemmap optimization, and it also avoids redundant initialization of
> shared tail vmemmap pages during early boot.
>
> Signed-off-by: Muchun Song <songmuchun@xxxxxxxxxxxxx>
> ---
> include/linux/mmzone.h | 4 ++++
> mm/internal.h | 16 ++++++++++++++++
> mm/mm_init.c | 25 +++++++++++++++++++------
> 3 files changed, 39 insertions(+), 6 deletions(-)
>
> @@ -673,19 +673,21 @@ static inline void fixup_hashdist(void)
> static inline void fixup_hashdist(void) {}
> #endif /* CONFIG_NUMA */
>
> -#if defined(CONFIG_ZONE_DEVICE) || defined(CONFIG_DEFERRED_STRUCT_PAGE_INIT)
> static __meminit void pageblock_migratetype_init_range(unsigned long pfn,
> - unsigned long nr_pages, int migratetype, bool atomic)
> + unsigned long nr_pages, int migratetype, bool isolate, bool atomic)

What is isolate parameter for?

> {
> const unsigned long end = pfn + nr_pages;
>
> for (pfn = pageblock_align(pfn); pfn < end; pfn += pageblock_nr_pages) {
> - init_pageblock_migratetype(pfn_to_page(pfn), migratetype, false);
> + init_pageblock_migratetype(pfn_to_page(pfn), migratetype, isolate);
> +#ifdef CONFIG_SPARSEMEM
> if (!atomic && IS_ALIGNED(pfn, PAGES_PER_SECTION))
> +#else
> + if (!atomic && IS_ALIGNED(pfn, MAX_FOLIO_NR_PAGES))
> +#endif

Let's trigger cond_resched() on some defined number of iterations or some
memory size chunk, e.g PAGES_PER_128M or even PAGES_PER_1G.

> cond_resched();
> }
> }

--
Sincerely yours,
Mike.