mirror of
https://github.com/torvalds/linux.git
synced 2026-09-22 12:44:03 +02:00
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>
This commit is contained in:
parent
284a474e94
commit
f1775ed34e
|
|
@ -2516,9 +2516,12 @@ static __net_init int nfsd_net_init(struct net *net)
|
|||
|
||||
memset(&nn->nfsd_svcstats, 0, sizeof(nn->nfsd_svcstats));
|
||||
nn->nfsd_svcstats.program = &nfsd_programs[0];
|
||||
retval = svc_stat_alloc_counts(&nn->nfsd_svcstats);
|
||||
if (retval)
|
||||
goto out_proc_error;
|
||||
if (!nfsd_proc_stat_init(net)) {
|
||||
retval = -ENOMEM;
|
||||
goto out_proc_error;
|
||||
goto out_svcstats_error;
|
||||
}
|
||||
|
||||
for (i = 0; i < sizeof(nn->nfsd_versions); i++)
|
||||
|
|
@ -2536,6 +2539,8 @@ static __net_init int nfsd_net_init(struct net *net)
|
|||
#endif
|
||||
return 0;
|
||||
|
||||
out_svcstats_error:
|
||||
svc_stat_free_counts(&nn->nfsd_svcstats);
|
||||
out_proc_error:
|
||||
percpu_counter_destroy_many(nn->counter, NFSD_STATS_COUNTERS_NUM);
|
||||
out_repcache_error:
|
||||
|
|
@ -2576,6 +2581,7 @@ static __net_exit void nfsd_net_exit(struct net *net)
|
|||
kfree_sensitive(nn->fh_key);
|
||||
nfsd_net_cb_shutdown(nn);
|
||||
nfsd_proc_stat_shutdown(net);
|
||||
svc_stat_free_counts(&nn->nfsd_svcstats);
|
||||
percpu_counter_destroy_many(nn->counter, NFSD_STATS_COUNTERS_NUM);
|
||||
nfsd_idmap_shutdown(net);
|
||||
nfsd_export_shutdown(net);
|
||||
|
|
|
|||
|
|
@ -37,9 +37,15 @@ struct svc_stat {
|
|||
rpcbadfmt,
|
||||
rpcbadauth,
|
||||
rpcbadclnt;
|
||||
|
||||
/* Per-version per-procedure call counts (per-cpu, per-netns) */
|
||||
unsigned long __percpu **vs_count;
|
||||
};
|
||||
|
||||
struct net;
|
||||
int svc_stat_alloc_counts(struct svc_stat *statp);
|
||||
void svc_stat_free_counts(struct svc_stat *statp);
|
||||
|
||||
#ifdef CONFIG_PROC_FS
|
||||
int rpc_proc_init(struct net *);
|
||||
void rpc_proc_exit(struct net *);
|
||||
|
|
|
|||
|
|
@ -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 @@ svc_generic_init_request(struct svc_rqst *rqstp,
|
|||
}
|
||||
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.
|
||||
*/
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user