]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
scsi: sd_zbc: block: Respect bio vector limits for REPORT ZONES buffer
authorSteve Siwinski <ssiwinski@atto.com>
Thu, 8 May 2025 20:01:22 +0000 (16:01 -0400)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 22 May 2025 12:10:06 +0000 (14:10 +0200)
commit e8007fad5457ea547ca63bb011fdb03213571c7e upstream.

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>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
block/bio.c
drivers/scsi/sd_zbc.c
include/linux/bio.h

index a7323d567c7989609940c31b6c48770b29c99b5f..7e2ce61bf2479d124f1f74cb35002a27986cc975 100644 (file)
@@ -576,7 +576,7 @@ struct bio *bio_kmalloc(unsigned short nr_vecs, gfp_t gfp_mask)
 {
        struct bio *bio;
 
-       if (nr_vecs > UIO_MAXIOV)
+       if (nr_vecs > BIO_MAX_INLINE_VECS)
                return NULL;
        return kmalloc(struct_size(bio, bi_inline_vecs, nr_vecs), gfp_mask);
 }
index 4c78288ffa72feae234f50593d0cbd9cdda36873..5fc6bf95258c64060af5bb5dc375764d605231e3 100644 (file)
@@ -197,6 +197,7 @@ static void *sd_zbc_alloc_report_buffer(struct scsi_disk *sdkp,
                                        unsigned int nr_zones, size_t *buflen)
 {
        struct request_queue *q = sdkp->disk->queue;
+       unsigned int max_segments;
        size_t bufsize;
        void *buf;
 
@@ -208,12 +209,15 @@ static void *sd_zbc_alloc_report_buffer(struct scsi_disk *sdkp,
         * Furthermore, since the report zone command cannot be split, make
         * sure that the allocated buffer can always be mapped by limiting the
         * number of pages allocated to the HBA max segments limit.
+        * Since max segments can be larger than the max inline bio vectors,
+        * further limit the allocated buffer to BIO_MAX_INLINE_VECS.
         */
        nr_zones = min(nr_zones, sdkp->zone_info.nr_zones);
        bufsize = roundup((nr_zones + 1) * 64, SECTOR_SIZE);
        bufsize = min_t(size_t, bufsize,
                        queue_max_hw_sectors(q) << SECTOR_SHIFT);
-       bufsize = min_t(size_t, bufsize, queue_max_segments(q) << PAGE_SHIFT);
+       max_segments = min(BIO_MAX_INLINE_VECS, queue_max_segments(q));
+       bufsize = min_t(size_t, bufsize, max_segments << PAGE_SHIFT);
 
        while (bufsize >= SECTOR_SIZE) {
                buf = kvzalloc(bufsize, GFP_KERNEL | __GFP_NORETRY);
index 2b9fc5edf49d6b0c65597638e6c9a0567738ab56..00ab98ce1d438f8339d88b41c98695995955e675 100644 (file)
@@ -11,6 +11,7 @@
 #include <linux/uio.h>
 
 #define BIO_MAX_VECS           256U
+#define BIO_MAX_INLINE_VECS    UIO_MAXIOV
 
 static inline unsigned int bio_max_segs(unsigned int nr_segs)
 {