Commit 1d260441 authored by Daniel Verkamp's avatar Daniel Verkamp
Browse files

nvme/rdma: factor out Connect command



This is a generic NVMe-oF command that may be used for other transports.

Change-Id: Id5fbf1f176ef5f75a221b40eff538e693817bcaf
Signed-off-by: default avatarDaniel Verkamp <daniel.verkamp@intel.com>
Reviewed-on: https://review.gerrithub.io/416578


Tested-by: default avatarSPDK Automated Test System <sys_sgsw@intel.com>
Reviewed-by: default avatarBen Walker <benjamin.walker@intel.com>
Reviewed-by: default avatarChangpeng Liu <changpeng.liu@intel.com>
Reviewed-by: default avatarShuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com>
parent 9f5fb75d
Loading
Loading
Loading
Loading
+70 −0
Original line number Diff line number Diff line
@@ -268,3 +268,73 @@ nvme_fabric_ctrlr_discover(struct spdk_nvme_ctrlr *ctrlr,

	return 0;
}

int
nvme_fabric_qpair_connect(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;
	int rc;

	if (num_entries == 0 || num_entries > SPDK_NVME_IO_QUEUE_MAX_ENTRIES) {
		return -EINVAL;
	}

	ctrlr = qpair->ctrlr;
	if (!ctrlr) {
		return -EINVAL;
	}

	nvmf_data = spdk_dma_zmalloc(sizeof(*nvmf_data), 0, NULL);
	if (!nvmf_data) {
		SPDK_ERRLOG("nvmf_data allocation error\n");
		return -ENOMEM;
	}

	memset(&cmd, 0, sizeof(cmd));
	cmd.opcode = SPDK_NVME_OPC_FABRIC;
	cmd.fctype = SPDK_NVMF_FABRIC_COMMAND_CONNECT;
	cmd.qid = qpair->id;
	cmd.sqsize = num_entries - 1;
	cmd.kato = ctrlr->opts.keep_alive_timeout_ms;

	if (nvme_qpair_is_admin_queue(qpair)) {
		nvmf_data->cntlid = 0xFFFF;
	} else {
		nvmf_data->cntlid = ctrlr->cntlid;
	}

	SPDK_STATIC_ASSERT(sizeof(nvmf_data->hostid) == sizeof(ctrlr->opts.extended_host_id),
			   "host ID size mismatch");
	memcpy(nvmf_data->hostid, ctrlr->opts.extended_host_id, sizeof(nvmf_data->hostid));
	snprintf(nvmf_data->hostnqn, sizeof(nvmf_data->hostnqn), "%s", ctrlr->opts.hostnqn);
	snprintf(nvmf_data->subnqn, sizeof(nvmf_data->subnqn), "%s", ctrlr->trid.subnqn);

	rc = spdk_nvme_ctrlr_cmd_io_raw(ctrlr, qpair,
					(struct spdk_nvme_cmd *)&cmd,
					nvmf_data, sizeof(*nvmf_data),
					nvme_completion_poll_cb, &status);
	if (rc < 0) {
		SPDK_ERRLOG("Connect command failed\n");
		spdk_dma_free(nvmf_data);
		return rc;
	}

	if (spdk_nvme_wait_for_completion(qpair, &status)) {
		SPDK_ERRLOG("Connect command failed\n");
		spdk_dma_free(nvmf_data);
		return -EIO;
	}

	if (nvme_qpair_is_admin_queue(qpair)) {
		rsp = (struct spdk_nvmf_fabric_connect_rsp *)&status.cpl;
		ctrlr->cntlid = rsp->status_code_specific.success.cntlid;
		SPDK_DEBUGLOG(SPDK_LOG_NVME, "CNTLID 0x%04" PRIx16 "\n", ctrlr->cntlid);
	}

	spdk_dma_free(nvmf_data);
	return 0;
}
+1 −0
Original line number Diff line number Diff line
@@ -688,6 +688,7 @@ int nvme_fabric_ctrlr_get_reg_4(struct spdk_nvme_ctrlr *ctrlr, uint32_t offset,
int	nvme_fabric_ctrlr_get_reg_8(struct spdk_nvme_ctrlr *ctrlr, uint32_t offset, uint64_t *value);
int	nvme_fabric_ctrlr_discover(struct spdk_nvme_ctrlr *ctrlr, void *cb_ctx,
				   spdk_nvme_probe_cb probe_cb);
int	nvme_fabric_qpair_connect(struct spdk_nvme_qpair *qpair, uint32_t num_entries);

static inline struct nvme_request *
nvme_allocate_request(struct spdk_nvme_qpair *qpair,
+1 −68
Original line number Diff line number Diff line
@@ -595,73 +595,6 @@ nvme_rdma_parse_addr(struct sockaddr_storage *sa, int family, const char *addr,
	return ret;
}

static int
nvme_rdma_qpair_fabric_connect(struct nvme_rdma_qpair *rqpair)
{
	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;
	int rc = 0;

	ctrlr = rqpair->qpair.ctrlr;
	if (!ctrlr) {
		return -1;
	}

	nvmf_data = spdk_dma_zmalloc(sizeof(*nvmf_data), 0, NULL);
	if (!nvmf_data) {
		SPDK_ERRLOG("nvmf_data allocation error\n");
		rc = -1;
		return rc;
	}

	memset(&cmd, 0, sizeof(cmd));

	cmd.opcode = SPDK_NVME_OPC_FABRIC;
	cmd.fctype = SPDK_NVMF_FABRIC_COMMAND_CONNECT;
	cmd.qid = rqpair->qpair.id;
	cmd.sqsize = rqpair->num_entries - 1;
	cmd.kato = ctrlr->opts.keep_alive_timeout_ms;

	if (nvme_qpair_is_admin_queue(&rqpair->qpair)) {
		nvmf_data->cntlid = 0xFFFF;
	} else {
		nvmf_data->cntlid = ctrlr->cntlid;
	}

	SPDK_STATIC_ASSERT(sizeof(nvmf_data->hostid) == sizeof(ctrlr->opts.extended_host_id),
			   "host ID size mismatch");
	memcpy(nvmf_data->hostid, ctrlr->opts.extended_host_id, sizeof(nvmf_data->hostid));
	snprintf(nvmf_data->hostnqn, sizeof(nvmf_data->hostnqn), "%s", ctrlr->opts.hostnqn);
	snprintf(nvmf_data->subnqn, sizeof(nvmf_data->subnqn), "%s", ctrlr->trid.subnqn);

	rc = spdk_nvme_ctrlr_cmd_io_raw(ctrlr, &rqpair->qpair,
					(struct spdk_nvme_cmd *)&cmd,
					nvmf_data, sizeof(*nvmf_data),
					nvme_completion_poll_cb, &status);
	if (rc < 0) {
		SPDK_ERRLOG("spdk_nvme_rdma_req_fabric_connect failed\n");
		rc = -1;
		goto ret;
	}

	if (spdk_nvme_wait_for_completion(&rqpair->qpair, &status)) {
		SPDK_ERRLOG("Connect command failed\n");
		return -1;
	}

	if (nvme_qpair_is_admin_queue(&rqpair->qpair)) {
		rsp = (struct spdk_nvmf_fabric_connect_rsp *)&status.cpl;
		ctrlr->cntlid = rsp->status_code_specific.success.cntlid;
		SPDK_DEBUGLOG(SPDK_LOG_NVME, "CNTLID 0x%04" PRIx16 "\n", ctrlr->cntlid);
	}
ret:
	spdk_dma_free(nvmf_data);
	return rc;
}

static int
nvme_rdma_mr_map_notify(void *cb_ctx, struct spdk_mem_map *map,
			enum spdk_mem_map_notify_action action,
@@ -868,7 +801,7 @@ nvme_rdma_qpair_connect(struct nvme_rdma_qpair *rqpair)
		return -1;
	}

	rc = nvme_rdma_qpair_fabric_connect(rqpair);
	rc = nvme_fabric_qpair_connect(&rqpair->qpair, rqpair->num_entries);
	if (rc < 0) {
		SPDK_ERRLOG("Failed to send an NVMe-oF Fabric CONNECT command\n");
		return -1;