selftests-cgroup-add-test-for-zswap-incompressible-pages.patch removed from -mm tree
The quilt patch titled
Subject: selftests/cgroup: add test for zswap incompressible pages
has been removed from the -mm tree. Its filename was
selftests-cgroup-add-test-for-zswap-incompressible-pages.patch
This patch was dropped because it was merged into the mm-stable branch of git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm
------------------------------------------------------
From: Jiayuan Chen <[email protected]>
Subject: selftests/cgroup: add test for zswap incompressible pages
Date: Fri, 13 Feb 2026 15:18:23 +0800
Add test_zswap_incompressible() to verify that the zswap_incomp memcg stat correctly tracks incompressible pages.
The test allocates memory filled with random data from /dev/urandom, which cannot be effectively compressed by zswap. When this data is swapped out to zswap, it should be stored as-is and tracked by the zswap_incomp counter.
The test verifies that:
1. Pages are swapped out to zswap (zswpout increases)
2. Incompressible pages are tracked (zswap_incomp increases)
test:
dd if=/dev/zero of=/swapfile bs=1M count=2048
chmod 600 /swapfile
mkswap /swapfile
swapon /swapfile
echo Y > /sys/module/zswap/parameters/enabled
./test_zswap
TAP version 13
1..8
ok 1 test_zswap_usage
ok 2 test_swapin_nozswap
ok 3 test_zswapin
ok 4 test_zswap_writeback_enabled
ok 5 test_zswap_writeback_disabled
ok 6 test_no_kmem_bypass
ok 7 test_no_invasive_cgroup_shrink
ok 8 test_zswap_incompressible
Totals: pass:8 fail:0 xfail:0 xpass:0 skip:0 error:0
---
tools/testing/selftests/cgroup/test_zswap.c | 136 ++++++++++++++++++ 1 file changed, 136 insertions(+)
tools/testing/selftests/cgroup/test_zswap.c renamed from tools/testing/selftests/cgroup/test_zswap.c~selftests-cgroup-add-test-for-zswap-incompressible-pages +136 -0
@@ -5,6 +5,8 @@#include <unistd.h> #include <stdio.h> #include <signal.h> +#include <errno.h> +#include <fcntl.h> #include <sys/sysinfo.h> #include <string.h> #include <sys/wait.h>
@@ -574,6 +576,139 @@ out:return ret; } +struct incomp_child_args { +size_t size; +int pipefd[2 ]; +int madvise_ret; +int madvise_errno; +}; + +static int allocate_random_and_wait (const char *cgroup,void *arg) +{ +struct incomp_child_args *values = arg; +size_t size = values->size; +char *mem; +int fd; +ssize_t n; + +close (values->pipefd[0 ]); + + mem =mmap (NULL , size,PROT_READ |PROT_WRITE , +MAP_PRIVATE |MAP_ANONYMOUS ,-1 ,0 ); +if (mem ==MAP_FAILED ) +return -1 ; + +/* Fill with random data from /dev/urandom - incompressible */ + fd =open ("/dev/urandom" ,O_RDONLY ); +if (fd <0 ) { +munmap (mem, size); +return -1 ; + } + +for (size_t i =0 ; i < size; ) { + n =read (fd, mem + i, size - i); +if (n <=0 ) +break ; + i += n; + } +close (fd); + +/* Touch all pages to ensure they're faulted in */ +for (size_t i =0 ; i < size; i +=PAGE_SIZE ) + mem[i] = mem[i]; + +/* Use MADV_PAGEOUT to push pages into zswap */ + values->madvise_ret =madvise (mem, size,MADV_PAGEOUT ); + values->madvise_errno = errno; + +/* Notify parent that allocation and pageout are done */ +write (values->pipefd[1 ],"x" ,1 ); +close (values->pipefd[1 ]); + +/* Keep memory alive for parent to check stats */ +pause (); +munmap (mem, size); +return 0 ; +} + +static long get_zswap_incomp (const char *cgroup) +{ +return cg_read_key_long (cgroup,"memory.stat" ,"zswap_incomp " ); +} + +/* +* Test that incompressible pages (random data) are tracked by zswap_incomp. +* +* The child process allocates random data within memory.max, then uses +* MADV_PAGEOUT to push pages into zswap. The parent waits on a pipe for +* the child to finish, then checks the zswap_incomp stat before the child +* exits (zswap_incomp is a gauge that decreases on free). +*/ +static int test_zswap_incompressible (const char *root) +{ +int ret =KSFT_FAIL ; +struct incomp_child_args *values; +char *test_group; +long zswap_incomp; +pid_t child_pid; +int child_status; +char buf; + + values =mmap (0 ,sizeof (struct incomp_child_args ),PROT_READ | +PROT_WRITE ,MAP_SHARED |MAP_ANONYMOUS ,-1 ,0 ); +if (values ==MAP_FAILED ) +return KSFT_FAIL ; + +if (pipe (values->pipefd)) { +munmap (values,sizeof (struct incomp_child_args )); +return KSFT_FAIL ; + } + + test_group =cg_name (root,"zswap_incompressible_test" ); +if (!test_group) + goto out; +if (cg_create (test_group)) + goto out; +if (cg_write (test_group,"memory.max" ,"32M" )) + goto out; + + values->size =MB (4 ); + child_pid =cg_run_nowait (test_group, allocate_random_and_wait, values); +if (child_pid <0 ) + goto out; + +close (values->pipefd[1 ]); + +/* Wait for child to finish allocating and pageout */ +read (values->pipefd[0 ], &buf,1 ); +close (values->pipefd[0 ]); + + zswap_incomp =get_zswap_incomp (test_group); +if (zswap_incomp <=0 ) { +long zswpout =get_zswpout (test_group); +long zswapped =cg_read_key_long (test_group,"memory.stat" ,"zswapped " ); +long zswap_b =cg_read_key_long (test_group,"memory.stat" ,"zswap " ); + +ksft_print_msg ("zswap_incomp not increased: %ld\n" , zswap_incomp); +ksft_print_msg ("debug: zswpout=%ld zswapped=%ld zswap_b=%ld\n" , + zswpout, zswapped, zswap_b); +ksft_print_msg ("debug: madvise ret=%d errno=%d\n" , + values->madvise_ret, values->madvise_errno); + goto out_kill; + } + + ret =KSFT_PASS ; + +out_kill: +kill (child_pid,SIGTERM ); +waitpid (child_pid, &child_status,0 ); +out: +cg_destroy (test_group); +free (test_group); +munmap (values,sizeof (struct incomp_child_args )); +return ret; +} +#define T (x) { x, #x }struct zswap_test {int (*fn)(const char *root);
@@ -586,6 +721,7 @@ struct zswap_test {T (test_zswap_writeback_disabled),T (test_no_kmem_bypass),T (test_no_invasive_cgroup_shrink), + T(test_zswap_incompressible), };#undef T
_
Patches currently in -mm which might be from [email protected] are