[syzbot] [mm?] WARNING in deferred_split_folio

3 views
Skip to first unread message

syzbot

unread,
2:08 AM (15 hours ago) 2:08 AM
to Liam.H...@oracle.com, ak...@linux-foundation.org, bao...@kernel.org, baoli...@linux.alibaba.com, da...@kernel.org, dev....@arm.com, lance...@linux.dev, linux-...@vger.kernel.org, linu...@kvack.org, l...@kernel.org, npa...@redhat.com, ryan.r...@arm.com, syzkall...@googlegroups.com, z...@nvidia.com
Hello,

syzbot found the following issue on:

HEAD commit: cf7c3c02fdd0 Add linux-next specific files for 20260330
git tree: linux-next
console output: https://syzkaller.appspot.com/x/log.txt?x=154ee46a580000
kernel config: https://syzkaller.appspot.com/x/.config?x=3944d875fa9bfb67
dashboard link: https://syzkaller.appspot.com/bug?extid=a7067a757858ac8eb085
compiler: Debian clang version 21.1.8 (++20251221033036+2078da43e25a-1~exp1~20251221153213.50), Debian LLD 21.1.8
syz repro: https://syzkaller.appspot.com/x/repro.syz?x=12c846ba580000

Downloadable assets:
disk image: https://storage.googleapis.com/syzbot-assets/053d3b49a360/disk-cf7c3c02.raw.xz
vmlinux: https://storage.googleapis.com/syzbot-assets/faabb37d41d0/vmlinux-cf7c3c02.xz
kernel image: https://storage.googleapis.com/syzbot-assets/8d47fe92aaa8/bzImage-cf7c3c02.xz

IMPORTANT: if you fix the issue, please add the following tag to the commit:
Reported-by: syzbot+a7067a...@syzkaller.appspotmail.com

free_pages_and_swap_cache+0x2b9/0x490 mm/swap_state.c:401
__tlb_batch_free_encoded_pages mm/mmu_gather.c:138 [inline]
tlb_batch_pages_flush mm/mmu_gather.c:151 [inline]
tlb_flush_mmu_free mm/mmu_gather.c:417 [inline]
tlb_flush_mmu+0x6d3/0xa30 mm/mmu_gather.c:424
tlb_finish_mmu+0xf9/0x230 mm/mmu_gather.c:549
exit_mmap+0x498/0x9e0 mm/mmap.c:1313
__mmput+0x118/0x430 kernel/fork.c:1177
exit_mm+0x18e/0x250 kernel/exit.c:581
do_exit+0x6a2/0x22c0 kernel/exit.c:962
do_group_exit+0x21b/0x2d0 kernel/exit.c:1116
__do_sys_exit_group kernel/exit.c:1127 [inline]
__se_sys_exit_group kernel/exit.c:1125 [inline]
__x64_sys_exit_group+0x3f/0x40 kernel/exit.c:1125
x64_sys_call+0x221a/0x2240 arch/x86/include/generated/asm/syscalls_64.h:232
do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline]
do_syscall_64+0x15f/0xf80 arch/x86/entry/syscall_64.c:94
entry_SYSCALL_64_after_hwframe+0x77/0x7f
------------[ cut here ]------------
1
WARNING: mm/huge_memory.c:4371 at deferred_split_folio+0x974/0xaa0 mm/huge_memory.c:4371, CPU#1: syz.3.1110/10500
Modules linked in:
CPU: 1 UID: 0 PID: 10500 Comm: syz.3.1110 Not tainted syzkaller #0 PREEMPT(full)
Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 02/12/2026
RIP: 0010:deferred_split_folio+0x974/0xaa0 mm/huge_memory.c:4371
Code: 31 48 8d 65 d8 5b 41 5c 41 5d 41 5e 41 5f 5d e9 c2 67 8d 09 cc e8 8c 73 93 ff 48 89 df 48 c7 c6 20 5b fc 8b e8 dd 2b f5 fe 90 <0f> 0b 90 e9 d4 fe ff ff e8 9f 7a 8a 09 e8 6a 73 93 ff 48 89 df 48
RSP: 0018:ffffc900047ef540 EFLAGS: 00010046
RAX: 1c05fb65cfaab100 RBX: ffffea0001840000 RCX: 0000000080000001
RDX: 0000000000000002 RSI: ffffffff8e4da1c7 RDI: ffff88807d6f9e80
RBP: ffffc900047ef610 R08: ffff8880b87247d3 R09: 1ffff110170e48fa
R10: dffffc0000000000 R11: ffffed10170e48fb R12: ffffea0001840040
R13: 0000000000000000 R14: 0000000000010000 R15: 1ffff920008fdeb0
FS: 00007f32e32a76c0(0000) GS:ffff8881250e8000(0000) knlGS:0000000000000000
CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 00007f5825757930 CR3: 0000000034ad8000 CR4: 00000000003526f0
Call Trace:
<TASK>
migrate_folio_move mm/migrate.c:1411 [inline]
migrate_folios_move mm/migrate.c:1740 [inline]
migrate_pages_batch+0x319f/0x4c40 mm/migrate.c:1996
migrate_pages_sync mm/migrate.c:2026 [inline]
migrate_pages+0x1c74/0x2a10 mm/migrate.c:2135
do_mbind mm/mempolicy.c:1614 [inline]
kernel_mbind mm/mempolicy.c:1757 [inline]
__do_sys_mbind mm/mempolicy.c:1831 [inline]
__se_sys_mbind+0xe89/0x10f0 mm/mempolicy.c:1827
do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline]
do_syscall_64+0x15f/0xf80 arch/x86/entry/syscall_64.c:94
entry_SYSCALL_64_after_hwframe+0x77/0x7f
RIP: 0033:0x7f32e239c819
Code: ff c3 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 44 00 00 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 c7 c1 e8 ff ff ff f7 d8 64 89 01 48
RSP: 002b:00007f32e32a7028 EFLAGS: 00000246 ORIG_RAX: 00000000000000ed
RAX: ffffffffffffffda RBX: 00007f32e2616090 RCX: 00007f32e239c819
RDX: 0000000000000000 RSI: 0000000000800000 RDI: 0000200000001000
RBP: 00007f32e2432c91 R08: 0000000000000000 R09: 0000000000000002
R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000000000
R13: 00007f32e2616128 R14: 00007f32e2616090 R15: 00007ffe30c61cc8
</TASK>


---
This report is generated by a bot. It may contain errors.
See https://goo.gl/tpsmEJ for more information about syzbot.
syzbot engineers can be reached at syzk...@googlegroups.com.

syzbot will keep track of this issue. See:
https://goo.gl/tpsmEJ#status for how to communicate with syzbot.

If the report is already addressed, let syzbot know by replying with:
#syz fix: exact-commit-title

If you want syzbot to run the reproducer, reply with:
#syz test: git://repo/address.git branch-or-commit-hash
If you attach or paste a git patch, syzbot will apply it before testing.

If you want to overwrite report's subsystems, reply with:
#syz set subsystems: new-subsystem
(See the list of subsystem names on the web dashboard)

If the report is a duplicate of another one, reply with:
#syz dup: exact-subject-of-another-report

If you want to undo deduplication, reply with:
#syz undup

syzbot

unread,
3:52 AM (14 hours ago) 3:52 AM
to linux-...@vger.kernel.org, syzkall...@googlegroups.com
For archival purposes, forwarding an incoming command email to
linux-...@vger.kernel.org, syzkall...@googlegroups.com.

***

Subject: [PATCH] mm/migrate: fix stale partially_mapped arg to deferred_split_folio()
Author: karti...@gmail.com

#syz test: git://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git master


In migrate_folio_move(), src_partially_mapped is sampled from the source
folio before move_to_new_folio() is called:

if (folio_order(src) > 1 &&
!data_race(list_empty(&src->_deferred_list))) {
src_deferred_split = true;
src_partially_mapped = folio_test_partially_mapped(src);
}

A concurrent thread can unmap pages from the source folio between this
read and the actual migration, making the sampled value stale.

After move_to_new_folio() succeeds, __folio_migrate_mapping() has already
copied all folio flags including PG_partially_mapped from src to dst.
Passing the stale src_partially_mapped=false to deferred_split_folio(dst)
while dst already has PG_partially_mapped=true triggers the invariant
check in deferred_split_folio():

VM_WARN_ON_FOLIO(folio_test_partially_mapped(folio), folio)

at mm/huge_memory.c:4371, because the argument contradicts the flag
already set on the folio.

Fix this by removing the src_partially_mapped variable entirely and
reading PG_partially_mapped directly from dst after move_to_new_folio()
completes, where it is authoritative and race-free.

Reported-by: syzbot+a7067a...@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=a7067a757858ac8eb085
Signed-off-by: Deepanshu Kartikey <karti...@gmail.com>
---
mm/migrate.c | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/mm/migrate.c b/mm/migrate.c
index 05cb408846f2..11236779e910 100644
--- a/mm/migrate.c
+++ b/mm/migrate.c
@@ -1361,7 +1361,6 @@ static int migrate_folio_move(free_folio_t put_new_folio, unsigned long private,
int old_page_state = 0;
struct anon_vma *anon_vma = NULL;
bool src_deferred_split = false;
- bool src_partially_mapped = false;
struct list_head *prev;

__migrate_folio_extract(dst, &old_page_state, &anon_vma);
@@ -1378,7 +1377,6 @@ static int migrate_folio_move(free_folio_t put_new_folio, unsigned long private,
if (folio_order(src) > 1 &&
!data_race(list_empty(&src->_deferred_list))) {
src_deferred_split = true;
- src_partially_mapped = folio_test_partially_mapped(src);
}

rc = move_to_new_folio(dst, src, mode);
@@ -1404,11 +1402,13 @@ static int migrate_folio_move(free_folio_t put_new_folio, unsigned long private,
/*
* 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().
+ * __folio_migrate_mapping(). Read PG_partially_mapped directly from
+ * dst: move_to_new_folio() copies all flags from src to dst, so dst
+ * now holds the correct authoritative state. The pre-migration value
+ * sampled from src is racy and must not be used.
*/
if (src_deferred_split)
- deferred_split_folio(dst, src_partially_mapped);
+ deferred_split_folio(dst, folio_test_partially_mapped(dst));

out_unlock_both:
folio_unlock(dst);
--
2.43.0

Lance Yang

unread,
4:10 AM (13 hours ago) 4:10 AM
to syzbot+a7067a...@syzkaller.appspotmail.com, usama...@linux.dev, Liam.H...@oracle.com, ak...@linux-foundation.org, bao...@kernel.org, baoli...@linux.alibaba.com, da...@kernel.org, dev....@arm.com, lance...@linux.dev, linux-...@vger.kernel.org, linu...@kvack.org, l...@kernel.org, npa...@redhat.com, ryan.r...@arm.com, syzkall...@googlegroups.com, z...@nvidia.com

+Cc Usama
Looks like a race introduced by commit[1] ("mm: migrate: requeue
destination folio on deferred split queue").

Between folio migration (mbind) and rmap removal (exit_mmap), I guess :)

migrate_folio_move() snapshots src_partially_mapped from src before
migration:

if (folio_order(src) > 1 &&
!data_race(list_empty(&src->_deferred_list))) {
src_deferred_split = true;
src_partially_mapped = folio_test_partially_mapped(src);
}

Then move_to_new_folio() eventually unqueues src in
__folio_migrate_mapping():

folio_unqueue_deferred_split(src);

After that, migration restores mappings to dst:

if (old_page_state & PAGE_WAS_MAPPED)
remove_migration_ptes(src, dst, 0);

At that point, dst is already visible again. A concurrent unmap path
from another sharer can then remove some of those mappings and reach
deferred_split_folio(dst, true), which sets PG_partially_mapped on
dst.

Migration then resumes and does:

if (src_deferred_split)
deferred_split_folio(dst, src_partially_mapped);

If the earlier snapshot from src was false, this becomes
deferred_split_folio(dst, false), but dst may already have been marked
partially mapped by the concurrent rmap-removal path, so the WARN in
deferred_split_folio() fires:

if (partially_mapped) {
...
} else {
/* partially mapped folios cannot become non-partially mapped */
VM_WARN_ON_FOLIO(folio_test_partially_mapped(folio), folio);
}

[1] https://lore.kernel.org/all/20260312104723.13...@linux.dev/

syzbot

unread,
4:34 AM (13 hours ago) 4:34 AM
to karti...@gmail.com, linux-...@vger.kernel.org, syzkall...@googlegroups.com
Hello,

syzbot has tested the proposed patch and the reproducer did not trigger any issue:

Reported-by: syzbot+a7067a...@syzkaller.appspotmail.com
Tested-by: syzbot+a7067a...@syzkaller.appspotmail.com

Tested on:

commit: 36ece969 Add linux-next specific files for 20260331
git tree: linux-next
console output: https://syzkaller.appspot.com/x/log.txt?x=1687e46a580000
kernel config: https://syzkaller.appspot.com/x/.config?x=e5c508e55e8ef9a7
dashboard link: https://syzkaller.appspot.com/bug?extid=a7067a757858ac8eb085
compiler: Debian clang version 21.1.8 (++20251221033036+2078da43e25a-1~exp1~20251221153213.50), Debian LLD 21.1.8
patch: https://syzkaller.appspot.com/x/patch.diff?x=1285b41f980000

Note: testing is done by a robot and is best-effort only.

Lance Yang

unread,
4:59 AM (12 hours ago) 4:59 AM
to usama...@linux.dev, da...@kernel.org, Liam.H...@oracle.com, z...@nvidia.com, syzbot+a7067a...@syzkaller.appspotmail.com, ak...@linux-foundation.org, bao...@kernel.org, baoli...@linux.alibaba.com, dev....@arm.com, linux-...@vger.kernel.org, linu...@kvack.org, l...@kernel.org, npa...@redhat.com, ryan.r...@arm.com, syzkall...@googlegroups.com, Lance Yang
Perhaps the WARN is simply too strict there :)

Migration already holds the folio lock on dst, while the competing
rmap-removal path runs under the page-table lock. So once
remove_migration_ptes(src, dst, 0) makes dst visible again, this race
looks hard to avoid.

So maybe the simplest fix is just to drop the WARN in the
!partially_mapped path:

---8<---
Subject: [PATCH 1/1] mm/thp: avoid false warning in deferred_split_folio()

From: Lance Yang <lance...@linux.dev>

migrate_folio_move() snapshots src_partially_mapped from src before
migration and later requeues dst after remove_migration_ptes(src, dst, 0).

Once dst is visible again, a competing rmap-removal path can legally set
PG_partially_mapped before the migration path reaches
deferred_split_folio(dst, src_partially_mapped).

Migration already holds the folio lock on dst, while the competing
rmap-removal path runs under the page-table lock. So once
remove_migration_ptes(src, dst, 0) makes dst visible again, this race
looks hard to avoid.

So just drop the WARN in the !partially_mapped path and preserve an
already-set PG_partially_mapped bit.

Link: https://lore.kernel.org/linux-mm/69ccb65b.050a022...@google.com/
Fixes: 8a8ca142a488 ("mm: migrate: requeue destination folio on deferred split queue")
Reported-by: syzbot+a7067a...@syzkaller.appspotmail.com
Signed-off-by: Lance Yang <lance...@linux.dev>
---
mm/huge_memory.c | 3 ---
1 file changed, 3 deletions(-)

diff --git a/mm/huge_memory.c b/mm/huge_memory.c
index 745eb3d0d4a7..8ea8e293dc7c 100644
--- a/mm/huge_memory.c
+++ b/mm/huge_memory.c
@@ -4433,9 +4433,6 @@ void deferred_split_folio(struct folio *folio, bool partially_mapped)
mod_mthp_stat(folio_order(folio), MTHP_STAT_NR_ANON_PARTIALLY_MAPPED, 1);

}
- } else {
- /* partially mapped folios cannot become non-partially mapped */
- VM_WARN_ON_FOLIO(folio_test_partially_mapped(folio), folio);
}
if (list_empty(&folio->_deferred_list)) {
struct mem_cgroup *memcg;
---

Thanks,
Lance

David Hildenbrand (Arm)

unread,
5:36 AM (12 hours ago) 5:36 AM
to Lance Yang, usama...@linux.dev, Liam.H...@oracle.com, z...@nvidia.com, syzbot+a7067a...@syzkaller.appspotmail.com, ak...@linux-foundation.org, bao...@kernel.org, baoli...@linux.alibaba.com, dev....@arm.com, linux-...@vger.kernel.org, linu...@kvack.org, l...@kernel.org, npa...@redhat.com, ryan.r...@arm.com, syzkall...@googlegroups.com, Deepanshu Kartikey
A fix just appeared:

https://lore.kernel.org/r/20260401084116.22...@gmail.com

Have to think about this :)


--
Cheers,

David

David Hildenbrand (Arm)

unread,
6:16 AM (11 hours ago) 6:16 AM
to Lance Yang, usama...@linux.dev, Liam.H...@oracle.com, z...@nvidia.com, syzbot+a7067a...@syzkaller.appspotmail.com, ak...@linux-foundation.org, bao...@kernel.org, baoli...@linux.alibaba.com, dev....@arm.com, linux-...@vger.kernel.org, linu...@kvack.org, l...@kernel.org, npa...@redhat.com, ryan.r...@arm.com, syzkall...@googlegroups.com
On 4/1/26 10:59, Lance Yang wrote:
>
Can't we simply move the setting before restoring migration ptes?

diff --git a/mm/migrate.c b/mm/migrate.c
index 05cb408846f2..5f222cb0ca90 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
@@ -1400,16 +1409,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);


--
Cheers,

David

Lance Yang

unread,
6:53 AM (11 hours ago) 6:53 AM
to da...@kernel.org, karti...@gmail.com, lance...@linux.dev, usama...@linux.dev, Liam.H...@oracle.com, z...@nvidia.com, syzbot+a7067a...@syzkaller.appspotmail.com, ak...@linux-foundation.org, bao...@kernel.org, baoli...@linux.alibaba.com, dev....@arm.com, linux-...@vger.kernel.org, linu...@kvack.org, l...@kernel.org, npa...@redhat.com, ryan.r...@arm.com, syzkall...@googlegroups.com

+Cc Deepanshu
Afraid not, it closes the remove_migration_ptes() ->
deferred_split_folio() race, but opens a new one with the shrinker, IIUC

Once dst is on the deferred split queue, deferred_split_scan() can
pick it up immediately. The shrinker unconditionally dequeues every
folio it visits:

list_del_init(&folio->_deferred_list); /* always */

Then for a non-partially-mapped folio, if folio_trylock() fails
(dst is still locked by migration), it falls through to:

next:
if (did_split || !folio_test_partially_mapped(folio))
continue; /* not requeued, dst silently lost */

so it is *not* requeued.

That seems to recreate the original issue commit[1] was fixing: letting
underused THPs silently fall off the deferred split queue again ...

Hopefully, I didn't miss something important :)

[1] https://lore.kernel.org/all/20260312104723.13...@linux.dev/

David Hildenbrand (Arm)

unread,
7:00 AM (10 hours ago) 7:00 AM
to Lance Yang, karti...@gmail.com, usama...@linux.dev, Liam.H...@oracle.com, z...@nvidia.com, syzbot+a7067a...@syzkaller.appspotmail.com, ak...@linux-foundation.org, bao...@kernel.org, baoli...@linux.alibaba.com, dev....@arm.com, linux-...@vger.kernel.org, linu...@kvack.org, l...@kernel.org, npa...@redhat.com, ryan.r...@arm.com, syzkall...@googlegroups.com
On 4/1/26 12:53, Lance Yang wrote:
>
> +Cc Deepanshu
>
> On Wed, Apr 01, 2026 at 12:16:43PM +0200, David Hildenbrand (Arm) wrote:
>> On 4/1/26 10:59, Lance Yang wrote:
>>>
>>> >from another sharer can then remove some of those mappings and reach
>>>
How is that different to the shrinker just trying to lock the folio before we
unlock it and failing? The race already exists?

To sort out that race a trylock must not result in the folio getting
discarded.

diff --git a/mm/huge_memory.c b/mm/huge_memory.c
index ff9a42abd1b6..521989517cd1 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,6 +4569,7 @@ 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


--
Cheers,

David

Lance Yang

unread,
7:21 AM (10 hours ago) 7:21 AM
to da...@kernel.org, lance...@linux.dev, karti...@gmail.com, usama...@linux.dev, Liam.H...@oracle.com, z...@nvidia.com, syzbot+a7067a...@syzkaller.appspotmail.com, ak...@linux-foundation.org, bao...@kernel.org, baoli...@linux.alibaba.com, dev....@arm.com, linux-...@vger.kernel.org, linu...@kvack.org, l...@kernel.org, npa...@redhat.com, ryan.r...@arm.com, syzkall...@googlegroups.com
Ouch, you're right, I was wrong - the trylock drop is a pre-existing
issue, not caused by the reorder ;)

>
>To sort out that race a trylock must not result in the folio getting
>discarded.

Nice, LGTM!

Given that the "trylock -> drop" behavior seems to exist already today,
do you think it's worth fixing that together with the reorder?

David Hildenbrand (Arm)

unread,
7:23 AM (10 hours ago) 7:23 AM
to Lance Yang, karti...@gmail.com, usama...@linux.dev, Liam.H...@oracle.com, z...@nvidia.com, syzbot+a7067a...@syzkaller.appspotmail.com, ak...@linux-foundation.org, bao...@kernel.org, baoli...@linux.alibaba.com, dev....@arm.com, linux-...@vger.kernel.org, linu...@kvack.org, l...@kernel.org, npa...@redhat.com, ryan.r...@arm.com, syzkall...@googlegroups.com
On 4/1/26 13:20, Lance Yang wrote:
>
> On Wed, Apr 01, 2026 at 01:00:13PM +0200, David Hildenbrand (Arm) wrote:
>> On 4/1/26 12:53, Lance Yang wrote:
>>>
>>> +Cc Deepanshu
>>>
>>>
>>> Afraid not, it closes the remove_migration_ptes() ->
>>> deferred_split_folio() race, but opens a new one with the shrinker, IIUC
>>>
>>> Once dst is on the deferred split queue, deferred_split_scan() can
>>> pick it up immediately. The shrinker unconditionally dequeues every
>>> folio it visits:
>>>
>>> list_del_init(&folio->_deferred_list); /* always */
>>>
>>> Then for a non-partially-mapped folio, if folio_trylock() fails
>>> (dst is still locked by migration), it falls through to:
>>>
>>> next:
>>> if (did_split || !folio_test_partially_mapped(folio))
>>> continue; /* not requeued, dst silently lost */
>>>
>>> so it is *not* requeued.
>>
>> How is that different to the shrinker just trying to lock the folio before we
>> unlock it and failing? The race already exists?
>
> Ouch, you're right, I was wrong - the trylock drop is a pre-existing
> issue, not caused by the reorder ;)
>
>>
>> To sort out that race a trylock must not result in the folio getting
>> discarded.
>
> Nice, LGTM!
>
> Given that the "trylock -> drop" behavior seems to exist already today,
> do you think it's worth fixing that together with the reorder?

I'd do it in a single shot if possible.

Can you craft something? (cc stable etc)

--
Cheers,

David

Lance Yang

unread,
7:35 AM (10 hours ago) 7:35 AM
to da...@kernel.org, lance...@linux.dev, karti...@gmail.com, usama...@linux.dev, Liam.H...@oracle.com, z...@nvidia.com, syzbot+a7067a...@syzkaller.appspotmail.com, ak...@linux-foundation.org, bao...@kernel.org, baoli...@linux.alibaba.com, dev....@arm.com, linux-...@vger.kernel.org, linu...@kvack.org, l...@kernel.org, npa...@redhat.com, ryan.r...@arm.com, syzkall...@googlegroups.com
ACK.

>Can you craft something? (cc stable etc)

certainly, will do! But commit[1] ("mm: migrate: requeue destination
folio on deferred split queue") is only in mm-stable now, not yet
upstream/stable ...

[1] https://lore.kernel.org/mm-commits/2026032900412...@smtp.kernel.org/

David Hildenbrand (Arm)

unread,
7:38 AM (10 hours ago) 7:38 AM
to Lance Yang, karti...@gmail.com, usama...@linux.dev, Liam.H...@oracle.com, z...@nvidia.com, syzbot+a7067a...@syzkaller.appspotmail.com, ak...@linux-foundation.org, bao...@kernel.org, baoli...@linux.alibaba.com, dev....@arm.com, linux-...@vger.kernel.org, linu...@kvack.org, l...@kernel.org, npa...@redhat.com, ryan.r...@arm.com, syzkall...@googlegroups.com
On 4/1/26 13:34, Lance Yang wrote:
>
> On Wed, Apr 01, 2026 at 01:22:58PM +0200, David Hildenbrand (Arm) wrote:
>> On 4/1/26 13:20, Lance Yang wrote:
>>>
>>>
>>> Ouch, you're right, I was wrong - the trylock drop is a pre-existing
>>> issue, not caused by the reorder ;)
>>>
>>>
>>> Nice, LGTM!
>>>
>>> Given that the "trylock -> drop" behavior seems to exist already today,
>>> do you think it's worth fixing that together with the reorder?
>>
>> I'd do it in a single shot if possible.
>
> ACK.
>
>> Can you craft something? (cc stable etc)
>
> certainly, will do! But commit[1] ("mm: migrate: requeue destination
> folio on deferred split queue") is only in mm-stable now, not yet
> upstream/stable ...

It's tricky. The original commit will be backported to stable kernels,
so we want also the fix to be backported to the same stable kernels.

The commit id in mm-stable is "stable" now.

--
Cheers,

David

Lance Yang

unread,
7:41 AM (10 hours ago) 7:41 AM
to David Hildenbrand (Arm), karti...@gmail.com, usama...@linux.dev, Liam.H...@oracle.com, z...@nvidia.com, syzbot+a7067a...@syzkaller.appspotmail.com, ak...@linux-foundation.org, bao...@kernel.org, baoli...@linux.alibaba.com, dev....@arm.com, linux-...@vger.kernel.org, linu...@kvack.org, l...@kernel.org, npa...@redhat.com, ryan.r...@arm.com, syzkall...@googlegroups.com
Emm... Not a big deal, I guess. We can always submit a stable backport
once that fix gets merged into stable :D

David Hildenbrand (Arm)

unread,
7:44 AM (10 hours ago) 7:44 AM
to Lance Yang, karti...@gmail.com, usama...@linux.dev, Liam.H...@oracle.com, z...@nvidia.com, syzbot+a7067a...@syzkaller.appspotmail.com, ak...@linux-foundation.org, bao...@kernel.org, baoli...@linux.alibaba.com, dev....@arm.com, linux-...@vger.kernel.org, linu...@kvack.org, l...@kernel.org, npa...@redhat.com, ryan.r...@arm.com, syzkall...@googlegroups.com
On 4/1/26 13:41, Lance Yang wrote:
>
>
> On 2026/4/1 19:38, David Hildenbrand (Arm) wrote:
>> On 4/1/26 13:34, Lance Yang wrote:
>>>
>>>
>>> ACK.
>>>
>>>
>>> certainly, will do! But commit[1] ("mm: migrate: requeue destination
>>> folio on deferred split queue") is only in mm-stable now, not yet
>>> upstream/stable ...
>>
>> It's tricky. The original commit will be backported to stable kernels,
>> so we want also the fix to be backported to the same stable kernels.
>>
>> The commit id in mm-stable is "stable" now.
>
> Emm... Not a big deal, I guess. We can always submit a stable backport
> once that fix gets merged into stable :D

What's the problem with tagging the commit right way as Cc: stable?

--
Cheers,

David

Lance Yang

unread,
7:51 AM (10 hours ago) 7:51 AM
to David Hildenbrand (Arm), karti...@gmail.com, usama...@linux.dev, Liam.H...@oracle.com, z...@nvidia.com, syzbot+a7067a...@syzkaller.appspotmail.com, ak...@linux-foundation.org, bao...@kernel.org, baoli...@linux.alibaba.com, dev....@arm.com, linux-...@vger.kernel.org, linu...@kvack.org, l...@kernel.org, npa...@redhat.com, ryan.r...@arm.com, syzkall...@googlegroups.com
Sure, that makes sense. I'll add "Cc: stable" to the fix as well, so
it can follow 8a8ca142a488 into stable ;)

Lance Yang

unread,
7:54 AM (10 hours ago) 7:54 AM
to David Hildenbrand (Arm), karti...@gmail.com, usama...@linux.dev, Liam.H...@oracle.com, z...@nvidia.com, syzbot+a7067a...@syzkaller.appspotmail.com, ak...@linux-foundation.org, bao...@kernel.org, baoli...@linux.alibaba.com, dev....@arm.com, linux-...@vger.kernel.org, linu...@kvack.org, l...@kernel.org, npa...@redhat.com, ryan.r...@arm.com, syzkall...@googlegroups.com
8a8ca142a488 refers to commit "mm: migrate: requeue destination folio on
deferred split queue".
Reply all
Reply to author
Forward
0 new messages