SCSI fixes on 20250516

Fix to zone block devices to make the maximum segment count match what
 the block layer is capable of.
 
 Signed-off-by: James E.J. Bottomley <James.Bottomley@HansenPartnership.com>
 -----BEGIN PGP SIGNATURE-----
 
 iJwEABMIAEQWIQTnYEDbdso9F2cI+arnQslM7pishQUCaCdNASYcamFtZXMuYm90
 dG9tbGV5QGhhbnNlbnBhcnRuZXJzaGlwLmNvbQAKCRDnQslM7pishdM9AQCAEmBq
 jLr8DawbZikyyoesDwaUelT2NHZv0N2pf4ju0gEAraO3pYMYWaDnUQ73cIKhl8Bo
 ZG3BCf6MZD1fRq8SxBU=
 =C6ti
 -----END PGP SIGNATURE-----

Merge tag 'scsi-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi

Pull SCSI fix from James Bottomley:
 "Fix to zone block devices to make the maximum segment count match what
  the block layer is capable of"

* tag 'scsi-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi:
  scsi: sd_zbc: block: Respect bio vector limits for REPORT ZONES buffer
This commit is contained in:
Linus Torvalds 2025-05-16 10:28:22 -07:00
commit 83a896549f
3 changed files with 7 additions and 2 deletions

View file

@ -611,7 +611,7 @@ struct bio *bio_kmalloc(unsigned short nr_vecs, gfp_t gfp_mask)
{ {
struct bio *bio; struct bio *bio;
if (nr_vecs > UIO_MAXIOV) if (nr_vecs > BIO_MAX_INLINE_VECS)
return NULL; return NULL;
return kmalloc(struct_size(bio, bi_inline_vecs, nr_vecs), gfp_mask); return kmalloc(struct_size(bio, bi_inline_vecs, nr_vecs), gfp_mask);
} }

View file

@ -169,6 +169,7 @@ static void *sd_zbc_alloc_report_buffer(struct scsi_disk *sdkp,
unsigned int nr_zones, size_t *buflen) unsigned int nr_zones, size_t *buflen)
{ {
struct request_queue *q = sdkp->disk->queue; struct request_queue *q = sdkp->disk->queue;
unsigned int max_segments;
size_t bufsize; size_t bufsize;
void *buf; void *buf;
@ -180,12 +181,15 @@ static void *sd_zbc_alloc_report_buffer(struct scsi_disk *sdkp,
* Furthermore, since the report zone command cannot be split, make * Furthermore, since the report zone command cannot be split, make
* sure that the allocated buffer can always be mapped by limiting the * sure that the allocated buffer can always be mapped by limiting the
* number of pages allocated to the HBA max segments limit. * 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); nr_zones = min(nr_zones, sdkp->zone_info.nr_zones);
bufsize = roundup((nr_zones + 1) * 64, SECTOR_SIZE); bufsize = roundup((nr_zones + 1) * 64, SECTOR_SIZE);
bufsize = min_t(size_t, bufsize, bufsize = min_t(size_t, bufsize,
queue_max_hw_sectors(q) << SECTOR_SHIFT); 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) { while (bufsize >= SECTOR_SIZE) {
buf = kvzalloc(bufsize, GFP_KERNEL | __GFP_NORETRY); buf = kvzalloc(bufsize, GFP_KERNEL | __GFP_NORETRY);

View file

@ -11,6 +11,7 @@
#include <linux/uio.h> #include <linux/uio.h>
#define BIO_MAX_VECS 256U #define BIO_MAX_VECS 256U
#define BIO_MAX_INLINE_VECS UIO_MAXIOV
struct queue_limits; struct queue_limits;