diff --git a/lib/nvmf/ctrlr.c b/lib/nvmf/ctrlr.c index 40a0cc05a4..0c2233636b 100644 --- a/lib/nvmf/ctrlr.c +++ b/lib/nvmf/ctrlr.c @@ -57,8 +57,6 @@ */ #define FW_VERSION SPDK_VERSION_MAJOR_STRING SPDK_VERSION_MINOR_STRING SPDK_VERSION_PATCH_STRING -static uint16_t spdk_nvmf_ctrlr_gen_cntlid(void); - static struct spdk_nvmf_ctrlr * spdk_nvmf_ctrlr_create(struct spdk_nvmf_subsystem *subsystem, struct spdk_nvmf_qpair *admin_qpair, @@ -83,7 +81,7 @@ spdk_nvmf_ctrlr_create(struct spdk_nvmf_subsystem *subsystem, return NULL; } - ctrlr->cntlid = spdk_nvmf_ctrlr_gen_cntlid(); + ctrlr->cntlid = spdk_nvmf_tgt_gen_cntlid(tgt); if (ctrlr->cntlid == 0) { /* Unable to get a cntlid */ SPDK_ERRLOG("Reached max simultaneous ctrlrs\n"); @@ -167,44 +165,6 @@ invalid_connect_response(struct spdk_nvmf_fabric_connect_rsp *rsp, uint8_t iattr rsp->status_code_specific.invalid.ipo = ipo; } -static uint16_t -spdk_nvmf_ctrlr_gen_cntlid(void) -{ - static uint16_t cntlid = 0; /* cntlid is static, so its value is preserved */ - struct spdk_nvmf_subsystem *subsystem; - uint16_t count; - - count = UINT16_MAX - 1; - do { - /* cntlid is an unsigned 16-bit integer, so let it overflow - * back to 0 if necessary. - */ - cntlid++; - if (cntlid == 0) { - /* 0 is not a valid cntlid because it is the reserved value in the RDMA - * private data for cntlid. This is the value sent by pre-NVMe-oF 1.1 - * initiators. - */ - cntlid++; - } - - /* Check if a subsystem with this cntlid currently exists. This could - * happen for a very long-lived ctrlr on a target with many short-lived - * ctrlrs, where cntlid wraps around. - */ - subsystem = spdk_nvmf_find_subsystem_with_cntlid(cntlid); - - count--; - - } while (subsystem != NULL && count > 0); - - if (count == 0) { - return 0; - } - - return cntlid; -} - void spdk_nvmf_ctrlr_connect(struct spdk_nvmf_qpair *qpair, struct spdk_nvmf_fabric_connect_cmd *cmd, diff --git a/lib/nvmf/nvmf.c b/lib/nvmf/nvmf.c index deeee8c38f..ab5524d1f8 100644 --- a/lib/nvmf/nvmf.c +++ b/lib/nvmf/nvmf.c @@ -39,6 +39,7 @@ #include "spdk_internal/log.h" +#include "ctrlr.h" #include "subsystem.h" #include "transport.h" @@ -173,6 +174,50 @@ spdk_nvmf_tgt_find_subsystem(struct spdk_nvmf_tgt *tgt, const char *subnqn) return NULL; } +uint16_t +spdk_nvmf_tgt_gen_cntlid(struct spdk_nvmf_tgt *tgt) +{ + struct spdk_nvmf_subsystem *subsystem; + struct spdk_nvmf_ctrlr *ctrlr; + uint16_t count; + + count = UINT16_MAX - 1; + do { + /* cntlid is an unsigned 16-bit integer, so let it overflow + * back to 0 if necessary. + */ + tgt->next_cntlid++; + if (tgt->next_cntlid == 0) { + /* 0 is not a valid cntlid because it is the reserved value in the RDMA + * private data for cntlid. This is the value sent by pre-NVMe-oF 1.1 + * initiators. + */ + tgt->next_cntlid++; + } + + /* Check if a subsystem with this cntlid currently exists. This could + * happen for a very long-lived ctrlr on a target with many short-lived + * ctrlrs, where cntlid wraps around. + */ + TAILQ_FOREACH(subsystem, &tgt->subsystems, entries) { + TAILQ_FOREACH(ctrlr, &subsystem->ctrlrs, link) { + if (ctrlr->cntlid == tgt->next_cntlid) { + break; + } + } + } + + count--; + + } while (subsystem != NULL && count > 0); + + if (count == 0) { + return 0; + } + + return tgt->next_cntlid; +} + struct spdk_nvmf_transport * spdk_nvmf_tgt_get_transport(struct spdk_nvmf_tgt *tgt, enum spdk_nvme_transport_type type) { diff --git a/lib/nvmf/nvmf_internal.h b/lib/nvmf/nvmf_internal.h index a32b61bf3e..0f6d6396b0 100644 --- a/lib/nvmf/nvmf_internal.h +++ b/lib/nvmf/nvmf_internal.h @@ -48,6 +48,7 @@ struct spdk_nvmf_tgt { struct spdk_nvmf_tgt_opts opts; + uint16_t next_cntlid; uint64_t discovery_genctr; TAILQ_HEAD(, spdk_nvmf_subsystem) subsystems; struct spdk_nvmf_discovery_log_page *discovery_log_page; @@ -113,6 +114,8 @@ extern struct spdk_nvmf_tgt g_nvmf_tgt; struct spdk_nvmf_listen_addr *spdk_nvmf_listen_addr_create(struct spdk_nvme_transport_id *trid); void spdk_nvmf_listen_addr_destroy(struct spdk_nvmf_listen_addr *addr); +uint16_t spdk_nvmf_tgt_gen_cntlid(struct spdk_nvmf_tgt *tgt); + struct spdk_nvmf_transport *spdk_nvmf_tgt_get_transport(struct spdk_nvmf_tgt *tgt, enum spdk_nvme_transport_type); diff --git a/lib/nvmf/subsystem.c b/lib/nvmf/subsystem.c index d035873519..0afe879bc7 100644 --- a/lib/nvmf/subsystem.c +++ b/lib/nvmf/subsystem.c @@ -46,23 +46,6 @@ #include "spdk_internal/bdev.h" #include "spdk_internal/log.h" -struct spdk_nvmf_subsystem * -spdk_nvmf_find_subsystem_with_cntlid(uint16_t cntlid) -{ - struct spdk_nvmf_subsystem *subsystem; - struct spdk_nvmf_ctrlr *ctrlr; - - TAILQ_FOREACH(subsystem, &g_nvmf_tgt.subsystems, entries) { - TAILQ_FOREACH(ctrlr, &subsystem->ctrlrs, link) { - if (ctrlr->cntlid == cntlid) { - return subsystem; - } - } - } - - return NULL; -} - int spdk_nvmf_subsystem_start(struct spdk_nvmf_subsystem *subsystem) { diff --git a/lib/nvmf/subsystem.h b/lib/nvmf/subsystem.h index dbf7b1d815..248b45f20a 100644 --- a/lib/nvmf/subsystem.h +++ b/lib/nvmf/subsystem.h @@ -39,8 +39,6 @@ #include "spdk/nvme.h" #include "spdk/nvmf.h" -struct spdk_nvmf_subsystem *spdk_nvmf_find_subsystem_with_cntlid(uint16_t cntlid); - void spdk_nvmf_get_discovery_log_page(struct spdk_nvmf_tgt *tgt, void *buffer, uint64_t offset, uint32_t length); diff --git a/test/unit/lib/nvmf/ctrlr.c/ctrlr_ut.c b/test/unit/lib/nvmf/ctrlr.c/ctrlr_ut.c index 2300846d2c..af53c51baf 100644 --- a/test/unit/lib/nvmf/ctrlr.c/ctrlr_ut.c +++ b/test/unit/lib/nvmf/ctrlr.c/ctrlr_ut.c @@ -42,15 +42,15 @@ SPDK_LOG_REGISTER_TRACE_FLAG("nvmf", SPDK_TRACE_NVMF) struct spdk_nvmf_tgt g_nvmf_tgt; struct spdk_nvmf_subsystem * -spdk_nvmf_find_subsystem_with_cntlid(uint16_t cntlid) +spdk_nvmf_tgt_find_subsystem(struct spdk_nvmf_tgt *tgt, const char *subnqn) { return NULL; } -struct spdk_nvmf_subsystem * -spdk_nvmf_tgt_find_subsystem(struct spdk_nvmf_tgt *tgt, const char *subnqn) +uint16_t +spdk_nvmf_tgt_gen_cntlid(struct spdk_nvmf_tgt *tgt) { - return NULL; + return 0; } const struct spdk_nvme_ctrlr_data *