Received: by 2002:ac0:a5b6:0:0:0:0:0 with SMTP id m51-v6csp3710245imm; Mon, 18 Jun 2018 02:45:39 -0700 (PDT) X-Google-Smtp-Source: ADUXVKKErqPj/tmXL9PuqgnDtRlFfdqGd5gU/ERXf5S5JkWX2uwv5ovSsF7h40Hd8B6yU1vX644h X-Received: by 2002:a62:10c2:: with SMTP id 63-v6mr12715988pfq.229.1529315139150; Mon, 18 Jun 2018 02:45:39 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1529315139; cv=none; d=google.com; s=arc-20160816; b=deKdXeK5grRd0uYp7XJoXTAkDPeXGpP/epsCIAXbgs25Hj/xUTIgdY5HE/Xo7AkDfw c/9l4gmvTFv8T+jZRV9RZ8/u9Dzr6aR+oD0DZCWLSJIFBLrLdhLgsEAgmpU8UNEvNTSw tJ42A1ahg1GXgRqIRiWE4MyVbzCQm9y/VkrtngHwd8m5maGQvy/V0Qxs8S6B+Q+hXydw sZdYxDRoqQCsbHr8NfiqFAbuZ25wb3rqm7VoAaekSFJFYgm6IBtcu0/uW+yEpBa25c/Q Gj+2+L4BPyMRUrCv00h8czZS9MlaaYkWnV4kNYzWuoVCekr743uhaLu/+6PqSU2T1LZz 8GJw== 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=0jLRpj0lxabtopTqd998JlHpxR0gIPa6gzIURRUt+ns=; b=foLYFBPRc737+Vb/HQ6uax7Sgz05Tj2opn2uathQwGBG3cMQHH28YTCGEO6H7RBLac Xh7JW9Qy8120VtmdxuzUkcIiZ8zrdcjMGDLheUXmOhfciyD91nG2bPba12PwMvQYHWOS 7CzS2aPL6yJMDb0UG+E7QYfOoiomJqS5H/WwGK92/L0Hx9AceRBnefAS2Y8FsJY2Gg9u YBNh/5JpEB+kgm9PXD/4qJQ4IMDa9fL1ogYFDQC4FfvlR2rFqAPQno7DoJHcFHQfhLoA UmeXONPPed41+Fbta/vjEu7XbHcq5ssJ2+D5h5BhX1bNqJFcmn4Esk1KV36h3CScWTZE 2zRg== 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 o3-v6si14735984pld.50.2018.06.18.02.45.24; Mon, 18 Jun 2018 02:45:39 -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 S965329AbeFRIV7 (ORCPT + 99 others); Mon, 18 Jun 2018 04:21:59 -0400 Received: from mail.linuxfoundation.org ([140.211.169.12]:55416 "EHLO mail.linuxfoundation.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S965094AbeFRIV5 (ORCPT ); Mon, 18 Jun 2018 04:21:57 -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 73F5DC7F; Mon, 18 Jun 2018 08:21:56 +0000 (UTC) From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Chuck Lever , Anna Schumaker , Sasha Levin Subject: [PATCH 4.16 147/279] xprtrdma: Fix list corruption / DMAR errors during MR recovery Date: Mon, 18 Jun 2018 10:12:12 +0200 Message-Id: <20180618080614.902591107@linuxfoundation.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20180618080608.851973560@linuxfoundation.org> References: <20180618080608.851973560@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.16-stable review patch. If anyone has any objections, please let me know. ------------------ From: Chuck Lever [ Upstream commit 054f155721d7af1f343ed52bea246626d8450ca8 ] The ro_release_mr methods check whether mr->mr_list is empty. Therefore, be sure to always use list_del_init when removing an MR linked into a list using that field. Otherwise, when recovering from transport failures or device removal, list corruption can result, or MRs can get mapped or unmapped an odd number of times, resulting in IOMMU-related failures. In general this fix is appropriate back to v4.8. However, code changes since then make it impossible to apply this patch directly to stable kernels. The fix would have to be applied by hand or reworked for kernels earlier than v4.16. Backport guidance -- there are several cases: - When creating an MR, initialize mr_list so that using list_empty on an as-yet-unused MR is safe. - When an MR is being handled by the remote invalidation path, ensure that mr_list is reinitialized when it is removed from rl_registered. - When an MR is being handled by rpcrdma_destroy_mrs, it is removed from mr_all, but it may still be on an rl_registered list. In that case, the MR needs to be removed from that list before being released. - Other cases are covered by using list_del_init in rpcrdma_mr_pop. Fixes: 9d6b04097882 ('xprtrdma: Place registered MWs on a ... ') Signed-off-by: Chuck Lever Signed-off-by: Anna Schumaker Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- net/sunrpc/xprtrdma/fmr_ops.c | 5 +---- net/sunrpc/xprtrdma/frwr_ops.c | 9 +++------ net/sunrpc/xprtrdma/verbs.c | 5 +++++ net/sunrpc/xprtrdma/xprt_rdma.h | 2 +- 4 files changed, 10 insertions(+), 11 deletions(-) --- a/net/sunrpc/xprtrdma/fmr_ops.c +++ b/net/sunrpc/xprtrdma/fmr_ops.c @@ -72,6 +72,7 @@ fmr_op_init_mr(struct rpcrdma_ia *ia, st if (IS_ERR(mr->fmr.fm_mr)) goto out_fmr_err; + INIT_LIST_HEAD(&mr->mr_list); return 0; out_fmr_err: @@ -102,10 +103,6 @@ fmr_op_release_mr(struct rpcrdma_mr *mr) LIST_HEAD(unmap_list); int rc; - /* Ensure MW is not on any rl_registered list */ - if (!list_empty(&mr->mr_list)) - list_del(&mr->mr_list); - kfree(mr->fmr.fm_physaddrs); kfree(mr->mr_sg); --- a/net/sunrpc/xprtrdma/frwr_ops.c +++ b/net/sunrpc/xprtrdma/frwr_ops.c @@ -110,6 +110,7 @@ frwr_op_init_mr(struct rpcrdma_ia *ia, s if (!mr->mr_sg) goto out_list_err; + INIT_LIST_HEAD(&mr->mr_list); sg_init_table(mr->mr_sg, depth); init_completion(&frwr->fr_linv_done); return 0; @@ -133,10 +134,6 @@ frwr_op_release_mr(struct rpcrdma_mr *mr { int rc; - /* Ensure MR is not on any rl_registered list */ - if (!list_empty(&mr->mr_list)) - list_del(&mr->mr_list); - rc = ib_dereg_mr(mr->frwr.fr_mr); if (rc) pr_err("rpcrdma: final ib_dereg_mr for %p returned %i\n", @@ -195,7 +192,7 @@ frwr_op_recover_mr(struct rpcrdma_mr *mr return; out_release: - pr_err("rpcrdma: FRWR reset failed %d, %p release\n", rc, mr); + pr_err("rpcrdma: FRWR reset failed %d, %p released\n", rc, mr); r_xprt->rx_stats.mrs_orphaned++; spin_lock(&r_xprt->rx_buf.rb_mrlock); @@ -458,7 +455,7 @@ frwr_op_reminv(struct rpcrdma_rep *rep, list_for_each_entry(mr, mrs, mr_list) if (mr->mr_handle == rep->rr_inv_rkey) { - list_del(&mr->mr_list); + list_del_init(&mr->mr_list); trace_xprtrdma_remoteinv(mr); mr->frwr.fr_state = FRWR_IS_INVALID; rpcrdma_mr_unmap_and_put(mr); --- a/net/sunrpc/xprtrdma/verbs.c +++ b/net/sunrpc/xprtrdma/verbs.c @@ -1244,6 +1244,11 @@ rpcrdma_mrs_destroy(struct rpcrdma_buffe list_del(&mr->mr_all); spin_unlock(&buf->rb_mrlock); + + /* Ensure MW is not on any rl_registered list */ + if (!list_empty(&mr->mr_list)) + list_del(&mr->mr_list); + ia->ri_ops->ro_release_mr(mr); count++; spin_lock(&buf->rb_mrlock); --- a/net/sunrpc/xprtrdma/xprt_rdma.h +++ b/net/sunrpc/xprtrdma/xprt_rdma.h @@ -381,7 +381,7 @@ rpcrdma_mr_pop(struct list_head *list) struct rpcrdma_mr *mr; mr = list_first_entry(list, struct rpcrdma_mr, mr_list); - list_del(&mr->mr_list); + list_del_init(&mr->mr_list); return mr; }