Skip to content

Commit 559218d

Browse files
Christoph Hellwigaxboe
authored andcommitted
block: pre-calculate max_zone_append_sectors
max_zone_append_sectors differs from all other queue limits in that the final value used is not stored in the queue_limits but needs to be obtained using queue_limits_max_zone_append_sectors helper. This not only adds (tiny) extra overhead to the I/O path, but also can be easily forgotten in file system code. Add a new max_hw_zone_append_sectors value to queue_limits which is set by the driver, and calculate max_zone_append_sectors from that and the other inputs in blk_validate_zoned_limits, similar to how max_sectors is calculated to fix this. Signed-off-by: Christoph Hellwig <hch@lst.de> Link: https://lore.kernel.org/r/20241104073955.112324-3-hch@lst.de Reviewed-by: Damien Le Moal <dlemoal@kernel.org> Link: https://lore.kernel.org/r/20241108154657.845768-2-hch@lst.de Signed-off-by: Jens Axboe <axboe@kernel.dk>
1 parent 0ef2b9e commit 559218d

File tree

12 files changed

+28
-58
lines changed

12 files changed

+28
-58
lines changed

block/blk-core.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -607,7 +607,7 @@ static inline blk_status_t blk_check_zone_append(struct request_queue *q,
607607
return BLK_STS_IOERR;
608608

609609
/* Make sure the BIO is small enough and will not get split */
610-
if (nr_sectors > queue_max_zone_append_sectors(q))
610+
if (nr_sectors > q->limits.max_zone_append_sectors)
611611
return BLK_STS_IOERR;
612612

613613
bio->bi_opf |= REQ_NOMERGE;

block/blk-merge.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -392,11 +392,10 @@ struct bio *bio_split_rw(struct bio *bio, const struct queue_limits *lim,
392392
struct bio *bio_split_zone_append(struct bio *bio,
393393
const struct queue_limits *lim, unsigned *nr_segs)
394394
{
395-
unsigned int max_sectors = queue_limits_max_zone_append_sectors(lim);
396395
int split_sectors;
397396

398397
split_sectors = bio_split_rw_at(bio, lim, nr_segs,
399-
max_sectors << SECTOR_SHIFT);
398+
lim->max_zone_append_sectors << SECTOR_SHIFT);
400399
if (WARN_ON_ONCE(split_sectors > 0))
401400
split_sectors = -EINVAL;
402401
return bio_submit_split(bio, split_sectors);

block/blk-settings.c

Lines changed: 13 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ void blk_set_stacking_limits(struct queue_limits *lim)
5050
lim->max_sectors = UINT_MAX;
5151
lim->max_dev_sectors = UINT_MAX;
5252
lim->max_write_zeroes_sectors = UINT_MAX;
53-
lim->max_zone_append_sectors = UINT_MAX;
53+
lim->max_hw_zone_append_sectors = UINT_MAX;
5454
lim->max_user_discard_sectors = UINT_MAX;
5555
}
5656
EXPORT_SYMBOL(blk_set_stacking_limits);
@@ -91,17 +91,16 @@ static int blk_validate_zoned_limits(struct queue_limits *lim)
9191
if (lim->zone_write_granularity < lim->logical_block_size)
9292
lim->zone_write_granularity = lim->logical_block_size;
9393

94-
if (lim->max_zone_append_sectors) {
95-
/*
96-
* The Zone Append size is limited by the maximum I/O size
97-
* and the zone size given that it can't span zones.
98-
*/
99-
lim->max_zone_append_sectors =
100-
min3(lim->max_hw_sectors,
101-
lim->max_zone_append_sectors,
102-
lim->chunk_sectors);
103-
}
104-
94+
/*
95+
* The Zone Append size is limited by the maximum I/O size and the zone
96+
* size given that it can't span zones.
97+
*
98+
* If no max_hw_zone_append_sectors limit is provided, the block layer
99+
* will emulated it, else we're also bound by the hardware limit.
100+
*/
101+
lim->max_zone_append_sectors =
102+
min_not_zero(lim->max_hw_zone_append_sectors,
103+
min(lim->chunk_sectors, lim->max_hw_sectors));
105104
return 0;
106105
}
107106

@@ -527,8 +526,8 @@ int blk_stack_limits(struct queue_limits *t, struct queue_limits *b,
527526
t->max_dev_sectors = min_not_zero(t->max_dev_sectors, b->max_dev_sectors);
528527
t->max_write_zeroes_sectors = min(t->max_write_zeroes_sectors,
529528
b->max_write_zeroes_sectors);
530-
t->max_zone_append_sectors = min(queue_limits_max_zone_append_sectors(t),
531-
queue_limits_max_zone_append_sectors(b));
529+
t->max_hw_zone_append_sectors = min(t->max_hw_zone_append_sectors,
530+
b->max_hw_zone_append_sectors);
532531

533532
t->seg_boundary_mask = min_not_zero(t->seg_boundary_mask,
534533
b->seg_boundary_mask);

block/blk-sysfs.c

Lines changed: 3 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,7 @@ QUEUE_SYSFS_LIMIT_SHOW_SECTORS_TO_BYTES(max_hw_discard_sectors)
131131
QUEUE_SYSFS_LIMIT_SHOW_SECTORS_TO_BYTES(max_write_zeroes_sectors)
132132
QUEUE_SYSFS_LIMIT_SHOW_SECTORS_TO_BYTES(atomic_write_max_sectors)
133133
QUEUE_SYSFS_LIMIT_SHOW_SECTORS_TO_BYTES(atomic_write_boundary_sectors)
134+
QUEUE_SYSFS_LIMIT_SHOW_SECTORS_TO_BYTES(max_zone_append_sectors)
134135

135136
#define QUEUE_SYSFS_LIMIT_SHOW_SECTORS_TO_KB(_field) \
136137
static ssize_t queue_##_field##_show(struct gendisk *disk, char *page) \
@@ -178,18 +179,6 @@ static ssize_t queue_max_discard_sectors_store(struct gendisk *disk,
178179
return ret;
179180
}
180181

181-
/*
182-
* For zone append queue_max_zone_append_sectors does not just return the
183-
* underlying queue limits, but actually contains a calculation. Because of
184-
* that we can't simply use QUEUE_SYSFS_LIMIT_SHOW_SECTORS_TO_BYTES here.
185-
*/
186-
static ssize_t queue_zone_append_max_show(struct gendisk *disk, char *page)
187-
{
188-
return sprintf(page, "%llu\n",
189-
(u64)queue_max_zone_append_sectors(disk->queue) <<
190-
SECTOR_SHIFT);
191-
}
192-
193182
static ssize_t
194183
queue_max_sectors_store(struct gendisk *disk, const char *page, size_t count)
195184
{
@@ -479,7 +468,7 @@ QUEUE_RO_ENTRY(queue_atomic_write_unit_min, "atomic_write_unit_min_bytes");
479468

480469
QUEUE_RO_ENTRY(queue_write_same_max, "write_same_max_bytes");
481470
QUEUE_RO_ENTRY(queue_max_write_zeroes_sectors, "write_zeroes_max_bytes");
482-
QUEUE_RO_ENTRY(queue_zone_append_max, "zone_append_max_bytes");
471+
QUEUE_RO_ENTRY(queue_max_zone_append_sectors, "zone_append_max_bytes");
483472
QUEUE_RO_ENTRY(queue_zone_write_granularity, "zone_write_granularity");
484473

485474
QUEUE_RO_ENTRY(queue_zoned, "zoned");
@@ -607,7 +596,7 @@ static struct attribute *queue_attrs[] = {
607596
&queue_atomic_write_unit_max_entry.attr,
608597
&queue_write_same_max_entry.attr,
609598
&queue_max_write_zeroes_sectors_entry.attr,
610-
&queue_zone_append_max_entry.attr,
599+
&queue_max_zone_append_sectors_entry.attr,
611600
&queue_zone_write_granularity_entry.attr,
612601
&queue_rotational_entry.attr,
613602
&queue_zoned_entry.attr,

drivers/block/null_blk/zoned.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,7 @@ int null_init_zoned_dev(struct nullb_device *dev,
166166

167167
lim->features |= BLK_FEAT_ZONED;
168168
lim->chunk_sectors = dev->zone_size_sects;
169-
lim->max_zone_append_sectors = dev->zone_append_max_sectors;
169+
lim->max_hw_zone_append_sectors = dev->zone_append_max_sectors;
170170
lim->max_open_zones = dev->zone_max_open;
171171
lim->max_active_zones = dev->zone_max_active;
172172
return 0;

drivers/block/ublk_drv.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2279,7 +2279,7 @@ static int ublk_ctrl_start_dev(struct ublk_device *ub, struct io_uring_cmd *cmd)
22792279
lim.features |= BLK_FEAT_ZONED;
22802280
lim.max_active_zones = p->max_active_zones;
22812281
lim.max_open_zones = p->max_open_zones;
2282-
lim.max_zone_append_sectors = p->max_zone_append_sectors;
2282+
lim.max_hw_zone_append_sectors = p->max_zone_append_sectors;
22832283
}
22842284

22852285
if (ub->params.basic.attrs & UBLK_ATTR_VOLATILE_CACHE) {

drivers/block/virtio_blk.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -784,7 +784,7 @@ static int virtblk_read_zoned_limits(struct virtio_blk *vblk,
784784
wg, v);
785785
return -ENODEV;
786786
}
787-
lim->max_zone_append_sectors = v;
787+
lim->max_hw_zone_append_sectors = v;
788788
dev_dbg(&vdev->dev, "max append sectors = %u\n", v);
789789

790790
return 0;

drivers/md/dm-zone.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -344,7 +344,7 @@ int dm_set_zones_restrictions(struct dm_table *t, struct request_queue *q,
344344
clear_bit(DMF_EMULATE_ZONE_APPEND, &md->flags);
345345
} else {
346346
set_bit(DMF_EMULATE_ZONE_APPEND, &md->flags);
347-
lim->max_zone_append_sectors = 0;
347+
lim->max_hw_zone_append_sectors = 0;
348348
}
349349

350350
/*
@@ -379,7 +379,7 @@ int dm_set_zones_restrictions(struct dm_table *t, struct request_queue *q,
379379
if (!zlim.mapped_nr_seq_zones) {
380380
lim->max_open_zones = 0;
381381
lim->max_active_zones = 0;
382-
lim->max_zone_append_sectors = 0;
382+
lim->max_hw_zone_append_sectors = 0;
383383
lim->zone_write_granularity = 0;
384384
lim->chunk_sectors = 0;
385385
lim->features &= ~BLK_FEAT_ZONED;

drivers/nvme/host/multipath.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -636,7 +636,7 @@ int nvme_mpath_alloc_disk(struct nvme_ctrl *ctrl, struct nvme_ns_head *head)
636636
if (head->ids.csi == NVME_CSI_ZNS)
637637
lim.features |= BLK_FEAT_ZONED;
638638
else
639-
lim.max_zone_append_sectors = 0;
639+
lim.max_hw_zone_append_sectors = 0;
640640

641641
head->disk = blk_alloc_disk(&lim, ctrl->numa_node);
642642
if (IS_ERR(head->disk))

drivers/nvme/host/zns.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ void nvme_update_zone_info(struct nvme_ns *ns, struct queue_limits *lim,
111111
lim->features |= BLK_FEAT_ZONED;
112112
lim->max_open_zones = zi->max_open_zones;
113113
lim->max_active_zones = zi->max_active_zones;
114-
lim->max_zone_append_sectors = ns->ctrl->max_zone_append;
114+
lim->max_hw_zone_append_sectors = ns->ctrl->max_zone_append;
115115
lim->chunk_sectors = ns->head->zsze =
116116
nvme_lba_to_sect(ns->head, zi->zone_size);
117117
}

0 commit comments

Comments
 (0)