@@ -1510,12 +1510,28 @@ void disk_free_zone_resources(struct gendisk *disk)
disk->nr_zones = 0;
}
+static inline bool disk_need_zone_resources(struct gendisk *disk)
+{
+ /*
+ * All mq zoned devices need zone resources so that the block layer
+ * can automatically handle write BIO plugging. BIO-based device drivers
+ * (e.g. DM devices) are normally responsible for handling zone write
+ * ordering and do not need zone resources, unless the driver requires
+ * zone append emulation.
+ */
+ return queue_is_mq(disk->queue) ||
+ queue_emulates_zone_append(disk->queue);
+}
+
static int disk_revalidate_zone_resources(struct gendisk *disk,
unsigned int nr_zones)
{
struct queue_limits *lim = &disk->queue->limits;
unsigned int pool_size;
+ if (!disk_need_zone_resources(disk))
+ return 0;
+
/*
* If the device has no limit on the maximum number of open and active
* zones, use BLK_ZONE_WPLUG_DEFAULT_POOL_SIZE.
@@ -1633,6 +1649,9 @@ static int blk_revalidate_zone_cb(struct blk_zone *zone, unsigned int idx,
disk->disk_name);
return -ENODEV;
}
+
+ if (!disk_need_zone_resources(disk))
+ break;
if (!args->conv_zones_bitmap) {
args->conv_zones_bitmap =
blk_alloc_zone_bitmap(q->node, args->nr_zones);
@@ -1664,10 +1683,11 @@ static int blk_revalidate_zone_cb(struct blk_zone *zone, unsigned int idx,
/*
* We need to track the write pointer of all zones that are not
* empty nor full. So make sure we have a zone write plug for
- * such zone.
+ * such zone if the device has a zone write plug hash table.
*/
wp_offset = blk_zone_wp_offset(zone);
- if (wp_offset && wp_offset < zone_sectors) {
+ if (disk->zone_wplugs_hash &&
+ wp_offset && wp_offset < zone_sectors) {
zwplug = disk_get_and_lock_zone_wplug(disk, zone->start,
GFP_NOIO, &flags);
if (!zwplug)
@@ -1698,8 +1718,8 @@ static int blk_revalidate_zone_cb(struct blk_zone *zone, unsigned int idx,
* be called within the disk ->revalidate method for blk-mq based drivers.
* Before calling this function, the device driver must already have set the
* device zone size (chunk_sector limit) and the max zone append limit.
- * For BIO based drivers, this function cannot be used. BIO based device drivers
- * only need to set disk->nr_zones so that the sysfs exposed value is correct.
+ * BIO based drivers can also use this function as long as the device queue
+ * can be safely frozen.
* If the @update_driver_data callback function is not NULL, the callback is
* executed with the device request queue frozen after all zones have been
* checked.
@@ -1716,8 +1736,6 @@ int blk_revalidate_disk_zones(struct gendisk *disk,
if (WARN_ON_ONCE(!blk_queue_is_zoned(q)))
return -EIO;
- if (WARN_ON_ONCE(!queue_is_mq(q)))
- return -EIO;
if (!capacity)
return -ENODEV;