Commit c76febef authored by Dave Chinner's avatar Dave Chinner Committed by Alex Elder

xfs: only run xfs_error_test if error injection is active

Recent tests writing lots of small files showed the flusher thread
being CPU bound and taking a long time to do allocations on a debug
kernel. perf showed this as the prime reason:

             samples  pcnt function                    DSO
             _______ _____ ___________________________ _________________

           224648.00 36.8% xfs_error_test              [kernel.kallsyms]
            86045.00 14.1% xfs_btree_check_sblock      [kernel.kallsyms]
            39778.00  6.5% prandom32                   [kernel.kallsyms]
            37436.00  6.1% xfs_btree_increment         [kernel.kallsyms]
            29278.00  4.8% xfs_btree_get_rec           [kernel.kallsyms]
            27717.00  4.5% random32                    [kernel.kallsyms]

Walking btree blocks during allocation checking them requires each
block (a cache hit, so no I/O) call xfs_error_test(), which then
does a random32() call as the first operation.  IOWs, ~50% of the
CPU is being consumed just testing whether we need to inject an
error, even though error injection is not active.

Kill this overhead when error injection is not active by adding a
global counter of active error traps and only calling into
xfs_error_test when fault injection is active.
Signed-off-by: default avatarDave Chinner <dchinner@redhat.com>
Reviewed-by: default avatarChristoph Hellwig <hch@lst.de>
parent de25c181
...@@ -58,6 +58,7 @@ xfs_error_trap(int e) ...@@ -58,6 +58,7 @@ xfs_error_trap(int e)
int xfs_etest[XFS_NUM_INJECT_ERROR]; int xfs_etest[XFS_NUM_INJECT_ERROR];
int64_t xfs_etest_fsid[XFS_NUM_INJECT_ERROR]; int64_t xfs_etest_fsid[XFS_NUM_INJECT_ERROR];
char * xfs_etest_fsname[XFS_NUM_INJECT_ERROR]; char * xfs_etest_fsname[XFS_NUM_INJECT_ERROR];
int xfs_error_test_active;
int int
xfs_error_test(int error_tag, int *fsidp, char *expression, xfs_error_test(int error_tag, int *fsidp, char *expression,
...@@ -108,6 +109,7 @@ xfs_errortag_add(int error_tag, xfs_mount_t *mp) ...@@ -108,6 +109,7 @@ xfs_errortag_add(int error_tag, xfs_mount_t *mp)
len = strlen(mp->m_fsname); len = strlen(mp->m_fsname);
xfs_etest_fsname[i] = kmem_alloc(len + 1, KM_SLEEP); xfs_etest_fsname[i] = kmem_alloc(len + 1, KM_SLEEP);
strcpy(xfs_etest_fsname[i], mp->m_fsname); strcpy(xfs_etest_fsname[i], mp->m_fsname);
xfs_error_test_active++;
return 0; return 0;
} }
} }
...@@ -137,6 +139,7 @@ xfs_errortag_clearall(xfs_mount_t *mp, int loud) ...@@ -137,6 +139,7 @@ xfs_errortag_clearall(xfs_mount_t *mp, int loud)
xfs_etest_fsid[i] = 0LL; xfs_etest_fsid[i] = 0LL;
kmem_free(xfs_etest_fsname[i]); kmem_free(xfs_etest_fsname[i]);
xfs_etest_fsname[i] = NULL; xfs_etest_fsname[i] = NULL;
xfs_error_test_active--;
} }
} }
......
...@@ -127,13 +127,14 @@ extern void xfs_corruption_error(const char *tag, int level, ...@@ -127,13 +127,14 @@ extern void xfs_corruption_error(const char *tag, int level,
#define XFS_RANDOM_BMAPIFORMAT XFS_RANDOM_DEFAULT #define XFS_RANDOM_BMAPIFORMAT XFS_RANDOM_DEFAULT
#ifdef DEBUG #ifdef DEBUG
extern int xfs_error_test_active;
extern int xfs_error_test(int, int *, char *, int, char *, unsigned long); extern int xfs_error_test(int, int *, char *, int, char *, unsigned long);
#define XFS_NUM_INJECT_ERROR 10 #define XFS_NUM_INJECT_ERROR 10
#define XFS_TEST_ERROR(expr, mp, tag, rf) \ #define XFS_TEST_ERROR(expr, mp, tag, rf) \
((expr) || \ ((expr) || (xfs_error_test_active && \
xfs_error_test((tag), (mp)->m_fixedfsid, "expr", __LINE__, __FILE__, \ xfs_error_test((tag), (mp)->m_fixedfsid, "expr", __LINE__, __FILE__, \
(rf))) (rf))))
extern int xfs_errortag_add(int error_tag, xfs_mount_t *mp); extern int xfs_errortag_add(int error_tag, xfs_mount_t *mp);
extern int xfs_errortag_clearall(xfs_mount_t *mp, int loud); extern int xfs_errortag_clearall(xfs_mount_t *mp, int loud);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment