[PATCH v3 18/18] selftests/mm: zap whole PTE tables in the khugepaged race harness
From: Kiryl Shutsemau
Date: Wed Aug 12 2026 - 09:30:36 EST
From: "Kiryl Shutsemau (Meta)" <kas@xxxxxxxxxx>
The harness's MADV_DONTNEED thread zaps 1 to 32 pages at a time, never a
whole PMD-aligned area. Empty-table reclaim (CONFIG_PT_RECLAIM) only
engages when a zap spans a full table, so no soak ever ran it against a
collapse -- fuzzing had to find that class instead: the page table
vanishing between the engine's park and install passes.
Make the thread zap a whole PMD-aligned area once every 64 iterations, and
keep the fine-grained zaps as the common case.
Assisted-by: Claude-Code:claude-opus-5
Tested-by: Muhammad Usama Anjum <usama.anjum@xxxxxxx>
Signed-off-by: Kiryl Shutsemau (Meta) <kas@xxxxxxxxxx>
---
tools/testing/selftests/mm/khugepaged_race.c | 20 ++++++++++++++++++--
1 file changed, 18 insertions(+), 2 deletions(-)
diff --git a/tools/testing/selftests/mm/khugepaged_race.c b/tools/testing/selftests/mm/khugepaged_race.c
index bde36af03e49..3601c030d43e 100644
--- a/tools/testing/selftests/mm/khugepaged_race.c
+++ b/tools/testing/selftests/mm/khugepaged_race.c
@@ -141,8 +141,24 @@ static void *dontneed_fn(void *arg)
unsigned long page_idx = rand_page(&seed);
unsigned long nr = 1UL << (rand_r(&seed) % 6); /* 1..32 pages */
- madvise(region + page_idx * page_size,
- room_from(page_idx, nr) * page_size, MADV_DONTNEED);
+ /*
+ * Once in a while zap a whole PMD-aligned area: only a zap
+ * spanning the full table triggers the empty-table reclaim
+ * (CONFIG_PT_RECLAIM), which can free the table under a
+ * collapse that is midway through it. Sub-table zaps never
+ * reach that path.
+ */
+ if (!(rand_r(&seed) % 64)) {
+ unsigned long area = page_idx /
+ (hpage_pmd_size / page_size);
+
+ madvise(region + area * hpage_pmd_size,
+ hpage_pmd_size, MADV_DONTNEED);
+ } else {
+ madvise(region + page_idx * page_size,
+ room_from(page_idx, nr) * page_size,
+ MADV_DONTNEED);
+ }
usleep(rand_r(&seed) % 500);
}
return NULL;
--
2.54.0