Received: by 2002:a05:6a10:206:0:0:0:0 with SMTP id 6csp4359754pxj; Tue, 8 Jun 2021 12:22:01 -0700 (PDT) X-Google-Smtp-Source: ABdhPJy49r4WCWsshlik+6MrcHUx0GYdP/xp5j+X6yd5FYjeNq96MWQXjYIN8JOZCccL64CXngs4 X-Received: by 2002:aa7:d78d:: with SMTP id s13mr27514318edq.208.1623180120945; Tue, 08 Jun 2021 12:22:00 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1623180120; cv=none; d=google.com; s=arc-20160816; b=alH9R8b++MgZtyv2lKOoJD8USjAIKxLPoYv+Sfo8FQPGs5ttfYnU+OYoGrp8NosyWg SMzW+VLtkunhsYouDLiCu2LhmTz7bWYaXDYbP/w+6X5du8cRb7jMdZDAeS3EeG3+a0nS rJwTS67W46oyB+JJS+Vb05bKg+N7bqWt+tfchefFvS9aCIIPElSZi23pSOSBOV1ztbJ0 45zS2GPulNmfbWr9FFnebRpDQls1ARspX9EInd64pELREO4gOvf06m9QW6i6E4Aw5Yz1 sY9ujHZfwxNM+BpQSRHPKJPbdROVxvyfunsgqUlzpQGSwF3jgEb/JcqfbgdJDFzrVdC5 HCTQ== 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=W+j5eA9BEL5Rq4tCoq9JiD2MZlhoRs4J2Tkwk8vA6B8=; b=MGYK0vhmHO1kRnb34oRHyLjGb8QTp9TwcVZ9Td02U3NWtB9OZ+/dug1+hbg7gK/i7S rnDN1PYP3uzgVAASOjNEDHj2u4Oz4Qh57vJl6p7+gZSZ7A2Ikxuc63rJYH0dP3KYFtch pDUxrNbMlUsgqxoTBZUSAlGvP3aItrCwlts7QWUxreSRJikP70OlCMuxOL+7/Qdm4kZJ mkuDsoJVncwAphzdhArHU6EqbTV6CVYz2WJ/1uvU6PCvUUT37rrE+Vmfp2yXwYRRUFZP nLzPQFcqOQnw2Oz3p42MgQc8wiV8rWy0vD1669VP/85ZuaRLdtw30y8v+ArvBfqooNlX drCA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b=D9IU4Q8d; 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 df25si472340edb.145.2021.06.08.12.21.38; Tue, 08 Jun 2021 12:22:00 -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=D9IU4Q8d; 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 S236232AbhFHTQv (ORCPT + 99 others); Tue, 8 Jun 2021 15:16:51 -0400 Received: from mail.kernel.org ([198.145.29.99]:40100 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S237822AbhFHTFg (ORCPT ); Tue, 8 Jun 2021 15:05:36 -0400 Received: by mail.kernel.org (Postfix) with ESMTPSA id 72A716142D; Tue, 8 Jun 2021 18:46:42 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=linuxfoundation.org; s=korg; t=1623178003; bh=4cpJrC+qDZ4i+XOG+qq41pqPN2GzUACvaDFGJms1hMQ=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=D9IU4Q8dodrahBBtbmghn1McdL4GeDarlS86A5bQLGabEj3AdTf+L64cQnQAqLDus JXHYXYS9azslHUW+AuWWDI0hxz2GMA9VSnZdCV83LuL2J7eIpSOkkfxhRGY2G4yjwS Bg1Js/VjzkJBNzu+kqVPYZ0uAHgZZ+XiKCymtdBg= 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.12 039/161] nvmet: fix freeing unallocated p2pmem Date: Tue, 8 Jun 2021 20:26:09 +0200 Message-Id: <20210608175946.783576152@linuxfoundation.org> X-Mailer: git-send-email 2.32.0 In-Reply-To: <20210608175945.476074951@linuxfoundation.org> References: <20210608175945.476074951@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 348057fdc568..7d16cb4cd8ac 100644 --- a/drivers/nvme/target/core.c +++ b/drivers/nvme/target/core.c @@ -999,19 +999,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); @@ -1019,25 +1023,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, @@ -1066,6 +1064,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