From: Pedro Falcato <pfalcato@suse.de>
To: Ayush Ranjan <ayushr@modal.com>
Cc: Hugh Dickins <hughd@google.com>,
Matthew Wilcox <willy@infradead.org>,
Andrew Morton <akpm@linux-foundation.org>,
Jan Kara <jack@suse.cz>,
Baolin Wang <baolin.wang@linux.alibaba.com>,
David Hildenbrand <david@kernel.org>,
Gregory Price <gourry@gourry.net>,
linux-mm@kvack.org, linux-fsdevel@vger.kernel.org,
linux-kernel@vger.kernel.org
Subject: Re: [BUG] shmem: FALLOC_FL_PUNCH_HOLE vs fault-around race corrupts page cache / rss counters
Date: Thu, 24 Sep 2026 09:34:24 +0100 [thread overview]
Message-ID: <arTdLsBENhrpOyk-@pedro-suse.tail5790ac.ts.net> (raw)
In-Reply-To: <20260924061708.1645968-1-ayushr@modal.com>
(please use the email I actually use for work, thanks; not sure how
you got to that one)
Hi,
On Thu, Sep 24, 2026 at 06:16:21AM +0000, Ayush Ranjan wrote:
> Hi,
>
> We are seeing shmem/tmpfs page cache corruption on production hosts
> running a workload that punches holes in a memfd (hole-punch based
> memory reclaim) while other threads and forked children fault the
> same MAP_SHARED mapping. The kernel taints but does not oops:
>
> BUG: Bad page cache in process ... pfn:...
> page dumped because: still mapped when deleted
> ...
> dentry name(?): "memfd:..."
>
> and, more frequently, a paired rss-counter imbalance when the mm is
> torn down, always exactly one PMD-order folio (512 pages):
>
> BUG: Bad rss-counter state mm:... type:MM_FILEPAGES val:-512
> BUG: Bad rss-counter state mm:... type:MM_SHMEMPAGES val:512
>
> Seen on 6.12 and 6.18, x86_64, bare metal and VM, with
> /sys/kernel/mm/transparent_hugepage/shmem_enabled = always.
>
> This looks like the same corruption Gregory reported in March, which
> as far as I can tell stalled without a fix; that report needed ~100
> ballooning VMs to reproduce:
Well, I thought (from the lack of replies) that it was probably a bug on
their side. Perhaps that's not true :/
>
> https://patchew.org/linux/20260326162611.693539-1-gourry@gourry.net/
>
> The reproducer at the end of this mail trips it with a single memfd,
> no VMs or ballooning, within a few minutes on a large machine, so
> hopefully it makes the race easier to confirm (and to test a fix
> against).
>
> Here is my best understanding of the race -- corrections welcome:
>
> shmem guards faults against an in-progress hole punch with
> inode->i_private: shmem_fault() -> shmem_falloc_wait() waits while
> shmem_fallocate(PUNCH_HOLE) holds i_private. But shmem's .map_pages
> is the generic filemap_map_pages() (shmem_vm_ops /
> shmem_anon_vm_ops), which does not consult i_private and does not
> take invalidate_lock, and shmem does not use invalidate_lock to
> serialize faults against truncation the way regular filesystems do --
> the i_private + waitq scheme stands in for it, but only shmem_fault()
> participates in that scheme.
>
> So while shmem_fallocate(PUNCH_HOLE) is between
> unmap_mapping_range() and shmem_truncate_range(), a concurrent
> fault-around can (re-)install PTEs for folios that are about to be
> truncated:
>
> - filemap_map_pages() samples mm_counter_file(folio) once per batch
> and applies it with add_mm_counter() after mapping; if the
> folio's swapbacked state changes while it is concurrently torn
But that cannot happen? We hold the folio lock in filemap_map_pages().
The folio (naturally) cannot be torn down while we have the folio lock.
> down, the map-time counter (MM_FILEPAGES) and the zap-time
> counter (MM_SHMEMPAGES) disagree by exactly one folio -- the
> +/-512 imbalance above.
>
> - a folio re-mapped in this window (by fault-around directly, or
> via a child VMA whose PTEs copy_page_range() installs after
> unmap_mapping_range() has already walked the i_mmap tree -- the
> dup_mmap() variant discussed in the earlier thread) can be
> deleted from the page cache while still mapped -> "still mapped
> when deleted".
No, I don't think this paragraph is true. Page cache truncation (via
truncate, or fallocate PUNCH_HOLE) takes the folio lock for each folio
that is about to be truncated out. Mapping folios takes the folio lock
as well, except in the fork() case where a myriad of weird interval tree
+ PTE lock interactions make it safe (AIUI).
>
> Reproducer
> ----------
>
> The race is on PMD-order folios, so khugepaged needs to scan
> aggressively (with the default 10s scan interval the punched ranges
> are not re-collapsed fast enough to reproduce quickly):
>
> echo always > /sys/kernel/mm/transparent_hugepage/shmem_enabled
> cd /sys/kernel/mm/transparent_hugepage/khugepaged
> echo 1 > scan_sleep_millisecs
> echo 4096 > pages_to_scan
> echo 511 > max_ptes_none
>
> cc -O2 -pthread -o repro repro_shmem_punch_race.c
> for i in $(seq $(( $(nproc) / 3 ))); do ./repro 60 & done; wait
> # watch: dmesg -w
>
> On a 112-CPU host this trips within ~2-5 minutes; this capture is
> from 6.12.0-204.92.4.4.3.el9uek.x86_64:
Awesome that you have a reproducer! Have you reproduced this on a mainline
kernel? Enterprise kernels are not supported upstream.
In any case, I'll take a closer look ASAP.
--
Pedro
next prev parent reply other threads:[~2026-09-24 8:34 UTC|newest]
Thread overview: 21+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-24 6:16 Ayush Ranjan
2026-09-24 7:12 ` David Hildenbrand (Arm)
2026-09-24 8:34 ` Pedro Falcato [this message]
2026-09-24 9:15 ` Jan Kara
2026-09-25 5:32 ` Ayush Ranjan
2026-09-24 9:30 ` Baolin Wang
2026-09-25 5:33 ` Ayush Ranjan
2026-09-25 5:30 ` Ayush Ranjan
2026-09-25 6:50 ` Ayush Ranjan
2026-10-03 3:31 ` Ayush Ranjan
2026-10-05 5:28 ` Andrew Morton
2026-10-08 9:24 ` Jan Kara
2026-10-08 15:23 ` Andrew Morton
2026-10-08 15:31 ` Andrew Morton
2026-10-09 6:46 ` Baolin Wang
2026-10-09 8:41 ` Pedro Falcato
2026-10-09 9:20 ` Baolin Wang
2026-10-09 10:14 ` Baolin Wang
2026-10-08 13:07 ` Gregory Price
2026-10-08 7:58 ` Baolin Wang
2026-10-08 9:26 ` Jan Kara
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=arTdLsBENhrpOyk-@pedro-suse.tail5790ac.ts.net \
--to=pfalcato@suse.de \
--cc=akpm@linux-foundation.org \
--cc=ayushr@modal.com \
--cc=baolin.wang@linux.alibaba.com \
--cc=david@kernel.org \
--cc=gourry@gourry.net \
--cc=hughd@google.com \
--cc=jack@suse.cz \
--cc=linux-fsdevel@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mm@kvack.org \
--cc=willy@infradead.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
all inboxes | Powered by JetHome®