Received: by 2002:a25:ab43:0:0:0:0:0 with SMTP id u61csp4577471ybi; Tue, 11 Jun 2019 08:53:59 -0700 (PDT) X-Google-Smtp-Source: APXvYqzx5An+yB0RQ/WZSb3BV32H1EHEQNnZYx1wdlhZ2mWihnfvb1aq0U7fzBaM8hvxCEgmJJPc X-Received: by 2002:a17:902:c83:: with SMTP id 3mr18655306plt.326.1560268439104; Tue, 11 Jun 2019 08:53:59 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1560268439; cv=none; d=google.com; s=arc-20160816; b=kb5fyx1nmssi8YY+Gq3+J1+blC833gYPSjrHpW1HFSgvw2LSZL0SVJYXE8TnVWu37i 0eTddGJ7Gv3KmIuqTMQxZuhYLhrFzEati3qzzwDNRDDBzaMym3VO2iUv505h7D3lud/O DPeT9pKCt0qYC76R/DW5++4WfEGp3MlKoRQ8vmOQifmT1F8JzGAAAEDb9xrSbYN2Hu3H meyymSixgo1B5ZznqS+vXQ+BCIeWFkjIa8+5xoatCp0dcRSUb3Mjn6ln9f/S1no8thma lmm6a5eb9YXoQL6T7Oh6EcNk6z28VXeb4D3eY+UgxidKNBFoECPj79MwsviRsHV9SmPw i+Aw== 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:to:from:subject :dkim-signature; bh=zzY6Uptd3ROAV+z9NkiuZ2yWpDluKKpERs4bvf+KRLA=; b=I0LflMf6+4EWjhPji43Ahp/bfm87bX/aRuS1Rlw5Lb+wbnAgw6rFXF5yoqWFjbP8Vd 4raV83HHWEW2f3Xw7iPZ/XrCDLZCeDJEn6MLwstfHx0m/tZ24zt+j0yIbyiV5XdlXWCq u9Olnix6v+q17GJ6Mm1YJVmjAjf9F6oc453AXwIq0fScqqX1leXv40m/1PKWWBbWmhbs yoSw2tr8nOvBmHfBmuTCfk+mAXdR73w36rOQ4PAhrinTepsYda3w7khgcX2E7TOUgLkK 1lvIh20sMiwDiPG2o3AFypGm69SoM5I6N/wl9R3xXlp0cwlRvkn2hXMLOgnKVuD8oUXz vEVw== ARC-Authentication-Results: i=1; mx.google.com; dkim=fail header.i=@gmail.com header.s=20161025 header.b=oTdNPfMw; spf=pass (google.com: best guess record for domain of linux-nfs-owner@vger.kernel.org designates 209.132.180.67 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. [209.132.180.67]) by mx.google.com with ESMTP id p11si12530389plk.67.2019.06.11.08.53.45; Tue, 11 Jun 2019 08:53:59 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-nfs-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=fail header.i=@gmail.com header.s=20161025 header.b=oTdNPfMw; spf=pass (google.com: best guess record for domain of linux-nfs-owner@vger.kernel.org designates 209.132.180.67 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 S2391726AbfFKPIt (ORCPT + 99 others); Tue, 11 Jun 2019 11:08:49 -0400 Received: from mail-io1-f68.google.com ([209.85.166.68]:43310 "EHLO mail-io1-f68.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2391700AbfFKPIs (ORCPT ); Tue, 11 Jun 2019 11:08:48 -0400 Received: by mail-io1-f68.google.com with SMTP id k20so10160261ios.10; Tue, 11 Jun 2019 08:08:48 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=sender:subject:from:to:date:message-id:in-reply-to:references :user-agent:mime-version:content-transfer-encoding; bh=zzY6Uptd3ROAV+z9NkiuZ2yWpDluKKpERs4bvf+KRLA=; b=oTdNPfMwXR/H3EmEr8iUY5kAQvqmGiD9TF9rs37Mf/dbmibfPUN3J/oYW/W019yFgq 6ppvM8BGqbphyB2nVURRndHaKdMbhFz6wEsgs+hS9zIm6p772e8R7Ys16PTftVboEmLs IdG2Ez59FYS594iicmf/zU7O2KdPJqzfk5lakq0geH3iBKp1slTaTP1ln7IgMxWZj03r iN4rb7z+GV+iWyueRlEoVpMUgSWn9XWvfdSqPnZD5W832iK8ImdDqjoR8yegcVfRVIyr uzGx5Rv2fS4npy+PE5Dotw5Ld4b10IEZMPi2ZRSMXGyXzKcNih/i+TTnf7My1f9iXRoy Y5pg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:subject:from:to:date:message-id :in-reply-to:references:user-agent:mime-version :content-transfer-encoding; bh=zzY6Uptd3ROAV+z9NkiuZ2yWpDluKKpERs4bvf+KRLA=; b=L2c8SohhN/t/UDABvlQ/uDgLy+0Cz92U5Afyi00a2zlj3jDxdoP0v5fxcYtIY4HIAC Iz19ckO9p17Z4WexT5eWFulwkvuskBYn/Oz6MLYyWBNJmMeb3xqoLyU9j0C2sWK81vAu 6wGuSF/m6Wmi0ZPwfBTJOIx3hoQzXQCnPdNxOVak5bvHFVNV9Ldk6op0S8NQMQcH7LYC lgHRJvQFfs/4AQoJPym1WTbduB9E4Z67VMLk2aaB1AVTwSqPEwQikOHAYZDwUMXe5Vb7 yeWCgxQOlY7u0NxYdPvs7nSIxaluZPMXJQmzUDr4aQ0N4AdoQdihCXpG0NVjTK6gfAq0 73Kg== X-Gm-Message-State: APjAAAWl70BzPDfUBUm/HbfUxnXwyV1X1MEJyeSqMuKybdAWXLva6hTd +QPTUhEpdjBVobLLxWG1Rzp8Tpd7 X-Received: by 2002:a5e:c705:: with SMTP id f5mr49676006iop.113.1560265727339; Tue, 11 Jun 2019 08:08:47 -0700 (PDT) Received: from gateway.1015granger.net (c-68-61-232-219.hsd1.mi.comcast.net. [68.61.232.219]) by smtp.gmail.com with ESMTPSA id m23sm1517301iti.0.2019.06.11.08.08.46 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 11 Jun 2019 08:08:46 -0700 (PDT) Received: from manet.1015granger.net (manet.1015granger.net [192.168.1.51]) by gateway.1015granger.net (8.14.7/8.14.7) with ESMTP id x5BF8kQk021752; Tue, 11 Jun 2019 15:08:46 GMT Subject: [PATCH v2 09/19] xprtrdma: Wake RPCs directly in rpcrdma_wc_send path From: Chuck Lever To: linux-rdma@vger.kernel.org, linux-nfs@vger.kernel.org Date: Tue, 11 Jun 2019 11:08:46 -0400 Message-ID: <20190611150846.2877.62136.stgit@manet.1015granger.net> In-Reply-To: <20190611150445.2877.8656.stgit@manet.1015granger.net> References: <20190611150445.2877.8656.stgit@manet.1015granger.net> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit Sender: linux-nfs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-nfs@vger.kernel.org Eliminate a context switch in the path that handles RPC wake-ups when a Receive completion has to wait for a Send completion. Signed-off-by: Chuck Lever --- net/sunrpc/xprtrdma/rpc_rdma.c | 61 +++++++++++++++------------------------ net/sunrpc/xprtrdma/transport.c | 10 ++++++ net/sunrpc/xprtrdma/verbs.c | 3 +- net/sunrpc/xprtrdma/xprt_rdma.h | 12 ++------ 4 files changed, 36 insertions(+), 50 deletions(-) diff --git a/net/sunrpc/xprtrdma/rpc_rdma.c b/net/sunrpc/xprtrdma/rpc_rdma.c index 33b6e6a..caf0b19 100644 --- a/net/sunrpc/xprtrdma/rpc_rdma.c +++ b/net/sunrpc/xprtrdma/rpc_rdma.c @@ -511,6 +511,16 @@ static bool rpcrdma_results_inline(struct rpcrdma_xprt *r_xprt, return 0; } +static void rpcrdma_sendctx_done(struct kref *kref) +{ + struct rpcrdma_req *req = + container_of(kref, struct rpcrdma_req, rl_kref); + struct rpcrdma_rep *rep = req->rl_reply; + + rpcrdma_complete_rqst(rep); + rep->rr_rxprt->rx_stats.reply_waits_for_send++; +} + /** * rpcrdma_sendctx_unmap - DMA-unmap Send buffer * @sc: sendctx containing SGEs to unmap @@ -520,6 +530,9 @@ void rpcrdma_sendctx_unmap(struct rpcrdma_sendctx *sc) { struct ib_sge *sge; + if (!sc->sc_unmap_count) + return; + /* The first two SGEs contain the transport header and * the inline buffer. These are always left mapped so * they can be cheaply re-used. @@ -529,9 +542,7 @@ void rpcrdma_sendctx_unmap(struct rpcrdma_sendctx *sc) ib_dma_unmap_page(sc->sc_device, sge->addr, sge->length, DMA_TO_DEVICE); - if (test_and_clear_bit(RPCRDMA_REQ_F_TX_RESOURCES, - &sc->sc_req->rl_flags)) - wake_up_bit(&sc->sc_req->rl_flags, RPCRDMA_REQ_F_TX_RESOURCES); + kref_put(&sc->sc_req->rl_kref, rpcrdma_sendctx_done); } /* Prepare an SGE for the RPC-over-RDMA transport header. @@ -666,7 +677,7 @@ static bool rpcrdma_prepare_msg_sges(struct rpcrdma_xprt *r_xprt, out: sc->sc_wr.num_sge += sge_no; if (sc->sc_unmap_count) - __set_bit(RPCRDMA_REQ_F_TX_RESOURCES, &req->rl_flags); + kref_get(&req->rl_kref); return true; out_regbuf: @@ -708,7 +719,7 @@ static bool rpcrdma_prepare_msg_sges(struct rpcrdma_xprt *r_xprt, req->rl_sendctx->sc_wr.num_sge = 0; req->rl_sendctx->sc_unmap_count = 0; req->rl_sendctx->sc_req = req; - __clear_bit(RPCRDMA_REQ_F_TX_RESOURCES, &req->rl_flags); + kref_init(&req->rl_kref); ret = -EIO; if (!rpcrdma_prepare_hdr_sge(r_xprt, req, hdrlen)) @@ -1268,36 +1279,12 @@ void rpcrdma_complete_rqst(struct rpcrdma_rep *rep) goto out; } -/* Ensure that any DMA mapped pages associated with - * the Send of the RPC Call have been unmapped before - * allowing the RPC to complete. This protects argument - * memory not controlled by the RPC client from being - * re-used before we're done with it. - */ -static void rpcrdma_release_tx(struct rpcrdma_xprt *r_xprt, - struct rpcrdma_req *req) +static void rpcrdma_reply_done(struct kref *kref) { - if (test_bit(RPCRDMA_REQ_F_TX_RESOURCES, &req->rl_flags)) { - r_xprt->rx_stats.reply_waits_for_send++; - out_of_line_wait_on_bit(&req->rl_flags, - RPCRDMA_REQ_F_TX_RESOURCES, - bit_wait, - TASK_UNINTERRUPTIBLE); - } -} + struct rpcrdma_req *req = + container_of(kref, struct rpcrdma_req, rl_kref); -/** - * rpcrdma_release_rqst - Release hardware resources - * @r_xprt: controlling transport instance - * @req: request with resources to release - * - */ -void rpcrdma_release_rqst(struct rpcrdma_xprt *r_xprt, struct rpcrdma_req *req) -{ - if (!list_empty(&req->rl_registered)) - frwr_unmap_sync(r_xprt, req); - - rpcrdma_release_tx(r_xprt, req); + rpcrdma_complete_rqst(req->rl_reply); } /** @@ -1367,13 +1354,11 @@ void rpcrdma_reply_handler(struct rpcrdma_rep *rep) if (rep->rr_wc_flags & IB_WC_WITH_INVALIDATE) frwr_reminv(rep, &req->rl_registered); - if (!list_empty(&req->rl_registered)) { + if (!list_empty(&req->rl_registered)) frwr_unmap_async(r_xprt, req); /* LocalInv completion will complete the RPC */ - } else { - rpcrdma_release_tx(r_xprt, req); - rpcrdma_complete_rqst(rep); - } + else + kref_put(&req->rl_kref, rpcrdma_reply_done); return; out_badversion: diff --git a/net/sunrpc/xprtrdma/transport.c b/net/sunrpc/xprtrdma/transport.c index f84375d..9575f1d 100644 --- a/net/sunrpc/xprtrdma/transport.c +++ b/net/sunrpc/xprtrdma/transport.c @@ -618,8 +618,16 @@ static bool rpcrdma_check_regbuf(struct rpcrdma_xprt *r_xprt, struct rpcrdma_xprt *r_xprt = rpcx_to_rdmax(rqst->rq_xprt); struct rpcrdma_req *req = rpcr_to_rdmar(rqst); - rpcrdma_release_rqst(r_xprt, req); trace_xprtrdma_op_free(task, req); + + if (!list_empty(&req->rl_registered)) + frwr_unmap_sync(r_xprt, req); + + /* XXX: If the RPC is completing because of a signal and + * not because a reply was received, we ought to ensure + * that the Send completion has fired, so that memory + * involved with the Send is not still visible to the NIC. + */ } /** diff --git a/net/sunrpc/xprtrdma/verbs.c b/net/sunrpc/xprtrdma/verbs.c index c50a4b2..4e22cc2 100644 --- a/net/sunrpc/xprtrdma/verbs.c +++ b/net/sunrpc/xprtrdma/verbs.c @@ -1462,8 +1462,7 @@ static void rpcrdma_regbuf_free(struct rpcrdma_regbuf *rb) struct ib_send_wr *send_wr = &req->rl_sendctx->sc_wr; int rc; - if (!ep->rep_send_count || - test_bit(RPCRDMA_REQ_F_TX_RESOURCES, &req->rl_flags)) { + if (!ep->rep_send_count || kref_read(&req->rl_kref) > 1) { send_wr->send_flags |= IB_SEND_SIGNALED; ep->rep_send_count = ep->rep_send_batch; } else { diff --git a/net/sunrpc/xprtrdma/xprt_rdma.h b/net/sunrpc/xprtrdma/xprt_rdma.h index e465221..5475f0d 100644 --- a/net/sunrpc/xprtrdma/xprt_rdma.h +++ b/net/sunrpc/xprtrdma/xprt_rdma.h @@ -44,7 +44,8 @@ #include /* wait_queue_head_t, etc */ #include /* spinlock_t, etc */ -#include /* atomic_t, etc */ +#include /* atomic_t, etc */ +#include /* struct kref */ #include /* struct work_struct */ #include /* RDMA connection api */ @@ -329,17 +330,12 @@ struct rpcrdma_req { struct rpcrdma_regbuf *rl_recvbuf; /* rq_rcv_buf */ struct list_head rl_all; - unsigned long rl_flags; + struct kref rl_kref; struct list_head rl_registered; /* registered segments */ struct rpcrdma_mr_seg rl_segments[RPCRDMA_MAX_SEGS]; }; -/* rl_flags */ -enum { - RPCRDMA_REQ_F_TX_RESOURCES, -}; - static inline struct rpcrdma_req * rpcr_to_rdmar(const struct rpc_rqst *rqst) { @@ -584,8 +580,6 @@ int rpcrdma_prepare_send_sges(struct rpcrdma_xprt *r_xprt, void rpcrdma_set_max_header_sizes(struct rpcrdma_xprt *); void rpcrdma_complete_rqst(struct rpcrdma_rep *rep); void rpcrdma_reply_handler(struct rpcrdma_rep *rep); -void rpcrdma_release_rqst(struct rpcrdma_xprt *r_xprt, - struct rpcrdma_req *req); static inline void rpcrdma_set_xdrlen(struct xdr_buf *xdr, size_t len) {