From: "Kiryl Shutsemau (Meta)" <[email protected]>

The race harness runs with max_ptes_none=0: strict occupancy keeps
selection honest under racing MADV_DONTNEED and avoids doomed PMD-sized
allocations on 512M-PMD configs. That regime never exercises collapse of
partially populated windows -- every candidate it emits is fully occupied.

Collapsing a window that contains holes is a different path: the hole is
not copied from anywhere, it is zero-filled into the new folio, and the
slot has to be re-checked under the page table lock at install time
because a racing fault may have filled it in the meantime. None of that is
reached at max_ptes_none=0.

Add -z, which selects the other supported end of the occupancy scale
(HPAGE_PMD_NR - 1, scaled per order): selection then emits hole-heavy
windows and those paths take the brunt of the racing faults and zaps.

Also drop the stale claim that max_ptes_none sits "mid-range" from the
header comment; the harness has always pinned it to an end of the scale.

Assisted-by: Claude-Code:claude-opus-5
Signed-off-by: Kiryl Shutsemau (Meta) <[email protected]>
---
 tools/testing/selftests/mm/khugepaged_race.c | 33 ++++++++++++++------
 tools/testing/selftests/mm/run_vmtests.sh    |  2 ++
 2 files changed, 25 insertions(+), 10 deletions(-)

diff --git a/tools/testing/selftests/mm/khugepaged_race.c 
b/tools/testing/selftests/mm/khugepaged_race.c
index b586a114e4cd..2e36e242caa7 100644
--- a/tools/testing/selftests/mm/khugepaged_race.c
+++ b/tools/testing/selftests/mm/khugepaged_race.c
@@ -15,8 +15,12 @@
  *   madvise   MADV_COLLAPSE in a loop — the legacy-PMD regression
  *             axis.
  *
- * All anon THP orders are enabled (inherit) and max_ptes_none is set
- * mid-range, so the MADV_DONTNEED holes steer selection across orders.
+ * All anon THP orders are enabled (inherit). max_ptes_none is 0 by
+ * default — racing MADV_DONTNEED then steers selection across orders —
+ * or the permissive limit with -z, which floods the batch engine with
+ * hole and zeropage slots so the population paths (park-time zeropage
+ * clear, zero-filled copy, install-time pte_none() verify and abort)
+ * race the faulters directly.
  *
  * Correctness signals: every racing page must read as its pattern or
  * zero (MADV_DONTNEED), never anything else — checked continuously by
@@ -196,7 +200,8 @@ static unsigned long now_ms(void)
 static void usage(void)
 {
        fprintf(stderr,
-               "Usage: khugepaged_race [-d seconds] [-m stepped|free|madvise] 
[-a areas]\n"
+               "Usage: khugepaged_race [-d seconds] [-m stepped|free|madvise] 
[-z] [-a areas]\n"
+               "\t-z: permissive max_ptes_none (hole-heavy windows)\n"
                "\t-a: number of shared PMD-sized playground areas (default 
3)\n");
        exit(1);
 }
@@ -219,11 +224,12 @@ int main(int argc, char **argv)
        int duration_s = 10;
        unsigned long thread_mask = ~0UL;
        int nr_areas_arg = 0;
+       bool permissive_none = false;
        unsigned long i;
        int steps = 0;
        int opt;
 
-       while ((opt = getopt(argc, argv, "a:d:m:t:h")) != -1) {
+       while ((opt = getopt(argc, argv, "a:d:m:t:zh")) != -1) {
                switch (opt) {
                case 'a':
                        nr_areas_arg = atoi(optarg);
@@ -238,6 +244,9 @@ int main(int argc, char **argv)
                        /* debug: bitmask of racing threads to start */
                        thread_mask = strtoul(optarg, NULL, 0);
                        break;
+               case 'z':
+                       permissive_none = true;
+                       break;
                default:
                        usage();
                }
@@ -274,13 +283,17 @@ int main(int argc, char **argv)
                strcmp(mode, "free") ? 1000 : 0;
        settings.khugepaged.alloc_sleep_millisecs = 10;
        /*
-        * Strict occupancy: mTHP collapse only supports 0 or
-        * HPAGE_PMD_NR - 1 and coerces anything else to 0 anyway, and 0
-        * also keeps khugepaged from burning the whole step in doomed
-        * PMD-sized allocations on 512M-PMD configs: under racing
-        * MADV_DONTNEED a fully populated PMD area is rare.
+        * mTHP collapse only supports the two ends of the occupancy
+        * scale: 0 or HPAGE_PMD_NR - 1 (anything else coerces to 0).
+        * Strict is the default — it also keeps khugepaged from burning
+        * the whole step in doomed PMD-sized allocations on 512M-PMD
+        * configs, where a fully populated area is rare under racing
+        * MADV_DONTNEED. -z selects the permissive end: selection then
+        * emits hole-heavy windows and the engine's population paths
+        * take the brunt of the racing faults and zaps.
         */
-       settings.khugepaged.max_ptes_none = 0;
+       settings.khugepaged.max_ptes_none = permissive_none ?
+               (hpage_pmd_size / page_size) - 1 : 0;
        settings.khugepaged.pages_to_scan =
                nr_areas * (hpage_pmd_size / page_size) * 8;
        for (i = 0; i < NR_ORDERS; i++) {
diff --git a/tools/testing/selftests/mm/run_vmtests.sh 
b/tools/testing/selftests/mm/run_vmtests.sh
index f61ec76d8e00..83a04b1e2520 100755
--- a/tools/testing/selftests/mm/run_vmtests.sh
+++ b/tools/testing/selftests/mm/run_vmtests.sh
@@ -413,6 +413,8 @@ CATEGORY="thp" run_test ./khugepaged_race -d 5 -m free
 
 CATEGORY="thp" run_test ./khugepaged_race -d 5 -m madvise
 
+CATEGORY="thp" run_test ./khugepaged_race -d 5 -m stepped -z
+
 CATEGORY="thp" run_test ./khugepaged
 
 CATEGORY="thp" run_test ./khugepaged -s 2
-- 
2.54.0


Reply via email to