Commit 771f65bb authored by Monica Kenguva's avatar Monica Kenguva Committed by Tomasz Zawadzki
Browse files

nvme: asynchronous create io qpair



async_mode option is currently supported in PCIe transport layer
to create io qpair asynchronously. User polls the io_qpair for
completions, after create cq and sq completes in order, pqpair
is set to READY state. I/O submitted before the qpair is ready
is queued internally. Currently other transports only support
synchronous io qpair creation.

Signed-off-by: default avatarMonica Kenguva <monica.kenguva@intel.com>
Signed-off-by: default avatarBen Walker <benjamin.walker@intel.com>
Change-Id: Ib2f9043872bd5602274e2508cf1fe9ff4211cabb
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/8911


Community-CI: Mellanox Build Bot
Community-CI: Broadcom CI <spdk-ci.pdl@broadcom.com>
Tested-by: default avatarSPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: default avatarKonrad Sztyber <konrad.sztyber@intel.com>
Reviewed-by: default avatarAleksey Marchuk <alexeymar@mellanox.com>
parent a7b15178
Loading
Loading
Loading
Loading
+8 −0
Original line number Diff line number Diff line
@@ -1434,6 +1434,14 @@ struct spdk_nvme_io_qpair_opts {
	 * poll group and then connect it later.
	 */
	bool create_only;

	/**
	 * This flag if set to true enables the creation of submission and completion queue
	 * asynchronously. This mode is currently supported at PCIe layer and tracks the
	 * qpair creation with state machine and returns to the user.Default mode is set to
	 * false to create io qpair synchronosuly.
	 */
	bool async_mode;
};

/**
+1 −1
Original line number Diff line number Diff line
@@ -34,7 +34,7 @@
SPDK_ROOT_DIR := $(abspath $(CURDIR)/../..)
include $(SPDK_ROOT_DIR)/mk/spdk.common.mk

SO_VER := 6
SO_VER := 7
SO_MINOR := 0

C_SRCS = nvme_ctrlr_cmd.c nvme_ctrlr.c nvme_fabric.c nvme_ns_cmd.c nvme_ns.c nvme_pcie_common.c nvme_pcie.c nvme_qpair.c nvme.c nvme_quirks.c nvme_transport.c \
+13 −0
Original line number Diff line number Diff line
@@ -314,6 +314,10 @@ spdk_nvme_ctrlr_get_default_io_qpair_opts(struct spdk_nvme_ctrlr *ctrlr,
		opts->create_only = false;
	}

	if (FIELD_OK(async_mode)) {
		opts->async_mode = false;
	}

#undef FIELD_OK
}

@@ -1449,6 +1453,7 @@ nvme_ctrlr_reinit_on_reset(struct spdk_nvme_ctrlr *ctrlr)
{
	struct spdk_nvme_qpair	*qpair;
	int rc = 0, rc_tmp = 0;
	bool async;

	if (nvme_ctrlr_process_init(ctrlr) != 0) {
		NVME_CTRLR_ERRLOG(ctrlr, "controller reinitialization failed\n");
@@ -1470,7 +1475,14 @@ nvme_ctrlr_reinit_on_reset(struct spdk_nvme_ctrlr *ctrlr)
		TAILQ_FOREACH(qpair, &ctrlr->active_io_qpairs, tailq) {
			assert(spdk_bit_array_get(ctrlr->free_io_qids, qpair->id));
			spdk_bit_array_clear(ctrlr->free_io_qids, qpair->id);

			/* Force a synchronous connect. We can't currently handle an asynchronous
			 * operation here. */
			async = qpair->async;
			qpair->async = false;
			rc_tmp = nvme_transport_ctrlr_connect_qpair(ctrlr, qpair);
			qpair->async = async;

			if (rc_tmp != 0) {
				rc = rc_tmp;
				qpair->transport_failure_reason = SPDK_NVME_QPAIR_FAILURE_LOCAL;
@@ -3292,6 +3304,7 @@ nvme_ctrlr_process_init(struct spdk_nvme_ctrlr *ctrlr)
		break;

	case NVME_CTRLR_STATE_CONNECT_ADMINQ: /* synonymous with NVME_CTRLR_STATE_INIT */
		assert(ctrlr->adminq->async == false); /* not currently supported */
		rc = nvme_transport_ctrlr_connect_qpair(ctrlr, ctrlr->adminq);
		if (rc == 0) {
			nvme_qpair_set_state(ctrlr->adminq, NVME_QPAIR_ENABLED);
+8 −2
Original line number Diff line number Diff line
@@ -408,6 +408,10 @@ struct spdk_nvme_qpair {

	uint8_t					state : 3;

	uint8_t					async: 1;

	uint8_t					is_new_qpair: 1;

	/*
	 * Members for handling IO qpair deletion inside of a completion context.
	 * These are specifically defined as single bits, so that they do not
@@ -1065,7 +1069,7 @@ void nvme_ctrlr_complete_queued_async_events(struct spdk_nvme_ctrlr *ctrlr);
int nvme_qpair_init(struct spdk_nvme_qpair *qpair, uint16_t id,
		    struct spdk_nvme_ctrlr *ctrlr,
		    enum spdk_nvme_qprio qprio,
		    uint32_t num_requests);
		    uint32_t num_requests, bool async);
void	nvme_qpair_deinit(struct spdk_nvme_qpair *qpair);
void	nvme_qpair_complete_error_reqs(struct spdk_nvme_qpair *qpair);
int	nvme_qpair_submit_request(struct spdk_nvme_qpair *qpair,
@@ -1073,7 +1077,6 @@ int nvme_qpair_submit_request(struct spdk_nvme_qpair *qpair,
void	nvme_qpair_abort_reqs(struct spdk_nvme_qpair *qpair, uint32_t dnr);
uint32_t nvme_qpair_abort_queued_reqs(struct spdk_nvme_qpair *qpair, void *cmd_cb_arg);
void	nvme_qpair_resubmit_requests(struct spdk_nvme_qpair *qpair, uint32_t num_requests);

int	nvme_ctrlr_identify_active_ns(struct spdk_nvme_ctrlr *ctrlr);
void	nvme_ns_set_identify_data(struct spdk_nvme_ns *ns);
void	nvme_ns_set_id_desc_list_data(struct spdk_nvme_ns *ns);
@@ -1219,6 +1222,9 @@ static inline void
nvme_qpair_set_state(struct spdk_nvme_qpair *qpair, enum nvme_qpair_state state)
{
	qpair->state = state;
	if (state == NVME_QPAIR_ENABLED) {
		qpair->is_new_qpair = false;
	}
}

static inline enum nvme_qpair_state
+3 −2
Original line number Diff line number Diff line
@@ -268,7 +268,8 @@ nvme_pcie_ctrlr_construct_admin_qpair(struct spdk_nvme_ctrlr *ctrlr, uint16_t nu
			     0, /* qpair ID */
			     ctrlr,
			     SPDK_NVME_QPRIO_URGENT,
			     num_entries);
			     num_entries,
			     false);
	if (rc != 0) {
		return rc;
	}
@@ -1000,7 +1001,7 @@ nvme_pcie_ctrlr_create_io_qpair(struct spdk_nvme_ctrlr *ctrlr, uint16_t qid,

	qpair = &pqpair->qpair;

	rc = nvme_qpair_init(qpair, qid, ctrlr, opts->qprio, opts->io_queue_requests);
	rc = nvme_qpair_init(qpair, qid, ctrlr, opts->qprio, opts->io_queue_requests, opts->async_mode);
	if (rc != 0) {
		nvme_pcie_qpair_destroy(qpair);
		return NULL;
Loading