Received: by 2002:a05:6a10:17d3:0:0:0:0 with SMTP id hz19csp2777278pxb; Mon, 19 Apr 2021 13:44:48 -0700 (PDT) X-Google-Smtp-Source: ABdhPJyrAX5BFzi4/HRNuzZCtRI9YcwQJgZxtu0jMZze5DO3v1Sqm4xhnNFjdu9Wk80u6+9MKy+L X-Received: by 2002:aa7:828f:0:b029:200:6e27:8c8f with SMTP id s15-20020aa7828f0000b02902006e278c8fmr21170428pfm.44.1618865088744; Mon, 19 Apr 2021 13:44:48 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1618865088; cv=none; d=google.com; s=arc-20160816; b=IAfX60SwMYsJVsLRJ7GcVhonIXxoxg8PkAY4vqQn4gjoLNsvFPNCXGPTa5cos0OFIH FIhmiAliemqM1JtZdMf9sD3QJCLIAPyCAOKcQccO3zy4n+eTK/PtDlMsm3Mr3eejzpg6 njQhLOPuO7DC2OrV4Kgj21eC6J6lXlq77kVAGSKNxt/UQXcBqVmKNR90lPMDPMY4+Ezm yOsrwgSXsZ4AfYWYpb+5UdYA2qJdMrsdXpHKMDLYrHTmflit65md3WqivXAJ6DivsZMJ g54CfTEiz9tZX7itIvtTC3KqdPi5f3Lp0iqp0uFeUiA8VV0vcXRLgOaGBSPHYKzBGysb rN2Q== 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:cc:to:from :subject; bh=UMnka4G/Vvq5Popi2TD2NXGddGXqVSuGViMOTxgVAU8=; b=V+3XhT3FejJQSoRta1erqpLMYNkjRi/YcwW2hh4YSuComPduBkkbmjpPPT5fUUGALE 8KgrZQv7niPFDa0nnYFeWdavTadTn6QHKhiVSTkOsadDzisIZwfhR5AXm0RI1XpKehB7 xLHULhA2JexJloyz4+6uTwDrCRPPKDB51DWjpEoSwyFE7OUd7D6MRdB2rTqvT+hvzQbJ oSUdeZ149NN7QzKcsgC/DPNZzIQo87KBEU2i3BnvImakUZpG85N+T2UEQYGCnTdbBIml w0Ba3neTMab+51G0EMrHHdmMuxqY670o19O/j94apYG2/GG/gwyhrfZ2YskH/9nIy+3w bW3g== 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 gw21si618657pjb.31.2021.04.19.13.44.34; Mon, 19 Apr 2021 13:44:48 -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 S240566AbhDSSDw (ORCPT + 99 others); Mon, 19 Apr 2021 14:03:52 -0400 Received: from mail.kernel.org ([198.145.29.99]:41290 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S240553AbhDSSDu (ORCPT ); Mon, 19 Apr 2021 14:03:50 -0400 Received: by mail.kernel.org (Postfix) with ESMTPSA id E9EE361001; Mon, 19 Apr 2021 18:03:19 +0000 (UTC) Subject: [PATCH v3 16/26] xprtrdma: Do not wake RPC consumer on a failed LocalInv From: Chuck Lever To: trondmy@hammerspace.com Cc: linux-nfs@vger.kernel.org, linux-rdma@vger.kernel.org Date: Mon, 19 Apr 2021 14:03:19 -0400 Message-ID: <161885539919.38598.16197910600306542657.stgit@manet.1015granger.net> In-Reply-To: <161885481568.38598.16682844600209775665.stgit@manet.1015granger.net> References: <161885481568.38598.16682844600209775665.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)