]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
nfsd: make all of the nfsd stats per-network namespace
authorJosef Bacik <josef@toxicpanda.com>
Thu, 5 Sep 2024 15:30:59 +0000 (11:30 -0400)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 12 Sep 2024 09:06:45 +0000 (11:06 +0200)
[ Upstream commit 4b14885411f74b2b0ce0eb2b39d0fffe54e5ca0d ]

We have a global set of counters that we modify for all of the nfsd
operations, but now that we're exposing these stats across all network
namespaces we need to make the stats also be per-network namespace.  We
already have some caching stats that are per-network namespace, so move
these definitions into the same counter and then adjust all the helpers
and users of these stats to provide the appropriate nfsd_net struct so
that the stats are maintained for the per-network namespace objects.

Signed-off-by: Josef Bacik <josef@toxicpanda.com>
Reviewed-by: Jeff Layton <jlayton@kernel.org>
[ cel: adjusted to apply to v5.10.y ]
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
fs/nfsd/cache.h
fs/nfsd/netns.h
fs/nfsd/nfs4proc.c
fs/nfsd/nfscache.c
fs/nfsd/nfsctl.c
fs/nfsd/nfsfh.c
fs/nfsd/stats.c
fs/nfsd/stats.h
fs/nfsd/vfs.c

index 4c9b87850ab12732baabc00992ac98c7069a63e0..f21259ead64bb3e64471da7eb290557168e81ec8 100644 (file)
@@ -80,8 +80,6 @@ enum {
 
 int    nfsd_drc_slab_create(void);
 void   nfsd_drc_slab_free(void);
-int    nfsd_net_reply_cache_init(struct nfsd_net *nn);
-void   nfsd_net_reply_cache_destroy(struct nfsd_net *nn);
 int    nfsd_reply_cache_init(struct nfsd_net *);
 void   nfsd_reply_cache_shutdown(struct nfsd_net *);
 int    nfsd_cache_lookup(struct svc_rqst *);
index d1428f96aa5cb5c261942ea851c01dd349b9b582..55ab923263844e860c50e22c6a3e30e52b8caff3 100644 (file)
@@ -10,6 +10,7 @@
 
 #include <net/net_namespace.h>
 #include <net/netns/generic.h>
+#include <linux/nfs4.h>
 #include <linux/percpu_counter.h>
 #include <linux/siphash.h>
 
@@ -28,7 +29,19 @@ enum {
        NFSD_STATS_PAYLOAD_MISSES,
        /* amount of memory (in bytes) currently consumed by the DRC */
        NFSD_STATS_DRC_MEM_USAGE,
-       NFSD_NET_COUNTERS_NUM
+       NFSD_STATS_RC_HITS,             /* repcache hits */
+       NFSD_STATS_RC_MISSES,           /* repcache misses */
+       NFSD_STATS_RC_NOCACHE,          /* uncached reqs */
+       NFSD_STATS_FH_STALE,            /* FH stale error */
+       NFSD_STATS_IO_READ,             /* bytes returned to read requests */
+       NFSD_STATS_IO_WRITE,            /* bytes passed in write requests */
+#ifdef CONFIG_NFSD_V4
+       NFSD_STATS_FIRST_NFS4_OP,       /* count of individual nfsv4 operations */
+       NFSD_STATS_LAST_NFS4_OP = NFSD_STATS_FIRST_NFS4_OP + LAST_NFS4_OP,
+#define NFSD_STATS_NFS4_OP(op) (NFSD_STATS_FIRST_NFS4_OP + (op))
+       NFSD_STATS_WDELEG_GETATTR,      /* count of getattr conflict with wdeleg */
+#endif
+       NFSD_STATS_COUNTERS_NUM
 };
 
 /*
@@ -168,7 +181,7 @@ struct nfsd_net {
        atomic_t                 num_drc_entries;
 
        /* Per-netns stats counters */
-       struct percpu_counter    counter[NFSD_NET_COUNTERS_NUM];
+       struct percpu_counter    counter[NFSD_STATS_COUNTERS_NUM];
 
        /* longest hash chain seen */
        unsigned int             longest_chain;
index 2c0de247083a9068014f0a8431b1c99365af8548..f10e70f372855218556dab5f25e2149ca33e6131 100644 (file)
@@ -2435,10 +2435,10 @@ nfsd4_proc_null(struct svc_rqst *rqstp)
        return rpc_success;
 }
 
-static inline void nfsd4_increment_op_stats(u32 opnum)
+static inline void nfsd4_increment_op_stats(struct nfsd_net *nn, u32 opnum)
 {
        if (opnum >= FIRST_NFS4_OP && opnum <= LAST_NFS4_OP)
-               percpu_counter_inc(&nfsdstats.counter[NFSD_STATS_NFS4_OP(opnum)]);
+               percpu_counter_inc(&nn->counter[NFSD_STATS_NFS4_OP(opnum)]);
 }
 
 static const struct nfsd4_operation nfsd4_ops[];
@@ -2713,7 +2713,7 @@ encode_op:
                                           status, nfsd4_op_name(op->opnum));
 
                nfsd4_cstate_clear_replay(cstate);
-               nfsd4_increment_op_stats(op->opnum);
+               nfsd4_increment_op_stats(nn, op->opnum);
        }
 
        fh_put(current_fh);
index b81308cac39299137c1fb7a350c09e9543befcf1..448700939dfe9b221f48ddc697bf43790db02574 100644 (file)
@@ -176,27 +176,6 @@ void nfsd_drc_slab_free(void)
        kmem_cache_destroy(drc_slab);
 }
 
-/**
- * nfsd_net_reply_cache_init - per net namespace reply cache set-up
- * @nn: nfsd_net being initialized
- *
- * Returns zero on succes; otherwise a negative errno is returned.
- */
-int nfsd_net_reply_cache_init(struct nfsd_net *nn)
-{
-       return nfsd_percpu_counters_init(nn->counter, NFSD_NET_COUNTERS_NUM);
-}
-
-/**
- * nfsd_net_reply_cache_destroy - per net namespace reply cache tear-down
- * @nn: nfsd_net being freed
- *
- */
-void nfsd_net_reply_cache_destroy(struct nfsd_net *nn)
-{
-       nfsd_percpu_counters_destroy(nn->counter, NFSD_NET_COUNTERS_NUM);
-}
-
 int nfsd_reply_cache_init(struct nfsd_net *nn)
 {
        unsigned int hashsize;
@@ -478,7 +457,7 @@ out:
  */
 int nfsd_cache_lookup(struct svc_rqst *rqstp)
 {
-       struct nfsd_net         *nn;
+       struct nfsd_net         *nn = net_generic(SVC_NET(rqstp), nfsd_net_id);
        struct svc_cacherep     *rp, *found;
        __wsum                  csum;
        struct nfsd_drc_bucket  *b;
@@ -489,7 +468,7 @@ int nfsd_cache_lookup(struct svc_rqst *rqstp)
 
        rqstp->rq_cacherep = NULL;
        if (type == RC_NOCACHE) {
-               nfsd_stats_rc_nocache_inc();
+               nfsd_stats_rc_nocache_inc(nn);
                goto out;
        }
 
@@ -499,7 +478,6 @@ int nfsd_cache_lookup(struct svc_rqst *rqstp)
         * Since the common case is a cache miss followed by an insert,
         * preallocate an entry.
         */
-       nn = net_generic(SVC_NET(rqstp), nfsd_net_id);
        rp = nfsd_cacherep_alloc(rqstp, csum, nn);
        if (!rp)
                goto out;
@@ -517,7 +495,7 @@ int nfsd_cache_lookup(struct svc_rqst *rqstp)
        freed = nfsd_cacherep_dispose(&dispose);
        trace_nfsd_drc_gc(nn, freed);
 
-       nfsd_stats_rc_misses_inc();
+       nfsd_stats_rc_misses_inc(nn);
        atomic_inc(&nn->num_drc_entries);
        nfsd_stats_drc_mem_usage_add(nn, sizeof(*rp));
        goto out;
@@ -525,7 +503,7 @@ int nfsd_cache_lookup(struct svc_rqst *rqstp)
 found_entry:
        /* We found a matching entry which is either in progress or done. */
        nfsd_reply_cache_free_locked(NULL, rp, nn);
-       nfsd_stats_rc_hits_inc();
+       nfsd_stats_rc_hits_inc(nn);
        rtn = RC_DROPIT;
        rp = found;
 
@@ -675,11 +653,11 @@ int nfsd_reply_cache_stats_show(struct seq_file *m, void *v)
        seq_printf(m, "mem usage:             %lld\n",
                   percpu_counter_sum_positive(&nn->counter[NFSD_STATS_DRC_MEM_USAGE]));
        seq_printf(m, "cache hits:            %lld\n",
-                  percpu_counter_sum_positive(&nfsdstats.counter[NFSD_STATS_RC_HITS]));
+                  percpu_counter_sum_positive(&nn->counter[NFSD_STATS_RC_HITS]));
        seq_printf(m, "cache misses:          %lld\n",
-                  percpu_counter_sum_positive(&nfsdstats.counter[NFSD_STATS_RC_MISSES]));
+                  percpu_counter_sum_positive(&nn->counter[NFSD_STATS_RC_MISSES]));
        seq_printf(m, "not cached:            %lld\n",
-                  percpu_counter_sum_positive(&nfsdstats.counter[NFSD_STATS_RC_NOCACHE]));
+                  percpu_counter_sum_positive(&nn->counter[NFSD_STATS_RC_NOCACHE]));
        seq_printf(m, "payload misses:        %lld\n",
                   percpu_counter_sum_positive(&nn->counter[NFSD_STATS_PAYLOAD_MISSES]));
        seq_printf(m, "longest chain len:     %u\n", nn->longest_chain);
index e49a778e18155d2ec410ac81126a2d4fadcd2d01..e7fa64834d7d8dcb6de9df08d3c5602a9a0e95a1 100644 (file)
@@ -1458,7 +1458,7 @@ static __net_init int nfsd_init_net(struct net *net)
        retval = nfsd_idmap_init(net);
        if (retval)
                goto out_idmap_error;
-       retval = nfsd_net_reply_cache_init(nn);
+       retval = nfsd_stat_counters_init(nn);
        if (retval)
                goto out_repcache_error;
        nn->nfsd_versions = NULL;
@@ -1483,7 +1483,7 @@ static __net_exit void nfsd_exit_net(struct net *net)
        struct nfsd_net *nn = net_generic(net, nfsd_net_id);
 
        nfsd_proc_stat_shutdown(net);
-       nfsd_net_reply_cache_destroy(nn);
+       nfsd_stat_counters_destroy(nn);
        nfsd_idmap_shutdown(net);
        nfsd_export_shutdown(net);
        nfsd_netns_free_versions(nn);
@@ -1506,12 +1506,9 @@ static int __init init_nfsd(void)
        retval = nfsd4_init_pnfs();
        if (retval)
                goto out_free_slabs;
-       retval = nfsd_stat_counters_init();     /* Statistics */
-       if (retval)
-               goto out_free_pnfs;
        retval = nfsd_drc_slab_create();
        if (retval)
-               goto out_free_stat;
+               goto out_free_pnfs;
        nfsd_lockd_init();      /* lockd->nfsd callbacks */
        retval = create_proc_exports_entry();
        if (retval)
@@ -1541,8 +1538,6 @@ out_free_exports:
 out_free_lockd:
        nfsd_lockd_shutdown();
        nfsd_drc_slab_free();
-out_free_stat:
-       nfsd_stat_counters_destroy();
 out_free_pnfs:
        nfsd4_exit_pnfs();
 out_free_slabs:
@@ -1559,7 +1554,6 @@ static void __exit exit_nfsd(void)
        nfsd_drc_slab_free();
        remove_proc_entry("fs/nfs/exports", NULL);
        remove_proc_entry("fs/nfs", NULL);
-       nfsd_stat_counters_destroy();
        nfsd_lockd_shutdown();
        nfsd4_free_slabs();
        nfsd4_exit_pnfs();
index ae3323e0708ddc52d0affe68bd637846cd62ebc6..44e9a9dd2868818b4ba8b06446bbdd3a0e89c189 100644 (file)
@@ -326,6 +326,7 @@ out:
 __be32
 fh_verify(struct svc_rqst *rqstp, struct svc_fh *fhp, umode_t type, int access)
 {
+       struct nfsd_net *nn = net_generic(SVC_NET(rqstp), nfsd_net_id);
        struct svc_export *exp = NULL;
        struct dentry   *dentry;
        __be32          error;
@@ -399,7 +400,7 @@ skip_pseudoflavor_check:
        }
 out:
        if (error == nfserr_stale)
-               nfsd_stats_fh_stale_inc(exp);
+               nfsd_stats_fh_stale_inc(nn, exp);
        return error;
 }
 
index 22d57f92187e10fb802243a0bc3b6aa703612eb4..c21dbd7d008641c682f5e545a6a9a2bac3e7c664 100644 (file)
@@ -34,15 +34,17 @@ struct svc_stat             nfsd_svcstats = {
 
 static int nfsd_show(struct seq_file *seq, void *v)
 {
+       struct net *net = PDE_DATA(file_inode(seq->file));
+       struct nfsd_net *nn = net_generic(net, nfsd_net_id);
        int i;
 
        seq_printf(seq, "rc %lld %lld %lld\nfh %lld 0 0 0 0\nio %lld %lld\n",
-                  percpu_counter_sum_positive(&nfsdstats.counter[NFSD_STATS_RC_HITS]),
-                  percpu_counter_sum_positive(&nfsdstats.counter[NFSD_STATS_RC_MISSES]),
-                  percpu_counter_sum_positive(&nfsdstats.counter[NFSD_STATS_RC_NOCACHE]),
-                  percpu_counter_sum_positive(&nfsdstats.counter[NFSD_STATS_FH_STALE]),
-                  percpu_counter_sum_positive(&nfsdstats.counter[NFSD_STATS_IO_READ]),
-                  percpu_counter_sum_positive(&nfsdstats.counter[NFSD_STATS_IO_WRITE]));
+                  percpu_counter_sum_positive(&nn->counter[NFSD_STATS_RC_HITS]),
+                  percpu_counter_sum_positive(&nn->counter[NFSD_STATS_RC_MISSES]),
+                  percpu_counter_sum_positive(&nn->counter[NFSD_STATS_RC_NOCACHE]),
+                  percpu_counter_sum_positive(&nn->counter[NFSD_STATS_FH_STALE]),
+                  percpu_counter_sum_positive(&nn->counter[NFSD_STATS_IO_READ]),
+                  percpu_counter_sum_positive(&nn->counter[NFSD_STATS_IO_WRITE]));
 
        /* thread usage: */
        seq_printf(seq, "th %u 0", atomic_read(&nfsdstats.th_cnt));
@@ -63,7 +65,7 @@ static int nfsd_show(struct seq_file *seq, void *v)
        seq_printf(seq,"proc4ops %u", LAST_NFS4_OP + 1);
        for (i = 0; i <= LAST_NFS4_OP; i++) {
                seq_printf(seq, " %lld",
-                          percpu_counter_sum_positive(&nfsdstats.counter[NFSD_STATS_NFS4_OP(i)]));
+                          percpu_counter_sum_positive(&nn->counter[NFSD_STATS_NFS4_OP(i)]));
        }
 
        seq_putc(seq, '\n');
@@ -106,14 +108,14 @@ void nfsd_percpu_counters_destroy(struct percpu_counter counters[], int num)
                percpu_counter_destroy(&counters[i]);
 }
 
-int nfsd_stat_counters_init(void)
+int nfsd_stat_counters_init(struct nfsd_net *nn)
 {
-       return nfsd_percpu_counters_init(nfsdstats.counter, NFSD_STATS_COUNTERS_NUM);
+       return nfsd_percpu_counters_init(nn->counter, NFSD_STATS_COUNTERS_NUM);
 }
 
-void nfsd_stat_counters_destroy(void)
+void nfsd_stat_counters_destroy(struct nfsd_net *nn)
 {
-       nfsd_percpu_counters_destroy(nfsdstats.counter, NFSD_STATS_COUNTERS_NUM);
+       nfsd_percpu_counters_destroy(nn->counter, NFSD_STATS_COUNTERS_NUM);
 }
 
 void nfsd_proc_stat_init(struct net *net)
index 31756a9a8a0ac471a9a65f95962b36d03ae14e3a..28f5c720e9b39118c3eed416e55b95bad854aafd 100644 (file)
 #include <uapi/linux/nfsd/stats.h>
 #include <linux/percpu_counter.h>
 
-
-enum {
-       NFSD_STATS_RC_HITS,             /* repcache hits */
-       NFSD_STATS_RC_MISSES,           /* repcache misses */
-       NFSD_STATS_RC_NOCACHE,          /* uncached reqs */
-       NFSD_STATS_FH_STALE,            /* FH stale error */
-       NFSD_STATS_IO_READ,             /* bytes returned to read requests */
-       NFSD_STATS_IO_WRITE,            /* bytes passed in write requests */
-#ifdef CONFIG_NFSD_V4
-       NFSD_STATS_FIRST_NFS4_OP,       /* count of individual nfsv4 operations */
-       NFSD_STATS_LAST_NFS4_OP = NFSD_STATS_FIRST_NFS4_OP + LAST_NFS4_OP,
-#define NFSD_STATS_NFS4_OP(op) (NFSD_STATS_FIRST_NFS4_OP + (op))
-#endif
-       NFSD_STATS_COUNTERS_NUM
-};
-
 struct nfsd_stats {
-       struct percpu_counter   counter[NFSD_STATS_COUNTERS_NUM];
-
        atomic_t        th_cnt;         /* number of available threads */
 };
 
@@ -39,43 +21,46 @@ extern struct svc_stat              nfsd_svcstats;
 int nfsd_percpu_counters_init(struct percpu_counter *counters, int num);
 void nfsd_percpu_counters_reset(struct percpu_counter *counters, int num);
 void nfsd_percpu_counters_destroy(struct percpu_counter *counters, int num);
-int nfsd_stat_counters_init(void);
-void nfsd_stat_counters_destroy(void);
+int nfsd_stat_counters_init(struct nfsd_net *nn);
+void nfsd_stat_counters_destroy(struct nfsd_net *nn);
 void nfsd_proc_stat_init(struct net *net);
 void nfsd_proc_stat_shutdown(struct net *net);
 
-static inline void nfsd_stats_rc_hits_inc(void)
+static inline void nfsd_stats_rc_hits_inc(struct nfsd_net *nn)
 {
-       percpu_counter_inc(&nfsdstats.counter[NFSD_STATS_RC_HITS]);
+       percpu_counter_inc(&nn->counter[NFSD_STATS_RC_HITS]);
 }
 
-static inline void nfsd_stats_rc_misses_inc(void)
+static inline void nfsd_stats_rc_misses_inc(struct nfsd_net *nn)
 {
-       percpu_counter_inc(&nfsdstats.counter[NFSD_STATS_RC_MISSES]);
+       percpu_counter_inc(&nn->counter[NFSD_STATS_RC_MISSES]);
 }
 
-static inline void nfsd_stats_rc_nocache_inc(void)
+static inline void nfsd_stats_rc_nocache_inc(struct nfsd_net *nn)
 {
-       percpu_counter_inc(&nfsdstats.counter[NFSD_STATS_RC_NOCACHE]);
+       percpu_counter_inc(&nn->counter[NFSD_STATS_RC_NOCACHE]);
 }
 
-static inline void nfsd_stats_fh_stale_inc(struct svc_export *exp)
+static inline void nfsd_stats_fh_stale_inc(struct nfsd_net *nn,
+                                          struct svc_export *exp)
 {
-       percpu_counter_inc(&nfsdstats.counter[NFSD_STATS_FH_STALE]);
+       percpu_counter_inc(&nn->counter[NFSD_STATS_FH_STALE]);
        if (exp && exp->ex_stats)
                percpu_counter_inc(&exp->ex_stats->counter[EXP_STATS_FH_STALE]);
 }
 
-static inline void nfsd_stats_io_read_add(struct svc_export *exp, s64 amount)
+static inline void nfsd_stats_io_read_add(struct nfsd_net *nn,
+                                         struct svc_export *exp, s64 amount)
 {
-       percpu_counter_add(&nfsdstats.counter[NFSD_STATS_IO_READ], amount);
+       percpu_counter_add(&nn->counter[NFSD_STATS_IO_READ], amount);
        if (exp && exp->ex_stats)
                percpu_counter_add(&exp->ex_stats->counter[EXP_STATS_IO_READ], amount);
 }
 
-static inline void nfsd_stats_io_write_add(struct svc_export *exp, s64 amount)
+static inline void nfsd_stats_io_write_add(struct nfsd_net *nn,
+                                          struct svc_export *exp, s64 amount)
 {
-       percpu_counter_add(&nfsdstats.counter[NFSD_STATS_IO_WRITE], amount);
+       percpu_counter_add(&nn->counter[NFSD_STATS_IO_WRITE], amount);
        if (exp && exp->ex_stats)
                percpu_counter_add(&exp->ex_stats->counter[EXP_STATS_IO_WRITE], amount);
 }
index 0ea05ddff0d08f3f149e990c70a54aabf3d8c2b3..dab44f187d01399417f15b1e5c2dd6f9e3a5e60b 100644 (file)
@@ -1000,7 +1000,9 @@ static __be32 nfsd_finish_read(struct svc_rqst *rqstp, struct svc_fh *fhp,
                               unsigned long *count, u32 *eof, ssize_t host_err)
 {
        if (host_err >= 0) {
-               nfsd_stats_io_read_add(fhp->fh_export, host_err);
+               struct nfsd_net *nn = net_generic(SVC_NET(rqstp), nfsd_net_id);
+
+               nfsd_stats_io_read_add(nn, fhp->fh_export, host_err);
                *eof = nfsd_eof_on_read(file, offset, host_err, *count);
                *count = host_err;
                fsnotify_access(file);
@@ -1143,7 +1145,7 @@ nfsd_vfs_write(struct svc_rqst *rqstp, struct svc_fh *fhp, struct nfsd_file *nf,
                goto out_nfserr;
        }
        *cnt = host_err;
-       nfsd_stats_io_write_add(exp, *cnt);
+       nfsd_stats_io_write_add(nn, exp, *cnt);
        fsnotify_modify(file);
        host_err = filemap_check_wb_err(file->f_mapping, since);
        if (host_err < 0)