[PATCH 1/1] mm/zswap: publish the initial pool with list_add_rcu()
From: Longlong Xia
Date: Mon Sep 07 2026 - 09:25:26 EST
From: Longlong Xia <xialonglong@xxxxxxxxxx>
zswap_setup() publishes the pool on the zswap_pools list with a
plain list_add(), but the list is walked by concurrent RCU readers
holding nothing but rcu_read_lock() through zswap_total_pages(), e.g.
/proc/meminfo and the shrinker count path.
CPU 0 (writer) CPU 1 (reader)
-------------- --------------
zswap_pool_create():
pool->zs_pool = zs_create_pool(); (1)
list_add() -> __list_add():
WRITE_ONCE(zswap_pools.next,
&pool->list); (2) zswap_total_pages():
pool = READ_ONCE( (a)
zswap_pools.next);
zs_get_total_pages( (b)
pool->zs_pool);
If (2) becomes visible to CPU 1 before (1), CPU 1 finds the pool at
(a) but dereferences a wild pointer at (b). Publish the node with
list_add_rcu().
Fixes: 91cdcd8d624bf ("mm: zswap: optimize zswap pool size tracking")
Cc: stable@xxxxxxxxxxxxxxx
Assisted-by: Zcode:GLM-5.3
Signed-off-by: Longlong Xia <xialonglong@xxxxxxxxxx>
---
Link: https://sashiko.dev/#/patchset/20260906133601.3563324-1-xialonglong2025%40163.com
mm/zswap.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/mm/zswap.c b/mm/zswap.c
index 37f34e406c8e..cb5a0855fd2a 100644
--- a/mm/zswap.c
+++ b/mm/zswap.c
@@ -1803,7 +1803,7 @@ static int zswap_setup(void)
pool = __zswap_pool_create_fallback();
if (pool) {
pr_info("loaded using pool %s\n", pool->tfm_name);
- list_add(&pool->list, &zswap_pools);
+ list_add_rcu(&pool->list, &zswap_pools);
zswap_has_pool = true;
static_branch_enable(&zswap_ever_enabled);
} else {
--
2.43.0