From b65b033758da6061ecf7ee683dcbeaa2e534a287 Mon Sep 17 00:00:00 2001 From: Ni Xun Date: Tue, 18 Sep 2018 11:32:15 +0800 Subject: [PATCH] vhost_nvme: add support for bdev_io_wait implement according to commit: bdev: add spdk_bdev_queue_io_wait This patch will make io_wait to support vhost_nvme Change-Id: I20f7c9f2005a0d4140db9ff2d522fb5e15356cd5 Signed-off-by: Ni Xun Signed-off-by: Li Lin Signed-off-by: Zhang Yu Reviewed-on: https://review.gerrithub.io/425884 Reviewed-by: Changpeng Liu Reviewed-by: Ben Walker Chandler-Test-Pool: SPDK Automated Test System Tested-by: SPDK CI Jenkins --- lib/vhost/vhost_nvme.c | 62 ++++++++++++++++++++++++++++++++++++++---- 1 file changed, 56 insertions(+), 6 deletions(-) diff --git a/lib/vhost/vhost_nvme.c b/lib/vhost/vhost_nvme.c index ff64a56bb..35015d93b 100644 --- a/lib/vhost/vhost_nvme.c +++ b/lib/vhost/vhost_nvme.c @@ -107,6 +107,11 @@ struct spdk_vhost_nvme_task { /** Offset in current iovec. */ uint32_t iov_offset; + /* for bdev_io_wait */ + struct spdk_bdev_io_wait_entry bdev_io_wait; + struct spdk_vhost_nvme_sq *sq; + struct spdk_vhost_nvme_ns *ns; + /* parent pointer. */ struct spdk_vhost_nvme_task *parent; uint8_t dnr; @@ -150,6 +155,10 @@ static const struct spdk_vhost_dev_backend spdk_vhost_nvme_device_backend; */ #define FW_VERSION SPDK_VERSION_MAJOR_STRING SPDK_VERSION_MINOR_STRING SPDK_VERSION_PATCH_STRING +static int +spdk_nvme_process_sq(struct spdk_vhost_nvme_dev *nvme, struct spdk_vhost_nvme_sq *sq, + struct spdk_vhost_nvme_task *task); + static struct spdk_vhost_nvme_dev * to_nvme_dev(struct spdk_vhost_dev *vdev) { @@ -411,6 +420,39 @@ spdk_vhost_nvme_get_ns_from_nsid(struct spdk_vhost_nvme_dev *dev, uint32_t nsid) return &dev->ns[nsid - 1]; } +static void +vhost_nvme_resubmit_task(void *arg) +{ + struct spdk_vhost_nvme_task *task = (struct spdk_vhost_nvme_task *)arg; + int rc; + + rc = spdk_nvme_process_sq(task->nvme, task->sq, task); + if (rc) { + SPDK_DEBUGLOG(SPDK_LOG_VHOST_NVME, "vhost_nvme: task resubmit failed, rc = %d.\n", rc); + } +} + +static int +vhost_nvme_queue_task(struct spdk_vhost_nvme_task *task) +{ + int rc; + + task->bdev_io_wait.bdev = task->ns->bdev; + task->bdev_io_wait.cb_fn = vhost_nvme_resubmit_task; + task->bdev_io_wait.cb_arg = task; + + rc = spdk_bdev_queue_io_wait(task->ns->bdev, task->ns->bdev_io_channel, &task->bdev_io_wait); + if (rc != 0) { + SPDK_ERRLOG("Queue io failed in vhost_nvme_queue_task, rc=%d.\n", rc); + task->dnr = 1; + task->sct = SPDK_NVME_SCT_GENERIC; + task->sc = SPDK_NVME_SC_INTERNAL_DEVICE_ERROR; + spdk_vhost_nvme_task_complete(task); + } + + return rc; +} + static int spdk_nvme_process_sq(struct spdk_vhost_nvme_dev *nvme, struct spdk_vhost_nvme_sq *sq, struct spdk_vhost_nvme_task *task) @@ -443,6 +485,8 @@ spdk_nvme_process_sq(struct spdk_vhost_nvme_dev *nvme, struct spdk_vhost_nvme_sq task->cqid = sq->cqid; task->sqid = sq->sqid; + task->ns = ns; + if (spdk_unlikely(!ns->active_ns)) { task->dnr = 1; task->sct = SPDK_NVME_SCT_GENERIC; @@ -531,12 +575,18 @@ spdk_nvme_process_sq(struct spdk_vhost_nvme_dev *nvme, struct spdk_vhost_nvme_sq } if (spdk_unlikely(ret)) { - /* post error status to cqe */ - SPDK_ERRLOG("Error Submission For Command %u, ret %d\n", cmd->opc, ret); - task->dnr = 1; - task->sct = SPDK_NVME_SCT_GENERIC; - task->sc = SPDK_NVME_SC_INTERNAL_DEVICE_ERROR; - spdk_vhost_nvme_task_complete(task); + if (ret == -ENOMEM) { + SPDK_DEBUGLOG(SPDK_LOG_VHOST_NVME, "No memory, start to queue io.\n"); + task->sq = sq; + ret = vhost_nvme_queue_task(task); + } else { + /* post error status to cqe */ + SPDK_ERRLOG("Error Submission For Command %u, ret %d\n", cmd->opc, ret); + task->dnr = 1; + task->sct = SPDK_NVME_SCT_GENERIC; + task->sc = SPDK_NVME_SC_INTERNAL_DEVICE_ERROR; + spdk_vhost_nvme_task_complete(task); + } } return ret;