Linux-mm Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [REGRESSION] mm/mprotect: shared-dirty base-page toggle slower since v6.17
@ 2026-06-24 17:28 Chengfeng Lin
  2026-07-01 10:50 ` Chengfeng Lin
  0 siblings, 1 reply; 7+ messages in thread
From: Chengfeng Lin @ 2026-06-24 17:28 UTC (permalink / raw)
  To: Pedro Falcato, Andrew Morton, linux-mm
  Cc: Liam R. Howlett, Lorenzo Stoakes, Vlastimil Babka, Jann Horn,
	linux-kernel, regressions

Hi,

I have a refreshed bare-metal result for the shared-dirty mprotect()
slowdown I reported earlier from QEMU/lab testing.

The reproducer is intentionally narrow:

  - MAP_SHARED | MAP_ANONYMOUS mapping
  - 64 MiB range, write-prefaulted before timing
  - state check: 4 KiB base pages, no THP backing
  - repeated full-range mprotect(PROT_READ)
  - restore with mprotect(PROT_READ | PROT_WRITE)
  - write-touch after each protect/restore cycle

So this is not a generic mprotect() regression claim.  The scope is the
shared-dirty base-page PTE permission-change path.

The bare-metal machine is an Intel Core i7-14700 system.  The workload is
single-threaded and pinned to one logical CPU with `taskset -c 2`.  The primary
metric is `iteration_ns_per_page`, lower is better.  It is the wall-clock time
for one full protect/restore/write-touch iteration, divided by the number of
4 KiB pages in the range.  Each benchmark step used 9 external rounds, 1000
iterations, and 10 warmup iterations.

First, the v6.12 -> v6.19 result still reproduces on bare metal:

  kernel                         iteration_ns_per_page
  v6.12.77                       26
  v6.19.9                        37

I then narrowed the release window with 3 interleaved boot/run steps per
kernel:

  kernel                         values          mean
  v6.16                          25 25 25        25.000
  v6.17                          37 37 37        37.000
  v6.18                          38 38 38        38.000
  v6.18.19                       38 38 38        38.000
  v6.19.9                        37 36 37        36.667

I also checked later context with the same standalone command:

  kernel                         values          mean
  v7.0.9                         36 36 36        36.000
  v6.19.9 + Pedro v3 patch-only  39 39 39        39.000
  v7.1.0-rc3 mm-unstable/Pedro   39 39 39        39.000

I do not treat the mm-unstable result as a clean release-kernel comparison.
It is only a follow-up check, and in this workload it did not improve the
standalone result.

All of these runs reported `expected_match_ratio=100` and
`unexpected_results=0`.  The state check in the standalone output stays in the
same shape: 4 KiB pages, no THP.

This puts the slowdown in the v6.16 -> v6.17 release window.

As an attribution check, I also built a v6.17 probe kernel that only changes
the present-PTE path in `mm/mprotect.c::change_pte_range()` for this workload
back to a single-PTE start/commit/flush shape.  That is not an upstream patch
and not a clean release-kernel comparison; it is only a hot-path probe.

The result was:

  kernel                         values          mean
  v6.16                          25 25 25        25.000
  v6.17                          37 37 37        37.000
  v6.17 single-PTE probe         25 25 25        25.000

So the targeted probe brings v6.17 back to the v6.16 range for this workload.
That points at the v6.17 PTE-batching shape in `change_pte_range()` as the
main cost for this shared-dirty 4 KiB base-page case.

I do not want to overstate the attribution.  I tried reversing the official
`cac1db8c3aad ("mm: optimize mprotect() by PTE batching")` patch onto my
linux-6.17 tree, but it did not apply cleanly.  That means this is not an
exact revert result.  I can only say that the slowdown appears in the
v6.16 -> v6.17 window, and that this focused probe brings the v6.17 result
back to the v6.16 range.

Evidence bundle:

  https://github.com/lcf0399/linux-mm-regression-evidence/tree/acd7fef0e0276ac361971b0960e6611811edf5b3/mprotect-shared-dirty-toggle

Standalone reproducer:

  https://github.com/lcf0399/linux-mm-regression-evidence/tree/acd7fef0e0276ac361971b0960e6611811edf5b3/mprotect-shared-dirty-toggle/reproducer

For each installed kernel, the standalone reproducer was run as:

  taskset -c 2 env MAPPING_MB=64 ITERATIONS=1000 WARMUP=10 \
    EXTERNAL_ROUNDS=9 ./run_mprotect_shared_dirty_reproducer.sh

For the release-window check, a small systemd/GRUB queue booted each target
kernel before running the same command.

Bare-metal summaries and raw run logs:

  https://github.com/lcf0399/linux-mm-regression-evidence/tree/acd7fef0e0276ac361971b0960e6611811edf5b3/mprotect-shared-dirty-toggle/bare-metal

Release-window narrowing:

  https://github.com/lcf0399/linux-mm-regression-evidence/tree/acd7fef0e0276ac361971b0960e6611811edf5b3/mprotect-shared-dirty-toggle/bare-metal/20260623-narrow-6.16-6.19-3rounds

v6.17 single-PTE probe:

  https://github.com/lcf0399/linux-mm-regression-evidence/tree/acd7fef0e0276ac361971b0960e6611811edf5b3/mprotect-shared-dirty-toggle/bare-metal/20260624-6.17-singlepte-probe

Probe patch used for that attribution run:

  https://github.com/lcf0399/linux-mm-regression-evidence/blob/acd7fef0e0276ac361971b0960e6611811edf5b3/mprotect-shared-dirty-toggle/bare-metal/20260624-6.17-singlepte-probe/0001-mm-mprotect-probe-6.17-single-pte-hotpath.patch

#regzbot introduced: v6.16..v6.17

Does this scope look useful to investigate further?  If yes, I can try a more
exact commit-level check or test a patch you think is the right direction.

Thanks,
Chengfeng


^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2026-07-22 14:11 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-06-24 17:28 [REGRESSION] mm/mprotect: shared-dirty base-page toggle slower since v6.17 Chengfeng Lin
2026-07-01 10:50 ` Chengfeng Lin
2026-07-21 12:39   ` Chengfeng Lin
2026-07-22  5:48     ` Dev Jain
2026-07-22 10:37       ` Chengfeng Lin
2026-07-22 13:54         ` Dev Jain
2026-07-22 14:11           ` Pedro Falcato

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox