[PATCH] nvmet-tcp: fix memory leak when having inflight commands on disconnect
elad.grupi at dell.com
elad.grupi at dell.com
Mon May 24 04:24:41 PDT 2021
From: Elad Grupi <elad.grupi at dell.com>
Some nvme commands might get completed during the execution of
nvmet_tcp_release_queue_work. Those commands are being added to
resp_list on the queue and never processed after cancel_work_sync
is done, causing memory leak of the resources allocated for those commands.
Signed-off-by: Elad Grupi <elad.grupi at dell.com>
---
drivers/nvme/target/tcp.c | 28 ++++++++++++++++++++++++++++
1 file changed, 28 insertions(+)
diff --git a/drivers/nvme/target/tcp.c b/drivers/nvme/target/tcp.c
index f9f34f6caf5e..3c6e36c6ed4a 100644
--- a/drivers/nvme/target/tcp.c
+++ b/drivers/nvme/target/tcp.c
@@ -1426,6 +1426,33 @@ static void nvmet_tcp_uninit_data_in_cmds(struct nvmet_tcp_queue *queue)
}
}
+static void nvmet_tcp_free_resp_list(struct nvmet_tcp_queue *queue)
+{
+ struct list_head *p;
+ struct nvmet_tcp_cmd *cmd;
+ int c = 0;
+
+ nvmet_tcp_process_resp_list(queue);
+
+ list_for_each(p, &queue->resp_send_list) {
+ cmd = list_entry(p, struct nvmet_tcp_cmd, entry);
+ kfree(cmd->iov);
+ sgl_free(cmd->req.sg);
+ c++;
+ }
+
+ WARN_ON(c != queue->send_list_len);
+
+ if (queue->snd_cmd) {
+ kfree(queue->snd_cmd->iov);
+ sgl_free(queue->snd_cmd->req.sg);
+ c++;
+ }
+
+ pr_debug("qid %u send_list_len %d, free %d unprocessed commands\n",
+ queue->nvme_sq.qid, queue->send_list_len, c);
+}
+
static void nvmet_tcp_release_queue_work(struct work_struct *w)
{
struct nvmet_tcp_queue *queue =
@@ -1441,6 +1468,7 @@ static void nvmet_tcp_release_queue_work(struct work_struct *w)
nvmet_tcp_uninit_data_in_cmds(queue);
nvmet_sq_destroy(&queue->nvme_sq);
cancel_work_sync(&queue->io_work);
+ nvmet_tcp_free_resp_list(queue);
sock_release(queue->sock);
nvmet_tcp_free_cmds(queue);
if (queue->hdr_digest || queue->data_digest)
--
2.18.2
More information about the Linux-nvme
mailing list