Commit 7e21385f authored by Jim Harris's avatar Jim Harris Committed by Tomasz Zawadzki
Browse files

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: default avatarJim Harris <james.r.harris@intel.com>
Signed-off-by: default avatarKonrad 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: default avatarSPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: default avatarShuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com>
Reviewed-by: default avatarAleksey Marchuk <alexeymar@mellanox.com>
parent b10fbdf5
Loading
Loading
Loading
Loading
+54 −16
Original line number Diff line number Diff line
@@ -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) {
			spdk_free(status->dma_data);
			free(status);
		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;
		}
		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);
	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;
}
+2 −0
Original line number Diff line number Diff line
@@ -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);
+1 −1
Original line number Diff line number Diff line
@@ -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);