Commit b0e9620b authored by Daniel Verkamp's avatar Daniel Verkamp
Browse files

nvme: add qpair create and delete to transport



Change-Id: Ibc057972c7eb84ada95fb173d559255e5c86c5ba
Signed-off-by: default avatarDaniel Verkamp <daniel.verkamp@intel.com>
parent 179f122c
Loading
Loading
Loading
Loading
+4 −79
Original line number Diff line number Diff line
@@ -115,54 +115,6 @@ spdk_nvme_ctrlr_opts_set_defaults(struct spdk_nvme_ctrlr_opts *opts)
	opts->arb_mechanism = SPDK_NVME_CC_AMS_RR;
}

static int
spdk_nvme_ctrlr_create_qpair(struct spdk_nvme_ctrlr *ctrlr, struct spdk_nvme_qpair *qpair)
{
	struct nvme_completion_poll_status	status;
	int rc;

	status.done = false;
	rc = nvme_ctrlr_cmd_create_io_cq(ctrlr, qpair, nvme_completion_poll_cb, &status);
	if (rc != 0) {
		return rc;
	}

	while (status.done == false) {
		spdk_nvme_qpair_process_completions(&ctrlr->adminq, 0);
	}
	if (spdk_nvme_cpl_is_error(&status.cpl)) {
		SPDK_ERRLOG("nvme_create_io_cq failed!\n");
		return -1;
	}

	status.done = false;
	rc = nvme_ctrlr_cmd_create_io_sq(qpair->ctrlr, qpair, nvme_completion_poll_cb, &status);
	if (rc != 0) {
		return rc;
	}

	while (status.done == false) {
		spdk_nvme_qpair_process_completions(&ctrlr->adminq, 0);
	}
	if (spdk_nvme_cpl_is_error(&status.cpl)) {
		SPDK_ERRLOG("nvme_create_io_sq failed!\n");
		/* Attempt to delete the completion queue */
		status.done = false;
		rc = nvme_ctrlr_cmd_delete_io_cq(qpair->ctrlr, qpair, nvme_completion_poll_cb, &status);
		if (rc != 0) {
			return -1;
		}
		while (status.done == false) {
			spdk_nvme_qpair_process_completions(&ctrlr->adminq, 0);
		}
		return -1;
	}

	nvme_qpair_reset(qpair);

	return 0;
}

struct spdk_nvme_qpair *
spdk_nvme_ctrlr_alloc_io_qpair(struct spdk_nvme_ctrlr *ctrlr,
			       enum spdk_nvme_qprio qprio)
@@ -208,9 +160,9 @@ spdk_nvme_ctrlr_alloc_io_qpair(struct spdk_nvme_ctrlr *ctrlr,
	 * Fill out the submission queue priority and send out the Create I/O Queue commands.
	 */
	qpair->qprio = qprio;
	if (spdk_nvme_ctrlr_create_qpair(ctrlr, qpair) != 0) {
	if (ctrlr->transport->ctrlr_create_io_qpair(ctrlr, qpair)) {
		/*
		 * spdk_nvme_ctrlr_create_qpair() failed, so the qpair structure is still unused.
		 * ctrlr_create_io_qpair() failed, so the qpair structure is still unused.
		 * Exit here so we don't insert it into the active_io_qpairs list.
		 */
		pthread_mutex_unlock(&ctrlr->ctrlr_lock);
@@ -228,8 +180,6 @@ int
spdk_nvme_ctrlr_free_io_qpair(struct spdk_nvme_qpair *qpair)
{
	struct spdk_nvme_ctrlr *ctrlr;
	struct nvme_completion_poll_status status;
	int rc;

	if (qpair == NULL) {
		return 0;
@@ -239,32 +189,7 @@ spdk_nvme_ctrlr_free_io_qpair(struct spdk_nvme_qpair *qpair)

	pthread_mutex_lock(&ctrlr->ctrlr_lock);

	/* Delete the I/O submission queue and then the completion queue */

	status.done = false;
	rc = nvme_ctrlr_cmd_delete_io_sq(ctrlr, qpair, nvme_completion_poll_cb, &status);
	if (rc != 0) {
		pthread_mutex_unlock(&ctrlr->ctrlr_lock);
		return rc;
	}
	while (status.done == false) {
		spdk_nvme_qpair_process_completions(&ctrlr->adminq, 0);
	}
	if (spdk_nvme_cpl_is_error(&status.cpl)) {
		pthread_mutex_unlock(&ctrlr->ctrlr_lock);
		return -1;
	}

	status.done = false;
	rc = nvme_ctrlr_cmd_delete_io_cq(ctrlr, qpair, nvme_completion_poll_cb, &status);
	if (rc != 0) {
		pthread_mutex_unlock(&ctrlr->ctrlr_lock);
		return rc;
	}
	while (status.done == false) {
		spdk_nvme_qpair_process_completions(&ctrlr->adminq, 0);
	}
	if (spdk_nvme_cpl_is_error(&status.cpl)) {
	if (ctrlr->transport->ctrlr_delete_io_qpair(ctrlr, qpair)) {
		pthread_mutex_unlock(&ctrlr->ctrlr_lock);
		return -1;
	}
@@ -670,7 +595,7 @@ spdk_nvme_ctrlr_reset(struct spdk_nvme_ctrlr *ctrlr)
	if (!ctrlr->is_failed) {
		/* Reinitialize qpairs */
		TAILQ_FOREACH(qpair, &ctrlr->active_io_qpairs, tailq) {
			if (spdk_nvme_ctrlr_create_qpair(ctrlr, qpair) != 0) {
			if (ctrlr->transport->ctrlr_create_io_qpair(ctrlr, qpair) != 0) {
				nvme_ctrlr_fail(ctrlr);
				rc = -1;
			}
+3 −0
Original line number Diff line number Diff line
@@ -256,6 +256,9 @@ struct spdk_nvme_transport {

	int (*ctrlr_get_reg_4)(struct spdk_nvme_ctrlr *ctrlr, uint32_t offset, uint32_t *value);
	int (*ctrlr_get_reg_8)(struct spdk_nvme_ctrlr *ctrlr, uint32_t offset, uint64_t *value);

	int (*ctrlr_create_io_qpair)(struct spdk_nvme_ctrlr *ctrlr, struct spdk_nvme_qpair *qpair);
	int (*ctrlr_delete_io_qpair)(struct spdk_nvme_ctrlr *ctrlr, struct spdk_nvme_qpair *qpair);
};

struct nvme_completion_poll_status {
+92 −0
Original line number Diff line number Diff line
@@ -96,6 +96,95 @@ nvme_pcie_ctrlr_get_reg_8(struct spdk_nvme_ctrlr *ctrlr, uint32_t offset, uint64
	return 0;
}

static int
nvme_pcie_ctrlr_create_io_qpair(struct spdk_nvme_ctrlr *ctrlr, struct spdk_nvme_qpair *qpair)
{
	struct nvme_completion_poll_status	status;
	int rc;

	assert(ctrlr != NULL);
	assert(qpair != NULL);

	status.done = false;
	rc = nvme_ctrlr_cmd_create_io_cq(ctrlr, qpair, nvme_completion_poll_cb, &status);
	if (rc != 0) {
		return rc;
	}

	while (status.done == false) {
		spdk_nvme_qpair_process_completions(&ctrlr->adminq, 0);
	}
	if (spdk_nvme_cpl_is_error(&status.cpl)) {
		SPDK_ERRLOG("nvme_create_io_cq failed!\n");
		return -1;
	}

	status.done = false;
	rc = nvme_ctrlr_cmd_create_io_sq(qpair->ctrlr, qpair, nvme_completion_poll_cb, &status);
	if (rc != 0) {
		return rc;
	}

	while (status.done == false) {
		spdk_nvme_qpair_process_completions(&ctrlr->adminq, 0);
	}
	if (spdk_nvme_cpl_is_error(&status.cpl)) {
		SPDK_ERRLOG("nvme_create_io_sq failed!\n");
		/* Attempt to delete the completion queue */
		status.done = false;
		rc = nvme_ctrlr_cmd_delete_io_cq(qpair->ctrlr, qpair, nvme_completion_poll_cb, &status);
		if (rc != 0) {
			return -1;
		}
		while (status.done == false) {
			spdk_nvme_qpair_process_completions(&ctrlr->adminq, 0);
		}
		return -1;
	}

	nvme_qpair_reset(qpair);

	return 0;
}

static int
nvme_pcie_ctrlr_delete_io_qpair(struct spdk_nvme_ctrlr *ctrlr, struct spdk_nvme_qpair *qpair)
{
	struct nvme_completion_poll_status status;
	int rc;

	assert(ctrlr != NULL);
	assert(qpair != NULL);

	/* Delete the I/O submission queue and then the completion queue */

	status.done = false;
	rc = nvme_ctrlr_cmd_delete_io_sq(ctrlr, qpair, nvme_completion_poll_cb, &status);
	if (rc != 0) {
		return rc;
	}
	while (status.done == false) {
		spdk_nvme_qpair_process_completions(&ctrlr->adminq, 0);
	}
	if (spdk_nvme_cpl_is_error(&status.cpl)) {
		return -1;
	}

	status.done = false;
	rc = nvme_ctrlr_cmd_delete_io_cq(ctrlr, qpair, nvme_completion_poll_cb, &status);
	if (rc != 0) {
		return rc;
	}
	while (status.done == false) {
		spdk_nvme_qpair_process_completions(&ctrlr->adminq, 0);
	}
	if (spdk_nvme_cpl_is_error(&status.cpl)) {
		return -1;
	}

	return 0;
}

const struct spdk_nvme_transport spdk_nvme_transport_pcie = {
	.ctrlr_get_pci_id = nvme_pcie_ctrlr_get_pci_id,

@@ -104,4 +193,7 @@ const struct spdk_nvme_transport spdk_nvme_transport_pcie = {

	.ctrlr_get_reg_4 = nvme_pcie_ctrlr_get_reg_4,
	.ctrlr_get_reg_8 = nvme_pcie_ctrlr_get_reg_8,

	.ctrlr_create_io_qpair = nvme_pcie_ctrlr_create_io_qpair,
	.ctrlr_delete_io_qpair = nvme_pcie_ctrlr_delete_io_qpair,
};
+16 −0
Original line number Diff line number Diff line
@@ -139,6 +139,19 @@ ut_ctrlr_get_reg_8(struct spdk_nvme_ctrlr *ctrlr, uint32_t offset, uint64_t *val
	return 0;
}


static int
ut_ctrlr_create_io_qpair(struct spdk_nvme_ctrlr *ctrlr, struct spdk_nvme_qpair *qpair)
{
	return 0;
}

static int
ut_ctrlr_delete_io_qpair(struct spdk_nvme_ctrlr *ctrlr, struct spdk_nvme_qpair *qpair)
{
	return 0;
}

static const struct spdk_nvme_transport nvme_ctrlr_ut_transport = {
	.ctrlr_get_pci_id = ut_ctrlr_get_pci_id,

@@ -147,6 +160,9 @@ static const struct spdk_nvme_transport nvme_ctrlr_ut_transport = {

	.ctrlr_get_reg_4 = ut_ctrlr_get_reg_4,
	.ctrlr_get_reg_8 = ut_ctrlr_get_reg_8,

	.ctrlr_create_io_qpair = ut_ctrlr_create_io_qpair,
	.ctrlr_delete_io_qpair = ut_ctrlr_delete_io_qpair,
};

uint16_t