Received: by 10.192.165.156 with SMTP id m28csp235526imm; Tue, 10 Apr 2018 20:36:03 -0700 (PDT) X-Google-Smtp-Source: AIpwx4/vSwWS6pj7/35gktuXCEQm5QMG7lXZux+hwO5SgIE6sQ+jXYiredGswPox2PdkxOmALDmw X-Received: by 2002:a17:902:8e8c:: with SMTP id bg12-v6mr3237479plb.295.1523417763684; Tue, 10 Apr 2018 20:36:03 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1523417763; cv=none; d=google.com; s=arc-20160816; b=P1+o12+IO5zuYU7sc3thjBne//Tc3uTQr9FhmoE2/TmHCJt8Su6f74HNNApuUFE5rn zQ6TNG0jbRzbgfiUO9G+xKLnQT6qDg+6uBMmMmFbgh50aaAem9gOhDpfR7KbpqmAXs9l /Phkwm0I1F4P8/jILyMKxRGbGQNmg1m9NFADozncRqTOmZedEObu8icUetuh96wD+Anp SkpdVVO6OKf8SPcBttLZwQgS4fZmfr6S5IELDe4APr6XRiOiRLzgkCYxSRpTmcV+Jr2z TMMVsxJXoEInH9NaFSj4AVrz/0lBJsqPy+LJIji5wYeKhBoFZJg+mX1E7LBo+EFCFDwg BBCg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:mime-version:user-agent:references :in-reply-to:message-id:date:subject:cc:to:from :arc-authentication-results; bh=32f89VvVA52Kq2/GKrrpj3mQzS8zd0xYRcFwJeY65p8=; b=u5f2lJU6iDBfYNSZS7w7lO49GIYsjuFAtgOAEISS01ESST3/l1XTkL0koOKSyqJyVG gYvvNydpbyeNJcD7z32PDqOSI5tl2m8iAVO73rGhowOFdhGy7aDYT/xNeZhdD7m7Oq2t 0NUsf2JJVioikGdG6esa54MQdbN6CjZwFiWUNGdTSLPMH7a8FS+txt7ZVANkzH2z4lTR 7W7HMEk8vP40kWyMN8/0lg8z1J4mG6VDbnJtRBfh0LV2/CUKQuBTyZCjJXB4vgQPqHXt /akWtLxZHpNQe98B7kNogKTqb+yWJtjYHPrb10rDCRzdvH8JM2L+NyFyilclL0XBo9Un Ecbw== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id s8si146333pgv.369.2018.04.10.20.35.26; Tue, 10 Apr 2018 20:36:03 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932247AbeDJWfb (ORCPT + 99 others); Tue, 10 Apr 2018 18:35:31 -0400 Received: from mail.linuxfoundation.org ([140.211.169.12]:42154 "EHLO mail.linuxfoundation.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1755559AbeDJWf3 (ORCPT ); Tue, 10 Apr 2018 18:35:29 -0400 Received: from localhost (LFbn-1-12247-202.w90-92.abo.wanadoo.fr [90.92.61.202]) by mail.linuxfoundation.org (Postfix) with ESMTPSA id 68BA0DAC; Tue, 10 Apr 2018 22:35:28 +0000 (UTC) From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, James Smart , Christoph Hellwig , Sasha Levin Subject: [PATCH 4.14 043/138] nvme_fcloop: disassocate local port structs Date: Wed, 11 Apr 2018 00:23:53 +0200 Message-Id: <20180410212907.112110104@linuxfoundation.org> X-Mailer: git-send-email 2.17.0 In-Reply-To: <20180410212902.121524696@linuxfoundation.org> References: <20180410212902.121524696@linuxfoundation.org> User-Agent: quilt/0.65 X-stable: review MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 4.14-stable review patch. If anyone has any objections, please let me know. ------------------ From: James Smart [ 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. Signed-off-by: James Smart Signed-off-by: Christoph Hellwig Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/nvme/target/fcloop.c | 35 +++++++++++++++++++++++++---------- 1 file changed, 25 insertions(+), 10 deletions(-) --- a/drivers/nvme/target/fcloop.c +++ b/drivers/nvme/target/fcloop.c @@ -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 *np static 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_lpo wait_for_completion(&lport->unreg_done); + kfree(lport); + return ret; }