From: Muchun Song <muchun.song@linux.dev>
To: Mike Rapoport <rppt@kernel.org>
Cc: Andrew Morton <akpm@linux-foundation.org>,
Oscar Salvador <osalvador@suse.de>,
David Hildenbrand <david@kernel.org>,
Vlastimil Babka <vbabka@kernel.org>,
Lorenzo Stoakes <ljs@kernel.org>, Michal Hocko <mhocko@suse.com>,
David Laight <david.laight.linux@gmail.com>,
"Liam R . Howlett" <liam@infradead.org>,
Suren Baghdasaryan <surenb@google.com>,
linux-mm@kvack.org, linux-kernel@vger.kernel.org,
Muchun Song <songmuchun@bytedance.com>
Subject: Re: [PATCH v4 08/17] mm/sparse-vmemmap: support section-based vmemmap optimization
Date: Mon, 24 Aug 2026 19:09:45 +0800 [thread overview]
Message-ID: <cde94ead-445e-45bd-88b0-ac64b3ed6ace@linux.dev> (raw)
In-Reply-To: <178756196750.3606540.8562704442052486227.b4-review@b4>
On 2026/8/24 16:59, Mike Rapoport wrote:
>> Teach sparse-vmemmap population code to use the compound page order
>> when deciding whether a vmemmap page can be optimized.
>>
>> With this information, the common sparse-vmemmap population path can
>> allocate or reuse shared tail vmemmap pages directly instead of relying
>> on HugeTLB-specific handling.
>>
>> This centralizes vmemmap optimization logic in the sparse-vmemmap code,
>> based on section metadata, and prepares for sharing the same mechanism
>> across different users of vmemmap optimization, including HugeTLB and
>> DAX.
>>
>> Signed-off-by: Muchun Song <songmuchun@bytedance.com>
>>
>> diff --git a/mm/sparse-vmemmap.c b/mm/sparse-vmemmap.c
>> index b770fe2428fd..737d50bdd3ef 100644
>> --- a/mm/sparse-vmemmap.c
>> +++ b/mm/sparse-vmemmap.c
>> @@ -186,6 +186,11 @@ static __meminit struct page *vmemmap_get_tail(unsigned int order, struct zone *
>>
>> return tail;
>> }
>> +#else
>> +static inline struct page *vmemmap_get_tail(unsigned int order, struct zone *zone)
>> +{
>> + return NULL;
>> +}
>> #endif
>>
>> static pte_t * __meminit vmemmap_pte_populate(pmd_t *pmd, unsigned long addr, int node,
>> @@ -193,12 +198,24 @@ static pte_t * __meminit vmemmap_pte_populate(pmd_t *pmd, unsigned long addr, in
>> unsigned long ptpfn, unsigned long flags)
>> {
>> pte_t *pte = pte_offset_kernel(pmd, addr);
>> + unsigned long pfn = page_to_pfn((struct page *)addr);
>> +
>> if (pte_none(ptep_get(pte))) {
>> pte_t entry;
>> - void *p;
>> +
>> + if (vmemmap_optimizable_pfn(pfn) && ptpfn == (unsigned long)-1) {
>> + unsigned int order = pfn_to_section_order(pfn);
>> + struct zone *zone = pfn_to_zone(pfn, node);
>> + struct page *page = vmemmap_get_tail(order, zone);
>> +
>> + if (!page)
>> + return NULL;
>> + ptpfn = page_to_pfn(page);
>> + }
>>
>> if (ptpfn == (unsigned long)-1) {
>> - p = vmemmap_alloc_block_buf(PAGE_SIZE, node, altmap);
>> + void *p = vmemmap_alloc_block_buf(PAGE_SIZE, node, altmap);
>> +
> What do you think about adding a helper function here, e.g something
> like
Better than mine. More clear.
>
> diff --git a/mm/sparse-vmemmap.c b/mm/sparse-vmemmap.c
> index 0aa0ab4f8b11..933b122f9937 100644
> --- a/mm/sparse-vmemmap.c
> +++ b/mm/sparse-vmemmap.c
> @@ -191,6 +191,23 @@ static inline struct page *vmemmap_get_tail(unsigned int order, struct zone *zon
> }
> #endif
>
> +static void * __meminit vmemmap_alloc_pte(unsigned long pfn, int node,
> + struct vmem_altmap *altmap)
> +{
> + unsigned int order = pfn_to_section_order(pfn);
> + struct zone *zone = pfn_to_zone(pfn, node);
> + struct page *page;
> +
> + if (!vmemmap_optimizable_pfn(pfn))
> + return vmemmap_alloc_block_buf(PAGE_SIZE, node, altmap);
> +
> + page = vmemmap_get_tail(order, zone);
> + if (!page)
> + return NULL;
> +
> + return page_address(page);
> +}
> +
> static pte_t * __meminit vmemmap_pte_populate(pmd_t *pmd, unsigned long addr, int node,
> struct vmem_altmap *altmap,
> unsigned long ptpfn, unsigned long flags)
> @@ -201,19 +218,8 @@ static pte_t * __meminit vmemmap_pte_populate(pmd_t *pmd, unsigned long addr, in
> if (pte_none(ptep_get(pte))) {
> pte_t entry;
>
> - if (vmemmap_optimizable_pfn(pfn) && ptpfn == (unsigned long)-1) {
> - unsigned int order = pfn_to_section_order(pfn);
> - struct zone *zone = pfn_to_zone(pfn, node);
> - struct page *page = vmemmap_get_tail(order, zone);
> -
> - if (!page)
> - return NULL;
> - ptpfn = page_to_pfn(page);
> - }
> -
> if (ptpfn == (unsigned long)-1) {
> - void *p = vmemmap_alloc_block_buf(PAGE_SIZE, node, altmap);
> -
> + void *p = vmemmap_alloc_pte(pfn, node, altmap);
> if (!p)
> return NULL;
> ptpfn = PHYS_PFN(__pa(p));
>
>> if (!p)
>> return NULL;
>> ptpfn = PHYS_PFN(__pa(p));
>> @@ -217,7 +234,8 @@ static pte_t * __meminit vmemmap_pte_populate(pmd_t *pmd, unsigned long addr, in
>> }
>> entry = pfn_pte(ptpfn, PAGE_KERNEL);
>> set_pte_at(&init_mm, addr, pte, entry);
>> - }
>> + } else if (WARN_ON_ONCE(vmemmap_optimizable_pfn(pfn)))
>> + return NULL;
>> return pte;
>> }
>>
>> @@ -406,6 +424,9 @@ int __meminit vmemmap_populate_hugepages(unsigned long start, unsigned long end,
>> pmd_t *pmd;
>>
>> for (addr = start; addr < end; addr = next) {
>> + unsigned long pfn = page_to_pfn((struct page *)addr);
>> + const struct mem_section *ms = __pfn_to_section(pfn);
>> +
>> next = pmd_addr_end(addr, end);
>>
>> pgd = vmemmap_pgd_populate(addr, node);
>> @@ -421,7 +442,7 @@ int __meminit vmemmap_populate_hugepages(unsigned long start, unsigned long end,
>> return -ENOMEM;
>>
>> pmd = pmd_offset(pud, addr);
>> - if (pmd_none(pmdp_get(pmd))) {
>> + if (pmd_none(pmdp_get(pmd)) && !section_vmemmap_optimizable(ms)) {
>> void *p;
>>
>> p = vmemmap_alloc_block_buf(PMD_SIZE, node, altmap);
>> @@ -439,8 +460,11 @@ int __meminit vmemmap_populate_hugepages(unsigned long start, unsigned long end,
>> */
>> return -ENOMEM;
>> }
>> - } else if (vmemmap_check_pmd(pmd, node, addr, next))
>> + } else if (vmemmap_check_pmd(pmd, node, addr, next)) {
>> + if (WARN_ON_ONCE(section_vmemmap_optimizable(ms)))
>> + return -EOPNOTSUPP;
>> continue;
>> + }
>> if (vmemmap_populate_basepages(addr, next, node, altmap))
>> return -ENOMEM;
>> }
>> @@ -620,6 +644,33 @@ void __init sparse_init_subsection_map(void)
>> sparse_init_subsection_map_range(start, end - start);
>> }
>>
>> +int __meminit section_nr_vmemmap_pages(unsigned long pfn, unsigned long nr_pages,
>> + struct vmem_altmap *altmap, struct dev_pagemap *pgmap)
>> +{
> Can we do all code movements in separate patches?
Yes.
> Maybe even move this to the previous patch and update the changelog to
> say "move code around in preparation ..."
Make sense. Will do next version.
Muchun,
Thanks.
next prev parent reply other threads:[~2026-08-24 11:10 UTC|newest]
Thread overview: 26+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-08-19 9:51 [PATCH v4 00/17] mm: Introduce section-based vmemmap optimization for HugeTLB Muchun Song
2026-08-19 9:51 ` [PATCH v4 01/17] mm/sparse: relax struct mem_section size constraints Muchun Song
2026-08-19 9:51 ` [PATCH v4 02/17] mm/sparse-vmemmap: rename HVO order macros Muchun Song
2026-08-19 9:51 ` [PATCH v4 03/17] mm/mm_init: skip initializing shared vmemmap tail pages Muchun Song
2026-08-24 8:59 ` Mike Rapoport
2026-08-24 11:18 ` Muchun Song
2026-08-19 9:51 ` [PATCH v4 04/17] mm/sparse-vmemmap: initialize shared tail vmemmap pages on allocation Muchun Song
2026-08-19 9:51 ` [PATCH v4 05/17] mm/sparse-vmemmap: support section-based vmemmap accounting Muchun Song
2026-08-24 8:59 ` Mike Rapoport
2026-08-19 9:51 ` [PATCH v4 06/17] mm/mm_init: factor out pfn_to_zone() Muchun Song
2026-08-19 9:51 ` [PATCH v4 07/17] mm/sparse-vmemmap: move vmemmap_get_tail() before PTE population Muchun Song
2026-08-24 8:59 ` Mike Rapoport
2026-08-19 9:51 ` [PATCH v4 08/17] mm/sparse-vmemmap: support section-based vmemmap optimization Muchun Song
2026-08-24 8:59 ` Mike Rapoport
2026-08-24 11:09 ` Muchun Song [this message]
2026-08-19 9:51 ` [PATCH v4 09/17] mm/sparse: initialize memory sections earlier Muchun Song
2026-08-24 8:59 ` Mike Rapoport
2026-08-19 9:51 ` [PATCH v4 10/17] mm/hugetlb: switch HugeTLB to section-based vmemmap optimization Muchun Song
2026-08-19 9:51 ` [PATCH v4 11/17] mm/sparse-vmemmap: remove SPARSEMEM_VMEMMAP_PREINIT support Muchun Song
2026-08-19 9:51 ` [PATCH v4 12/17] mm/sparse: inline usemap allocation into sparse_init_nid() Muchun Song
2026-08-19 9:51 ` [PATCH v4 13/17] mm/sparse: remove section_map_size() Muchun Song
2026-08-19 9:51 ` [PATCH v4 14/17] mm/hugetlb: remove HUGE_BOOTMEM_HVO Muchun Song
2026-08-19 9:51 ` [PATCH v4 15/17] mm/hugetlb: remove HUGE_BOOTMEM_CMA Muchun Song
2026-08-19 9:51 ` [PATCH v4 16/17] mm/hugetlb: localize struct huge_bootmem_page Muchun Song
2026-08-19 9:51 ` [PATCH v4 17/17] mm/hugetlb: localize HUGE_BOOTMEM_ZONES_VALID Muchun Song
2026-08-19 11:30 ` [PATCH v4 00/17] mm: Introduce section-based vmemmap optimization for HugeTLB Muchun Song
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=cde94ead-445e-45bd-88b0-ac64b3ed6ace@linux.dev \
--to=muchun.song@linux.dev \
--cc=akpm@linux-foundation.org \
--cc=david.laight.linux@gmail.com \
--cc=david@kernel.org \
--cc=liam@infradead.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mm@kvack.org \
--cc=ljs@kernel.org \
--cc=mhocko@suse.com \
--cc=osalvador@suse.de \
--cc=rppt@kernel.org \
--cc=songmuchun@bytedance.com \
--cc=surenb@google.com \
--cc=vbabka@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.