From: Lance Yang <lance.yang@linux.dev>
To: akpm@linux-foundation.org
Cc: david@kernel.org, ljs@kernel.org, ziy@nvidia.com,
baolin.wang@linux.alibaba.com, Liam.Howlett@oracle.com,
npache@redhat.com, ryan.roberts@arm.com, dev.jain@arm.com,
baohua@kernel.org, matthew.brost@intel.com,
joshua.hahnjy@gmail.com, rakie.kim@sk.com, byungchul@sk.com,
gourry@gourry.net, ying.huang@linux.alibaba.com,
apopple@nvidia.com, richard.weiyang@gmail.com,
usama.arif@linux.dev, linux-mm@kvack.org,
linux-kernel@vger.kernel.org, kartikey406@gmail.com,
syzbot+a7067a757858ac8eb085@syzkaller.appspotmail.com,
stable@vger.kernel.org, Lance Yang <lance.yang@linux.dev>
Subject: [PATCH mm-unstable 1/1] mm: fix deferred split queue races during migration
Date: Wed, 1 Apr 2026 21:10:32 +0800 [thread overview]
Message-ID: <20260401131032.13011-1-lance.yang@linux.dev> (raw)
From: Lance Yang <lance.yang@linux.dev>
migrate_folio_move() records the deferred split queue state from src and
replays it on dst. Replaying it after remove_migration_ptes(src, dst, 0)
makes dst visible before it is requeued, so a concurrent rmap-removal path
can mark dst partially mapped and trip the WARN in deferred_split_folio().
Move the requeue before remove_migration_ptes() so dst is back on the
deferred split queue before it becomes visible again.
Because migration still holds dst locked at that point, teach
deferred_split_scan() to requeue a folio when folio_trylock() fails.
Otherwise a fully mapped underused folio can be dequeued by the shrinker
and silently lost from split_queue.
Link: https://syzkaller.appspot.com/bug?extid=a7067a757858ac8eb085
Fixes: 8a8ca142a488 ("mm: migrate: requeue destination folio on deferred split queue")
Reported-by: syzbot+a7067a757858ac8eb085@syzkaller.appspotmail.com
Closes: https://lore.kernel.org/linux-mm/69ccb65b.050a0220.183828.003a.GAE@google.com/
Cc: <stable@vger.kernel.org>
Suggested-by: David Hildenbrand (Arm) <david@kernel.org>
Signed-off-by: Lance Yang <lance.yang@linux.dev>
---
[ Backport note ]
This patch is a follow-up fix for 8a8ca142a488 ("mm: migrate: requeue
destination folio on deferred split queue"), which is currently only in
mm-stable, and should be backported together with it.
Credit for this fix goes to David, thanks!
mm/huge_memory.c | 12 +++++++-----
mm/migrate.c | 18 +++++++++---------
2 files changed, 16 insertions(+), 14 deletions(-)
diff --git a/mm/huge_memory.c b/mm/huge_memory.c
index ff9a42abd1b6..ac6d823e351f 100644
--- a/mm/huge_memory.c
+++ b/mm/huge_memory.c
@@ -4558,7 +4558,7 @@ static unsigned long deferred_split_scan(struct shrinker *shrink,
goto next;
}
if (!folio_trylock(folio))
- goto next;
+ goto requeue;
if (!split_folio(folio)) {
did_split = true;
if (underused)
@@ -4569,11 +4569,13 @@ static unsigned long deferred_split_scan(struct shrinker *shrink,
next:
if (did_split || !folio_test_partially_mapped(folio))
continue;
+requeue:
/*
- * Only add back to the queue if folio is partially mapped.
- * If thp_underused returns false, or if split_folio fails
- * in the case it was underused, then consider it used and
- * don't add it back to split_queue.
+ * Add back partially mapped folios, or underused folios
+ * that we could not lock this round. If thp_underused()
+ * returns false, or if split_folio() succeeds, or if
+ * split_folio() fails in the case it was underused, then
+ * consider it used and don't add it back to split_queue.
*/
fqueue = folio_split_queue_lock_irqsave(folio, &flags);
if (list_empty(&folio->_deferred_list)) {
diff --git a/mm/migrate.c b/mm/migrate.c
index 05cb408846f2..8a64291ab5b4 100644
--- a/mm/migrate.c
+++ b/mm/migrate.c
@@ -1385,6 +1385,15 @@ static int migrate_folio_move(free_folio_t put_new_folio, unsigned long private,
if (rc)
goto out;
+ /*
+ * Requeue the destination folio on the deferred split queue if
+ * the source was on the queue. The source is unqueued in
+ * __folio_migrate_mapping(), so we recorded the state from
+ * before move_to_new_folio().
+ */
+ if (src_deferred_split)
+ deferred_split_folio(dst, src_partially_mapped);
+
/*
* When successful, push dst to LRU immediately: so that if it
* turns out to be an mlocked page, remove_migration_ptes() will
@@ -1401,15 +1410,6 @@ static int migrate_folio_move(free_folio_t put_new_folio, unsigned long private,
if (old_page_state & PAGE_WAS_MAPPED)
remove_migration_ptes(src, dst, 0);
- /*
- * Requeue the destination folio on the deferred split queue if
- * the source was on the queue. The source is unqueued in
- * __folio_migrate_mapping(), so we recorded the state from
- * before move_to_new_folio().
- */
- if (src_deferred_split)
- deferred_split_folio(dst, src_partially_mapped);
-
out_unlock_both:
folio_unlock(dst);
folio_set_owner_migrate_reason(dst, reason);
--
2.49.0
next reply other threads:[~2026-04-01 13:11 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-04-01 13:10 Lance Yang [this message]
2026-04-01 16:28 ` [PATCH mm-unstable 1/1] mm: fix deferred split queue races during migration Usama Arif
2026-04-01 18:50 ` David Hildenbrand (Arm)
2026-04-01 18:51 ` David Hildenbrand (Arm)
2026-04-01 19:21 ` Zi Yan
2026-04-01 22:55 ` Zi Yan
2026-04-01 23:19 ` Andrew Morton
2026-04-03 4:24 ` Lance Yang
2026-04-01 21:48 ` Andrew Morton
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=20260401131032.13011-1-lance.yang@linux.dev \
--to=lance.yang@linux.dev \
--cc=Liam.Howlett@oracle.com \
--cc=akpm@linux-foundation.org \
--cc=apopple@nvidia.com \
--cc=baohua@kernel.org \
--cc=baolin.wang@linux.alibaba.com \
--cc=byungchul@sk.com \
--cc=david@kernel.org \
--cc=dev.jain@arm.com \
--cc=gourry@gourry.net \
--cc=joshua.hahnjy@gmail.com \
--cc=kartikey406@gmail.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mm@kvack.org \
--cc=ljs@kernel.org \
--cc=matthew.brost@intel.com \
--cc=npache@redhat.com \
--cc=rakie.kim@sk.com \
--cc=richard.weiyang@gmail.com \
--cc=ryan.roberts@arm.com \
--cc=stable@vger.kernel.org \
--cc=syzbot+a7067a757858ac8eb085@syzkaller.appspotmail.com \
--cc=usama.arif@linux.dev \
--cc=ying.huang@linux.alibaba.com \
--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.