From: Qu Wenruo <quwenruo.btrfs@gmx.com>
To: Josef Bacik <josef@toxicpanda.com>,
linux-btrfs@vger.kernel.org, kernel-team@fb.com
Subject: Re: [PATCH 08/10] btrfs: rework btrfs_check_space_for_delayed_refs
Date: Mon, 14 Jan 2019 14:28:33 +0800 [thread overview]
Message-ID: <fe91b104-8be5-031e-daf8-2d8b50414e32@gmx.com> (raw)
In-Reply-To: <20181203152038.21388-9-josef@toxicpanda.com>
[-- Attachment #1.1: Type: text/plain, Size: 6377 bytes --]
On 2018/12/3 下午11:20, Josef Bacik wrote:
> Now with the delayed_refs_rsv we can now know exactly how much pending
> delayed refs space we need. This means we can drastically simplify
> btrfs_check_space_for_delayed_refs by simply checking how much space we
> have reserved for the global rsv (which acts as a spill over buffer) and
> the delayed refs rsv. If our total size is beyond that amount then we
> know it's time to commit the transaction and stop any more delayed refs
> from being generated.
This patch is causing obvious large performance regression for metadata
relocation.
Bisect leads to this patch.
I'm using a script copying /usr (around 3.5G) into a subvolume, and do
16 snapshots, then touching 3 random files in each snapshot.
Then do a *metadata* balance.
Please note, quota is *DISABLED* here.
The full scripts can be found here:
https://gist.github.com/adam900710/e0a9719441e770a4d0d7b32c4a88bf95
Before this patch, it's around 5s to relocate 3 metadata block groups.
(VM is using unsafe cache mode, so IO is as fast as memory speed).
After this patch, I don't know how long it will take, as it doesn't even
finish before I reset the VM.
I also found during the super slow relocation, the generation of the fs
is increasing like crazy.
So something is definitely causing a ton of transaction commit.
Thanks,
Qu
>
> Signed-off-by: Josef Bacik <josef@toxicpanda.com>
> ---
> fs/btrfs/ctree.h | 2 +-
> fs/btrfs/extent-tree.c | 48 ++++++++++++++++++------------------------------
> fs/btrfs/inode.c | 4 ++--
> fs/btrfs/transaction.c | 2 +-
> 4 files changed, 22 insertions(+), 34 deletions(-)
>
> diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h
> index 2eba398c722b..30da075c042e 100644
> --- a/fs/btrfs/ctree.h
> +++ b/fs/btrfs/ctree.h
> @@ -2631,7 +2631,7 @@ static inline u64 btrfs_calc_trunc_metadata_size(struct btrfs_fs_info *fs_info,
> }
>
> int btrfs_should_throttle_delayed_refs(struct btrfs_trans_handle *trans);
> -int btrfs_check_space_for_delayed_refs(struct btrfs_trans_handle *trans);
> +bool btrfs_check_space_for_delayed_refs(struct btrfs_fs_info *fs_info);
> void btrfs_dec_block_group_reservations(struct btrfs_fs_info *fs_info,
> const u64 start);
> void btrfs_wait_block_group_reservations(struct btrfs_block_group_cache *bg);
> diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c
> index 5a2d0b061f57..07ef1b8087f7 100644
> --- a/fs/btrfs/extent-tree.c
> +++ b/fs/btrfs/extent-tree.c
> @@ -2839,40 +2839,28 @@ u64 btrfs_csum_bytes_to_leaves(struct btrfs_fs_info *fs_info, u64 csum_bytes)
> return num_csums;
> }
>
> -int btrfs_check_space_for_delayed_refs(struct btrfs_trans_handle *trans)
> +bool btrfs_check_space_for_delayed_refs(struct btrfs_fs_info *fs_info)
> {
> - struct btrfs_fs_info *fs_info = trans->fs_info;
> - struct btrfs_block_rsv *global_rsv;
> - u64 num_heads = trans->transaction->delayed_refs.num_heads_ready;
> - u64 csum_bytes = trans->transaction->delayed_refs.pending_csums;
> - unsigned int num_dirty_bgs = trans->transaction->num_dirty_bgs;
> - u64 num_bytes, num_dirty_bgs_bytes;
> - int ret = 0;
> + struct btrfs_block_rsv *delayed_refs_rsv = &fs_info->delayed_refs_rsv;
> + struct btrfs_block_rsv *global_rsv = &fs_info->global_block_rsv;
> + bool ret = false;
> + u64 reserved;
>
> - num_bytes = btrfs_calc_trans_metadata_size(fs_info, 1);
> - num_heads = heads_to_leaves(fs_info, num_heads);
> - if (num_heads > 1)
> - num_bytes += (num_heads - 1) * fs_info->nodesize;
> - num_bytes <<= 1;
> - num_bytes += btrfs_csum_bytes_to_leaves(fs_info, csum_bytes) *
> - fs_info->nodesize;
> - num_dirty_bgs_bytes = btrfs_calc_trans_metadata_size(fs_info,
> - num_dirty_bgs);
> - global_rsv = &fs_info->global_block_rsv;
> + spin_lock(&global_rsv->lock);
> + reserved = global_rsv->reserved;
> + spin_unlock(&global_rsv->lock);
>
> /*
> - * If we can't allocate any more chunks lets make sure we have _lots_ of
> - * wiggle room since running delayed refs can create more delayed refs.
> + * Since the global reserve is just kind of magic we don't really want
> + * to rely on it to save our bacon, so if our size is more than the
> + * delayed_refs_rsv and the global rsv then it's time to think about
> + * bailing.
> */
> - if (global_rsv->space_info->full) {
> - num_dirty_bgs_bytes <<= 1;
> - num_bytes <<= 1;
> - }
> -
> - spin_lock(&global_rsv->lock);
> - if (global_rsv->reserved <= num_bytes + num_dirty_bgs_bytes)
> - ret = 1;
> - spin_unlock(&global_rsv->lock);
> + spin_lock(&delayed_refs_rsv->lock);
> + reserved += delayed_refs_rsv->reserved;
> + if (delayed_refs_rsv->size >= reserved)
> + ret = true;
> + spin_unlock(&delayed_refs_rsv->lock);
> return ret;
> }
>
> @@ -2891,7 +2879,7 @@ int btrfs_should_throttle_delayed_refs(struct btrfs_trans_handle *trans)
> if (val >= NSEC_PER_SEC / 2)
> return 2;
>
> - return btrfs_check_space_for_delayed_refs(trans);
> + return btrfs_check_space_for_delayed_refs(trans->fs_info);
> }
>
> struct async_delayed_refs {
> diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
> index a097f5fde31d..8532a2eb56d1 100644
> --- a/fs/btrfs/inode.c
> +++ b/fs/btrfs/inode.c
> @@ -5326,8 +5326,8 @@ static struct btrfs_trans_handle *evict_refill_and_join(struct btrfs_root *root,
> * Try to steal from the global reserve if there is space for
> * it.
> */
> - if (!btrfs_check_space_for_delayed_refs(trans) &&
> - !btrfs_block_rsv_migrate(global_rsv, rsv, rsv->size, false))
> + if (!btrfs_check_space_for_delayed_refs(fs_info) &&
> + !btrfs_block_rsv_migrate(global_rsv, rsv, rsv->size, 0))
> return trans;
>
> /* If not, commit and try again. */
> diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c
> index a21c4defad92..2d8401bf8df9 100644
> --- a/fs/btrfs/transaction.c
> +++ b/fs/btrfs/transaction.c
> @@ -789,7 +789,7 @@ static int should_end_transaction(struct btrfs_trans_handle *trans)
> {
> struct btrfs_fs_info *fs_info = trans->fs_info;
>
> - if (btrfs_check_space_for_delayed_refs(trans))
> + if (btrfs_check_space_for_delayed_refs(fs_info))
> return 1;
>
> return !!btrfs_block_rsv_check(&fs_info->global_block_rsv, 5);
>
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 488 bytes --]
next prev parent reply other threads:[~2019-01-14 6:28 UTC|newest]
Thread overview: 26+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-12-03 15:20 [PATCH 00/10][V2] Delayed refs rsv Josef Bacik
2018-12-03 15:20 ` [PATCH 01/10] btrfs: add btrfs_delete_ref_head helper Josef Bacik
2018-12-06 12:32 ` Nikolay Borisov
2018-12-03 15:20 ` [PATCH 02/10] btrfs: add cleanup_ref_head_accounting helper Josef Bacik
2018-12-06 12:38 ` Nikolay Borisov
2018-12-03 15:20 ` [PATCH 03/10] btrfs: cleanup extent_op handling Josef Bacik
2018-12-03 15:20 ` [PATCH 04/10] btrfs: only track ref_heads in delayed_ref_updates Josef Bacik
2018-12-07 13:01 ` Nikolay Borisov
2018-12-13 16:36 ` David Sterba
2018-12-03 15:20 ` [PATCH 05/10] btrfs: introduce delayed_refs_rsv Josef Bacik
2018-12-07 14:45 ` Nikolay Borisov
2018-12-13 16:49 ` David Sterba
2018-12-03 15:20 ` [PATCH 06/10] btrfs: update may_commit_transaction to use the delayed refs rsv Josef Bacik
2018-12-06 12:51 ` Nikolay Borisov
2018-12-03 15:20 ` [PATCH 07/10] btrfs: add new flushing states for " Josef Bacik
2018-12-03 15:20 ` [PATCH 08/10] btrfs: rework btrfs_check_space_for_delayed_refs Josef Bacik
2018-12-06 16:52 ` Nikolay Borisov
2018-12-06 17:54 ` David Sterba
2018-12-07 7:09 ` Nikolay Borisov
2018-12-07 9:57 ` Nikolay Borisov
2018-12-13 16:44 ` David Sterba
2019-01-14 6:28 ` Qu Wenruo [this message]
2018-12-03 15:20 ` [PATCH 09/10] btrfs: don't run delayed refs in the end transaction logic Josef Bacik
2018-12-06 16:43 ` Nikolay Borisov
2018-12-03 15:20 ` [PATCH 10/10] btrfs: fix truncate throttling Josef Bacik
2018-12-06 15:56 ` [PATCH 00/10][V2] Delayed refs rsv David Sterba
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=fe91b104-8be5-031e-daf8-2d8b50414e32@gmx.com \
--to=quwenruo.btrfs@gmx.com \
--cc=josef@toxicpanda.com \
--cc=kernel-team@fb.com \
--cc=linux-btrfs@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).