Skip to content

Commit 31b9655

Browse files
Josef Bacikmasoncl
authored andcommitted
Btrfs: track transid for delayed ref flushing
Using the offwakecputime bpf script I noticed most of our time was spent waiting on the delayed ref throttling. This is what is supposed to happen, but sometimes the transaction can commit and then we're waiting for throttling that doesn't matter anymore. So change this stuff to be a little smarter by tracking the transid we were in when we initiated the throttling. If the transaction we get is different then we can just bail out. This resulted in a 50% speedup in my fs_mark test, and reduced the amount of time spent throttling by 60 seconds over the entire run (which is about 30 minutes). Thanks, Signed-off-by: Josef Bacik <[email protected]> Signed-off-by: Chris Mason <[email protected]>
1 parent de18c16 commit 31b9655

File tree

4 files changed

+16
-5
lines changed

4 files changed

+16
-5
lines changed

fs/btrfs/ctree.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2518,7 +2518,7 @@ void btrfs_put_block_group(struct btrfs_block_group_cache *cache);
25182518
int btrfs_run_delayed_refs(struct btrfs_trans_handle *trans,
25192519
struct btrfs_root *root, unsigned long count);
25202520
int btrfs_async_run_delayed_refs(struct btrfs_root *root,
2521-
unsigned long count, int wait);
2521+
unsigned long count, u64 transid, int wait);
25222522
int btrfs_lookup_data_extent(struct btrfs_root *root, u64 start, u64 len);
25232523
int btrfs_lookup_extent_info(struct btrfs_trans_handle *trans,
25242524
struct btrfs_root *root, u64 bytenr,

fs/btrfs/extent-tree.c

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2835,6 +2835,7 @@ int btrfs_should_throttle_delayed_refs(struct btrfs_trans_handle *trans,
28352835

28362836
struct async_delayed_refs {
28372837
struct btrfs_root *root;
2838+
u64 transid;
28382839
int count;
28392840
int error;
28402841
int sync;
@@ -2850,9 +2851,16 @@ static void delayed_ref_async_start(struct btrfs_work *work)
28502851

28512852
async = container_of(work, struct async_delayed_refs, work);
28522853

2853-
trans = btrfs_join_transaction(async->root);
2854+
trans = btrfs_attach_transaction(async->root);
28542855
if (IS_ERR(trans)) {
2855-
async->error = PTR_ERR(trans);
2856+
if (PTR_ERR(trans) != -ENOENT)
2857+
async->error = PTR_ERR(trans);
2858+
goto done;
2859+
}
2860+
2861+
/* Don't bother flushing if we got into a different transaction */
2862+
if (trans->transid != async->transid) {
2863+
btrfs_end_transaction(trans, async->root);
28562864
goto done;
28572865
}
28582866

@@ -2876,7 +2884,7 @@ static void delayed_ref_async_start(struct btrfs_work *work)
28762884
}
28772885

28782886
int btrfs_async_run_delayed_refs(struct btrfs_root *root,
2879-
unsigned long count, int wait)
2887+
unsigned long count, u64 transid, int wait)
28802888
{
28812889
struct async_delayed_refs *async;
28822890
int ret;
@@ -2888,6 +2896,7 @@ int btrfs_async_run_delayed_refs(struct btrfs_root *root,
28882896
async->root = root->fs_info->tree_root;
28892897
async->count = count;
28902898
async->error = 0;
2899+
async->transid = transid;
28912900
if (wait)
28922901
async->sync = 1;
28932902
else

fs/btrfs/inode.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4558,6 +4558,7 @@ int btrfs_truncate_inode_items(struct btrfs_trans_handle *trans,
45584558
BUG_ON(ret);
45594559
if (btrfs_should_throttle_delayed_refs(trans, root))
45604560
btrfs_async_run_delayed_refs(root,
4561+
trans->transid,
45614562
trans->delayed_ref_updates * 2, 0);
45624563
if (be_nice) {
45634564
if (truncate_space_check(trans, root,

fs/btrfs/transaction.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -818,6 +818,7 @@ static int __btrfs_end_transaction(struct btrfs_trans_handle *trans,
818818
{
819819
struct btrfs_transaction *cur_trans = trans->transaction;
820820
struct btrfs_fs_info *info = root->fs_info;
821+
u64 transid = trans->transid;
821822
unsigned long cur = trans->delayed_ref_updates;
822823
int lock = (trans->type != TRANS_JOIN_NOLOCK);
823824
int err = 0;
@@ -905,7 +906,7 @@ static int __btrfs_end_transaction(struct btrfs_trans_handle *trans,
905906

906907
kmem_cache_free(btrfs_trans_handle_cachep, trans);
907908
if (must_run_delayed_refs) {
908-
btrfs_async_run_delayed_refs(root, cur,
909+
btrfs_async_run_delayed_refs(root, cur, transid,
909910
must_run_delayed_refs == 1);
910911
}
911912
return err;

0 commit comments

Comments
 (0)