On Wed, Mar 11, 2026 at 4:05 AM Li Wang <[email protected]> wrote:
>
> test_zswap currently checks only for zswap presence via /sys/module/zswap,
> but does not account for the global runtime state in
> /sys/module/zswap/parameters/enabled.
>
> If zswap is configured but globally disabled, zswap cgroup tests may run in
> an invalid environment and fail spuriously.
>
> Add helpers to:
> - detect the runtime zswap enabled state,
> - enable zswap when it is initially disabled,
> - restore the original state after tests complete.
>
> Skip the test when zswap state cannot be determined (e.g. unsupported or
> unreadable), and keep existing behavior when zswap is already enabled.
>
> This makes test_zswap more robust across systems where zswap is built but
> disabled by default.
>
> Signed-off-by: Li Wang <[email protected]>
> Cc: Johannes Weiner <[email protected]>
> Cc: Michal Hocko <[email protected]>
> Cc: Michal Koutný <[email protected]>
> Cc: Muchun Song <[email protected]>
> Cc: Nhat Pham <[email protected]>
> Cc: Tejun Heo <[email protected]>
> Cc: Roman Gushchin <[email protected]>
> Cc: Shakeel Butt <[email protected]>
> Cc: Yosry Ahmed <[email protected]>
> ---
> tools/testing/selftests/cgroup/test_zswap.c | 77 ++++++++++++++++++++-
> 1 file changed, 75 insertions(+), 2 deletions(-)
>
> diff --git a/tools/testing/selftests/cgroup/test_zswap.c
> b/tools/testing/selftests/cgroup/test_zswap.c
> index 64ebc3f3f203..1c80f4af9683 100644
> --- a/tools/testing/selftests/cgroup/test_zswap.c
> +++ b/tools/testing/selftests/cgroup/test_zswap.c
> @@ -594,18 +594,88 @@ static bool zswap_configured(void)
> return access("/sys/module/zswap", F_OK) == 0;
> }
>
> +static int zswap_enabled_state(void)
Just zswap_enabled() is good.
> +{
> + char buf[16];
> + ssize_t n;
> +
> + if (!zswap_configured())
> + return -1;
Return 0 here, zswap is disabled for all intents and purposes.
> +
> + n = read_text("/sys/module/zswap/parameters/enabled", buf,
> sizeof(buf));
> + if (n < 0 || n == 0)
> + return -1;
if (read_text(..) <= 0)
> +
> + switch (buf[0]) {
> + case 'Y':
> + case 'y':
> + case '1':
> + return 1;
> + case 'N':
> + case 'n':
> + case '0':
Can a read really return any of these values? Or just Y/N?
> + return 0;
> + default:
> + return -1;
> + }
> +}
> +
[..]
> int main(int argc, char **argv)
> {
> char root[PATH_MAX];
> - int i;
> + int i, orig_zswap_state;
>
> ksft_print_header();
> ksft_set_plan(ARRAY_SIZE(tests));
> if (cg_find_unified_root(root, sizeof(root), NULL))
> ksft_exit_skip("cgroup v2 isn't mounted\n");
>
> - if (!zswap_configured())
> + orig_zswap_state = zswap_enabled_state();
> +
> + if (orig_zswap_state == -1)
> ksft_exit_skip("zswap isn't configured\n");
> + else if (orig_zswap_state == 0 && !enable_zswap())
> + ksft_exit_skip("zswap is disabled and cannot be enabled\n");
As Michal mentioned, skip the test if zswap is not enabled.
Assuming zswap_enabled() only returns -1 if it fails to read the
module param (and zswap_configured() is true), then we should probably
fail instead of skip, as it means something is wrong with the test or
the module param.