Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

scsi: sd_zbc: block: Respect bio vector limits for REPORT ZONES buffer

The REPORT ZONES buffer size is currently limited by the HBA's maximum
segment count to ensure the buffer can be mapped. However, the block
layer further limits the number of iovec entries to 1024 when allocating
a bio.

To avoid allocation of buffers too large to be mapped, further restrict
the maximum buffer size to BIO_MAX_INLINE_VECS.

Replace the UIO_MAXIOV symbolic name with the more contextually
appropriate BIO_MAX_INLINE_VECS.

Fixes: b091ac616846 ("sd_zbc: Fix report zones buffer allocation")
Cc: stable@vger.kernel.org
Signed-off-by: Steve Siwinski <ssiwinski@atto.com>
Link: https://lore.kernel.org/r/20250508200122.243129-1-ssiwinski@atto.com
Reviewed-by: Damien Le Moal <dlemoal@kernel.org>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>

authored by

Steve Siwinski and committed by
Martin K. Petersen
e8007fad 0e9693b9

+7 -2
+1 -1
block/bio.c
··· 611 611 { 612 612 struct bio *bio; 613 613 614 - if (nr_vecs > UIO_MAXIOV) 614 + if (nr_vecs > BIO_MAX_INLINE_VECS) 615 615 return NULL; 616 616 return kmalloc(struct_size(bio, bi_inline_vecs, nr_vecs), gfp_mask); 617 617 }
+5 -1
drivers/scsi/sd_zbc.c
··· 169 169 unsigned int nr_zones, size_t *buflen) 170 170 { 171 171 struct request_queue *q = sdkp->disk->queue; 172 + unsigned int max_segments; 172 173 size_t bufsize; 173 174 void *buf; 174 175 ··· 181 180 * Furthermore, since the report zone command cannot be split, make 182 181 * sure that the allocated buffer can always be mapped by limiting the 183 182 * number of pages allocated to the HBA max segments limit. 183 + * Since max segments can be larger than the max inline bio vectors, 184 + * further limit the allocated buffer to BIO_MAX_INLINE_VECS. 184 185 */ 185 186 nr_zones = min(nr_zones, sdkp->zone_info.nr_zones); 186 187 bufsize = roundup((nr_zones + 1) * 64, SECTOR_SIZE); 187 188 bufsize = min_t(size_t, bufsize, 188 189 queue_max_hw_sectors(q) << SECTOR_SHIFT); 189 - bufsize = min_t(size_t, bufsize, queue_max_segments(q) << PAGE_SHIFT); 190 + max_segments = min(BIO_MAX_INLINE_VECS, queue_max_segments(q)); 191 + bufsize = min_t(size_t, bufsize, max_segments << PAGE_SHIFT); 190 192 191 193 while (bufsize >= SECTOR_SIZE) { 192 194 buf = kvzalloc(bufsize, GFP_KERNEL | __GFP_NORETRY);
+1
include/linux/bio.h
··· 11 11 #include <linux/uio.h> 12 12 13 13 #define BIO_MAX_VECS 256U 14 + #define BIO_MAX_INLINE_VECS UIO_MAXIOV 14 15 15 16 struct queue_limits; 16 17