]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/commitdiff
xfs: make xfs btree stats less huge
authorDave Chinner <dchinner@redhat.com>
Tue, 10 Jan 2017 02:18:49 +0000 (20:18 -0600)
committerEric Sandeen <sandeen@redhat.com>
Tue, 10 Jan 2017 02:18:49 +0000 (20:18 -0600)
Source kernel commit: 11ef38afe98cc7ad1a46ef24945232ec1760d5e2

Embedding a switch statement in every btree stats inc/add adds a lot
of code overhead to the core btree infrastructure paths. Stats are
supposed to be small and lightweight, but the btree stats have
become big and bloated as we've added more btrees. It needs fixing
because the reflink code will just add more overhead again.

Convert the v2 btree stats to arrays instead of independent
variables, and instead use the type to index the specific btree
array via an enum. This allows us to use array based indexing
to update the stats, rather than having to derefence variables
specific to the btree type.

If we then wrap the xfsstats structure in a union and place uint32_t
array beside it, and calculate the correct btree stats array base
array index when creating a btree cursor,  we can easily access
entries in the stats structure without having to switch names based
on the btree type.

We then replace with the switch statement with a simple set of stats
wrapper macros, resulting in a significant simplification of the
btree stats code, and:

text    data     bss     dec     hex filename
48905     144       8   49057    bfa1 fs/xfs/libxfs/xfs_btree.o.old
36793     144       8   36945    9051 fs/xfs/libxfs/xfs_btree.o

it reduces the core btree infrastructure code size by close to 25%!

Signed-off-by: Dave Chinner <dchinner@redhat.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Dave Chinner <david@fromorbit.com>
Signed-off-by: Eric Sandeen <sandeen@sandeen.net>
libxfs/libxfs_priv.h
libxfs/xfs_alloc_btree.c
libxfs/xfs_bmap_btree.c
libxfs/xfs_btree.h
libxfs/xfs_ialloc_btree.c
libxfs/xfs_refcount_btree.c
libxfs/xfs_rmap_btree.c

index 0c4baa809d775cfdfeb1285b60133cf6d0767b21..14ae78897d46708ce61839455a4ce74a9bd1129c 100644 (file)
@@ -521,4 +521,10 @@ bool xfs_log_check_lsn(struct xfs_mount *, xfs_lsn_t);
 #define xfs_inode_set_cowblocks_tag(ip)
 #define xfs_inode_set_eofblocks_tag(ip)
 
+/* xfs_stats.h */
+#define XFS_STATS_CALC_INDEX(member)   0
+#define XFS_STATS_INC_OFF(mp, off)
+#define XFS_STATS_ADD_OFF(mp, off, val)
+
+
 #endif /* __LIBXFS_INTERNAL_XFS_H__ */
index ff4bae4206872392b4e308c89fcd271ea0c3c824..58a36e5502eff1f7a9b4339b35b86d5bd744d77d 100644 (file)
@@ -426,6 +426,10 @@ xfs_allocbt_init_cursor(
        cur->bc_btnum = btnum;
        cur->bc_blocklog = mp->m_sb.sb_blocklog;
        cur->bc_ops = &xfs_allocbt_ops;
+       if (btnum == XFS_BTNUM_BNO)
+               cur->bc_statoff = XFS_STATS_CALC_INDEX(xs_abtb_2);
+       else
+               cur->bc_statoff = XFS_STATS_CALC_INDEX(xs_abtc_2);
 
        if (btnum == XFS_BTNUM_CNT) {
                cur->bc_nlevels = be32_to_cpu(agf->agf_levels[XFS_BTNUM_CNT]);
index 601385d4eba0eb86f66c747c46313c940fc0c1ac..89ba30799845723fce9053cb9f9242e734bcb393 100644 (file)
@@ -800,6 +800,7 @@ xfs_bmbt_init_cursor(
        cur->bc_nlevels = be16_to_cpu(ifp->if_broot->bb_level) + 1;
        cur->bc_btnum = XFS_BTNUM_BMAP;
        cur->bc_blocklog = mp->m_sb.sb_blocklog;
+       cur->bc_statoff = XFS_STATS_CALC_INDEX(xs_bmbt_2);
 
        cur->bc_ops = &xfs_bmbt_ops;
        cur->bc_flags = XFS_BTREE_LONG_PTRS | XFS_BTREE_ROOT_IN_INODE;
index eb20376f2ddb6123546b636e2000b272001d3914..30ef4e51c90c080e0f16426208d4c71ea569e425 100644 (file)
@@ -96,46 +96,10 @@ union xfs_btree_rec {
 /*
  * Generic stats interface
  */
-#define __XFS_BTREE_STATS_INC(mp, type, stat) \
-       XFS_STATS_INC(mp, xs_ ## type ## _2_ ## stat)
 #define XFS_BTREE_STATS_INC(cur, stat) \
-do {    \
-       struct xfs_mount *__mp = cur->bc_mp; \
-       switch (cur->bc_btnum) {  \
-       case XFS_BTNUM_BNO: __XFS_BTREE_STATS_INC(__mp, abtb, stat); break; \
-       case XFS_BTNUM_CNT: __XFS_BTREE_STATS_INC(__mp, abtc, stat); break; \
-       case XFS_BTNUM_BMAP: __XFS_BTREE_STATS_INC(__mp, bmbt, stat); break; \
-       case XFS_BTNUM_INO: __XFS_BTREE_STATS_INC(__mp, ibt, stat); break; \
-       case XFS_BTNUM_FINO: __XFS_BTREE_STATS_INC(__mp, fibt, stat); break; \
-       case XFS_BTNUM_RMAP: __XFS_BTREE_STATS_INC(__mp, rmap, stat); break; \
-       case XFS_BTNUM_REFC: __XFS_BTREE_STATS_INC(__mp, refcbt, stat); break; \
-       case XFS_BTNUM_MAX: ASSERT(0); __mp = __mp /* fucking gcc */ ; break; \
-       }       \
-} while (0)
-
-#define __XFS_BTREE_STATS_ADD(mp, type, stat, val) \
-       XFS_STATS_ADD(mp, xs_ ## type ## _2_ ## stat, val)
-#define XFS_BTREE_STATS_ADD(cur, stat, val)  \
-do {    \
-       struct xfs_mount *__mp = cur->bc_mp; \
-       switch (cur->bc_btnum) {  \
-       case XFS_BTNUM_BNO:     \
-               __XFS_BTREE_STATS_ADD(__mp, abtb, stat, val); break; \
-       case XFS_BTNUM_CNT:     \
-               __XFS_BTREE_STATS_ADD(__mp, abtc, stat, val); break; \
-       case XFS_BTNUM_BMAP:    \
-               __XFS_BTREE_STATS_ADD(__mp, bmbt, stat, val); break; \
-       case XFS_BTNUM_INO:     \
-               __XFS_BTREE_STATS_ADD(__mp, ibt, stat, val); break; \
-       case XFS_BTNUM_FINO:    \
-               __XFS_BTREE_STATS_ADD(__mp, fibt, stat, val); break; \
-       case XFS_BTNUM_RMAP:    \
-               __XFS_BTREE_STATS_ADD(__mp, rmap, stat, val); break; \
-       case XFS_BTNUM_REFC:    \
-               __XFS_BTREE_STATS_ADD(__mp, refcbt, stat, val); break; \
-       case XFS_BTNUM_MAX: ASSERT(0); __mp = __mp /* fucking gcc */ ; break; \
-       }       \
-} while (0)
+       XFS_STATS_INC_OFF((cur)->bc_mp, (cur)->bc_statoff + __XBTS_ ## stat)
+#define XFS_BTREE_STATS_ADD(cur, stat, val)    \
+       XFS_STATS_ADD_OFF((cur)->bc_mp, (cur)->bc_statoff + __XBTS_ ## stat, val)
 
 #define        XFS_BTREE_MAXLEVELS     9       /* max of all btrees */
 
@@ -253,6 +217,7 @@ typedef struct xfs_btree_cur
        __uint8_t       bc_nlevels;     /* number of levels in the tree */
        __uint8_t       bc_blocklog;    /* log2(blocksize) of btree blocks */
        xfs_btnum_t     bc_btnum;       /* identifies which btree type */
+       int             bc_statoff;     /* offset of btre stats array */
        union {
                struct {                        /* needed for BNO, CNT, INO */
                        struct xfs_buf  *agbp;  /* agf/agi buffer pointer */
index 7bf6040ccee578e8923110de6128d99603fa7c4c..4cb182ffd08ebe7e41ca31085f68c2455a21b97f 100644 (file)
@@ -364,9 +364,11 @@ xfs_inobt_init_cursor(
        if (btnum == XFS_BTNUM_INO) {
                cur->bc_nlevels = be32_to_cpu(agi->agi_level);
                cur->bc_ops = &xfs_inobt_ops;
+               cur->bc_statoff = XFS_STATS_CALC_INDEX(xs_ibt_2);
        } else {
                cur->bc_nlevels = be32_to_cpu(agi->agi_free_level);
                cur->bc_ops = &xfs_finobt_ops;
+               cur->bc_statoff = XFS_STATS_CALC_INDEX(xs_fibt_2);
        }
 
        cur->bc_blocklog = mp->m_sb.sb_blocklog;
index 50c4682ef9068f26c79390332ad94d7b9a4e2f42..7c066257b6c6f972fa981fa8c3a4ba0dc72558ba 100644 (file)
@@ -353,6 +353,7 @@ xfs_refcountbt_init_cursor(
        cur->bc_btnum = XFS_BTNUM_REFC;
        cur->bc_blocklog = mp->m_sb.sb_blocklog;
        cur->bc_ops = &xfs_refcountbt_ops;
+       cur->bc_statoff = XFS_STATS_CALC_INDEX(xs_refcbt_2);
 
        cur->bc_nlevels = be32_to_cpu(agf->agf_refcount_level);
 
index d11112aaceb5a31900abf81e4c027acd7a573c30..30ddcda4e9a86fcc24b98451e625cee545e83d62 100644 (file)
@@ -482,6 +482,7 @@ xfs_rmapbt_init_cursor(
        cur->bc_blocklog = mp->m_sb.sb_blocklog;
        cur->bc_ops = &xfs_rmapbt_ops;
        cur->bc_nlevels = be32_to_cpu(agf->agf_levels[XFS_BTNUM_RMAP]);
+       cur->bc_statoff = XFS_STATS_CALC_INDEX(xs_rmap_2);
 
        cur->bc_private.a.agbp = agbp;
        cur->bc_private.a.agno = agno;