Received: by 2002:a05:6a10:9848:0:0:0:0 with SMTP id x8csp3706657pxf; Mon, 5 Apr 2021 20:51:07 -0700 (PDT) X-Google-Smtp-Source: ABdhPJwMemex81eGACDnyWeFVr3paWSepvFH/BedhVeYZNv9hC2STjGFUe+8JQkIhdr1hTb+Iyq3 X-Received: by 2002:a05:6638:3ba:: with SMTP id z26mr27684007jap.40.1617681067422; Mon, 05 Apr 2021 20:51:07 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1617681067; cv=none; d=google.com; s=arc-20160816; b=JxyOz4RmLg5LQQw9dJsY9vvTigq1mTJ4B2TPEkyV+OcD4XW23GK8erVVETSg6U25NL Jr6/LGPLdFanEEh0aR/huNhQtyKbhxhvJheUtF2Phyjy1BHg7obpcIJ4pqZq6gM3sJHG uySmCV5M00ltLrkRHEfgSyxv1RGxhhl3WJr2EaRvroRs7ZkDhocuZYVBHSkZQrrmYDQ0 mbIvXmWuQtD1ml3MTCgsy6kSq8+fMlH8nkUkA3Fay0KY7//LxhxC7BZYlvnpgqtoiGlE M/uIWwFobp1Hl9YzxGJmMHEyO6WCYsHaFp1qoEjMG6Uv0CcV7T0i7Mes9gyb3zanrNPy UVOw== 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:to:from:subject; bh=UMnka4G/Vvq5Popi2TD2NXGddGXqVSuGViMOTxgVAU8=; b=bN0l6Y3qlrsTzviasQ+WSaSAxbZtfAoROSiCaPb2MospuzH9JAnIjzDgRN2iHtHskQ fYudeXNguamWafgc5nI2IrkSAvWEZH5Ivk5bEffCON8N2jafvv19Faov2mYLKUkPMqaC JMh3ClCoSqgmmmErTSK7bBulS8iGC/ZKgSMX/CHA1tFG533uWUQ4EBxj7g3TMv+qkr9v iqPGxPGi0FGlIxRfngQXLDHGUMiM644IihMicpY4fvWYe2Q2Nk9YstI0+Tp3LODEh4GC sp3aMEHkxMBIVOBVcrXYtkZRuvoWHyx6h80kct3lP+9+dN6bQ7tTzy8QKEKJZjpM13/2 7iPQ== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of linux-nfs-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-nfs-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=oracle.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id q8si15599304iog.50.2021.04.05.20.50.54; Mon, 05 Apr 2021 20:51:07 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-nfs-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; spf=pass (google.com: domain of linux-nfs-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-nfs-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=oracle.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S242402AbhDEQfZ (ORCPT + 99 others); Mon, 5 Apr 2021 12:35:25 -0400 Received: from mail.kernel.org ([198.145.29.99]:40864 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S238877AbhDEQfZ (ORCPT ); Mon, 5 Apr 2021 12:35:25 -0400 Received: by mail.kernel.org (Postfix) with ESMTPSA id 9A5FC60FDB; Mon, 5 Apr 2021 16:35:18 +0000 (UTC) Subject: [PATCH v1 5/6] xprtrdma: Do not wake RPC consumer on a failed LocalInv From: Chuck Lever To: linux-rdma@vger.kernel.org, linux-nfs@vger.kernel.org Date: Mon, 05 Apr 2021 12:35:17 -0400 Message-ID: <161764051785.29855.4833398750635827274.stgit@manet.1015granger.net> In-Reply-To: <161764034907.29855.614994107807503843.stgit@manet.1015granger.net> References: <161764034907.29855.614994107807503843.stgit@manet.1015granger.net> User-Agent: StGit/0.23-29-ga622f1 MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit Precedence: bulk List-ID: X-Mailing-List: linux-nfs@vger.kernel.org Throw away any reply where the LocalInv flushes or could not be posted. The registered memory region is in an unknown state until the disconnect completes. rpcrdma_xprt_disconnect() will find and release the MR. No need to put it back on the MR free list in this case. The client retransmits pending RPC requests once it reestablishes a fresh connection, so a replacement reply should be forthcoming on the next connection instance. Signed-off-by: Chuck Lever --- net/sunrpc/xprtrdma/frwr_ops.c | 17 +++++++++++------ net/sunrpc/xprtrdma/rpc_rdma.c | 32 +++++++++++++++++++++++++++++--- net/sunrpc/xprtrdma/xprt_rdma.h | 1 + 3 files changed, 41 insertions(+), 9 deletions(-) diff --git a/net/sunrpc/xprtrdma/frwr_ops.c b/net/sunrpc/xprtrdma/frwr_ops.c index 27087dc8ba3c..951ae20485f3 100644 --- a/net/sunrpc/xprtrdma/frwr_ops.c +++ b/net/sunrpc/xprtrdma/frwr_ops.c @@ -576,10 +576,14 @@ static void frwr_wc_localinv_done(struct ib_cq *cq, struct ib_wc *wc) rep = mr->mr_req->rl_reply; smp_rmb(); - frwr_mr_done(wc, mr); + if (wc->status != IB_WC_SUCCESS) { + if (rep) + rpcrdma_unpin_rqst(rep); + rpcrdma_flush_disconnect(cq->cq_context, wc); + return; + } + frwr_mr_put(mr); rpcrdma_complete_rqst(rep); - - rpcrdma_flush_disconnect(cq->cq_context, wc); } /** @@ -645,8 +649,9 @@ void frwr_unmap_async(struct rpcrdma_xprt *r_xprt, struct rpcrdma_req *req) trace_xprtrdma_post_linv_err(req, rc); /* The final LOCAL_INV WR in the chain is supposed to - * do the wake. If it was never posted, the wake will - * not happen, so wake here in that case. + * do the wake. If it was never posted, the wake does + * not happen. Unpin the rqst in preparation for its + * retransmission. */ - rpcrdma_complete_rqst(req->rl_reply); + rpcrdma_unpin_rqst(req->rl_reply); } diff --git a/net/sunrpc/xprtrdma/rpc_rdma.c b/net/sunrpc/xprtrdma/rpc_rdma.c index be4e888e78a3..649f7d8b9733 100644 --- a/net/sunrpc/xprtrdma/rpc_rdma.c +++ b/net/sunrpc/xprtrdma/rpc_rdma.c @@ -1326,9 +1326,35 @@ rpcrdma_decode_error(struct rpcrdma_xprt *r_xprt, struct rpcrdma_rep *rep, return -EIO; } -/* Perform XID lookup, reconstruction of the RPC reply, and - * RPC completion while holding the transport lock to ensure - * the rep, rqst, and rq_task pointers remain stable. +/** + * rpcrdma_unpin_rqst - Release rqst without completing it + * @rep: RPC/RDMA Receive context + * + * This is done when a connection is lost so that a Reply + * can be dropped and its matching Call can be subsequently + * retransmitted on a new connection. + */ +void rpcrdma_unpin_rqst(struct rpcrdma_rep *rep) +{ + struct rpc_xprt *xprt = &rep->rr_rxprt->rx_xprt; + struct rpc_rqst *rqst = rep->rr_rqst; + struct rpcrdma_req *req = rpcr_to_rdmar(rqst); + + req->rl_reply = NULL; + rep->rr_rqst = NULL; + + spin_lock(&xprt->queue_lock); + xprt_unpin_rqst(rqst); + spin_unlock(&xprt->queue_lock); +} + +/** + * rpcrdma_complete_rqst - Pass completed rqst back to RPC + * @rep: RPC/RDMA Receive context + * + * Reconstruct the RPC reply and complete the transaction + * while @rqst is still pinned to ensure the rep, rqst, and + * rq_task pointers remain stable. */ void rpcrdma_complete_rqst(struct rpcrdma_rep *rep) { diff --git a/net/sunrpc/xprtrdma/xprt_rdma.h b/net/sunrpc/xprtrdma/xprt_rdma.h index 1b187d1dee8a..bb8aba390b88 100644 --- a/net/sunrpc/xprtrdma/xprt_rdma.h +++ b/net/sunrpc/xprtrdma/xprt_rdma.h @@ -561,6 +561,7 @@ int rpcrdma_marshal_req(struct rpcrdma_xprt *r_xprt, struct rpc_rqst *rqst); void rpcrdma_set_max_header_sizes(struct rpcrdma_ep *ep); void rpcrdma_reset_cwnd(struct rpcrdma_xprt *r_xprt); void rpcrdma_complete_rqst(struct rpcrdma_rep *rep); +void rpcrdma_unpin_rqst(struct rpcrdma_rep *rep); void rpcrdma_reply_handler(struct rpcrdma_rep *rep); static inline void rpcrdma_set_xdrlen(struct xdr_buf *xdr, size_t len)