Commit 4fbe54f1 authored by Changpeng Liu's avatar Changpeng Liu Committed by Daniel Verkamp
Browse files

nvmf: add discovery subsystem to NVMf target



Change-Id: I4ee79ad268ae75208feddd62e22d6210a9c0d944
Signed-off-by: default avatarChangpeng Liu <changpeng.liu@intel.com>
parent 771d2c1a
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -59,6 +59,7 @@ timing_enter nvmf

time test/nvmf/fio/fio.sh
time test/nvmf/filesystem/filesystem.sh
time test/nvmf/discovery/discovery.sh

timing_exit nvmf

+8 −0
Original line number Diff line number Diff line
@@ -39,6 +39,7 @@
#include "port.h"
#include "spdk/log.h"
#include "spdk/trace.h"
#include "spdk/nvmf_spec.h"

#define MAX_FABRIC_INTF_PER_PORT 4
#define MAX_PORTS 4
@@ -65,6 +66,9 @@ spdk_nvmf_fabric_intf_create(char *host, char *sin_port)

	fabric_intf->host = host;
	fabric_intf->sin_port = sin_port;
	fabric_intf->trtype = SPDK_NVMF_TRANS_RDMA;
	fabric_intf->adrfam = SPDK_NVMF_ADDR_FAMILY_IPV4;
	fabric_intf->treq = SPDK_NVMF_TREQ_NOT_SPECIFIED;

	return fabric_intf;
}
@@ -132,6 +136,10 @@ spdk_nvmf_port_create(int tag)
	port->state = GROUP_INIT;
	port->tag = tag;
	port->type = FABRIC_RDMA;
	port->rdma.rdma_qptype = SPDK_NVMF_QP_TYPE_RELIABLE_CONNECTED;
	/* No provider specified */
	port->rdma.rdma_prtype = SPDK_NVMF_RDMA_NO_PROVIDER;
	port->rdma.rdma_cms = SPDK_NVMF_RDMA_CMS_RDMA_CM;

	TAILQ_INIT(&port->head);

+5 −0
Original line number Diff line number Diff line
@@ -38,6 +38,7 @@

#include "spdk/conf.h"
#include "spdk/queue.h"
#include "spdk/nvmf_spec.h"

/** \file
* An NVMf subsystem port, referred to as simply "port" is defined by the
@@ -65,6 +66,9 @@ struct spdk_nvmf_fabric_intf {
	char					*host;
	char					*sin_port;
	struct spdk_nvmf_port			*port;
	enum spdk_nvmf_transport_types		trtype;
	enum spdk_nvmf_address_family_types	adrfam;
	enum spdk_nvmf_transport_requirements	treq;
	uint32_t				num_sessions;
	TAILQ_ENTRY(spdk_nvmf_fabric_intf)	tailq;
};
@@ -73,6 +77,7 @@ struct spdk_nvmf_port {
	int tag;
	enum group_state state;
	enum fabric_type type;
	struct spdk_nvmf_rdma_transport_specific_address rdma;
	TAILQ_HEAD(, spdk_nvmf_fabric_intf)	head;
	TAILQ_ENTRY(spdk_nvmf_port)		tailq;
};
+70 −8
Original line number Diff line number Diff line
@@ -91,6 +91,64 @@ spdk_nvmf_request_release(struct spdk_nvmf_request *req)
	return spdk_nvmf_rdma_request_release(req->conn, req);
}

static bool
nvmf_process_discovery_cmd(struct spdk_nvmf_request *req)
{
	struct nvmf_session *session = req->conn->sess;
	struct spdk_nvme_cmd *cmd = &req->cmd->nvme_cmd;
	struct spdk_nvme_cpl *response = &req->rsp->nvme_cpl;
	struct spdk_nvmf_discovery_log_page *log;

	/* pre-set response details for this command */
	response->status.sc = SPDK_NVME_SC_SUCCESS;
	response->cid = cmd->cid;

	if (req->data == NULL) {
		SPDK_ERRLOG("discovery command with no buffer\n");
		response->status.sc = SPDK_NVME_SC_INVALID_FIELD;
		return true;
	}

	switch (cmd->opc) {
	case SPDK_NVME_OPC_IDENTIFY:
		/* Only identify controller can be supported */
		if (cmd->cdw10 == 1) {
			/* identify controller */
			SPDK_TRACELOG(SPDK_TRACE_NVMF, "Identify Controller\n");
			memcpy(req->data, (char *)&session->vcdata, sizeof(struct spdk_nvme_ctrlr_data));
			return true;
		} else {
			SPDK_ERRLOG("Unsupported identify command\n");
			response->status.sc = SPDK_NVME_SC_INVALID_FIELD;
			return true;
		}
		break;
	case SPDK_NVME_OPC_GET_LOG_PAGE:
		if ((cmd->cdw10 & 0xFF) == SPDK_NVME_LOG_DISCOVERY) {
			log = (struct spdk_nvmf_discovery_log_page *)req->data;
			/*
			 * Does not support change discovery
			 *  information at runtime now.
			 */
			log->genctr = 0;
			log->numrec = 0;
			spdk_format_discovery_log(log, req->length);
			return true;
		} else {
			SPDK_ERRLOG("Unsupported log page %u\n", cmd->cdw10 & 0xFF);
			response->status.sc = SPDK_NVME_SC_INVALID_FIELD;
			return true;
		}
		break;
	default:
		SPDK_ERRLOG("Unsupported Opcode 0x%x for Discovery service\n", cmd->opc);
		response->status.sc = SPDK_NVME_SC_INVALID_FIELD;
		return true;
	}

	return true;
}

static bool
nvmf_process_admin_cmd(struct spdk_nvmf_request *req)
{
@@ -107,13 +165,6 @@ nvmf_process_admin_cmd(struct spdk_nvmf_request *req)
	response->status.sc = SPDK_NVME_SC_SUCCESS;
	response->cid = cmd->cid;

	/* verify subsystem */
	if (subsystem == NULL) {
		SPDK_TRACELOG(SPDK_TRACE_NVMF, "Subsystem Not Initialized!\n");
		response->status.sc = SPDK_NVME_SC_INTERNAL_DEVICE_ERROR;
		return true;
	}

	if (cmd->nsid == 0) {
		/* may be valid for the requested command. but need
		   to at least map to a known valid controller.
@@ -653,7 +704,18 @@ spdk_nvmf_request_exec(struct spdk_nvmf_request *req)
	if (cmd->opc == SPDK_NVME_OPC_FABRIC) {
		done = nvmf_process_fabrics_command(req);
	} else if (req->conn->type == CONN_TYPE_AQ) {
		struct nvmf_session *session;
		struct spdk_nvmf_subsystem *subsystem;

		session = req->conn->sess;
		RTE_VERIFY(session != NULL);
		subsystem = session->subsys;
		RTE_VERIFY(subsystem != NULL);
		if (subsystem->subtype == SPDK_NVMF_SUB_DISCOVERY) {
			done = nvmf_process_discovery_cmd(req);
		} else {
			done = nvmf_process_admin_cmd(req);
		}
	} else {
		done = nvmf_process_io_cmd(req);
	}
+52 −2
Original line number Diff line number Diff line
@@ -38,6 +38,7 @@
#include "subsystem_grp.h"
#include "spdk/log.h"
#include "spdk/trace.h"
#include "spdk/nvme_spec.h"

static struct nvmf_session *
nvmf_create_session(const char *subnqn)
@@ -81,8 +82,47 @@ nvmf_delete_session(struct nvmf_session *session)
	free(session);
}

void
nvmf_init_session_properties(struct nvmf_session *session, int aq_depth)
static void
nvmf_init_discovery_session_properties(struct nvmf_session *session)
{
	struct spdk_nvmf_extended_identify_ctrlr_data *nvmfdata;

	session->vcdata.maxcmd = SPDK_NVMF_DEFAULT_MAX_QUEUE_DEPTH;
	/* extended data for get log page supportted */
	session->vcdata.lpa.edlp = 1;
	/* reset cntlid in vcdata to match the logical cntlid known to NVMf */
	session->vcdata.cntlid = session->cntlid;
	nvmfdata = (struct spdk_nvmf_extended_identify_ctrlr_data *)session->vcdata.nvmf_specific;
	nvmfdata->ioccsz = (NVMF_H2C_MAX_MSG / 16);
	nvmfdata->iorcsz = (NVMF_C2H_MAX_MSG / 16);
	nvmfdata->icdoff = 0; /* offset starts directly after SQE */
	nvmfdata->ctrattr = 0; /* dynamic controller model */
	nvmfdata->msdbd = 1; /* target supports single SGL in capsule */
	session->vcdata.sgls.keyed_sgl = 1;
	session->vcdata.sgls.sgl_offset = 1;

	/* Properties */
	session->vcprop.cap_lo.raw = 0;
	session->vcprop.cap_lo.bits.cqr = 1;	/* NVMF specification required */
	session->vcprop.cap_lo.bits.mqes = (session->vcdata.maxcmd - 1);	/* max queue depth */
	session->vcprop.cap_lo.bits.ams = 0;	/* optional arb mechanisms */

	session->vcprop.cap_hi.raw = 0;
	session->vcprop.cap_hi.bits.dstrd = 0;	/* fixed to 0 for NVMf */
	session->vcprop.cap_hi.bits.css_nvm = 1; /* NVM command set */
	session->vcprop.cap_hi.bits.mpsmin = 0; /* 2 ^ 12 + mpsmin == 4k */
	session->vcprop.cap_hi.bits.mpsmax = 0; /* 2 ^ 12 + mpsmax == 4k */

	session->vcprop.vs = 0x10000;	/* Version Supported: Major 1, Minor 0 */

	session->vcprop.cc.raw = 0;

	session->vcprop.csts.raw = 0;
	session->vcprop.csts.bits.rdy = 0; /* Init controller as not ready */
}

static void
nvmf_init_nvme_session_properties(struct nvmf_session *session, int aq_depth)
{
	/* for now base virtual controller properties on first namespace controller */
	struct spdk_nvme_ctrlr *ctrlr = session->subsys->ns_list_map[0].ctrlr;
@@ -191,6 +231,16 @@ nvmf_init_session_properties(struct nvmf_session *session, int aq_depth)
		      session->vcprop.capattr_hi.raw);
}

void
nvmf_init_session_properties(struct nvmf_session *session, int aq_depth)
{
	if (session->subsys->subtype == SPDK_NVMF_SUB_NVME) {
		nvmf_init_nvme_session_properties(session, aq_depth);
	} else {
		nvmf_init_discovery_session_properties(session);
	}
}

static struct nvmf_session *
nvmf_find_session_by_id(const char *subnqn, uint16_t cntl_id)
{
Loading