Loading autotest.sh +1 −0 Original line number Diff line number Diff line Loading @@ -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 Loading lib/nvmf/port.c +8 −0 Original line number Diff line number Diff line Loading @@ -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 Loading @@ -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; } Loading Loading @@ -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); Loading lib/nvmf/port.h +5 −0 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -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; }; Loading @@ -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; }; Loading lib/nvmf/request.c +70 −8 Original line number Diff line number Diff line Loading @@ -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) { Loading @@ -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. Loading Loading @@ -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); } Loading lib/nvmf/session.c +52 −2 Original line number Diff line number Diff line Loading @@ -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) Loading Loading @@ -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; Loading Loading @@ -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 Loading
autotest.sh +1 −0 Original line number Diff line number Diff line Loading @@ -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 Loading
lib/nvmf/port.c +8 −0 Original line number Diff line number Diff line Loading @@ -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 Loading @@ -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; } Loading Loading @@ -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); Loading
lib/nvmf/port.h +5 −0 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -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; }; Loading @@ -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; }; Loading
lib/nvmf/request.c +70 −8 Original line number Diff line number Diff line Loading @@ -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) { Loading @@ -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. Loading Loading @@ -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); } Loading
lib/nvmf/session.c +52 −2 Original line number Diff line number Diff line Loading @@ -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) Loading Loading @@ -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; Loading Loading @@ -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