Skip to content

Commit

Permalink
Btrfs: Throttle tuning
Browse files Browse the repository at this point in the history
This avoids waiting for transactions with pages locked by breaking out
the code to wait for the current transaction to close into a function
called by btrfs_throttle.

It also lowers the limits for where we start throttling.

Signed-off-by: Chris Mason <chris.mason@oracle.com>
  • Loading branch information
Chris Mason committed Sep 25, 2008
1 parent 47ac14f commit 37d1aee
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 12 deletions.
3 changes: 3 additions & 0 deletions fs/btrfs/extent-tree.c
Original file line number Diff line number Diff line change
Expand Up @@ -2526,6 +2526,9 @@ static int noinline walk_down_tree(struct btrfs_trans_handle *trans,
*level = 0;
break;
}
if (printk_ratelimit())
printk("leaf ref miss for bytenr %llu\n",
(unsigned long long)bytenr);
}
next = btrfs_find_tree_block(root, bytenr, blocksize);
if (!next || !btrfs_buffer_uptodate(next, ptr_gen)) {
Expand Down
2 changes: 1 addition & 1 deletion fs/btrfs/file.c
Original file line number Diff line number Diff line change
Expand Up @@ -253,7 +253,7 @@ static int noinline dirty_and_release_pages(struct btrfs_trans_handle *trans,
end_of_last_block = start_pos + num_bytes - 1;

lock_extent(io_tree, start_pos, end_of_last_block, GFP_NOFS);
trans = btrfs_start_transaction(root, 1);
trans = btrfs_join_transaction(root, 1);
if (!trans) {
err = -ENOMEM;
goto out_unlock;
Expand Down
38 changes: 27 additions & 11 deletions fs/btrfs/transaction.c
Original file line number Diff line number Diff line change
Expand Up @@ -124,17 +124,12 @@ static noinline int record_root_in_trans(struct btrfs_root *root)
return 0;
}

struct btrfs_trans_handle *start_transaction(struct btrfs_root *root,
int num_blocks, int join)
static void wait_current_trans(struct btrfs_root *root)
{
struct btrfs_trans_handle *h =
kmem_cache_alloc(btrfs_trans_handle_cachep, GFP_NOFS);
struct btrfs_transaction *cur_trans;
int ret;

mutex_lock(&root->fs_info->trans_mutex);
cur_trans = root->fs_info->running_transaction;
if (cur_trans && cur_trans->blocked && !join) {
if (cur_trans && cur_trans->blocked) {
DEFINE_WAIT(wait);
cur_trans->use_count++;
while(1) {
Expand All @@ -154,6 +149,18 @@ struct btrfs_trans_handle *start_transaction(struct btrfs_root *root,
}
put_transaction(cur_trans);
}
}

struct btrfs_trans_handle *start_transaction(struct btrfs_root *root,
int num_blocks, int join)
{
struct btrfs_trans_handle *h =
kmem_cache_alloc(btrfs_trans_handle_cachep, GFP_NOFS);
int ret;

mutex_lock(&root->fs_info->trans_mutex);
if (!join)
wait_current_trans(root);
ret = join_transaction(root);
BUG_ON(ret);

Expand Down Expand Up @@ -200,7 +207,7 @@ static noinline int wait_for_commit(struct btrfs_root *root,
return 0;
}

void btrfs_throttle(struct btrfs_root *root)
static void throttle_on_drops(struct btrfs_root *root)
{
struct btrfs_fs_info *info = root->fs_info;

Expand All @@ -223,19 +230,28 @@ void btrfs_throttle(struct btrfs_root *root)
} while (thr == atomic_read(&info->throttle_gen));

if (harder_count < 5 &&
info->total_ref_cache_size > 5 * 1024 * 1024) {
info->total_ref_cache_size > 1 * 1024 * 1024) {
harder_count++;
goto harder;
}

if (harder_count < 10 &&
info->total_ref_cache_size > 10 * 1024 * 1024) {
info->total_ref_cache_size > 5 * 1024 * 1024) {
harder_count++;
goto harder;
}
}
}

void btrfs_throttle(struct btrfs_root *root)
{
mutex_lock(&root->fs_info->trans_mutex);
wait_current_trans(root);
mutex_unlock(&root->fs_info->trans_mutex);

throttle_on_drops(root);
}

static int __btrfs_end_transaction(struct btrfs_trans_handle *trans,
struct btrfs_root *root, int throttle)
{
Expand All @@ -256,7 +272,7 @@ static int __btrfs_end_transaction(struct btrfs_trans_handle *trans,
kmem_cache_free(btrfs_trans_handle_cachep, trans);

if (throttle)
btrfs_throttle(root);
throttle_on_drops(root);

return 0;
}
Expand Down

0 comments on commit 37d1aee

Please sign in to comment.