diff mbox series

[v2,09/28] block: Fake max open zones limit when there is no limit

Message ID 20240325044452.3125418-10-dlemoal@kernel.org (mailing list archive)
State New, archived
Headers show
Series Zone write plugging | expand

Commit Message

Damien Le Moal March 25, 2024, 4:44 a.m. UTC
For a zoned block device that has no limit on the number of open zones
and no limit on the number of active zones, the zone write plug mempool
size defaults to 128 zone write plugs. For such case, set the device
max_open_zones queue limit to this value to indicate to the user the
potential performance penalty that may happen when writing
simultaneously to more zones than the mempool size.

Signed-off-by: Damien Le Moal <dlemoal@kernel.org>
---
 block/blk-zoned.c      | 22 ++++++++++++++++++++--
 include/linux/blkdev.h |  1 +
 2 files changed, 21 insertions(+), 2 deletions(-)

Comments

Christoph Hellwig March 26, 2024, 6:57 a.m. UTC | #1
On Mon, Mar 25, 2024 at 01:44:33PM +0900, Damien Le Moal wrote:
> For a zoned block device that has no limit on the number of open zones
> and no limit on the number of active zones, the zone write plug mempool
> size defaults to 128 zone write plugs. For such case, set the device
> max_open_zones queue limit to this value to indicate to the user the
> potential performance penalty that may happen when writing
> simultaneously to more zones than the mempool size.

zone_hw_limits is a horrible name for
max(lim->max_active_zones, lim->max_open_zones).

But why do we even need it?  I'd rather make sure that we always
have valid max_open/active limits, doing something like:

	if (!max_open && !max_active)
		max_open = max_active = DEFAULT_CAP;
	else if (!max_open || WARN_ON_ONCE(max_open > max_active)
		max_open = max_active;
	else if (!max_active)
		max_active = max_open;

and do away with the extra limit.  Maybe DEFAULT_CAP should be
tunable as well?
Hannes Reinecke March 27, 2024, 7:21 a.m. UTC | #2
On 3/25/24 05:44, Damien Le Moal wrote:
> For a zoned block device that has no limit on the number of open zones
> and no limit on the number of active zones, the zone write plug mempool
> size defaults to 128 zone write plugs. For such case, set the device
> max_open_zones queue limit to this value to indicate to the user the
> potential performance penalty that may happen when writing
> simultaneously to more zones than the mempool size.
> 
> Signed-off-by: Damien Le Moal <dlemoal@kernel.org>
> ---
>   block/blk-zoned.c      | 22 ++++++++++++++++++++--
>   include/linux/blkdev.h |  1 +
>   2 files changed, 21 insertions(+), 2 deletions(-)
> 
Reviewed-by: Hannes Reinecke <hare@suse.de>

Cheers,

Hannes
diff mbox series

Patch

diff --git a/block/blk-zoned.c b/block/blk-zoned.c
index 4e93293b1233..33dea8ca9a6f 100644
--- a/block/blk-zoned.c
+++ b/block/blk-zoned.c
@@ -1428,6 +1428,9 @@  void disk_free_zone_resources(struct gendisk *disk)
 
 	disk->zone_capacity = 0;
 	disk->nr_zones = 0;
+
+	if (!disk->zone_hw_limits)
+		disk_set_max_open_zones(disk, 0);
 }
 
 static int disk_revalidate_zone_resources(struct gendisk *disk,
@@ -1437,11 +1440,24 @@  static int disk_revalidate_zone_resources(struct gendisk *disk,
 	unsigned int hash_size;
 	int ret;
 
-	hash_size = max(lim->max_open_zones, lim->max_active_zones);
-	if (!hash_size)
+	/*
+	 * If the device has no limit on the maximum number of open and active
+	 * zones, set the max_open_zones queue limit to indicate the size of
+	 * the zone write plug memory pool and hash table size so that the user
+	 * is aware of the potential performance penalty for simultaneously
+	 * writing to too many zones.
+	 */
+	disk->zone_hw_limits =
+		max(lim->max_active_zones, lim->max_open_zones);
+	if (!disk->zone_hw_limits)
 		hash_size = BLK_ZONE_DEFAULT_WPLUG_HASH_SIZE;
+	else
+		hash_size = disk->zone_hw_limits;
 	hash_size = min(hash_size, nr_zones);
 
+	if (!disk->zone_hw_limits && hash_size < nr_zones)
+		disk_set_max_open_zones(disk, hash_size);
+
 	if (!disk->zone_wplugs_hash)
 		return disk_alloc_zone_resources(disk, hash_size);
 
@@ -1451,6 +1467,8 @@  static int disk_revalidate_zone_resources(struct gendisk *disk,
 		if (ret)
 			return ret;
 		disk->zone_wplugs_pool_size = hash_size;
+		if (!disk->zone_hw_limits && hash_size < nr_zones)
+			disk_set_max_open_zones(disk, hash_size);
 	}
 
 	return 0;
diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h
index 68c60039a7ea..8eb99cab7221 100644
--- a/include/linux/blkdev.h
+++ b/include/linux/blkdev.h
@@ -193,6 +193,7 @@  struct gendisk {
 	 */
 	unsigned int		nr_zones;
 	unsigned int		zone_capacity;
+	unsigned int		zone_hw_limits;
 	unsigned long		*conv_zones_bitmap;
 	unsigned long		*seq_zones_wlock;
 	unsigned int		zone_wplugs_pool_size;