[PATCH 15/16] selftests/mm: scale khugepaged's collapse wait with the PMD size

Kiryl Shutsemau <[email protected]>
Newsgroups gmane.linux.kernel,gmane.linux.kernel.mm
Message-ID <[email protected]>
From: "Kiryl Shutsemau (Meta)" <[email protected]>

wait_for_scan() gives khugepaged a fixed three seconds, whatever a huge
page costs to build. collapse_full() asks for four of them, which is 8M at
a 2M PMD and 2G at a 512M PMD -- arm64 with 64K base pages -- and three
seconds does not cover copying 2G. The escape hatch does not help either:
it wants two full khugepaged passes inside the same three seconds, and one
pass over a 512M PMD takes about that long by itself.

So collapse_full fails there on a collapse that works. Measured with a
probe that faults 4 x 512M, marks it MADV_HUGEPAGE and polls: all four PMDs
collapse, with collapse_alloc=4 at the PMD size and no allocation
failures. Raising only this budget makes the test pass, and it does not
turn into a "Fail" -- which is what khugepaged completing two passes
without collapsing would produce.

Scale the budget with the memory to be collapsed: keep three seconds as
the floor and add a second per 64M. That leaves a 2M PMD at exactly the
three seconds it has now, and gives 35s at a 512M PMD, where the collapse
measures under 3s. Keying it on nr_hpages * hpage_pmd_size rather than the
PMD size alone matters because the callers ask for one or four; scaling
linearly on PMD size alone would ask for 768s, which is not a budget so
much as a hang.

This also brings the helper in line with khugepaged_full_pass(), which
already allows 30s and is why the order-parameterized cases pass at a 512M
PMD while this one did not.

arm64/64K: khugepaged all:anon 21 pass/1 fail -> 22 pass/0 fail. x86-64
unchanged, 129 ok.

Assisted-by: Claude-Code:claude-opus-5
Signed-off-by: Kiryl Shutsemau (Meta) <[email protected]>
---
 tools/testing/selftests/mm/khugepaged.c | 11 ++++++++++-
 1 file changed, 10 insertions(+), 1 deletion(-)

diff --git a/tools/testing/selftests/mm/khugepaged.c b/tools/testing/selftests/mm/khugepaged.c
index 21a8fb24dc43..9213ce1658d0 100644
--- a/tools/testing/selftests/mm/khugepaged.c
+++ b/tools/testing/selftests/mm/khugepaged.c
@@ -573,8 +573,17 @@ static void madvise_collapse(const char *msg, char *p, int nr_hpages,
 static bool wait_for_scan(const char *msg, char *p, int nr_hpages,
 			  struct mem_ops *ops)
 {
+	/*
+	 * The budget has to cover khugepaged copying nr_hpages *
+	 * hpage_pmd_size, plus two of its passes over the mm. Three seconds
+	 * does that at a 2M PMD, but the same test moves 2G at a 512M PMD
+	 * (arm64 with 64K base pages) and 3s is then marginal: it fails on a
+	 * collapse that completes correctly, just not inside the budget.
+	 * Allow a further second per 64M to collapse.
+	 */
+	const unsigned long bytes = (unsigned long)nr_hpages * hpage_pmd_size;
+	int timeout = 6 + 2 * (bytes / (64UL << 20));
 	int full_scans;
-	int timeout = 6; /* 3 seconds */
 
 	/* Sanity check */
 	if (!ops->check_huge(p, 0))
-- 
2.54.0
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.