mirror of https://gitee.com/openkylin/linux.git
355e353213
The realtime summary is a two-dimensional array on disk, effectively: u32 rsum[log2(number of realtime extents) + 1][number of blocks in the bitmap] rsum[log][bbno] is the number of extents of size 2**log which start in bitmap block bbno. xfs_rtallocate_extent_near() uses xfs_rtany_summary() to check whether rsum[log][bbno] != 0 for any log level. However, the summary array is stored in row-major order (i.e., like an array in C), so all of these entries are not adjacent, but rather spread across the entire summary file. In the worst case (a full bitmap block), xfs_rtany_summary() has to check every level. This means that on a moderately-used realtime device, an allocation will waste a lot of time finding, reading, and releasing buffers for the realtime summary. In particular, one of our storage services (which runs on servers with 8 very slow CPUs and 15 8 TB XFS realtime filesystems) spends almost 5% of its CPU cycles in xfs_rtbuf_get() and xfs_trans_brelse() called from xfs_rtany_summary(). One solution would be to also store the summary with the dimensions swapped. However, this would require a disk format change to a very old component of XFS. Instead, we can cache the minimum size which contains any extents. We do so lazily; rather than guaranteeing that the cache contains the precise minimum, it always contains a loose lower bound which we tighten when we read or update a summary block. This only uses a few kilobytes of memory and is already serialized via the realtime bitmap and summary inode locks, so the cost is minimal. With this change, the same workload only spends 0.2% of its CPU cycles in the realtime allocator. Signed-off-by: Omar Sandoval <osandov@fb.com> Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com> Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com> |
||
---|---|---|
.. | ||
xfs_ag.c | ||
xfs_ag.h | ||
xfs_ag_resv.c | ||
xfs_ag_resv.h | ||
xfs_alloc.c | ||
xfs_alloc.h | ||
xfs_alloc_btree.c | ||
xfs_alloc_btree.h | ||
xfs_attr.c | ||
xfs_attr.h | ||
xfs_attr_leaf.c | ||
xfs_attr_leaf.h | ||
xfs_attr_remote.c | ||
xfs_attr_remote.h | ||
xfs_attr_sf.h | ||
xfs_bit.c | ||
xfs_bit.h | ||
xfs_bmap.c | ||
xfs_bmap.h | ||
xfs_bmap_btree.c | ||
xfs_bmap_btree.h | ||
xfs_btree.c | ||
xfs_btree.h | ||
xfs_cksum.h | ||
xfs_da_btree.c | ||
xfs_da_btree.h | ||
xfs_da_format.c | ||
xfs_da_format.h | ||
xfs_defer.c | ||
xfs_defer.h | ||
xfs_dir2.c | ||
xfs_dir2.h | ||
xfs_dir2_block.c | ||
xfs_dir2_data.c | ||
xfs_dir2_leaf.c | ||
xfs_dir2_node.c | ||
xfs_dir2_priv.h | ||
xfs_dir2_sf.c | ||
xfs_dquot_buf.c | ||
xfs_errortag.h | ||
xfs_format.h | ||
xfs_fs.h | ||
xfs_ialloc.c | ||
xfs_ialloc.h | ||
xfs_ialloc_btree.c | ||
xfs_ialloc_btree.h | ||
xfs_iext_tree.c | ||
xfs_inode_buf.c | ||
xfs_inode_buf.h | ||
xfs_inode_fork.c | ||
xfs_inode_fork.h | ||
xfs_log_format.h | ||
xfs_log_recover.h | ||
xfs_log_rlimit.c | ||
xfs_quota_defs.h | ||
xfs_refcount.c | ||
xfs_refcount.h | ||
xfs_refcount_btree.c | ||
xfs_refcount_btree.h | ||
xfs_rmap.c | ||
xfs_rmap.h | ||
xfs_rmap_btree.c | ||
xfs_rmap_btree.h | ||
xfs_rtbitmap.c | ||
xfs_sb.c | ||
xfs_sb.h | ||
xfs_shared.h | ||
xfs_symlink_remote.c | ||
xfs_trans_resv.c | ||
xfs_trans_resv.h | ||
xfs_trans_space.h | ||
xfs_types.c | ||
xfs_types.h |