Patch "nvme_fcloop: disassocate local port structs" has been added to the 4.14-stable tree
Subsystems (3)
This is a note to let you know that I've just added the patch titled
nvme_fcloop: disassocate local port structs
to the 4.14-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary
The filename of the patch is:
nvme_fcloop-disassocate-local-port-structs.patch
and it can be found in the queue-4.14 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree, please let <[email protected]> know about it.
Quoted 1 line
From foo@baz Mon Apr 9 13:58:16 CEST 2018
From: James Smart <[email protected]>
Date: Wed, 29 Nov 2017 16:47:31 -0800
Subject: nvme_fcloop: disassocate local port structs
From: James Smart <[email protected]>
[ Upstream commit 6fda20283e55b9d288cd56822ce39fc8e64f2208 ]
The current fcloop driver gets its lport structure from the private area co-allocated with the fc_localport. All is fine except the teardown path, which wants to wait on the completion, which is marked complete by the delete_localport callback performed after unregister_localport. The issue is, the nvme_fc transport frees the localport structure immediately after delete_localport is called, meaning the original routine is trying to wait on a complete that was just freed.
Change such that a lport struct is allocated coincident with the addition and registration of a localport. The private area of the localport now contains just a backpointer to the real lport struct. Now, the completion can be waited for, and after completing, the new structure can be kfree'd.
--- drivers/nvme/target/fcloop.c | 35 +++++++++++++++++++++++++---------- 1 file changed, 25 insertions(+), 10 deletions(-)
drivers/nvme/target/fcloop.c +25 -10
@@ -204,6 +204,10 @@ struct fcloop_lport {struct completion unreg_done; }; +struct fcloop_lport_priv { +struct fcloop_lport *lport; +}; +struct fcloop_rport {struct nvme_fc_remote_port *remoteport;struct nvmet_fc_target_port *targetport;
@@ -657,7 +661,8 @@ fcloop_nport_get(struct fcloop_nport *npstatic void fcloop_localport_delete (struct nvme_fc_local_port *localport) { -struct fcloop_lport *lport = localport->private; +struct fcloop_lport_priv *lport_priv = localport->private; +struct fcloop_lport *lport = lport_priv->lport;/* release any threads waiting for the unreg to complete */ complete (&lport->unreg_done);
@@ -697,7 +702,7 @@ static struct nvme_fc_port_template fcte .max_dif_sgl_segments = FCLOOP_SGL_SEGS, .dma_boundary = FCLOOP_DMABOUND_4G,/* sizes of additional private data for data structures */ - .local_priv_sz = sizeof(struct fcloop_lport), + .local_priv_sz = sizeof(struct fcloop_lport_priv), .remote_priv_sz = sizeof(struct fcloop_rport), .lsrqst_priv_sz = sizeof(struct fcloop_lsreq), .fcprqst_priv_sz = sizeof(struct fcloop_ini_fcpreq),
@@ -728,11 +733,17 @@ fcloop_create_local_port(struct device *struct fcloop_ctrl_options *opts;struct nvme_fc_local_port *localport;struct fcloop_lport *lport; -int ret; +struct fcloop_lport_priv *lport_priv; +unsigned long flags; +int ret = -ENOMEM ; + + lport =kzalloc (sizeof (*lport),GFP_KERNEL ); +if (!lport) +return -ENOMEM ; opts =kzalloc (sizeof (*opts),GFP_KERNEL );if (!opts) -return -ENOMEM ; + goto out_free_lport; ret =fcloop_parse_options (opts, buf);if (ret)
@@ -752,23 +763,25 @@ fcloop_create_local_port(struct device * ret =nvme_fc_register_localport (&pinfo, &fctemplate,NULL , &localport);if (!ret) { -unsigned long flags; -/* success */ - lport = localport->private; + lport_priv = localport->private; + lport_priv->lport = lport; + lport->localport = localport;INIT_LIST_HEAD (&lport->lport_list);spin_lock_irqsave (&fcloop_lock, flags);list_add_tail (&lport->lport_list, &fcloop_lports);spin_unlock_irqrestore (&fcloop_lock, flags); - -/* mark all of the input buffer consumed */ - ret = count; } out_free_opts:kfree (opts); +out_free_lport: +/* free only if we're going to fail */ +if (ret) +kfree (lport); +return ret ? ret : count; }
@@ -790,6 +803,8 @@ __wait_localport_unreg(struct fcloop_lpowait_for_completion (&lport->unreg_done); +kfree (lport); +return ret; }
Patches currently in stable-queue which might be from [email protected] are
queue-4.14/nvme_fcloop-fix-abort-race-condition.patch queue-4.14/nvme_fcloop-disassocate-local-port-structs.patch