On 2020/06/29 8:01, Matias Bjorling wrote: > The NVMe Zoned Namespace Command Set adds support for associating > data to a zone through the Zone Descriptor Extension feature. > > The Zone Descriptor Extension size is fixed to a multiple of 64 > bytes. A value of zero communicates the feature is not available. > A value larger than zero communites the feature is available, and > the specified Zone Descriptor Extension size in bytes. > > The Zone Descriptor Extension feature is only available in the > NVMe Zoned Namespaces Command Set. Devices that supports ZAC/ZBC > therefore reports this value as zero, where as the NVMe device > driver reports the Zone Descriptor Extension size from the > specific device. > > Signed-off-by: Matias Bjørling <matias.bjorling@xxxxxxx> > --- > Documentation/block/queue-sysfs.rst | 6 ++++++ > block/blk-sysfs.c | 15 ++++++++++++++- > drivers/nvme/host/zns.c | 1 + > drivers/scsi/sd_zbc.c | 1 + > include/linux/blkdev.h | 22 ++++++++++++++++++++++ > 5 files changed, 44 insertions(+), 1 deletion(-) > > diff --git a/Documentation/block/queue-sysfs.rst b/Documentation/block/queue-sysfs.rst > index f261a5c84170..c4fa195c87b4 100644 > --- a/Documentation/block/queue-sysfs.rst > +++ b/Documentation/block/queue-sysfs.rst > @@ -265,4 +265,10 @@ devices are described in the ZBC (Zoned Block Commands) and ZAC > do not support zone commands, they will be treated as regular block devices > and zoned will report "none". > > +zone_desc_ext_bytes (RO) > +------------------------- > +This indicates the zone description extension (ZDE) size, in bytes, of a zoned > +block device. A value of '0' means that zone description extension is not > +supported. > + > Jens Axboe <jens.axboe@xxxxxxxxxx>, February 2009 > diff --git a/block/blk-sysfs.c b/block/blk-sysfs.c > index 624bb4d85fc7..0c99454823b7 100644 > --- a/block/blk-sysfs.c > +++ b/block/blk-sysfs.c > @@ -315,6 +315,12 @@ static ssize_t queue_max_active_zones_show(struct request_queue *q, char *page) > return queue_var_show(queue_max_active_zones(q), page); > } > > +static ssize_t queue_zone_desc_ext_bytes_show(struct request_queue *q, > + char *page) > +{ > + return queue_var_show(queue_zone_desc_ext_bytes(q), page); > +} > + > static ssize_t queue_nomerges_show(struct request_queue *q, char *page) > { > return queue_var_show((blk_queue_nomerges(q) << 1) | > @@ -687,6 +693,11 @@ static struct queue_sysfs_entry queue_max_active_zones_entry = { > .show = queue_max_active_zones_show, > }; > > +static struct queue_sysfs_entry queue_zone_desc_ext_bytes_entry = { > + .attr = {.name = "zone_desc_ext_bytes", .mode = 0444 }, > + .show = queue_zone_desc_ext_bytes_show, > +}; > + > static struct queue_sysfs_entry queue_nomerges_entry = { > .attr = {.name = "nomerges", .mode = 0644 }, > .show = queue_nomerges_show, > @@ -787,6 +798,7 @@ static struct attribute *queue_attrs[] = { > &queue_nr_zones_entry.attr, > &queue_max_open_zones_entry.attr, > &queue_max_active_zones_entry.attr, Which tree is this patch based on ? Not I have seen any patch introducing max active zones. > + &queue_zone_desc_ext_bytes_entry.attr, > &queue_nomerges_entry.attr, > &queue_rq_affinity_entry.attr, > &queue_iostats_entry.attr, > @@ -815,7 +827,8 @@ static umode_t queue_attr_visible(struct kobject *kobj, struct attribute *attr, > return 0; > > if ((attr == &queue_max_open_zones_entry.attr || > - attr == &queue_max_active_zones_entry.attr) && > + attr == &queue_max_active_zones_entry.attr || > + attr == &queue_zone_desc_ext_bytes_entry.attr) && > !blk_queue_is_zoned(q)) > return 0; > > diff --git a/drivers/nvme/host/zns.c b/drivers/nvme/host/zns.c > index 502070763266..5792d953a8f3 100644 > --- a/drivers/nvme/host/zns.c > +++ b/drivers/nvme/host/zns.c > @@ -84,6 +84,7 @@ int nvme_update_zone_info(struct gendisk *disk, struct nvme_ns *ns, > blk_queue_flag_set(QUEUE_FLAG_ZONE_RESETALL, q); > blk_queue_max_open_zones(q, le32_to_cpu(id->mor) + 1); > blk_queue_max_active_zones(q, le32_to_cpu(id->mar) + 1); > + blk_queue_zone_desc_ext_bytes(q, id->lbafe[lbaf].zdes << 6); > free_data: > kfree(id); > return status; > diff --git a/drivers/scsi/sd_zbc.c b/drivers/scsi/sd_zbc.c > index d8b2c49d645b..a4b6d6cf5457 100644 > --- a/drivers/scsi/sd_zbc.c > +++ b/drivers/scsi/sd_zbc.c > @@ -722,6 +722,7 @@ int sd_zbc_read_zones(struct scsi_disk *sdkp, unsigned char *buf) > else > blk_queue_max_open_zones(q, sdkp->zones_max_open); > blk_queue_max_active_zones(q, 0); > + blk_queue_zone_desc_ext_bytes(q, 0); > nr_zones = round_up(sdkp->capacity, zone_blocks) >> ilog2(zone_blocks); > > /* READ16/WRITE16 is mandatory for ZBC disks */ > diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h > index 3776140f8f20..2ed55055f68d 100644 > --- a/include/linux/blkdev.h > +++ b/include/linux/blkdev.h > @@ -522,6 +522,7 @@ struct request_queue { > unsigned long *seq_zones_wlock; > unsigned int max_open_zones; > unsigned int max_active_zones; > + unsigned int zone_desc_ext_bytes; Why is this not a queue limit ? This may need to be to be gracefully handled by device mapper for a target device using multiple zoned drives. > #endif /* CONFIG_BLK_DEV_ZONED */ > > /* > @@ -753,6 +754,18 @@ static inline unsigned int queue_max_active_zones(const struct request_queue *q) > { > return q->max_active_zones; > } > + > +static inline void blk_queue_zone_desc_ext_bytes(struct request_queue *q, > + unsigned int zone_desc_ext_bytes) > +{ > + q->zone_desc_ext_bytes = zone_desc_ext_bytes; > +} > + > +static inline unsigned int queue_zone_desc_ext_bytes( > + const struct request_queue *q) > +{ > + return q->zone_desc_ext_bytes; > +} > #else /* CONFIG_BLK_DEV_ZONED */ > static inline unsigned int blk_queue_nr_zones(struct request_queue *q) > { > @@ -784,6 +797,15 @@ static inline unsigned int queue_max_active_zones(const struct request_queue *q) > { > return 0; > } > +static inline void blk_queue_zone_desc_ext_bytes(struct request_queue *q, > + unsigned int zone_desc_ext_bytes) > +{ > +} > +static inline unsigned int queue_zone_desc_ext_bytes( > + const struct request_queue *q) > +{ > + return 0; > +} > #endif /* CONFIG_BLK_DEV_ZONED */ > > static inline bool rq_is_sync(struct request *rq) > -- Damien Le Moal Western Digital Research