From patchwork Sun Jul 9 20:04:59 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Chuck Lever X-Patchwork-Id: 13306097 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 6806BEB64DC for ; Sun, 9 Jul 2023 20:05:04 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229876AbjGIUFD (ORCPT ); Sun, 9 Jul 2023 16:05:03 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:51854 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229441AbjGIUFC (ORCPT ); Sun, 9 Jul 2023 16:05:02 -0400 Received: from dfw.source.kernel.org (dfw.source.kernel.org [IPv6:2604:1380:4641:c500::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 4F47CFE for ; Sun, 9 Jul 2023 13:05:01 -0700 (PDT) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id D87AF60C20 for ; Sun, 9 Jul 2023 20:05:00 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 1228CC433C7; Sun, 9 Jul 2023 20:05:00 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1688933100; bh=ZXO4VBboXz6nwlfOObYIiSKQYzW7iklyQb04SlyKTsU=; h=Subject:From:To:Cc:Date:In-Reply-To:References:From; b=P33eoAx7wzlz5LAh3FNKJ0NmB8Zb4ZxxDaMwHoN6yQFhM8frKbr/b4+hmKJjJD9aL wOCGicAbYLOCg6LpTG1KVJt2QaPsj/ELZx+LL9DmRbL96iT17aHvoh73eeyZC4Ol5x 9u0813/AGyYY+jzgs+0ZprV/6dXiRvwf8w60NwV2mzua3nKJ7xhvAbtVhWp4UvGUav 0K2r8QzeZ3EeUowpYGVWEuKuGtDTVcrX6PG4DWZeS13zg36MUaLEx+N1SBPZgfTgHa aIviv5PoHoRUCS5bCQyX2wpbPQxPhKiIUyJ8mfzxjFQqP0oGWKxlreK8MNrG9TUlbG Rs3QFpLvbWlRg== Subject: [PATCH RFC 1/4] SUNRPC: Convert svc_tcp_sendmsg to use bio_vecs directly From: Chuck Lever To: linux-nfs@vger.kernel.org Cc: Chuck Lever , dhowells@redhat.com Date: Sun, 09 Jul 2023 16:04:59 -0400 Message-ID: <168893309913.1949.840437707678733371.stgit@manet.1015granger.net> In-Reply-To: <168893265677.1949.1632048925203798962.stgit@manet.1015granger.net> References: <168893265677.1949.1632048925203798962.stgit@manet.1015granger.net> User-Agent: StGit/1.5 MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-nfs@vger.kernel.org From: Chuck Lever Add a helper to convert a whole xdr_buf directly into an array of bio_vecs, then send this array instead of iterating piecemeal over the xdr_buf containing the outbound RPC message. Note that the rules of the RPC protocol mean there can be only one outstanding send at a time on a transport socket. The kernel's SunRPC server enforces this via the transport's xpt_mutex. Thus we can use a per-transport shared array for the xdr_buf conversion rather than allocate one every time or use one that is part of struct svc_rqst. Signed-off-by: Chuck Lever --- include/linux/sunrpc/svcsock.h | 3 + net/sunrpc/svcsock.c | 93 +++++++++++++++++++++++----------------- 2 files changed, 56 insertions(+), 40 deletions(-) diff --git a/include/linux/sunrpc/svcsock.h b/include/linux/sunrpc/svcsock.h index a7116048a4d4..a9bfeadf4cbe 100644 --- a/include/linux/sunrpc/svcsock.h +++ b/include/linux/sunrpc/svcsock.h @@ -40,6 +40,9 @@ struct svc_sock { struct completion sk_handshake_done; + struct bio_vec sk_send_bvec[RPCSVC_MAXPAGES] + ____cacheline_aligned; + struct page * sk_pages[RPCSVC_MAXPAGES]; /* received data */ }; diff --git a/net/sunrpc/svcsock.c b/net/sunrpc/svcsock.c index e43f26382411..d3c5f1a07979 100644 --- a/net/sunrpc/svcsock.c +++ b/net/sunrpc/svcsock.c @@ -188,6 +188,42 @@ static int svc_sock_result_payload(struct svc_rqst *rqstp, unsigned int offset, return 0; } +static unsigned int svc_sock_xdr_to_bvecs(struct bio_vec *bvec, + struct xdr_buf *xdr) +{ + const struct kvec *head = xdr->head; + const struct kvec *tail = xdr->tail; + unsigned int count = 0; + + if (head->iov_len) { + bvec_set_virt(bvec++, head->iov_base, head->iov_len); + count++; + } + + if (xdr->page_len) { + unsigned int offset, len, remaining; + struct page **pages = xdr->pages; + + offset = offset_in_page(xdr->page_base); + remaining = xdr->page_len; + while (remaining > 0) { + len = min_t(unsigned int, remaining, + PAGE_SIZE - offset); + bvec_set_page(bvec++, *pages++, len, offset); + remaining -= len; + offset = 0; + count++; + } + } + + if (tail->iov_len) { + bvec_set_virt(bvec, tail->iov_base, tail->iov_len); + count++; + } + + return count; +} + /* * Report socket names for nfsdfs */ @@ -1194,72 +1230,50 @@ static int svc_tcp_recvfrom(struct svc_rqst *rqstp) return 0; /* record not complete */ } -static int svc_tcp_send_kvec(struct socket *sock, const struct kvec *vec, - int flags) -{ - struct msghdr msg = { .msg_flags = MSG_SPLICE_PAGES | flags, }; - - iov_iter_kvec(&msg.msg_iter, ITER_SOURCE, vec, 1, vec->iov_len); - return sock_sendmsg(sock, &msg); -} - /* * MSG_SPLICE_PAGES is used exclusively to reduce the number of * copy operations in this path. Therefore the caller must ensure * that the pages backing @xdr are unchanging. * - * In addition, the logic assumes that * .bv_len is never larger - * than PAGE_SIZE. + * Note that the send is non-blocking. The caller has incremented + * the reference count on each page backing the RPC message, and + * the network layer will "put" these pages when transmission is + * complete. + * + * This is safe for our RPC services because the memory backing + * the head and tail components is never kmalloc'd. These always + * come from pages in the svc_rqst::rq_pages array. */ -static int svc_tcp_sendmsg(struct socket *sock, struct xdr_buf *xdr, +static int svc_tcp_sendmsg(struct svc_sock *svsk, struct xdr_buf *xdr, rpc_fraghdr marker, unsigned int *sentp) { - const struct kvec *head = xdr->head; - const struct kvec *tail = xdr->tail; struct kvec rm = { .iov_base = &marker, .iov_len = sizeof(marker), }; struct msghdr msg = { - .msg_flags = 0, + .msg_flags = MSG_MORE, }; + unsigned int count; int ret; *sentp = 0; - ret = xdr_alloc_bvec(xdr, GFP_KERNEL); - if (ret < 0) - return ret; - ret = kernel_sendmsg(sock, &msg, &rm, 1, rm.iov_len); + ret = kernel_sendmsg(svsk->sk_sock, &msg, &rm, 1, rm.iov_len); if (ret < 0) return ret; *sentp += ret; if (ret != rm.iov_len) return -EAGAIN; - ret = svc_tcp_send_kvec(sock, head, 0); - if (ret < 0) - return ret; - *sentp += ret; - if (ret != head->iov_len) - goto out; - + count = svc_sock_xdr_to_bvecs(svsk->sk_send_bvec, xdr); msg.msg_flags = MSG_SPLICE_PAGES; - iov_iter_bvec(&msg.msg_iter, ITER_SOURCE, xdr->bvec, - xdr_buf_pagecount(xdr), xdr->page_len); - ret = sock_sendmsg(sock, &msg); + iov_iter_bvec(&msg.msg_iter, ITER_SOURCE, svsk->sk_send_bvec, + count, xdr->len); + ret = sock_sendmsg(svsk->sk_sock, &msg); if (ret < 0) return ret; *sentp += ret; - - if (tail->iov_len) { - ret = svc_tcp_send_kvec(sock, tail, 0); - if (ret < 0) - return ret; - *sentp += ret; - } - -out: return 0; } @@ -1290,8 +1304,7 @@ static int svc_tcp_sendto(struct svc_rqst *rqstp) if (svc_xprt_is_dead(xprt)) goto out_notconn; tcp_sock_set_cork(svsk->sk_sk, true); - err = svc_tcp_sendmsg(svsk->sk_sock, xdr, marker, &sent); - xdr_free_bvec(xdr); + err = svc_tcp_sendmsg(svsk, xdr, marker, &sent); trace_svcsock_tcp_send(xprt, err < 0 ? (long)err : sent); if (err < 0 || sent != (xdr->len + sizeof(marker))) goto out_close; From patchwork Sun Jul 9 20:05:05 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Chuck Lever X-Patchwork-Id: 13306098 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id D1EDAEB64DD for ; Sun, 9 Jul 2023 20:05:10 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229554AbjGIUFJ (ORCPT ); Sun, 9 Jul 2023 16:05:09 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:51880 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229441AbjGIUFI (ORCPT ); Sun, 9 Jul 2023 16:05:08 -0400 Received: from dfw.source.kernel.org (dfw.source.kernel.org [139.178.84.217]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 96F47FE for ; Sun, 9 Jul 2023 13:05:07 -0700 (PDT) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id 3101860691 for ; Sun, 9 Jul 2023 20:05:07 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 5DF29C433C7; Sun, 9 Jul 2023 20:05:06 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1688933106; bh=aAHnJnucxrZOZRQ/gTjDMNguv+ZJw0XWnbv6SMqZelY=; h=Subject:From:To:Cc:Date:In-Reply-To:References:From; b=LDwrQ9E+H08hXQKLIebjxIp/KTj0EGAdAewBh6kfkq7mYtvRXwhYVl03lHlqMB1sT oJ7WciTbfCEx7019ifx8bLsm/ScRFofma92Nl3kbV8uc28UhZ6hZSpLSkZMnGPHOrd Sev9AcNtR3HX8a8n+1kqmr8+bhvIR9VCQyXm5ZZ6aQeYO6ndTYQy4BQvClKTm5KsMm OdvABBz/eJSrZVvAidoMDu22AjCa4uF2199SbdacwRahaYD1nJ9rLKpgIFZCfwjqvx sL2qWUiGjUCv6POHtynx953lL8nMOzpovcMafJNXR5efISMsJl45pyFuZogZbJ3trg aKhvI+cnABzsg== Subject: [PATCH RFC 2/4] SUNRPC: Convert svc_udp_sendto() to use the per-socket bio_vec array From: Chuck Lever To: linux-nfs@vger.kernel.org Cc: Chuck Lever , dhowells@redhat.com Date: Sun, 09 Jul 2023 16:05:05 -0400 Message-ID: <168893310550.1949.17162895369192976101.stgit@manet.1015granger.net> In-Reply-To: <168893265677.1949.1632048925203798962.stgit@manet.1015granger.net> References: <168893265677.1949.1632048925203798962.stgit@manet.1015granger.net> User-Agent: StGit/1.5 MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-nfs@vger.kernel.org From: Chuck Lever Commit da1661b93bf4 ("SUNRPC: Teach server to use xprt_sock_sendmsg for socket sends") modified svc_udp_sendto() to use xprt_sock_sendmsg() because we originally believed xprt_sock_sendmsg() would be needed for TLS support. That does not actually appear to be the case. In addition, the linkage between the client and server send code has been a bit of a maintenance headache because of the distinct ways that the client and server handle memory allocation. Going forward, eventually the XDR layer will deal with its buffers in the form of bio_vec arrays, so convert this function accordingly. Once the use of bio_vecs is ubiquitous, the xdr_buf-to-bio_vec array code can be hoisted into a path that is common for all transports. Signed-off-by: Chuck Lever --- net/sunrpc/svcsock.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/net/sunrpc/svcsock.c b/net/sunrpc/svcsock.c index d3c5f1a07979..ae7143f68343 100644 --- a/net/sunrpc/svcsock.c +++ b/net/sunrpc/svcsock.c @@ -729,7 +729,7 @@ static int svc_udp_sendto(struct svc_rqst *rqstp) .msg_control = cmh, .msg_controllen = sizeof(buffer), }; - unsigned int sent; + unsigned int count; int err; svc_udp_release_ctxt(xprt, rqstp->rq_xprt_ctxt); @@ -742,22 +742,22 @@ static int svc_udp_sendto(struct svc_rqst *rqstp) if (svc_xprt_is_dead(xprt)) goto out_notconn; - err = xdr_alloc_bvec(xdr, GFP_KERNEL); - if (err < 0) - goto out_unlock; + count = svc_sock_xdr_to_bvecs(svsk->sk_send_bvec, xdr); - err = xprt_sock_sendmsg(svsk->sk_sock, &msg, xdr, 0, 0, &sent); + iov_iter_bvec(&msg.msg_iter, ITER_SOURCE, svsk->sk_send_bvec, + count, 0); + err = sock_sendmsg(svsk->sk_sock, &msg); if (err == -ECONNREFUSED) { /* ICMP error on earlier request. */ - err = xprt_sock_sendmsg(svsk->sk_sock, &msg, xdr, 0, 0, &sent); + iov_iter_bvec(&msg.msg_iter, ITER_SOURCE, svsk->sk_send_bvec, + count, 0); + err = sock_sendmsg(svsk->sk_sock, &msg); } - xdr_free_bvec(xdr); + trace_svcsock_udp_send(xprt, err); -out_unlock: + mutex_unlock(&xprt->xpt_mutex); - if (err < 0) - return err; - return sent; + return err; out_notconn: mutex_unlock(&xprt->xpt_mutex); From patchwork Sun Jul 9 20:05:11 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Chuck Lever X-Patchwork-Id: 13306099 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 5E595EB64DD for ; Sun, 9 Jul 2023 20:05:16 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229884AbjGIUFP (ORCPT ); Sun, 9 Jul 2023 16:05:15 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:51904 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229441AbjGIUFO (ORCPT ); Sun, 9 Jul 2023 16:05:14 -0400 Received: from dfw.source.kernel.org (dfw.source.kernel.org [139.178.84.217]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 01D19FE for ; Sun, 9 Jul 2023 13:05:14 -0700 (PDT) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id 8F92E60C20 for ; Sun, 9 Jul 2023 20:05:13 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id BDFFCC433C7; Sun, 9 Jul 2023 20:05:12 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1688933113; bh=fou8AGJVg7txseqewnRn0AjTBVgDNvNRiu8TRqNRdGE=; h=Subject:From:To:Cc:Date:In-Reply-To:References:From; b=f6poD2pOHsZfS7G83N4DG7cvKaNHC+YDY9smk8KyAG2XOVDPhknxpkMxyUIjGeF+p 0qVP07AC3m6xEPs7N3R2+0J0H4Y9XSDtyyIMEe3z7LBO01oVWMpzkz5nz5cbgntMZR e958Y0B8jYu4qW76Xpl1kFFIvywTuPtCZSyuMhw1/Gf/XyLPa2wjpx4Mg7r/Mizgxp h1NhYkUy5QZr2X0VZL2Hu26xlxhWtP/w2G+rFdOiw2OE+VKh6OmUpto3ZhIdX6qyOK tcbIEKXWVTIbgsY1sD+S+G6XWADllB8TuYcGfuywyYBu/4pcHmrm5u/xm3ys0WigAy bCeJZex0qCE/w== Subject: [PATCH RFC 3/4] SUNRPC: Use a per-transport receive bio_vec array From: Chuck Lever To: linux-nfs@vger.kernel.org Cc: Chuck Lever , dhowells@redhat.com Date: Sun, 09 Jul 2023 16:05:11 -0400 Message-ID: <168893311179.1949.11410720662404392708.stgit@manet.1015granger.net> In-Reply-To: <168893265677.1949.1632048925203798962.stgit@manet.1015granger.net> References: <168893265677.1949.1632048925203798962.stgit@manet.1015granger.net> User-Agent: StGit/1.5 MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-nfs@vger.kernel.org From: Chuck Lever TCP receives are serialized, so we need only one bio_vec array per socket. This shrinks the size of struct svc_rqst by 4144 bytes on x86_64. Signed-off-by: Chuck Lever --- include/linux/sunrpc/svc.h | 1 - include/linux/sunrpc/svcsock.h | 2 ++ net/sunrpc/svcsock.c | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/include/linux/sunrpc/svc.h b/include/linux/sunrpc/svc.h index f8751118c122..36052188222d 100644 --- a/include/linux/sunrpc/svc.h +++ b/include/linux/sunrpc/svc.h @@ -224,7 +224,6 @@ struct svc_rqst { struct folio_batch rq_fbatch; struct kvec rq_vec[RPCSVC_MAXPAGES]; /* generally useful.. */ - struct bio_vec rq_bvec[RPCSVC_MAXPAGES]; __be32 rq_xid; /* transmission id */ u32 rq_prog; /* program number */ diff --git a/include/linux/sunrpc/svcsock.h b/include/linux/sunrpc/svcsock.h index a9bfeadf4cbe..4efae760f3cb 100644 --- a/include/linux/sunrpc/svcsock.h +++ b/include/linux/sunrpc/svcsock.h @@ -40,6 +40,8 @@ struct svc_sock { struct completion sk_handshake_done; + struct bio_vec sk_recv_bvec[RPCSVC_MAXPAGES] + ____cacheline_aligned; struct bio_vec sk_send_bvec[RPCSVC_MAXPAGES] ____cacheline_aligned; diff --git a/net/sunrpc/svcsock.c b/net/sunrpc/svcsock.c index ae7143f68343..6f672cb0b0b3 100644 --- a/net/sunrpc/svcsock.c +++ b/net/sunrpc/svcsock.c @@ -333,7 +333,7 @@ static ssize_t svc_tcp_read_msg(struct svc_rqst *rqstp, size_t buflen, { struct svc_sock *svsk = container_of(rqstp->rq_xprt, struct svc_sock, sk_xprt); - struct bio_vec *bvec = rqstp->rq_bvec; + struct bio_vec *bvec = svsk->sk_recv_bvec; struct msghdr msg = { NULL }; unsigned int i; ssize_t len; From patchwork Sun Jul 9 20:05:18 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Chuck Lever X-Patchwork-Id: 13306100 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id EE4D8EB64DD for ; Sun, 9 Jul 2023 20:05:22 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229624AbjGIUFW (ORCPT ); Sun, 9 Jul 2023 16:05:22 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:51934 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229441AbjGIUFV (ORCPT ); Sun, 9 Jul 2023 16:05:21 -0400 Received: from dfw.source.kernel.org (dfw.source.kernel.org [139.178.84.217]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 5F466FE for ; Sun, 9 Jul 2023 13:05:20 -0700 (PDT) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id F22F760C20 for ; Sun, 9 Jul 2023 20:05:19 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 2FA5CC433C8; Sun, 9 Jul 2023 20:05:19 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1688933119; bh=f6izZdO3VuQUntLxWUjulGDu7AYVq4c1pjyxSeg2vZU=; h=Subject:From:To:Cc:Date:In-Reply-To:References:From; b=oyY8eUPF/0med4CPeMC5FGwDSUh0l1qGh+uXCOXlkojZOP4KfzNSX/WKWCheRkWXR 1otknn1YBf74GKmgUFKHeq8SyXHScONivQP5kdTbA40CP+XmyoO6IuJz7Y0ap3m57W rNgWC0Bk8oHwbGLt1ukY9BHySqLUn+QG0MwFAOh/lm3pGAaRoLcqPUU3IzRogUmDUS lAQuQv8ED8YU7Ul3qASqiS9Kall+F+tJqjXCRs3AK4GPl7GwHdr7ghC03oV5GxwmPY J9oRyuNzAZESLzwu/Kn2WJ/b3+iSD3UHXb15iizPyb6jH6s4+3JvUZikuMFV47DRG0 /H4qJhsoiLuyA== Subject: [PATCH RFC 4/4] SUNRPC: Send RPC message on TCP with a single sock_sendmsg() call From: Chuck Lever To: linux-nfs@vger.kernel.org Cc: David Howells , Chuck Lever , dhowells@redhat.com Date: Sun, 09 Jul 2023 16:05:18 -0400 Message-ID: <168893311819.1949.12216126239653940727.stgit@manet.1015granger.net> In-Reply-To: <168893265677.1949.1632048925203798962.stgit@manet.1015granger.net> References: <168893265677.1949.1632048925203798962.stgit@manet.1015granger.net> User-Agent: StGit/1.5 MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-nfs@vger.kernel.org From: Chuck Lever There is now enough infrastructure in place to combine the stream record marker into the biovec array used to send each outgoing RPC message. The whole message can be more efficiently sent with a single call to sock_sendmsg() using a bio_vec iterator. Note that this also helps with RPC-with-TLS: the TLS implementation can now clearly see where the upper layer message boundaries are. Before, it would send each component of the xdr_buf in a separate TLS record. Suggested-by: David Howells Signed-off-by: Chuck Lever --- include/linux/sunrpc/svcsock.h | 2 ++ net/sunrpc/svcsock.c | 33 ++++++++++++++++++--------------- 2 files changed, 20 insertions(+), 15 deletions(-) diff --git a/include/linux/sunrpc/svcsock.h b/include/linux/sunrpc/svcsock.h index 4efae760f3cb..55446136499f 100644 --- a/include/linux/sunrpc/svcsock.h +++ b/include/linux/sunrpc/svcsock.h @@ -38,6 +38,8 @@ struct svc_sock { /* Number of queued send requests */ atomic_t sk_sendqlen; + struct page_frag_cache sk_frag_cache; + struct completion sk_handshake_done; struct bio_vec sk_recv_bvec[RPCSVC_MAXPAGES] diff --git a/net/sunrpc/svcsock.c b/net/sunrpc/svcsock.c index 6f672cb0b0b3..19cab73229e4 100644 --- a/net/sunrpc/svcsock.c +++ b/net/sunrpc/svcsock.c @@ -1247,29 +1247,28 @@ static int svc_tcp_recvfrom(struct svc_rqst *rqstp) static int svc_tcp_sendmsg(struct svc_sock *svsk, struct xdr_buf *xdr, rpc_fraghdr marker, unsigned int *sentp) { - struct kvec rm = { - .iov_base = &marker, - .iov_len = sizeof(marker), - }; struct msghdr msg = { - .msg_flags = MSG_MORE, + .msg_flags = MSG_SPLICE_PAGES, }; unsigned int count; + void *tmp; int ret; *sentp = 0; - ret = kernel_sendmsg(svsk->sk_sock, &msg, &rm, 1, rm.iov_len); - if (ret < 0) - return ret; - *sentp += ret; - if (ret != rm.iov_len) - return -EAGAIN; - - count = svc_sock_xdr_to_bvecs(svsk->sk_send_bvec, xdr); - msg.msg_flags = MSG_SPLICE_PAGES; + /* The stream record marker is copied into a temporary page + * buffer so that it can be included in sk_send_bvec. + */ + tmp = page_frag_alloc(&svsk->sk_frag_cache, sizeof(marker), + GFP_KERNEL); + if (!tmp) + return -ENOMEM; + memcpy(tmp, &marker, sizeof(marker)); + bvec_set_virt(svsk->sk_send_bvec, tmp, sizeof(marker)); + + count = svc_sock_xdr_to_bvecs(svsk->sk_send_bvec + 1, xdr); iov_iter_bvec(&msg.msg_iter, ITER_SOURCE, svsk->sk_send_bvec, - count, xdr->len); + 1 + count, sizeof(marker) + xdr->len); ret = sock_sendmsg(svsk->sk_sock, &msg); if (ret < 0) return ret; @@ -1648,6 +1647,7 @@ static void svc_tcp_sock_detach(struct svc_xprt *xprt) static void svc_sock_free(struct svc_xprt *xprt) { struct svc_sock *svsk = container_of(xprt, struct svc_sock, sk_xprt); + struct page_frag_cache *pfc = &svsk->sk_frag_cache; struct socket *sock = svsk->sk_sock; trace_svcsock_free(svsk, sock); @@ -1657,5 +1657,8 @@ static void svc_sock_free(struct svc_xprt *xprt) sockfd_put(sock); else sock_release(sock); + if (pfc->va) + __page_frag_cache_drain(virt_to_head_page(pfc->va), + pfc->pagecnt_bias); kfree(svsk); }