All of lore.kernel.org
 help / color / mirror / Atom feed
From: Jiayuan Chen <jiayuan.chen@linux.dev>
To: stable@vger.kernel.org, linux-mm@kvack.org
Cc: jiayuan.chen@shopee.com, jiayuan.chen@linux.dev,
	yingfu.zhou@shopee.com, willy@infradead.org,
	Andrew Morton <akpm@linux-foundation.org>,
	Huang Ying <ying.huang@intel.com>,
	linux-kernel@vger.kernel.org
Subject: [PATCH 5.15.y 6.1.y 6.6.y 0/1] mm/vmscan: flush deferred TLB before freeing large folios in reclaim
Date: Wed,  8 Jul 2026 12:12:35 +0800	[thread overview]
Message-ID: <20260708041237.289026-1-jiayuan.chen@linux.dev> (raw)

Hi,

We were chasing random user-space segfaults on our production kernels.
They were fully non-deterministic, and the fault address reported for each
SIGSEGV was itself random and had nothing to do with the code that was
actually running -- which smells like a stale TLB entry, not corrupted
data.

We managed to reproduce it with stress-ng: under memory pressure the
workers take random SIGSEGV/SIGILL too, again at random fault addresses.

It turns out we're missing a TLB flush. In reclaim, shrink_folio_list()
tears down the PTEs with a deferred, batched flush. Order-0 folios are
collected and only freed after that batch is flushed by
try_to_unmap_flush(). Large folios, though, are freed right away at the
free_it label via destroy_large_folio(), which runs *before* the flush. So
a large folio's pages can go back to the allocator and get reused while
some other CPU still has a stale TLB entry pointing at them -- and that CPU
then reads or executes through the old translation into a page that now
belongs to someone else. When it's executable text mapped as a large
folio, the CPU literally fetches instructions out of a reused page, which
is where the random crashes come from. (This is about file-backed large
folios, not anonymous THP, so transparent_hugepage=never doesn't help.)

How we reproduce it:
- Make a cgroup and set memory.high.
- Run ~45 stress-ng workers in it (e.g. --cpu N --cpu-method all).
- Alongside, run a tiny program that keeps allocating anonymous memory to
  push the cgroup over memory.high and keep reclaim busy.
Dropping caches first (echo 3 > /proc/sys/vm/drop_caches) makes the text
refault as large folios and reproduces it much faster.

To be 100% sure about the mechanism, we filled every reclaimed large folio
with 0xCC (INT3) and held onto it instead of freeing it. Under the repro,
stress-ng workers immediately hit INT3 at instruction pointers inside their
own text -- i.e. CPUs were fetching instructions through stale TLB entries
from freed, poisoned pages. stress-ng has no INT3 in its binary, so the
only way to execute one is through a stale translation into a freed page.
Several CPUs hit it within the same microsecond, which lines up nicely with
a single batched unmap whose flush was skipped on more than one CPU.

Upstream this got fixed as a side effect of
commit bc2ff4cbc329 ("mm: free folios in a batch in shrink_folio_list()")
which sends large folios down the same flush-before-free batch path.

The patch below is the minimal fix: just flush the deferred batch before
freeing a large folio inline.

Jiayuan Chen (1):
  mm/vmscan: flush deferred TLB before freeing large folios

 mm/vmscan.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

-- 
2.43.0


             reply	other threads:[~2026-07-08  4:13 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-07-08  4:12 Jiayuan Chen [this message]
2026-07-08  4:12 ` [PATCH 5.15.y 6.1.y 6.6.y 1/1] mm/vmscan: flush deferred TLB before freeing large folios Jiayuan Chen
2026-07-08 11:58   ` Matthew Wilcox
2026-07-08 16:18   ` Sasha Levin
2026-07-09  0:56     ` Jiayuan Chen

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=20260708041237.289026-1-jiayuan.chen@linux.dev \
    --to=jiayuan.chen@linux.dev \
    --cc=akpm@linux-foundation.org \
    --cc=jiayuan.chen@shopee.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-mm@kvack.org \
    --cc=stable@vger.kernel.org \
    --cc=willy@infradead.org \
    --cc=ying.huang@intel.com \
    --cc=yingfu.zhou@shopee.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.