Message ID | 20250411203600.84477-1-ssiwinski@atto.com |
---|---|
State | New |
Headers | show |
Series | scsi: sd_zbc: Limit the report zones buffer size to UIO_MAXIOV | expand |
On Fri, Apr 11, 2025 at 04:36:00PM -0400, Steve Siwinski wrote: > The report zones buffer size is currently limited by the HBA's > maximum segment count to ensure the buffer can be mapped. However, > the user-space SG_IO interface further limits the number of iovec > entries to UIO_MAXIOV when allocating a bio. Why does the userspace SG_IO interface matter here? sd_zbc_alloc_report_buffer is only used for the in-kernel ->report_zones call. > > To avoid allocation of buffers too large to be mapped, further > restrict the maximum buffer size to UIO_MAXIOV * PAGE_SIZE. > > This ensures that the buffer size complies with both kernel > and user-space constraints. > > Signed-off-by: Steve Siwinski <ssiwinski@atto.com> > --- > drivers/scsi/sd_zbc.c | 3 +++ > 1 file changed, 3 insertions(+) > > diff --git a/drivers/scsi/sd_zbc.c b/drivers/scsi/sd_zbc.c > index 7a447ff600d2..a19e76ec8fb6 100644 > --- a/drivers/scsi/sd_zbc.c > +++ b/drivers/scsi/sd_zbc.c > @@ -180,12 +180,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 sgio entries, further > + * limit the allocated buffer to the UIO_MAXIOV. > */ > 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); > + bufsize = min_t(size_t, bufsize, UIO_MAXIOV * PAGE_SIZE); > > while (bufsize >= SECTOR_SIZE) { > buf = kvzalloc(bufsize, GFP_KERNEL | __GFP_NORETRY); > -- > 2.43.5 > > ---end quoted text---
On 4/19/25 05:46, SSiwinski@atto.com wrote: > > "Christoph Hellwig" <hch@infradead.org> wrote on 04/14/2025 01:52:31 AM: > >> On Fri, Apr 11, 2025 at 04:36:00PM -0400, Steve Siwinski wrote: >>> The report zones buffer size is currently limited by the HBA's >>> maximum segment count to ensure the buffer can be mapped. However, >>> the user-space SG_IO interface further limits the number of iovec >>> entries to UIO_MAXIOV when allocating a bio. >> >> Why does the userspace SG_IO interface matter here? >> sd_zbc_alloc_report_buffer is only used for the in-kernel >> ->report_zones call. > > I was referring to the userspace SG_IO limitation (UIO_MAXIOV) in > bio_kmalloc(), which gets called when the report zones command is > executed and the buffer mapped in bio_map_kern(). > > Perhaps my wording here was poor and this is really a limitation of bio? sd_zbc_alloc_report_buffer() is called only from sd_zbc_report_zones() which is the disk ->report_zones() operations, which is NOT called for passthrough commands. So modifying sd_zbc_alloc_report_buffer() will not help in any way solving your issue with an SG_IO passthrough report zones command issued by the user. For reference, libzbc uses ioctl(SG_GET_SG_TABLESIZE) * sysconf(_SC_PAGESIZE) as the max buffer size and allocates page aligned buffers to avoid these SG_IO buffer mapping limitations.
diff --git a/drivers/scsi/sd_zbc.c b/drivers/scsi/sd_zbc.c index 7a447ff600d2..a19e76ec8fb6 100644 --- a/drivers/scsi/sd_zbc.c +++ b/drivers/scsi/sd_zbc.c @@ -180,12 +180,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 sgio entries, further + * limit the allocated buffer to the UIO_MAXIOV. */ 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); + bufsize = min_t(size_t, bufsize, UIO_MAXIOV * PAGE_SIZE); while (bufsize >= SECTOR_SIZE) { buf = kvzalloc(bufsize, GFP_KERNEL | __GFP_NORETRY);
The report zones buffer size is currently limited by the HBA's maximum segment count to ensure the buffer can be mapped. However, the user-space SG_IO interface further limits the number of iovec entries to UIO_MAXIOV when allocating a bio. To avoid allocation of buffers too large to be mapped, further restrict the maximum buffer size to UIO_MAXIOV * PAGE_SIZE. This ensures that the buffer size complies with both kernel and user-space constraints. Signed-off-by: Steve Siwinski <ssiwinski@atto.com> --- drivers/scsi/sd_zbc.c | 3 +++ 1 file changed, 3 insertions(+)