From 67c9c1c5d8d2634010118d1ee7e89a4c6157df99 Mon Sep 17 00:00:00 2001 From: Tomasz Kulasek Date: Thu, 28 Nov 2019 15:24:19 -0500 Subject: [PATCH] lib/nvmf: add fused operations Change-Id: If3162a5683d1c57011f9a66cbcfe47ba161734bf Signed-off-by: Tomasz Kulasek Reviewed-on: https://review.gerrithub.io/c/spdk/spdk/+/476138 Community-CI: Broadcom SPDK FC-NVMe CI Reviewed-by: Shuhei Matsumoto Reviewed-by: Jim Harris Tested-by: SPDK CI Jenkins --- lib/nvmf/ctrlr.c | 28 ++++++++++++++++++++++++++++ lib/nvmf/ctrlr_bdev.c | 24 ++++++++++++++++++++---- lib/nvmf/nvmf_internal.h | 3 +++ 3 files changed, 51 insertions(+), 4 deletions(-) diff --git a/lib/nvmf/ctrlr.c b/lib/nvmf/ctrlr.c index 022412fa9..872fc9e02 100644 --- a/lib/nvmf/ctrlr.c +++ b/lib/nvmf/ctrlr.c @@ -1623,6 +1623,7 @@ spdk_nvmf_ctrlr_identify_ctrlr(struct spdk_nvmf_ctrlr *ctrlr, struct spdk_nvme_c cdata->sgls.supported = 1; cdata->sgls.keyed_sgl = 1; cdata->sgls.sgl_offset = 1; + cdata->fuses.compare_and_write = 0; spdk_strcpy_pad(cdata->subnqn, subsystem->subnqn, sizeof(cdata->subnqn), '\0'); SPDK_DEBUGLOG(SPDK_LOG_NVMF, "ctrlr data: maxcmd 0x%x\n", cdata->maxcmd); @@ -2461,6 +2462,33 @@ spdk_nvmf_ctrlr_process_io_cmd(struct spdk_nvmf_request *req) response->status.sc = SPDK_NVME_SC_SUCCESS; nsid = cmd->nsid; + if (cmd->fuse == SPDK_NVME_CMD_FUSE_FIRST) { + /* first fused operation (should be compare) */ + if (req->qpair->first_fused_req != NULL) { + struct spdk_nvme_cpl *fused_response = &req->qpair->first_fused_req->rsp->nvme_cpl; + + SPDK_ERRLOG("Wrong sequence of fused operations\n"); + /* abort req->qpair->first_fused_request and continue with new fused command */ + fused_response->status.sc = SPDK_NVME_SC_ABORTED_MISSING_FUSED; + fused_response->status.sct = SPDK_NVME_SCT_GENERIC; + spdk_nvmf_request_complete(req->qpair->first_fused_req); + } + + req->qpair->first_fused_req = req; + } else if (cmd->fuse == SPDK_NVME_CMD_FUSE_SECOND) { + /* second fused operation */ + if (req->qpair->first_fused_req == NULL) { + SPDK_ERRLOG("Wrong sequence of fused operations\n"); + response->status.sct = SPDK_NVME_SCT_GENERIC; + response->status.sc = SPDK_NVME_SC_ABORTED_MISSING_FUSED; + return SPDK_NVMF_REQUEST_EXEC_STATUS_COMPLETE; + } + + /* save request of first command to generate response later */ + req->first_fused_req = req->qpair->first_fused_req; + req->qpair->first_fused_req = NULL; + } + if (spdk_unlikely(ctrlr == NULL)) { SPDK_ERRLOG("I/O command sent before CONNECT\n"); response->status.sct = SPDK_NVME_SCT_GENERIC; diff --git a/lib/nvmf/ctrlr_bdev.c b/lib/nvmf/ctrlr_bdev.c index 4b9370e12..4409a7159 100644 --- a/lib/nvmf/ctrlr_bdev.c +++ b/lib/nvmf/ctrlr_bdev.c @@ -93,13 +93,29 @@ nvmf_bdev_ctrlr_complete_cmd(struct spdk_bdev_io *bdev_io, bool success, { struct spdk_nvmf_request *req = cb_arg; struct spdk_nvme_cpl *response = &req->rsp->nvme_cpl; - int sc, sct; + int first_sc, first_sct, second_sc, second_sct; uint32_t cdw0; + struct spdk_nvmf_request *first_req = req->first_fused_req; + + if (spdk_unlikely(first_req != NULL)) { + /* fused commands - get status for both operations */ + struct spdk_nvme_cpl *fused_response = &first_req->rsp->nvme_cpl; + + spdk_bdev_io_get_nvme_fused_status(bdev_io, &cdw0, &second_sct, &second_sc, &first_sct, &first_sc); + fused_response->cdw0 = cdw0; + fused_response->status.sc = second_sc; + fused_response->status.sct = second_sct; + + /* first request should be completed */ + spdk_nvmf_request_complete(first_req); + req->first_fused_req = NULL; + } else { + spdk_bdev_io_get_nvme_status(bdev_io, &cdw0, &first_sct, &first_sc); + } - spdk_bdev_io_get_nvme_status(bdev_io, &cdw0, &sct, &sc); response->cdw0 = cdw0; - response->status.sc = sc; - response->status.sct = sct; + response->status.sc = first_sc; + response->status.sct = first_sct; spdk_nvmf_request_complete(req); spdk_bdev_free_io(bdev_io); diff --git a/lib/nvmf/nvmf_internal.h b/lib/nvmf/nvmf_internal.h index f83b116ca..1dc93451e 100644 --- a/lib/nvmf/nvmf_internal.h +++ b/lib/nvmf/nvmf_internal.h @@ -224,6 +224,7 @@ struct spdk_nvmf_request { struct spdk_bdev_io_wait_entry bdev_io_wait; struct spdk_nvmf_dif_info dif; spdk_nvmf_nvme_passthru_cmd_cb cmd_cb_fn; + struct spdk_nvmf_request *first_fused_req; STAILQ_ENTRY(spdk_nvmf_request) buf_link; TAILQ_ENTRY(spdk_nvmf_request) link; @@ -273,6 +274,8 @@ struct spdk_nvmf_qpair { uint16_t sq_head; uint16_t sq_head_max; + struct spdk_nvmf_request *first_fused_req; + TAILQ_HEAD(, spdk_nvmf_request) outstanding; TAILQ_ENTRY(spdk_nvmf_qpair) link; };