linux/fs/xfs
Dave Chinner ed3b4d6cdc xfs: Improve scalability of busy extent tracking
When we free a metadata extent, we record it in the per-AG busy
extent array so that it is not re-used before the freeing
transaction hits the disk. This array is fixed size, so when it
overflows we make further allocation transactions synchronous
because we cannot track more freed extents until those transactions
hit the disk and are completed. Under heavy mixed allocation and
freeing workloads with large log buffers, we can overflow this array
quite easily.

Further, the array is sparsely populated, which means that inserts
need to search for a free slot, and array searches often have to
search many more slots that are actually used to check all the
busy extents. Quite inefficient, really.

To enable this aspect of extent freeing to scale better, we need
a structure that can grow dynamically. While in other areas of
XFS we have used radix trees, the extents being freed are at random
locations on disk so are better suited to being indexed by an rbtree.

So, use a per-AG rbtree indexed by block number to track busy
extents.  This incures a memory allocation when marking an extent
busy, but should not occur too often in low memory situations. This
should scale to an arbitrary number of extents so should not be a
limitation for features such as in-memory aggregation of
transactions.

However, there are still situations where we can't avoid allocating
busy extents (such as allocation from the AGFL). To minimise the
overhead of such occurences, we need to avoid doing a synchronous
log force while holding the AGF locked to ensure that the previous
transactions are safely on disk before we use the extent. We can do
this by marking the transaction doing the allocation as synchronous
rather issuing a log force.

Because of the locking involved and the ordering of transactions,
the synchronous transaction provides the same guarantees as a
synchronous log force because it ensures that all the prior
transactions are already on disk when the synchronous transaction
hits the disk. i.e. it preserves the free->allocate order of the
extent correctly in recovery.

By doing this, we avoid holding the AGF locked while log writes are
in progress, hence reducing the length of time the lock is held and
therefore we increase the rate at which we can allocate and free
from the allocation group, thereby increasing overall throughput.

The only problem with this approach is that when a metadata buffer is
marked stale (e.g. a directory block is removed), then buffer remains
pinned and locked until the log goes to disk. The issue here is that
if that stale buffer is reallocated in a subsequent transaction, the
attempt to lock that buffer in the transaction will hang waiting
the log to go to disk to unlock and unpin the buffer. Hence if
someone tries to lock a pinned, stale, locked buffer we need to
push on the log to get it unlocked ASAP. Effectively we are trading
off a guaranteed log force for a much less common trigger for log
force to occur.

Ideally we should not reallocate busy extents. That is a much more
complex fix to the problem as it involves direct intervention in the
allocation btree searches in many places. This is left to a future
set of modifications.

Finally, now that we track busy extents in allocated memory, we
don't need the descriptors in the transaction structure to point to
them. We can replace the complex busy chunk infrastructure with a
simple linked list of busy extents. This allows us to remove a large
chunk of code, making the overall change a net reduction in code
size.

Signed-off-by: Dave Chinner <david@fromorbit.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Alex Elder <aelder@sgi.com>
2010-05-24 10:34:00 -05:00
..
linux-2.6 xfs: Improve scalability of busy extent tracking 2010-05-24 10:34:00 -05:00
quota xfs: Clean up XFS_BLI_* flag namespace 2010-05-24 10:33:39 -05:00
support xfs: event tracing support 2009-12-14 23:08:16 -06:00
Kconfig xfs: use generic Posix ACL code 2009-06-10 17:07:47 +02:00
Makefile xfs: merge xfs_lrw.c into xfs_file.c 2010-03-01 16:34:18 -06:00
xfs_acl.h xfs: convert attr to use unsigned names 2010-01-20 10:47:48 +11:00
xfs_ag.h xfs: Improve scalability of busy extent tracking 2010-05-24 10:34:00 -05:00
xfs_alloc_btree.c xfs: Improve scalability of busy extent tracking 2010-05-24 10:34:00 -05:00
xfs_alloc_btree.h
xfs_alloc.c xfs: Improve scalability of busy extent tracking 2010-05-24 10:34:00 -05:00
xfs_alloc.h xfs: Improve scalability of busy extent tracking 2010-05-24 10:34:00 -05:00
xfs_arch.h xfs: use generic Posix ACL code 2009-06-10 17:07:47 +02:00
xfs_attr_leaf.c xfs: remove duplicate buffer flags 2010-01-21 13:44:36 -06:00
xfs_attr_leaf.h [XFS] Remove macro-to-function indirections in attr code 2009-01-09 15:46:44 +11:00
xfs_attr_sf.h xfs: convert attr to use unsigned names 2010-01-20 10:47:48 +11:00
xfs_attr.c xfs: remove duplicate buffer flags 2010-01-21 13:44:36 -06:00
xfs_attr.h xfs: convert attr to use unsigned names 2010-01-20 10:47:48 +11:00
xfs_bit.c
xfs_bit.h [XFS] Remove macro-to-function indirections in the mask code 2009-01-09 15:53:54 +11:00
xfs_bmap_btree.c xfs: make several more functions static 2010-01-15 15:31:38 -06:00
xfs_bmap_btree.h xfs: make several more functions static 2010-01-15 15:31:38 -06:00
xfs_bmap.c xfs: fix reservation release commit flag in xfs_bmap_add_attrfork() 2010-05-19 09:58:08 -05:00
xfs_bmap.h xfs: event tracing support 2009-12-14 23:08:16 -06:00
xfs_btree_trace.c
xfs_btree_trace.h xfs: event tracing support 2009-12-14 23:08:16 -06:00
xfs_btree.c xfs: remove duplicate buffer flags 2010-01-21 13:44:36 -06:00
xfs_btree.h xfs: add more statics & drop some unused functions 2009-08-31 14:46:20 -05:00
xfs_buf_item.c xfs: Clean up XFS_BLI_* flag namespace 2010-05-24 10:33:39 -05:00
xfs_buf_item.h xfs: Clean up XFS_BLI_* flag namespace 2010-05-24 10:33:39 -05:00
xfs_da_btree.c xfs: convert dirnameops to unsigned char names 2010-01-20 10:47:17 +11:00
xfs_da_btree.h xfs: convert dirnameops to unsigned char names 2010-01-20 10:47:17 +11:00
xfs_dfrag.c xfs: more swap extent fixes for dynamic fork offsets 2010-04-26 12:38:51 -05:00
xfs_dfrag.h xfs: clean up inconsistent variable naming in xfs_swap_extent 2010-01-15 15:31:23 -06:00
xfs_dinode.h xfs: remove m_litino 2009-03-29 09:51:14 +02:00
xfs_dir2_block.c xfs: clean up sign warnings in dir2 code 2010-01-20 10:48:05 +11:00
xfs_dir2_block.h
xfs_dir2_data.c
xfs_dir2_data.h xfs: fix various typos 2009-03-29 09:55:42 +02:00
xfs_dir2_leaf.c xfs: clean up sign warnings in dir2 code 2010-01-20 10:48:05 +11:00
xfs_dir2_leaf.h
xfs_dir2_node.c xfs: make several more functions static 2010-01-15 15:31:38 -06:00
xfs_dir2_node.h xfs: make several more functions static 2010-01-15 15:31:38 -06:00
xfs_dir2_sf.c xfs: clean up sign warnings in dir2 code 2010-01-20 10:48:05 +11:00
xfs_dir2_sf.h [XFS] kill xfs_dinode_core_t 2008-12-01 11:37:35 +11:00
xfs_dir2.c xfs: clean up sign warnings in dir2 code 2010-01-20 10:48:05 +11:00
xfs_dir2.h xfs: make xfs_dir_cilookup_result use unsigned char 2010-01-20 10:47:25 +11:00
xfs_dmapi.h
xfs_dmops.c
xfs_error.c xfs: clean up log ticket overrun debug output 2010-05-24 10:33:46 -05:00
xfs_error.h xfs: add const qualifiers to xfs error function args 2010-05-19 09:58:11 -05:00
xfs_extfree_item.c xfs: remove stale parameter from ->iop_unpin method 2010-05-19 09:58:08 -05:00
xfs_extfree_item.h [XFS] remove always-true #ifndef HAVE_FORMAT32 tests 2009-01-22 14:07:31 +11:00
xfs_filestream.c xfs: Kill filestreams cache flush 2010-01-15 15:34:22 -06:00
xfs_filestream.h xfs: Kill filestreams cache flush 2010-01-15 15:34:22 -06:00
xfs_fs.h xfs: return inode fork offset in bulkstat for fsr 2010-03-05 11:02:07 -06:00
xfs_fsops.c xfs: Replace per-ag array with a radix tree 2010-01-15 15:33:52 -06:00
xfs_fsops.h filesystem freeze: add error handling of write_super_lockfs/unlockfs 2009-01-09 16:54:42 -08:00
xfs_ialloc_btree.c xfs: fix various typos 2009-03-29 09:55:42 +02:00
xfs_ialloc_btree.h xfs: remove superflous inobt macros 2009-02-09 08:37:14 +01:00
xfs_ialloc.c xfs: remove duplicate buffer flags 2010-01-21 13:44:36 -06:00
xfs_ialloc.h xfs: rationalize xfs_inobt_lookup* 2009-09-01 12:45:39 -05:00
xfs_iget.c xfs: fix locking for inode cache radix tree tag updates 2010-03-01 19:14:36 -06:00
xfs_inode_item.c xfs: remove stale parameter from ->iop_unpin method 2010-05-19 09:58:08 -05:00
xfs_inode_item.h xfs: Don't issue buffer IO direct from AIL push V2 2010-02-02 10:13:42 +11:00
xfs_inode.c xfs: Add inode pin counts to traces 2010-05-19 09:58:08 -05:00
xfs_inode.h xfs: remove xfs_ipin/xfs_iunpin 2010-03-01 16:35:56 -06:00
xfs_inum.h xfs: remove XFS_INO64_OFFSET 2009-08-31 14:46:22 -05:00
xfs_iomap.c xfs: mark xfs_iomap_write_ helpers static 2010-05-19 09:58:20 -05:00
xfs_iomap.h xfs: mark xfs_iomap_write_ helpers static 2010-05-19 09:58:20 -05:00
xfs_itable.c xfs: return inode fork offset in bulkstat for fsr 2010-03-05 11:02:07 -06:00
xfs_itable.h xfs: add more statics & drop some unused functions 2009-08-31 14:46:20 -05:00
xfs_log_priv.h xfs: make the log ticket ID available outside the log infrastructure 2010-05-24 10:33:52 -05:00
xfs_log_recover.c xfs: Clean up XFS_BLI_* flag namespace 2010-05-24 10:33:39 -05:00
xfs_log_recover.h xfs: Clean up XFS_BLI_* flag namespace 2010-05-24 10:33:39 -05:00
xfs_log.c xfs: make the log ticket ID available outside the log infrastructure 2010-05-24 10:33:52 -05:00
xfs_log.h xfs: make the log ticket ID available outside the log infrastructure 2010-05-24 10:33:52 -05:00
xfs_mount.c xfs: remove dead XFS_LOUD_RECOVERY code 2010-05-19 09:58:15 -05:00
xfs_mount.h xfs: add a shrinker to background inode reclaim 2010-04-29 16:22:13 -05:00
xfs_mru_cache.c xfs: Kill filestreams cache flush 2010-01-15 15:34:22 -06:00
xfs_mru_cache.h xfs: Kill filestreams cache flush 2010-01-15 15:34:22 -06:00
xfs_quota.h xfs: removed unused XFS_QMOPT_ flags 2010-05-19 09:58:15 -05:00
xfs_refcache.h
xfs_rename.c xfs: event tracing support 2009-12-14 23:08:16 -06:00
xfs_rtalloc.c xfs: fix missing error check in xfs_rtfree_range 2010-01-15 13:46:19 -06:00
xfs_rtalloc.h xfs: fix various typos 2009-03-29 09:55:42 +02:00
xfs_rw.c xfs: only clear the suid bit once in xfs_write 2010-02-12 13:43:57 -06:00
xfs_rw.h xfs: only clear the suid bit once in xfs_write 2010-02-12 13:43:57 -06:00
xfs_sb.h [XFS] Remove the rest of the macro-to-function indirections. 2009-01-19 14:45:55 +11:00
xfs_trans_ail.c xfs: Don't issue buffer IO direct from AIL push V2 2010-02-02 10:13:42 +11:00
xfs_trans_buf.c xfs: Clean up XFS_BLI_* flag namespace 2010-05-24 10:33:39 -05:00
xfs_trans_extfree.c
xfs_trans_inode.c xfs: simplify xfs_trans_iget 2009-09-01 12:46:16 -05:00
xfs_trans_item.c xfs: Improve scalability of busy extent tracking 2010-05-24 10:34:00 -05:00
xfs_trans_priv.h xfs: Improve scalability of busy extent tracking 2010-05-24 10:34:00 -05:00
xfs_trans_space.h xfs: remove superflous inobt macros 2009-02-09 08:37:14 +01:00
xfs_trans.c xfs: Improve scalability of busy extent tracking 2010-05-24 10:34:00 -05:00
xfs_trans.h xfs: Improve scalability of busy extent tracking 2010-05-24 10:34:00 -05:00
xfs_types.h xfs: make the log ticket ID available outside the log infrastructure 2010-05-24 10:33:52 -05:00
xfs_utils.c xfs: kill xfs_qmops 2009-06-08 15:33:32 +02:00
xfs_utils.h
xfs_vnodeops.c xfs: remove wrapper for the fsync file operation 2010-03-01 16:34:38 -06:00
xfs_vnodeops.h xfs: kill xfs_lrw.h 2010-03-01 16:35:44 -06:00
xfs.h xfs: event tracing support 2009-12-14 23:08:16 -06:00