Received: by 2002:ac0:a582:0:0:0:0:0 with SMTP id m2-v6csp3928886imm; Mon, 8 Oct 2018 11:51:00 -0700 (PDT) X-Google-Smtp-Source: ACcGV60vrdws4Obe9EzTziJ58xxcmzDCcCFzUwzMJDYfmBcVAS4qmV/Nvb4F9OzYnxqgiaPgWWNW X-Received: by 2002:a62:2606:: with SMTP id m6-v6mr24046891pfm.104.1539024660170; Mon, 08 Oct 2018 11:51:00 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1539024660; cv=none; d=google.com; s=arc-20160816; b=JkXPIIRUxtcgkfK5iNfwum2r1aQ+nBQlYtYbDT6YV0dlPOxyw+D3FoxxzRXs2Q9uWY VPnw+LNZxTU2+N9X0lJnf6Ns3jbY3aEbovVOYZdS17+uNc8XD5dEMoboDsBW2FXrmY38 d7qhnzMFnk9550X2+n2nfaZnGNWCdNGvcVns1k3TyIMdTHbD5uGD5+/p3jhjM8yg77Wy /lHp6mS6kxpEzw1nftWU5BNpKAVl57j1G2EFdBNTwuSwZvVlAnJCIyPnUcq5rNzLF8/C /PXZfS6YWWDNzhSk5AOW47Nz0CbjppBQTB7sDgvyyjZ3EOtYTFSASkkQMkU6YQT2YUjn c1HQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :user-agent:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=bscBZ0vRfbrmll3NsiQrm1L3dHBLUCZSzrO/9SXeA6k=; b=iBD1uuft8ooVMlpJzgCGQcTp64PWGfoZrQi/A5JMZbugUkJsbXit01VFWR867RnLRb th1HGF4tYbxt2PmCGS9+sFqJEH/YqVg05jBVwFm1Mx7xLkri7xhMA2L914E3keiF3JV0 l4JwLt9UFm3xQxJN1yLzjM23U4oDcRITKQto60aWN561WCcxV7to1xEM3kaCL/M+Y6FC SX1PdceEHyjYsR/fwIqMccVQG6+KaX+jQymuj1iYQfPJGHGCcNk8KzJedjrM2c/15c1R vki+capKfmPoYh8Shivmt3yGIUw3BDLZHjnB4pycAdNvA8aGR190lKXjsCMd14DlKvAg 9jAg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=eECjGeDO; 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 r13-v6si18383127pfb.43.2018.10.08.11.50.45; Mon, 08 Oct 2018 11:51:00 -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; dkim=pass header.i=@kernel.org header.s=default header.b=eECjGeDO; 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 S1732111AbeJICDk (ORCPT + 99 others); Mon, 8 Oct 2018 22:03:40 -0400 Received: from mail.kernel.org ([198.145.29.99]:53198 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726391AbeJICDj (ORCPT ); Mon, 8 Oct 2018 22:03:39 -0400 Received: from localhost (ip-213-127-77-176.ip.prioritytelecom.net [213.127.77.176]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id AF8CD21479; Mon, 8 Oct 2018 18:50:31 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1539024632; bh=eKBGKW6JqlfhSyRUGuhsEl/8Dc5H8/44s5cvxOGfdj0=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=eECjGeDOfNfw+vdGW7f0VW+bTKwGpVuUPOTS7VTjemDVNOSj5D/IIdBVDCjdmX1QK g1wsVu87TlRm2dljWQwnMjmsE5jpHQsAYfvt0cXOrOOR9AZUIWxUFWIaR2qDE/9QP9 h/dOK80vhl9RSC+Fok2VPssnFvEHOCDxElWRcfD4= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Steve Wise , Sagi Grimberg , Christoph Hellwig , Sasha Levin Subject: [PATCH 4.18 103/168] nvmet-rdma: fix possible bogus dereference under heavy load Date: Mon, 8 Oct 2018 20:31:23 +0200 Message-Id: <20181008175623.975423964@linuxfoundation.org> X-Mailer: git-send-email 2.19.0 In-Reply-To: <20181008175620.043587728@linuxfoundation.org> References: <20181008175620.043587728@linuxfoundation.org> User-Agent: quilt/0.65 X-stable: review MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 4.18-stable review patch. If anyone has any objections, please let me know. ------------------ From: Sagi Grimberg [ Upstream commit 8407879c4e0d7731f6e7e905893cecf61a7762c7 ] Currently we always repost the recv buffer before we send a response capsule back to the host. Since ordering is not guaranteed for send and recv completions, it is posible that we will receive a new request from the host before we got a send completion for the response capsule. Today, we pre-allocate 2x rsps the length of the queue, but in reality, under heavy load there is nothing that is really preventing the gap to expand until we exhaust all our rsps. To fix this, if we don't have any pre-allocated rsps left, we dynamically allocate a rsp and make sure to free it when we are done. If under memory pressure we fail to allocate a rsp, we silently drop the command and wait for the host to retry. Reported-by: Steve Wise Tested-by: Steve Wise Signed-off-by: Sagi Grimberg [hch: dropped a superflous assignment] Signed-off-by: Christoph Hellwig Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/nvme/target/rdma.c | 27 +++++++++++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) --- a/drivers/nvme/target/rdma.c +++ b/drivers/nvme/target/rdma.c @@ -65,6 +65,7 @@ struct nvmet_rdma_rsp { struct nvmet_req req; + bool allocated; u8 n_rdma; u32 flags; u32 invalidate_rkey; @@ -166,11 +167,19 @@ nvmet_rdma_get_rsp(struct nvmet_rdma_que unsigned long flags; spin_lock_irqsave(&queue->rsps_lock, flags); - rsp = list_first_entry(&queue->free_rsps, + rsp = list_first_entry_or_null(&queue->free_rsps, struct nvmet_rdma_rsp, free_list); - list_del(&rsp->free_list); + if (likely(rsp)) + list_del(&rsp->free_list); spin_unlock_irqrestore(&queue->rsps_lock, flags); + if (unlikely(!rsp)) { + rsp = kmalloc(sizeof(*rsp), GFP_KERNEL); + if (unlikely(!rsp)) + return NULL; + rsp->allocated = true; + } + return rsp; } @@ -179,6 +188,11 @@ nvmet_rdma_put_rsp(struct nvmet_rdma_rsp { unsigned long flags; + if (rsp->allocated) { + kfree(rsp); + return; + } + spin_lock_irqsave(&rsp->queue->rsps_lock, flags); list_add_tail(&rsp->free_list, &rsp->queue->free_rsps); spin_unlock_irqrestore(&rsp->queue->rsps_lock, flags); @@ -702,6 +716,15 @@ static void nvmet_rdma_recv_done(struct cmd->queue = queue; rsp = nvmet_rdma_get_rsp(queue); + if (unlikely(!rsp)) { + /* + * we get here only under memory pressure, + * silently drop and have the host retry + * as we can't even fail it. + */ + nvmet_rdma_post_recv(queue->dev, cmd); + return; + } rsp->queue = queue; rsp->cmd = cmd; rsp->flags = 0;