Received: by 10.192.165.156 with SMTP id m28csp22624imm; Tue, 10 Apr 2018 15:34:22 -0700 (PDT) X-Google-Smtp-Source: AIpwx48yzFOWL8ZCexPB867qZgh5CWr3d/fadMpQwFyvpMXLwA2hxzKaZSpFEH653MQOVQRNUSJM X-Received: by 2002:a17:902:8602:: with SMTP id f2-v6mr2237984plo.73.1523399662635; Tue, 10 Apr 2018 15:34:22 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1523399662; cv=none; d=google.com; s=arc-20160816; b=vRUxg86NjolfcES580JGihNXqDbOI90xoMknD6D6ozzqSFi/7dChO5CngJFGad5Wlh gbLVY54DSU85SjzG40RJAtQc1dSHZ9jySl45VO1AMQ8cc8yH51AAwSuB5QavGuGoiiHm L58u7tG0XGyrJoHWIzN4zSZCUfYW4D7c9EWEisokTLGbkZCmYFszlXY2nwHPSGTnkq/d /MueuptzZsYwt/h56MR2BIxjzm2CwGH4NSsuSX8xk3r0RGyPLb/g/C3wQ5qq/12Gjiui 50LO81Jbc8MnydXhM0T2BUJntndPNdbfB5dMqUhtEDOoS9GEXZBnO4uQEvLkhlLBP0uD RXTQ== 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=2W3g3E3oHEL+idXNgy5S3hU/5WgpZCOpxhep77uJ7G4=; b=avI9tXnzvzlaW6USzQZLVKkil1/lpMn9zShfJ/Nt+yRJ6UJzh37WkFHdeW9F2fQtr2 iTI524c6mAnY193GBdyZ7W+2oUCwr1r9cyZbvomwQCl9uw82hOe1HDovUxaf0MU303qV n3c3Nc1YQMTLDieGhoGdsdHda4vQUMLPyAjk338sBPj2sFgCgmfN26c/yN0Xhu50Mndz 6FRf9WafqSC3JS0ebMycte0L5Qr66Adyb3JwTMy2ff5oDKEm+Nv63rxr0RTwXj+FKZio xBp3vkBYfA4AI5i15+AHuksEwED7YJl9p/Kgv+Lc6uXpMnWj8vYAqWQwlDKukjHHXsPn jIhg== 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 y62si2838319pfd.309.2018.04.10.15.33.45; Tue, 10 Apr 2018 15:34:22 -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 S1754264AbeDJW3P (ORCPT + 99 others); Tue, 10 Apr 2018 18:29:15 -0400 Received: from mail.linuxfoundation.org ([140.211.169.12]:39412 "EHLO mail.linuxfoundation.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754223AbeDJW3M (ORCPT ); Tue, 10 Apr 2018 18:29:12 -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 C914BD4F; Tue, 10 Apr 2018 22:29:11 +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.15 058/168] nvme_fcloop: disassocate local port structs Date: Wed, 11 Apr 2018 00:23:20 +0200 Message-Id: <20180410212802.680195717@linuxfoundation.org> X-Mailer: git-send-email 2.17.0 In-Reply-To: <20180410212800.144079021@linuxfoundation.org> References: <20180410212800.144079021@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.15-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; }