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)
+{
+       char buf[16];
+       ssize_t n;
+
+       if (!zswap_configured())
+               return -1;
+
+       n = read_text("/sys/module/zswap/parameters/enabled", buf, sizeof(buf));
+       if (n < 0 || n == 0)
+               return -1;
+
+       switch (buf[0]) {
+       case 'Y':
+       case 'y':
+       case '1':
+               return 1;
+       case 'N':
+       case 'n':
+       case '0':
+               return 0;
+       default:
+               return -1;
+       }
+}
+
+static bool enable_zswap(void)
+{
+       int st;
+       char y[] = "Y\n";
+
+       st = zswap_enabled_state();
+       if (st == 1)
+               return true;
+       if (st < 0)
+               return false;
+
+       if (write_text("/sys/module/zswap/parameters/enabled", y, strlen(y)) >= 
0) {
+               if (zswap_enabled_state() == 1)
+                       return true;
+       }
+
+       ksft_print_msg("Failed to enable zswap\n");
+       return false;
+}
+
+static bool disable_zswap(void)
+{
+       int st;
+       char n[] = "N\n";
+
+       st = zswap_enabled_state();
+       if (st == 0)
+               return true;
+       if (st < 0)
+               return false;
+
+       if (write_text("/sys/module/zswap/parameters/enabled", n, strlen(n)) >= 
0) {
+               if (zswap_enabled_state() == 0)
+                       return true;
+       }
+
+       ksft_print_msg("Failed to disable zswap\n");
+       return false;
+}
+
 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");
 
        /*
         * Check that memory controller is available:
@@ -632,5 +702,8 @@ int main(int argc, char **argv)
                }
        }
 
+       if (orig_zswap_state == 0)
+               disable_zswap();
+
        ksft_finished();
 }
-- 
2.53.0


Reply via email to