From 789f48dec74f7e24158ec16f5462855f436b6034 Mon Sep 17 00:00:00 2001 From: Evgeniy Kochetov Date: Mon, 22 Aug 2022 15:47:31 +0300 Subject: [PATCH] bdev/nvme: Add copy IO type support Signed-off-by: Evgeniy Kochetov Change-Id: I6a272161e129b592f535f8671e174e6b20e09fd0 Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/14347 Tested-by: SPDK CI Jenkins Reviewed-by: Ben Walker Reviewed-by: Aleksey Marchuk Reviewed-by: Shuhei Matsumoto Community-CI: Mellanox Build Bot --- module/bdev/nvme/bdev_nvme.c | 34 +++++++++++++++++++ .../lib/bdev/nvme/bdev_nvme.c/bdev_nvme_ut.c | 9 +++++ 2 files changed, 43 insertions(+) diff --git a/module/bdev/nvme/bdev_nvme.c b/module/bdev/nvme/bdev_nvme.c index 1b18a15f4..4884d726e 100644 --- a/module/bdev/nvme/bdev_nvme.c +++ b/module/bdev/nvme/bdev_nvme.c @@ -2036,6 +2036,10 @@ static int bdev_nvme_unmap(struct nvme_bdev_io *bio, uint64_t offset_blocks, static int bdev_nvme_write_zeroes(struct nvme_bdev_io *bio, uint64_t offset_blocks, uint64_t num_blocks); +static int bdev_nvme_copy(struct nvme_bdev_io *bio, uint64_t dst_offset_blocks, + uint64_t src_offset_blocks, + uint64_t num_blocks); + static void bdev_nvme_get_buf_cb(struct spdk_io_channel *ch, struct spdk_bdev_io *bdev_io, bool success) @@ -2206,6 +2210,12 @@ bdev_nvme_submit_request(struct spdk_io_channel *ch, struct spdk_bdev_io *bdev_i nbdev_io, nbdev_io_to_abort); break; + case SPDK_BDEV_IO_TYPE_COPY: + rc = bdev_nvme_copy(nbdev_io, + bdev_io->u.bdev.offset_blocks, + bdev_io->u.bdev.copy.src_offset_blocks, + bdev_io->u.bdev.num_blocks); + break; default: rc = -EINVAL; break; @@ -2270,6 +2280,10 @@ bdev_nvme_io_type_supported(void *ctx, enum spdk_bdev_io_type io_type) return spdk_nvme_ns_get_csi(ns) == SPDK_NVME_CSI_ZNS && spdk_nvme_ctrlr_get_flags(ctrlr) & SPDK_NVME_CTRLR_ZONE_APPEND_SUPPORTED; + case SPDK_BDEV_IO_TYPE_COPY: + cdata = spdk_nvme_ctrlr_get_data(ctrlr); + return cdata->oncs.copy; + default: return false; } @@ -2981,6 +2995,11 @@ nvme_disk_create(struct spdk_bdev *disk, const char *base_name, disk->acwu = cdata->acwu + 1; /* 0-based */ } + if (cdata->oncs.copy) { + /* For now bdev interface allows only single segment copy */ + disk->max_copy = nsdata->mssrl; + } + disk->ctxt = ctx; disk->fn_table = &nvmelib_fn_table; disk->module = &nvme_if; @@ -6490,6 +6509,21 @@ bdev_nvme_abort(struct nvme_bdev_channel *nbdev_ch, struct nvme_bdev_io *bio, } } +static int +bdev_nvme_copy(struct nvme_bdev_io *bio, uint64_t dst_offset_blocks, uint64_t src_offset_blocks, + uint64_t num_blocks) +{ + struct spdk_nvme_scc_source_range range = { + .slba = src_offset_blocks, + .nlb = num_blocks - 1 + }; + + return spdk_nvme_ns_cmd_copy(bio->io_path->nvme_ns->ns, + bio->io_path->qpair->qpair, + &range, 1, dst_offset_blocks, + bdev_nvme_queued_done, bio); +} + static void bdev_nvme_opts_config_json(struct spdk_json_write_ctx *w) { diff --git a/test/unit/lib/bdev/nvme/bdev_nvme.c/bdev_nvme_ut.c b/test/unit/lib/bdev/nvme/bdev_nvme.c/bdev_nvme_ut.c index ad46046eb..45e36a8eb 100644 --- a/test/unit/lib/bdev/nvme/bdev_nvme.c/bdev_nvme_ut.c +++ b/test/unit/lib/bdev/nvme/bdev_nvme.c/bdev_nvme_ut.c @@ -1046,6 +1046,15 @@ spdk_nvme_ns_cmd_write_zeroes(struct spdk_nvme_ns *ns, struct spdk_nvme_qpair *q return ut_submit_nvme_request(ns, qpair, SPDK_NVME_OPC_WRITE_ZEROES, cb_fn, cb_arg); } +int +spdk_nvme_ns_cmd_copy(struct spdk_nvme_ns *ns, struct spdk_nvme_qpair *qpair, + const struct spdk_nvme_scc_source_range *ranges, + uint16_t num_ranges, uint64_t dest_lba, + spdk_nvme_cmd_cb cb_fn, void *cb_arg) +{ + return ut_submit_nvme_request(ns, qpair, SPDK_NVME_OPC_COPY, cb_fn, cb_arg); +} + struct spdk_nvme_poll_group * spdk_nvme_poll_group_create(void *ctx, struct spdk_nvme_accel_fn_table *table) {