btrfs: zoned: limit active zones to max_open_zones
authorNaohiro Aota <naohiro.aota@wdc.com>
Wed, 16 Jul 2025 07:59:55 +0000 (16:59 +0900)
committerDavid Sterba <dsterba@suse.com>
Wed, 13 Aug 2025 10:28:58 +0000 (12:28 +0200)
When there is no active zone limit, we can technically write into any
number of zones at the same time. However, exceeding the max open zones can
degrade performance. To prevent this, set the max_active_zones to
bdev_max_open_zones() if there is no active zone limit.

Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
Signed-off-by: Naohiro Aota <naohiro.aota@wdc.com>
Signed-off-by: David Sterba <dsterba@suse.com>
fs/btrfs/zoned.c

index ab6844d..e0ee3ae 100644 (file)
@@ -43,6 +43,9 @@
 /* Number of superblock log zones */
 #define BTRFS_NR_SB_LOG_ZONES 2
 
+/* Default number of max active zones when the device has no limits. */
+#define BTRFS_DEFAULT_MAX_ACTIVE_ZONES 128
+
 /*
  * Minimum of active zones we need:
  *
@@ -417,7 +420,10 @@ int btrfs_get_dev_zone_info(struct btrfs_device *device, bool populate_cache)
        if (!IS_ALIGNED(nr_sectors, zone_sectors))
                zone_info->nr_zones++;
 
-       max_active_zones = bdev_max_active_zones(bdev);
+       max_active_zones = min_not_zero(bdev_max_active_zones(bdev),
+                                       bdev_max_open_zones(bdev));
+       if (!max_active_zones && zone_info->nr_zones > BTRFS_DEFAULT_MAX_ACTIVE_ZONES)
+               max_active_zones = BTRFS_DEFAULT_MAX_ACTIVE_ZONES;
        if (max_active_zones && max_active_zones < BTRFS_MIN_ACTIVE_ZONES) {
                btrfs_err(fs_info,
 "zoned: %s: max active zones %u is too small, need at least %u active zones",