From 3a58a5f19c780c7ae82d93e057cc73120ac4fd81 Mon Sep 17 00:00:00 2001 From: Changpeng Liu Date: Tue, 13 Apr 2021 20:30:13 +0800 Subject: [PATCH] nvme: add spdk_nvme_map_cmd API The API `spdk_nvme_map_prps` is used in nvmf/vfio-user to remap VM's NVMe command data buffer to local virtual address, and for command using PRP, there maybe multiple pages, when parsing the PRP list to local IOVs, we need a parameter to check that the maximum number of vectors can't exceed the IOVs, this API can't meet the requirement, while here, we add a new API `spdk_nvme_map_cmd` and with a new parameter `max_iovcnt` to fix this case, and it can also cover the command using SGL in the coming patches. Change-Id: I71063524bed16ee3434103867a556d3741e55326 Signed-off-by: Changpeng Liu Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/7278 Reviewed-by: Ben Walker Reviewed-by: Jim Harris Community-CI: Broadcom CI Tested-by: SPDK CI Jenkins --- CHANGELOG.md | 2 ++ include/spdk/nvme.h | 15 +++++++++++++++ lib/nvme/nvme_ctrlr.c | 12 ++++++++++++ lib/nvme/spdk_nvme.map | 1 + lib/nvmf/vfio_user.c | 4 ++-- 5 files changed, 32 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2f161e9b6..9833dd126 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,8 @@ Added an accelerated table pointer in spdk_nvme_poll_group which can be used provide the accelerated functions by users with hardware engine, such as crc32c accelerated function. +Added `spdk_nvme_map_cmd` API to map the NVMe command with SGL cases. + ### raid For `bdev_raid_create` RPC, the deprecated parameter `strip_size` was removed. diff --git a/include/spdk/nvme.h b/include/spdk/nvme.h index 75f9021d2..a382f597d 100644 --- a/include/spdk/nvme.h +++ b/include/spdk/nvme.h @@ -3472,6 +3472,21 @@ int spdk_nvme_map_prps(void *prv, struct spdk_nvme_cmd *cmd, struct iovec *iovs, uint32_t len, size_t mps, void *(*gpa_to_vva)(void *prv, uint64_t addr, uint64_t len)); +/** + * Map NVMe command data buffers sent from Virtual Machine to virtual addresses + * + *\param prv Opaque handle to gpa_to_vva callback + *\param cmd NVMe command + *\param iovs IO vectors used to point the data buffers in NVMe command + *\param max_iovcnt Maximum IO vectors that can be used + *\param len Total buffer length for the NVMe command + *\param mps Memory page size + *\param gpa_to_vva Callback to map memory from Guest Physical address to Virtual address + */ +int spdk_nvme_map_cmd(void *prv, struct spdk_nvme_cmd *cmd, struct iovec *iovs, uint32_t max_iovcnt, + uint32_t len, size_t mps, + void *(*gpa_to_vva)(void *prv, uint64_t addr, uint64_t len)); + /** * Opaque handle for a transport poll group. Used by the transport function table. */ diff --git a/lib/nvme/nvme_ctrlr.c b/lib/nvme/nvme_ctrlr.c index 008a80d55..22f5ecea6 100644 --- a/lib/nvme/nvme_ctrlr.c +++ b/lib/nvme/nvme_ctrlr.c @@ -4273,3 +4273,15 @@ spdk_nvme_map_prps(void *prv, struct spdk_nvme_cmd *cmd, struct iovec *iovs, return -EINVAL; } + +int +spdk_nvme_map_cmd(void *prv, struct spdk_nvme_cmd *cmd, struct iovec *iovs, uint32_t max_iovcnt, + uint32_t len, size_t mps, + void *(*gpa_to_vva)(void *prv, uint64_t addr, uint64_t len)) +{ + if (cmd->psdt == SPDK_NVME_PSDT_PRP) { + return nvme_cmd_map_prps(prv, cmd, iovs, max_iovcnt, len, mps, gpa_to_vva); + } + + return -EINVAL; +} diff --git a/lib/nvme/spdk_nvme.map b/lib/nvme/spdk_nvme.map index 19a6e817b..4881bc768 100644 --- a/lib/nvme/spdk_nvme.map +++ b/lib/nvme/spdk_nvme.map @@ -167,6 +167,7 @@ spdk_nvme_cuse_update_namespaces; spdk_nvme_map_prps; + spdk_nvme_map_cmd; spdk_nvme_poll_group_get_stats; spdk_nvme_poll_group_free_stats; diff --git a/lib/nvmf/vfio_user.c b/lib/nvmf/vfio_user.c index d7b670061..55551b771 100644 --- a/lib/nvmf/vfio_user.c +++ b/lib/nvmf/vfio_user.c @@ -559,8 +559,8 @@ vfio_user_map_prps(struct nvmf_vfio_user_ctrlr *ctrlr, struct spdk_nvmf_request /* Map PRP list to from Guest physical memory to * virtual memory address. */ - return spdk_nvme_map_prps(req, &req->cmd->nvme_cmd, iov, length, - 4096, _map_one); + return spdk_nvme_map_cmd(req, &req->cmd->nvme_cmd, iov, NVMF_REQ_MAX_BUFFERS, + length, 4096, _map_one); } static struct spdk_nvmf_request *