From: Christoph Hellwig <hch@infradead.org>
To: David Milburn <dmilburn@redhat.com>
Cc: Christoph Hellwig <hch@infradead.org>,
linux-nvme@lists.infradead.org, dwagner@suse.de,
Sagi Grimberg <sagi@grimberg.me>,
chaitanya.kulkarni@wdc.com
Subject: Re: [PATCH v2 2/2] nvmet: avoid memleak by freeing any remaining aens in nvmet_async_events_free
Date: Wed, 20 May 2020 10:27:41 -0700 [thread overview]
Message-ID: <20200520172741.GB22182@infradead.org> (raw)
In-Reply-To: <41bae172-289e-1407-93a6-4147491a346c@redhat.com>
On Wed, May 20, 2020 at 05:39:18AM -0500, David Milburn wrote:
> Yi was able to reproduce the memleak using the v2 of the patch series
> since nvmet_async_events_free() ran before nvmet_add_async_event().
>
> http://lists.infradead.org/pipermail/linux-nvme/2020-May/030512.html
>
> With Sagi's patch below, I do see after nvmet_add_async_event(),
> nvmet_async_events_process pulls the request, decrements
> ctrl->nr_async_event_cmds to 0, and frees the aen,
> and no memory leak.
>
> http://lists.infradead.org/pipermail/linux-nvme/2020-May/030548.html
Ok, let's try a version of Sagis latest suggestion then. What about
this (replacement for this patch only, I applied the first one already):
diff --git a/drivers/nvme/target/core.c b/drivers/nvme/target/core.c
index 54679260e6648..1525426d0a31f 100644
--- a/drivers/nvme/target/core.c
+++ b/drivers/nvme/target/core.c
@@ -129,8 +129,10 @@ static u32 nvmet_async_event_result(struct nvmet_async_event *aen)
return aen->event_type | (aen->event_info << 8) | (aen->log_page << 16);
}
-static void nvmet_async_events_process(struct nvmet_ctrl *ctrl, u16 status)
+static void nvmet_async_event_work(struct work_struct *work)
{
+ struct nvmet_ctrl *ctrl =
+ container_of(work, struct nvmet_ctrl, async_event_work);
struct nvmet_async_event *aen;
struct nvmet_req *req;
@@ -139,21 +141,20 @@ static void nvmet_async_events_process(struct nvmet_ctrl *ctrl, u16 status)
aen = list_first_entry(&ctrl->async_events,
struct nvmet_async_event, entry);
req = ctrl->async_event_cmds[--ctrl->nr_async_event_cmds];
- if (status == 0)
- nvmet_set_result(req, nvmet_async_event_result(aen));
+ nvmet_set_result(req, nvmet_async_event_result(aen));
list_del(&aen->entry);
kfree(aen);
mutex_unlock(&ctrl->lock);
trace_nvmet_async_event(ctrl, req->cqe->result.u32);
- nvmet_req_complete(req, status);
+ nvmet_req_complete(req, 0);
mutex_lock(&ctrl->lock);
}
mutex_unlock(&ctrl->lock);
}
-static void nvmet_async_events_free(struct nvmet_ctrl *ctrl)
+static void nvmet_async_events_fail_all(struct nvmet_ctrl *ctrl)
{
struct nvmet_req *req;
@@ -167,12 +168,14 @@ static void nvmet_async_events_free(struct nvmet_ctrl *ctrl)
mutex_unlock(&ctrl->lock);
}
-static void nvmet_async_event_work(struct work_struct *work)
+static void nvmet_async_events_free(struct nvmet_ctrl *ctrl)
{
- struct nvmet_ctrl *ctrl =
- container_of(work, struct nvmet_ctrl, async_event_work);
+ struct nvmet_async_event *aen, *n;
- nvmet_async_events_process(ctrl, 0);
+ list_for_each_entry_safe(aen, n, &ctrl->async_events, entry) {
+ list_del(&aen->entry);
+ kfree(aen);
+ }
}
void nvmet_add_async_event(struct nvmet_ctrl *ctrl, u8 event_type,
@@ -768,17 +771,14 @@ static void nvmet_confirm_sq(struct percpu_ref *ref)
void nvmet_sq_destroy(struct nvmet_sq *sq)
{
- u16 status = NVME_SC_INTERNAL | NVME_SC_DNR;
struct nvmet_ctrl *ctrl = sq->ctrl;
/*
* If this is the admin queue, complete all AERs so that our
* queue doesn't have outstanding requests on it.
*/
- if (ctrl && ctrl->sqs && ctrl->sqs[0] == sq) {
- nvmet_async_events_process(ctrl, status);
- nvmet_async_events_free(ctrl);
- }
+ if (ctrl && ctrl->sqs && ctrl->sqs[0] == sq)
+ nvmet_async_events_fail_all(ctrl);
percpu_ref_kill_and_confirm(&sq->ref, nvmet_confirm_sq);
wait_for_completion(&sq->confirm_done);
wait_for_completion(&sq->free_done);
@@ -1368,6 +1368,7 @@ static void nvmet_ctrl_free(struct kref *ref)
ida_simple_remove(&cntlid_ida, ctrl->cntlid);
+ nvmet_async_events_free(ctrl);
kfree(ctrl->sqs);
kfree(ctrl->cqs);
kfree(ctrl->changed_ns_list);
_______________________________________________
linux-nvme mailing list
linux-nvme@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-nvme
next prev parent reply other threads:[~2020-05-20 17:27 UTC|newest]
Thread overview: 29+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-05-18 18:59 [PATCH v2 0/2] nvmet: fixup processing async events David Milburn
2020-05-18 18:59 ` [PATCH v2 1/2] nvmet: check command slot before pulling and freeing aen David Milburn
2020-05-20 17:18 ` Christoph Hellwig
2020-05-18 18:59 ` [PATCH v2 2/2] nvmet: avoid memleak by freeing any remaining aens in nvmet_async_events_free David Milburn
2020-05-19 8:33 ` Sagi Grimberg
2020-05-19 19:14 ` David Milburn
2020-05-19 20:42 ` Sagi Grimberg
2020-05-19 20:51 ` Sagi Grimberg
2020-05-20 6:18 ` Christoph Hellwig
2020-05-20 7:01 ` Sagi Grimberg
2020-05-20 6:16 ` Christoph Hellwig
2020-05-20 6:59 ` Sagi Grimberg
2020-05-20 7:03 ` Christoph Hellwig
2020-05-20 7:08 ` Sagi Grimberg
2020-05-20 7:15 ` Christoph Hellwig
2020-05-20 8:06 ` Sagi Grimberg
2020-05-20 10:39 ` David Milburn
2020-05-20 17:19 ` Sagi Grimberg
2020-05-20 17:23 ` David Milburn
2020-05-20 17:30 ` Christoph Hellwig
2020-05-20 17:27 ` Christoph Hellwig [this message]
2020-05-20 17:41 ` Sagi Grimberg
2020-05-20 17:46 ` Christoph Hellwig
2020-05-20 18:04 ` Sagi Grimberg
2020-05-20 18:15 ` Christoph Hellwig
2020-05-20 19:40 ` Sagi Grimberg
2020-05-19 8:40 ` [PATCH v2 0/2] nvmet: fixup processing async events Chaitanya Kulkarni
2020-05-19 19:17 ` David Milburn
2020-05-20 6:20 ` hch
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=20200520172741.GB22182@infradead.org \
--to=hch@infradead.org \
--cc=chaitanya.kulkarni@wdc.com \
--cc=dmilburn@redhat.com \
--cc=dwagner@suse.de \
--cc=linux-nvme@lists.infradead.org \
--cc=sagi@grimberg.me \
/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