mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-05-16 06:41:39 -04:00
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 <jlayton@kernel.org> Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
This commit is contained in:
@@ -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;
|
||||
struct page **pp;
|
||||
|
||||
if (count) {
|
||||
release_pages(rqstp->rq_respages, count);
|
||||
for (i = 0; i < count; i++)
|
||||
rqstp->rq_respages[i] = NULL;
|
||||
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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user