[PATCH] selftests/cgroup: Skip test_no_invasive_cgroup_shrink if zswap shrinker is enabled

Joshua Hahn posted 1 patch 3 weeks, 3 days ago
tools/testing/selftests/cgroup/test_zswap.c | 22 +++++++++++++++++++++
1 file changed, 22 insertions(+)
[PATCH] selftests/cgroup: Skip test_no_invasive_cgroup_shrink if zswap shrinker is enabled
Posted by Joshua Hahn 3 weeks, 3 days ago
The test_no_invasive_cgroup_shrink selftest checks that when a cgroup
has zswapped out more pages than memory.zswap.max, that it does not
trigger writeback for other cgroups. To do this, it compares the
writeback count in a control cgroup and makes sure that it is 0,
and compares it to the writeback count in a aggressor cgroup who
does expect to see writeback.

When the zswap shrinker is enabled however, there is an additional path
to zswap writeback, which can happen independently of reaching the
memory.zswap.max limit.

The writeback counter cannot distinguish between invasive noisy-neighbor
driven writeback and the zswap shrinker work, so the test becomes
invalid.

Skip test_no_invasive_cgroup_shrink if the zswap shrinker is enabled.

Signed-off-by: Joshua Hahn <joshua.hahnjy@gmail.com>
---
 tools/testing/selftests/cgroup/test_zswap.c | 22 +++++++++++++++++++++
 1 file changed, 22 insertions(+)

diff --git a/tools/testing/selftests/cgroup/test_zswap.c b/tools/testing/selftests/cgroup/test_zswap.c
index 9c5bd503c3f73..6f9b5c631d030 100644
--- a/tools/testing/selftests/cgroup/test_zswap.c
+++ b/tools/testing/selftests/cgroup/test_zswap.c
@@ -20,6 +20,8 @@ static int page_size;
 
 #define PATH_ZSWAP "/sys/module/zswap"
 #define PATH_ZSWAP_ENABLED "/sys/module/zswap/parameters/enabled"
+#define PATH_ZSWAP_SHRINKER_ENABLED \
+	"/sys/module/zswap/parameters/shrinker_enabled"
 #define PATH_ZSWAP_STORED_PAGES "/sys/kernel/debug/zswap/stored_pages"
 
 static int read_int(const char *path, size_t *value)
@@ -446,6 +448,16 @@ static int test_zswap_writeback_disabled(const char *root)
 	return test_zswap_writeback(root, false);
 }
 
+static bool zswap_shrinker_enabled(void)
+{
+	char value[2];
+
+	if (read_text(PATH_ZSWAP_SHRINKER_ENABLED, value, sizeof(value)) <= 0)
+		return false;
+
+	return value[0] == 'Y';
+}
+
 /*
  * When trying to store a memcg page in zswap, if the memcg hits its memory
  * limit in zswap, writeback should affect only the zswapped pages of that
@@ -461,6 +473,16 @@ static int test_no_invasive_cgroup_shrink(const char *root)
 	char *zw_allocation = NULL, *wb_allocation = NULL;
 	char *zw_group = NULL, *wb_group = NULL;
 
+	/*
+	 * The shrinker can write back zw_group's pages despite not hitting the
+	 * zswap limit. Skip the test if the zswap shrinker is enabled since the
+	 * test cannot distinguish invasive writeback from shrinker work.
+	 */
+	if (zswap_shrinker_enabled()) {
+		ksft_print_msg("zswap shrinker is enabled\n");
+		return KSFT_SKIP;
+	}
+
 	snprintf(zswap_max_buf, sizeof(zswap_max_buf), "%d", page_size);
 	snprintf(mem_max_buf, sizeof(mem_max_buf), "%zu", allocation_size / 2);
 
-- 
2.53.0-Meta
Re: [PATCH] selftests/cgroup: Skip test_no_invasive_cgroup_shrink if zswap shrinker is enabled
Posted by Nhat Pham 3 weeks, 3 days ago
On Tue, Sep 1, 2026 at 12:13 PM Joshua Hahn <joshua.hahnjy@gmail.com> wrote:
>
> The test_no_invasive_cgroup_shrink selftest checks that when a cgroup
> has zswapped out more pages than memory.zswap.max, that it does not
> trigger writeback for other cgroups. To do this, it compares the
> writeback count in a control cgroup and makes sure that it is 0,
> and compares it to the writeback count in a aggressor cgroup who
> does expect to see writeback.
>
> When the zswap shrinker is enabled however, there is an additional path
> to zswap writeback, which can happen independently of reaching the
> memory.zswap.max limit.
>
> The writeback counter cannot distinguish between invasive noisy-neighbor
> driven writeback and the zswap shrinker work, so the test becomes
> invalid.

I think writeback in the control group (zw_group) happens right during
the first round of memory allocation, but there shouldn't be any on
the second round (as the second round involves writing to wb_group
only). So if we read zswap writeback counter of that cgroup (zw_group)
right after that first allocation round, and make sure delta = 0 after
the second round, then that should work for both shrinker_enabled = Y
v.s N.

If it's still too noisy, then I'm fine with skipping it when
shrinker_enabled = Y.
Re: [PATCH] selftests/cgroup: Skip test_no_invasive_cgroup_shrink if zswap shrinker is enabled
Posted by Joshua Hahn 3 weeks, 2 days ago
On Tue, 1 Sep 2026 14:04:22 -0400 Nhat Pham <nphamcs@gmail.com> wrote:

> On Tue, Sep 1, 2026 at 12:13 PM Joshua Hahn <joshua.hahnjy@gmail.com> wrote:
> >
> > The test_no_invasive_cgroup_shrink selftest checks that when a cgroup
> > has zswapped out more pages than memory.zswap.max, that it does not
> > trigger writeback for other cgroups. To do this, it compares the
> > writeback count in a control cgroup and makes sure that it is 0,
> > and compares it to the writeback count in a aggressor cgroup who
> > does expect to see writeback.
> >
> > When the zswap shrinker is enabled however, there is an additional path
> > to zswap writeback, which can happen independently of reaching the
> > memory.zswap.max limit.
> >
> > The writeback counter cannot distinguish between invasive noisy-neighbor
> > driven writeback and the zswap shrinker work, so the test becomes
> > invalid.

Hi Nhat!

Thanks for the quick review on this.

> I think writeback in the control group (zw_group) happens right during
> the first round of memory allocation, but there shouldn't be any on
> the second round (as the second round involves writing to wb_group
> only). So if we read zswap writeback counter of that cgroup (zw_group)
> right after that first allocation round, and make sure delta = 0 after
> the second round, then that should work for both shrinker_enabled = Y
> v.s N.

That is very smart and much better than just skipping the test, I'll
take your approach. I've sent a v2 in [1].

Have a great day Nhat! Thank you again!
Joshua

[1] https://lore.kernel.org/all/20260902194521.3652178-1-joshua.hahnjy@gmail.com/