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 ab6844dce8bc13948fb02fe8a69b88d4e9c3e201..e0ee3aeabd2c89dbfb25e663d70f80cfb3ae318c 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",