summaryrefslogtreecommitdiffstats
path: root/net/sunrpc/svc.c
diff options
context:
space:
mode:
authorChuck Lever <chuck.lever@oracle.com>2023-01-10 10:32:00 -0500
committerChuck Lever <chuck.lever@oracle.com>2023-02-20 09:20:32 -0500
commitccf08bed6e7a80519569456edd2ea21b7b1701c6 (patch)
tree5895f6b9e423350291c32b02a990a9b8d1b988ac /net/sunrpc/svc.c
parent65ba3d2425bf51165b6e88509c632bd15d12883d (diff)
downloadlinux-ccf08bed6e7a80519569456edd2ea21b7b1701c6.tar.gz
linux-ccf08bed6e7a80519569456edd2ea21b7b1701c6.tar.bz2
linux-ccf08bed6e7a80519569456edd2ea21b7b1701c6.zip
SUNRPC: Replace pool stats with per-CPU variables
Eliminate the use of bus-locked operations in svc_xprt_enqueue(), which is a hot path. Replace them with per-cpu variables to reduce cross-CPU memory bus traffic. Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
Diffstat (limited to 'net/sunrpc/svc.c')
-rw-r--r--net/sunrpc/svc.c12
1 files changed, 12 insertions, 0 deletions
diff --git a/net/sunrpc/svc.c b/net/sunrpc/svc.c
index 5dc298c30ea8..1fd3f5e57285 100644
--- a/net/sunrpc/svc.c
+++ b/net/sunrpc/svc.c
@@ -512,6 +512,10 @@ __svc_create(struct svc_program *prog, unsigned int bufsize, int npools,
INIT_LIST_HEAD(&pool->sp_sockets);
INIT_LIST_HEAD(&pool->sp_all_threads);
spin_lock_init(&pool->sp_lock);
+
+ percpu_counter_init(&pool->sp_sockets_queued, 0, GFP_KERNEL);
+ percpu_counter_init(&pool->sp_threads_woken, 0, GFP_KERNEL);
+ percpu_counter_init(&pool->sp_threads_timedout, 0, GFP_KERNEL);
}
return serv;
@@ -565,6 +569,7 @@ void
svc_destroy(struct kref *ref)
{
struct svc_serv *serv = container_of(ref, struct svc_serv, sv_refcnt);
+ unsigned int i;
dprintk("svc: svc_destroy(%s)\n", serv->sv_program->pg_name);
timer_shutdown_sync(&serv->sv_temptimer);
@@ -580,6 +585,13 @@ svc_destroy(struct kref *ref)
svc_pool_map_put(serv->sv_nrpools);
+ for (i = 0; i < serv->sv_nrpools; i++) {
+ struct svc_pool *pool = &serv->sv_pools[i];
+
+ percpu_counter_destroy(&pool->sp_sockets_queued);
+ percpu_counter_destroy(&pool->sp_threads_woken);
+ percpu_counter_destroy(&pool->sp_threads_timedout);
+ }
kfree(serv->sv_pools);
kfree(serv);
}