linux-btrfs.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
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




  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).