From: ZhengYuan Huang <gality369@gmail.com>
To: akpm@linux-foundation.org, david@kernel.org, ljs@kernel.org,
Liam.Howlett@oracle.com, vbabka@kernel.org, rppt@kernel.org,
surenb@google.com, mhocko@suse.com, willy@infradead.org
Cc: linux-mm@kvack.org, linux-kernel@vger.kernel.org,
baijiaju1990@gmail.com, r33s3n6@gmail.com, zzzccc427@gmail.com,
ZhengYuan Huang <gality369@gmail.com>
Subject: [PATCH] mm: prepare anon_vma before swapin rmap
Date: Fri, 17 Apr 2026 09:16:06 +0800 [thread overview]
Message-ID: <20260417011606.1089985-1-gality369@gmail.com> (raw)
[BUG]
madvise(MADV_HWPOISON) can fault a swap entry back in through
get_user_pages_fast() and hit:
kernel BUG at mm/rmap.c:1364!
Oops: invalid opcode: 0000 [#1] SMP KASAN NOPTI
RIP: 0010:__folio_set_anon mm/rmap.c:1364 [inline]
RIP: 0010:folio_add_new_anon_rmap+0x41d/0xc10 mm/rmap.c:1553
Call Trace:
do_swap_page+0x14c5/0x5c30 mm/memory.c:4963
handle_pte_fault mm/memory.c:6198 [inline]
__handle_mm_fault+0x1512/0x22f0 mm/memory.c:6336
handle_mm_fault+0x42f/0x820 mm/memory.c:6505
faultin_page mm/gup.c:1126 [inline]
__get_user_pages+0x4b3/0x3400 mm/gup.c:1428
__get_user_pages_locked mm/gup.c:1692 [inline]
__gup_longterm_locked+0x945/0x14b0 mm/gup.c:2476
gup_fast_fallback+0x8a3/0x2440 mm/gup.c:3220
get_user_pages_fast+0x64/0xb0 mm/gup.c:3298
madvise_inject_error mm/madvise.c:1456 [inline]
madvise_do_behavior+0x503/0x860 mm/madvise.c:1875
do_madvise+0x17e/0x210 mm/madvise.c:1978
__do_sys_madvise mm/madvise.c:1987 [inline]
__se_sys_madvise mm/madvise.c:1985 [inline]
__x64_sys_madvise+0xae/0x120 mm/madvise.c:1985
...
[CAUSE]
Commit a373baed5a9d ("mm: delay the check for a NULL anon_vma") moved
anon_vma preparation out of the generic fault path and into the fault
handlers that actually need to install anonymous rmap state.
do_swap_page() was left behind. It can still restore anonymous mappings
via folio_add_new_anon_rmap() or folio_add_anon_rmap_ptes(), but it does
not call vmf_anon_prepare() first. On a VMA-lock fault this can leave
vma->anon_vma NULL all the way down to __folio_set_anon(), which BUG_ONs
on that violated invariant.
[FIX]
Prepare the faulting VMA's anon_vma once do_swap_page() has confirmed it
is handling a real swap entry, before any swapin path can install
anonymous rmap state.
vmf_anon_prepare() already handles the retry rules for VMA-lock faults,
and when anon_vma is already present this stays a single likely branch in
the swap fault hot path.
Fixes: a373baed5a9d ("mm: delay the check for a NULL anon_vma")
Signed-off-by: ZhengYuan Huang <gality369@gmail.com>
---
I can reproduce this issue deterministically on v6.18, but I have not
been able to reproduce it with the same setup on next-20260415.
However, I have not identified a change that clearly explains the
difference. From code inspection, do_swap_page() still appears able to
reach folio_add_new_anon_rmap()/folio_add_anon_rmap_ptes() without a
prior vmf_anon_prepare(), while __folio_set_anon() still BUG_ONs if
vma->anon_vma is NULL. So although I could not reproduce the issue on
next-20260415, I also could not confirm that it has been fixed there.
Recent changes around the swap fault path may have affected the
reproduction conditions, but I may also be missing another relevant
change.
---
mm/memory.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/mm/memory.c b/mm/memory.c
index ea6568571131..a64bc9826cc5 100644
--- a/mm/memory.c
+++ b/mm/memory.c
@@ -4850,6 +4850,11 @@ vm_fault_t do_swap_page(struct vm_fault *vmf)
goto out;
}
+ /* Swapin installs anonymous rmap state into the faulting VMA. */
+ ret = vmf_anon_prepare(vmf);
+ if (ret)
+ goto out;
+
/* Prevent swapoff from happening to us. */
si = get_swap_device(entry);
if (unlikely(!si))
--
2.49.0
next reply other threads:[~2026-04-17 1:16 UTC|newest]
Thread overview: 13+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-04-17 1:16 ZhengYuan Huang [this message]
2026-04-17 4:03 ` [PATCH] mm: prepare anon_vma before swapin rmap Matthew Wilcox
2026-04-18 9:38 ` Lorenzo Stoakes
2026-04-17 10:53 ` David Hildenbrand (Arm)
2026-04-17 11:57 ` David Hildenbrand (Arm)
2026-04-17 13:03 ` Matthew Wilcox
2026-04-17 13:36 ` Vlastimil Babka (SUSE)
2026-04-17 15:09 ` Matthew Wilcox
2026-04-18 9:35 ` Lorenzo Stoakes
2026-04-19 8:19 ` David Hildenbrand (Arm)
2026-04-19 14:21 ` Lorenzo Stoakes
2026-04-22 7:59 ` ZhengYuan Huang
2026-04-22 10:20 ` Lorenzo Stoakes
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=20260417011606.1089985-1-gality369@gmail.com \
--to=gality369@gmail.com \
--cc=Liam.Howlett@oracle.com \
--cc=akpm@linux-foundation.org \
--cc=baijiaju1990@gmail.com \
--cc=david@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mm@kvack.org \
--cc=ljs@kernel.org \
--cc=mhocko@suse.com \
--cc=r33s3n6@gmail.com \
--cc=rppt@kernel.org \
--cc=surenb@google.com \
--cc=vbabka@kernel.org \
--cc=willy@infradead.org \
--cc=zzzccc427@gmail.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.