From 1384ad007cf930e2420d13a82967769d5789cea5 Mon Sep 17 00:00:00 2001 From: Seth Howell Date: Tue, 17 Dec 2019 17:00:37 -0700 Subject: [PATCH] module/bdev: add zcopy abilities to virtual bdevs. These bdevs claim native support for zcopy operations. They should actually support them when running on top of a bdev that claims zcopy support. For example, if you were to build a part or passthru bdev on top of a malloc_bdev (which is just for testing primarily) and then try to run bdevperf on top of that, you will currently get errors. This patch fixes that problem. Change-Id: I023557a3a5b1baf177cc29f1cbc1cd391cc67a8a Signed-off-by: Seth Howell Reviewed-on: https://review.gerrithub.io/c/spdk/spdk/+/478243 Community-CI: Broadcom SPDK FC-NVMe CI Tested-by: SPDK CI Jenkins Reviewed-by: Jim Harris Reviewed-by: Shuhei Matsumoto --- lib/bdev/part.c | 16 +++++++++++++++ module/bdev/passthru/vbdev_passthru.c | 28 +++++++++++++++++++++++++++ 2 files changed, 44 insertions(+) diff --git a/lib/bdev/part.c b/lib/bdev/part.c index d26e6b9ce..daba5bdf2 100644 --- a/lib/bdev/part.c +++ b/lib/bdev/part.c @@ -279,6 +279,17 @@ spdk_bdev_part_complete_io(struct spdk_bdev_io *bdev_io, bool success, void *cb_ spdk_bdev_free_io(bdev_io); } +static void +spdk_bdev_part_complete_zcopy_io(struct spdk_bdev_io *bdev_io, bool success, void *cb_arg) +{ + struct spdk_bdev_io *part_io = cb_arg; + int status = success ? SPDK_BDEV_IO_STATUS_SUCCESS : SPDK_BDEV_IO_STATUS_FAILED; + + spdk_bdev_io_set_buf(part_io, bdev_io->u.bdev.iovs[0].iov_base, bdev_io->u.bdev.iovs[0].iov_len); + spdk_bdev_io_complete(part_io, status); + spdk_bdev_free_io(bdev_io); +} + int spdk_bdev_part_submit_request(struct spdk_bdev_part_channel *ch, struct spdk_bdev_io *bdev_io) { @@ -347,6 +358,11 @@ spdk_bdev_part_submit_request(struct spdk_bdev_part_channel *ch, struct spdk_bde rc = spdk_bdev_reset(base_desc, base_ch, spdk_bdev_part_complete_io, bdev_io); break; + case SPDK_BDEV_IO_TYPE_ZCOPY: + rc = spdk_bdev_zcopy_start(base_desc, base_ch, remapped_offset, + bdev_io->u.bdev.num_blocks, bdev_io->u.bdev.zcopy.populate, + spdk_bdev_part_complete_zcopy_io, bdev_io); + break; default: SPDK_ERRLOG("unknown I/O type %d\n", bdev_io->type); return SPDK_BDEV_IO_STATUS_FAILED; diff --git a/module/bdev/passthru/vbdev_passthru.c b/module/bdev/passthru/vbdev_passthru.c index af3cab857..69b1c8b18 100644 --- a/module/bdev/passthru/vbdev_passthru.c +++ b/module/bdev/passthru/vbdev_passthru.c @@ -179,6 +179,29 @@ _pt_complete_io(struct spdk_bdev_io *bdev_io, bool success, void *cb_arg) spdk_bdev_free_io(bdev_io); } +static void +_pt_complete_zcopy_io(struct spdk_bdev_io *bdev_io, bool success, void *cb_arg) +{ + struct spdk_bdev_io *orig_io = cb_arg; + int status = success ? SPDK_BDEV_IO_STATUS_SUCCESS : SPDK_BDEV_IO_STATUS_FAILED; + struct passthru_bdev_io *io_ctx = (struct passthru_bdev_io *)orig_io->driver_ctx; + + /* We setup this value in the submission routine, just showing here that it is + * passed back to us. + */ + if (io_ctx->test != 0x5a) { + SPDK_ERRLOG("Error, original IO device_ctx is wrong! 0x%x\n", + io_ctx->test); + } + + /* Complete the original IO and then free the one that we created here + * as a result of issuing an IO via submit_request. + */ + spdk_bdev_io_set_buf(orig_io, bdev_io->u.bdev.iovs[0].iov_base, bdev_io->u.bdev.iovs[0].iov_len); + spdk_bdev_io_complete(orig_io, status); + spdk_bdev_free_io(bdev_io); +} + static void vbdev_passthru_resubmit_io(void *arg) { @@ -310,6 +333,11 @@ vbdev_passthru_submit_request(struct spdk_io_channel *ch, struct spdk_bdev_io *b rc = spdk_bdev_reset(pt_node->base_desc, pt_ch->base_ch, _pt_complete_io, bdev_io); break; + case SPDK_BDEV_IO_TYPE_ZCOPY: + rc = spdk_bdev_zcopy_start(pt_node->base_desc, pt_ch->base_ch, bdev_io->u.bdev.offset_blocks, + bdev_io->u.bdev.num_blocks, bdev_io->u.bdev.zcopy.populate, + _pt_complete_zcopy_io, bdev_io); + break; default: SPDK_ERRLOG("passthru: unknown I/O type %d\n", bdev_io->type); spdk_bdev_io_complete(bdev_io, SPDK_BDEV_IO_STATUS_FAILED);