Message ID | 20240606082147.96422-2-dlemoal@kernel.org (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | Fix DM zone resource limits stacking | expand |
On Thu, Jun 06, 2024 at 05:21:44PM +0900, Damien Le Moal wrote: > Make sure that the zone resource limits of a zoned block device are > correct by checking that: > (a) If the device has a max active zones limit, make sure that the max > open zones limit is lower than the max active zones limit. > (b) If the device has zone resource limits, check that the limits > values are lower than the number of sequential zones of the device. > If it is not, assume that the zoned device has no limits by setting > the limits to 0. > > For (a), a check is added to blk_validate_zoned_limits() and an error > returned if the max open zones limit exceeds the value of the max active > zone limit (if there is one). > > For (b), given that we need the number of sequential zones of the zoned > device, this check is added to disk_update_zone_resources(). This is > safe to do as that function is executed with the disk queue frozen and > the check executed after queue_limits_start_update() which takes the > queue limits lock. Of note is that the early return in this function > for zoned devices that do not use zone write plugging (e.g. DM devices > using native zone append) is moved to after the new check and adjustment > of the zone resource limits so that the check applies to any zoned > device. > > Signed-off-by: Damien Le Moal <dlemoal@kernel.org> > Reviewed-by: Christoph Hellwig <hch@lst.de> > Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com> > --- Reviewed-by: Niklas Cassel <cassel@kernel.org>
diff --git a/block/blk-settings.c b/block/blk-settings.c index effeb9a639bb..607f888fe93b 100644 --- a/block/blk-settings.c +++ b/block/blk-settings.c @@ -80,6 +80,14 @@ static int blk_validate_zoned_limits(struct queue_limits *lim) if (WARN_ON_ONCE(!IS_ENABLED(CONFIG_BLK_DEV_ZONED))) return -EINVAL; + /* + * Given that active zones include open zones, the maximum number of + * open zones cannot be larger than the maximum number of active zones. + */ + if (lim->max_active_zones && + lim->max_open_zones > lim->max_active_zones) + return -EINVAL; + if (lim->zone_write_granularity < lim->logical_block_size) lim->zone_write_granularity = lim->logical_block_size; diff --git a/block/blk-zoned.c b/block/blk-zoned.c index 52abebf56027..8f89705f5e1c 100644 --- a/block/blk-zoned.c +++ b/block/blk-zoned.c @@ -1647,8 +1647,22 @@ static int disk_update_zone_resources(struct gendisk *disk, return -ENODEV; } + lim = queue_limits_start_update(q); + + /* + * Some devices can advertize zone resource limits that are larger than + * the number of sequential zones of the zoned block device, e.g. a + * small ZNS namespace. For such case, assume that the zoned device has + * no zone resource limits. + */ + nr_seq_zones = disk->nr_zones - nr_conv_zones; + if (lim.max_open_zones >= nr_seq_zones) + lim.max_open_zones = 0; + if (lim.max_active_zones >= nr_seq_zones) + lim.max_active_zones = 0; + if (!disk->zone_wplugs_pool) - return 0; + goto commit; /* * If the device has no limit on the maximum number of open and active @@ -1657,9 +1671,6 @@ static int disk_update_zone_resources(struct gendisk *disk, * dynamic zone write plug allocation when simultaneously writing to * more zones than the size of the mempool. */ - lim = queue_limits_start_update(q); - - nr_seq_zones = disk->nr_zones - nr_conv_zones; pool_size = max(lim.max_open_zones, lim.max_active_zones); if (!pool_size) pool_size = min(BLK_ZONE_WPLUG_DEFAULT_POOL_SIZE, nr_seq_zones); @@ -1673,6 +1684,7 @@ static int disk_update_zone_resources(struct gendisk *disk, lim.max_open_zones = 0; } +commit: return queue_limits_commit_update(q, &lim); }