linux/fs/nfsd/stats.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2/*
   3 * procfs-based user access to knfsd statistics
   4 *
   5 * /proc/net/rpc/nfsd
   6 *
   7 * Format:
   8 *      rc <hits> <misses> <nocache>
   9 *                      Statistsics for the reply cache
  10 *      fh <stale> <deprecated filehandle cache stats>
  11 *                      statistics for filehandle lookup
  12 *      io <bytes-read> <bytes-written>
  13 *                      statistics for IO throughput
  14 *      th <threads> <deprecated thread usage histogram stats>
  15 *                      number of threads
  16 *      ra <deprecated ra-cache stats>
  17 *
  18 *      plus generic RPC stats (see net/sunrpc/stats.c)
  19 *
  20 * Copyright (C) 1995, 1996, 1997 Olaf Kirch <okir@monad.swb.de>
  21 */
  22
  23#include <linux/seq_file.h>
  24#include <linux/module.h>
  25#include <linux/sunrpc/stats.h>
  26#include <net/net_namespace.h>
  27
  28#include "nfsd.h"
  29
  30struct nfsd_stats       nfsdstats;
  31struct svc_stat         nfsd_svcstats = {
  32        .program        = &nfsd_program,
  33};
  34
  35static int nfsd_proc_show(struct seq_file *seq, void *v)
  36{
  37        int i;
  38
  39        seq_printf(seq, "rc %lld %lld %lld\nfh %lld 0 0 0 0\nio %lld %lld\n",
  40                   percpu_counter_sum_positive(&nfsdstats.counter[NFSD_STATS_RC_HITS]),
  41                   percpu_counter_sum_positive(&nfsdstats.counter[NFSD_STATS_RC_MISSES]),
  42                   percpu_counter_sum_positive(&nfsdstats.counter[NFSD_STATS_RC_NOCACHE]),
  43                   percpu_counter_sum_positive(&nfsdstats.counter[NFSD_STATS_FH_STALE]),
  44                   percpu_counter_sum_positive(&nfsdstats.counter[NFSD_STATS_IO_READ]),
  45                   percpu_counter_sum_positive(&nfsdstats.counter[NFSD_STATS_IO_WRITE]));
  46
  47        /* thread usage: */
  48        seq_printf(seq, "th %u 0", nfsdstats.th_cnt);
  49
  50        /* deprecated thread usage histogram stats */
  51        for (i = 0; i < 10; i++)
  52                seq_puts(seq, " 0.000");
  53
  54        /* deprecated ra-cache stats */
  55        seq_puts(seq, "\nra 0 0 0 0 0 0 0 0 0 0 0 0\n");
  56
  57        /* show my rpc info */
  58        svc_seq_show(seq, &nfsd_svcstats);
  59
  60#ifdef CONFIG_NFSD_V4
  61        /* Show count for individual nfsv4 operations */
  62        /* Writing operation numbers 0 1 2 also for maintaining uniformity */
  63        seq_printf(seq,"proc4ops %u", LAST_NFS4_OP + 1);
  64        for (i = 0; i <= LAST_NFS4_OP; i++) {
  65                seq_printf(seq, " %lld",
  66                           percpu_counter_sum_positive(&nfsdstats.counter[NFSD_STATS_NFS4_OP(i)]));
  67        }
  68
  69        seq_putc(seq, '\n');
  70#endif
  71
  72        return 0;
  73}
  74
  75static int nfsd_proc_open(struct inode *inode, struct file *file)
  76{
  77        return single_open(file, nfsd_proc_show, NULL);
  78}
  79
  80static const struct proc_ops nfsd_proc_ops = {
  81        .proc_open      = nfsd_proc_open,
  82        .proc_read      = seq_read,
  83        .proc_lseek     = seq_lseek,
  84        .proc_release   = single_release,
  85};
  86
  87int nfsd_percpu_counters_init(struct percpu_counter counters[], int num)
  88{
  89        int i, err = 0;
  90
  91        for (i = 0; !err && i < num; i++)
  92                err = percpu_counter_init(&counters[i], 0, GFP_KERNEL);
  93
  94        if (!err)
  95                return 0;
  96
  97        for (; i > 0; i--)
  98                percpu_counter_destroy(&counters[i-1]);
  99
 100        return err;
 101}
 102
 103void nfsd_percpu_counters_reset(struct percpu_counter counters[], int num)
 104{
 105        int i;
 106
 107        for (i = 0; i < num; i++)
 108                percpu_counter_set(&counters[i], 0);
 109}
 110
 111void nfsd_percpu_counters_destroy(struct percpu_counter counters[], int num)
 112{
 113        int i;
 114
 115        for (i = 0; i < num; i++)
 116                percpu_counter_destroy(&counters[i]);
 117}
 118
 119static int nfsd_stat_counters_init(void)
 120{
 121        return nfsd_percpu_counters_init(nfsdstats.counter, NFSD_STATS_COUNTERS_NUM);
 122}
 123
 124static void nfsd_stat_counters_destroy(void)
 125{
 126        nfsd_percpu_counters_destroy(nfsdstats.counter, NFSD_STATS_COUNTERS_NUM);
 127}
 128
 129int nfsd_stat_init(void)
 130{
 131        int err;
 132
 133        err = nfsd_stat_counters_init();
 134        if (err)
 135                return err;
 136
 137        svc_proc_register(&init_net, &nfsd_svcstats, &nfsd_proc_ops);
 138
 139        return 0;
 140}
 141
 142void nfsd_stat_shutdown(void)
 143{
 144        nfsd_stat_counters_destroy();
 145        svc_proc_unregister(&init_net, "nfsd");
 146}
 147