xfs: use common code for quota statistics
authorChristoph Hellwig <hch@infradead.org>
Tue, 13 Mar 2012 08:52:33 +0000 (08:52 +0000)
committerBen Myers <bpm@sgi.com>
Wed, 14 Mar 2012 16:09:06 +0000 (11:09 -0500)
Switch the quota code over to use the generic XFS statistics infrastructure.
While the legacy /proc/fs/xfs/xqm and /proc/fs/xfs/xqmstats interfaces are
preserved for now the statistics that still have a meaning with the current
code are now also available from /proc/fs/xfs/stats.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Dave Chinner <dchinner@redhat.com>
Signed-off-by: Ben Myers <bpm@sgi.com>
fs/xfs/Makefile
fs/xfs/xfs_dquot.c
fs/xfs/xfs_qm.c
fs/xfs/xfs_qm.h
fs/xfs/xfs_qm_bhv.c
fs/xfs/xfs_qm_stats.c [deleted file]
fs/xfs/xfs_qm_stats.h [deleted file]
fs/xfs/xfs_stats.c
fs/xfs/xfs_stats.h

index 427a4e82a588759dbfb49394f73eca9400d455e7..0a9977983f92b358989f3cb01e81cb0e31db27e7 100644 (file)
@@ -96,9 +96,6 @@ xfs-$(CONFIG_XFS_QUOTA)               += xfs_dquot.o \
                                   xfs_qm_bhv.o \
                                   xfs_qm.o \
                                   xfs_quotaops.o
-ifeq ($(CONFIG_XFS_QUOTA),y)
-xfs-$(CONFIG_PROC_FS)          += xfs_qm_stats.o
-endif
 xfs-$(CONFIG_XFS_RT)           += xfs_rtalloc.o
 xfs-$(CONFIG_XFS_POSIX_ACL)    += xfs_acl.o
 xfs-$(CONFIG_PROC_FS)          += xfs_stats.o
index 71e615fef174336fe92814bd74db7627a966c3fc..98d7e25947fa69c851c720c09fe939e0d40676bc 100644 (file)
@@ -74,7 +74,7 @@ xfs_qm_dqdestroy(
        mutex_destroy(&dqp->q_qlock);
        kmem_zone_free(xfs_Gqm->qm_dqzone, dqp);
 
-       atomic_dec(&xfs_Gqm->qm_totaldquots);
+       XFS_STATS_DEC(xs_qm_dquot);
 }
 
 /*
@@ -516,7 +516,7 @@ xfs_qm_dqread(
        if (!(type & XFS_DQ_USER))
                lockdep_set_class(&dqp->q_qlock, &xfs_dquot_other_class);
 
-       atomic_inc(&xfs_Gqm->qm_totaldquots);
+       XFS_STATS_INC(xs_qm_dquot);
 
        trace_xfs_dqread(dqp);
 
@@ -712,12 +712,12 @@ restart:
         */
        switch (xfs_qm_dqlookup(mp, id, h, O_dqpp)) {
        case -1:
-               XQM_STATS_INC(xqmstats.xs_qm_dquot_dups);
+               XFS_STATS_INC(xs_qm_dquot_dups);
                mutex_unlock(&h->qh_lock);
                delay(1);
                goto restart;
        case 0:
-               XQM_STATS_INC(xqmstats.xs_qm_dqcachehits);
+               XFS_STATS_INC(xs_qm_dqcachehits);
                /*
                 * The dquot was found, moved to the front of the chain,
                 * taken off the freelist if it was on it, and locked
@@ -729,7 +729,7 @@ restart:
                trace_xfs_dqget_hit(*O_dqpp);
                return 0;       /* success */
        default:
-               XQM_STATS_INC(xqmstats.xs_qm_dqcachemisses);
+               XFS_STATS_INC(xs_qm_dqcachemisses);
                break;
        }
 
@@ -804,7 +804,7 @@ restart:
                                xfs_qm_dqput(tmpdqp);
                        mutex_unlock(&h->qh_lock);
                        xfs_qm_dqdestroy(dqp);
-                       XQM_STATS_INC(xqmstats.xs_qm_dquot_dups);
+                       XFS_STATS_INC(xs_qm_dquot_dups);
                        goto restart;
                default:
                        break;
@@ -873,6 +873,7 @@ recurse:
        if (list_empty(&dqp->q_freelist)) {
                list_add_tail(&dqp->q_freelist, &xfs_Gqm->qm_dqfrlist);
                xfs_Gqm->qm_dqfrlist_cnt++;
+               XFS_STATS_INC(xs_qm_dquot_unused);
        }
        mutex_unlock(&xfs_Gqm->qm_dqfrlist_lock);
 
@@ -1178,6 +1179,7 @@ xfs_qm_dqpurge(
        ASSERT(!list_empty(&dqp->q_freelist));
        list_del_init(&dqp->q_freelist);
        xfs_Gqm->qm_dqfrlist_cnt--;
+       XFS_STATS_DEC(xs_qm_dquot_unused);
        mutex_unlock(&xfs_Gqm->qm_dqfrlist_lock);
 
        xfs_qm_dqdestroy(dqp);
index c872feaf3697f1014823372e4b0f81ada5234631..0dde1f48c280a37b7390f0c2cefc18436f814193 100644 (file)
@@ -134,7 +134,6 @@ xfs_Gqm_init(void)
        } else
                xqm->qm_dqtrxzone = qm_dqtrxzone;
 
-       atomic_set(&xqm->qm_totaldquots, 0);
        xqm->qm_nrefs = 0;
        return xqm;
 
@@ -1637,10 +1636,11 @@ xfs_qm_dqreclaim_one(
                xfs_dqunlock(dqp);
 
                trace_xfs_dqreclaim_want(dqp);
-               XQM_STATS_INC(xqmstats.xs_qm_dqwants);
+               XFS_STATS_INC(xs_qm_dqwants);
 
                list_del_init(&dqp->q_freelist);
                xfs_Gqm->qm_dqfrlist_cnt--;
+               XFS_STATS_DEC(xs_qm_dquot_unused);
                return;
        }
 
@@ -1690,9 +1690,10 @@ xfs_qm_dqreclaim_one(
        ASSERT(dqp->q_nrefs == 0);
        list_move_tail(&dqp->q_freelist, dispose_list);
        xfs_Gqm->qm_dqfrlist_cnt--;
+       XFS_STATS_DEC(xs_qm_dquot_unused);
 
        trace_xfs_dqreclaim_done(dqp);
-       XQM_STATS_INC(xqmstats.xs_qm_dqreclaims);
+       XFS_STATS_INC(xs_qm_dqreclaims);
        return;
 
 out_busy:
@@ -1704,7 +1705,7 @@ out_busy:
        list_move_tail(&dqp->q_freelist, &xfs_Gqm->qm_dqfrlist);
 
        trace_xfs_dqreclaim_busy(dqp);
-       XQM_STATS_INC(xqmstats.xs_qm_dqreclaim_misses);
+       XFS_STATS_INC(xs_qm_dqreclaim_misses);
 }
 
 STATIC int
index 9a9b997e1a0a294bd6f180ccaac011f2ec49a517..89f213f7252a4ac88378da3832e5debd96ec3506 100644 (file)
@@ -21,7 +21,6 @@
 #include "xfs_dquot_item.h"
 #include "xfs_dquot.h"
 #include "xfs_quota_priv.h"
-#include "xfs_qm_stats.h"
 
 struct xfs_qm;
 struct xfs_inode;
@@ -60,7 +59,6 @@ typedef struct xfs_qm {
        struct list_head qm_dqfrlist;    /* freelist of dquots */
        struct mutex     qm_dqfrlist_lock;
        int              qm_dqfrlist_cnt;
-       atomic_t         qm_totaldquots; /* total incore dquots */
        uint             qm_nrefs;       /* file systems with quota on */
        kmem_zone_t     *qm_dqzone;      /* dquot mem-alloc zone */
        kmem_zone_t     *qm_dqtrxzone;   /* t_dqinfo of transactions */
index e4e37877f867a511efb91683ba2bcd66566376f0..809f86857c6d4899d8794d3d8d344be453fe1ff6 100644 (file)
@@ -162,13 +162,11 @@ xfs_qm_init(void)
 {
        printk(KERN_INFO "SGI XFS Quota Management subsystem\n");
        mutex_init(&xfs_Gqm_lock);
-       xfs_qm_init_procfs();
 }
 
 void __exit
 xfs_qm_exit(void)
 {
-       xfs_qm_cleanup_procfs();
        if (qm_dqzone)
                kmem_zone_destroy(qm_dqzone);
        if (qm_dqtrxzone)
diff --git a/fs/xfs/xfs_qm_stats.c b/fs/xfs/xfs_qm_stats.c
deleted file mode 100644 (file)
index 5729ba5..0000000
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- * Copyright (c) 2000-2003 Silicon Graphics, Inc.
- * All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it would be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write the Free Software Foundation,
- * Inc.,  51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- */
-#include "xfs.h"
-#include "xfs_fs.h"
-#include "xfs_bit.h"
-#include "xfs_log.h"
-#include "xfs_inum.h"
-#include "xfs_trans.h"
-#include "xfs_sb.h"
-#include "xfs_ag.h"
-#include "xfs_alloc.h"
-#include "xfs_quota.h"
-#include "xfs_mount.h"
-#include "xfs_bmap_btree.h"
-#include "xfs_inode.h"
-#include "xfs_itable.h"
-#include "xfs_bmap.h"
-#include "xfs_rtalloc.h"
-#include "xfs_error.h"
-#include "xfs_attr.h"
-#include "xfs_buf_item.h"
-#include "xfs_qm.h"
-
-struct xqmstats xqmstats;
-
-static int xqm_proc_show(struct seq_file *m, void *v)
-{
-       /* maximum; incore; ratio free to inuse; freelist */
-       seq_printf(m, "%d\t%d\t%d\t%u\n",
-                       0,
-                       xfs_Gqm? atomic_read(&xfs_Gqm->qm_totaldquots) : 0,
-                       0,
-                       xfs_Gqm? xfs_Gqm->qm_dqfrlist_cnt : 0);
-       return 0;
-}
-
-static int xqm_proc_open(struct inode *inode, struct file *file)
-{
-       return single_open(file, xqm_proc_show, NULL);
-}
-
-static const struct file_operations xqm_proc_fops = {
-       .owner          = THIS_MODULE,
-       .open           = xqm_proc_open,
-       .read           = seq_read,
-       .llseek         = seq_lseek,
-       .release        = single_release,
-};
-
-static int xqmstat_proc_show(struct seq_file *m, void *v)
-{
-       /* quota performance statistics */
-       seq_printf(m, "qm %u %u %u %u %u %u %u %u\n",
-                       xqmstats.xs_qm_dqreclaims,
-                       xqmstats.xs_qm_dqreclaim_misses,
-                       xqmstats.xs_qm_dquot_dups,
-                       xqmstats.xs_qm_dqcachemisses,
-                       xqmstats.xs_qm_dqcachehits,
-                       xqmstats.xs_qm_dqwants,
-                       xqmstats.xs_qm_dqshake_reclaims,
-                       xqmstats.xs_qm_dqinact_reclaims);
-       return 0;
-}
-
-static int xqmstat_proc_open(struct inode *inode, struct file *file)
-{
-       return single_open(file, xqmstat_proc_show, NULL);
-}
-
-static const struct file_operations xqmstat_proc_fops = {
-       .owner          = THIS_MODULE,
-       .open           = xqmstat_proc_open,
-       .read           = seq_read,
-       .llseek         = seq_lseek,
-       .release        = single_release,
-};
-
-void
-xfs_qm_init_procfs(void)
-{
-       proc_create("fs/xfs/xqmstat", 0, NULL, &xqmstat_proc_fops);
-       proc_create("fs/xfs/xqm", 0, NULL, &xqm_proc_fops);
-}
-
-void
-xfs_qm_cleanup_procfs(void)
-{
-       remove_proc_entry("fs/xfs/xqm", NULL);
-       remove_proc_entry("fs/xfs/xqmstat", NULL);
-}
diff --git a/fs/xfs/xfs_qm_stats.h b/fs/xfs/xfs_qm_stats.h
deleted file mode 100644 (file)
index 5b964fc..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Copyright (c) 2002 Silicon Graphics, Inc.
- * All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it would be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write the Free Software Foundation,
- * Inc.,  51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- */
-#ifndef __XFS_QM_STATS_H__
-#define __XFS_QM_STATS_H__
-
-#if defined(CONFIG_PROC_FS) && !defined(XFS_STATS_OFF)
-
-/*
- * XQM global statistics
- */
-struct xqmstats {
-       __uint32_t              xs_qm_dqreclaims;
-       __uint32_t              xs_qm_dqreclaim_misses;
-       __uint32_t              xs_qm_dquot_dups;
-       __uint32_t              xs_qm_dqcachemisses;
-       __uint32_t              xs_qm_dqcachehits;
-       __uint32_t              xs_qm_dqwants;
-       __uint32_t              xs_qm_dqshake_reclaims;
-       __uint32_t              xs_qm_dqinact_reclaims;
-};
-
-extern struct xqmstats xqmstats;
-
-# define XQM_STATS_INC(count)  ( (count)++ )
-
-extern void xfs_qm_init_procfs(void);
-extern void xfs_qm_cleanup_procfs(void);
-
-#else
-
-# define XQM_STATS_INC(count)  do { } while (0)
-
-static inline void xfs_qm_init_procfs(void) { };
-static inline void xfs_qm_cleanup_procfs(void) { };
-
-#endif
-
-#endif /* __XFS_QM_STATS_H__ */
index 76fdc5861932f8ed5412b4345dbb59a1054f8f9c..ce372b7d5644600ec6e52a23f8ec00584e1f2e9c 100644 (file)
 
 DEFINE_PER_CPU(struct xfsstats, xfsstats);
 
+static int counter_val(int idx)
+{
+       int val = 0, cpu;
+
+       for_each_possible_cpu(cpu)
+               val += *(((__u32 *)&per_cpu(xfsstats, cpu) + idx));
+       return val;
+}
+
 static int xfs_stat_proc_show(struct seq_file *m, void *v)
 {
-       int             c, i, j, val;
+       int             i, j;
        __uint64_t      xs_xstrat_bytes = 0;
        __uint64_t      xs_write_bytes = 0;
        __uint64_t      xs_read_bytes = 0;
@@ -50,20 +59,16 @@ static int xfs_stat_proc_show(struct seq_file *m, void *v)
                { "abtc2",              XFSSTAT_END_ABTC_V2             },
                { "bmbt2",              XFSSTAT_END_BMBT_V2             },
                { "ibt2",               XFSSTAT_END_IBT_V2              },
+               /* we print both series of quota information together */
+               { "qm",                 XFSSTAT_END_QM                  },
        };
 
        /* Loop over all stats groups */
-       for (i=j = 0; i < ARRAY_SIZE(xstats); i++) {
+       for (i = j = 0; i < ARRAY_SIZE(xstats); i++) {
                seq_printf(m, "%s", xstats[i].desc);
                /* inner loop does each group */
-               while (j < xstats[i].endpoint) {
-                       val = 0;
-                       /* sum over all cpus */
-                       for_each_possible_cpu(c)
-                               val += *(((__u32*)&per_cpu(xfsstats, c) + j));
-                       seq_printf(m, " %u", val);
-                       j++;
-               }
+               for (; j < xstats[i].endpoint; j++)
+                       seq_printf(m, " %u", counter_val(j));
                seq_putc(m, '\n');
        }
        /* extra precision counters */
@@ -97,6 +102,58 @@ static const struct file_operations xfs_stat_proc_fops = {
        .release        = single_release,
 };
 
+/* legacy quota interfaces */
+#ifdef CONFIG_XFS_QUOTA
+static int xqm_proc_show(struct seq_file *m, void *v)
+{
+       /* maximum; incore; ratio free to inuse; freelist */
+       seq_printf(m, "%d\t%d\t%d\t%u\n",
+                       0,
+                       counter_val(XFSSTAT_END_XQMSTAT),
+                       0,
+                       counter_val(XFSSTAT_END_XQMSTAT + 1));
+       return 0;
+}
+
+static int xqm_proc_open(struct inode *inode, struct file *file)
+{
+       return single_open(file, xqm_proc_show, NULL);
+}
+
+static const struct file_operations xqm_proc_fops = {
+       .owner          = THIS_MODULE,
+       .open           = xqm_proc_open,
+       .read           = seq_read,
+       .llseek         = seq_lseek,
+       .release        = single_release,
+};
+
+/* legacy quota stats interface no 2 */
+static int xqmstat_proc_show(struct seq_file *m, void *v)
+{
+       int j;
+
+       seq_printf(m, "qm");
+       for (j = XFSSTAT_END_IBT_V2; j < XFSSTAT_END_XQMSTAT; j++)
+               seq_printf(m, " %u", counter_val(j));
+       seq_putc(m, '\n');
+       return 0;
+}
+
+static int xqmstat_proc_open(struct inode *inode, struct file *file)
+{
+       return single_open(file, xqmstat_proc_show, NULL);
+}
+
+static const struct file_operations xqmstat_proc_fops = {
+       .owner          = THIS_MODULE,
+       .open           = xqmstat_proc_open,
+       .read           = seq_read,
+       .llseek         = seq_lseek,
+       .release        = single_release,
+};
+#endif /* CONFIG_XFS_QUOTA */
+
 int
 xfs_init_procfs(void)
 {
@@ -105,10 +162,24 @@ xfs_init_procfs(void)
 
        if (!proc_create("fs/xfs/stat", 0, NULL,
                         &xfs_stat_proc_fops))
-               goto out_remove_entry;
+               goto out_remove_xfs_dir;
+#ifdef CONFIG_XFS_QUOTA
+       if (!proc_create("fs/xfs/xqmstat", 0, NULL,
+                        &xqmstat_proc_fops))
+               goto out_remove_stat_file;
+       if (!proc_create("fs/xfs/xqm", 0, NULL,
+                        &xqm_proc_fops))
+               goto out_remove_xqmstat_file;
+#endif
        return 0;
 
- out_remove_entry:
+#ifdef CONFIG_XFS_QUOTA
+ out_remove_xqmstat_file:
+       remove_proc_entry("fs/xfs/xqmstat", NULL);
+ out_remove_stat_file:
+       remove_proc_entry("fs/xfs/stat", NULL);
+#endif
+ out_remove_xfs_dir:
        remove_proc_entry("fs/xfs", NULL);
  out:
        return -ENOMEM;
@@ -117,6 +188,10 @@ xfs_init_procfs(void)
 void
 xfs_cleanup_procfs(void)
 {
+#ifdef CONFIG_XFS_QUOTA
+       remove_proc_entry("fs/xfs/xqm", NULL);
+       remove_proc_entry("fs/xfs/xqmstat", NULL);
+#endif
        remove_proc_entry("fs/xfs/stat", NULL);
        remove_proc_entry("fs/xfs", NULL);
 }
index 736854b1ca1a0c6d1d92488f6cc79891241b8a6d..c03ad38ceaebaeb8b82a2e0fae785cc592e9adaf 100644 (file)
@@ -183,6 +183,16 @@ struct xfsstats {
        __uint32_t              xs_ibt_2_alloc;
        __uint32_t              xs_ibt_2_free;
        __uint32_t              xs_ibt_2_moves;
+#define XFSSTAT_END_XQMSTAT            (XFSSTAT_END_IBT_V2+6)
+       __uint32_t              xs_qm_dqreclaims;
+       __uint32_t              xs_qm_dqreclaim_misses;
+       __uint32_t              xs_qm_dquot_dups;
+       __uint32_t              xs_qm_dqcachemisses;
+       __uint32_t              xs_qm_dqcachehits;
+       __uint32_t              xs_qm_dqwants;
+#define XFSSTAT_END_QM                 (XFSSTAT_END_XQMSTAT+2)
+       __uint32_t              xs_qm_dquot;
+       __uint32_t              xs_qm_dquot_unused;
 /* Extra precision counters */
        __uint64_t              xs_xstrat_bytes;
        __uint64_t              xs_write_bytes;