nfsd: make all of the nfsd stats per-network namespace
authorJosef Bacik <josef@toxicpanda.com>
Fri, 26 Jan 2024 15:39:47 +0000 (10:39 -0500)
committerChuck Lever <chuck.lever@oracle.com>
Fri, 1 Mar 2024 14:12:10 +0000 (09:12 -0500)
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>
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
fs/nfsd/cache.h
fs/nfsd/netns.h
fs/nfsd/nfs4proc.c
fs/nfsd/nfs4state.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 4cbe0434cbb8ce973865153ddf4a9d7c332bea5e..66a05fefae98eacd29e227de6883ffe56998fb18 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 *rqstp, unsigned int start,
index e3605cb5f044d8a3c00aef72cfeaf0cb648ef9b4..0cef4bb407a9c6176a840f32995dc4124497fe79 100644 (file)
@@ -11,6 +11,7 @@
 #include <net/net_namespace.h>
 #include <net/netns/generic.h>
 #include <linux/filelock.h>
+#include <linux/nfs4.h>
 #include <linux/percpu_counter.h>
 #include <linux/siphash.h>
 
@@ -29,7 +30,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
 };
 
 /*
@@ -164,7 +177,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 14712fa08f769ea37b78e51c3672366c4b6e8bf0..648ff427005e6ccdea657949134c36332ff5a337 100644 (file)
@@ -2490,10 +2490,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[];
@@ -2768,7 +2768,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 7d6c657e0409ddc62567554304e4a51779dd2934..0ff7f83ac6c8727a3f342819190723a372281554 100644 (file)
@@ -8450,6 +8450,7 @@ __be32
 nfsd4_deleg_getattr_conflict(struct svc_rqst *rqstp, struct inode *inode)
 {
        __be32 status;
+       struct nfsd_net *nn = net_generic(SVC_NET(rqstp), nfsd_net_id);
        struct file_lock_context *ctx;
        struct file_lock *fl;
        struct nfs4_delegation *dp;
@@ -8479,7 +8480,7 @@ nfsd4_deleg_getattr_conflict(struct svc_rqst *rqstp, struct inode *inode)
                        }
 break_lease:
                        spin_unlock(&ctx->flc_lock);
-                       nfsd_stats_wdeleg_getattr_inc();
+                       nfsd_stats_wdeleg_getattr_inc(nn);
                        status = nfserrno(nfsd_open_break_lease(inode, NFSD_MAY_READ));
                        if (status != nfserr_jukebox ||
                                        !nfsd_wait_for_delegreturn(rqstp, inode))
index 3d4a9d181c43e22afb551daf2454fa3b74cea494..cfcc6ac8f255a89b1f9f0d6a6022e5037e74654d 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;
@@ -501,7 +480,7 @@ out:
 int nfsd_cache_lookup(struct svc_rqst *rqstp, unsigned int start,
                      unsigned int len, struct nfsd_cacherep **cacherep)
 {
-       struct nfsd_net         *nn;
+       struct nfsd_net         *nn = net_generic(SVC_NET(rqstp), nfsd_net_id);
        struct nfsd_cacherep    *rp, *found;
        __wsum                  csum;
        struct nfsd_drc_bucket  *b;
@@ -510,7 +489,7 @@ int nfsd_cache_lookup(struct svc_rqst *rqstp, unsigned int start,
        int rtn = RC_DOIT;
 
        if (type == RC_NOCACHE) {
-               nfsd_stats_rc_nocache_inc();
+               nfsd_stats_rc_nocache_inc(nn);
                goto out;
        }
 
@@ -520,7 +499,6 @@ int nfsd_cache_lookup(struct svc_rqst *rqstp, unsigned int start,
         * 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;
@@ -537,7 +515,7 @@ int nfsd_cache_lookup(struct svc_rqst *rqstp, unsigned int start,
 
        nfsd_cacherep_dispose(&dispose);
 
-       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;
@@ -545,7 +523,7 @@ int nfsd_cache_lookup(struct svc_rqst *rqstp, unsigned int start,
 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;
 
@@ -689,11 +667,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 b57480b50e350c929b481c7a30a0b954944c777f..ea3c8114245c28dcff43347f39dd849383491d37 100644 (file)
@@ -1671,7 +1671,7 @@ static __net_init int nfsd_net_init(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;
@@ -1701,7 +1701,7 @@ static __net_exit void nfsd_net_exit(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);
@@ -1724,12 +1724,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)
@@ -1763,8 +1760,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:
@@ -1782,7 +1777,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 dbfa0ac13564aca709723be1ca9e5f6458ce93c9..40fecf7b224f2fab00747c1b385a37f1bbd8923b 100644 (file)
@@ -327,6 +327,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;
@@ -395,7 +396,7 @@ skip_pseudoflavor_check:
 out:
        trace_nfsd_fh_verify_err(rqstp, fhp, type, access, error);
        if (error == nfserr_stale)
-               nfsd_stats_fh_stale_inc(exp);
+               nfsd_stats_fh_stale_inc(nn, exp);
        return error;
 }
 
index 394a65a33942d7c8a62c9fc302dcf7cae3085819..44e275324b06e50b68ec47cd0c6d2a026d05007b 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,10 +65,10 @@ 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_printf(seq, "\nwdeleg_getattr %lld",
-               percpu_counter_sum_positive(&nfsdstats.counter[NFSD_STATS_WDELEG_GETATTR]));
+               percpu_counter_sum_positive(&nn->counter[NFSD_STATS_WDELEG_GETATTR]));
 
        seq_putc(seq, '\n');
 #endif
@@ -108,14 +110,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 38811aa7d13e1e368e51c8927d9ad69954a0218e..c24be4ddbe7d7076f627c313922f11bdb1390242 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))
-       NFSD_STATS_WDELEG_GETATTR,      /* count of getattr conflict with wdeleg */
-#endif
-       NFSD_STATS_COUNTERS_NUM
-};
-
 struct nfsd_stats {
-       struct percpu_counter   counter[NFSD_STATS_COUNTERS_NUM];
-
        atomic_t        th_cnt;         /* number of available threads */
 };
 
@@ -40,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);
 }
@@ -97,9 +81,9 @@ static inline void nfsd_stats_drc_mem_usage_sub(struct nfsd_net *nn, s64 amount)
 }
 
 #ifdef CONFIG_NFSD_V4
-static inline void nfsd_stats_wdeleg_getattr_inc(void)
+static inline void nfsd_stats_wdeleg_getattr_inc(struct nfsd_net *nn)
 {
-       percpu_counter_inc(&nfsdstats.counter[NFSD_STATS_WDELEG_GETATTR]);
+       percpu_counter_inc(&nn->counter[NFSD_STATS_WDELEG_GETATTR]);
 }
 #endif
 #endif /* _NFSD_STATS_H */
index f57749cd6f0b1ac778c7d257984c7ca2f428536b..38952105ed7fd4389a847c3b30b4d953cb1a66da 100644 (file)
@@ -1002,7 +1002,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);
@@ -1185,7 +1187,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)