Skip to content

Commit ab9bc81

Browse files
committed
Revert "block: pre-calculate max_zone_append_sectors"
This causes issue on, at least, nvme-mpath where my boot fails with: WARNING: CPU: 354 PID: 2729 at block/blk-settings.c:75 blk_validate_limits+0x356/0x380 Modules linked in: tg3(+) nvme usbcore scsi_mod ptp i2c_piix4 libphy nvme_core crc32c_intel scsi_common usb_common pps_core i2c_smbus CPU: 354 UID: 0 PID: 2729 Comm: kworker/u2061:1 Not tainted 6.12.0-rc6+ torvalds#181 Hardware name: Dell Inc. PowerEdge R7625/06444F, BIOS 1.8.3 04/02/2024 Workqueue: async async_run_entry_fn RIP: 0010:blk_validate_limits+0x356/0x380 Code: f6 47 01 04 75 28 83 bf 94 00 00 00 00 75 39 83 bf 98 00 00 00 00 75 34 83 7f 68 00 75 32 31 c0 83 7f 5c 00 0f 84 9b fd ff ff <0f> 0b eb 13 0f 0b eb 0f 48 c7 c0 74 12 58 92 48 89 c7 e8 13 76 46 RSP: 0018:ffffa8a1dfb93b30 EFLAGS: 00010286 RAX: 0000000000000000 RBX: ffff9232829c8388 RCX: 0000000000000088 RDX: 0000000000000080 RSI: 0000000000000200 RDI: ffffa8a1dfb93c38 RBP: 000000000000000c R08: 00000000ffffffff R09: 000000000000ffff R10: 0000000000000000 R11: 0000000000000000 R12: ffff9232829b9000 R13: ffff9232829b9010 R14: ffffa8a1dfb93c38 R15: ffffa8a1dfb93c38 FS: 0000000000000000(0000) GS:ffff923867c80000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 000055c1b92480a8 CR3: 0000002484ff0002 CR4: 0000000000370ef0 Call Trace: <TASK> ? __warn+0xca/0x1a0 ? blk_validate_limits+0x356/0x380 ? report_bug+0x11a/0x1a0 ? handle_bug+0x5e/0x90 ? exc_invalid_op+0x16/0x40 ? asm_exc_invalid_op+0x16/0x20 ? blk_validate_limits+0x356/0x380 blk_alloc_queue+0x7a/0x250 __blk_alloc_disk+0x39/0x80 nvme_mpath_alloc_disk+0x13d/0x1b0 [nvme_core] nvme_scan_ns+0xcc7/0x1010 [nvme_core] async_run_entry_fn+0x27/0x120 process_scheduled_works+0x1a0/0x360 worker_thread+0x2bc/0x350 ? pr_cont_work+0x1b0/0x1b0 kthread+0x111/0x120 ? kthread_unuse_mm+0x90/0x90 ret_from_fork+0x30/0x40 ? kthread_unuse_mm+0x90/0x90 ret_from_fork_asm+0x11/0x20 </TASK> ---[ end trace 0000000000000000 ]--- presumably due to max_zone_append_sectors not being cleared to zero, resulting in blk_validate_zoned_limits() complaining and failing. This reverts commit 2a8f615. Signed-off-by: Jens Axboe <[email protected]>
1 parent 0b66deb commit ab9bc81

File tree

12 files changed

+57
-27
lines changed

12 files changed

+57
-27
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 > q->limits.max_zone_append_sectors)
610+
if (nr_sectors > queue_max_zone_append_sectors(q))
611611
return BLK_STS_IOERR;
612612

613613
bio->bi_opf |= REQ_NOMERGE;

block/blk-merge.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -388,10 +388,11 @@ struct bio *bio_split_rw(struct bio *bio, const struct queue_limits *lim,
388388
struct bio *bio_split_zone_append(struct bio *bio,
389389
const struct queue_limits *lim, unsigned *nr_segs)
390390
{
391+
unsigned int max_sectors = queue_limits_max_zone_append_sectors(lim);
391392
int split_sectors;
392393

393394
split_sectors = bio_split_rw_at(bio, lim, nr_segs,
394-
lim->max_zone_append_sectors << SECTOR_SHIFT);
395+
max_sectors << SECTOR_SHIFT);
395396
if (WARN_ON_ONCE(split_sectors > 0))
396397
split_sectors = -EINVAL;
397398
return bio_submit_split(bio, split_sectors);

block/blk-settings.c

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -91,16 +91,17 @@ 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-
/*
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));
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+
104105
return 0;
105106
}
106107

@@ -526,8 +527,8 @@ int blk_stack_limits(struct queue_limits *t, struct queue_limits *b,
526527
t->max_dev_sectors = min_not_zero(t->max_dev_sectors, b->max_dev_sectors);
527528
t->max_write_zeroes_sectors = min(t->max_write_zeroes_sectors,
528529
b->max_write_zeroes_sectors);
529-
t->max_hw_zone_append_sectors = min(t->max_hw_zone_append_sectors,
530-
b->max_hw_zone_append_sectors);
530+
t->max_zone_append_sectors = min(queue_limits_max_zone_append_sectors(t),
531+
queue_limits_max_zone_append_sectors(b));
531532

532533
t->seg_boundary_mask = min_not_zero(t->seg_boundary_mask,
533534
b->seg_boundary_mask);

block/blk-sysfs.c

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,6 @@ 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)
135134

136135
#define QUEUE_SYSFS_LIMIT_SHOW_SECTORS_TO_KB(_field) \
137136
static ssize_t queue_##_field##_show(struct gendisk *disk, char *page) \
@@ -179,6 +178,18 @@ static ssize_t queue_max_discard_sectors_store(struct gendisk *disk,
179178
return ret;
180179
}
181180

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+
182193
static ssize_t
183194
queue_max_sectors_store(struct gendisk *disk, const char *page, size_t count)
184195
{
@@ -468,7 +479,7 @@ QUEUE_RO_ENTRY(queue_atomic_write_unit_min, "atomic_write_unit_min_bytes");
468479

469480
QUEUE_RO_ENTRY(queue_write_same_max, "write_same_max_bytes");
470481
QUEUE_RO_ENTRY(queue_max_write_zeroes_sectors, "write_zeroes_max_bytes");
471-
QUEUE_RO_ENTRY(queue_max_zone_append_sectors, "zone_append_max_bytes");
482+
QUEUE_RO_ENTRY(queue_zone_append_max, "zone_append_max_bytes");
472483
QUEUE_RO_ENTRY(queue_zone_write_granularity, "zone_write_granularity");
473484

474485
QUEUE_RO_ENTRY(queue_zoned, "zoned");
@@ -596,7 +607,7 @@ static struct attribute *queue_attrs[] = {
596607
&queue_atomic_write_unit_max_entry.attr,
597608
&queue_write_same_max_entry.attr,
598609
&queue_max_write_zeroes_sectors_entry.attr,
599-
&queue_max_zone_append_sectors_entry.attr,
610+
&queue_zone_append_max_entry.attr,
600611
&queue_zone_write_granularity_entry.attr,
601612
&queue_rotational_entry.attr,
602613
&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_hw_zone_append_sectors = dev->zone_append_max_sectors;
169+
lim->max_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
@@ -2270,7 +2270,7 @@ static int ublk_ctrl_start_dev(struct ublk_device *ub, struct io_uring_cmd *cmd)
22702270
lim.features |= BLK_FEAT_ZONED;
22712271
lim.max_active_zones = p->max_active_zones;
22722272
lim.max_open_zones = p->max_open_zones;
2273-
lim.max_hw_zone_append_sectors = p->max_zone_append_sectors;
2273+
lim.max_zone_append_sectors = p->max_zone_append_sectors;
22742274
}
22752275

22762276
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_hw_zone_append_sectors = v;
787+
lim->max_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_hw_zone_append_sectors = 0;
347+
lim->max_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_hw_zone_append_sectors = 0;
382+
lim->max_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_hw_zone_append_sectors = 0;
639+
lim.max_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_hw_zone_append_sectors = ns->ctrl->max_zone_append;
114+
lim->max_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
}

drivers/scsi/sd_zbc.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -634,6 +634,8 @@ int sd_zbc_read_zones(struct scsi_disk *sdkp, struct queue_limits *lim,
634634
lim->max_open_zones = sdkp->zones_max_open;
635635
lim->max_active_zones = 0;
636636
lim->chunk_sectors = logical_to_sectors(sdkp->device, zone_blocks);
637+
/* Enable block layer zone append emulation */
638+
lim->max_zone_append_sectors = 0;
637639

638640
return 0;
639641

include/linux/blkdev.h

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -375,7 +375,6 @@ struct queue_limits {
375375
unsigned int max_user_discard_sectors;
376376
unsigned int max_secure_erase_sectors;
377377
unsigned int max_write_zeroes_sectors;
378-
unsigned int max_hw_zone_append_sectors;
379378
unsigned int max_zone_append_sectors;
380379
unsigned int discard_granularity;
381380
unsigned int discard_alignment;
@@ -1205,9 +1204,25 @@ static inline unsigned int queue_max_segment_size(const struct request_queue *q)
12051204
return q->limits.max_segment_size;
12061205
}
12071206

1207+
static inline unsigned int
1208+
queue_limits_max_zone_append_sectors(const struct queue_limits *l)
1209+
{
1210+
unsigned int max_sectors = min(l->chunk_sectors, l->max_hw_sectors);
1211+
1212+
return min_not_zero(l->max_zone_append_sectors, max_sectors);
1213+
}
1214+
1215+
static inline unsigned int queue_max_zone_append_sectors(struct request_queue *q)
1216+
{
1217+
if (!blk_queue_is_zoned(q))
1218+
return 0;
1219+
1220+
return queue_limits_max_zone_append_sectors(&q->limits);
1221+
}
1222+
12081223
static inline bool queue_emulates_zone_append(struct request_queue *q)
12091224
{
1210-
return blk_queue_is_zoned(q) && !q->limits.max_hw_zone_append_sectors;
1225+
return blk_queue_is_zoned(q) && !q->limits.max_zone_append_sectors;
12111226
}
12121227

12131228
static inline bool bdev_emulates_zone_append(struct block_device *bdev)
@@ -1218,7 +1233,7 @@ static inline bool bdev_emulates_zone_append(struct block_device *bdev)
12181233
static inline unsigned int
12191234
bdev_max_zone_append_sectors(struct block_device *bdev)
12201235
{
1221-
return bdev_limits(bdev)->max_zone_append_sectors;
1236+
return queue_max_zone_append_sectors(bdev_get_queue(bdev));
12221237
}
12231238

12241239
static inline unsigned int bdev_max_segments(struct block_device *bdev)

0 commit comments

Comments
 (0)