nvme: add async+poll APIs for nvme_fabric_qpair_connect

These functions will allow for sending the connect fabric command
asynchronously.

Additionally, this patch changes the return code for
`nvme_fabric_qpair_connect()` when a timeout occurs from -EIO to
-ECANCELED. It gives better description of the error as well as make it
more consistent with `nvme_wait_for_completion*` APIs.

Signed-off-by: Jim Harris <james.r.harris@intel.com>
Signed-off-by: Konrad Sztyber <konrad.sztyber@intel.com>
Change-Id: I95806626d3573ebe4b1568157fd57013c4b909a7
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/8604
Community-CI: Broadcom CI <spdk-ci.pdl@broadcom.com>
Community-CI: Mellanox Build Bot
Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: Shuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com>
Reviewed-by: Aleksey Marchuk <alexeymar@mellanox.com>
This commit is contained in:
Jim Harris 2021-06-08 19:25:37 +00:00 committed by Tomasz Zawadzki
parent b10fbdf58f
commit 7e21385f8a
3 changed files with 57 additions and 17 deletions

View File

@ -384,10 +384,9 @@ nvme_fabric_ctrlr_discover(struct spdk_nvme_ctrlr *ctrlr,
}
int
nvme_fabric_qpair_connect(struct spdk_nvme_qpair *qpair, uint32_t num_entries)
nvme_fabric_qpair_connect_async(struct spdk_nvme_qpair *qpair, uint32_t num_entries)
{
struct nvme_completion_poll_status *status;
struct spdk_nvmf_fabric_connect_rsp *rsp;
struct spdk_nvmf_fabric_connect_cmd cmd;
struct spdk_nvmf_fabric_connect_data *nvmf_data;
struct spdk_nvme_ctrlr *ctrlr;
@ -454,26 +453,43 @@ nvme_fabric_qpair_connect(struct spdk_nvme_qpair *qpair, uint32_t num_entries)
spdk_get_ticks_hz() / SPDK_SEC_TO_USEC;
}
/* Wait until the command completes or times out */
while (nvme_wait_for_completion_robust_lock_timeout_poll(qpair, status, NULL) == -EAGAIN) {}
qpair->poll_status = status;
return 0;
}
int
nvme_fabric_qpair_connect_poll(struct spdk_nvme_qpair *qpair)
{
struct nvme_completion_poll_status *status;
struct spdk_nvmf_fabric_connect_rsp *rsp;
struct spdk_nvme_ctrlr *ctrlr;
int rc = 0;
ctrlr = qpair->ctrlr;
status = qpair->poll_status;
if (nvme_wait_for_completion_robust_lock_timeout_poll(qpair, status, NULL) == -EAGAIN) {
return -EAGAIN;
}
if (status->timed_out || spdk_nvme_cpl_is_error(&status->cpl)) {
SPDK_ERRLOG("Connect command failed, rc %d, trtype:%s adrfam:%s traddr:%s trsvcid:%s subnqn:%s\n",
SPDK_ERRLOG("Connect command failed, rc %d, trtype:%s adrfam:%s "
"traddr:%s trsvcid:%s subnqn:%s\n",
status->timed_out ? -ECANCELED : -EIO,
spdk_nvme_transport_id_trtype_str(ctrlr->trid.trtype),
spdk_nvme_transport_id_adrfam_str(ctrlr->trid.adrfam),
ctrlr->trid.traddr,
ctrlr->trid.trsvcid,
ctrlr->trid.subnqn);
if (spdk_nvme_cpl_is_error(&status->cpl)) {
SPDK_ERRLOG("Connect command completed with error: sct %d, sc %d\n", status->cpl.status.sct,
status->cpl.status.sc);
if (status->timed_out) {
rc = -ECANCELED;
} else {
SPDK_ERRLOG("Connect command completed with error: sct %d, sc %d\n",
status->cpl.status.sct, status->cpl.status.sc);
rc = -EIO;
}
if (!status->timed_out) {
spdk_free(status->dma_data);
free(status);
}
return -EIO;
goto finish;
}
if (nvme_qpair_is_admin_queue(qpair)) {
@ -481,8 +497,30 @@ nvme_fabric_qpair_connect(struct spdk_nvme_qpair *qpair, uint32_t num_entries)
ctrlr->cntlid = rsp->status_code_specific.success.cntlid;
SPDK_DEBUGLOG(nvme, "CNTLID 0x%04" PRIx16 "\n", ctrlr->cntlid);
}
finish:
qpair->poll_status = NULL;
if (!status->timed_out) {
spdk_free(status->dma_data);
free(status);
}
spdk_free(status->dma_data);
free(status);
return 0;
return rc;
}
int
nvme_fabric_qpair_connect(struct spdk_nvme_qpair *qpair, uint32_t num_entries)
{
int rc;
rc = nvme_fabric_qpair_connect_async(qpair, num_entries);
if (rc) {
return rc;
}
do {
/* Wait until the command completes or times out */
rc = nvme_fabric_qpair_connect_poll(qpair);
} while (rc == -EAGAIN);
return rc;
}

View File

@ -1124,6 +1124,8 @@ int nvme_fabric_ctrlr_get_reg_8(struct spdk_nvme_ctrlr *ctrlr, uint32_t offset,
int nvme_fabric_ctrlr_discover(struct spdk_nvme_ctrlr *ctrlr,
struct spdk_nvme_probe_ctx *probe_ctx);
int nvme_fabric_qpair_connect(struct spdk_nvme_qpair *qpair, uint32_t num_entries);
int nvme_fabric_qpair_connect_async(struct spdk_nvme_qpair *qpair, uint32_t num_entries);
int nvme_fabric_qpair_connect_poll(struct spdk_nvme_qpair *qpair);
typedef int (*spdk_nvme_parse_ana_log_page_cb)(
const struct spdk_nvme_ana_group_descriptor *desc, void *cb_arg);

View File

@ -432,7 +432,7 @@ test_nvme_fabric_qpair_connect(void)
g_nvme_wait_for_completion_timeout = true;
rc = nvme_fabric_qpair_connect(&qpair, 1);
CU_ASSERT(rc == -EIO);
CU_ASSERT(rc == -ECANCELED);
g_nvme_wait_for_completion_timeout = false;
abort_request(g_request);