Linux-mm Archive on lore.kernel.org
 help / color / mirror / Atom feed
From: Muchun Song <muchun.song@linux.dev>
To: sashiko-reviews@lists.linux.dev
Cc: Muchun Song <songmuchun@bytedance.com>,
	Andrew Morton <akpm@linux-foundation.org>,
	David Hildenbrand <david@kernel.org>,
	Oscar Salvador <osalvador@suse.de>,
	Mike Rapoport <rppt@kernel.org>, Lorenzo Stoakes <ljs@kernel.org>,
	"Liam R . Howlett" <liam@infradead.org>,
	Vlastimil Babka <vbabka@kernel.org>,
	Suren Baghdasaryan <surenb@google.com>,
	Michal Hocko <mhocko@suse.com>,
	James Houghton <jthoughton@google.com>,
	Lance Yang <lance.yang@linux.dev>, Qi Zheng <qi.zheng@linux.dev>,
	linux-mm@kvack.org
Subject: Re: [PATCH 05/11] mm/hugetlb: drop boot-time HVO handling for gigantic folios
Date: Tue, 10 Nov 2026 11:16:43 +0800	[thread overview]
Message-ID: <7EBF14BA-50E3-456C-A005-CE96CE148B5A@linux.dev> (raw)
In-Reply-To: <sashiko-outbox-204839@kernel.org>



> On Nov 9, 2026, at 18:43, sashiko-bot@kernel.org wrote:
> 
> Thank you for your contribution! Sashiko AI review found no new issues
> in this patch, but noticed 2 related pre-existing issues it does not
> introduce:
> - [High] mm/memory-failure: race between hugetlb_update_hwpoison() and
>  HVO head remap [1]
> - [Critical] mm/hugetlb_vmemmap: race between deferred PMD split flush
>  and PTE remap in vmemmap_split_pmd() [2]
> --

I will not fix both pre-existing problems in this series.

> 
> commit da0d2d6e0b849f9a259d74fcb047aaceb9617411
> Author: Muchun Song <muchun.song@linux.dev>
> 
> mm/hugetlb: drop boot-time HVO handling for gigantic folios
> 
> This commit removes the boot-time bulk vmemmap optimization call and tail
> page initialization fallback for gigantic folios, relying instead on the
> section-based vmemmap optimization infrastructure during bootmem gathering.
> 
>> diff --git a/mm/hugetlb_vmemmap.c b/mm/hugetlb_vmemmap.c
>> index ba8e11e399b24..d73ceeef392eb 100644
>> --- a/mm/hugetlb_vmemmap.c
>> +++ b/mm/hugetlb_vmemmap.c
>> @@ -552,7 +552,6 @@ static int hugetlb_vmemmap_pteify_folio(const struct hstate *h, struct folio *fo
>> void hugetlb_vmemmap_optimize_folios(struct hstate *h, struct list_head *folio_list)
>> {
>> 	struct folio *folio;
>> -	unsigned long nr_to_optimize = 0;
>> 	LIST_HEAD(vmemmap_pages);
>> 	unsigned long flags = VMEMMAP_DEFER_TLB_FLUSH;
> 
> [Severity: High]
> This problem wasn't introduced by this patch, but can a concurrent memory
> failure race with vmemmap optimization [1] and lose hardware poison
> state on a newly allocated hugetlb folio?
> 
> After init_new_hugetlb_folio() sets the hugetlb flag on a fresh folio
> (for example in prep_and_add_allocated_folios()), both
> folio_test_hugetlb_freed() and folio_test_hugetlb_migratable() remain
> false while hugetlb_vmemmap_optimize_folios() remaps its vmemmap pages:
> 
> CPU0                                  CPU1
> hugetlb_vmemmap_optimize_folios()
>  __hugetlb_vmemmap_optimize_folio()
>    vmemmap_optimize_folio()
>      vmemmap_optimize_pte()
>        vmemmap_dup_page_from_list()
>          copy_page(dst, src)
>                                      try_memory_failure_hugetlb()
>                                        get_huge_page_for_hwpoison()
>                                          // returns MF_HUGETLB_RETRY
>                                        // retries with MF_NO_RETRY:
>                                        get_huge_page_for_hwpoison()
>                                          spin_lock_irq(&hugetlb_lock)
>                                          hugetlb_update_hwpoison()
>                                            folio_test_set_hwpoison(folio)
>                                            llist_add(&raw_hwp->node, head)
>                                          spin_unlock_irq(&hugetlb_lock)
>        set_pte_at(..., dst, ...)
>  flush_tlb_all()
>  free_vmemmap_page_list()  <-- old head page freed, hwpoison lost
> 
> Because vmemmap_optimize_pte() copies and remaps the head struct page
> without synchronizing with hugetlb_lock (and defers the TLB flush across
> the batch), hugetlb_update_hwpoison() can write PG_hwpoison and the
> raw_hwp_page list entry to the old head struct page after copy_page() has
> already finished.  Once the remap and TLB flush complete, the raw_hwp_page
> allocation is leaked and the poisoned hugepage is added to the pool
> unmarked.
> 
>> @@ -560,18 +559,7 @@ void hugetlb_vmemmap_optimize_folios(struct hstate *h, struct list_head *folio_l
>> 		return;
>> 
>> 	list_for_each_entry(folio, folio_list, lru) {
>> -		int ret;
>> -
>> -		/*
>> -		 * Bootmem gigantic folios may already be marked optimized when
>> -		 * their vmemmap layout was prepared earlier, so skip them here.
>> -		 */
>> -		if (folio_test_hugetlb_vmemmap_optimized(folio))
>> -			continue;
>> -
>> -		nr_to_optimize++;
>> -
>> -		ret = hugetlb_vmemmap_pteify_folio(h, folio, flags);
>> +		int ret = hugetlb_vmemmap_pteify_folio(h, folio, flags);
>> 
>> 		/*
>> 		 * Splitting the PMD requires allocating a page, thus let's fail
>> @@ -583,9 +571,6 @@ void hugetlb_vmemmap_optimize_folios(struct hstate *h, struct list_head *folio_l
>> 			break;
>> 	}
>> 
>> -	if (!nr_to_optimize)
>> -		return;
>> -
>> 	flush_tlb_all();
> 
> [Severity: Critical]
> This problem wasn't introduced by this patch, but can deferring the TLB
> flush across PMD splits here race with a concurrent single-folio vmemmap
> optimization [2] and remap PTEs before the 2MB PMD split is
> flushed from the TLB?

Right. I'll fix it later in a separate patch.

> 
> A single 2MB vmemmap PMD covers 64 2MB folios.  While
> hugetlb_vmemmap_optimize_folios() splits PMDs with VMEMMAP_DEFER_TLB_FLUSH
> during bulk pool resize or demotion, a concurrent
> hugetlb_vmemmap_optimize_folio() (such as from
> alloc_surplus_hugetlb_folio()) can optimize another folio covered by the
> same vmemmap PMD:
> 
> CPU0                                  CPU1
> hugetlb_vmemmap_optimize_folios()
>  hugetlb_vmemmap_pteify_folio()
>    ...
>      vmemmap_split_pmd()
>        pmd_populate_kernel()
>        // skips TLB flush
>                                      hugetlb_vmemmap_optimize_folio()
>                                        ...
>                                          vmemmap_pmd_entry()
>                                            // !pmd_leaf(*pmd), returns 0
>                                          vmemmap_optimize_pte()
>                                            set_pte_at()
>                                        free_vmemmap_page_list()
>                                          <-- old vmemmap pages freed with
>                                              stale 2MB PMD TLB entry live
>  flush_tlb_all()
> 
> Because CPU0 has already replaced the leaf PMD under
> init_mm.page_table_lock, CPU1 sees !pmd_leaf(*pmd) in vmemmap_pmd_entry()
> and proceeds directly to vmemmap_optimize_pte() without a PMD-range TLB
> flush.  CPU1 then installs 4KB PTEs pointing to different physical pages,
> flushes only its own folio's vmemmap range, and frees the displaced
> vmemmap pages while stale 2MB PMD TLB entries remain active, which can
> cause overlapping-TLB machine checks or use-after-free writes to the freed
> vmemmap pages.
> 
> [1] https://sashiko.dev/#/bug/linux-18e93f17-529b-4d84-ba44-a41829f4be64
> [2] https://sashiko.dev/#/bug/linux-fbdc3410-a4cf-457e-88e6-684380fbadfe
> 
> -- 
> Sashiko AI review · https://sashiko.dev/#/patchset/20261109095807.41547-1-songmuchun@bytedance.com?part=5



  reply	other threads:[~2026-11-10  3:17 UTC|newest]

Thread overview: 21+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-11-09  9:57 [PATCH 00/11] mm: Unify memmap initialization for compound pages Muchun Song
2026-11-09  9:57 ` [PATCH 01/11] mm/mm_init: verify zones for template-initialized pages Muchun Song
2026-11-12 16:18   ` Mike Rapoport
2026-11-09  9:57 ` [PATCH 02/11] mm/mm_init: factor out common struct page initialization Muchun Song
2026-11-09 10:43   ` sashiko-bot
2026-11-10  3:08     ` Muchun Song
2026-11-09  9:57 ` [PATCH 03/11] mm/mm_init: simplify zone device " Muchun Song
2026-11-09  9:57 ` [PATCH 04/11] mm/mm_init: factor out frozen compound " Muchun Song
2026-11-09  9:58 ` [PATCH 05/11] mm/hugetlb: drop boot-time HVO handling for gigantic folios Muchun Song
2026-11-09 10:43   ` sashiko-bot
2026-11-10  3:16     ` Muchun Song [this message]
2026-11-09  9:58 ` [PATCH 06/11] mm/hugetlb: initialize all struct pages for bootmem hugepages Muchun Song
2026-11-09 10:43   ` sashiko-bot
2026-11-10  3:23     ` Muchun Song
2026-11-09  9:58 ` [PATCH 07/11] mm/hugetlb: use common compound page initialization helper Muchun Song
2026-11-09  9:58 ` [PATCH 08/11] mm/mm_init: make __init_single_page() static Muchun Song
2026-11-09  9:58 ` [PATCH 09/11] mm/cma: centralize CMA pageblock initialization Muchun Song
2026-11-09  9:58 ` [PATCH 10/11] mm/cma: localize init_cma_pageblock() to cma.c Muchun Song
2026-11-09  9:58 ` [PATCH 11/11] mm/mm_init: move pageblock migratetype init to memmap helpers Muchun Song
2026-11-09 10:43   ` sashiko-bot
2026-11-10  3:55     ` 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=7EBF14BA-50E3-456C-A005-CE96CE148B5A@linux.dev \
    --to=muchun.song@linux.dev \
    --cc=akpm@linux-foundation.org \
    --cc=david@kernel.org \
    --cc=jthoughton@google.com \
    --cc=lance.yang@linux.dev \
    --cc=liam@infradead.org \
    --cc=linux-mm@kvack.org \
    --cc=ljs@kernel.org \
    --cc=mhocko@suse.com \
    --cc=osalvador@suse.de \
    --cc=qi.zheng@linux.dev \
    --cc=rppt@kernel.org \
    --cc=sashiko-reviews@lists.linux.dev \
    --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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox