From: "Kiryl Shutsemau (Meta)" The race harness's MADV_DONTNEED thread zaps 1..32 pages at a time — never a whole PMD-aligned area, so the empty-table reclaim (CONFIG_PT_RECLAIM), which only engages when a zap spans the full table, never ran against a collapse in any soak. Fuzzing had to find the resulting class instead: the table vanishing between the engine's park and install passes. Make the thread zap a whole PMD-aligned area once every 64 iterations, keeping the fine-grained zaps as the common case. Assisted-by: Claude-Code:claude-opus-5 Signed-off-by: Kiryl Shutsemau (Meta) --- tools/testing/selftests/mm/khugepaged_race.c | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/tools/testing/selftests/mm/khugepaged_race.c b/tools/testing/selftests/mm/khugepaged_race.c index 304c72b4ee3c..2aa45c9e8a77 100644 --- a/tools/testing/selftests/mm/khugepaged_race.c +++ b/tools/testing/selftests/mm/khugepaged_race.c @@ -124,8 +124,23 @@ 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, 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 a table + * out from under a parked collapse — 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, + nr * page_size, MADV_DONTNEED); + } usleep(rand_r(&seed) % 500); } return NULL; -- 2.54.0