From: Chuck Lever <cel@kernel.org>
To: NeilBrown <neilb@ownmail.net>, Jeff Layton <jlayton@kernel.org>,
Olga Kornievskaia <okorniev@redhat.com>,
Dai Ngo <dai.ngo@oracle.com>, Tom Talpey <tom@talpey.com>
Cc: <linux-nfs@vger.kernel.org>, Chuck Lever <chuck.lever@oracle.com>
Subject: [RFC PATCH 5/6] sunrpc: Track consumed rq_pages entries
Date: Sun, 22 Feb 2026 11:20:01 -0500 [thread overview]
Message-ID: <20260222162002.10613-6-cel@kernel.org> (raw)
In-Reply-To: <20260222162002.10613-1-cel@kernel.org>
From: Chuck Lever <chuck.lever@oracle.com>
Transports that consume pages from the rq_pages array --
svc_tcp_save_pages() for TCP fragment reassembly and
svc_rdma_clear_rqst_pages() for RDMA Read I/O -- NULL
the consumed entries starting at rq_pages[0]. A new
rq_pages_nfree field in struct svc_rqst records the
count of entries consumed.
svc_alloc_arg() uses rq_pages_nfree to refill only
the consumed entries rather than scanning the full
rq_pages array. In steady state, the transport consume
path NULLs a handful of entries per RPC, so the
allocator visits only those entries instead of the
full ~259 slots (for 1MB messages).
svc_init_buffer() initializes rq_pages_nfree to
rq_maxpages so that the first svc_alloc_arg() call
populates every entry.
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
---
include/linux/sunrpc/svc.h | 8 ++++++++
net/sunrpc/svc.c | 1 +
net/sunrpc/svc_xprt.c | 11 ++++++++---
net/sunrpc/svcsock.c | 1 +
net/sunrpc/xprtrdma/svc_rdma_rw.c | 1 +
5 files changed, 19 insertions(+), 3 deletions(-)
diff --git a/include/linux/sunrpc/svc.h b/include/linux/sunrpc/svc.h
index b1fb728724f5..bb2029e396db 100644
--- a/include/linux/sunrpc/svc.h
+++ b/include/linux/sunrpc/svc.h
@@ -143,6 +143,13 @@ extern u32 svc_max_payload(const struct svc_rqst *rqstp);
* server thread needs to allocate more to replace those used in
* sending.
*
+ * Transport page-consumption contract:
+ *
+ * Transports that consume rq_pages entries (for TCP fragment
+ * reassembly or RDMA Read I/O) NULL entries starting at
+ * rq_pages[0] and set rq_pages_nfree to the count of entries
+ * consumed. svc_alloc_arg() refills only that many entries.
+ *
* xdr_buf holds responses; the structure fits NFS read responses
* (header, data pages, optional tail) and enables sharing of
* client-side routines.
@@ -201,6 +208,7 @@ struct svc_rqst {
struct folio *rq_scratch_folio;
struct xdr_buf rq_res;
unsigned long rq_maxpages; /* entries per page array */
+ unsigned long rq_pages_nfree; /* NULL rq_pages to refill */
struct page * *rq_pages;
struct page * *rq_respages; /* Reply buffer pages */
struct page * *rq_next_page; /* next reply page to use */
diff --git a/net/sunrpc/svc.c b/net/sunrpc/svc.c
index 620de9abedbb..a8c26634ecf1 100644
--- a/net/sunrpc/svc.c
+++ b/net/sunrpc/svc.c
@@ -654,6 +654,7 @@ svc_init_buffer(struct svc_rqst *rqstp, const struct svc_serv *serv, int node)
return false;
}
+ rqstp->rq_pages_nfree = rqstp->rq_maxpages;
return true;
}
diff --git a/net/sunrpc/svc_xprt.c b/net/sunrpc/svc_xprt.c
index cd38f09c1803..9d8f6adcfe1f 100644
--- a/net/sunrpc/svc_xprt.c
+++ b/net/sunrpc/svc_xprt.c
@@ -675,12 +675,17 @@ static bool svc_fill_pages(struct svc_rqst *rqstp, struct page **pages,
static bool svc_alloc_arg(struct svc_rqst *rqstp)
{
struct xdr_buf *arg = &rqstp->rq_arg;
- unsigned long pages;
+ unsigned long pages, nfree;
pages = rqstp->rq_maxpages;
- if (!svc_fill_pages(rqstp, rqstp->rq_pages, pages))
- return false;
+ nfree = rqstp->rq_pages_nfree;
+ if (nfree) {
+ if (!svc_fill_pages(rqstp, rqstp->rq_pages, nfree))
+ return false;
+ rqstp->rq_pages_nfree = 0;
+ }
+
if (!svc_fill_pages(rqstp, rqstp->rq_respages, pages))
return false;
rqstp->rq_next_page = rqstp->rq_respages;
diff --git a/net/sunrpc/svcsock.c b/net/sunrpc/svcsock.c
index 10a298f440cc..f9140ac8ed99 100644
--- a/net/sunrpc/svcsock.c
+++ b/net/sunrpc/svcsock.c
@@ -1009,6 +1009,7 @@ static void svc_tcp_save_pages(struct svc_sock *svsk, struct svc_rqst *rqstp)
svsk->sk_pages[i] = rqstp->rq_pages[i];
rqstp->rq_pages[i] = NULL;
}
+ rqstp->rq_pages_nfree = npages;
}
static void svc_tcp_clear_pages(struct svc_sock *svsk)
diff --git a/net/sunrpc/xprtrdma/svc_rdma_rw.c b/net/sunrpc/xprtrdma/svc_rdma_rw.c
index 4ec2f9ae06aa..cf4a1762b629 100644
--- a/net/sunrpc/xprtrdma/svc_rdma_rw.c
+++ b/net/sunrpc/xprtrdma/svc_rdma_rw.c
@@ -1107,6 +1107,7 @@ static void svc_rdma_clear_rqst_pages(struct svc_rqst *rqstp,
head->rc_pages[i] = rqstp->rq_pages[i];
rqstp->rq_pages[i] = NULL;
}
+ rqstp->rq_pages_nfree = head->rc_page_count;
}
/**
--
2.53.0
next prev parent reply other threads:[~2026-02-22 16:20 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-02-22 16:19 [RFC PATCH 0/6] Optimize NFSD buffer page management Chuck Lever
2026-02-22 16:19 ` [RFC PATCH 1/6] sunrpc: Tighten bounds checking in svc_rqst_replace_page Chuck Lever
2026-02-22 16:19 ` [RFC PATCH 2/6] sunrpc: Allocate a separate Reply page array Chuck Lever
2026-02-23 0:15 ` NeilBrown
2026-02-23 14:43 ` Chuck Lever
2026-02-22 16:19 ` [RFC PATCH 3/6] sunrpc: Handle NULL entries in svc_rqst_release_pages Chuck Lever
2026-02-22 16:20 ` [RFC PATCH 4/6] svcrdma: preserve rq_next_page in svc_rdma_save_io_pages Chuck Lever
2026-02-22 16:20 ` Chuck Lever [this message]
2026-02-23 0:19 ` [RFC PATCH 5/6] sunrpc: Track consumed rq_pages entries NeilBrown
2026-02-22 16:20 ` [RFC PATCH 6/6] sunrpc: Optimize rq_respages allocation in svc_alloc_arg Chuck Lever
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260222162002.10613-6-cel@kernel.org \
--to=cel@kernel.org \
--cc=chuck.lever@oracle.com \
--cc=dai.ngo@oracle.com \
--cc=jlayton@kernel.org \
--cc=linux-nfs@vger.kernel.org \
--cc=neilb@ownmail.net \
--cc=okorniev@redhat.com \
--cc=tom@talpey.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.