On Tue, Jun 08, 2021 at 03:16:30PM +0200, Paolo Bonzini wrote: > For block host devices, I/O can happen through either the kernel file > descriptor I/O system calls (preadv/pwritev, io_submit, io_uring) > or the SCSI passthrough ioctl SG_IO. > > In the latter case, the size of each transfer can be limited by the > HBA, while for file descriptor I/O the kernel is able to split and > merge I/O in smaller pieces as needed. Applying the HBA limits to > file descriptor I/O results in more system calls and suboptimal > performance, so this patch splits the max_transfer limit in two: > max_transfer remains valid and is used in general, while max_hw_transfer > is limited to the maximum hardware size. max_hw_transfer can then be > included by the scsi-generic driver in the block limits page, to ensure > that the stricter hardware limit is used. > > Signed-off-by: Paolo Bonzini <pbonz...@redhat.com> > --- > block/block-backend.c | 12 ++++++++++++ > block/file-posix.c | 2 +- > block/io.c | 1 + > hw/scsi/scsi-generic.c | 2 +- > include/block/block_int.h | 7 +++++++ > include/sysemu/block-backend.h | 1 +
[you can use git's orderfile option to put .h changes first] > 6 files changed, 23 insertions(+), 2 deletions(-) > > diff --git a/block/block-backend.c b/block/block-backend.c > index 15f1ea4288..2ea1412a54 100644 > --- a/block/block-backend.c > +++ b/block/block-backend.c > @@ -1953,6 +1953,18 @@ uint32_t blk_get_request_alignment(BlockBackend *blk) > return bs ? bs->bl.request_alignment : BDRV_SECTOR_SIZE; > } > > +/* Returns the maximum hardware transfer length, in bytes; guaranteed > nonzero */ > +uint64_t blk_get_max_hw_transfer(BlockBackend *blk) Since we have declared (elsewhere) that the maximum block device is signed, would this be better as int64_t? (Our reasoning is that off_t is also signed, and we are unlikely to need to handle anything bigger than what off_t can handle; plus it leaves room for returning errors, although this particular function is not giving errors; see also Vladimir's work on making the block layer 64-bit clean). I'm not opposed to unsigned here to represent lack of errors, but consistency with the rest of the block layer may argue for signed. > +++ b/include/block/block_int.h > @@ -695,6 +695,13 @@ typedef struct BlockLimits { > * clamped down. */ > uint32_t max_transfer; > > + /* Maximal hardware transfer length in bytes. Applies whenever > + * transfers to the device bypass the kernel I/O scheduler, for > + * example with SG_IO. If larger than max_transfer or if zero, > + * blk_get_max_hw_transfer will fall back to max_transfer. > + */ > + uint64_t max_hw_transfer; > + Reviewed-by: Eric Blake <ebl...@redhat.com> -- Eric Blake, Principal Software Engineer Red Hat, Inc. +1-919-301-3266 Virtualization: qemu.org | libvirt.org