summaryrefslogtreecommitdiff
path: root/net/sunrpc
diff options
context:
space:
mode:
authorJeff Layton <jlayton@kernel.org>2026-07-17 07:08:53 -0400
committerChuck Lever <cel@kernel.org>2026-08-10 09:54:35 -0400
commitf1775ed34ed3ecf1289588574b892aa9584e6ef3 (patch)
tree6f502266d16a6ec84ca4460847c1c4459c16cb1f /net/sunrpc
parent284a474e947afe1d48bbd820c5327a911e685332 (diff)
downloadlinux-next-f1775ed34ed3ecf1289588574b892aa9584e6ef3.tar.gz
linux-next-f1775ed34ed3ecf1289588574b892aa9584e6ef3.zip
sunrpc: add per-netns per-procedure call counts to svc_stat
The existing per-procedure call counts live in global svc_version->vs_count[] arrays which are not network-namespace-aware. Add per-netns equivalents in struct svc_stat so the upcoming netlink stats interface can return namespace-scoped statistics. Add a vs_count pointer array to struct svc_stat, along with svc_stat_alloc_counts() and svc_stat_free_counts() helpers to manage per-version percpu call count arrays. Increment the per-net counter alongside the global one in svc_generic_init_request(). Call the alloc/free helpers from nfsd_net_init() and nfsd_net_exit(). Assisted-by: LLM Signed-off-by: Jeff Layton <jlayton@kernel.org> Link: https://patch.msgid.link/20260717-exportd-netlink-v7-1-b7ce17b83b60@kernel.org Signed-off-by: Chuck Lever <cel@kernel.org>
Diffstat (limited to 'net/sunrpc')
-rw-r--r--net/sunrpc/svc.c62
1 files changed, 62 insertions, 0 deletions
diff --git a/net/sunrpc/svc.c b/net/sunrpc/svc.c
index 05c3e6e2f659..9b27c43309a4 100644
--- a/net/sunrpc/svc.c
+++ b/net/sunrpc/svc.c
@@ -1347,6 +1347,14 @@ svc_generic_init_request(struct svc_rqst *rqstp,
/* Bump per-procedure stats counter */
this_cpu_inc(versp->vs_count[rqstp->rq_proc]);
+ /* Bump per-net per-procedure stats counter */
+ if (rqstp->rq_server->sv_stats &&
+ rqstp->rq_server->sv_stats->program == progp &&
+ rqstp->rq_server->sv_stats->vs_count &&
+ rqstp->rq_server->sv_stats->vs_count[rqstp->rq_vers])
+ this_cpu_inc(rqstp->rq_server->sv_stats->vs_count
+ [rqstp->rq_vers][rqstp->rq_proc]);
+
ret->dispatch = versp->vs_dispatch;
return rpc_success;
err_bad_vers:
@@ -1358,6 +1366,60 @@ err_bad_proc:
}
EXPORT_SYMBOL_GPL(svc_generic_init_request);
+/**
+ * svc_stat_alloc_counts - allocate per-netns per-version call count arrays
+ * @statp: svc_stat whose vs_count arrays should be allocated
+ *
+ * statp->program must be set before calling this.
+ *
+ * Returns zero on success, or a negative errno otherwise.
+ */
+int svc_stat_alloc_counts(struct svc_stat *statp)
+{
+ struct svc_program *prog = statp->program;
+ unsigned int i;
+
+ statp->vs_count = kcalloc(prog->pg_nvers,
+ sizeof(unsigned long __percpu *),
+ GFP_KERNEL);
+ if (!statp->vs_count)
+ return -ENOMEM;
+
+ for (i = 0; i < prog->pg_nvers; i++) {
+ if (!prog->pg_vers[i])
+ continue;
+ statp->vs_count[i] = __alloc_percpu(prog->pg_vers[i]->vs_nproc *
+ sizeof(unsigned long),
+ sizeof(unsigned long));
+ if (!statp->vs_count[i])
+ goto err;
+ }
+ return 0;
+err:
+ svc_stat_free_counts(statp);
+ return -ENOMEM;
+}
+EXPORT_SYMBOL_GPL(svc_stat_alloc_counts);
+
+/**
+ * svc_stat_free_counts - free per-netns per-version call count arrays
+ * @statp: svc_stat whose vs_count arrays should be freed
+ */
+void svc_stat_free_counts(struct svc_stat *statp)
+{
+ struct svc_program *prog = statp->program;
+ unsigned int i;
+
+ if (!statp->vs_count)
+ return;
+
+ for (i = 0; i < prog->pg_nvers; i++)
+ free_percpu(statp->vs_count[i]);
+ kfree(statp->vs_count);
+ statp->vs_count = NULL;
+}
+EXPORT_SYMBOL_GPL(svc_stat_free_counts);
+
/*
* Common routine for processing the RPC request.
*/