diff --git a/lib/nvmf/ctrlr.c b/lib/nvmf/ctrlr.c index f80f9f974..0115eae8b 100644 --- a/lib/nvmf/ctrlr.c +++ b/lib/nvmf/ctrlr.c @@ -80,8 +80,8 @@ spdk_nvmf_ctrlr_create(struct spdk_nvmf_subsystem *subsystem, return NULL; } - ctrlr->cntlid = spdk_nvmf_tgt_gen_cntlid(tgt); - if (ctrlr->cntlid == 0) { + ctrlr->cntlid = spdk_nvmf_subsystem_gen_cntlid(subsystem); + if (ctrlr->cntlid == 0xFFFF) { /* Unable to get a cntlid */ SPDK_ERRLOG("Reached max simultaneous ctrlrs\n"); spdk_nvmf_poll_group_destroy(ctrlr->group); diff --git a/lib/nvmf/nvmf.c b/lib/nvmf/nvmf.c index 8d446f4d2..0e67a0253 100644 --- a/lib/nvmf/nvmf.c +++ b/lib/nvmf/nvmf.c @@ -164,48 +164,6 @@ 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; - - /* - * In the worst case, we might have to try all CNTLID values between 1 and 0xFFF0 - 1 - * before we find one that is unused (or find that all values are in use). - */ - count = 0xFFF0 - 1; - do { - tgt->next_cntlid++; - if (tgt->next_cntlid >= 0xFFF0) { - /* The spec reserves cntlid values in the range FFF0h to FFFFh. */ - tgt->next_cntlid = 1; - } - - /* 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 14ecd710f..d5c48b0ce 100644 --- a/lib/nvmf/nvmf_internal.h +++ b/lib/nvmf/nvmf_internal.h @@ -50,7 +50,6 @@ struct spdk_nvmf_tgt { struct spdk_thread *master_thread; - uint16_t next_cntlid; uint64_t discovery_genctr; TAILQ_HEAD(, spdk_nvmf_subsystem) subsystems; struct spdk_nvmf_discovery_log_page *discovery_log_page; @@ -176,6 +175,7 @@ struct spdk_nvmf_subsystem { uint32_t id; char subnqn[SPDK_NVMF_NQN_MAX_LEN + 1]; enum spdk_nvmf_subtype subtype; + uint16_t next_cntlid; bool allow_any_host; struct spdk_nvmf_tgt *tgt; @@ -196,7 +196,6 @@ struct spdk_nvmf_subsystem { TAILQ_ENTRY(spdk_nvmf_subsystem) entries; }; -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); @@ -241,6 +240,7 @@ int spdk_nvmf_bdev_ctrlr_identify_ns(struct spdk_bdev *bdev, struct spdk_nvme_ns int spdk_nvmf_subsystem_bdev_attach(struct spdk_nvmf_subsystem *subsystem); void spdk_nvmf_subsystem_bdev_detach(struct spdk_nvmf_subsystem *subsystem); +uint16_t spdk_nvmf_subsystem_gen_cntlid(struct spdk_nvmf_subsystem *subsystem); static inline struct spdk_nvmf_ns * _spdk_nvmf_subsystem_get_ns(struct spdk_nvmf_subsystem *subsystem, uint32_t nsid) diff --git a/lib/nvmf/subsystem.c b/lib/nvmf/subsystem.c index b813bdac4..dcb03ba1a 100644 --- a/lib/nvmf/subsystem.c +++ b/lib/nvmf/subsystem.c @@ -117,6 +117,7 @@ spdk_nvmf_create_subsystem(struct spdk_nvmf_tgt *tgt, subsystem->subtype = type; subsystem->max_nsid = num_ns; subsystem->num_allocated_nsid = 0; + subsystem->next_cntlid = 0; snprintf(subsystem->subnqn, sizeof(subsystem->subnqn), "%s", nqn); TAILQ_INIT(&subsystem->listeners); TAILQ_INIT(&subsystem->hosts); @@ -495,3 +496,42 @@ spdk_nvmf_subsystem_get_type(struct spdk_nvmf_subsystem *subsystem) { return subsystem->subtype; } + +uint16_t +spdk_nvmf_subsystem_gen_cntlid(struct spdk_nvmf_subsystem *subsystem) +{ + struct spdk_nvmf_ctrlr *ctrlr; + uint16_t count; + bool in_use = true; + + /* + * In the worst case, we might have to try all CNTLID values between 1 and 0xFFF0 - 1 + * before we find one that is unused (or find that all values are in use). + */ + count = 0xFFF0 - 1; + do { + subsystem->next_cntlid++; + if (subsystem->next_cntlid >= 0xFFF0) { + /* The spec reserves cntlid values in the range FFF0h to FFFFh. */ + subsystem->next_cntlid = 1; + } + + /* Check if a controller with this cntlid currently exists. */ + in_use = false; + TAILQ_FOREACH(ctrlr, &subsystem->ctrlrs, link) { + if (ctrlr->cntlid == subsystem->next_cntlid) { + in_use = true; + break; + } + } + + count--; + } while (in_use && count > 0); + + if (count == 0) { + /* All valid cntlid values are in use. */ + return 0xFFFF; + } + + return subsystem->next_cntlid; +} diff --git a/test/unit/lib/nvmf/ctrlr.c/ctrlr_ut.c b/test/unit/lib/nvmf/ctrlr.c/ctrlr_ut.c index 081c69e72..db8706de1 100644 --- a/test/unit/lib/nvmf/ctrlr.c/ctrlr_ut.c +++ b/test/unit/lib/nvmf/ctrlr.c/ctrlr_ut.c @@ -45,12 +45,6 @@ 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) -{ - return 0; -} - const struct spdk_nvme_ctrlr_data * spdk_nvme_ctrlr_get_data(struct spdk_nvme_ctrlr *ctrlr) { @@ -121,6 +115,12 @@ spdk_nvmf_subsystem_get_next_ns(struct spdk_nvmf_subsystem *subsystem, struct sp return NULL; } +uint16_t +spdk_nvmf_subsystem_gen_cntlid(struct spdk_nvmf_subsystem *subsystem) +{ + return 0; +} + bool spdk_nvmf_ctrlr_dsm_supported(struct spdk_nvmf_ctrlr *ctrlr) {