All of lore.kernel.org
 help / color / mirror / Atom feed
From: Yuan-Hao Hsu <aa9736195201@gmail.com>
To: Andrew Morton <akpm@linux-foundation.org>,
	David Hildenbrand <david@kernel.org>
Cc: Lorenzo Stoakes <ljs@kernel.org>,
	liam@infradead.org, Vlastimil Babka <vbabka@kernel.org>,
	Mike Rapoport <rppt@kernel.org>,
	Suren Baghdasaryan <surenb@google.com>,
	Michal Hocko <mhocko@suse.com>, Barry Song <baohua@kernel.org>,
	Ryan Roberts <ryan.roberts@arm.com>, Dev Jain <dev.jain@arm.com>,
	linux-mm@kvack.org, linux-kernel@vger.kernel.org
Subject: [PATCH v2 0/2] mm/memory: reuse the whole exclusive large folio on a write fault
Date: Sat, 19 Sep 2026 15:31:31 +0800	[thread overview]
Message-ID: <20260919073134.639-1-aa9736195201@gmail.com> (raw)
In-Reply-To: <20260918064238.868-1-aa9736195201@gmail.com>

After fork() and the child's exit, the parent's write faults reuse a
large anonymous folio one PTE at a time, although
wp_can_reuse_anon_folio() has already found the whole folio exclusive.

v2, after the comments on v1 [1]:
- Split in two.  1/2 handles an aligned block of 16 PTEs around the
  fault, the contpte-sized version David was fine with in the 2024
  discussion of Barry's RFC [2].  2/2 lifts that to the folio.
- The earlier discussion is linked; the changelogs say how its two
  reservations, the latency of the individual fault and how far to go
  around it, are answered.
- The bound of the walk is spelled out (Barry): folio, VMA and block or
  page table, each PTE read once by folio_pte_batch_flags().
- Changelogs cut to what is needed to judge the change.
- Same base as v1; 1/2 + 2/2 is the code of v1.

Two points from the AI review of v1, both done as mprotect() does them:
change_pte_range() does not flush_cache_range() before making PTEs
writable, and it makes clean exclusive anonymous PTEs writable without
pte_mkdirty() (the dirty rule is for shared file mappings, see
can_change_shared_pte_writable()).

Controls, unchanged: order-0 pages, PMD-mapped THPs, the COW copy path
and the order-0 and cow/fork/write-fault modes of David's
pte-mapped-folio-benchmarks.

What does not get faster on x86: stores to pages this CPU still holds
a read-only TLB entry for.  The fault makes the PTEs writable but, like
mprotect(), does not flush, so such a page takes one spurious fault,
about the cost of the reuse fault it replaces.  That is the case for
pages read since fork(), and for a loop that only stores one byte per
page in ascending order (David's reuse-byte mode): the CPU runs the
next stores speculatively while the first one faults and caches their
read-only translations.  Shown with kprobes (135,687 handle_mm_fault()
for 8,457 do_wp_page()) and an LFENCE after every store (4,100 faults
instead of 65,400); the untouched PMD-mapped case behaves the same.  A
flush_tlb_local() in the helper would fix it (that loop 28 -> 4 ms,
memset() 38 -> 21 ms, +140 ns per fault), but generic code has no way
to ask x86 for a flush that stays on this CPU, so that is for later.

Tested with DEBUG_VM, DEBUG_VM_PGTABLE, PROVE_LOCKING and
PAGE_TABLE_CHECK_ENFORCED: the mm selftests, a 12-scenario COW test
(child alive, vmsplice, PROT_READ VMA inside the folio, soft-dirty and
uffd-wp counts, mremap, holes, pageout, FOLL_FORCE), a
fork/pageout/mprotect/vmsplice stress, NUMA balancing on numa=fake=2
(protnone PTEs left alone), and arm64 under QEMU for the counters.
Cross-built for arm64 4K/16K/64K, i386 with and without PAE, x86
without THP, arm, arm nommu, riscv64, powerpc64le and s390x.

[1] https://lore.kernel.org/r/20260918064238.868-1-aa9736195201@gmail.com
[2] https://lore.kernel.org/r/20240831092339.66085-1-21cnbao@gmail.com

Yuan-Hao Hsu (2):
  mm/memory: reuse 16 PTEs of an exclusive large folio on a write fault
  mm/memory: reuse the whole exclusive large folio on a write fault

 mm/memory.c | 68 +++++++++++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 66 insertions(+), 2 deletions(-)


base-commit: 238650ef6c7c7cca08e032527329424c9fbd70e5
-- 
2.43.0



  parent reply	other threads:[~2026-09-19  7:31 UTC|newest]

Thread overview: 18+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-09-18  6:42 [PATCH] mm/memory: reuse the whole exclusive large folio on a write fault Yuan-Hao Hsu
2026-09-18 12:14 ` David Hildenbrand (Arm)
2026-09-18 18:28   ` Yuan-Hao Hsu
2026-09-18 23:48     ` Barry Song
2026-09-19  7:24       ` Yuan-Hao Hsu
2026-09-18 13:54 ` Lorenzo Stoakes (ARM)
2026-09-19  7:31 ` Yuan-Hao Hsu [this message]
2026-09-19  7:31   ` [PATCH v2 1/2] mm/memory: reuse 16 PTEs of an " Yuan-Hao Hsu
2026-09-24 18:46     ` David Hildenbrand (Arm)
2026-09-29 22:45       ` Yuan-Hao Hsu
2026-09-19  7:31   ` [PATCH v2 2/2] mm/memory: reuse the whole " Yuan-Hao Hsu
2026-09-19 10:10     ` David Hildenbrand (Arm)
2026-09-19 11:18       ` Yuan-Hao Hsu
2026-09-24 19:54         ` David Hildenbrand (Arm)
2026-09-19 10:08   ` [PATCH v2 0/2] " David Hildenbrand (Arm)
2026-09-19 11:18     ` Yuan-Hao Hsu
2026-09-21 12:36       ` Lorenzo Stoakes (ARM)
2026-09-21 19:59         ` Yuan-Hao Hsu

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=20260919073134.639-1-aa9736195201@gmail.com \
    --to=aa9736195201@gmail.com \
    --cc=akpm@linux-foundation.org \
    --cc=baohua@kernel.org \
    --cc=david@kernel.org \
    --cc=dev.jain@arm.com \
    --cc=liam@infradead.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-mm@kvack.org \
    --cc=ljs@kernel.org \
    --cc=mhocko@suse.com \
    --cc=rppt@kernel.org \
    --cc=ryan.roberts@arm.com \
    --cc=surenb@google.com \
    --cc=vbabka@kernel.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 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.