Re: [RFC PATCH v4 1/3] mm/zswap: release retired pools via queue_rcu_work() instead of synchronize_rcu()
From: Yosry Ahmed
Date: Mon Aug 31 2026 - 16:09:02 EST
On Sun, Aug 30, 2026 at 4:47 AM Jianyue Wu <wujianyue000@xxxxxxxxx> wrote:
>
> When a pool's last reference is dropped, __zswap_pool_empty() removes it
> from the pool list and schedules __zswap_pool_release(), which calls
> synchronize_rcu() to wait for readers before tearing the pool down.
>
> synchronize_rcu() is a synchronous, potentially long wait. Replace it
> with queue_rcu_work(): __zswap_pool_empty() hands the pool to
> queue_rcu_work(), which waits for a grace period asynchronously and then
> runs __zswap_pool_release() from a worker for the sleepable teardown
> (__zswap_pool_empty() can run in atomic context and must not block).
> The grace-period guarantee is unchanged; the retirement path just no
> longer blocks on it.
>
> Suggested-by: Yosry Ahmed <yosry@xxxxxxxxxx>
> Signed-off-by: Jianyue Wu <wujianyue000@xxxxxxxxx>
Why are the patches still tagged RFC?
Anyway, with one nit below:
Acked-by: Yosry Ahmed <yosry@xxxxxxxxxx>
> ---
> mm/zswap.c | 12 +++++-------
> 1 file changed, 5 insertions(+), 7 deletions(-)
>
> diff --git a/mm/zswap.c b/mm/zswap.c
> index 37f34e406c8e..0bb30e58950a 100644
> --- a/mm/zswap.c
> +++ b/mm/zswap.c
> @@ -155,7 +155,7 @@ struct zswap_pool {
> struct crypto_acomp_ctx __percpu *acomp_ctx;
> struct percpu_ref ref;
> struct list_head list;
> - struct work_struct release_work;
> + struct rcu_work release_work;
Seems like the convention is to use rwork in the name instead of work.
> struct hlist_node node;
> char tfm_name[CRYPTO_MAX_ALG_NAME];
> };
> @@ -379,10 +379,8 @@ static void zswap_pool_destroy(struct zswap_pool *pool)
>
> static void __zswap_pool_release(struct work_struct *work)
> {
> - struct zswap_pool *pool = container_of(work, typeof(*pool),
> - release_work);
> -
> - synchronize_rcu();
> + struct zswap_pool *pool = container_of(to_rcu_work(work),
> + typeof(*pool), release_work);
>
> /* nobody should have been able to get a ref... */
> WARN_ON(!percpu_ref_is_zero(&pool->ref));
> @@ -406,8 +404,8 @@ static void __zswap_pool_empty(struct percpu_ref *ref)
>
> list_del_rcu(&pool->list);
>
> - INIT_WORK(&pool->release_work, __zswap_pool_release);
> - schedule_work(&pool->release_work);
> + INIT_RCU_WORK(&pool->release_work, __zswap_pool_release);
> + queue_rcu_work(system_percpu_wq, &pool->release_work);
>
> spin_unlock_bh(&zswap_pools_lock);
> }
> --
> 2.43.0
>