[PATCH v5 00/19] selftests/mm: improve khugepaged coverage

From: Kiryl Shutsemau

Date: Tue Sep 08 2026 - 09:08:52 EST


From: "Kiryl Shutsemau (Meta)" <kas@xxxxxxxxxx>

khugepaged collapses to mTHP orders since 7.2, and 7.3 added three
selftest cases for it: the generic collapse cases run at one order named
by -c, with the result detected by counting folios of that order.

That leaves the collapse path largely untested. The suite does not run
where a PMD is 512M. A folio count cannot say where a collapse landed.
Fixed sleeps cannot tell "not collapsed" from "not scanned yet". And
nothing exercises collapse under contention.

Close those gaps in order:

- Make the suite run at a 512M PMD: scale the collapse wait with the PMD
size, skip what such a PMD cannot serve, make the swapout the swap
cases depend on deterministic, and keep khugepaged out of the
MADV_COLLAPSE cases.

- Detect results per window rather than by count, with folio-order
helpers in vm_util that are checked against the kernel before any
collapse test trusts them.

- Drive khugepaged deterministically: a completion barrier that wakes the
daemon and waits for a full pass, and a check that one pass yields one
attributed collapse.

- Cover collapse at every supported order by default: which window
collapses, occupancy at both limits, sources that are already large
folios, and a fork-shared source under concurrent writes.

- Race collapse against everything that can touch its sources, at both
occupancy limits and over whole-table zaps, checked by content and by
the kernel's own assertions.

Everything passes on an unmodified kernel.

Changes since v4:

- Comments and changelogs rewritten: why, not what (Lorenzo Stoakes,
Mike Rapoport).
- Helper names say what they check, one pass budget across the new
tests, and the review nits taken.
- The raised collapse wait is measured: a passing run costs the same
with either budget.
- Rebased onto mm-unstable; Assisted-by per coding-assistants.rst.

Tested on mm-unstable 20cab322c95c with KASAN, lockdep, DEBUG_VM and
page_table_check, in 16G guests:

x86-64/4K khugepaged all:all 104 pass, 11 skip, 0 fail
arm64/64K khugepaged all:all 102 pass, 3 skip, 0 fail

folio_order_check, khugepaged_sync_check and khugepaged_race pass on both.

The skips are structural: tmpfs cannot host some file cases, and mixed
sources has no order below the smallest. arm64 never registers the file
and shmem contexts, having no PMD-order page cache folio. The default
./khugepaged run there takes about 220 seconds under TCG.

Kiryl Shutsemau (Meta) (19):
selftests/mm: raise the khugepaged test-case cap
selftests/mm: skip collapse_compound_extreme() where the PMD is too
large
selftests/mm: scale khugepaged's collapse wait with the PMD size
selftests/mm: skip khugepaged page cache cases without a PMD folio
selftests/mm: make the swap cases' swapout reliable
selftests/mm: stop khugepaged during the MADV_COLLAPSE cases
selftests/mm: move is_backed_by_folio() into vm_util
selftests/mm: add folio-order check for address ranges
selftests/mm: add folio-order detection self-check
selftests/mm: add khugepaged completion barrier helper
selftests/mm: add order-parameterized khugepaged collapse cases
selftests/mm: parameterize the mixed-source collapse case by source
order
selftests/mm: cover a shared-source collapse write race
selftests/mm: run every supported collapse order by default
selftests/mm: check that one khugepaged pass collapses one window
selftests/mm: add khugepaged race harness
selftests/mm: race the collapse of windows with holes
selftests/mm: add memory-pressure threads to the khugepaged race
harness
selftests/mm: zap whole PTE tables in the khugepaged race harness

tools/testing/selftests/mm/Makefile | 3 +
.../testing/selftests/mm/folio_order_check.c | 122 ++++
tools/testing/selftests/mm/hmm-tests.c | 1 -
.../testing/selftests/mm/hugepage_settings.c | 60 +-
.../testing/selftests/mm/hugepage_settings.h | 11 +
tools/testing/selftests/mm/khugepaged.c | 485 +++++++++++++++-
tools/testing/selftests/mm/khugepaged_race.c | 533 ++++++++++++++++++
.../selftests/mm/khugepaged_sync_check.c | 179 ++++++
tools/testing/selftests/mm/migration.c | 1 -
tools/testing/selftests/mm/run_vmtests.sh | 8 +-
.../selftests/mm/split_huge_page_test.c | 62 --
tools/testing/selftests/mm/vm_util.c | 147 +++++
tools/testing/selftests/mm/vm_util.h | 10 +
13 files changed, 1519 insertions(+), 103 deletions(-)
create mode 100644 tools/testing/selftests/mm/folio_order_check.c
create mode 100644 tools/testing/selftests/mm/khugepaged_race.c
create mode 100644 tools/testing/selftests/mm/khugepaged_sync_check.c


base-commit: 20cab322c95cea0327215bb81a05df69336032dd
--
2.54.0