summaryrefslogtreecommitdiff
path: root/fs/xfs/libxfs/xfs_rtbitmap.h
diff options
context:
space:
mode:
authorOmar Sandoval <osandov@fb.com>2023-10-16 10:13:22 -0700
committerDarrick J. Wong <djwong@kernel.org>2023-10-19 08:22:36 -0700
commite94b53ff699c2674a9ec083342a5254866210ade (patch)
treefa12328b5eca604ca8013ed14e754b5e4784ac3e /fs/xfs/libxfs/xfs_rtbitmap.h
parent41f33d82cfd310e344fc9183f02cc9e0d2d27663 (diff)
xfs: cache last bitmap block in realtime allocator
Profiling a workload on a highly fragmented realtime device showed a ton of CPU cycles being spent in xfs_trans_read_buf() called by xfs_rtbuf_get(). Further tracing showed that much of that was repeated calls to xfs_rtbuf_get() for the same block of the realtime bitmap. These come from xfs_rtallocate_extent_block(): as it walks through ranges of free bits in the bitmap, each call to xfs_rtcheck_range() and xfs_rtfind_{forw,back}() gets the same bitmap block. If the bitmap block is very fragmented, then this is _a lot_ of buffer lookups. The realtime allocator already passes around a cache of the last used realtime summary block to avoid repeated reads (the parameters rbpp and rsb). We can do the same for the realtime bitmap. This replaces rbpp and rsb with a struct xfs_rtbuf_cache, which caches the most recently used block for both the realtime bitmap and summary. xfs_rtbuf_get() now handles the caching instead of the callers, which requires plumbing xfs_rtbuf_cache to more functions but also makes sure we don't miss anything. Signed-off-by: Omar Sandoval <osandov@fb.com> Reviewed-by: Darrick J. Wong <djwong@kernel.org> Signed-off-by: Darrick J. Wong <djwong@kernel.org> Reviewed-by: Christoph Hellwig <hch@lst.de>
Diffstat (limited to 'fs/xfs/libxfs/xfs_rtbitmap.h')
-rw-r--r--fs/xfs/libxfs/xfs_rtbitmap.h17
1 files changed, 12 insertions, 5 deletions
diff --git a/fs/xfs/libxfs/xfs_rtbitmap.h b/fs/xfs/libxfs/xfs_rtbitmap.h
index 52aa301aba7b..253f5b763a6c 100644
--- a/fs/xfs/libxfs/xfs_rtbitmap.h
+++ b/fs/xfs/libxfs/xfs_rtbitmap.h
@@ -9,6 +9,12 @@
struct xfs_rtalloc_args {
struct xfs_mount *mp;
struct xfs_trans *tp;
+
+ struct xfs_buf *rbmbp; /* bitmap block buffer */
+ struct xfs_buf *sumbp; /* summary block buffer */
+
+ xfs_fileoff_t rbmoff; /* bitmap block number */
+ xfs_fileoff_t sumoff; /* summary block number */
};
static inline xfs_rtblock_t
@@ -286,6 +292,8 @@ typedef int (*xfs_rtalloc_query_range_fn)(
void *priv);
#ifdef CONFIG_XFS_RT
+void xfs_rtbuf_cache_relse(struct xfs_rtalloc_args *args);
+
int xfs_rtbuf_get(struct xfs_rtalloc_args *args, xfs_fileoff_t block,
int issum, struct xfs_buf **bpp);
int xfs_rtcheck_range(struct xfs_rtalloc_args *args, xfs_rtxnum_t start,
@@ -297,13 +305,11 @@ int xfs_rtfind_forw(struct xfs_rtalloc_args *args, xfs_rtxnum_t start,
int xfs_rtmodify_range(struct xfs_rtalloc_args *args, xfs_rtxnum_t start,
xfs_rtxlen_t len, int val);
int xfs_rtmodify_summary_int(struct xfs_rtalloc_args *args, int log,
- xfs_fileoff_t bbno, int delta, struct xfs_buf **rbpp,
- xfs_fileoff_t *rsb, xfs_suminfo_t *sum);
+ xfs_fileoff_t bbno, int delta, xfs_suminfo_t *sum);
int xfs_rtmodify_summary(struct xfs_rtalloc_args *args, int log,
- xfs_fileoff_t bbno, int delta, struct xfs_buf **rbpp,
- xfs_fileoff_t *rsb);
+ xfs_fileoff_t bbno, int delta);
int xfs_rtfree_range(struct xfs_rtalloc_args *args, xfs_rtxnum_t start,
- xfs_rtxlen_t len, struct xfs_buf **rbpp, xfs_fileoff_t *rsb);
+ xfs_rtxlen_t len);
int xfs_rtalloc_query_range(struct xfs_mount *mp, struct xfs_trans *tp,
const struct xfs_rtalloc_rec *low_rec,
const struct xfs_rtalloc_rec *high_rec,
@@ -343,6 +349,7 @@ unsigned long long xfs_rtsummary_wordcount(struct xfs_mount *mp,
# define xfs_rtalloc_query_range(m,t,l,h,f,p) (-ENOSYS)
# define xfs_rtalloc_query_all(m,t,f,p) (-ENOSYS)
# define xfs_rtbuf_get(m,t,b,i,p) (-ENOSYS)
+# define xfs_rtbuf_cache_relse(a) (0)
# define xfs_rtalloc_extent_is_free(m,t,s,l,i) (-ENOSYS)
static inline xfs_filblks_t
xfs_rtbitmap_blockcount(struct xfs_mount *mp, xfs_rtbxlen_t rtextents)