From: Maurizio Lombardi <m.lombardi85@mail.ru>
To: Hannes Reinecke <hare@suse.de>
Cc: Maurizio Lombardi <mlombard@redhat.com>,
Keith Busch <kbusch@kernel.org>, Sagi Grimberg <sagi@grimberg.me>,
Yi Zhang <yi.zhang@redhat.com>,
"open list:NVM EXPRESS DRIVER" <linux-nvme@lists.infradead.org>,
Shin'ichiro Kawasaki <shinichiro.kawasaki@wdc.com>
Subject: Re: blktests nvme 041,042 leak memory
Date: Mon, 3 Jun 2024 11:35:30 +0200 [thread overview]
Message-ID: <Zl2OYgyN0exmIKk0@kalibr> (raw)
In-Reply-To: <8058afc6-8272-42fa-a024-e477a29148e1@suse.de>
V Mon, Jun 03, 2024 at 10:37:33AM +0200, Hannes Reinecke napsal(a):
> Hmm. Don't really like it.
> We took great pains of moving then entire DH-CHAP code into its own
> file, and this patch reverts it and is causing the DH-CHAP code to be
> littered all over the place.
The following would do the same thing without littering
the auth code around.
But the real problem of this approach is that, in case of failure, the nvme_init_ctrl()
function is unable to cleanly revert all of its changes and cleaning
it up is left to the callers (they have to execute nvme_put_ctrl()).
diff --git a/drivers/nvme/host/auth.c b/drivers/nvme/host/auth.c
index 371e14f0a203..df0c8211b381 100644
--- a/drivers/nvme/host/auth.c
+++ b/drivers/nvme/host/auth.c
@@ -940,6 +940,8 @@ int nvme_auth_init_ctrl(struct nvme_ctrl *ctrl)
struct nvme_dhchap_queue_context *chap;
int i, ret;
+ ctrl->auth_initialized = true;
+
mutex_init(&ctrl->dhchap_auth_mutex);
INIT_WORK(&ctrl->dhchap_auth_work, nvme_ctrl_auth_work);
if (!ctrl->opts)
@@ -947,7 +949,7 @@ int nvme_auth_init_ctrl(struct nvme_ctrl *ctrl)
ret = nvme_auth_generate_key(ctrl->opts->dhchap_secret,
&ctrl->host_key);
if (ret)
- return ret;
+ goto out;
ret = nvme_auth_generate_key(ctrl->opts->dhchap_ctrl_secret,
&ctrl->ctrl_key);
if (ret)
@@ -977,13 +979,16 @@ int nvme_auth_init_ctrl(struct nvme_ctrl *ctrl)
err_free_dhchap_secret:
nvme_auth_free_key(ctrl->host_key);
ctrl->host_key = NULL;
+out:
+ ctrl->auth_initialized = false;
return ret;
}
EXPORT_SYMBOL_GPL(nvme_auth_init_ctrl);
void nvme_auth_stop(struct nvme_ctrl *ctrl)
{
- cancel_work_sync(&ctrl->dhchap_auth_work);
+ if (ctrl->auth_initialized)
+ cancel_work_sync(&ctrl->dhchap_auth_work);
}
EXPORT_SYMBOL_GPL(nvme_auth_stop);
diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c
index 954f850f113a..68b9f2ce98c8 100644
--- a/drivers/nvme/host/core.c
+++ b/drivers/nvme/host/core.c
@@ -4572,14 +4572,16 @@ static void nvme_free_ctrl(struct device *dev)
container_of(dev, struct nvme_ctrl, ctrl_device);
struct nvme_subsystem *subsys = ctrl->subsys;
- if (!subsys || ctrl->instance != subsys->instance)
+ if (ctrl->instance >= 0 &&
+ (!subsys || ctrl->instance != subsys->instance))
ida_free(&nvme_instance_ida, ctrl->instance);
key_put(ctrl->tls_key);
nvme_free_cels(ctrl);
nvme_mpath_uninit(ctrl);
nvme_auth_stop(ctrl);
nvme_auth_free(ctrl);
- __free_page(ctrl->discard_page);
+ if (ctrl->discard_page)
+ __free_page(ctrl->discard_page);
free_opal_dev(ctrl->opal_dev);
if (subsys) {
@@ -4631,16 +4633,8 @@ int nvme_init_ctrl(struct nvme_ctrl *ctrl, struct device *dev,
BUILD_BUG_ON(NVME_DSM_MAX_RANGES * sizeof(struct nvme_dsm_range) >
PAGE_SIZE);
- ctrl->discard_page = alloc_page(GFP_KERNEL);
- if (!ctrl->discard_page) {
- ret = -ENOMEM;
- goto out;
- }
- ret = ida_alloc(&nvme_instance_ida, GFP_KERNEL);
- if (ret < 0)
- goto out;
- ctrl->instance = ret;
+ ctrl->instance = -1;
device_initialize(&ctrl->ctrl_device);
ctrl->device = &ctrl->ctrl_device;
@@ -4654,16 +4648,28 @@ 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);
+
+ ret = ida_alloc(&nvme_instance_ida, GFP_KERNEL);
+ if (ret < 0)
+ goto out;
+
+ ctrl->instance = ret;
ret = dev_set_name(ctrl->device, "nvme%d", ctrl->instance);
if (ret)
- goto out_release_instance;
+ goto out;
+
+ ctrl->discard_page = alloc_page(GFP_KERNEL);
+ if (!ctrl->discard_page) {
+ ret = -ENOMEM;
+ goto out;
+ }
nvme_get_ctrl(ctrl);
cdev_init(&ctrl->cdev, &nvme_dev_fops);
ctrl->cdev.owner = ops->module;
ret = cdev_device_add(&ctrl->cdev, ctrl->device);
if (ret)
- goto out_free_name;
+ goto out_put_ctrl;
/*
* Initialize latency tolerance controls. The sysfs files won't
@@ -4684,14 +4690,9 @@ int nvme_init_ctrl(struct nvme_ctrl *ctrl, struct device *dev,
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:
+out_put_ctrl:
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);
return ret;
}
EXPORT_SYMBOL_GPL(nvme_init_ctrl);
diff --git a/drivers/nvme/host/nvme.h b/drivers/nvme/host/nvme.h
index cacc56f4bbf4..c723c51e244a 100644
--- a/drivers/nvme/host/nvme.h
+++ b/drivers/nvme/host/nvme.h
@@ -368,6 +368,7 @@ struct nvme_ctrl {
struct nvme_dhchap_key *host_key;
struct nvme_dhchap_key *ctrl_key;
u16 transaction;
+ bool auth_initialized;
#endif
struct key *tls_key;
diff --git a/drivers/nvme/host/rdma.c b/drivers/nvme/host/rdma.c
index 51a62b0c645a..bc749bebe134 100644
--- a/drivers/nvme/host/rdma.c
+++ b/drivers/nvme/host/rdma.c
@@ -2302,7 +2302,7 @@ static struct nvme_ctrl *nvme_rdma_create_ctrl(struct device *dev,
ret = nvme_init_ctrl(&ctrl->ctrl, dev, &nvme_rdma_ctrl_ops,
0 /* no quirks, we're perfect! */);
if (ret)
- goto out_kfree_queues;
+ goto out_put_ctrl;
changed = nvme_change_ctrl_state(&ctrl->ctrl, NVME_CTRL_CONNECTING);
WARN_ON_ONCE(!changed);
@@ -2322,12 +2322,11 @@ 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;
return ERR_PTR(ret);
-out_kfree_queues:
- kfree(ctrl->queues);
out_free_ctrl:
kfree(ctrl);
return ERR_PTR(ret);
diff --git a/drivers/nvme/host/tcp.c b/drivers/nvme/host/tcp.c
index 8b5e4327fe83..9787a4fdbb00 100644
--- a/drivers/nvme/host/tcp.c
+++ b/drivers/nvme/host/tcp.c
@@ -2759,7 +2759,7 @@ static struct nvme_ctrl *nvme_tcp_create_ctrl(struct device *dev,
ret = nvme_init_ctrl(&ctrl->ctrl, dev, &nvme_tcp_ctrl_ops, 0);
if (ret)
- goto out_kfree_queues;
+ goto out_put_ctrl;
if (!nvme_change_ctrl_state(&ctrl->ctrl, NVME_CTRL_CONNECTING)) {
WARN_ON_ONCE(1);
@@ -2782,12 +2782,11 @@ 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;
return ERR_PTR(ret);
-out_kfree_queues:
- kfree(ctrl->queues);
out_free_ctrl:
kfree(ctrl);
return ERR_PTR(ret);
diff --git a/drivers/nvme/target/loop.c b/drivers/nvme/target/loop.c
index e589915ddef8..6d1359915b6c 100644
--- a/drivers/nvme/target/loop.c
+++ b/drivers/nvme/target/loop.c
@@ -550,10 +550,8 @@ static struct nvme_ctrl *nvme_loop_create_ctrl(struct device *dev,
ret = nvme_init_ctrl(&ctrl->ctrl, dev, &nvme_loop_ctrl_ops,
0 /* no quirks, we're perfect! */);
- if (ret) {
- kfree(ctrl);
+ if (ret)
goto out;
- }
if (!nvme_change_ctrl_state(&ctrl->ctrl, NVME_CTRL_CONNECTING))
WARN_ON_ONCE(1);
@@ -611,8 +609,8 @@ static struct nvme_ctrl *nvme_loop_create_ctrl(struct device *dev,
kfree(ctrl->queues);
out_uninit_ctrl:
nvme_uninit_ctrl(&ctrl->ctrl);
- nvme_put_ctrl(&ctrl->ctrl);
out:
+ nvme_put_ctrl(&ctrl->ctrl);
if (ret > 0)
ret = -EIO;
return ERR_PTR(ret);
--
2.43.0
prev parent reply other threads:[~2024-06-03 9:35 UTC|newest]
Thread overview: 19+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-05-26 19:47 blktests nvme 041,042 leak memory Sagi Grimberg
2024-05-27 1:11 ` Yi Zhang
2024-05-28 9:44 ` Maurizio Lombardi
2024-05-29 9:08 ` Maurizio Lombardi
2024-05-29 12:51 ` Sagi Grimberg
2024-05-29 13:45 ` Maurizio Lombardi
2024-05-29 16:25 ` Keith Busch
2024-05-29 16:48 ` Keith Busch
2024-05-30 6:59 ` Sagi Grimberg
2024-05-30 7:25 ` Maurizio Lombardi
2024-05-30 16:29 ` Keith Busch
2024-05-30 17:40 ` Maurizio Lombardi
2024-05-31 11:55 ` Maurizio Lombardi
2024-05-31 14:37 ` Maurizio Lombardi
2024-06-03 8:37 ` Hannes Reinecke
2024-06-03 8:52 ` Maurizio Lombardi
2024-06-03 9:33 ` Hannes Reinecke
2024-06-03 9:38 ` Maurizio Lombardi
2024-06-03 9:35 ` Maurizio Lombardi [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=Zl2OYgyN0exmIKk0@kalibr \
--to=m.lombardi85@mail.ru \
--cc=hare@suse.de \
--cc=kbusch@kernel.org \
--cc=linux-nvme@lists.infradead.org \
--cc=mlombard@redhat.com \
--cc=sagi@grimberg.me \
--cc=shinichiro.kawasaki@wdc.com \
--cc=yi.zhang@redhat.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox