All of lore.kernel.org
 help / color / mirror / Atom feed
From: Naohiro Aota <naohiro.aota@wdc.com>
To: linux-btrfs@vger.kernel.org, dsterba@suse.com
Cc: hare@suse.com, linux-fsdevel@vger.kernel.org,
	Naohiro Aota <naohiro.aota@wdc.com>,
	Josef Bacik <josef@toxicpanda.com>,
	Johannes Thumshirn <johannes.thumshirn@wdc.com>
Subject: [PATCH v15 39/42] btrfs: zoned: extend zoned allocator to use dedicated tree-log block group
Date: Thu,  4 Feb 2021 19:22:18 +0900	[thread overview]
Message-ID: <4a02c3ff283a1c2d71bfa3b0a7135b062af7385e.1612434091.git.naohiro.aota@wdc.com> (raw)
In-Reply-To: <b36444df121d46c6d9638a8ae8eacecaa845fbe4.1612434091.git.naohiro.aota@wdc.com>

This is the 1/3 patch to enable tree log on zoned filesystems.

The tree-log feature does not work on a zoned filesystem as is. Blocks for
a tree-log tree are allocated mixed with other metadata blocks and btrfs
writes and syncs the tree-log blocks to devices at the time of fsync(),
which has a different timing than a global transaction commit. As a
result, both writing tree-log blocks and writing other metadata blocks
become non-sequential writes that zoned filesystems must avoid.

Introduce a dedicated block group for tree-log blocks, so that tree-log
blocks and other metadata blocks can be separate write streams.  As a
result, each write stream can now be written to devices separately.
"fs_info->treelog_bg" tracks the dedicated block group and btrfs assigns
"treelog_bg" on-demand on tree-log block allocation time.

This commit extends the zoned block allocator to use the block group.

Reviewed-by: Josef Bacik <josef@toxicpanda.com>
Signed-off-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
Signed-off-by: Naohiro Aota <naohiro.aota@wdc.com>
---
 fs/btrfs/block-group.c |  2 ++
 fs/btrfs/ctree.h       |  2 ++
 fs/btrfs/disk-io.c     |  1 +
 fs/btrfs/extent-tree.c | 75 +++++++++++++++++++++++++++++++++++++++---
 fs/btrfs/zoned.h       | 14 ++++++++
 5 files changed, 90 insertions(+), 4 deletions(-)

diff --git a/fs/btrfs/block-group.c b/fs/btrfs/block-group.c
index f5e9f560ce6d..5064be59dac5 100644
--- a/fs/btrfs/block-group.c
+++ b/fs/btrfs/block-group.c
@@ -901,6 +901,8 @@ int btrfs_remove_block_group(struct btrfs_trans_handle *trans,
 	btrfs_return_cluster_to_free_space(block_group, cluster);
 	spin_unlock(&cluster->refill_lock);
 
+	btrfs_clear_treelog_bg(block_group);
+
 	path = btrfs_alloc_path();
 	if (!path) {
 		ret = -ENOMEM;
diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h
index 1bb4f767966a..6f4b493625ef 100644
--- a/fs/btrfs/ctree.h
+++ b/fs/btrfs/ctree.h
@@ -976,6 +976,8 @@ struct btrfs_fs_info {
 	/* Max size to emit ZONE_APPEND write command */
 	u64 max_zone_append_size;
 	struct mutex zoned_meta_io_lock;
+	spinlock_t treelog_bg_lock;
+	u64 treelog_bg;
 
 #ifdef CONFIG_BTRFS_FS_REF_VERIFY
 	spinlock_t ref_verify_lock;
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
index d2fa92526b3b..84c6650d5ef7 100644
--- a/fs/btrfs/disk-io.c
+++ b/fs/btrfs/disk-io.c
@@ -2787,6 +2787,7 @@ void btrfs_init_fs_info(struct btrfs_fs_info *fs_info)
 	spin_lock_init(&fs_info->super_lock);
 	spin_lock_init(&fs_info->buffer_lock);
 	spin_lock_init(&fs_info->unused_bgs_lock);
+	spin_lock_init(&fs_info->treelog_bg_lock);
 	rwlock_init(&fs_info->tree_mod_log_lock);
 	mutex_init(&fs_info->unused_bg_unpin_mutex);
 	mutex_init(&fs_info->delete_unused_bgs_mutex);
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c
index e2b2abc42295..f8e8c17e5624 100644
--- a/fs/btrfs/extent-tree.c
+++ b/fs/btrfs/extent-tree.c
@@ -3497,6 +3497,9 @@ struct find_free_extent_ctl {
 	bool have_caching_bg;
 	bool orig_have_caching_bg;
 
+	/* Allocation is called for tree-log */
+	bool for_treelog;
+
 	/* RAID index, converted from flags */
 	int index;
 
@@ -3725,6 +3728,22 @@ static int do_allocation_clustered(struct btrfs_block_group *block_group,
 	return find_free_extent_unclustered(block_group, ffe_ctl);
 }
 
+/*
+ * Tree-log block group locking
+ * ============================
+ *
+ * fs_info::treelog_bg_lock protects the fs_info::treelog_bg which
+ * indicates the starting address of a block group, which is reserved only
+ * for tree-log metadata.
+ *
+ * Lock nesting
+ * ============
+ *
+ * space_info::lock
+ *   block_group::lock
+ *     fs_info::treelog_bg_lock
+ */
+
 /*
  * Simple allocator for sequential only block group. It only allows sequential
  * allocation. No need to play with trees. This function also reserves the
@@ -3734,23 +3753,54 @@ static int do_allocation_zoned(struct btrfs_block_group *block_group,
 			       struct find_free_extent_ctl *ffe_ctl,
 			       struct btrfs_block_group **bg_ret)
 {
+	struct btrfs_fs_info *fs_info = block_group->fs_info;
 	struct btrfs_space_info *space_info = block_group->space_info;
 	struct btrfs_free_space_ctl *ctl = block_group->free_space_ctl;
 	u64 start = block_group->start;
 	u64 num_bytes = ffe_ctl->num_bytes;
 	u64 avail;
+	u64 bytenr = block_group->start;
+	u64 log_bytenr;
 	int ret = 0;
+	bool skip;
 
 	ASSERT(btrfs_is_zoned(block_group->fs_info));
 
+	/*
+	 * Do not allow non-tree-log blocks in the dedicated tree-log block
+	 * group, and vice versa.
+	 */
+	spin_lock(&fs_info->treelog_bg_lock);
+	log_bytenr = fs_info->treelog_bg;
+	skip = log_bytenr && ((ffe_ctl->for_treelog && bytenr != log_bytenr) ||
+			      (!ffe_ctl->for_treelog && bytenr == log_bytenr));
+	spin_unlock(&fs_info->treelog_bg_lock);
+	if (skip)
+		return 1;
+
 	spin_lock(&space_info->lock);
 	spin_lock(&block_group->lock);
+	spin_lock(&fs_info->treelog_bg_lock);
+
+	ASSERT(!ffe_ctl->for_treelog ||
+	       block_group->start == fs_info->treelog_bg ||
+	       fs_info->treelog_bg == 0);
 
 	if (block_group->ro) {
 		ret = 1;
 		goto out;
 	}
 
+	/*
+	 * Do not allow currently using block group to be tree-log dedicated
+	 * block group.
+	 */
+	if (ffe_ctl->for_treelog && !fs_info->treelog_bg &&
+	    (block_group->used || block_group->reserved)) {
+		ret = 1;
+		goto out;
+	}
+
 	avail = block_group->length - block_group->alloc_offset;
 	if (avail < num_bytes) {
 		if (ffe_ctl->max_extent_size < avail) {
@@ -3765,6 +3815,9 @@ static int do_allocation_zoned(struct btrfs_block_group *block_group,
 		goto out;
 	}
 
+	if (ffe_ctl->for_treelog && !fs_info->treelog_bg)
+		fs_info->treelog_bg = block_group->start;
+
 	ffe_ctl->found_offset = start + block_group->alloc_offset;
 	block_group->alloc_offset += num_bytes;
 	spin_lock(&ctl->tree_lock);
@@ -3779,6 +3832,9 @@ static int do_allocation_zoned(struct btrfs_block_group *block_group,
 	ffe_ctl->search_start = ffe_ctl->found_offset;
 
 out:
+	if (ret && ffe_ctl->for_treelog)
+		fs_info->treelog_bg = 0;
+	spin_unlock(&fs_info->treelog_bg_lock);
 	spin_unlock(&block_group->lock);
 	spin_unlock(&space_info->lock);
 	return ret;
@@ -4028,7 +4084,12 @@ static int prepare_allocation(struct btrfs_fs_info *fs_info,
 		return prepare_allocation_clustered(fs_info, ffe_ctl,
 						    space_info, ins);
 	case BTRFS_EXTENT_ALLOC_ZONED:
-		/* Nothing to do */
+		if (ffe_ctl->for_treelog) {
+			spin_lock(&fs_info->treelog_bg_lock);
+			if (fs_info->treelog_bg)
+				ffe_ctl->hint_byte = fs_info->treelog_bg;
+			spin_unlock(&fs_info->treelog_bg_lock);
+		}
 		return 0;
 	default:
 		BUG();
@@ -4072,6 +4133,7 @@ static noinline int find_free_extent(struct btrfs_root *root,
 	struct find_free_extent_ctl ffe_ctl = {0};
 	struct btrfs_space_info *space_info;
 	bool full_search = false;
+	bool for_treelog = root->root_key.objectid == BTRFS_TREE_LOG_OBJECTID;
 
 	WARN_ON(num_bytes < fs_info->sectorsize);
 
@@ -4085,6 +4147,7 @@ static noinline int find_free_extent(struct btrfs_root *root,
 	ffe_ctl.orig_have_caching_bg = false;
 	ffe_ctl.found_offset = 0;
 	ffe_ctl.hint_byte = hint_byte_orig;
+	ffe_ctl.for_treelog = for_treelog;
 	ffe_ctl.policy = BTRFS_EXTENT_ALLOC_CLUSTERED;
 
 	/* For clustered allocation */
@@ -4159,8 +4222,11 @@ static noinline int find_free_extent(struct btrfs_root *root,
 		struct btrfs_block_group *bg_ret;
 
 		/* If the block group is read-only, we can skip it entirely. */
-		if (unlikely(block_group->ro))
+		if (unlikely(block_group->ro)) {
+			if (for_treelog)
+				btrfs_clear_treelog_bg(block_group);
 			continue;
+		}
 
 		btrfs_grab_block_group(block_group, delalloc);
 		ffe_ctl.search_start = block_group->start;
@@ -4346,6 +4412,7 @@ int btrfs_reserve_extent(struct btrfs_root *root, u64 ram_bytes,
 	bool final_tried = num_bytes == min_alloc_size;
 	u64 flags;
 	int ret;
+	bool for_treelog = root->root_key.objectid == BTRFS_TREE_LOG_OBJECTID;
 
 	flags = get_alloc_profile_by_root(root, is_data);
 again:
@@ -4369,8 +4436,8 @@ int btrfs_reserve_extent(struct btrfs_root *root, u64 ram_bytes,
 
 			sinfo = btrfs_find_space_info(fs_info, flags);
 			btrfs_err(fs_info,
-				  "allocation failed flags %llu, wanted %llu",
-				  flags, num_bytes);
+			"allocation failed flags %llu, wanted %llu tree-log %d",
+				  flags, num_bytes, for_treelog);
 			if (sinfo)
 				btrfs_dump_space_info(fs_info, sinfo,
 						      num_bytes, 1);
diff --git a/fs/btrfs/zoned.h b/fs/btrfs/zoned.h
index 932ad9bc0de6..61e969652fe1 100644
--- a/fs/btrfs/zoned.h
+++ b/fs/btrfs/zoned.h
@@ -7,6 +7,7 @@
 #include <linux/blkdev.h>
 #include "volumes.h"
 #include "disk-io.h"
+#include "block-group.h"
 
 struct btrfs_zoned_device_info {
 	/*
@@ -290,4 +291,17 @@ static inline void btrfs_zoned_meta_io_unlock(struct btrfs_fs_info *fs_info)
 	mutex_unlock(&fs_info->zoned_meta_io_lock);
 }
 
+static inline void btrfs_clear_treelog_bg(struct btrfs_block_group *bg)
+{
+	struct btrfs_fs_info *fs_info = bg->fs_info;
+
+	if (!btrfs_is_zoned(fs_info))
+		return;
+
+	spin_lock(&fs_info->treelog_bg_lock);
+	if (fs_info->treelog_bg == bg->start)
+		fs_info->treelog_bg = 0;
+	spin_unlock(&fs_info->treelog_bg_lock);
+}
+
 #endif
-- 
2.30.0


  parent reply	other threads:[~2021-02-04 10:33 UTC|newest]

Thread overview: 72+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-02-04 10:21 [PATCH v15 00/42] btrfs: zoned block device support Naohiro Aota
2021-02-04 10:21 ` [PATCH v15 01/42] block: add bio_add_zone_append_page Naohiro Aota
2021-02-04 10:21   ` [PATCH v15 02/42] iomap: support REQ_OP_ZONE_APPEND Naohiro Aota
2021-02-04 10:21   ` [PATCH v15 03/42] btrfs: zoned: defer loading zone info after opening trees Naohiro Aota
2021-02-04 10:21   ` [PATCH v15 04/42] btrfs: zoned: use regular super block location on zone emulation Naohiro Aota
2021-02-04 10:21   ` [PATCH v15 05/42] btrfs: release path before calling to btrfs_load_block_group_zone_info Naohiro Aota
2021-02-04 10:21   ` [PATCH v15 06/42] btrfs: zoned: do not load fs_info::zoned from incompat flag Naohiro Aota
2021-02-04 10:21   ` [PATCH v15 07/42] btrfs: zoned: disallow fitrim on zoned filesystems Naohiro Aota
2021-02-04 10:21   ` [PATCH v15 08/42] btrfs: zoned: allow zoned filesystems on non-zoned block devices Naohiro Aota
2021-02-04 10:21   ` [PATCH v15 09/42] btrfs: zoned: implement zoned chunk allocator Naohiro Aota
2021-02-04 10:21   ` [PATCH v15 10/42] btrfs: zoned: verify device extent is aligned to zone Naohiro Aota
2021-02-04 10:21   ` [PATCH v15 11/42] btrfs: zoned: load zone's allocation offset Naohiro Aota
2021-02-04 10:21   ` [PATCH v15 12/42] btrfs: zoned: calculate allocation offset for conventional zones Naohiro Aota
2021-02-04 10:21   ` [PATCH v15 13/42] btrfs: zoned: track unusable bytes for zones Naohiro Aota
2021-02-04 10:21   ` [PATCH v15 14/42] btrfs: zoned: implement sequential extent allocation Naohiro Aota
2021-02-04 10:21   ` [PATCH v15 15/42] btrfs: zoned: redirty released extent buffers Naohiro Aota
2021-02-04 10:21   ` [PATCH v15 16/42] btrfs: zoned: advance allocation pointer after tree log node Naohiro Aota
2021-02-04 10:21   ` [PATCH v15 17/42] btrfs: zoned: reset zones of unused block groups Naohiro Aota
2021-02-04 10:21   ` [PATCH v15 18/42] btrfs: factor out helper adding a page to bio Naohiro Aota
2021-02-04 10:21   ` [PATCH v15 19/42] btrfs: zoned: use bio_add_zone_append_page Naohiro Aota
2021-02-04 10:21   ` [PATCH v15 20/42] btrfs: zoned: handle REQ_OP_ZONE_APPEND as writing Naohiro Aota
2021-02-04 10:22   ` [PATCH v15 21/42] btrfs: zoned: split ordered extent when bio is sent Naohiro Aota
2021-02-04 10:22   ` [PATCH v15 22/42] btrfs: zoned: check if bio spans across an ordered extent Naohiro Aota
2021-02-04 10:22   ` [PATCH v15 23/42] btrfs: extend btrfs_rmap_block for specifying a device Naohiro Aota
2021-02-04 10:22   ` [PATCH v15 24/42] btrfs: zoned: cache if block-group is on a sequential zone Naohiro Aota
2021-02-04 10:22   ` [PATCH v15 25/42] btrfs: save irq flags when looking up an ordered extent Naohiro Aota
2021-02-04 10:22   ` [PATCH v15 26/42] btrfs: zoned: use ZONE_APPEND write for zoned btrfs Naohiro Aota
2021-02-04 10:22   ` [PATCH v15 27/42] btrfs: zoned: enable zone append writing for direct IO Naohiro Aota
2021-02-04 10:22   ` [PATCH v15 28/42] btrfs: zoned: introduce dedicated data write path for zoned filesystems Naohiro Aota
2021-02-04 10:22   ` [PATCH v15 29/42] btrfs: zoned: serialize metadata IO Naohiro Aota
2021-02-04 10:22   ` [PATCH v15 30/42] btrfs: zoned: wait for existing extents before truncating Naohiro Aota
2021-02-04 10:22   ` [PATCH v15 31/42] btrfs: zoned: do not use async metadata checksum on zoned filesystems Naohiro Aota
2021-02-04 10:22   ` [PATCH v15 32/42] btrfs: zoned: mark block groups to copy for device-replace Naohiro Aota
2021-02-04 10:22   ` [PATCH v15 33/42] btrfs: zoned: implement cloning for zoned device-replace Naohiro Aota
2021-02-04 10:22   ` [PATCH v15 34/42] btrfs: zoned: implement copying " Naohiro Aota
2021-02-04 10:22   ` [PATCH v15 35/42] btrfs: zoned: support dev-replace in zoned filesystems Naohiro Aota
2021-02-04 10:22   ` [PATCH v15 36/42] btrfs: zoned: enable relocation on a zoned filesystem Naohiro Aota
2021-02-04 10:22   ` [PATCH v15 37/42] btrfs: zoned: relocate block group to repair IO failure in zoned filesystems Naohiro Aota
2021-02-04 10:22   ` [PATCH v15 38/42] btrfs: split alloc_log_tree() Naohiro Aota
2021-02-04 10:22   ` Naohiro Aota [this message]
2021-02-04 10:22   ` [PATCH v15 40/42] btrfs: zoned: serialize log transaction on zoned filesystems Naohiro Aota
2021-02-04 11:50     ` Filipe Manana
2021-02-05  7:21       ` Naohiro Aota
2021-02-05  9:15     ` Naohiro Aota
2021-02-05 11:21       ` Filipe Manana
2021-02-09  1:49       ` David Sterba
2021-02-04 10:22   ` [PATCH v15 41/42] btrfs: zoned: reorder log node allocation on zoned filesystem Naohiro Aota
2021-02-04 11:57     ` Filipe Manana
2021-02-04 14:54       ` Johannes Thumshirn
2021-02-04 15:48         ` David Sterba
2021-02-04 15:51           ` Johannes Thumshirn
2021-02-04 10:22   ` [PATCH v15 42/42] btrfs: zoned: enable to mount ZONED incompat flag Naohiro Aota
2021-02-05  9:26   ` [PATCH v15 43/43] btrfs: zoned: deal with holes writing out tree-log pages Naohiro Aota
2021-02-05 11:49     ` Filipe Manana
2021-02-05 12:55       ` Naohiro Aota
2021-02-05 13:07         ` Filipe Manana
2021-02-05 14:19       ` Filipe Manana
2021-02-05 14:46         ` Naohiro Aota
2021-02-05 14:58     ` [PATCH v15.1 " Naohiro Aota
2021-02-05 16:25       ` Filipe Manana
2021-02-09  1:55       ` David Sterba
2021-02-10 19:58 ` [PATCH v15 00/42] btrfs: zoned block device support David Sterba
2021-02-11  9:58   ` Johannes Thumshirn
2021-02-11 15:19     ` David Sterba
2021-02-11 15:26       ` Johannes Thumshirn
2021-02-11 15:46         ` David Sterba
2021-02-15 16:58           ` Johannes Thumshirn
2021-02-15 17:02             ` David Sterba
2021-02-16  4:33             ` Naohiro Aota
2021-02-16 11:46               ` David Sterba
2021-02-22  7:50                 ` Naohiro Aota
2021-02-22 16:00                   ` 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=4a02c3ff283a1c2d71bfa3b0a7135b062af7385e.1612434091.git.naohiro.aota@wdc.com \
    --to=naohiro.aota@wdc.com \
    --cc=dsterba@suse.com \
    --cc=hare@suse.com \
    --cc=johannes.thumshirn@wdc.com \
    --cc=josef@toxicpanda.com \
    --cc=linux-btrfs@vger.kernel.org \
    --cc=linux-fsdevel@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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.