[PATCH v2 3/4] block: factor out path limit stacking
Yao Sang <[email protected]> Thu, 6 Aug 2026 10:46:57 +0800
| Newsgroups | org.infradead.lists.linux-nvme,org.kernel.vger.linux-block |
|---|---|
| Message-ID | <[email protected]> |
Some queue limits are path limits: every queue that can execute an I/O must support them, and they do not depend on start, the first data sector used in a bottom device. This includes BLK_FEAT_NOWAIT, BLK_FEAT_POLL, BLK_FEAT_PCI_P2PDMA, max_hw_sectors, max_dev_sectors, seg_boundary_mask, virt_boundary_mask, max_segments, max_integrity_segments, max_segment_size and dma_alignment. Move these path limits into a static blk_stack_path_limits() helper and call it from blk_stack_limits(). Keep topology, discard alignment, atomic writes and other operation and resource limits in blk_stack_limits() where the caller context is still available. There is no behavior change. Signed-off-by: Yao Sang <[email protected]> --- block/blk-settings.c | 59 +++++++++++++++++++++++--------------------- 1 file changed, 31 insertions(+), 28 deletions(-) diff --git a/block/blk-settings.c b/block/blk-settings.c index 1aff818aaaac..40cd3490f168 100644 --- a/block/blk-settings.c +++ b/block/blk-settings.c @@ -756,6 +756,36 @@ static void blk_stack_atomic_writes_limits(struct queue_limits *t, t->atomic_write_hw_boundary = 0; } +static void blk_stack_path_limits(struct queue_limits *t, + const struct queue_limits *b) +{ + /* + * Some features need to be supported both by the stacking driver and all + * underlying devices. The stacking driver sets these flags before + * stacking the limits, and this will clear the flags if any of the + * underlying devices does not support it. + */ + if (!(b->features & BLK_FEAT_NOWAIT)) + t->features &= ~BLK_FEAT_NOWAIT; + if (!(b->features & BLK_FEAT_POLL)) + t->features &= ~BLK_FEAT_POLL; + if (!(b->features & BLK_FEAT_PCI_P2PDMA)) + t->features &= ~BLK_FEAT_PCI_P2PDMA; + + t->max_hw_sectors = min_not_zero(t->max_hw_sectors, b->max_hw_sectors); + t->max_dev_sectors = min_not_zero(t->max_dev_sectors, b->max_dev_sectors); + t->seg_boundary_mask = min_not_zero(t->seg_boundary_mask, + b->seg_boundary_mask); + t->virt_boundary_mask = min_not_zero(t->virt_boundary_mask, + b->virt_boundary_mask); + t->max_segments = min_not_zero(t->max_segments, b->max_segments); + t->max_integrity_segments = min_not_zero(t->max_integrity_segments, + b->max_integrity_segments); + t->max_segment_size = min_not_zero(t->max_segment_size, + b->max_segment_size); + t->dma_alignment = max(t->dma_alignment, b->dma_alignment); +} + /* * Stack and check logical_block_size, physical_block_size, io_min, io_opt, * chunk_sectors and alignment_offset for a bottom-device range, then round @@ -874,25 +904,11 @@ int blk_stack_limits(struct queue_limits *t, struct queue_limits *b, int ret; t->features |= (b->features & BLK_FEAT_INHERIT_MASK); - - /* - * Some feaures need to be supported both by the stacking driver and all - * underlying devices. The stacking driver sets these flags before - * stacking the limits, and this will clear the flags if any of the - * underlying devices does not support it. - */ - if (!(b->features & BLK_FEAT_NOWAIT)) - t->features &= ~BLK_FEAT_NOWAIT; - if (!(b->features & BLK_FEAT_POLL)) - t->features &= ~BLK_FEAT_POLL; - if (!(b->features & BLK_FEAT_PCI_P2PDMA)) - t->features &= ~BLK_FEAT_PCI_P2PDMA; + blk_stack_path_limits(t, b); t->max_sectors = min_not_zero(t->max_sectors, b->max_sectors); t->max_user_sectors = min_not_zero(t->max_user_sectors, b->max_user_sectors); - t->max_hw_sectors = min_not_zero(t->max_hw_sectors, b->max_hw_sectors); - t->max_dev_sectors = min_not_zero(t->max_dev_sectors, b->max_dev_sectors); t->max_write_zeroes_sectors = min(t->max_write_zeroes_sectors, b->max_write_zeroes_sectors); t->max_user_wzeroes_unmap_sectors = @@ -904,21 +920,8 @@ int blk_stack_limits(struct queue_limits *t, struct queue_limits *b, t->max_hw_zone_append_sectors = min(t->max_hw_zone_append_sectors, b->max_hw_zone_append_sectors); - - t->seg_boundary_mask = min_not_zero(t->seg_boundary_mask, - b->seg_boundary_mask); - t->virt_boundary_mask = min_not_zero(t->virt_boundary_mask, - b->virt_boundary_mask); - - t->max_segments = min_not_zero(t->max_segments, b->max_segments); t->max_discard_segments = min_not_zero(t->max_discard_segments, b->max_discard_segments); - t->max_integrity_segments = min_not_zero(t->max_integrity_segments, - b->max_integrity_segments); - - t->max_segment_size = min_not_zero(t->max_segment_size, - b->max_segment_size); - t->dma_alignment = max(t->dma_alignment, b->dma_alignment); ret = blk_stack_topology_limits(t, b, start); -- 2.25.1