[LTP] [PATCH v1] madvise09: Scale cgroup memory/swap limits dynamically with page size

Wei Gao wegao@suse.com
Thu Jul 23 09:53:15 CEST 2026


On systems with 64KB page size (such as ppc64le), the mapped footprint
of PAGES (128) is 128 * 64KB = 8MB. Since the cgroup MEM_LIMIT was
hardcoded to 8MB, there was zero headroom left for the parent's process
overhead, resulting in OOM when trying to fork the memory pressure
process.

This caused the test to enter an infinite "Both children killed,
retrying..." loop.

Fix this by scaling mem_limit and swap_limit dynamically based on the
system page size at runtime. Also add a dynamic swap availability check
in setup() using tst_available_swap() to skip gracefully on machines
lacking sufficient swap space, and define BASE_SWAP_LIMIT for the static
.min_swap_avail check.

Signed-off-by: Wei Gao <wegao@suse.com>
---
 testcases/kernel/syscalls/madvise/madvise09.c | 24 +++++++++++++------
 1 file changed, 17 insertions(+), 7 deletions(-)

diff --git a/testcases/kernel/syscalls/madvise/madvise09.c b/testcases/kernel/syscalls/madvise/madvise09.c
index 5453f9411..567782896 100644
--- a/testcases/kernel/syscalls/madvise/madvise09.c
+++ b/testcases/kernel/syscalls/madvise/madvise09.c
@@ -54,8 +54,10 @@ static int swap_accounting_enabled;
 #define TOUCHED_PAGE1 0
 #define TOUCHED_PAGE2 10
 
-#define MEM_LIMIT (8 * 1024 * 1024)
-#define SWAP_LIMIT (2 * MEM_LIMIT)
+#define BASE_SWAP_LIMIT (16 * 1024 * 1024)
+
+static long mem_limit;
+static long swap_limit;
 
 static void memory_pressure_child(void)
 {
@@ -176,12 +178,12 @@ static void child(void)
 	ptr[TOUCHED_PAGE1 * page_size] = 'b';
 	ptr[TOUCHED_PAGE2 * page_size] = 'b';
 
-	SAFE_CG_PRINTF(tst_cg, "memory.max", "%d", MEM_LIMIT);
-	tst_res(TINFO, "Setting memory.max to %d bytes", MEM_LIMIT);
+	SAFE_CG_PRINTF(tst_cg, "memory.max", "%ld", mem_limit);
+	tst_res(TINFO, "Setting memory.max to %ld bytes", mem_limit);
 
 	if (swap_accounting_enabled) {
-		SAFE_CG_PRINTF(tst_cg, "memory.swap.max", "%d", SWAP_LIMIT);
-		tst_res(TINFO, "Setting memory.swap.max to %d bytes", SWAP_LIMIT);
+		SAFE_CG_PRINTF(tst_cg, "memory.swap.max", "%ld", swap_limit);
+		tst_res(TINFO, "Setting memory.swap.max to %ld bytes", swap_limit);
 	} else {
 		tst_res(TINFO, "memory.swap.max is unavailable, running without SWAP_LIMIT");
 	}
@@ -284,6 +286,14 @@ static void setup(void)
 		tst_res(TINFO, "Swap accounting is disabled");
 
 	page_size = getpagesize();
+
+	mem_limit = 16 * PAGES * page_size;
+	swap_limit = 2 * mem_limit;
+
+	if (tst_available_swap() < swap_limit / 1024) {
+		tst_brk(TCONF, "System needs at least %ldMB free swap to run this test",
+			swap_limit / TST_MB);
+	}
 }
 
 static struct tst_test test = {
@@ -291,6 +301,6 @@ static struct tst_test test = {
 	.test_all = run,
 	.needs_root = 1,
 	.forks_child = 1,
-	.min_swap_avail = SWAP_LIMIT / TST_MB,
+	.min_swap_avail = BASE_SWAP_LIMIT / TST_MB,
 	.needs_cgroup_ctrls = (const char *const []){ "memory", NULL },
 };
-- 
2.54.0



More information about the ltp mailing list