* [PATCH v4 0/7] selftests/cgroup: improve zswap tests robustness and support large page sizes
@ 2026-03-22 6:10 Li Wang
2026-03-22 6:10 ` [PATCH v4 1/7] selftests/cgroup: skip test_zswap if zswap is globally disabled Li Wang
` (7 more replies)
0 siblings, 8 replies; 21+ messages in thread
From: Li Wang @ 2026-03-22 6:10 UTC (permalink / raw)
To: akpm, yosry, yosryahmed, nphamcs, hannes, mhocko, mkoutny,
muchun.song, tj, roman.gushchin, shakeel.butt
Cc: longman, liwang, linux-kselftest, linux-kernel, linux-mm
This patchset aims to fix various spurious failures and improve the overall
robustness of the cgroup zswap selftests.
The primary motivation is to make the tests compatible with architectures
that use non-4K page sizes (such as 64K on ppc64le and arm64). Currently,
the tests rely heavily on hardcoded 4K page sizes and fixed memory limits.
On 64K page size systems, these hardcoded values lead to sub-page granularity
accesses, incorrect page count calculations, and insufficient memory pressure
to trigger zswap writeback, ultimately causing the tests to fail.
Additionally, this series addresses OOM kills occurring in test_swapin_nozswap
by dynamically scaling memory limits, and prevents spurious test failures
when zswap is built into the kernel but globally disabled.
Changes in v4:
Patch 2: Use %zu format specifier when printing pagesize.
Patch 4: Use page_size instead of BUF_SIZE in test_memcontrol.c.
Patch 6: Print the expected swap amount in KB instead of MB.
Tested on v6.12:
across x86_64, aarch64, ppc64le archs.
Li Wang (7):
selftests/cgroup: skip test_zswap if zswap is globally disabled
selftests/cgroup: avoid OOM in test_swapin_nozswap
selftests/cgroup: use runtime page size for zswpin check
selftests/cgroup: rename PAGE_SIZE to BUF_SIZE in cgroup_util
selftests/cgroup: replace hardcoded page size values in test_zswap
selftest/cgroup: fix zswap test_no_invasive_cgroup_shrink on large
pagesize system
selftest/cgroup: fix zswap attempt_writeback() on 64K pagesize system
.../selftests/cgroup/lib/cgroup_util.c | 18 ++---
.../cgroup/lib/include/cgroup_util.h | 4 +-
tools/testing/selftests/cgroup/test_core.c | 2 +-
tools/testing/selftests/cgroup/test_freezer.c | 2 +-
.../selftests/cgroup/test_memcontrol.c | 15 ++--
tools/testing/selftests/cgroup/test_zswap.c | 79 +++++++++++++------
6 files changed, 74 insertions(+), 46 deletions(-)
--
2.53.0
^ permalink raw reply [flat|nested] 21+ messages in thread
* [PATCH v4 1/7] selftests/cgroup: skip test_zswap if zswap is globally disabled
2026-03-22 6:10 [PATCH v4 0/7] selftests/cgroup: improve zswap tests robustness and support large page sizes Li Wang
@ 2026-03-22 6:10 ` Li Wang
2026-03-24 0:13 ` Yosry Ahmed
2026-03-22 6:10 ` [PATCH v4 2/7] selftests/cgroup: avoid OOM in test_swapin_nozswap Li Wang
` (6 subsequent siblings)
7 siblings, 1 reply; 21+ messages in thread
From: Li Wang @ 2026-03-22 6:10 UTC (permalink / raw)
To: akpm, yosry, yosryahmed, nphamcs, hannes, mhocko, mkoutny,
muchun.song, tj, roman.gushchin, shakeel.butt
Cc: longman, liwang, linux-kselftest, linux-kernel, linux-mm
test_zswap currently only checks whether zswap is present by testing
/sys/module/zswap. This misses the runtime global state exposed in
/sys/module/zswap/parameters/enabled.
When zswap is built/loaded but globally disabled, the zswap cgroup
selftests run in an invalid environment and may fail spuriously.
Check the runtime enabled state before running the tests:
- skip if zswap is not configured,
- fail if the enabled knob cannot be read,
- skip if zswap is globally disabled.
Also print a hint in the skip message on how to enable zswap.
Signed-off-by: Li Wang <liwang@redhat.com>
Cc: Johannes Weiner <hannes@cmpxchg.org>
Cc: Michal Hocko <mhocko@kernel.org>
Cc: Michal Koutný <mkoutny@suse.com>
Cc: Muchun Song <muchun.song@linux.dev>
Cc: Nhat Pham <nphamcs@gmail.com>
Cc: Tejun Heo <tj@kernel.org>
Cc: Roman Gushchin <roman.gushchin@linux.dev>
Cc: Shakeel Butt <shakeel.butt@linux.dev>
Cc: Yosry Ahmed <yosryahmed@google.com>
Acked-by: Yosry Ahmed <yosry@kernel.org>
---
Notes:
v4:
- No changes.
v3:
- Replace tri-state zswap_enabled() with check_zswap_enabled() for clearer flow.
- Move skip/fail decisions into the helper instead of branching in main().
- Make read failure reporting more explicit by naming
`/sys/module/zswap/parameters/enabled`.
- Keep skip hint for enabling zswap:
`echo 1 > /sys/module/zswap/parameters/enabled`.
v2:
- remove enable/disable_zswap functions
- skip the test if zswap is not enabled
- reporting fail when zswap_enabled return -1
tools/testing/selftests/cgroup/test_zswap.c | 19 +++++++++++++++----
1 file changed, 15 insertions(+), 4 deletions(-)
diff --git a/tools/testing/selftests/cgroup/test_zswap.c b/tools/testing/selftests/cgroup/test_zswap.c
index 64ebc3f3f203..e69d845d3592 100644
--- a/tools/testing/selftests/cgroup/test_zswap.c
+++ b/tools/testing/selftests/cgroup/test_zswap.c
@@ -589,9 +589,21 @@ struct zswap_test {
};
#undef T
-static bool zswap_configured(void)
+static void check_zswap_enabled(void)
{
- return access("/sys/module/zswap", F_OK) == 0;
+ char value[2];
+
+ if (access("/sys/module/zswap", F_OK))
+ ksft_exit_skip("zswap isn't configured\n");
+
+ if (read_text("/sys/module/zswap/parameters/enabled", value,
+ sizeof(value)) <= 0)
+ ksft_exit_fail_msg("Failed to read "
+ "/sys/module/zswap/parameters/enabled\n");
+
+ if (value[0] == 'N')
+ ksft_exit_skip("zswap is disabled (hint: echo 1 > "
+ "/sys/module/zswap/parameters/enabled)\n");
}
int main(int argc, char **argv)
@@ -604,8 +616,7 @@ int main(int argc, char **argv)
if (cg_find_unified_root(root, sizeof(root), NULL))
ksft_exit_skip("cgroup v2 isn't mounted\n");
- if (!zswap_configured())
- ksft_exit_skip("zswap isn't configured\n");
+ check_zswap_enabled();
/*
* Check that memory controller is available:
--
2.53.0
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH v4 2/7] selftests/cgroup: avoid OOM in test_swapin_nozswap
2026-03-22 6:10 [PATCH v4 0/7] selftests/cgroup: improve zswap tests robustness and support large page sizes Li Wang
2026-03-22 6:10 ` [PATCH v4 1/7] selftests/cgroup: skip test_zswap if zswap is globally disabled Li Wang
@ 2026-03-22 6:10 ` Li Wang
2026-03-22 6:10 ` [PATCH v4 3/7] selftests/cgroup: use runtime page size for zswpin check Li Wang
` (5 subsequent siblings)
7 siblings, 0 replies; 21+ messages in thread
From: Li Wang @ 2026-03-22 6:10 UTC (permalink / raw)
To: akpm, yosry, yosryahmed, nphamcs, hannes, mhocko, mkoutny,
muchun.song, tj, roman.gushchin, shakeel.butt
Cc: longman, liwang, linux-kselftest, linux-kernel, linux-mm
test_swapin_nozswap can hit OOM before reaching its assertions on some
setups. The test currently sets memory.max=8M and then allocates/reads
32M with memory.zswap.max=0, which may over-constrain reclaim and kill
the workload process.
Replace hardcoded sizes with PAGE_SIZE-based values:
- control_allocation_size = PAGE_SIZE * 512
- memory.max = control_allocation_size * 3 / 4
- minimum expected swap = control_allocation_size / 4
This keeps the test pressure model intact (allocate/read beyond memory.max to
force swap-in/out) while making it more robust across different environments.
The test intent is unchanged: confirm that swapping occurs while zswap remains
unused when memory.zswap.max=0.
=== Error Logs ===
# ./test_zswap
TAP version 13
1..7
ok 1 test_zswap_usage
not ok 2 test_swapin_nozswap
...
# dmesg
[271641.879153] test_zswap invoked oom-killer: gfp_mask=0xcc0(GFP_KERNEL), order=0, oom_score_adj=0
[271641.879168] CPU: 1 UID: 0 PID: 177372 Comm: test_zswap Kdump: loaded Not tainted 6.12.0-211.el10.ppc64le #1 VOLUNTARY
[271641.879171] Hardware name: IBM,9009-41A POWER9 (architected) 0x4e0202 0xf000005 of:IBM,FW940.02 (UL940_041) hv:phyp pSeries
[271641.879173] Call Trace:
[271641.879174] [c00000037540f730] [c00000000127ec44] dump_stack_lvl+0x88/0xc4 (unreliable)
[271641.879184] [c00000037540f760] [c0000000005cc594] dump_header+0x5c/0x1e4
[271641.879188] [c00000037540f7e0] [c0000000005cb464] oom_kill_process+0x324/0x3b0
[271641.879192] [c00000037540f860] [c0000000005cbe48] out_of_memory+0x118/0x420
[271641.879196] [c00000037540f8f0] [c00000000070d8ec] mem_cgroup_out_of_memory+0x18c/0x1b0
[271641.879200] [c00000037540f990] [c000000000713888] try_charge_memcg+0x598/0x890
[271641.879204] [c00000037540fa70] [c000000000713dbc] charge_memcg+0x5c/0x110
[271641.879207] [c00000037540faa0] [c0000000007159f8] __mem_cgroup_charge+0x48/0x120
[271641.879211] [c00000037540fae0] [c000000000641914] alloc_anon_folio+0x2b4/0x5a0
[271641.879215] [c00000037540fb60] [c000000000641d58] do_anonymous_page+0x158/0x6b0
[271641.879218] [c00000037540fbd0] [c000000000642f8c] __handle_mm_fault+0x4bc/0x910
[271641.879221] [c00000037540fcf0] [c000000000643500] handle_mm_fault+0x120/0x3c0
[271641.879224] [c00000037540fd40] [c00000000014bba0] ___do_page_fault+0x1c0/0x980
[271641.879228] [c00000037540fdf0] [c00000000014c44c] hash__do_page_fault+0x2c/0xc0
[271641.879232] [c00000037540fe20] [c0000000001565d8] do_hash_fault+0x128/0x1d0
[271641.879236] [c00000037540fe50] [c000000000008be0] data_access_common_virt+0x210/0x220
[271641.879548] Tasks state (memory values in pages):
...
[271641.879550] [ pid ] uid tgid total_vm rss rss_anon rss_file rss_shmem pgtables_bytes swapents oom_score_adj name
[271641.879555] [ 177372] 0 177372 571 0 0 0 0 51200 96 0 test_zswap
[271641.879562] oom-kill:constraint=CONSTRAINT_MEMCG,nodemask=(null),cpuset=/,mems_allowed=0,oom_memcg=/no_zswap_test,task_memcg=/no_zswap_test,task=test_zswap,pid=177372,uid=0
[271641.879578] Memory cgroup out of memory: Killed process 177372 (test_zswap) total-vm:36544kB, anon-rss:0kB, file-rss:0kB, shmem-rss:0kB, UID:0 pgtables:50kB oom_score_adj:0
Signed-off-by: Li Wang <liwang@redhat.com>
Cc: Johannes Weiner <hannes@cmpxchg.org>
Cc: Michal Hocko <mhocko@kernel.org>
Cc: Michal Koutný <mkoutny@suse.com>
Cc: Muchun Song <muchun.song@linux.dev>
Cc: Nhat Pham <nphamcs@gmail.com>
Cc: Tejun Heo <tj@kernel.org>
Cc: Roman Gushchin <roman.gushchin@linux.dev>
Cc: Shakeel Butt <shakeel.butt@linux.dev>
Acked-by: Yosry Ahmed <yosry@kernel.org>
---
Notes:
v4:
- print the expected swap amount in KB but not MB.
v3:
- Replace fixed 8M/32M sizing with PAGE_SIZE-based sizing in
test_swapin_nozswap.
- Set memory.max to 3/4 of workload size to reduce OOM risk while still
forcing reclaim/swap activity.
- Derive minimum swap expectation from workload size (1/4) instead of a
fixed 8M threshold.
v2:
- No change.
tools/testing/selftests/cgroup/test_zswap.c | 17 +++++++++++------
1 file changed, 11 insertions(+), 6 deletions(-)
diff --git a/tools/testing/selftests/cgroup/test_zswap.c b/tools/testing/selftests/cgroup/test_zswap.c
index e69d845d3592..4481db4bc0f6 100644
--- a/tools/testing/selftests/cgroup/test_zswap.c
+++ b/tools/testing/selftests/cgroup/test_zswap.c
@@ -160,21 +160,25 @@ static int test_zswap_usage(const char *root)
static int test_swapin_nozswap(const char *root)
{
int ret = KSFT_FAIL;
- char *test_group;
- long swap_peak, zswpout;
+ char *test_group, mem_max_buf[32];
+ long swap_peak, zswpout, min_swap;
+ size_t control_allocation_size = sysconf(_SC_PAGESIZE) * 512;
+
+ min_swap = control_allocation_size / 4;
+ snprintf(mem_max_buf, sizeof(mem_max_buf), "%zu", control_allocation_size * 3/4);
test_group = cg_name(root, "no_zswap_test");
if (!test_group)
goto out;
if (cg_create(test_group))
goto out;
- if (cg_write(test_group, "memory.max", "8M"))
+ if (cg_write(test_group, "memory.max", mem_max_buf))
goto out;
if (cg_write(test_group, "memory.zswap.max", "0"))
goto out;
/* Allocate and read more than memory.max to trigger swapin */
- if (cg_run(test_group, allocate_and_read_bytes, (void *)MB(32)))
+ if (cg_run(test_group, allocate_and_read_bytes, (void *)control_allocation_size))
goto out;
/* Verify that pages are swapped out, but no zswap happened */
@@ -184,8 +188,9 @@ static int test_swapin_nozswap(const char *root)
goto out;
}
- if (swap_peak < MB(24)) {
- ksft_print_msg("at least 24MB of memory should be swapped out\n");
+ if (swap_peak < min_swap) {
+ ksft_print_msg("at least %ldKB of memory should be swapped out\n",
+ min_swap / 1024);
goto out;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH v4 3/7] selftests/cgroup: use runtime page size for zswpin check
2026-03-22 6:10 [PATCH v4 0/7] selftests/cgroup: improve zswap tests robustness and support large page sizes Li Wang
2026-03-22 6:10 ` [PATCH v4 1/7] selftests/cgroup: skip test_zswap if zswap is globally disabled Li Wang
2026-03-22 6:10 ` [PATCH v4 2/7] selftests/cgroup: avoid OOM in test_swapin_nozswap Li Wang
@ 2026-03-22 6:10 ` Li Wang
2026-03-22 6:10 ` [PATCH v4 4/7] selftests/cgroup: rename PAGE_SIZE to BUF_SIZE in cgroup_util Li Wang
` (4 subsequent siblings)
7 siblings, 0 replies; 21+ messages in thread
From: Li Wang @ 2026-03-22 6:10 UTC (permalink / raw)
To: akpm, yosry, yosryahmed, nphamcs, hannes, mhocko, mkoutny,
muchun.song, tj, roman.gushchin, shakeel.butt
Cc: longman, liwang, linux-kselftest, linux-kernel, linux-mm
test_zswapin compares memory.stat:zswpin (counted in pages) against a
byte threshold converted with PAGE_SIZE. In cgroup selftests, PAGE_SIZE
is hardcoded to 4096, which makes the conversion wrong on systems with
non-4K base pages (e.g. 64K).
As a result, the test requires too many pages to pass and fails
spuriously even when zswap is working.
Use sysconf(_SC_PAGESIZE) for the zswpin threshold conversion so the
check matches the actual system page size.
Signed-off-by: Li Wang <liwang@redhat.com>
Cc: Johannes Weiner <hannes@cmpxchg.org>
Cc: Michal Hocko <mhocko@kernel.org>
Cc: Michal Koutný <mkoutny@suse.com>
Cc: Muchun Song <muchun.song@linux.dev>
Cc: Nhat Pham <nphamcs@gmail.com>
Cc: Tejun Heo <tj@kernel.org>
Cc: Roman Gushchin <roman.gushchin@linux.dev>
Cc: Shakeel Butt <shakeel.butt@linux.dev>
Reviewed-by: Yosry Ahmed <yosry@kernel.org>
---
tools/testing/selftests/cgroup/test_zswap.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tools/testing/selftests/cgroup/test_zswap.c b/tools/testing/selftests/cgroup/test_zswap.c
index 4481db4bc0f6..4982e8c4759c 100644
--- a/tools/testing/selftests/cgroup/test_zswap.c
+++ b/tools/testing/selftests/cgroup/test_zswap.c
@@ -240,7 +240,7 @@ static int test_zswapin(const char *root)
goto out;
}
- if (zswpin < MB(24) / PAGE_SIZE) {
+ if (zswpin < MB(24) / sysconf(_SC_PAGESIZE)) {
ksft_print_msg("at least 24MB should be brought back from zswap\n");
goto out;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH v4 4/7] selftests/cgroup: rename PAGE_SIZE to BUF_SIZE in cgroup_util
2026-03-22 6:10 [PATCH v4 0/7] selftests/cgroup: improve zswap tests robustness and support large page sizes Li Wang
` (2 preceding siblings ...)
2026-03-22 6:10 ` [PATCH v4 3/7] selftests/cgroup: use runtime page size for zswpin check Li Wang
@ 2026-03-22 6:10 ` Li Wang
2026-03-22 6:10 ` [PATCH v4 5/7] selftests/cgroup: replace hardcoded page size values in test_zswap Li Wang
` (3 subsequent siblings)
7 siblings, 0 replies; 21+ messages in thread
From: Li Wang @ 2026-03-22 6:10 UTC (permalink / raw)
To: akpm, yosry, yosryahmed, nphamcs, hannes, mhocko, mkoutny,
muchun.song, tj, roman.gushchin, shakeel.butt
Cc: longman, liwang, linux-kselftest, linux-kernel, linux-mm
The cgroup utility code defines a local PAGE_SIZE macro hardcoded to
4096, which is used solely as a generic buffer size for reading cgroup
and proc files. This is misleading because the value has nothing to do
with the actual page size of the system, and on architectures with
larger pages (e.g., 64K on arm64 or ppc64) the name suggests a
relationship that does not exist.
Additionally, the name can shadow or conflict with the PAGE_SIZE
definition from system headers, leading to confusion or subtle bugs.
Rename it to BUF_SIZE to accurately reflect its purpose as a general
I/O buffer size. No functional change.
Signed-off-by: Li Wang <liwang@redhat.com>
Cc: Johannes Weiner <hannes@cmpxchg.org>
Cc: Michal Hocko <mhocko@kernel.org>
Cc: Michal Koutný <mkoutny@suse.com>
Cc: Muchun Song <muchun.song@linux.dev>
Cc: Nhat Pham <nphamcs@gmail.com>
Cc: Tejun Heo <tj@kernel.org>
Cc: Roman Gushchin <roman.gushchin@linux.dev>
Cc: Shakeel Butt <shakeel.butt@linux.dev>
Cc: Yosry Ahmed <yosryahmed@google.com>
---
Notes:
v4:
- Use page_size instead of BUF_SIZE in test_memcontrol.c
v3, v2, v1:
- No changes.
.../testing/selftests/cgroup/lib/cgroup_util.c | 18 +++++++++---------
.../selftests/cgroup/lib/include/cgroup_util.h | 4 ++--
tools/testing/selftests/cgroup/test_core.c | 2 +-
tools/testing/selftests/cgroup/test_freezer.c | 2 +-
.../testing/selftests/cgroup/test_memcontrol.c | 15 ++++++++-------
5 files changed, 21 insertions(+), 20 deletions(-)
diff --git a/tools/testing/selftests/cgroup/lib/cgroup_util.c b/tools/testing/selftests/cgroup/lib/cgroup_util.c
index ce6c2642fd9b..0be525ed11db 100644
--- a/tools/testing/selftests/cgroup/lib/cgroup_util.c
+++ b/tools/testing/selftests/cgroup/lib/cgroup_util.c
@@ -125,7 +125,7 @@ int cg_read_strcmp(const char *cgroup, const char *control,
int cg_read_strstr(const char *cgroup, const char *control, const char *needle)
{
- char buf[PAGE_SIZE];
+ char buf[BUF_SIZE];
if (cg_read(cgroup, control, buf, sizeof(buf)))
return -1;
@@ -155,7 +155,7 @@ long cg_read_long_fd(int fd)
long cg_read_key_long(const char *cgroup, const char *control, const char *key)
{
- char buf[PAGE_SIZE];
+ char buf[BUF_SIZE];
char *ptr;
if (cg_read(cgroup, control, buf, sizeof(buf)))
@@ -191,7 +191,7 @@ long cg_read_key_long_poll(const char *cgroup, const char *control,
long cg_read_lc(const char *cgroup, const char *control)
{
- char buf[PAGE_SIZE];
+ char buf[BUF_SIZE];
const char delim[] = "\n";
char *line;
long cnt = 0;
@@ -243,7 +243,7 @@ int cg_write_numeric(const char *cgroup, const char *control, long value)
static int cg_find_root(char *root, size_t len, const char *controller,
bool *nsdelegate)
{
- char buf[10 * PAGE_SIZE];
+ char buf[10 * BUF_SIZE];
char *fs, *mount, *type, *options;
const char delim[] = "\n\t ";
@@ -298,7 +298,7 @@ int cg_create(const char *cgroup)
int cg_wait_for_proc_count(const char *cgroup, int count)
{
- char buf[10 * PAGE_SIZE] = {0};
+ char buf[10 * BUF_SIZE] = {0};
int attempts;
char *ptr;
@@ -323,7 +323,7 @@ int cg_wait_for_proc_count(const char *cgroup, int count)
int cg_killall(const char *cgroup)
{
- char buf[PAGE_SIZE];
+ char buf[BUF_SIZE];
char *ptr = buf;
/* If cgroup.kill exists use it. */
@@ -533,7 +533,7 @@ int cg_run_nowait(const char *cgroup,
int proc_mount_contains(const char *option)
{
- char buf[4 * PAGE_SIZE];
+ char buf[4 * BUF_SIZE];
ssize_t read;
read = read_text("/proc/mounts", buf, sizeof(buf));
@@ -545,7 +545,7 @@ int proc_mount_contains(const char *option)
int cgroup_feature(const char *feature)
{
- char buf[PAGE_SIZE];
+ char buf[BUF_SIZE];
ssize_t read;
read = read_text("/sys/kernel/cgroup/features", buf, sizeof(buf));
@@ -572,7 +572,7 @@ ssize_t proc_read_text(int pid, bool thread, const char *item, char *buf, size_t
int proc_read_strstr(int pid, bool thread, const char *item, const char *needle)
{
- char buf[PAGE_SIZE];
+ char buf[BUF_SIZE];
if (proc_read_text(pid, thread, item, buf, sizeof(buf)) < 0)
return -1;
diff --git a/tools/testing/selftests/cgroup/lib/include/cgroup_util.h b/tools/testing/selftests/cgroup/lib/include/cgroup_util.h
index 77f386dab5e8..ca4a161c17a4 100644
--- a/tools/testing/selftests/cgroup/lib/include/cgroup_util.h
+++ b/tools/testing/selftests/cgroup/lib/include/cgroup_util.h
@@ -2,8 +2,8 @@
#include <stdbool.h>
#include <stdlib.h>
-#ifndef PAGE_SIZE
-#define PAGE_SIZE 4096
+#ifndef BUF_SIZE
+#define BUF_SIZE 4096
#endif
#define MB(x) (x << 20)
diff --git a/tools/testing/selftests/cgroup/test_core.c b/tools/testing/selftests/cgroup/test_core.c
index 102262555a59..df7fac7e5554 100644
--- a/tools/testing/selftests/cgroup/test_core.c
+++ b/tools/testing/selftests/cgroup/test_core.c
@@ -87,7 +87,7 @@ static int test_cgcore_destroy(const char *root)
int ret = KSFT_FAIL;
char *cg_test = NULL;
int child_pid;
- char buf[PAGE_SIZE];
+ char buf[BUF_SIZE];
cg_test = cg_name(root, "cg_test");
diff --git a/tools/testing/selftests/cgroup/test_freezer.c b/tools/testing/selftests/cgroup/test_freezer.c
index 97fae92c8387..160a9e6ad277 100644
--- a/tools/testing/selftests/cgroup/test_freezer.c
+++ b/tools/testing/selftests/cgroup/test_freezer.c
@@ -642,7 +642,7 @@ static int test_cgfreezer_ptrace(const char *root)
*/
static int proc_check_stopped(int pid)
{
- char buf[PAGE_SIZE];
+ char buf[BUF_SIZE];
int len;
len = proc_read_text(pid, 0, "stat", buf, sizeof(buf));
diff --git a/tools/testing/selftests/cgroup/test_memcontrol.c b/tools/testing/selftests/cgroup/test_memcontrol.c
index 2fb096a2a9f9..2a8d887a849f 100644
--- a/tools/testing/selftests/cgroup/test_memcontrol.c
+++ b/tools/testing/selftests/cgroup/test_memcontrol.c
@@ -33,7 +33,7 @@ int get_temp_fd(void)
int alloc_pagecache(int fd, size_t size)
{
- char buf[PAGE_SIZE];
+ char buf[BUF_SIZE];
struct stat st;
int i;
@@ -57,10 +57,11 @@ int alloc_pagecache(int fd, size_t size)
int alloc_anon(const char *cgroup, void *arg)
{
size_t size = (unsigned long)arg;
+ size_t page_size = sysconf(_SC_PAGESIZE);
char *buf, *ptr;
buf = malloc(size);
- for (ptr = buf; ptr < buf + size; ptr += PAGE_SIZE)
+ for (ptr = buf; ptr < buf + size; ptr += page_size)
*ptr = 0;
free(buf);
@@ -69,7 +70,7 @@ int alloc_anon(const char *cgroup, void *arg)
int is_swap_enabled(void)
{
- char buf[PAGE_SIZE];
+ char buf[BUF_SIZE];
const char delim[] = "\n";
int cnt = 0;
char *line;
@@ -112,7 +113,7 @@ static int test_memcg_subtree_control(const char *root)
{
char *parent, *child, *parent2 = NULL, *child2 = NULL;
int ret = KSFT_FAIL;
- char buf[PAGE_SIZE];
+ char buf[BUF_SIZE];
/* Create two nested cgroups with the memory controller enabled */
parent = cg_name(root, "memcg_test_0");
@@ -183,7 +184,7 @@ static int alloc_anon_50M_check(const char *cgroup, void *arg)
return -1;
}
- for (ptr = buf; ptr < buf + size; ptr += PAGE_SIZE)
+ for (ptr = buf; ptr < buf + size; ptr += BUF_SIZE)
*ptr = 0;
current = cg_read_long(cgroup, "memory.current");
@@ -413,7 +414,7 @@ static int alloc_anon_noexit(const char *cgroup, void *arg)
return -1;
}
- for (ptr = buf; ptr < buf + size; ptr += PAGE_SIZE)
+ for (ptr = buf; ptr < buf + size; ptr += BUF_SIZE)
*ptr = 0;
while (getppid() == ppid)
@@ -999,7 +1000,7 @@ static int alloc_anon_50M_check_swap(const char *cgroup, void *arg)
return -1;
}
- for (ptr = buf; ptr < buf + size; ptr += PAGE_SIZE)
+ for (ptr = buf; ptr < buf + size; ptr += BUF_SIZE)
*ptr = 0;
mem_current = cg_read_long(cgroup, "memory.current");
--
2.53.0
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH v4 5/7] selftests/cgroup: replace hardcoded page size values in test_zswap
2026-03-22 6:10 [PATCH v4 0/7] selftests/cgroup: improve zswap tests robustness and support large page sizes Li Wang
` (3 preceding siblings ...)
2026-03-22 6:10 ` [PATCH v4 4/7] selftests/cgroup: rename PAGE_SIZE to BUF_SIZE in cgroup_util Li Wang
@ 2026-03-22 6:10 ` Li Wang
2026-03-24 0:05 ` Yosry Ahmed
2026-03-22 6:10 ` [PATCH v4 6/7] selftest/cgroup: fix zswap test_no_invasive_cgroup_shrink on large pagesize system Li Wang
` (2 subsequent siblings)
7 siblings, 1 reply; 21+ messages in thread
From: Li Wang @ 2026-03-22 6:10 UTC (permalink / raw)
To: akpm, yosry, yosryahmed, nphamcs, hannes, mhocko, mkoutny,
muchun.song, tj, roman.gushchin, shakeel.butt
Cc: longman, liwang, linux-kselftest, linux-kernel, linux-mm
test_zswap uses hardcoded values of 4095 and 4096 throughout as page
stride and page size, which are only correct on systems with a 4K page
size. On architectures with larger pages (e.g., 64K on arm64 or ppc64),
these constants cause memory to be touched at sub-page granularity,
leading to inefficient access patterns and incorrect page count
calculations, which can cause test failures.
Replace all hardcoded 4095 and 4096 values with a global pagesize
variable initialized from sysconf(_SC_PAGESIZE) at startup, and remove
the redundant local sysconf() calls scattered across individual
functions. No functional change on 4K page size systems.
Signed-off-by: Li Wang <liwang@redhat.com>
Cc: Johannes Weiner <hannes@cmpxchg.org>
Cc: Michal Hocko <mhocko@kernel.org>
Cc: Michal Koutný <mkoutny@suse.com>
Cc: Muchun Song <muchun.song@linux.dev>
Cc: Nhat Pham <nphamcs@gmail.com>
Cc: Tejun Heo <tj@kernel.org>
Cc: Roman Gushchin <roman.gushchin@linux.dev>
Cc: Shakeel Butt <shakeel.butt@linux.dev>
Cc: Yosry Ahmed <yosryahmed@google.com>
---
tools/testing/selftests/cgroup/test_zswap.c | 22 +++++++++++----------
1 file changed, 12 insertions(+), 10 deletions(-)
diff --git a/tools/testing/selftests/cgroup/test_zswap.c b/tools/testing/selftests/cgroup/test_zswap.c
index 4982e8c4759c..407cfb6ae34d 100644
--- a/tools/testing/selftests/cgroup/test_zswap.c
+++ b/tools/testing/selftests/cgroup/test_zswap.c
@@ -13,6 +13,8 @@
#include "kselftest.h"
#include "cgroup_util.h"
+static size_t pagesize;
+
static int read_int(const char *path, size_t *value)
{
FILE *file;
@@ -68,11 +70,11 @@ static int allocate_and_read_bytes(const char *cgroup, void *arg)
if (!mem)
return -1;
- for (int i = 0; i < size; i += 4095)
+ for (int i = 0; i < size; i += pagesize)
mem[i] = 'a';
/* Go through the allocated memory to (z)swap in and out pages */
- for (int i = 0; i < size; i += 4095) {
+ for (int i = 0; i < size; i += pagesize) {
if (mem[i] != 'a')
ret = -1;
}
@@ -88,7 +90,7 @@ static int allocate_bytes(const char *cgroup, void *arg)
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;
@@ -267,7 +269,6 @@ static int test_zswapin(const char *root)
*/
static int attempt_writeback(const char *cgroup, void *arg)
{
- long pagesize = sysconf(_SC_PAGESIZE);
size_t memsize = MB(4);
char buf[pagesize];
long zswap_usage;
@@ -436,7 +437,7 @@ static int test_no_invasive_cgroup_shrink(const char *root)
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;
@@ -476,7 +477,7 @@ static int no_kmem_bypass_child(const char *cgroup, void *arg)
values->child_allocated = true;
return -1;
}
- for (long i = 0; i < values->target_alloc_bytes; i += 4095)
+ for (long i = 0; i < values->target_alloc_bytes; i += pagesize)
((char *)allocation)[i] = 'a';
values->child_allocated = true;
pause();
@@ -524,7 +525,7 @@ static int test_no_kmem_bypass(const char *root)
min_free_kb_low = sys_info.totalram / 500000;
values->target_alloc_bytes = (sys_info.totalram - min_free_kb_high * 1000) +
sys_info.totalram * 5 / 100;
- stored_pages_threshold = sys_info.totalram / 5 / 4096;
+ stored_pages_threshold = sys_info.totalram / 5 / pagesize;
trigger_allocation_size = sys_info.totalram / 20;
/* Set up test memcg */
@@ -551,7 +552,7 @@ static int test_no_kmem_bypass(const char *root)
if (!trigger_allocation)
break;
- for (int i = 0; i < trigger_allocation_size; i += 4095)
+ for (int i = 0; i < trigger_allocation_size; i += pagesize)
trigger_allocation[i] = 'b';
usleep(100000);
free(trigger_allocation);
@@ -562,8 +563,8 @@ static int test_no_kmem_bypass(const char *root)
/* If memory was pushed to zswap, verify it belongs to memcg */
if (stored_pages > stored_pages_threshold) {
int zswapped = cg_read_key_long(test_group, "memory.stat", "zswapped ");
- int delta = stored_pages * 4096 - zswapped;
- int result_ok = delta < stored_pages * 4096 / 4;
+ int delta = stored_pages * pagesize - zswapped;
+ int result_ok = delta < stored_pages * pagesize / 4;
ret = result_ok ? KSFT_PASS : KSFT_FAIL;
break;
@@ -616,6 +617,7 @@ int main(int argc, char **argv)
char root[PATH_MAX];
int i;
+ pagesize = sysconf(_SC_PAGESIZE);
ksft_print_header();
ksft_set_plan(ARRAY_SIZE(tests));
if (cg_find_unified_root(root, sizeof(root), NULL))
--
2.53.0
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH v4 6/7] selftest/cgroup: fix zswap test_no_invasive_cgroup_shrink on large pagesize system
2026-03-22 6:10 [PATCH v4 0/7] selftests/cgroup: improve zswap tests robustness and support large page sizes Li Wang
` (4 preceding siblings ...)
2026-03-22 6:10 ` [PATCH v4 5/7] selftests/cgroup: replace hardcoded page size values in test_zswap Li Wang
@ 2026-03-22 6:10 ` Li Wang
2026-03-22 6:10 ` [PATCH v4 7/7] selftest/cgroup: fix zswap attempt_writeback() on 64K " Li Wang
2026-03-22 16:18 ` [PATCH v4 0/7] selftests/cgroup: improve zswap tests robustness and support large page sizes Andrew Morton
7 siblings, 0 replies; 21+ messages in thread
From: Li Wang @ 2026-03-22 6:10 UTC (permalink / raw)
To: akpm, yosry, yosryahmed, nphamcs, hannes, mhocko, mkoutny,
muchun.song, tj, roman.gushchin, shakeel.butt
Cc: longman, liwang, linux-kselftest, linux-kernel, linux-mm
test_no_invasive_cgroup_shrink uses fixed zswap/memory limits and
allocation sizes that are too small on systems with large PAGE_SIZE
(e.g. 64K). In that case, the test may fail to build enough pressure
to trigger zswap writeback reliably, leading to false failures.
Make the test size parameters PAGE_SIZE-aware and consistent:
- set control_allocation_size to PAGE_SIZE * 1024,
- set memory.zswap.max to PAGE_SIZE,
- set memory.max of both cgroups to control_allocation_size / 2,
- allocate control_allocation_size in wb_group (2x memory.max).
This keeps the test behavior stable across 4K and 64K PAGE_SIZE
configurations and avoids spurious failures in
test_no_invasive_cgroup_shrink.
=== 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@redhat.com>
Cc: Johannes Weiner <hannes@cmpxchg.org>
Cc: Michal Hocko <mhocko@kernel.org>
Cc: Michal Koutný <mkoutny@suse.com>
Cc: Muchun Song <muchun.song@linux.dev>
Cc: Nhat Pham <nphamcs@gmail.com>
Cc: Tejun Heo <tj@kernel.org>
Cc: Roman Gushchin <roman.gushchin@linux.dev>
Cc: Shakeel Butt <shakeel.butt@linux.dev>
Cc: Yosry Ahmed <yosryahmed@google.com>
---
Notes:
v4:
- Use use %zu in print pagesize format.
v3:
- Make PAGE_SIZE aware instead of using fixed sizing.
- Set memory.max for wb_group/control_group to control_allocation_size/2.
- Update wb_group pressure allocation to control_allocation_size.
- Clarify commit message to focus on this test's sizing issue.
v2:
- No change.
tools/testing/selftests/cgroup/test_zswap.c | 17 +++++++++++++----
1 file changed, 13 insertions(+), 4 deletions(-)
diff --git a/tools/testing/selftests/cgroup/test_zswap.c b/tools/testing/selftests/cgroup/test_zswap.c
index 407cfb6ae34d..ec7f0bd515e1 100644
--- a/tools/testing/selftests/cgroup/test_zswap.c
+++ b/tools/testing/selftests/cgroup/test_zswap.c
@@ -421,17 +421,26 @@ 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);
+ size_t control_allocation_size = pagesize * 1024;
+ char zswap_max_buf[32], mem_max_buf[32];
char *control_allocation = NULL, *wb_group = NULL, *control_group = NULL;
+ snprintf(zswap_max_buf, sizeof(zswap_max_buf), "%zu", pagesize);
+ snprintf(mem_max_buf, sizeof(mem_max_buf), "%zu", control_allocation_size / 2);
+
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", zswap_max_buf))
+ goto out;
+ if (cg_write(wb_group, "memory.max", mem_max_buf))
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", mem_max_buf))
+ goto out;
/* Push some test_group2 memory into zswap */
if (cg_enter_current(control_group))
@@ -442,8 +451,8 @@ static int test_no_invasive_cgroup_shrink(const char *root)
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 *)control_allocation_size))
goto out;
/* Verify that only zswapped memory from gwb_group has been written back */
--
2.53.0
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH v4 7/7] selftest/cgroup: fix zswap attempt_writeback() on 64K pagesize system
2026-03-22 6:10 [PATCH v4 0/7] selftests/cgroup: improve zswap tests robustness and support large page sizes Li Wang
` (5 preceding siblings ...)
2026-03-22 6:10 ` [PATCH v4 6/7] selftest/cgroup: fix zswap test_no_invasive_cgroup_shrink on large pagesize system Li Wang
@ 2026-03-22 6:10 ` Li Wang
2026-03-22 16:18 ` [PATCH v4 0/7] selftests/cgroup: improve zswap tests robustness and support large page sizes Andrew Morton
7 siblings, 0 replies; 21+ messages in thread
From: Li Wang @ 2026-03-22 6:10 UTC (permalink / raw)
To: akpm, yosry, yosryahmed, nphamcs, hannes, mhocko, mkoutny,
muchun.song, tj, roman.gushchin, shakeel.butt
Cc: longman, liwang, linux-kselftest, linux-kernel, linux-mm
In attempt_writeback(), a memsize of 4M only covers 64 pages on 64K
page size systems. When memory.reclaim is called, the kernel prefers
reclaiming clean file pages (binary, libc, linker, etc.) over swapping
anonymous pages. With only 64 pages of anonymous memory, the reclaim
target can be largely or entirely satisfied by dropping file pages,
resulting in very few or zero anonymous pages being pushed into zswap.
This causes zswap_usage to be extremely small or zero, making
zswap_usage/2 insufficient to create meaningful writeback pressure.
The test then fails because no writeback is triggered.
On 4K page size systems this is not an issue because 4M covers 1024
pages, and file pages are a small fraction of the reclaim target.
Fix this by always allocating 1024 pages regardless of page size.
This ensures enough anonymous pages to reliably populate zswap and
trigger writeback, while keeping the original 4M allocation on 4K
page size systems.
=== Error Log ===
# uname -rm
6.12.0-211.el10.ppc64le ppc64le
# getconf PAGESIZE
65536
# ./test_zswap
TAP version 13
1..7
ok 1 test_zswap_usage
ok 2 test_swapin_nozswap
ok 3 test_zswapin
not ok 4 test_zswap_writeback_enabled
...
Signed-off-by: Li Wang <liwang@redhat.com>
Cc: Johannes Weiner <hannes@cmpxchg.org>
Cc: Michal Hocko <mhocko@kernel.org>
Cc: Michal Koutný <mkoutny@suse.com>
Cc: Muchun Song <muchun.song@linux.dev>
Cc: Nhat Pham <nphamcs@gmail.com>
Cc: Tejun Heo <tj@kernel.org>
Cc: Roman Gushchin <roman.gushchin@linux.dev>
Cc: Shakeel Butt <shakeel.butt@linux.dev>
Acked-by: Yosry Ahmed <yosry@kernel.org>
---
Notes:
v4, v3:
- No changes.
v2:
- use pagesize * 1024 which clearly shows the page numbers.
tools/testing/selftests/cgroup/test_zswap.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tools/testing/selftests/cgroup/test_zswap.c b/tools/testing/selftests/cgroup/test_zswap.c
index ec7f0bd515e1..107b20db2fec 100644
--- a/tools/testing/selftests/cgroup/test_zswap.c
+++ b/tools/testing/selftests/cgroup/test_zswap.c
@@ -269,7 +269,7 @@ static int test_zswapin(const char *root)
*/
static int attempt_writeback(const char *cgroup, void *arg)
{
- size_t memsize = MB(4);
+ size_t memsize = pagesize * 1024;
char buf[pagesize];
long zswap_usage;
bool wb_enabled = *(bool *) arg;
--
2.53.0
^ permalink raw reply related [flat|nested] 21+ messages in thread
* Re: [PATCH v4 0/7] selftests/cgroup: improve zswap tests robustness and support large page sizes
2026-03-22 6:10 [PATCH v4 0/7] selftests/cgroup: improve zswap tests robustness and support large page sizes Li Wang
` (6 preceding siblings ...)
2026-03-22 6:10 ` [PATCH v4 7/7] selftest/cgroup: fix zswap attempt_writeback() on 64K " Li Wang
@ 2026-03-22 16:18 ` Andrew Morton
2026-03-23 3:23 ` Li Wang
7 siblings, 1 reply; 21+ messages in thread
From: Andrew Morton @ 2026-03-22 16:18 UTC (permalink / raw)
To: Li Wang
Cc: yosry, yosryahmed, nphamcs, hannes, mhocko, mkoutny, muchun.song,
tj, roman.gushchin, shakeel.butt, longman, linux-kselftest,
linux-kernel, linux-mm
On Sun, 22 Mar 2026 14:10:31 +0800 Li Wang <liwang@redhat.com> wrote:
> This patchset aims to fix various spurious failures and improve the overall
> robustness of the cgroup zswap selftests.
AI review has questions:
https://sashiko.dev/#/patchset/20260322061038.156146-1-liwang@redhat.com
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH v4 0/7] selftests/cgroup: improve zswap tests robustness and support large page sizes
2026-03-22 16:18 ` [PATCH v4 0/7] selftests/cgroup: improve zswap tests robustness and support large page sizes Andrew Morton
@ 2026-03-23 3:23 ` Li Wang
2026-03-24 0:12 ` Yosry Ahmed
0 siblings, 1 reply; 21+ messages in thread
From: Li Wang @ 2026-03-23 3:23 UTC (permalink / raw)
To: Andrew Morton, longman
Cc: yosry, yosryahmed, nphamcs, hannes, mhocko, mkoutny, muchun.song,
tj, roman.gushchin, shakeel.butt, linux-kselftest, linux-kernel,
linux-mm
On Sun, Mar 22, 2026 at 09:18:51AM -0700, Andrew Morton wrote:
> On Sun, 22 Mar 2026 14:10:31 +0800 Li Wang <liwang@redhat.com> wrote:
>
> > This patchset aims to fix various spurious failures and improve the overall
> > robustness of the cgroup zswap selftests.
>
> AI review has questions:
> https://sashiko.dev/#/patchset/20260322061038.156146-1-liwang@redhat.com
> [Sashiko comments in patch 4/7]
> ...
> Could we update this loop, along with the identical loops in
> alloc_anon_noexit() and alloc_anon_50M_check_swap() shown below, to use
> sysconf(_SC_PAGESIZE) instead?
I found that Waiman submit another patch that do same thing like this
suggestion. I'd consider to merge that one into my patch 4/7.
So, let me talk to Waiman first.
> [Sashiko comments in patch 5/7]
> ..
> if (zswpin < MB(24) / sysconf(_SC_PAGESIZE)) {
> Should these also be updated to use the new global pagesize variable for
> consistency? Subsequent patches in the series do not seem to correct this
> omission.
Good catch, that remainds should be corrected too.
> If control_allocation is NULL, wouldn't the loop immediately dereference it
> and cause an unhandled segmentation fault rather than a graceful test
> failure?
That's right, but better to be resolved in another series, not this one.
> However, there does not appear to be a corresponding munmap() call in the
> test's cleanup path. Although the OS reclaims this memory when the test
> process exits, should this explicit unmap be added for a balanced resource
> lifecycle within the test?
That's right, but better to be resolved in another series, not this one.
> [Sashiko comments in patch 6/7]
> ...
> If malloc returns a null pointer in a memory-constrained environment, the
> loop will unconditionally dereference it. Should there be a null check
> before the loop?
That's right, but better to be resolved in another series, not this one.
> The test data is generated by writing a single 'a' character per page, leaving
> the rest zero-filled:
> for (int i = 0; i < control_allocation_size; i += pagesize)
> control_allocation[i] = 'a';
> This makes the data highly compressible. Because memory.max is set to half of
> control_allocation_size, 512 pages are pushed into zswap.
> 512 pages of mostly zeros can compress down to roughly 11 to 15 kilobytes
> using compressors like zstd, which is well below the 65536 byte (64k)
> zswap.max limit on a 64k page system.
> Since the limit might not be reached, writeback might never trigger,
> causing the test to falsely fail. Should the test use incompressible data
> or a lower fixed limit?
If Sashiko suggests reducing compressibility, we'd need to fill a significant
fraction of each page with varied data, but that would work against the test:
zswap would reject poorly compressing pages and send them straight to swap,
and memory.stat:zswapped might never reach the threshold the test checks
with cg_read_key_long(..., "zswapped") < 1.
So, at most I'd keep the data highly compressible and just ensure non-zero,
unique-per-page markers.
i.e.
control_allocation[i] = (char)((i / pagesize) + 1);
--
Regards,
Li Wang
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH v4 5/7] selftests/cgroup: replace hardcoded page size values in test_zswap
2026-03-22 6:10 ` [PATCH v4 5/7] selftests/cgroup: replace hardcoded page size values in test_zswap Li Wang
@ 2026-03-24 0:05 ` Yosry Ahmed
0 siblings, 0 replies; 21+ messages in thread
From: Yosry Ahmed @ 2026-03-24 0:05 UTC (permalink / raw)
To: Li Wang
Cc: akpm, yosryahmed, nphamcs, hannes, mhocko, mkoutny, muchun.song,
tj, roman.gushchin, shakeel.butt, longman, linux-kselftest,
linux-kernel, linux-mm
On Sat, Mar 21, 2026 at 11:11 PM Li Wang <liwang@redhat.com> wrote:
>
> test_zswap uses hardcoded values of 4095 and 4096 throughout as page
> stride and page size, which are only correct on systems with a 4K page
> size. On architectures with larger pages (e.g., 64K on arm64 or ppc64),
> these constants cause memory to be touched at sub-page granularity,
> leading to inefficient access patterns and incorrect page count
> calculations, which can cause test failures.
>
> Replace all hardcoded 4095 and 4096 values with a global pagesize
> variable initialized from sysconf(_SC_PAGESIZE) at startup, and remove
> the redundant local sysconf() calls scattered across individual
> functions. No functional change on 4K page size systems.
>
> Signed-off-by: Li Wang <liwang@redhat.com>
> Cc: Johannes Weiner <hannes@cmpxchg.org>
> Cc: Michal Hocko <mhocko@kernel.org>
> Cc: Michal Koutný <mkoutny@suse.com>
> Cc: Muchun Song <muchun.song@linux.dev>
> Cc: Nhat Pham <nphamcs@gmail.com>
> Cc: Tejun Heo <tj@kernel.org>
> Cc: Roman Gushchin <roman.gushchin@linux.dev>
> Cc: Shakeel Butt <shakeel.butt@linux.dev>
> Cc: Yosry Ahmed <yosryahmed@google.com>
Acked-by: Yosry Ahmed <yosry@kernel.org>
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH v4 0/7] selftests/cgroup: improve zswap tests robustness and support large page sizes
2026-03-23 3:23 ` Li Wang
@ 2026-03-24 0:12 ` Yosry Ahmed
2026-03-24 12:16 ` Li Wang
0 siblings, 1 reply; 21+ messages in thread
From: Yosry Ahmed @ 2026-03-24 0:12 UTC (permalink / raw)
To: Li Wang
Cc: Andrew Morton, longman, yosryahmed, nphamcs, hannes, mhocko,
mkoutny, muchun.song, tj, roman.gushchin, shakeel.butt,
linux-kselftest, linux-kernel, linux-mm
On Sun, Mar 22, 2026 at 8:23 PM Li Wang <liwang@redhat.com> wrote:
>
> On Sun, Mar 22, 2026 at 09:18:51AM -0700, Andrew Morton wrote:
> > On Sun, 22 Mar 2026 14:10:31 +0800 Li Wang <liwang@redhat.com> wrote:
> >
> > > This patchset aims to fix various spurious failures and improve the overall
> > > robustness of the cgroup zswap selftests.
> >
> > AI review has questions:
> > https://sashiko.dev/#/patchset/20260322061038.156146-1-liwang@redhat.com
>
> > [Sashiko comments in patch 4/7]
> > ...
> > Could we update this loop, along with the identical loops in
> > alloc_anon_noexit() and alloc_anon_50M_check_swap() shown below, to use
> > sysconf(_SC_PAGESIZE) instead?
>
> I found that Waiman submit another patch that do same thing like this
> suggestion. I'd consider to merge that one into my patch 4/7.
>
> So, let me talk to Waiman first.
Probably fits better in your patch.
> > The test data is generated by writing a single 'a' character per page, leaving
> > the rest zero-filled:
>
> > for (int i = 0; i < control_allocation_size; i += pagesize)
> > control_allocation[i] = 'a';
>
> > This makes the data highly compressible. Because memory.max is set to half of
> > control_allocation_size, 512 pages are pushed into zswap.
>
> > 512 pages of mostly zeros can compress down to roughly 11 to 15 kilobytes
> > using compressors like zstd, which is well below the 65536 byte (64k)
> > zswap.max limit on a 64k page system.
>
> > Since the limit might not be reached, writeback might never trigger,
> > causing the test to falsely fail. Should the test use incompressible data
> > or a lower fixed limit?
>
> If Sashiko suggests reducing compressibility, we'd need to fill a significant
> fraction of each page with varied data, but that would work against the test:
>
> zswap would reject poorly compressing pages and send them straight to swap,
> and memory.stat:zswapped might never reach the threshold the test checks
> with cg_read_key_long(..., "zswapped") < 1.
>
> So, at most I'd keep the data highly compressible and just ensure non-zero,
> unique-per-page markers.
Sashiko claims that 512 pages will end up consuming 11K to 15K in
zswap with this setup, do you know what the actual number is?
Especially with different compressors? If it's close to 64K, this
might be a problem.
Maybe we can fill half of each page with increasing values? It should
still be compressible but not too compressible.
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH v4 1/7] selftests/cgroup: skip test_zswap if zswap is globally disabled
2026-03-22 6:10 ` [PATCH v4 1/7] selftests/cgroup: skip test_zswap if zswap is globally disabled Li Wang
@ 2026-03-24 0:13 ` Yosry Ahmed
2026-03-24 6:46 ` Li Wang
0 siblings, 1 reply; 21+ messages in thread
From: Yosry Ahmed @ 2026-03-24 0:13 UTC (permalink / raw)
To: Li Wang
Cc: akpm, yosryahmed, nphamcs, hannes, mhocko, mkoutny, muchun.song,
tj, roman.gushchin, shakeel.butt, longman, linux-kselftest,
linux-kernel, linux-mm
> diff --git a/tools/testing/selftests/cgroup/test_zswap.c b/tools/testing/selftests/cgroup/test_zswap.c
> index 64ebc3f3f203..e69d845d3592 100644
> --- a/tools/testing/selftests/cgroup/test_zswap.c
> +++ b/tools/testing/selftests/cgroup/test_zswap.c
> @@ -589,9 +589,21 @@ struct zswap_test {
> };
> #undef T
>
> -static bool zswap_configured(void)
> +static void check_zswap_enabled(void)
> {
> - return access("/sys/module/zswap", F_OK) == 0;
> + char value[2];
> +
> + if (access("/sys/module/zswap", F_OK))
> + ksft_exit_skip("zswap isn't configured\n");
> +
> + if (read_text("/sys/module/zswap/parameters/enabled", value,
> + sizeof(value)) <= 0)
> + ksft_exit_fail_msg("Failed to read "
> + "/sys/module/zswap/parameters/enabled\n");
> +
> + if (value[0] == 'N')
> + ksft_exit_skip("zswap is disabled (hint: echo 1 > "
> + "/sys/module/zswap/parameters/enabled)\n");
> }
In the next version please put "/sys/module/zswap" and
"/sys/module/zswap/parameters/enabled" in macros to avoid all the line
breaks here.
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH v4 1/7] selftests/cgroup: skip test_zswap if zswap is globally disabled
2026-03-24 0:13 ` Yosry Ahmed
@ 2026-03-24 6:46 ` Li Wang
0 siblings, 0 replies; 21+ messages in thread
From: Li Wang @ 2026-03-24 6:46 UTC (permalink / raw)
To: Yosry Ahmed
Cc: akpm, yosryahmed, nphamcs, hannes, mhocko, mkoutny, muchun.song,
tj, roman.gushchin, shakeel.butt, longman, linux-kselftest,
linux-kernel, linux-mm
On Mon, Mar 23, 2026 at 05:13:14PM -0700, Yosry Ahmed wrote:
> > diff --git a/tools/testing/selftests/cgroup/test_zswap.c b/tools/testing/selftests/cgroup/test_zswap.c
> > index 64ebc3f3f203..e69d845d3592 100644
> > --- a/tools/testing/selftests/cgroup/test_zswap.c
> > +++ b/tools/testing/selftests/cgroup/test_zswap.c
> > @@ -589,9 +589,21 @@ struct zswap_test {
> > };
> > #undef T
> >
> > -static bool zswap_configured(void)
> > +static void check_zswap_enabled(void)
> > {
> > - return access("/sys/module/zswap", F_OK) == 0;
> > + char value[2];
> > +
> > + if (access("/sys/module/zswap", F_OK))
> > + ksft_exit_skip("zswap isn't configured\n");
> > +
> > + if (read_text("/sys/module/zswap/parameters/enabled", value,
> > + sizeof(value)) <= 0)
> > + ksft_exit_fail_msg("Failed to read "
> > + "/sys/module/zswap/parameters/enabled\n");
> > +
> > + if (value[0] == 'N')
> > + ksft_exit_skip("zswap is disabled (hint: echo 1 > "
> > + "/sys/module/zswap/parameters/enabled)\n");
> > }
>
> In the next version please put "/sys/module/zswap" and
> "/sys/module/zswap/parameters/enabled" in macros to avoid all the line
> breaks here.
Sure, I will. Thanks!
--
Regards,
Li Wang
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH v4 0/7] selftests/cgroup: improve zswap tests robustness and support large page sizes
2026-03-24 0:12 ` Yosry Ahmed
@ 2026-03-24 12:16 ` Li Wang
2026-03-24 20:28 ` Yosry Ahmed
0 siblings, 1 reply; 21+ messages in thread
From: Li Wang @ 2026-03-24 12:16 UTC (permalink / raw)
To: Yosry Ahmed
Cc: Andrew Morton, longman, yosryahmed, nphamcs, hannes, mhocko,
mkoutny, muchun.song, tj, roman.gushchin, shakeel.butt,
linux-kselftest, linux-kernel, linux-mm
On Mon, Mar 23, 2026 at 05:12:27PM -0700, Yosry Ahmed wrote:
> On Sun, Mar 22, 2026 at 8:23 PM Li Wang <liwang@redhat.com> wrote:
> >
> > On Sun, Mar 22, 2026 at 09:18:51AM -0700, Andrew Morton wrote:
> > > On Sun, 22 Mar 2026 14:10:31 +0800 Li Wang <liwang@redhat.com> wrote:
> > >
> > > > This patchset aims to fix various spurious failures and improve the overall
> > > > robustness of the cgroup zswap selftests.
> > >
> > > AI review has questions:
> > > https://sashiko.dev/#/patchset/20260322061038.156146-1-liwang@redhat.com
> >
> > > [Sashiko comments in patch 4/7]
> > > ...
> > > Could we update this loop, along with the identical loops in
> > > alloc_anon_noexit() and alloc_anon_50M_check_swap() shown below, to use
> > > sysconf(_SC_PAGESIZE) instead?
> >
> > I found that Waiman submit another patch that do same thing like this
> > suggestion. I'd consider to merge that one into my patch 4/7.
> >
> > So, let me talk to Waiman first.
>
> Probably fits better in your patch.
>
> > > The test data is generated by writing a single 'a' character per page, leaving
> > > the rest zero-filled:
> >
> > > for (int i = 0; i < control_allocation_size; i += pagesize)
> > > control_allocation[i] = 'a';
> >
> > > This makes the data highly compressible. Because memory.max is set to half of
> > > control_allocation_size, 512 pages are pushed into zswap.
> >
> > > 512 pages of mostly zeros can compress down to roughly 11 to 15 kilobytes
> > > using compressors like zstd, which is well below the 65536 byte (64k)
> > > zswap.max limit on a 64k page system.
> >
> > > Since the limit might not be reached, writeback might never trigger,
> > > causing the test to falsely fail. Should the test use incompressible data
> > > or a lower fixed limit?
> >
> > If Sashiko suggests reducing compressibility, we'd need to fill a significant
> > fraction of each page with varied data, but that would work against the test:
> >
> > zswap would reject poorly compressing pages and send them straight to swap,
> > and memory.stat:zswapped might never reach the threshold the test checks
> > with cg_read_key_long(..., "zswapped") < 1.
> >
> > So, at most I'd keep the data highly compressible and just ensure non-zero,
> > unique-per-page markers.
>
> Sashiko claims that 512 pages will end up consuming 11K to 15K in
> zswap with this setup, do you know what the actual number is?
Not very sure, I guess each 64K page contains 1 byte of 'a' and 65535 bytes
of zero. A single page like that compresses down to roughly 20–30 bytes
(a short literal plus a very long zero run, plus frame/header overhead).
So the estimate is roughly 512 × 25 bytes ≈ 12.8 KB, which is where the
"11 to 15 kilobytes" ballpark comes from.
> Especially with different compressors? If it's close to 64K, this
> might be a problem.
Yes, good point, when I swith to use 'zstd' compressor, it doesn't work.
> Maybe we can fill half of each page with increasing values? It should
> still be compressible but not too compressible.
I tried, this method works on Lzo algorithm but not Zstd.
Anyway, I am still investigating.
--
Regards,
Li Wang
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH v4 0/7] selftests/cgroup: improve zswap tests robustness and support large page sizes
2026-03-24 12:16 ` Li Wang
@ 2026-03-24 20:28 ` Yosry Ahmed
2026-03-25 2:26 ` Li Wang
0 siblings, 1 reply; 21+ messages in thread
From: Yosry Ahmed @ 2026-03-24 20:28 UTC (permalink / raw)
To: Li Wang
Cc: Andrew Morton, longman, yosryahmed, nphamcs, hannes, mhocko,
mkoutny, muchun.song, tj, roman.gushchin, shakeel.butt,
linux-kselftest, linux-kernel, linux-mm
> > Sashiko claims that 512 pages will end up consuming 11K to 15K in
> > zswap with this setup, do you know what the actual number is?
>
> Not very sure, I guess each 64K page contains 1 byte of 'a' and 65535 bytes
> of zero. A single page like that compresses down to roughly 20–30 bytes
> (a short literal plus a very long zero run, plus frame/header overhead).
> So the estimate is roughly 512 × 25 bytes ≈ 12.8 KB, which is where the
> "11 to 15 kilobytes" ballpark comes from.
>
> > Especially with different compressors? If it's close to 64K, this
> > might be a problem.
>
> Yes, good point, when I swith to use 'zstd' compressor, it doesn't work.
>
> > Maybe we can fill half of each page with increasing values? It should
> > still be compressible but not too compressible.
>
> I tried, this method works on Lzo algorithm but not Zstd.
> Anyway, I am still investigating.
Do you mean the compressibility is still very high on zstd? I vaguely
remember filling a page with repeating patterns (e.g. alphabet
letters) seemed to produce a decent compression ratio, but I don't
remember the specifics.
I am pretty sure an LLM could figure out what values will work for
different compression algorithms :)
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH v4 0/7] selftests/cgroup: improve zswap tests robustness and support large page sizes
2026-03-24 20:28 ` Yosry Ahmed
@ 2026-03-25 2:26 ` Li Wang
2026-03-25 2:49 ` Yosry Ahmed
0 siblings, 1 reply; 21+ messages in thread
From: Li Wang @ 2026-03-25 2:26 UTC (permalink / raw)
To: Yosry Ahmed
Cc: Andrew Morton, longman, yosryahmed, nphamcs, hannes, mhocko,
mkoutny, muchun.song, tj, roman.gushchin, shakeel.butt,
linux-kselftest, linux-kernel, linux-mm
On Tue, Mar 24, 2026 at 01:28:12PM -0700, Yosry Ahmed wrote:
> > > Sashiko claims that 512 pages will end up consuming 11K to 15K in
> > > zswap with this setup, do you know what the actual number is?
> >
> > Not very sure, I guess each 64K page contains 1 byte of 'a' and 65535 bytes
> > of zero. A single page like that compresses down to roughly 20–30 bytes
> > (a short literal plus a very long zero run, plus frame/header overhead).
> > So the estimate is roughly 512 × 25 bytes ≈ 12.8 KB, which is where the
> > "11 to 15 kilobytes" ballpark comes from.
> >
> > > Especially with different compressors? If it's close to 64K, this
> > > might be a problem.
> >
> > Yes, good point, when I swith to use 'zstd' compressor, it doesn't work.
> >
> > > Maybe we can fill half of each page with increasing values? It should
> > > still be compressible but not too compressible.
> >
> > I tried, this method works on Lzo algorithm but not Zstd.
> > Anyway, I am still investigating.
>
> Do you mean the compressibility is still very high on zstd? I vaguely
> remember filling a page with repeating patterns (e.g. alphabet
> letters) seemed to produce a decent compression ratio, but I don't
> remember the specifics.
>
> I am pretty sure an LLM could figure out what values will work for
> different compression algorithms :)
Well, I have tried many ways for ditry each page of the total, but none
works on zstd compreseor.
e.g,.
--- a/tools/testing/selftests/cgroup/test_zswap.c
+++ b/tools/testing/selftests/cgroup/test_zswap.c
@@ -9,6 +9,7 @@
#include <string.h>
#include <sys/wait.h>
#include <sys/mman.h>
+#include <sys/random.h>
#include "kselftest.h"
#include "cgroup_util.h"
@@ -473,8 +474,12 @@ static int test_no_invasive_cgroup_shrink(const char *root)
if (cg_enter_current(control_group))
goto out;
control_allocation = malloc(control_allocation_size);
- for (int i = 0; i < control_allocation_size; i += page_size)
- control_allocation[i] = (char)((i / page_size) + 1);
+ unsigned int nr_pages = control_allocation_size/page_size;
+ for (int i = 0; i < nr_pages; i++) {
+ unsigned long off = (unsigned long)i * page_size;
+ memset(&control_allocation[off], 0, page_size);
+ getrandom(&control_allocation[off], nr_pages/2, 0);
+ }
if (cg_read_key_long(control_group, "memory.stat", "zswapped") < 1)
goto out;
Even I tried to set random data for all of the pages, they still not
works (zstd). But it can be worked on lzo compressor, I don't know if
the zstd have any addtional configures or I missed anything there.
My current thought is just to satisfy the lzo (default) compressor in
this patch series, and leave the zstd for additional work.
What do you think? any better idea?
--
Regards,
Li Wang
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH v4 0/7] selftests/cgroup: improve zswap tests robustness and support large page sizes
2026-03-25 2:26 ` Li Wang
@ 2026-03-25 2:49 ` Yosry Ahmed
2026-03-25 6:12 ` Li Wang
0 siblings, 1 reply; 21+ messages in thread
From: Yosry Ahmed @ 2026-03-25 2:49 UTC (permalink / raw)
To: Li Wang
Cc: Andrew Morton, longman, yosryahmed, nphamcs, hannes, mhocko,
mkoutny, muchun.song, tj, roman.gushchin, shakeel.butt,
linux-kselftest, linux-kernel, linux-mm
On Tue, Mar 24, 2026 at 7:26 PM Li Wang <liwang@redhat.com> wrote:
>
> On Tue, Mar 24, 2026 at 01:28:12PM -0700, Yosry Ahmed wrote:
> > > > Sashiko claims that 512 pages will end up consuming 11K to 15K in
> > > > zswap with this setup, do you know what the actual number is?
> > >
> > > Not very sure, I guess each 64K page contains 1 byte of 'a' and 65535 bytes
> > > of zero. A single page like that compresses down to roughly 20–30 bytes
> > > (a short literal plus a very long zero run, plus frame/header overhead).
> > > So the estimate is roughly 512 × 25 bytes ≈ 12.8 KB, which is where the
> > > "11 to 15 kilobytes" ballpark comes from.
> > >
> > > > Especially with different compressors? If it's close to 64K, this
> > > > might be a problem.
> > >
> > > Yes, good point, when I swith to use 'zstd' compressor, it doesn't work.
> > >
> > > > Maybe we can fill half of each page with increasing values? It should
> > > > still be compressible but not too compressible.
> > >
> > > I tried, this method works on Lzo algorithm but not Zstd.
> > > Anyway, I am still investigating.
> >
> > Do you mean the compressibility is still very high on zstd? I vaguely
> > remember filling a page with repeating patterns (e.g. alphabet
> > letters) seemed to produce a decent compression ratio, but I don't
> > remember the specifics.
> >
> > I am pretty sure an LLM could figure out what values will work for
> > different compression algorithms :)
>
> Well, I have tried many ways for ditry each page of the total, but none
> works on zstd compreseor.
>
> e.g,.
>
> --- a/tools/testing/selftests/cgroup/test_zswap.c
> +++ b/tools/testing/selftests/cgroup/test_zswap.c
> @@ -9,6 +9,7 @@
> #include <string.h>
> #include <sys/wait.h>
> #include <sys/mman.h>
> +#include <sys/random.h>
>
> #include "kselftest.h"
> #include "cgroup_util.h"
> @@ -473,8 +474,12 @@ static int test_no_invasive_cgroup_shrink(const char *root)
> if (cg_enter_current(control_group))
> goto out;
> control_allocation = malloc(control_allocation_size);
> - for (int i = 0; i < control_allocation_size; i += page_size)
> - control_allocation[i] = (char)((i / page_size) + 1);
> + unsigned int nr_pages = control_allocation_size/page_size;
> + for (int i = 0; i < nr_pages; i++) {
> + unsigned long off = (unsigned long)i * page_size;
> + memset(&control_allocation[off], 0, page_size);
> + getrandom(&control_allocation[off], nr_pages/2, 0);
This should be page_size/2, right?
nr_pages is 1024 IIUC, so that's 512 bytes only. If the page size is
64K, we're leaving 63.5K (99% of the page) as zeroes.
> + }
> if (cg_read_key_long(control_group, "memory.stat", "zswapped") < 1)
> goto out;
>
> Even I tried to set random data for all of the pages, they still not
> works (zstd). But it can be worked on lzo compressor, I don't know if
> the zstd have any addtional configures or I missed anything there.
>
> My current thought is just to satisfy the lzo (default) compressor in
> this patch series, and leave the zstd for additional work.
>
> What do you think? any better idea?
Let's check if using page_size/2 fixes it first. If a page is 100%
filled with random data it should be incompressible, so I would be
surprised if 50% random data yields a very high compression ratio.
It would also help if you check what the compression ratio actually is
(i.e. compressed_size / uncompressed_size).
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH v4 0/7] selftests/cgroup: improve zswap tests robustness and support large page sizes
2026-03-25 2:49 ` Yosry Ahmed
@ 2026-03-25 6:12 ` Li Wang
2026-03-25 6:17 ` Li Wang
0 siblings, 1 reply; 21+ messages in thread
From: Li Wang @ 2026-03-25 6:12 UTC (permalink / raw)
To: Yosry Ahmed
Cc: Andrew Morton, longman, yosryahmed, nphamcs, hannes, mhocko,
mkoutny, muchun.song, tj, roman.gushchin, shakeel.butt,
linux-kselftest, linux-kernel, linux-mm
On Tue, Mar 24, 2026 at 07:49:17PM -0700, Yosry Ahmed wrote:
> On Tue, Mar 24, 2026 at 7:26 PM Li Wang <liwang@redhat.com> wrote:
> >
> > On Tue, Mar 24, 2026 at 01:28:12PM -0700, Yosry Ahmed wrote:
> > > > > Sashiko claims that 512 pages will end up consuming 11K to 15K in
> > > > > zswap with this setup, do you know what the actual number is?
> > > >
> > > > Not very sure, I guess each 64K page contains 1 byte of 'a' and 65535 bytes
> > > > of zero. A single page like that compresses down to roughly 20–30 bytes
> > > > (a short literal plus a very long zero run, plus frame/header overhead).
> > > > So the estimate is roughly 512 × 25 bytes ≈ 12.8 KB, which is where the
> > > > "11 to 15 kilobytes" ballpark comes from.
> > > >
> > > > > Especially with different compressors? If it's close to 64K, this
> > > > > might be a problem.
> > > >
> > > > Yes, good point, when I swith to use 'zstd' compressor, it doesn't work.
> > > >
> > > > > Maybe we can fill half of each page with increasing values? It should
> > > > > still be compressible but not too compressible.
> > > >
> > > > I tried, this method works on Lzo algorithm but not Zstd.
> > > > Anyway, I am still investigating.
> > >
> > > Do you mean the compressibility is still very high on zstd? I vaguely
> > > remember filling a page with repeating patterns (e.g. alphabet
> > > letters) seemed to produce a decent compression ratio, but I don't
> > > remember the specifics.
> > >
> > > I am pretty sure an LLM could figure out what values will work for
> > > different compression algorithms :)
> >
> > Well, I have tried many ways for ditry each page of the total, but none
> > works on zstd compreseor.
> >
> > e.g,.
> >
> > --- a/tools/testing/selftests/cgroup/test_zswap.c
> > +++ b/tools/testing/selftests/cgroup/test_zswap.c
> > @@ -9,6 +9,7 @@
> > #include <string.h>
> > #include <sys/wait.h>
> > #include <sys/mman.h>
> > +#include <sys/random.h>
> >
> > #include "kselftest.h"
> > #include "cgroup_util.h"
> > @@ -473,8 +474,12 @@ static int test_no_invasive_cgroup_shrink(const char *root)
> > if (cg_enter_current(control_group))
> > goto out;
> > control_allocation = malloc(control_allocation_size);
> > - for (int i = 0; i < control_allocation_size; i += page_size)
> > - control_allocation[i] = (char)((i / page_size) + 1);
> > + unsigned int nr_pages = control_allocation_size/page_size;
> > + for (int i = 0; i < nr_pages; i++) {
> > + unsigned long off = (unsigned long)i * page_size;
> > + memset(&control_allocation[off], 0, page_size);
> > + getrandom(&control_allocation[off], nr_pages/2, 0);
>
> This should be page_size/2, right?
Ah, that's right.
> nr_pages is 1024 IIUC, so that's 512 bytes only. If the page size is
> 64K, we're leaving 63.5K (99% of the page) as zeroes.
nr_pages is 512, but you're right on the analysis.
> > + }
> > if (cg_read_key_long(control_group, "memory.stat", "zswapped") < 1)
> > goto out;
> >
> > Even I tried to set random data for all of the pages, they still not
> > works (zstd). But it can be worked on lzo compressor, I don't know if
> > the zstd have any addtional configures or I missed anything there.
> >
> > My current thought is just to satisfy the lzo (default) compressor in
> > this patch series, and leave the zstd for additional work.
> >
> > What do you think? any better idea?
>
> Let's check if using page_size/2 fixes it first. If a page is 100%
> filled with random data it should be incompressible, so I would be
> surprised if 50% random data yields a very high compression ratio.
>
> It would also help if you check what the compression ratio actually is
> (i.e. compressed_size / uncompressed_size).
Randomly dirty the page_size/2 always led to OOM, so I swith to page_size/4,
it looks like both algorithms compress pages successfully, but zstd doesn't
update 'zswpwb' stat so that test result fails.
Considering that zswap writeback is asynchronous, I additianlly introduced
a polling method for checking 500 times, but 'zswpwb' still returned zero.
==== Test results ====
lzo:
# uncompressed: 51511296, compressed: 13353876, ratio: 0.26
# get_cg_wb_count(wb_group) is 206, get_cg_wb_count(control_group) is 0
ok 7 test_no_invasive_cgroup_shrink
zstd:
# uncompressed: 48037888, compressed: 12019013, ratio: 0.25
# get_cg_wb_count(wb_group) is 0, get_cg_wb_count(control_group) is 0
not ok 7 test_no_invasive_cgroup_shrink
==== debug code for the above output ====
long zswapped = cg_read_key_long(control_group, "memory.stat", "zswapped");
long zswap_compressed = cg_read_key_long(control_group, "memory.stat", "zswap");
ksft_print_msg("uncompressed: %ld, compressed: %ld, ratio: %.2f\n",
zswapped, zswap_compressed,
(double)zswap_compressed / zswapped);
ksft_print_msg("get_cg_wb_count(wb_group) is %zu, get_cg_wb_count(control_group) is %zu\n",
get_cg_wb_count(wb_group),
get_cg_wb_count(control_group));
In summary, the problem is that 'zswpwb' does not update when zswap is executed
under the zstd algorithm. I'd debugging this issue separately from the kernel side.
--
Regards,
Li Wang
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH v4 0/7] selftests/cgroup: improve zswap tests robustness and support large page sizes
2026-03-25 6:12 ` Li Wang
@ 2026-03-25 6:17 ` Li Wang
2026-03-25 7:21 ` Li Wang
0 siblings, 1 reply; 21+ messages in thread
From: Li Wang @ 2026-03-25 6:17 UTC (permalink / raw)
To: Yosry Ahmed
Cc: Andrew Morton, longman, yosryahmed, nphamcs, hannes, mhocko,
mkoutny, muchun.song, tj, roman.gushchin, shakeel.butt,
linux-kselftest, linux-kernel, linux-mm
> In summary, the problem is that 'zswpwb' does not update when zswap is executed
> under the zstd algorithm. I'd debugging this issue separately from the kernel side.
I forgot to mention, this issue only observed on systems with a 64K
pagesize (ppc64le, aarch64). I changed the aarch64 page size to 4K,
and it passed the test every time.
--
Regards,
Li Wang
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH v4 0/7] selftests/cgroup: improve zswap tests robustness and support large page sizes
2026-03-25 6:17 ` Li Wang
@ 2026-03-25 7:21 ` Li Wang
0 siblings, 0 replies; 21+ messages in thread
From: Li Wang @ 2026-03-25 7:21 UTC (permalink / raw)
To: Yosry Ahmed
Cc: Andrew Morton, longman, yosryahmed, nphamcs, hannes, mhocko,
mkoutny, muchun.song, tj, roman.gushchin, shakeel.butt,
linux-kselftest, linux-kernel, linux-mm
On Wed, Mar 25, 2026 at 02:17:42PM +0800, Li Wang wrote:
> > In summary, the problem is that 'zswpwb' does not update when zswap is executed
> > under the zstd algorithm. I'd debugging this issue separately from the kernel side.
Plz ignore above test logs and conclusion.
> I forgot to mention, this issue only observed on systems with a 64K
> pagesize (ppc64le, aarch64). I changed the aarch64 page size to 4K,
> and it passed the test every time.
Well, finally, I think I've found the root cause of the failure of
test_no_invasive_cgroup_shrink.
The test sets up two cgroups:
wb_group, which is expected to trigger zswap writeback,
control_group, which should have pages in zswap but must not experience any writeback.
However, the data patterns used for each group are reversed:
wb_group uses allocate_bytes(), which only writes a single byte per page (mem[i] = 'a').
The rest of each page is effectively zero. This data is trivially compressible,
especially by zstd, so the compressed pages easily fit within zswap.max and writeback
is never triggered.
control_group, on the other hand, uses getrandom() to dirty 1/4 of each page, producing
data that is much harder to compress. Ironically, this is the group that does not need
to trigger writeback.
So the test has the hard-to-compress data in the wrong cgroup. The fix is to swap the
allocation patterns: wb_group should use the partially random data to ensure its
compressed pages exceed zswap.max and trigger writeback, while control_group only
needs simple, easily compressible data to occupy zswap.
I have confirmed this when I reverse the two partens and get all passed
on both lzo and zstd.
Will fix in next patch version.
--
Regards,
Li Wang
^ permalink raw reply [flat|nested] 21+ messages in thread
end of thread, other threads:[~2026-03-25 7:21 UTC | newest]
Thread overview: 21+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-03-22 6:10 [PATCH v4 0/7] selftests/cgroup: improve zswap tests robustness and support large page sizes Li Wang
2026-03-22 6:10 ` [PATCH v4 1/7] selftests/cgroup: skip test_zswap if zswap is globally disabled Li Wang
2026-03-24 0:13 ` Yosry Ahmed
2026-03-24 6:46 ` Li Wang
2026-03-22 6:10 ` [PATCH v4 2/7] selftests/cgroup: avoid OOM in test_swapin_nozswap Li Wang
2026-03-22 6:10 ` [PATCH v4 3/7] selftests/cgroup: use runtime page size for zswpin check Li Wang
2026-03-22 6:10 ` [PATCH v4 4/7] selftests/cgroup: rename PAGE_SIZE to BUF_SIZE in cgroup_util Li Wang
2026-03-22 6:10 ` [PATCH v4 5/7] selftests/cgroup: replace hardcoded page size values in test_zswap Li Wang
2026-03-24 0:05 ` Yosry Ahmed
2026-03-22 6:10 ` [PATCH v4 6/7] selftest/cgroup: fix zswap test_no_invasive_cgroup_shrink on large pagesize system Li Wang
2026-03-22 6:10 ` [PATCH v4 7/7] selftest/cgroup: fix zswap attempt_writeback() on 64K " Li Wang
2026-03-22 16:18 ` [PATCH v4 0/7] selftests/cgroup: improve zswap tests robustness and support large page sizes Andrew Morton
2026-03-23 3:23 ` Li Wang
2026-03-24 0:12 ` Yosry Ahmed
2026-03-24 12:16 ` Li Wang
2026-03-24 20:28 ` Yosry Ahmed
2026-03-25 2:26 ` Li Wang
2026-03-25 2:49 ` Yosry Ahmed
2026-03-25 6:12 ` Li Wang
2026-03-25 6:17 ` Li Wang
2026-03-25 7:21 ` Li Wang
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox