* [PATCH-RFC 0/5] nvme: fix initialization memleak
@ 2024-06-03 23:05 Keith Busch
2024-06-03 23:05 ` [PATCH-RFC 1/5] nvme: apple: fix device reference counting Keith Busch
` (6 more replies)
0 siblings, 7 replies; 13+ messages in thread
From: Keith Busch @ 2024-06-03 23:05 UTC (permalink / raw)
To: linux-nvme; +Cc: hch, sagi, mlombard, hare, shinichiro.kawasaki, Keith Busch
From: Keith Busch <kbusch@kernel.org>
The pci driver is the only one runtime tested. Everything else is
compile tested, except for apple.
Keith Busch (5):
nvme: apple: fix device reference counting
nvme: tcp: split controller bringup handling
nvme: rdma: split controller bringup handling
nvme: fc: split controller bringup handling
nvme: split device add from initialzation
drivers/nvme/host/apple.c | 31 ++++++++++++++++----
drivers/nvme/host/core.c | 58 +++++++++++++++++++++++---------------
drivers/nvme/host/fc.c | 48 ++++++++++++++++++++-----------
drivers/nvme/host/nvme.h | 1 +
drivers/nvme/host/pci.c | 5 ++++
drivers/nvme/host/rdma.c | 33 +++++++++++++++++-----
drivers/nvme/host/tcp.c | 30 ++++++++++++++++----
drivers/nvme/target/loop.c | 5 ++++
8 files changed, 154 insertions(+), 57 deletions(-)
--
2.43.0
^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH-RFC 1/5] nvme: apple: fix device reference counting
2024-06-03 23:05 [PATCH-RFC 0/5] nvme: fix initialization memleak Keith Busch
@ 2024-06-03 23:05 ` Keith Busch
2024-06-03 23:17 ` Keith Busch
2024-06-03 23:05 ` [PATCH-RFC 2/5] nvme: tcp: split controller bringup handling Keith Busch
` (5 subsequent siblings)
6 siblings, 1 reply; 13+ messages in thread
From: Keith Busch @ 2024-06-03 23:05 UTC (permalink / raw)
To: linux-nvme; +Cc: hch, sagi, mlombard, hare, shinichiro.kawasaki, Keith Busch
From: Keith Busch <kbusch@kernel.org>
Drivers must call nvme_uninit_ctrl after a successful nvme_init_ctrl.
Split the allocation side out to make the error handling boundary easier
to navigate. The apple driver had been doing this wrong, leaking the
controller device memory on a tagset failure.
Signed-off-by: Keith Busch <kbusch@kernel.org>
---
drivers/nvme/host/apple.c | 26 +++++++++++++++++++++-----
1 file changed, 21 insertions(+), 5 deletions(-)
diff --git a/drivers/nvme/host/apple.c b/drivers/nvme/host/apple.c
index dd6ec0865141a..b6ac8a1630b2b 100644
--- a/drivers/nvme/host/apple.c
+++ b/drivers/nvme/host/apple.c
@@ -1388,7 +1388,7 @@ static void devm_apple_nvme_mempool_destroy(void *data)
mempool_destroy(data);
}
-static int apple_nvme_probe(struct platform_device *pdev)
+static struct apple_nvme *apple_nvme_alloc(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct apple_nvme *anv;
@@ -1396,7 +1396,7 @@ static int apple_nvme_probe(struct platform_device *pdev)
anv = devm_kzalloc(dev, sizeof(*anv), GFP_KERNEL);
if (!anv)
- return -ENOMEM;
+ return ERR_PTR(-ENOMEM);
anv->dev = get_device(dev);
anv->adminq.is_adminq = true;
@@ -1516,10 +1516,25 @@ static int apple_nvme_probe(struct platform_device *pdev)
goto put_dev;
}
+ return anv;
+put_dev:
+ put_device(anv->dev);
+ return ERR_PTR(ret);
+}
+
+static int apple_nvme_probe(struct platform_device *pdev)
+{
+ struct apple_nvme *anv;
+ int ret;
+
+ anv = apple_nvme_alloc(pdev);
+ if (IS_ERR(anv))
+ return PTR_ERR(anv);
+
anv->ctrl.admin_q = blk_mq_alloc_queue(&anv->admin_tagset, NULL, NULL);
if (IS_ERR(anv->ctrl.admin_q)) {
ret = -ENOMEM;
- goto put_dev;
+ goto out_uninit_ctrl;
}
nvme_reset_ctrl(&anv->ctrl);
@@ -1527,8 +1542,9 @@ static int apple_nvme_probe(struct platform_device *pdev)
return 0;
-put_dev:
- put_device(anv->dev);
+out_uninit_ctrl:
+ nvme_uninit_ctrl(&dev->ctrl);
+ nvme_put_ctrl(&dev->ctrl);
return ret;
}
--
2.43.0
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH-RFC 2/5] nvme: tcp: split controller bringup handling
2024-06-03 23:05 [PATCH-RFC 0/5] nvme: fix initialization memleak Keith Busch
2024-06-03 23:05 ` [PATCH-RFC 1/5] nvme: apple: fix device reference counting Keith Busch
@ 2024-06-03 23:05 ` Keith Busch
2024-06-04 0:35 ` Caleb Sander
2024-06-03 23:05 ` [PATCH-RFC 3/5] nvme: rdma: " Keith Busch
` (4 subsequent siblings)
6 siblings, 1 reply; 13+ messages in thread
From: Keith Busch @ 2024-06-03 23:05 UTC (permalink / raw)
To: linux-nvme; +Cc: hch, sagi, mlombard, hare, shinichiro.kawasaki, Keith Busch
From: Keith Busch <kbusch@kernel.org>
Drivers must call nvme_uninit_ctrl after a successful nvme_init_ctrl.
Split the allocation side out to make the error handling boundary easier
to navigate. The nvme tcp driver's error handling had different returns
in the error goto labels, which harm readability.
Signed-off-by: Keith Busch <kbusch@kernel.org>
---
drivers/nvme/host/tcp.c | 25 +++++++++++++++++++------
1 file changed, 19 insertions(+), 6 deletions(-)
diff --git a/drivers/nvme/host/tcp.c b/drivers/nvme/host/tcp.c
index 8b5e4327fe83b..7f75d01dcbed0 100644
--- a/drivers/nvme/host/tcp.c
+++ b/drivers/nvme/host/tcp.c
@@ -2686,7 +2686,7 @@ nvme_tcp_existing_controller(struct nvmf_ctrl_options *opts)
return found;
}
-static struct nvme_ctrl *nvme_tcp_create_ctrl(struct device *dev,
+static struct nvme_tcp_ctrl *nvme_tcp_alloc_ctrl(struct device *dev,
struct nvmf_ctrl_options *opts)
{
struct nvme_tcp_ctrl *ctrl;
@@ -2761,6 +2761,24 @@ static struct nvme_ctrl *nvme_tcp_create_ctrl(struct device *dev,
if (ret)
goto out_kfree_queues;
+ return ctrl;
+out_kfree_queues:
+ kfree(ctrl->queues);
+out_free_ctrl:
+ kfree(ctrl);
+ return ERR_PTR(ret);
+}
+
+static struct nvme_ctrl *nvme_tcp_create_ctrl(struct device *dev,
+ struct nvmf_ctrl_options *opts)
+{
+ struct nvme_tcp_ctrl *ctrl;
+ int ret;
+
+ ctrl = nvme_tcp_alloc_ctrl(dev, opts);
+ if (IS_ERR(ctrl))
+ return (struct nvme_ctrl *)ctrl;
+
if (!nvme_change_ctrl_state(&ctrl->ctrl, NVME_CTRL_CONNECTING)) {
WARN_ON_ONCE(1);
ret = -EINTR;
@@ -2786,11 +2804,6 @@ static struct nvme_ctrl *nvme_tcp_create_ctrl(struct device *dev,
if (ret > 0)
ret = -EIO;
return ERR_PTR(ret);
-out_kfree_queues:
- kfree(ctrl->queues);
-out_free_ctrl:
- kfree(ctrl);
- return ERR_PTR(ret);
}
static struct nvmf_transport_ops nvme_tcp_transport = {
--
2.43.0
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH-RFC 3/5] nvme: rdma: split controller bringup handling
2024-06-03 23:05 [PATCH-RFC 0/5] nvme: fix initialization memleak Keith Busch
2024-06-03 23:05 ` [PATCH-RFC 1/5] nvme: apple: fix device reference counting Keith Busch
2024-06-03 23:05 ` [PATCH-RFC 2/5] nvme: tcp: split controller bringup handling Keith Busch
@ 2024-06-03 23:05 ` Keith Busch
2024-06-03 23:05 ` [PATCH-RFC 4/5] nvme: fc: " Keith Busch
` (3 subsequent siblings)
6 siblings, 0 replies; 13+ messages in thread
From: Keith Busch @ 2024-06-03 23:05 UTC (permalink / raw)
To: linux-nvme; +Cc: hch, sagi, mlombard, hare, shinichiro.kawasaki, Keith Busch
From: Keith Busch <kbusch@kernel.org>
Drivers must call nvme_uninit_ctrl after a successful nvme_init_ctrl.
Split the allocation side out to make the error handling boundary easier
to navigate. The nvme rdma driver's error handling had different returns
in the error goto labels, which harm readability.
Signed-off-by: Keith Busch <kbusch@kernel.org>
---
drivers/nvme/host/rdma.c | 28 +++++++++++++++++++++-------
1 file changed, 21 insertions(+), 7 deletions(-)
diff --git a/drivers/nvme/host/rdma.c b/drivers/nvme/host/rdma.c
index 51a62b0c645a7..dab8ade8e9489 100644
--- a/drivers/nvme/host/rdma.c
+++ b/drivers/nvme/host/rdma.c
@@ -2237,12 +2237,11 @@ nvme_rdma_existing_controller(struct nvmf_ctrl_options *opts)
return found;
}
-static struct nvme_ctrl *nvme_rdma_create_ctrl(struct device *dev,
+static struct nvme_rdma_ctrl *nvme_rdma_alloc_ctrl(struct device *dev,
struct nvmf_ctrl_options *opts)
{
struct nvme_rdma_ctrl *ctrl;
int ret;
- bool changed;
ctrl = kzalloc(sizeof(*ctrl), GFP_KERNEL);
if (!ctrl)
@@ -2304,6 +2303,26 @@ static struct nvme_ctrl *nvme_rdma_create_ctrl(struct device *dev,
if (ret)
goto out_kfree_queues;
+ return ctrl;
+
+out_kfree_queues:
+ kfree(ctrl->queues);
+out_free_ctrl:
+ kfree(ctrl);
+ return ERR_PTR(ret);
+}
+
+static struct nvme_ctrl *nvme_rdma_create_ctrl(struct device *dev,
+ struct nvmf_ctrl_options *opts)
+{
+ struct nvme_rdma_ctrl *ctrl;
+ bool changed;
+ int ret;
+
+ ctrl = nvme_rdma_alloc_ctrl(dev, opts);
+ if (IS_ERR(ctrl))
+ return (struct nvme_ctrl *)ctrl;
+
changed = nvme_change_ctrl_state(&ctrl->ctrl, NVME_CTRL_CONNECTING);
WARN_ON_ONCE(!changed);
@@ -2326,11 +2345,6 @@ static struct nvme_ctrl *nvme_rdma_create_ctrl(struct device *dev,
if (ret > 0)
ret = -EIO;
return ERR_PTR(ret);
-out_kfree_queues:
- kfree(ctrl->queues);
-out_free_ctrl:
- kfree(ctrl);
- return ERR_PTR(ret);
}
static struct nvmf_transport_ops nvme_rdma_transport = {
--
2.43.0
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH-RFC 4/5] nvme: fc: split controller bringup handling
2024-06-03 23:05 [PATCH-RFC 0/5] nvme: fix initialization memleak Keith Busch
` (2 preceding siblings ...)
2024-06-03 23:05 ` [PATCH-RFC 3/5] nvme: rdma: " Keith Busch
@ 2024-06-03 23:05 ` Keith Busch
2024-06-03 23:05 ` [PATCH-RFC 5/5] nvme: split device add from initialzation Keith Busch
` (2 subsequent siblings)
6 siblings, 0 replies; 13+ messages in thread
From: Keith Busch @ 2024-06-03 23:05 UTC (permalink / raw)
To: linux-nvme; +Cc: hch, sagi, mlombard, hare, shinichiro.kawasaki, Keith Busch
From: Keith Busch <kbusch@kernel.org>
Drivers must call nvme_uninit_ctrl after a successful nvme_init_ctrl.
Split the allocation side out to make the error handling boundary easier
to navigate. The nvme fc driver's error handling had different returns
in the error goto labels, which harm readability.
Signed-off-by: Keith Busch <kbusch@kernel.org>
---
drivers/nvme/host/fc.c | 43 ++++++++++++++++++++++++++----------------
1 file changed, 27 insertions(+), 16 deletions(-)
diff --git a/drivers/nvme/host/fc.c b/drivers/nvme/host/fc.c
index f0b0813327491..43bc8f16b3a78 100644
--- a/drivers/nvme/host/fc.c
+++ b/drivers/nvme/host/fc.c
@@ -3444,12 +3444,11 @@ nvme_fc_existing_controller(struct nvme_fc_rport *rport,
return found;
}
-static struct nvme_ctrl *
-nvme_fc_init_ctrl(struct device *dev, struct nvmf_ctrl_options *opts,
+static struct nvme_fc_ctrl *
+nvme_fc_alloc_ctrl(struct device *dev, struct nvmf_ctrl_options *opts,
struct nvme_fc_lport *lport, struct nvme_fc_rport *rport)
{
struct nvme_fc_ctrl *ctrl;
- unsigned long flags;
int ret, idx, ctrl_loss_tmo;
if (!(rport->remoteport.port_role &
@@ -3538,7 +3537,31 @@ nvme_fc_init_ctrl(struct device *dev, struct nvmf_ctrl_options *opts,
if (lport->dev)
ctrl->ctrl.numa_node = dev_to_node(lport->dev);
- /* at this point, teardown path changes to ref counting on nvme ctrl */
+ return ctrl;
+
+out_free_queues:
+ kfree(ctrl->queues);
+out_free_ida:
+ put_device(ctrl->dev);
+ ida_free(&nvme_fc_ctrl_cnt, ctrl->cnum);
+out_free_ctrl:
+ kfree(ctrl);
+out_fail:
+ /* exit via here doesn't follow ctlr ref points */
+ return ERR_PTR(ret);
+}
+
+static struct nvme_ctrl *
+nvme_fc_init_ctrl(struct device *dev, struct nvmf_ctrl_options *opts,
+ struct nvme_fc_lport *lport, struct nvme_fc_rport *rport)
+{
+ struct nvme_fc_ctrl *ctrl;
+ unsigned long flags;
+ int ret;
+
+ ctrl = nvme_fc_alloc_ctrl(dev, opts, lport, rport);
+ if (IS_ERR(ctrl))
+ return (struct nvme_ctrl *)ctrl;
ret = nvme_alloc_admin_tag_set(&ctrl->ctrl, &ctrl->admin_tag_set,
&nvme_fc_admin_mq_ops,
@@ -3597,20 +3620,8 @@ nvme_fc_init_ctrl(struct device *dev, struct nvmf_ctrl_options *opts,
nvme_fc_rport_get(rport);
return ERR_PTR(-EIO);
-
-out_free_queues:
- kfree(ctrl->queues);
-out_free_ida:
- put_device(ctrl->dev);
- ida_free(&nvme_fc_ctrl_cnt, ctrl->cnum);
-out_free_ctrl:
- kfree(ctrl);
-out_fail:
- /* exit via here doesn't follow ctlr ref points */
- return ERR_PTR(ret);
}
-
struct nvmet_fc_traddr {
u64 nn;
u64 pn;
--
2.43.0
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH-RFC 5/5] nvme: split device add from initialzation
2024-06-03 23:05 [PATCH-RFC 0/5] nvme: fix initialization memleak Keith Busch
` (3 preceding siblings ...)
2024-06-03 23:05 ` [PATCH-RFC 4/5] nvme: fc: " Keith Busch
@ 2024-06-03 23:05 ` Keith Busch
2024-06-04 4:24 ` [PATCH-RFC 0/5] nvme: fix initialization memleak Christoph Hellwig
2024-06-04 14:51 ` Sagi Grimberg
6 siblings, 0 replies; 13+ messages in thread
From: Keith Busch @ 2024-06-03 23:05 UTC (permalink / raw)
To: linux-nvme; +Cc: hch, sagi, mlombard, hare, shinichiro.kawasaki, Keith Busch
From: Keith Busch <kbusch@kernel.org>
Combining both creates an ambiguous cleanup scenario for the caller if
an error is returned: does the device reference need to be dropped or
did the error occur before the device was initialized? If an error
occurs after the device is added, then the existing cleanup routines
will leak memory.
Furthermore, the nvme core is taking it upon itself to free the device's
kobj.name under certain conditions. We shouldn't be peaking into these
implementation details.
Split the device initialization from the addition to make it easier to
know the error handling actions and stop the layering violations.
Signed-off-by: Keith Busch <kbusch@kernel.org>
---
drivers/nvme/host/apple.c | 5 ++++
drivers/nvme/host/core.c | 58 +++++++++++++++++++++++---------------
drivers/nvme/host/fc.c | 5 ++++
drivers/nvme/host/nvme.h | 1 +
drivers/nvme/host/pci.c | 5 ++++
drivers/nvme/host/rdma.c | 5 ++++
drivers/nvme/host/tcp.c | 5 ++++
drivers/nvme/target/loop.c | 5 ++++
8 files changed, 66 insertions(+), 23 deletions(-)
diff --git a/drivers/nvme/host/apple.c b/drivers/nvme/host/apple.c
index b6ac8a1630b2b..89f60851e63a6 100644
--- a/drivers/nvme/host/apple.c
+++ b/drivers/nvme/host/apple.c
@@ -1531,6 +1531,10 @@ static int apple_nvme_probe(struct platform_device *pdev)
if (IS_ERR(anv))
return PTR_ERR(anv);
+ result = nvme_add_ctrl(&anv->ctrl);
+ if (result)
+ goto out_put_ctrl;
+
anv->ctrl.admin_q = blk_mq_alloc_queue(&anv->admin_tagset, NULL, NULL);
if (IS_ERR(anv->ctrl.admin_q)) {
ret = -ENOMEM;
@@ -1544,6 +1548,7 @@ static int apple_nvme_probe(struct platform_device *pdev)
out_uninit_ctrl:
nvme_uninit_ctrl(&dev->ctrl);
+out_put_ctrl:
nvme_put_ctrl(&dev->ctrl);
return ret;
}
diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c
index f5d150c62955d..070cc4d76b6a4 100644
--- a/drivers/nvme/host/core.c
+++ b/drivers/nvme/host/core.c
@@ -4611,6 +4611,9 @@ static void nvme_free_ctrl(struct device *dev)
* Initialize a NVMe controller structures. This needs to be called during
* earliest initialization so that we have the initialized structured around
* during probing.
+ *
+ * On success, the caller must use the nvme_put_ctrl() to release this when
+ * needed, which also invokes the ops->free_ctrl() callback.
*/
int nvme_init_ctrl(struct nvme_ctrl *ctrl, struct device *dev,
const struct nvme_ctrl_ops *ops, unsigned long quirks)
@@ -4659,6 +4662,12 @@ int nvme_init_ctrl(struct nvme_ctrl *ctrl, struct device *dev,
goto out;
ctrl->instance = ret;
+ ret = nvme_auth_init_ctrl(ctrl);
+ if (ret)
+ goto out_release_instance;
+
+ nvme_mpath_init_ctrl(ctrl);
+
device_initialize(&ctrl->ctrl_device);
ctrl->device = &ctrl->ctrl_device;
ctrl->device->devt = MKDEV(MAJOR(nvme_ctrl_base_chr_devt),
@@ -4671,16 +4680,36 @@ int nvme_init_ctrl(struct nvme_ctrl *ctrl, struct device *dev,
ctrl->device->groups = nvme_dev_attr_groups;
ctrl->device->release = nvme_free_ctrl;
dev_set_drvdata(ctrl->device, ctrl);
+
+ return ret;
+
+out_release_instance:
+ ida_free(&nvme_instance_ida, ctrl->instance);
+out:
+ if (ctrl->discard_page)
+ __free_page(ctrl->discard_page);
+ cleanup_srcu_struct(&ctrl->srcu);
+ return ret;
+}
+EXPORT_SYMBOL_GPL(nvme_init_ctrl);
+
+/*
+ * On success, returns with an elevated controller reference and caller must
+ * use nvme_uninit_ctrl() to properly free resources associated with the ctrl.
+ */
+int nvme_add_ctrl(struct nvme_ctrl *ctrl)
+{
+ int ret;
+
ret = dev_set_name(ctrl->device, "nvme%d", ctrl->instance);
if (ret)
- goto out_release_instance;
+ return ret;
- nvme_get_ctrl(ctrl);
cdev_init(&ctrl->cdev, &nvme_dev_fops);
- ctrl->cdev.owner = ops->module;
+ ctrl->cdev.owner = ctrl->ops->module;
ret = cdev_device_add(&ctrl->cdev, ctrl->device);
if (ret)
- goto out_free_name;
+ return ret;
/*
* Initialize latency tolerance controls. The sysfs files won't
@@ -4691,28 +4720,11 @@ int nvme_init_ctrl(struct nvme_ctrl *ctrl, struct device *dev,
min(default_ps_max_latency_us, (unsigned long)S32_MAX));
nvme_fault_inject_init(&ctrl->fault_inject, dev_name(ctrl->device));
- nvme_mpath_init_ctrl(ctrl);
- ret = nvme_auth_init_ctrl(ctrl);
- if (ret)
- goto out_free_cdev;
+ nvme_get_ctrl(ctrl);
return 0;
-out_free_cdev:
- nvme_fault_inject_fini(&ctrl->fault_inject);
- dev_pm_qos_hide_latency_tolerance(ctrl->device);
- cdev_device_del(&ctrl->cdev, ctrl->device);
-out_free_name:
- nvme_put_ctrl(ctrl);
- kfree_const(ctrl->device->kobj.name);
-out_release_instance:
- ida_free(&nvme_instance_ida, ctrl->instance);
-out:
- if (ctrl->discard_page)
- __free_page(ctrl->discard_page);
- cleanup_srcu_struct(&ctrl->srcu);
- return ret;
}
-EXPORT_SYMBOL_GPL(nvme_init_ctrl);
+EXPORT_SYMBOL_GPL(nvme_add_ctrl);
/* let I/O to all namespaces fail in preparation for surprise removal */
void nvme_mark_namespaces_dead(struct nvme_ctrl *ctrl)
diff --git a/drivers/nvme/host/fc.c b/drivers/nvme/host/fc.c
index 43bc8f16b3a78..2ce54f560e004 100644
--- a/drivers/nvme/host/fc.c
+++ b/drivers/nvme/host/fc.c
@@ -3563,6 +3563,10 @@ nvme_fc_init_ctrl(struct device *dev, struct nvmf_ctrl_options *opts,
if (IS_ERR(ctrl))
return (struct nvme_ctrl *)ctrl;
+ ret = nvme_add_ctrl(&ctrl->ctrl);
+ if (ret)
+ goto out_put_ctrl;
+
ret = nvme_alloc_admin_tag_set(&ctrl->ctrl, &ctrl->admin_tag_set,
&nvme_fc_admin_mq_ops,
struct_size_t(struct nvme_fcp_op_w_sgl, priv,
@@ -3607,6 +3611,7 @@ nvme_fc_init_ctrl(struct device *dev, struct nvmf_ctrl_options *opts,
/* initiate nvme ctrl ref counting teardown */
nvme_uninit_ctrl(&ctrl->ctrl);
+out_put_ctrl:
/* Remove core ctrl ref. */
nvme_put_ctrl(&ctrl->ctrl);
diff --git a/drivers/nvme/host/nvme.h b/drivers/nvme/host/nvme.h
index f3a41133ac3f9..9693490680866 100644
--- a/drivers/nvme/host/nvme.h
+++ b/drivers/nvme/host/nvme.h
@@ -792,6 +792,7 @@ int nvme_disable_ctrl(struct nvme_ctrl *ctrl, bool shutdown);
int nvme_enable_ctrl(struct nvme_ctrl *ctrl);
int nvme_init_ctrl(struct nvme_ctrl *ctrl, struct device *dev,
const struct nvme_ctrl_ops *ops, unsigned long quirks);
+int nvme_add_ctrl(struct nvme_ctrl *ctrl);
void nvme_uninit_ctrl(struct nvme_ctrl *ctrl);
void nvme_start_ctrl(struct nvme_ctrl *ctrl);
void nvme_stop_ctrl(struct nvme_ctrl *ctrl);
diff --git a/drivers/nvme/host/pci.c b/drivers/nvme/host/pci.c
index 102a9fb0c65ff..c92125b0238d4 100644
--- a/drivers/nvme/host/pci.c
+++ b/drivers/nvme/host/pci.c
@@ -3015,6 +3015,10 @@ static int nvme_probe(struct pci_dev *pdev, const struct pci_device_id *id)
if (IS_ERR(dev))
return PTR_ERR(dev);
+ result = nvme_add_ctrl(&dev->ctrl);
+ if (result)
+ goto out_put_ctrl;
+
result = nvme_dev_map(dev);
if (result)
goto out_uninit_ctrl;
@@ -3101,6 +3105,7 @@ static int nvme_probe(struct pci_dev *pdev, const struct pci_device_id *id)
nvme_dev_unmap(dev);
out_uninit_ctrl:
nvme_uninit_ctrl(&dev->ctrl);
+out_put_ctrl:
nvme_put_ctrl(&dev->ctrl);
return result;
}
diff --git a/drivers/nvme/host/rdma.c b/drivers/nvme/host/rdma.c
index dab8ade8e9489..bfe1b21974cdd 100644
--- a/drivers/nvme/host/rdma.c
+++ b/drivers/nvme/host/rdma.c
@@ -2323,6 +2323,10 @@ static struct nvme_ctrl *nvme_rdma_create_ctrl(struct device *dev,
if (IS_ERR(ctrl))
return (struct nvme_ctrl *)ctrl;
+ ret = nvme_add_ctrl(&ctrl->ctrl);
+ if (ret)
+ goto out_put_ctrl;
+
changed = nvme_change_ctrl_state(&ctrl->ctrl, NVME_CTRL_CONNECTING);
WARN_ON_ONCE(!changed);
@@ -2341,6 +2345,7 @@ static struct nvme_ctrl *nvme_rdma_create_ctrl(struct device *dev,
out_uninit_ctrl:
nvme_uninit_ctrl(&ctrl->ctrl);
+out_put_ctrl:
nvme_put_ctrl(&ctrl->ctrl);
if (ret > 0)
ret = -EIO;
diff --git a/drivers/nvme/host/tcp.c b/drivers/nvme/host/tcp.c
index 7f75d01dcbed0..8549ea87df6ff 100644
--- a/drivers/nvme/host/tcp.c
+++ b/drivers/nvme/host/tcp.c
@@ -2779,6 +2779,10 @@ static struct nvme_ctrl *nvme_tcp_create_ctrl(struct device *dev,
if (IS_ERR(ctrl))
return (struct nvme_ctrl *)ctrl;
+ ret = nvme_add_ctrl(&ctrl->ctrl);
+ if (ret)
+ goto out_put_ctrl;
+
if (!nvme_change_ctrl_state(&ctrl->ctrl, NVME_CTRL_CONNECTING)) {
WARN_ON_ONCE(1);
ret = -EINTR;
@@ -2800,6 +2804,7 @@ static struct nvme_ctrl *nvme_tcp_create_ctrl(struct device *dev,
out_uninit_ctrl:
nvme_uninit_ctrl(&ctrl->ctrl);
+out_put_ctrl:
nvme_put_ctrl(&ctrl->ctrl);
if (ret > 0)
ret = -EIO;
diff --git a/drivers/nvme/target/loop.c b/drivers/nvme/target/loop.c
index e589915ddef85..e32790d8fc260 100644
--- a/drivers/nvme/target/loop.c
+++ b/drivers/nvme/target/loop.c
@@ -555,6 +555,10 @@ static struct nvme_ctrl *nvme_loop_create_ctrl(struct device *dev,
goto out;
}
+ ret = nvme_add_ctrl(&ctrl->ctrl);
+ if (ret)
+ goto out_put_ctrl;
+
if (!nvme_change_ctrl_state(&ctrl->ctrl, NVME_CTRL_CONNECTING))
WARN_ON_ONCE(1);
@@ -611,6 +615,7 @@ static struct nvme_ctrl *nvme_loop_create_ctrl(struct device *dev,
kfree(ctrl->queues);
out_uninit_ctrl:
nvme_uninit_ctrl(&ctrl->ctrl);
+out_put_ctrl:
nvme_put_ctrl(&ctrl->ctrl);
out:
if (ret > 0)
--
2.43.0
^ permalink raw reply related [flat|nested] 13+ messages in thread
* Re: [PATCH-RFC 1/5] nvme: apple: fix device reference counting
2024-06-03 23:05 ` [PATCH-RFC 1/5] nvme: apple: fix device reference counting Keith Busch
@ 2024-06-03 23:17 ` Keith Busch
0 siblings, 0 replies; 13+ messages in thread
From: Keith Busch @ 2024-06-03 23:17 UTC (permalink / raw)
To: Keith Busch; +Cc: linux-nvme, hch, sagi, mlombard, hare, shinichiro.kawasaki
On Mon, Jun 03, 2024 at 04:05:19PM -0700, Keith Busch wrote:
> +static int apple_nvme_probe(struct platform_device *pdev)
> +{
> + struct apple_nvme *anv;
> + int ret;
> +
> + anv = apple_nvme_alloc(pdev);
> + if (IS_ERR(anv))
> + return PTR_ERR(anv);
> +
> anv->ctrl.admin_q = blk_mq_alloc_queue(&anv->admin_tagset, NULL, NULL);
> if (IS_ERR(anv->ctrl.admin_q)) {
> ret = -ENOMEM;
> - goto put_dev;
> + goto out_uninit_ctrl;
> }
Replying to myself: need to add 'anv->ctrl.admin_q = NULL' before the
goto.
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH-RFC 2/5] nvme: tcp: split controller bringup handling
2024-06-03 23:05 ` [PATCH-RFC 2/5] nvme: tcp: split controller bringup handling Keith Busch
@ 2024-06-04 0:35 ` Caleb Sander
2024-06-04 2:44 ` Keith Busch
2024-06-04 6:47 ` Hannes Reinecke
0 siblings, 2 replies; 13+ messages in thread
From: Caleb Sander @ 2024-06-04 0:35 UTC (permalink / raw)
To: Keith Busch
Cc: linux-nvme, hch, sagi, mlombard, hare, shinichiro.kawasaki,
Keith Busch
On Mon, Jun 3, 2024 at 4:08 PM Keith Busch <kbusch@meta.com> wrote:
>
> From: Keith Busch <kbusch@kernel.org>
>
> Drivers must call nvme_uninit_ctrl after a successful nvme_init_ctrl.
> Split the allocation side out to make the error handling boundary easier
> to navigate. The nvme tcp driver's error handling had different returns
> in the error goto labels, which harm readability.
>
> Signed-off-by: Keith Busch <kbusch@kernel.org>
> ---
> drivers/nvme/host/tcp.c | 25 +++++++++++++++++++------
> 1 file changed, 19 insertions(+), 6 deletions(-)
>
> diff --git a/drivers/nvme/host/tcp.c b/drivers/nvme/host/tcp.c
> index 8b5e4327fe83b..7f75d01dcbed0 100644
> --- a/drivers/nvme/host/tcp.c
> +++ b/drivers/nvme/host/tcp.c
> @@ -2686,7 +2686,7 @@ nvme_tcp_existing_controller(struct nvmf_ctrl_options *opts)
> return found;
> }
>
> -static struct nvme_ctrl *nvme_tcp_create_ctrl(struct device *dev,
> +static struct nvme_tcp_ctrl *nvme_tcp_alloc_ctrl(struct device *dev,
> struct nvmf_ctrl_options *opts)
> {
> struct nvme_tcp_ctrl *ctrl;
> @@ -2761,6 +2761,24 @@ static struct nvme_ctrl *nvme_tcp_create_ctrl(struct device *dev,
> if (ret)
> goto out_kfree_queues;
>
> + return ctrl;
> +out_kfree_queues:
> + kfree(ctrl->queues);
> +out_free_ctrl:
> + kfree(ctrl);
> + return ERR_PTR(ret);
> +}
> +
> +static struct nvme_ctrl *nvme_tcp_create_ctrl(struct device *dev,
> + struct nvmf_ctrl_options *opts)
> +{
> + struct nvme_tcp_ctrl *ctrl;
> + int ret;
> +
> + ctrl = nvme_tcp_alloc_ctrl(dev, opts);
> + if (IS_ERR(ctrl))
> + return (struct nvme_ctrl *)ctrl;
This cast doesn't look right, as struct nvme_tcp_ctrl doesn't start
with a struct nvme_ctrl field. Looks like this should be &ctrl->ctrl
to match the current implementation of nvme_tcp_create_ctrl()?
> +
> if (!nvme_change_ctrl_state(&ctrl->ctrl, NVME_CTRL_CONNECTING)) {
> WARN_ON_ONCE(1);
> ret = -EINTR;
> @@ -2786,11 +2804,6 @@ static struct nvme_ctrl *nvme_tcp_create_ctrl(struct device *dev,
> if (ret > 0)
> ret = -EIO;
> return ERR_PTR(ret);
> -out_kfree_queues:
> - kfree(ctrl->queues);
> -out_free_ctrl:
> - kfree(ctrl);
> - return ERR_PTR(ret);
> }
>
> static struct nvmf_transport_ops nvme_tcp_transport = {
> --
> 2.43.0
>
>
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH-RFC 2/5] nvme: tcp: split controller bringup handling
2024-06-04 0:35 ` Caleb Sander
@ 2024-06-04 2:44 ` Keith Busch
2024-06-04 4:23 ` Christoph Hellwig
2024-06-04 6:47 ` Hannes Reinecke
1 sibling, 1 reply; 13+ messages in thread
From: Keith Busch @ 2024-06-04 2:44 UTC (permalink / raw)
To: Caleb Sander
Cc: Keith Busch, linux-nvme, hch, sagi, mlombard, hare,
shinichiro.kawasaki
On Mon, Jun 03, 2024 at 05:35:13PM -0700, Caleb Sander wrote:
> On Mon, Jun 3, 2024 at 4:08 PM Keith Busch <kbusch@meta.com> wrote:
> > +static struct nvme_ctrl *nvme_tcp_create_ctrl(struct device *dev,
> > + struct nvmf_ctrl_options *opts)
> > +{
> > + struct nvme_tcp_ctrl *ctrl;
> > + int ret;
> > +
> > + ctrl = nvme_tcp_alloc_ctrl(dev, opts);
> > + if (IS_ERR(ctrl))
> > + return (struct nvme_ctrl *)ctrl;
>
> This cast doesn't look right, as struct nvme_tcp_ctrl doesn't start
> with a struct nvme_ctrl field. Looks like this should be &ctrl->ctrl
> to match the current implementation of nvme_tcp_create_ctrl()?
We can't take an offset here because the "ctrl" is an ERR_PTR, and we
want to preserve that for this function's return value. I could cast to
a "void *" instead to suppress the compiler complaints if that helps get
the intention across.
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH-RFC 2/5] nvme: tcp: split controller bringup handling
2024-06-04 2:44 ` Keith Busch
@ 2024-06-04 4:23 ` Christoph Hellwig
0 siblings, 0 replies; 13+ messages in thread
From: Christoph Hellwig @ 2024-06-04 4:23 UTC (permalink / raw)
To: Keith Busch
Cc: Caleb Sander, Keith Busch, linux-nvme, hch, sagi, mlombard, hare,
shinichiro.kawasaki
On Mon, Jun 03, 2024 at 08:44:55PM -0600, Keith Busch wrote:
> > > + ctrl = nvme_tcp_alloc_ctrl(dev, opts);
> > > + if (IS_ERR(ctrl))
> > > + return (struct nvme_ctrl *)ctrl;
> >
> > This cast doesn't look right, as struct nvme_tcp_ctrl doesn't start
> > with a struct nvme_ctrl field. Looks like this should be &ctrl->ctrl
> > to match the current implementation of nvme_tcp_create_ctrl()?
>
> We can't take an offset here because the "ctrl" is an ERR_PTR, and we
> want to preserve that for this function's return value. I could cast to
> a "void *" instead to suppress the compiler complaints if that helps get
> the intention across.
Or you could use the ERR_CAST helper, which does exactly that void *
cast, but actually documents why it is done :)
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH-RFC 0/5] nvme: fix initialization memleak
2024-06-03 23:05 [PATCH-RFC 0/5] nvme: fix initialization memleak Keith Busch
` (4 preceding siblings ...)
2024-06-03 23:05 ` [PATCH-RFC 5/5] nvme: split device add from initialzation Keith Busch
@ 2024-06-04 4:24 ` Christoph Hellwig
2024-06-04 14:51 ` Sagi Grimberg
6 siblings, 0 replies; 13+ messages in thread
From: Christoph Hellwig @ 2024-06-04 4:24 UTC (permalink / raw)
To: Keith Busch
Cc: linux-nvme, hch, sagi, mlombard, hare, shinichiro.kawasaki,
Keith Busch
On Mon, Jun 03, 2024 at 04:05:18PM -0700, Keith Busch wrote:
> From: Keith Busch <kbusch@kernel.org>
>
> The pci driver is the only one runtime tested. Everything else is
> compile tested, except for apple.
The highlevel flow looks good to me. FYI, TCP/loop and to a lesser
extent the other fabrics transports can be exercised using blktests
nicely.
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH-RFC 2/5] nvme: tcp: split controller bringup handling
2024-06-04 0:35 ` Caleb Sander
2024-06-04 2:44 ` Keith Busch
@ 2024-06-04 6:47 ` Hannes Reinecke
1 sibling, 0 replies; 13+ messages in thread
From: Hannes Reinecke @ 2024-06-04 6:47 UTC (permalink / raw)
To: Caleb Sander, Keith Busch
Cc: linux-nvme, hch, sagi, mlombard, shinichiro.kawasaki, Keith Busch
On 6/4/24 02:35, Caleb Sander wrote:
> On Mon, Jun 3, 2024 at 4:08 PM Keith Busch <kbusch@meta.com> wrote:
>>
>> From: Keith Busch <kbusch@kernel.org>
>>
>> Drivers must call nvme_uninit_ctrl after a successful nvme_init_ctrl.
>> Split the allocation side out to make the error handling boundary easier
>> to navigate. The nvme tcp driver's error handling had different returns
>> in the error goto labels, which harm readability.
>>
>> Signed-off-by: Keith Busch <kbusch@kernel.org>
>> ---
>> drivers/nvme/host/tcp.c | 25 +++++++++++++++++++------
>> 1 file changed, 19 insertions(+), 6 deletions(-)
>>
>> diff --git a/drivers/nvme/host/tcp.c b/drivers/nvme/host/tcp.c
>> index 8b5e4327fe83b..7f75d01dcbed0 100644
>> --- a/drivers/nvme/host/tcp.c
>> +++ b/drivers/nvme/host/tcp.c
>> @@ -2686,7 +2686,7 @@ nvme_tcp_existing_controller(struct nvmf_ctrl_options *opts)
>> return found;
>> }
>>
>> -static struct nvme_ctrl *nvme_tcp_create_ctrl(struct device *dev,
>> +static struct nvme_tcp_ctrl *nvme_tcp_alloc_ctrl(struct device *dev,
>> struct nvmf_ctrl_options *opts)
>> {
>> struct nvme_tcp_ctrl *ctrl;
>> @@ -2761,6 +2761,24 @@ static struct nvme_ctrl *nvme_tcp_create_ctrl(struct device *dev,
>> if (ret)
>> goto out_kfree_queues;
>>
>> + return ctrl;
>> +out_kfree_queues:
>> + kfree(ctrl->queues);
>> +out_free_ctrl:
>> + kfree(ctrl);
>> + return ERR_PTR(ret);
>> +}
>> +
>> +static struct nvme_ctrl *nvme_tcp_create_ctrl(struct device *dev,
>> + struct nvmf_ctrl_options *opts)
>> +{
>> + struct nvme_tcp_ctrl *ctrl;
>> + int ret;
>> +
>> + ctrl = nvme_tcp_alloc_ctrl(dev, opts);
>> + if (IS_ERR(ctrl))
>> + return (struct nvme_ctrl *)ctrl;
>
> This cast doesn't look right, as struct nvme_tcp_ctrl doesn't start
> with a struct nvme_ctrl field. Looks like this should be &ctrl->ctrl
> to match the current implementation of nvme_tcp_create_ctrl()?
>
ERR_CAST() ?
Cheers,
Hannes
--
Dr. Hannes Reinecke Kernel Storage Architect
hare@suse.de +49 911 74053 688
SUSE Software Solutions GmbH, Frankenstr. 146, 90461 Nürnberg
HRB 36809 (AG Nürnberg), GF: I. Totev, A. McDonald, W. Knoblich
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH-RFC 0/5] nvme: fix initialization memleak
2024-06-03 23:05 [PATCH-RFC 0/5] nvme: fix initialization memleak Keith Busch
` (5 preceding siblings ...)
2024-06-04 4:24 ` [PATCH-RFC 0/5] nvme: fix initialization memleak Christoph Hellwig
@ 2024-06-04 14:51 ` Sagi Grimberg
6 siblings, 0 replies; 13+ messages in thread
From: Sagi Grimberg @ 2024-06-04 14:51 UTC (permalink / raw)
To: Keith Busch, linux-nvme
Cc: hch, mlombard, hare, shinichiro.kawasaki, Keith Busch
On 04/06/2024 2:05, Keith Busch wrote:
> From: Keith Busch <kbusch@kernel.org>
>
> The pci driver is the only one runtime tested. Everything else is
> compile tested, except for apple.
>
>
> Keith Busch (5):
> nvme: apple: fix device reference counting
> nvme: tcp: split controller bringup handling
> nvme: rdma: split controller bringup handling
> nvme: fc: split controller bringup handling
For some reason patches 3,4 got lost from my inbox...
I'll wait for your v1.
^ permalink raw reply [flat|nested] 13+ messages in thread
end of thread, other threads:[~2024-06-04 14:52 UTC | newest]
Thread overview: 13+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-06-03 23:05 [PATCH-RFC 0/5] nvme: fix initialization memleak Keith Busch
2024-06-03 23:05 ` [PATCH-RFC 1/5] nvme: apple: fix device reference counting Keith Busch
2024-06-03 23:17 ` Keith Busch
2024-06-03 23:05 ` [PATCH-RFC 2/5] nvme: tcp: split controller bringup handling Keith Busch
2024-06-04 0:35 ` Caleb Sander
2024-06-04 2:44 ` Keith Busch
2024-06-04 4:23 ` Christoph Hellwig
2024-06-04 6:47 ` Hannes Reinecke
2024-06-03 23:05 ` [PATCH-RFC 3/5] nvme: rdma: " Keith Busch
2024-06-03 23:05 ` [PATCH-RFC 4/5] nvme: fc: " Keith Busch
2024-06-03 23:05 ` [PATCH-RFC 5/5] nvme: split device add from initialzation Keith Busch
2024-06-04 4:24 ` [PATCH-RFC 0/5] nvme: fix initialization memleak Christoph Hellwig
2024-06-04 14:51 ` Sagi Grimberg
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox