From 5cc565999ecd48bdd7d8fa0395437b7f6f090875 Mon Sep 17 00:00:00 2001 From: yupeng Date: Sun, 16 May 2021 10:45:11 +0000 Subject: [PATCH] nvmf: support NVME ACRE feature Support ACRE (Advanced Command Retry Enable) feature. Currently set all crdt to 0 and only select crdt[0] (crd=1) when the IO has any error. Signed-off-by: Peng Yu Change-Id: If7bc30f91f5b2d0839002dead17188a4b3a52d5d Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/7885 Community-CI: Broadcom CI Community-CI: Mellanox Build Bot Tested-by: SPDK CI Jenkins Reviewed-by: Jim Harris Reviewed-by: Ben Walker --- lib/nvmf/ctrlr.c | 56 ++++++++++++++++++++++++++++++++++++++++ lib/nvmf/nvmf_internal.h | 1 + 2 files changed, 57 insertions(+) diff --git a/lib/nvmf/ctrlr.c b/lib/nvmf/ctrlr.c index bcef8de6a..763e9251a 100644 --- a/lib/nvmf/ctrlr.c +++ b/lib/nvmf/ctrlr.c @@ -1589,6 +1589,41 @@ nvmf_ctrlr_set_features_reservation_persistence(struct spdk_nvmf_request *req) return SPDK_NVMF_REQUEST_EXEC_STATUS_COMPLETE; } +static int +nvmf_ctrlr_set_features_host_behavior_support(struct spdk_nvmf_request *req) +{ + struct spdk_nvmf_ctrlr *ctrlr = req->qpair->ctrlr; + struct spdk_nvme_cpl *response = &req->rsp->nvme_cpl; + struct spdk_nvme_host_behavior *host_behavior; + + SPDK_DEBUGLOG(nvmf, "Set Features - Host Behavior Support\n"); + if (req->iovcnt != 1) { + SPDK_ERRLOG("Host Behavior Support invalid iovcnt: %d\n", req->iovcnt); + response->status.sct = SPDK_NVME_SCT_GENERIC; + response->status.sc = SPDK_NVME_SC_INVALID_FIELD; + return SPDK_NVMF_REQUEST_EXEC_STATUS_COMPLETE; + } + if (req->iov[0].iov_len != sizeof(struct spdk_nvme_host_behavior)) { + SPDK_ERRLOG("Host Behavior Support invalid iov_len: %ld\n", req->iov[0].iov_len); + response->status.sct = SPDK_NVME_SCT_GENERIC; + response->status.sc = SPDK_NVME_SC_INVALID_FIELD; + return SPDK_NVMF_REQUEST_EXEC_STATUS_COMPLETE; + } + + host_behavior = (struct spdk_nvme_host_behavior *)req->iov[0].iov_base; + if (host_behavior->acre == 0) { + ctrlr->acre_enabled = false; + } else if (host_behavior->acre == 1) { + ctrlr->acre_enabled = true; + } else { + SPDK_ERRLOG("Host Behavior Support invalid acre: 0x%02x\n", host_behavior->acre); + response->status.sct = SPDK_NVME_SCT_GENERIC; + response->status.sc = SPDK_NVME_SC_INVALID_FIELD; + return SPDK_NVMF_REQUEST_EXEC_STATUS_COMPLETE; + } + return SPDK_NVMF_REQUEST_EXEC_STATUS_COMPLETE; +} + static int nvmf_ctrlr_set_features_keep_alive_timer(struct spdk_nvmf_request *req) { @@ -2249,6 +2284,14 @@ spdk_nvmf_ctrlr_identify_ctrlr(struct spdk_nvmf_ctrlr *ctrlr, struct spdk_nvme_c nvmf_ctrlr_populate_oacs(ctrlr, cdata); + /* + * FIXME: Set all crdt to 0 currently, + * will provide an API to customize them later. + */ + cdata->crdt[0] = 0; + cdata->crdt[1] = 0; + cdata->crdt[2] = 0; + SPDK_DEBUGLOG(nvmf, "ext ctrlr data: ioccsz 0x%x\n", cdata->nvmf_specific.ioccsz); SPDK_DEBUGLOG(nvmf, "ext ctrlr data: iorcsz 0x%x\n", @@ -2742,6 +2785,8 @@ nvmf_ctrlr_set_features(struct spdk_nvmf_request *req) return nvmf_ctrlr_set_features_reservation_notification_mask(req); case SPDK_NVME_FEAT_HOST_RESERVE_PERSIST: return nvmf_ctrlr_set_features_reservation_persistence(req); + case SPDK_NVME_FEAT_HOST_BEHAVIOR_SUPPORT: + return nvmf_ctrlr_set_features_host_behavior_support(req); default: SPDK_ERRLOG("Set Features command with unsupported feature ID 0x%02x\n", feature); response->status.sc = SPDK_NVME_SC_INVALID_FIELD; @@ -3490,6 +3535,17 @@ _nvmf_request_complete(void *ctx) sgroup = &qpair->group->sgroups[qpair->ctrlr->subsys->id]; assert(sgroup != NULL); is_aer = req->cmd->nvme_cmd.opc == SPDK_NVME_OPC_ASYNC_EVENT_REQUEST; + + /* + * Set the crd value. + * If the the IO has any error, and dnr (DoNotRetry) is not 1, + * and ACRE is enabled, we will set the crd to 1 to select the first CRDT. + */ + if (spdk_nvme_cpl_is_error(rsp) && + rsp->status.dnr == 0 && + qpair->ctrlr->acre_enabled) { + rsp->status.crd = 1; + } } else if (spdk_unlikely(nvmf_request_is_fabric_connect(req))) { sgroup = nvmf_subsystem_pg_from_connect_cmd(req); } diff --git a/lib/nvmf/nvmf_internal.h b/lib/nvmf/nvmf_internal.h index 9c6510305..8e300429a 100644 --- a/lib/nvmf/nvmf_internal.h +++ b/lib/nvmf/nvmf_internal.h @@ -261,6 +261,7 @@ struct spdk_nvmf_ctrlr { bool dif_insert_or_strip; bool in_destruct; bool disconnect_in_progress; + bool acre_enabled; TAILQ_ENTRY(spdk_nvmf_ctrlr) link; };