From: sashiko-bot@kernel.org
To: "Joanne Koong" <joannelkoong@gmail.com>,
akpm@linux-foundation.org, david@kernel.org, ljs@kernel.org
Cc: baohua@kernel.org, usama.arif@linux.dev, hannes@cmpxchg.org,
kas@kernel.org, alex@ghiti.fr, ziy@nvidia.com,
baolin.wang@linux.alibaba.com, liam@infradead.org,
npache@redhat.com, ryan.roberts@arm.com, dev.jain@arm.com,
lance.yang@linux.dev, vbabka@kernel.org, rppt@kernel.org,
surenb@google.com, mhocko@suse.com, willy@infradead.org,
linux-mm@kvack.org
Subject: Re: [PATCH v4 4/4] mm: add anonymous mTHP folios to the deferred split list
Date: Wed, 04 Nov 2026 21:21:03 +0000 [thread overview]
Message-ID: <sashiko-outbox-198104@kernel.org> (raw)
In-Reply-To: <20261103212004.1356327-5-joannelkoong@gmail.com>
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [High] mm: try_to_migrate_one() triggers deferred_split_folio() on underused mTHP
--
commit 82b7b7063b986d802fe52e75e17211e58f3f420c
Author: Joanne Koong <joannelkoong@gmail.com>
mm: add anonymous mTHP folios to the deferred split list
This commit queues newly mapped anonymous mTHP folios of at least 2M onto the
deferred split list in map_anon_folio_pte_nopf() so that underused mTHP folios
can be split by the deferred split shrinker under memory pressure.
> diff --git a/mm/memory.c b/mm/memory.c
> index 0c9ed04528d88..44376321180b5 100644
> --- a/mm/memory.c
> +++ b/mm/memory.c
> @@ -5477,6 +5477,8 @@ void map_anon_folio_pte_nopf(struct folio *folio, pte_t *pte,
> folio_add_lru_vma(folio, vma);
> set_ptes(vma->vm_mm, addr, pte, entry, nr_pages);
> update_mmu_cache_range(NULL, vma, addr, pte, nr_pages);
> + if (folio_test_large(folio))
> + deferred_split_folio(folio, false);
> }
[Severity: High]
When deferred_split_scan() splits an underused PTE-mapped mTHP folio queued
here with PG_partially_mapped left clear, doesn't unmap_folio() trigger a
false-positive deferred_split_folio(folio, true) transition during the split?
In deferred_split_scan(), the folio is first removed from the local dispose
list while PG_partially_mapped is still false:
mm/huge_memory.c:deferred_split_scan()
list_del_init(&folio->_deferred_list);
if (!folio_test_partially_mapped(folio)) {
if (folio_test_mlocked(folio))
goto next;
underused = thp_underused(folio);
if (!underused)
goto next;
}
if (!folio_trylock(folio))
goto requeue;
if (!split_folio(folio)) {
split_folio() then calls __folio_split() -> __folio_freeze_split_anon(), which
unmaps the folio before freezing its refcount:
mm/huge_memory.c:__folio_freeze_split_anon()
if (folio_mapped(folio)) {
anon_vma = folio_get_anon_vma(folio);
if (!anon_vma)
return -EBUSY;
anon_vma_lock_write(anon_vma);
ret = unmap_folio(folio);
if (ret)
goto out_unlock;
}
local_irq_disable();
if (!folio_ref_freeze(folio, folio_swapcache_ref_count(folio) + 1)) {
ret = -EAGAIN;
goto out_no_split;
}
Unlike a PMD-mapped THP (where split_huge_pmd_locked() with freeze=true
removes the entire PMD rmap in one folio_remove_rmap_pmd() call), an mTHP
folio is PTE-mapped, so unmap_folio() -> try_to_migrate() ->
try_to_migrate_one() removes its PTEs one subpage at a time via
folio_remove_rmap_pte().
On the first subpage unmapped while the remaining subpages are still mapped,
__folio_remove_rmap() sees partially_mapped == true and
!folio_test_partially_mapped(folio) == true:
mm/rmap.c:__folio_remove_rmap()
if (partially_mapped && folio_test_anon(folio) &&
!folio_test_partially_mapped(folio) &&
!folio_is_device_private(folio))
deferred_split_folio(folio, true);
Because folio->_deferred_list was emptied by list_del_init() in
deferred_split_scan() and the folio refcount is not frozen yet,
deferred_split_folio(folio, true) sets PG_partially_mapped, increments
MTHP_STAT_SPLIT_DEFERRED and MTHP_STAT_NR_ANON_PARTIALLY_MAPPED, and re-adds
folio->_deferred_list onto deferred_split_lru.
Could this cause three problems?
1. Even when folio_ref_freeze() succeeds and __folio_freeze_split_anon()
subsequently unqueues the folio and resets PG_partially_mapped, every
underused mTHP split will also increment MTHP_STAT_SPLIT_DEFERRED in
addition to MTHP_STAT_SPLIT_UNDERUSED.
2. If folio_ref_freeze() fails (for example due to a concurrent GUP pin, or
because a second CPU running deferred_split_scan() isolated the re-queued
folio via folio_try_get() while the remaining PTEs were still being
unmapped), __folio_freeze_split_anon() jumps to out_no_split and remaps all
PTEs via remap_anon_folio() without unqueueing the folio or clearing
PG_partially_mapped. That leaves a fully mapped folio permanently marked
PG_partially_mapped with MTHP_STAT_NR_ANON_PARTIALLY_MAPPED leaked.
3. If a second CPU running deferred_split_scan() isolates the re-queued folio
onto its local dispose list while unmap_folio() is still in progress, that
extra refcount causes folio_ref_freeze() on the first CPU to fail. When the
first CPU returns to deferred_split_scan(), it sees !did_split &&
folio_test_partially_mapped(folio) == true and calls list_lru_add_irq() on
folio->_deferred_list while the folio is on the second CPU's unlocked
dispose list, corrupting the list.
--
Sashiko AI review · https://sashiko.dev/#/patchset/20261103212004.1356327-1-joannelkoong@gmail.com?part=4
next prev parent reply other threads:[~2026-11-04 21:21 UTC|newest]
Thread overview: 22+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-11-03 21:20 [PATCH v4 0/4] mm: split underused anonymous mTHP folios Joanne Koong
2026-11-03 21:20 ` [PATCH v4 1/4] mm/huge_memory: scale thp_underused() to the folio size Joanne Koong
2026-11-05 12:20 ` Kiryl Shutsemau
2026-11-10 3:54 ` Zi Yan
2026-11-12 23:50 ` Joanne Koong
2026-11-10 8:00 ` Baolin Wang
2026-11-03 21:20 ` [PATCH v4 2/4] mm/huge_memory: don't queue folios when underused splitting is inactive Joanne Koong
2026-11-03 22:15 ` Usama Arif
2026-11-05 12:23 ` Kiryl Shutsemau
2026-11-10 8:13 ` Baolin Wang
2026-11-03 21:20 ` [PATCH v4 3/4] mm/huge_memory: add a per-order counter for underused splits Joanne Koong
2026-11-03 22:20 ` Usama Arif
2026-11-05 12:26 ` Kiryl Shutsemau
2026-11-06 0:06 ` Joanne Koong
2026-11-10 8:10 ` Baolin Wang
2026-11-03 21:20 ` [PATCH v4 4/4] mm: add anonymous mTHP folios to the deferred split list Joanne Koong
2026-11-03 22:20 ` Barry Song
2026-11-04 21:21 ` sashiko-bot [this message]
2026-11-04 23:50 ` Joanne Koong
2026-11-05 12:37 ` Kiryl Shutsemau
2026-11-06 0:05 ` Joanne Koong
2026-11-09 22:29 ` Joanne Koong
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=sashiko-outbox-198104@kernel.org \
--to=sashiko-bot@kernel.org \
--cc=akpm@linux-foundation.org \
--cc=alex@ghiti.fr \
--cc=baohua@kernel.org \
--cc=baolin.wang@linux.alibaba.com \
--cc=david@kernel.org \
--cc=dev.jain@arm.com \
--cc=hannes@cmpxchg.org \
--cc=joannelkoong@gmail.com \
--cc=kas@kernel.org \
--cc=lance.yang@linux.dev \
--cc=liam@infradead.org \
--cc=linux-mm@kvack.org \
--cc=ljs@kernel.org \
--cc=mhocko@suse.com \
--cc=npache@redhat.com \
--cc=rppt@kernel.org \
--cc=ryan.roberts@arm.com \
--cc=sashiko-reviews@lists.linux.dev \
--cc=surenb@google.com \
--cc=usama.arif@linux.dev \
--cc=vbabka@kernel.org \
--cc=willy@infradead.org \
--cc=ziy@nvidia.com \
/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.