From: Su Yue <suy.fnst@cn.fujitsu.com>
To: <linux-btrfs@vger.kernel.org>
Cc: <suy.fnst@cn.fujitsu.com>
Subject: [RFC PATCH 13/17] btrfs: priority alloc: modify find_free_extent() to fit priority allocator
Date: Wed, 28 Nov 2018 11:11:44 +0800 [thread overview]
Message-ID: <20181128031148.357-14-suy.fnst@cn.fujitsu.com> (raw)
In-Reply-To: <20181128031148.357-1-suy.fnst@cn.fujitsu.com>
Add member priority_tree to find_free_extent_ctl to represents the
tree using.
Modify find_free_extent to use find_free_extent_search, so it can
work in default mount option and priorit aware allocator.
Signed-off-by: Su Yue <suy.fnst@cn.fujitsu.com>
---
fs/btrfs/extent-tree.c | 114 ++++++++++++++++++++++++++++++++---------
1 file changed, 91 insertions(+), 23 deletions(-)
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c
index 5484256169dd..4c76677a54a9 100644
--- a/fs/btrfs/extent-tree.c
+++ b/fs/btrfs/extent-tree.c
@@ -7328,6 +7328,8 @@ struct find_free_extent_ctl {
/* Found result */
u64 found_offset;
+
+ struct btrfs_priority_tree *priority_tree;
};
@@ -7692,6 +7694,10 @@ static int find_free_extent_update_loop(struct btrfs_fs_info *fs_info,
return -ENOSPC;
}
+static inline bool
+is_priority_alloc_enabled(struct btrfs_fs_info *fs_info);
+
+static long compute_block_group_priority(struct btrfs_block_group_cache *bg);
/*
* walks the btree of allocated extents and find a hole of a given size.
* The key ins is changed to record the hole:
@@ -7729,6 +7735,7 @@ static noinline int find_free_extent(struct btrfs_fs_info *fs_info,
struct btrfs_space_info *space_info;
bool use_cluster = true;
bool full_search = false;
+ bool use_priority = is_priority_alloc_enabled(fs_info);
WARN_ON(num_bytes < fs_info->sectorsize);
@@ -7744,6 +7751,7 @@ static noinline int find_free_extent(struct btrfs_fs_info *fs_info,
ffe_ctl.have_caching_bg = false;
ffe_ctl.orig_have_caching_bg = false;
ffe_ctl.found_offset = 0;
+ ffe_ctl.priority_tree = NULL;
ins->type = BTRFS_EXTENT_ITEM_KEY;
ins->objectid = 0;
@@ -7813,40 +7821,82 @@ static noinline int find_free_extent(struct btrfs_fs_info *fs_info,
*/
if (block_group && block_group_bits(block_group, flags) &&
block_group->cached != BTRFS_CACHE_NO) {
- down_read(&space_info->groups_sem);
- if (list_empty(&block_group->list) ||
- block_group->ro) {
- /*
- * someone is removing this block group,
- * we can't jump into the have_block_group
- * target because our list pointers are not
- * valid
- */
- btrfs_put_block_group(block_group);
- up_read(&space_info->groups_sem);
+ if (use_priority) {
+ spin_lock(&block_group->lock);
+ if (block_group->priority ==
+ PRIORITY_BG_DELETED ||
+ block_group->priority ==
+ PRIORITY_BG_BUSY ||
+ block_group->ro) {
+ spin_unlock(&block_group->lock);
+ btrfs_put_block_group(block_group);
+ goto search;
+ }
+
+ block_group->priority = PRIORITY_BG_BUSY;
+ spin_unlock(&block_group->lock);
+ ffe_ctl.priority_tree =
+ block_group->priority_tree;
+ down_read(&ffe_ctl.priority_tree->groups_sem);
} else {
- ffe_ctl.index = btrfs_bg_flags_to_raid_index(
- block_group->flags);
- btrfs_lock_block_group(block_group, delalloc);
- goto have_block_group;
+ down_read(&space_info->groups_sem);
+ if (list_empty(&block_group->list) ||
+ block_group->ro) {
+ /*
+ * someone is removing this block
+ * group, we can't jump into the
+ * have_block_group target because our
+ * list pointers are not valid
+ */
+ btrfs_put_block_group(block_group);
+ up_read(&space_info->groups_sem);
+ goto search;
+ }
}
+ ffe_ctl.index = btrfs_bg_flags_to_raid_index(
+ block_group->flags);
+ btrfs_lock_block_group(block_group, delalloc);
+ goto have_block_group;
} else if (block_group) {
btrfs_put_block_group(block_group);
}
}
search:
+ ffe_ctl.priority_tree = NULL;
+ block_group = NULL;
ffe_ctl.have_caching_bg = false;
if (ffe_ctl.index == btrfs_bg_flags_to_raid_index(flags) ||
ffe_ctl.index == 0)
full_search = true;
- down_read(&space_info->groups_sem);
- list_for_each_entry(block_group,
- &space_info->block_groups[ffe_ctl.index], list) {
+ if (!use_priority)
+ down_read(&space_info->groups_sem);
+ while (1) {
+ block_group = find_free_extent_search(space_info,
+ ffe_ctl.index, block_group, use_priority,
+ &ffe_ctl.priority_tree);
+
+ if (block_group == NULL)
+ break;
/* If the block group is read-only, we can skip it entirely. */
if (unlikely(block_group->ro))
continue;
btrfs_grab_block_group(block_group, delalloc);
+
+ if (use_priority) {
+ spin_lock(&block_group->lock);
+ /* someone the block group is unavaiable now */
+ if (block_group->priority == PRIORITY_BG_DELETED ||
+ block_group->priority == PRIORITY_BG_UPDATING ||
+ block_group->priority == PRIORITY_BG_BUSY) {
+ spin_unlock(&block_group->lock);
+ goto loop;
+ }
+
+ block_group->priority = PRIORITY_BG_BUSY;
+ spin_unlock(&block_group->lock);
+ }
+
ffe_ctl.search_start = block_group->key.objectid;
/*
@@ -7945,9 +7995,20 @@ static noinline int find_free_extent(struct btrfs_fs_info *fs_info,
trace_btrfs_reserve_extent(block_group, ffe_ctl.search_start,
num_bytes);
- btrfs_release_block_group(block_group, delalloc);
- break;
+ goto out;
loop:
+ if (use_priority) {
+ long priority;
+
+ spin_lock(&block_group->lock);
+ if (block_group->priority == PRIORITY_BG_BUSY) {
+ priority = compute_block_group_priority(
+ block_group);
+ block_group->priority = priority;
+ }
+ spin_unlock(&block_group->lock);
+ }
+
ffe_ctl.retry_clustered = false;
ffe_ctl.retry_unclustered = false;
BUG_ON(btrfs_bg_flags_to_raid_index(block_group->flags) !=
@@ -7955,8 +8016,16 @@ static noinline int find_free_extent(struct btrfs_fs_info *fs_info,
btrfs_release_block_group(block_group, delalloc);
cond_resched();
}
- up_read(&space_info->groups_sem);
-
+ if (!use_priority)
+ up_read(&space_info->groups_sem);
+out:
+ if (ins->objectid) {
+ if (use_priority)
+ up_read(&ffe_ctl.priority_tree->groups_sem);
+ else
+ up_read(&space_info->groups_sem);
+ btrfs_release_block_group(block_group, delalloc);
+ }
ret = find_free_extent_update_loop(fs_info, last_ptr, ins, &ffe_ctl,
full_search, use_cluster);
if (ret > 0)
@@ -10194,7 +10263,6 @@ static int check_chunk_block_group_mappings(struct btrfs_fs_info *fs_info)
return ret;
}
-static long compute_block_group_priority(struct btrfs_block_group_cache *bg);
static void add_block_group_priority(struct btrfs_block_group_cache *cache);
int btrfs_read_block_groups(struct btrfs_fs_info *info)
{
--
2.19.1
next prev parent reply other threads:[~2018-11-28 3:04 UTC|newest]
Thread overview: 23+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-11-28 3:11 [RFC PATCH 00/17] btrfs: implementation of priority aware allocator Su Yue
2018-11-28 3:11 ` [RFC PATCH 01/17] btrfs: priority alloc: prepare " Su Yue
2018-11-28 8:24 ` Nikolay Borisov
2018-11-28 9:24 ` Su Yue
2018-11-28 3:11 ` [RFC PATCH 02/17] btrfs: add mount definition BTRFS_MOUNT_PRIORITY_USAGE Su Yue
2018-11-28 3:11 ` [RFC PATCH 03/17] btrfs: priority alloc: introduce compute_block_group_priority/usage Su Yue
2018-11-28 8:56 ` Nikolay Borisov
2018-11-28 3:11 ` [RFC PATCH 04/17] btrfs: priority alloc: add functions to create/remove priority trees Su Yue
2018-11-28 3:11 ` [RFC PATCH 05/17] btrfs: priority alloc: introduce functions to add block group to priority tree Su Yue
2018-11-28 3:11 ` [RFC PATCH 06/17] btrfs: priority alloc: introduce three macros to mark block group status Su Yue
2018-11-28 3:11 ` [RFC PATCH 07/17] btrfs: priority alloc: add functions to remove block group from priority tree Su Yue
2018-11-28 3:11 ` [RFC PATCH 08/17] btrfs: priority alloc: add btrfs_update_block_group_priority() Su Yue
2018-11-28 3:11 ` [RFC PATCH 09/17] btrfs: priority alloc: call create/remove_priority_trees in space_info Su Yue
2018-11-28 3:11 ` [RFC PATCH 10/17] btrfs: priority alloc: call add_block_group_priority while reading or making block group Su Yue
2018-11-28 3:11 ` [RFC PATCH 11/17] btrfs: priority alloc: remove block group from priority tree while removing " Su Yue
2018-11-28 3:11 ` [RFC PATCH 12/17] btrfs: priority alloc: introduce find_free_extent_search() Su Yue
2018-11-28 3:11 ` Su Yue [this message]
2018-11-28 3:11 ` [RFC PATCH 14/17] btrfs: priority alloc: introduce btrfs_set_bg_updating and call btrfs_update_block_group_prioriy Su Yue
2018-11-28 3:11 ` [RFC PATCH 15/17] btrfs: priority alloc: write bg->priority_groups_sem while waiting reservation Su Yue
2018-11-28 3:11 ` [RFC PATCH 16/17] btrfs: priority alloc: write bg->priority_tree->groups_sem to avoid race in btrfs_delete_unused_bgs() Su Yue
2018-11-28 3:11 ` [RFC PATCH 17/17] btrfs: add mount option "priority_alloc=%s" Su Yue
2018-11-28 4:04 ` [RFC PATCH 00/17] btrfs: implementation of priority aware allocator Qu Wenruo
2018-12-02 5:28 ` Su Yue
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=20181128031148.357-14-suy.fnst@cn.fujitsu.com \
--to=suy.fnst@cn.fujitsu.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).