[PATCH v5 4/5] sunrpc: tear down pool counters before dropping the pool map reference
From: Jeff Layton
Date: Mon Jul 06 2026 - 09:39:49 EST
svc_destroy() drops the service's reference to the global svc_pool_map
before iterating serv->sv_pools[] to destroy each pool's percpu counters.
That ordering happens to be fine today because the loop is bounded by the
per-service sv_nrpools field.
A following patch removes sv_nrpools and derives the pool count from the
pool map instead. svc_pool_map_put() zeroes svc_pool_map.npools when the
last reference is dropped, so a derived loop bound would read as zero for
the last pooled service and skip svc_pool_destroy_counters() entirely,
leaking the percpu counters (which remain linked on the global
percpu_counters list while the svc_serv is freed).
Reorder svc_destroy() to destroy the pool counters while the map is still
referenced, then drop the reference. No functional change.
Assisted-by: Claude:claude-opus-4-8
Signed-off-by: Jeff Layton <jlayton@xxxxxxxxxx>
---
net/sunrpc/svc.c | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/net/sunrpc/svc.c b/net/sunrpc/svc.c
index 2d1cdf55c561..ece69cb0138a 100644
--- a/net/sunrpc/svc.c
+++ b/net/sunrpc/svc.c
@@ -520,14 +520,15 @@ svc_destroy(struct svc_serv **servp)
cache_clean_deferred(serv);
- if (serv->sv_is_pooled)
- svc_pool_map_put();
-
for (i = 0; i < serv->sv_nrpools; i++) {
struct svc_pool *pool = &serv->sv_pools[i];
svc_pool_destroy_counters(pool);
}
+
+ if (serv->sv_is_pooled)
+ svc_pool_map_put();
+
kfree(serv->sv_pools);
kfree(serv);
}
--
2.55.0