[PATCH RFC 06/11] nvmet: Allow nvmet_alloc_ctrl users to specify the cntlid

Mike Christie
2025-03-13T05:24:49Z

For the configfs controller interface we will want to pass in the
cntlid from userspace. This modifies nvmet_alloc_ctrl so the caller
can pass in the cntlid or allow nvmet code to allocate it like it does
today for dynamic controllers.

Signed-off-by: Mike Christie <michael.christie@oracle.com>
---
drivers/nvme/target/core.c | 9 ++++++---
drivers/nvme/target/fabrics-cmd.c | 1 +
drivers/nvme/target/nvmet.h | 3 +++
drivers/nvme/target/pci-epf.c | 1 +
4 files changed, 11 insertions(+), 3 deletions(-)

diff --git a/drivers/nvme/target/core.c b/drivers/nvme/target/core.c
index 06967c00e9a2..f587ec410023 100644
--- a/drivers/nvme/target/core.c
+++ b/drivers/nvme/target/core.c
@@ -1621,9 +1621,12 @@ struct nvmet_ctrl *nvmet_alloc_ctrl(struct nvmet_alloc_ctrl_args *args)
if (!ctrl->sqs)
goto out_free_changed_ns_list;

- ret = ida_alloc_range(&cntlid_ida,
- subsys->cntlid_min, subsys->cntlid_max,
- GFP_KERNEL);
+ if (args->cntlid == NVMET_MAX_CNTLID)
+ ret = ida_alloc_range(&cntlid_ida, subsys->cntlid_min,
+ subsys->cntlid_max, GFP_KERNEL);
+ else
+ ret = ida_alloc_range(&cntlid_ida, args->cntlid, args->cntlid,
+ GFP_KERNEL);
if (ret < 0) {
args->status = NVME_SC_CONNECT_CTRL_BUSY | NVME_STATUS_DNR;
goto out_free_sqs;
diff --git a/drivers/nvme/target/fabrics-cmd.c b/drivers/nvme/target/fabrics-cmd.c
index eb406c90c167..b26e60d41e8c 100644
--- a/drivers/nvme/target/fabrics-cmd.c
+++ b/drivers/nvme/target/fabrics-cmd.c
@@ -288,6 +288,7 @@ static void nvmet_execute_admin_connect(struct nvmet_req *req)
args.hostnqn = d->hostnqn;
args.hostid = &d->hostid;
args.kato = le32_to_cpu(c->kato);
+ args.cntlid = NVMET_MAX_CNTLID;

ctrl = nvmet_alloc_ctrl(&args);
if (!ctrl)
diff --git a/drivers/nvme/target/nvmet.h b/drivers/nvme/target/nvmet.h
index 052ea4a105fc..990dd43df5c9 100644
--- a/drivers/nvme/target/nvmet.h
+++ b/drivers/nvme/target/nvmet.h
@@ -582,6 +582,8 @@ void nvmet_ctrl_fatal_error(struct nvmet_ctrl *ctrl);

void nvmet_update_cc(struct nvmet_ctrl *ctrl, u32 new);

+#define NVMET_MAX_CNTLID 0xFFF0
+
struct nvmet_alloc_ctrl_args {
struct nvmet_port *port;
char *subsysnqn;
@@ -590,6 +592,7 @@ struct nvmet_alloc_ctrl_args {
const struct nvmet_fabrics_ops *ops;
struct device *p2p_client;
u32 kato;
+ u16 cntlid;
__le32 result;
u16 error_loc;
u16 status;
diff --git a/drivers/nvme/target/pci-epf.c b/drivers/nvme/target/pci-epf.c
index 565d2bd36dcd..b0e14e8aae7b 100644
--- a/drivers/nvme/target/pci-epf.c
+++ b/drivers/nvme/target/pci-epf.c
@@ -2031,6 +2031,7 @@ static int nvmet_pci_epf_create_ctrl(struct nvmet_pci_epf *nvme_epf,
args.hostid = &id;
args.hostnqn = hostnqn;
args.ops = &nvmet_pci_epf_fabrics_ops;
+ args.cntlid = NVMET_MAX_CNTLID;

ctrl->tctrl = nvmet_alloc_ctrl(&args);
if (!ctrl->tctrl) {
--
2.43.0