The zswap_writeback_enabled test fails when a write to memory.reclaim
returns -EAGAIN, which means less than the requested amount was
reclaimed. attempt_writeback() propagates the -EAGAIN to the caller,
and the test case is marked as failed even when zswap writeback did
happen.
This heavily depends on the performance of the backing swap device.
Reclaim does not wait for writeback (on cgroup v2), does not count pages
that are under writeback as reclaimed, and memory.reclaim gives up after
MAX_RECLAIM_RETRIES passes without making progress. On a slow device
where reclaim does not make any progress before writeback completes,
a write to memory.reclaim fails.
On a VM with zswap enabled, where IO delay was injected via dm-delay,
the success rate of the zswap writeback test drops dramatically once
the delay reaches 11 ms: 7% failures at 10 ms and 79% failures at 11 ms,
n = 100.
When zswap writeback is enabled, ignore -EAGAIN from memory.reclaim and
determine pass/fail based on the zswpwb counter because that is what
zswap_writeback_enabled actually wants to test.
With this change, the test reliably passes even on a slow swap device
(tested up to 1000 ms delay). This makes the test resilient against
the performance of the swap device.
Assisted-by: LLM
Fixes: 158863e5d7cc ("selftests: cgroup: add tests to verify the zswap
writeback path")
Signed-off-by: Harry Yoo (Meta) <[email protected]>
---
- Huge thanks to Joshua Hahn who kindly helped the investigation and
the discussion of the problem.
- LLM was used to perform experiments with injected IO delay and
to investigate why memory.reclaim fails (and verified by Harry Yoo).
Everything else was handcrafted by Harry Yoo.
---
tools/testing/selftests/cgroup/test_zswap.c | 11 ++++++++++-
1 file changed, 10 insertions(+), 1 deletion(-)
diff --git a/tools/testing/selftests/cgroup/test_zswap.c
b/tools/testing/selftests/cgroup/test_zswap.c
index 1ac779072775..d50acc1b83ac 100644
--- a/tools/testing/selftests/cgroup/test_zswap.c
+++ b/tools/testing/selftests/cgroup/test_zswap.c
@@ -346,7 +346,16 @@ static int attempt_writeback(const char *cgroup, void *arg)
* it can't writeback to swap.
*/
ret = cg_write_numeric(cgroup, "memory.reclaim", memsize);
- if (!wb_enabled)
+
+ /*
+ * When writeback is enabled, memory.reclaim may still fail to reclaim
+ * the requested amount of memory due to a slow swap device.
+ * Ignore -EAGAIN here. The caller determines pass/fail based on the
+ * zswap writeback counter.
+ */
+ if (wb_enabled && ret == -EAGAIN)
+ ret = 0;
+ else if (!wb_enabled)
ret = (ret == -EAGAIN) ? 0 : -1;
out:
---
base-commit: baa8de2f3448d1466a888a805c18d01c998fe052
change-id: 20260914-test-zswap-wb-ignore-eagain-0195c36aaa90
Best regards,
--
Cheers,
Harry / Hyeonggon