[PATCH v2 5/7] selftest/cgroup: fix zswap test_no_invasive_cgroup_shrink on 64K pagesize system

From: Li Wang

Date: Thu Mar 12 2026 - 00:08:43 EST


The test_no_invasive_cgroup_shrink and allocate_bytes use a hardcoded
stride of 4095 bytes when touching allocated pages. On systems with 64K
page size, this results in writing to the same page multiple times
instead of touching all pages, leading to insufficient memory pressure.

Additionally, the original memory limits and allocation sizes are too
small for 64K page size systems. With only 1M memory.max, there are
very few pages available, and a zswap.max of 10K may not provide enough
room to store even a single compressed page. This can cause OOM kills
or false positives due to insufficient zswap writeback being triggered.

Fix these issues by:
- Using sysconf(_SC_PAGESIZE) instead of the hardcoded 4095 stride in
both allocate_bytes() and test_no_invasive_cgroup_shrink().
- Increasing memory.max to 32M for both wb_group and control_group to
ensure enough pages are available regardless of page size.
- Increasing zswap.max from 10K to 64K and allocation sizes from 10M
to 64M to reliably trigger zswap writeback on all configurations.

=== Error Log ===
# getconf PAGESIZE
65536

# ./test_zswap
TAP version 13
...
ok 5 test_zswap_writeback_disabled
ok 6 # SKIP test_no_kmem_bypass
not ok 7 test_no_invasive_cgroup_shrink

Signed-off-by: Li Wang <liwang@xxxxxxxxxx>
Cc: Johannes Weiner <hannes@xxxxxxxxxxx>
Cc: Michal Hocko <mhocko@xxxxxxxxxx>
Cc: Michal Koutný <mkoutny@xxxxxxxx>
Cc: Muchun Song <muchun.song@xxxxxxxxx>
Cc: Nhat Pham <nphamcs@xxxxxxxxx>
Cc: Tejun Heo <tj@xxxxxxxxxx>
Cc: Roman Gushchin <roman.gushchin@xxxxxxxxx>
Cc: Shakeel Butt <shakeel.butt@xxxxxxxxx>
Cc: Yosry Ahmed <yosryahmed@xxxxxxxxxx>
---
tools/testing/selftests/cgroup/test_zswap.c | 20 ++++++++++++++------
1 file changed, 14 insertions(+), 6 deletions(-)

diff --git a/tools/testing/selftests/cgroup/test_zswap.c b/tools/testing/selftests/cgroup/test_zswap.c
index 032c36658a15..654874fb371b 100644
--- a/tools/testing/selftests/cgroup/test_zswap.c
+++ b/tools/testing/selftests/cgroup/test_zswap.c
@@ -83,12 +83,13 @@ static int allocate_and_read_bytes(const char *cgroup, void *arg)

static int allocate_bytes(const char *cgroup, void *arg)
{
+ long pagesize = sysconf(_SC_PAGESIZE);
size_t size = (size_t)arg;
char *mem = (char *)malloc(size);

if (!mem)
return -1;
- for (int i = 0; i < size; i += 4095)
+ for (int i = 0; i < size; i += pagesize)
mem[i] = 'a';
free(mem);
return 0;
@@ -415,34 +416,41 @@ static int test_zswap_writeback_disabled(const char *root)
static int test_no_invasive_cgroup_shrink(const char *root)
{
int ret = KSFT_FAIL;
- size_t control_allocation_size = MB(10);
+ long pagesize = sysconf(_SC_PAGESIZE);
+ size_t control_allocation_size = MB(64);
char *control_allocation = NULL, *wb_group = NULL, *control_group = NULL;

wb_group = setup_test_group_1M(root, "per_memcg_wb_test1");
if (!wb_group)
return KSFT_FAIL;
- if (cg_write(wb_group, "memory.zswap.max", "10K"))
+ if (cg_write(wb_group, "memory.zswap.max", "64K"))
+ goto out;
+ if (cg_write(wb_group, "memory.max", "32M"))
goto out;
+
control_group = setup_test_group_1M(root, "per_memcg_wb_test2");
if (!control_group)
goto out;
+ if (cg_write(control_group, "memory.max", "32M"))
+ goto out;

/* Push some test_group2 memory into zswap */
if (cg_enter_current(control_group))
goto out;
control_allocation = malloc(control_allocation_size);
- for (int i = 0; i < control_allocation_size; i += 4095)
+ for (int i = 0; i < control_allocation_size; i += pagesize)
control_allocation[i] = 'a';
if (cg_read_key_long(control_group, "memory.stat", "zswapped") < 1)
goto out;

- /* Allocate 10x memory.max to push wb_group memory into zswap and trigger wb */
- if (cg_run(wb_group, allocate_bytes, (void *)MB(10)))
+ /* Allocate 2x memory.max to push wb_group memory into zswap and trigger wb */
+ if (cg_run(wb_group, allocate_bytes, (void *)MB(64)))
goto out;

/* Verify that only zswapped memory from gwb_group has been written back */
if (get_cg_wb_count(wb_group) > 0 && get_cg_wb_count(control_group) == 0)
ret = KSFT_PASS;
+
out:
cg_enter_current(root);
if (control_group) {
--
2.53.0