Received: by 2002:a05:6a10:206:0:0:0:0 with SMTP id 6csp4848109pxj; Wed, 9 Jun 2021 03:26:54 -0700 (PDT) X-Google-Smtp-Source: ABdhPJwq50CgEEr6JSonsNTcjEcSs9is5awSM9tbd9CBB+i3WKRmr8xDNoYU80eLxHF+CY9wKAVg X-Received: by 2002:a17:906:606:: with SMTP id s6mr27430314ejb.206.1623234414041; Wed, 09 Jun 2021 03:26:54 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1623234414; cv=none; d=google.com; s=arc-20160816; b=uT6pZNMKDpKc58rciPKeYC4GlEHVHic+hEG9+BT6ihS72zXn533DHG1N6DCbPp87DT jk2nHjEU6dOwgZ+tAGa+g5YPqsne4Vxg86draBry2wDV1iLcvErhMKWbkdrVuYpReh/+ TOnGqQh86GD7WwSWW9Q1Kp86Gq67+2stoPKuzcaoQPzHCUkk81N/WBGex71ZKJzOfK/S 4QYDUwNiapXRbq/BalW9sAuKE+dMBO2DdheG5a7Nzvqu7yZ/5JSzxJTqzGRlS+co/xgf DJQS7vjxn4v33H2rn5sSZxXY3DSIHdgmgRFOX3Qp8GHEIdTqdykc17ZN7HXXFuh9yCAx 8AZg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :user-agent:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=+p0IzgyxGStv4rneb3PNuQdUshnXTwmo01P0CG+uiwY=; b=XyWZnBpkgzoYl7wrnIXsxhN7f0xQTNYuPqQqJreeP6HS6NBNUhbAXxjg2PXPWIiCcW b2ryfe52aALHu2sUJjPuvefAlUQLsak7e8udnIK/PHxqBA9juONmSINbZDkmHQPIOBkd EArdhUzeqNx3SyIPxB1M4Dja7aW37K93N1eBN+Jctwh/LMdDNJBLZmwEqx1oSOk814Ez cXsc5fO3TfzXmHS8S4iIcT+/IawF+KQtTBbLCkL4sfDL3RKBV7TbAi3BfTSbVqk/V3hf Eei+NMbp+b2yayYSCmiskeWaEZ67uUQHcE4hywJgHL9ZaMB6bTef938HQr+84nrMqHlY jkWg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b=HOIZrc5n; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linuxfoundation.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id y7si2021853edd.593.2021.06.09.03.26.30; Wed, 09 Jun 2021 03:26:54 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b=HOIZrc5n; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linuxfoundation.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234781AbhFHS6t (ORCPT + 99 others); Tue, 8 Jun 2021 14:58:49 -0400 Received: from mail.kernel.org ([198.145.29.99]:48452 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235976AbhFHSwH (ORCPT ); Tue, 8 Jun 2021 14:52:07 -0400 Received: by mail.kernel.org (Postfix) with ESMTPSA id 71A3061376; Tue, 8 Jun 2021 18:40:08 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=linuxfoundation.org; s=korg; t=1623177609; bh=Bwe6XoLtofniYeM5aZxEBFbkK0EPzcC2VDo/n+04e+I=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=HOIZrc5ns7Vz//rRPr+LDDPheUvbIs9KxDfdqvXB1A2IJ77adbzUXS/M1cmXk46S8 A/OzKL1QLwaCv7HQNhvxcQaHzOEvMEtPt2dqqsaGXEo2drR2wAD8Nf9Yn3q3Z2F8Gp t018Sb4eW/Zzo5gq/iiE20FpWYFmjuul1gStidlA= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Israel Rukshin , Max Gurtovoy , Logan Gunthorpe , Chaitanya Kulkarni , Christoph Hellwig , Sasha Levin Subject: [PATCH 5.10 033/137] nvmet: fix freeing unallocated p2pmem Date: Tue, 8 Jun 2021 20:26:13 +0200 Message-Id: <20210608175943.532766707@linuxfoundation.org> X-Mailer: git-send-email 2.32.0 In-Reply-To: <20210608175942.377073879@linuxfoundation.org> References: <20210608175942.377073879@linuxfoundation.org> User-Agent: quilt/0.66 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Max Gurtovoy [ Upstream commit bcd9a0797d73eeff659582f23277e7ab6e5f18f3 ] In case p2p device was found but the p2p pool is empty, the nvme target is still trying to free the sgl from the p2p pool instead of the regular sgl pool and causing a crash (BUG() is called). Instead, assign the p2p_dev for the request only if it was allocated from p2p pool. This is the crash that was caused: [Sun May 30 19:13:53 2021] ------------[ cut here ]------------ [Sun May 30 19:13:53 2021] kernel BUG at lib/genalloc.c:518! [Sun May 30 19:13:53 2021] invalid opcode: 0000 [#1] SMP PTI ... [Sun May 30 19:13:53 2021] kernel BUG at lib/genalloc.c:518! ... [Sun May 30 19:13:53 2021] RIP: 0010:gen_pool_free_owner+0xa8/0xb0 ... [Sun May 30 19:13:53 2021] Call Trace: [Sun May 30 19:13:53 2021] ------------[ cut here ]------------ [Sun May 30 19:13:53 2021] pci_free_p2pmem+0x2b/0x70 [Sun May 30 19:13:53 2021] pci_p2pmem_free_sgl+0x4f/0x80 [Sun May 30 19:13:53 2021] nvmet_req_free_sgls+0x1e/0x80 [nvmet] [Sun May 30 19:13:53 2021] kernel BUG at lib/genalloc.c:518! [Sun May 30 19:13:53 2021] nvmet_rdma_release_rsp+0x4e/0x1f0 [nvmet_rdma] [Sun May 30 19:13:53 2021] nvmet_rdma_send_done+0x1c/0x60 [nvmet_rdma] Fixes: c6e3f1339812 ("nvmet: add metadata support for block devices") Reviewed-by: Israel Rukshin Signed-off-by: Max Gurtovoy Reviewed-by: Logan Gunthorpe Reviewed-by: Chaitanya Kulkarni Signed-off-by: Christoph Hellwig Signed-off-by: Sasha Levin --- drivers/nvme/target/core.c | 33 ++++++++++++++++----------------- 1 file changed, 16 insertions(+), 17 deletions(-) diff --git a/drivers/nvme/target/core.c b/drivers/nvme/target/core.c index 46e4f7ea34c8..8b939e9db470 100644 --- a/drivers/nvme/target/core.c +++ b/drivers/nvme/target/core.c @@ -988,19 +988,23 @@ static unsigned int nvmet_data_transfer_len(struct nvmet_req *req) return req->transfer_len - req->metadata_len; } -static int nvmet_req_alloc_p2pmem_sgls(struct nvmet_req *req) +static int nvmet_req_alloc_p2pmem_sgls(struct pci_dev *p2p_dev, + struct nvmet_req *req) { - req->sg = pci_p2pmem_alloc_sgl(req->p2p_dev, &req->sg_cnt, + req->sg = pci_p2pmem_alloc_sgl(p2p_dev, &req->sg_cnt, nvmet_data_transfer_len(req)); if (!req->sg) goto out_err; if (req->metadata_len) { - req->metadata_sg = pci_p2pmem_alloc_sgl(req->p2p_dev, + req->metadata_sg = pci_p2pmem_alloc_sgl(p2p_dev, &req->metadata_sg_cnt, req->metadata_len); if (!req->metadata_sg) goto out_free_sg; } + + req->p2p_dev = p2p_dev; + return 0; out_free_sg: pci_p2pmem_free_sgl(req->p2p_dev, req->sg); @@ -1008,25 +1012,19 @@ out_err: return -ENOMEM; } -static bool nvmet_req_find_p2p_dev(struct nvmet_req *req) +static struct pci_dev *nvmet_req_find_p2p_dev(struct nvmet_req *req) { - if (!IS_ENABLED(CONFIG_PCI_P2PDMA)) - return false; - - if (req->sq->ctrl && req->sq->qid && req->ns) { - req->p2p_dev = radix_tree_lookup(&req->sq->ctrl->p2p_ns_map, - req->ns->nsid); - if (req->p2p_dev) - return true; - } - - req->p2p_dev = NULL; - return false; + if (!IS_ENABLED(CONFIG_PCI_P2PDMA) || + !req->sq->ctrl || !req->sq->qid || !req->ns) + return NULL; + return radix_tree_lookup(&req->sq->ctrl->p2p_ns_map, req->ns->nsid); } int nvmet_req_alloc_sgls(struct nvmet_req *req) { - if (nvmet_req_find_p2p_dev(req) && !nvmet_req_alloc_p2pmem_sgls(req)) + struct pci_dev *p2p_dev = nvmet_req_find_p2p_dev(req); + + if (p2p_dev && !nvmet_req_alloc_p2pmem_sgls(p2p_dev, req)) return 0; req->sg = sgl_alloc(nvmet_data_transfer_len(req), GFP_KERNEL, @@ -1055,6 +1053,7 @@ void nvmet_req_free_sgls(struct nvmet_req *req) pci_p2pmem_free_sgl(req->p2p_dev, req->sg); if (req->metadata_sg) pci_p2pmem_free_sgl(req->p2p_dev, req->metadata_sg); + req->p2p_dev = NULL; } else { sgl_free(req->sg); if (req->metadata_sg) -- 2.30.2