bdev: split requests first if the request has data buffer
There is one existing example usage case to describe the issue: Users(e.g. Vhost-blk target with Windows Guest) call spdk_bdev_readv_blocks() to submit a 128KiB length data READ request, and the data buffer provides by vhost isn't aligned, but the backend block device requires aligned data buffer, so existing function call trace: spdk_bdev_readv_blocks()--> spdk_bdev_io_submit()--> spdk_bdev_io_get_buf() spdk_bdev_io_get_buf() will allocate buffer from large data buffer pool for 128KiB length, of course, it will return error with existing logic. So here, no matter what the data length is, we can go through the split process first for both READ and WRITE. However, there is one scenario that for iSCSI READ request, the iSCSI layer will not allocate data buffer for the request, so for this case if the IO boundary is required we should keep the logic as before. Change-Id: I67661f5fa4c3c7c561b45c86146759aa3477adbf Signed-off-by: Changpeng Liu <changpeng.liu@intel.com> Reviewed-on: https://review.gerrithub.io/c/spdk/spdk/+/453133 Tested-by: SPDK CI Jenkins <sys_sgci@intel.com> Reviewed-by: Shuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com> Reviewed-by: Darek Stojaczyk <dariusz.stojaczyk@intel.com>
This commit is contained in:
parent
77290bfe6b
commit
5d718951a6
@ -1739,6 +1739,10 @@ _spdk_bdev_io_split_done(struct spdk_bdev_io *bdev_io, bool success, void *cb_ar
|
||||
_spdk_bdev_io_split(parent_io);
|
||||
}
|
||||
|
||||
static void
|
||||
_spdk_bdev_io_split_get_buf_cb(struct spdk_io_channel *ch, struct spdk_bdev_io *bdev_io,
|
||||
bool success);
|
||||
|
||||
static void
|
||||
spdk_bdev_io_split(struct spdk_io_channel *ch, struct spdk_bdev_io *bdev_io)
|
||||
{
|
||||
@ -1749,7 +1753,13 @@ spdk_bdev_io_split(struct spdk_io_channel *ch, struct spdk_bdev_io *bdev_io)
|
||||
bdev_io->u.bdev.split_outstanding = 0;
|
||||
bdev_io->internal.status = SPDK_BDEV_IO_STATUS_SUCCESS;
|
||||
|
||||
_spdk_bdev_io_split(bdev_io);
|
||||
if (_is_buf_allocated(bdev_io->u.bdev.iovs)) {
|
||||
_spdk_bdev_io_split(bdev_io);
|
||||
} else {
|
||||
assert(bdev_io->type == SPDK_BDEV_IO_TYPE_READ);
|
||||
spdk_bdev_io_get_buf(bdev_io, _spdk_bdev_io_split_get_buf_cb,
|
||||
bdev_io->u.bdev.num_blocks * bdev_io->bdev->blocklen);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
@ -1812,12 +1822,7 @@ spdk_bdev_io_submit(struct spdk_bdev_io *bdev_io)
|
||||
assert(bdev_io->internal.status == SPDK_BDEV_IO_STATUS_PENDING);
|
||||
|
||||
if (bdev->split_on_optimal_io_boundary && _spdk_bdev_io_should_split(bdev_io)) {
|
||||
if (bdev_io->type == SPDK_BDEV_IO_TYPE_READ) {
|
||||
spdk_bdev_io_get_buf(bdev_io, _spdk_bdev_io_split_get_buf_cb,
|
||||
bdev_io->u.bdev.num_blocks * bdev_io->bdev->blocklen);
|
||||
} else {
|
||||
spdk_bdev_io_split(NULL, bdev_io);
|
||||
}
|
||||
spdk_bdev_io_split(NULL, bdev_io);
|
||||
return;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user