[PATCH 2/4] nvmet: make cntlid ida per subsystem

Max Gurtovoy mgurtovoy at nvidia.com
Wed Sep 24 13:26:02 PDT 2025


Commit 15fbad96fc5f ("nvmet: Make cntlid globally unique") moved the
cntlid ida allocator to global scope. This worked until commit
94a39d61f80f ("nvmet: make ctrl-id configurable") introduced subsystem
specific cntlid_min and cntlid_max configfs attributes.
Since controller ID ranges are now per subsystem, the ida should also be
per subsystem. Fix that to ensure controller IDs are managed correctly
per subsystem.

Signed-off-by: Max Gurtovoy <mgurtovoy at nvidia.com>
---
 drivers/nvme/target/core.c  | 10 +++++-----
 drivers/nvme/target/nvmet.h |  1 +
 2 files changed, 6 insertions(+), 5 deletions(-)

diff --git a/drivers/nvme/target/core.c b/drivers/nvme/target/core.c
index 20e7b3d6a810..b0bdb20132ab 100644
--- a/drivers/nvme/target/core.c
+++ b/drivers/nvme/target/core.c
@@ -22,7 +22,6 @@ struct kmem_cache *nvmet_bvec_cache;
 struct workqueue_struct *buffered_io_wq;
 struct workqueue_struct *zbd_wq;
 static LIST_HEAD(nvmet_transports);
-static DEFINE_IDA(cntlid_ida);
 
 struct workqueue_struct *nvmet_wq;
 EXPORT_SYMBOL_GPL(nvmet_wq);
@@ -1684,7 +1683,7 @@ struct nvmet_ctrl *nvmet_alloc_ctrl(struct nvmet_alloc_ctrl_args *args)
 	if (!ctrl->cqs)
 		goto out_free_sqs;
 
-	ret = ida_alloc_range(&cntlid_ida,
+	ret = ida_alloc_range(&subsys->cntlid_ida,
 			     subsys->cntlid_min, subsys->cntlid_max,
 			     GFP_KERNEL);
 	if (ret < 0) {
@@ -1747,7 +1746,7 @@ struct nvmet_ctrl *nvmet_alloc_ctrl(struct nvmet_alloc_ctrl_args *args)
 init_pr_fail:
 	mutex_unlock(&subsys->lock);
 	nvmet_stop_keep_alive_timer(ctrl);
-	ida_free(&cntlid_ida, ctrl->cntlid);
+	ida_free(&subsys->cntlid_ida, ctrl->cntlid);
 out_free_cqs:
 	kfree(ctrl->cqs);
 out_free_sqs:
@@ -1782,7 +1781,7 @@ static void nvmet_ctrl_free(struct kref *ref)
 
 	nvmet_debugfs_ctrl_free(ctrl);
 
-	ida_free(&cntlid_ida, ctrl->cntlid);
+	ida_free(&subsys->cntlid_ida, ctrl->cntlid);
 
 	nvmet_async_events_free(ctrl);
 	kfree(ctrl->sqs);
@@ -1911,6 +1910,7 @@ struct nvmet_subsys *nvmet_subsys_alloc(const char *subsysnqn,
 	xa_init(&subsys->namespaces);
 	INIT_LIST_HEAD(&subsys->ctrls);
 	INIT_LIST_HEAD(&subsys->hosts);
+	ida_init(&subsys->cntlid_ida);
 
 	ret = nvmet_debugfs_subsys_setup(subsys);
 	if (ret)
@@ -1940,6 +1940,7 @@ static void nvmet_subsys_free(struct kref *ref)
 
 	nvmet_debugfs_subsys_free(subsys);
 
+	ida_destroy(&subsys->cntlid_ida);
 	xa_destroy(&subsys->namespaces);
 	nvmet_passthru_subsys_free(subsys);
 
@@ -2024,7 +2025,6 @@ static void __exit nvmet_exit(void)
 	nvmet_exit_configfs();
 	nvmet_exit_discovery();
 	nvmet_exit_debugfs();
-	ida_destroy(&cntlid_ida);
 	destroy_workqueue(nvmet_wq);
 	destroy_workqueue(buffered_io_wq);
 	destroy_workqueue(zbd_wq);
diff --git a/drivers/nvme/target/nvmet.h b/drivers/nvme/target/nvmet.h
index e5a4571199aa..9245fe4f6cae 100644
--- a/drivers/nvme/target/nvmet.h
+++ b/drivers/nvme/target/nvmet.h
@@ -322,6 +322,7 @@ struct nvmet_subsys {
 	u32			max_nsid;
 	u16			cntlid_min;
 	u16			cntlid_max;
+	struct ida		cntlid_ida;
 
 	struct list_head	ctrls;
 
-- 
2.18.1




More information about the Linux-nvme mailing list