From: Chuck Lever Date: Thu, 26 Feb 2026 14:47:36 +0000 (-0500) Subject: SUNRPC: Handle NULL entries in svc_rqst_release_pages X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=22cc2ba5c27a500040d13cecb1dbfc3e4bccab81;p=thirdparty%2Fkernel%2Fstable.git SUNRPC: Handle NULL entries in svc_rqst_release_pages svc_rqst_release_pages() releases response pages between rq_respages and rq_next_page. It currently passes the entire range to release_pages(), which does not expect NULL entries. A subsequent patch preserves the rq_next_page pointer in svc_rdma_save_io_pages() so that it accurately records how many response pages were consumed. After that change, the range [rq_respages, rq_next_page) can contain NULL entries where pages have already been transferred to a send context. Iterate through the range entry by entry, skipping NULLs, to handle this case correctly. Reviewed-by: Jeff Layton Signed-off-by: Chuck Lever --- diff --git a/net/sunrpc/svc.c b/net/sunrpc/svc.c index 9abef638b1e0..0ce16e9abdf6 100644 --- a/net/sunrpc/svc.c +++ b/net/sunrpc/svc.c @@ -990,18 +990,24 @@ EXPORT_SYMBOL_GPL(svc_rqst_replace_page); * svc_rqst_release_pages - Release Reply buffer pages * @rqstp: RPC transaction context * - * Release response pages that might still be in flight after - * svc_send, and any spliced filesystem-owned pages. + * Release response pages in the range [rq_respages, rq_next_page). + * NULL entries in this range are skipped, allowing transports to + * transfer pages to a send context before this function runs. */ void svc_rqst_release_pages(struct svc_rqst *rqstp) { - int i, count = rqstp->rq_next_page - rqstp->rq_respages; - - if (count) { - release_pages(rqstp->rq_respages, count); - for (i = 0; i < count; i++) - rqstp->rq_respages[i] = NULL; + struct page **pp; + + for (pp = rqstp->rq_respages; pp < rqstp->rq_next_page; pp++) { + if (*pp) { + if (!folio_batch_add(&rqstp->rq_fbatch, + page_folio(*pp))) + __folio_batch_release(&rqstp->rq_fbatch); + *pp = NULL; + } } + if (rqstp->rq_fbatch.nr) + __folio_batch_release(&rqstp->rq_fbatch); } /**