linux-btrfs.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Naohiro Aota <naohiro.aota@wdc.com>
To: David Sterba <dsterba@suse.com>, Josef Bacik <josef@toxicpanda.com>
Cc: linux-btrfs@vger.kernel.org, Naohiro Aota <naohiro.aota@wdc.com>
Subject: [PATCH v2 15/17] btrfs: zoned: avoid chunk allocation if active block group has enough space
Date: Thu, 19 Aug 2021 21:19:22 +0900	[thread overview]
Message-ID: <e084ccec159d9e5b1e4015b46cc09c7876e2fa30.1629349224.git.naohiro.aota@wdc.com> (raw)
In-Reply-To: <cover.1629349224.git.naohiro.aota@wdc.com>

The current extent allocator tries to allocate a new block group when the
existing block groups do not have enough space. On a ZNS device, a new
block group means a new active zone. If the number of active zones has
already reached the max_active_zones, activating a new zone needs to finish
an existing zone, leading to wasting the free space there.

So, instead, it should reuse the existing active block groups as much as
possible when we can't activate any other zones without sacrificing an
already activated block group.

While at it, I converted find_free_extent_update_loop() to check the
found_extent() case early and made the other conditions simpler.

Signed-off-by: Naohiro Aota <naohiro.aota@wdc.com>
---
 fs/btrfs/extent-tree.c | 27 ++++++++++++++++++++-------
 fs/btrfs/zoned.c       | 32 ++++++++++++++++++++++++++++++++
 fs/btrfs/zoned.h       |  8 ++++++++
 3 files changed, 60 insertions(+), 7 deletions(-)

diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c
index 1daa432673c4..b11097f557f8 100644
--- a/fs/btrfs/extent-tree.c
+++ b/fs/btrfs/extent-tree.c
@@ -3478,6 +3478,7 @@ struct find_free_extent_ctl {
 	/* Basic allocation info */
 	u64 ram_bytes;
 	u64 num_bytes;
+	u64 min_alloc_size;
 	u64 empty_size;
 	u64 flags;
 	int delalloc;
@@ -3946,18 +3947,29 @@ static int find_free_extent_update_loop(struct btrfs_fs_info *fs_info,
 	    ffe_ctl->have_caching_bg && !ffe_ctl->orig_have_caching_bg)
 		ffe_ctl->orig_have_caching_bg = true;
 
-	if (!ins->objectid && ffe_ctl->loop >= LOOP_CACHING_WAIT &&
-	    ffe_ctl->have_caching_bg)
-		return 1;
-
-	if (!ins->objectid && ++(ffe_ctl->index) < BTRFS_NR_RAID_TYPES)
-		return 1;
-
 	if (ins->objectid) {
 		found_extent(ffe_ctl, ins);
 		return 0;
 	}
 
+	if (ffe_ctl->max_extent_size >= ffe_ctl->min_alloc_size &&
+	    !btrfs_can_activate_zone(fs_info->fs_devices, ffe_ctl->index)) {
+		/*
+		 * If we have enough free space left in an already active
+		 * block group and we can't activate any other zone now,
+		 * retry the active ones with a smaller allocation size.
+		 * Returning early from here will tell
+		 * btrfs_reserve_extent() to haven the size.
+		 */
+		return -ENOSPC;
+	}
+
+	if (ffe_ctl->loop >= LOOP_CACHING_WAIT && ffe_ctl->have_caching_bg)
+		return 1;
+
+	if (++(ffe_ctl->index) < BTRFS_NR_RAID_TYPES)
+		return 1;
+
 	/*
 	 * LOOP_CACHING_NOWAIT, search partially cached block groups, kicking
 	 *			caching kthreads as we move along
@@ -4434,6 +4446,7 @@ int btrfs_reserve_extent(struct btrfs_root *root, u64 ram_bytes,
 
 	ffe_ctl.ram_bytes = ram_bytes;
 	ffe_ctl.num_bytes = num_bytes;
+	ffe_ctl.min_alloc_size = min_alloc_size;
 	ffe_ctl.empty_size = empty_size;
 	ffe_ctl.flags = flags;
 	ffe_ctl.delalloc = delalloc;
diff --git a/fs/btrfs/zoned.c b/fs/btrfs/zoned.c
index 441cdd4c507f..74f98d38abcc 100644
--- a/fs/btrfs/zoned.c
+++ b/fs/btrfs/zoned.c
@@ -1878,3 +1878,35 @@ int btrfs_zone_finish(struct btrfs_block_group *block_group)
 
 	return ret;
 }
+
+bool btrfs_can_activate_zone(struct btrfs_fs_devices *fs_devices,
+			     int raid_index)
+{
+	struct btrfs_device *device;
+	bool ret = false;
+
+	if (!btrfs_is_zoned(fs_devices->fs_info))
+		return true;
+
+	/* Non-single profiles are not supported yet */
+	if (raid_index != BTRFS_RAID_SINGLE)
+		return false;
+
+	/* Check if there is a device with active zones left */
+	mutex_lock(&fs_devices->device_list_mutex);
+	list_for_each_entry(device, &fs_devices->devices, dev_list) {
+		struct btrfs_zoned_device_info *zinfo = device->zone_info;
+
+		if (!device->bdev)
+			continue;
+
+		if (!zinfo->max_active_zones ||
+		    atomic_read(&zinfo->active_zones_left)) {
+			ret = true;
+			break;
+		}
+	}
+	mutex_unlock(&fs_devices->device_list_mutex);
+
+	return ret;
+}
diff --git a/fs/btrfs/zoned.h b/fs/btrfs/zoned.h
index 2345ecfa1805..ade6588c4ccd 100644
--- a/fs/btrfs/zoned.h
+++ b/fs/btrfs/zoned.h
@@ -71,6 +71,8 @@ struct btrfs_device *btrfs_zoned_get_device(struct btrfs_fs_info *fs_info,
 					    u64 logical, u64 length);
 bool btrfs_zone_activate(struct btrfs_block_group *block_group);
 int btrfs_zone_finish(struct btrfs_block_group *block_group);
+bool btrfs_can_activate_zone(struct btrfs_fs_devices *fs_devices,
+			     int raid_index);
 #else /* CONFIG_BLK_DEV_ZONED */
 static inline int btrfs_get_dev_zone(struct btrfs_device *device, u64 pos,
 				     struct blk_zone *zone)
@@ -216,6 +218,12 @@ static inline int btrfs_zone_finish(struct btrfs_block_group *block_group)
 	return 0;
 }
 
+static inline bool btrfs_can_activate_zone(struct btrfs_fs_devices *fs_devices,
+					   int raid_index)
+{
+	return true;
+}
+
 #endif
 
 static inline bool btrfs_dev_is_sequential(struct btrfs_device *device, u64 pos)
-- 
2.33.0


  parent reply	other threads:[~2021-08-19 12:27 UTC|newest]

Thread overview: 27+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-08-19 12:19 [PATCH v2 00/17] ZNS Support for Btrfs Naohiro Aota
2021-08-19 12:19 ` [PATCH v2 01/17] btrfs: zoned: load zone capacity information from devices Naohiro Aota
2021-08-24  7:52   ` Johannes Thumshirn
2021-08-19 12:19 ` [PATCH v2 02/17] btrfs: zoned: move btrfs_free_excluded_extents out from btrfs_calc_zone_unusable Naohiro Aota
2021-08-24  7:55   ` Johannes Thumshirn
2021-08-19 12:19 ` [PATCH v2 03/17] btrfs: zoned: calculate free space from zone capacity Naohiro Aota
2021-08-24  7:59   ` Johannes Thumshirn
2021-08-24 15:27     ` David Sterba
2021-08-24 16:04       ` Johannes Thumshirn
2021-08-19 12:19 ` [PATCH v2 04/17] btrfs: zoned: tweak reclaim threshold for " Naohiro Aota
2021-08-24  8:09   ` Johannes Thumshirn
2021-08-19 12:19 ` [PATCH v2 05/17] btrfs: zoned: consider zone as full when no more SB can be written Naohiro Aota
2021-08-24  8:37   ` Johannes Thumshirn
2021-08-19 12:19 ` [PATCH v2 06/17] btrfs: zoned: locate superblock position using zone capacity Naohiro Aota
2021-08-25  8:32   ` Johannes Thumshirn
2021-08-19 12:19 ` [PATCH v2 07/17] btrfs: zoned: finish superblock zone once no space left for new SB Naohiro Aota
2021-08-19 12:19 ` [PATCH v2 08/17] btrfs: zoned: load active zone information from devices Naohiro Aota
2021-08-19 12:19 ` [PATCH v2 09/17] btrfs: zoned: introduce physical_map to btrfs_block_group Naohiro Aota
2021-08-19 12:19 ` [PATCH v2 10/17] btrfs: zoned: implement active zone tracking Naohiro Aota
2021-08-19 12:19 ` [PATCH v2 11/17] btrfs: zoned: load active zone info for block group Naohiro Aota
2021-08-19 12:19 ` [PATCH v2 12/17] btrfs: zoned: activate block group on allocation Naohiro Aota
2021-08-19 12:19 ` [PATCH v2 13/17] btrfs: zoned: activate new block group Naohiro Aota
2021-08-19 12:19 ` [PATCH v2 14/17] btrfs: move ffe_ctl one level up Naohiro Aota
2021-08-19 12:19 ` Naohiro Aota [this message]
2021-08-19 12:19 ` [PATCH v2 16/17] btrfs: zoned: finish fully written block group Naohiro Aota
2021-08-19 12:19 ` [PATCH v2 17/17] btrfs: zoned: finish relocating " Naohiro Aota
2021-08-27 16:25 ` [PATCH v2 00/17] ZNS Support for Btrfs 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=e084ccec159d9e5b1e4015b46cc09c7876e2fa30.1629349224.git.naohiro.aota@wdc.com \
    --to=naohiro.aota@wdc.com \
    --cc=dsterba@suse.com \
    --cc=josef@toxicpanda.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).