Re: [PATCH v1 6/7] nfs: Optimize direct I/O to use folios for requests
"Anna Schumaker" <[email protected]>
| Newsgroups | gmane.linux.kernel,gmane.linux.nfs |
|---|---|
| Message-ID | <[email protected]> |
Hi Pranjal, On Wed, Jun 3, 2026, at 1:30 AM, Pranjal Shrivastava wrote: > Optimize nfs_direct_extract_pages() to group contiguous pages from the > same folio into single nfs_page structures. This effectively migrates > NFS Direct I/O from being page-based to being folio-based. > > Reduce the number of nfs_page allocations and subsequent iterations > by utilizing nfs_page_create_from_folio() to create aggregated > requests. I am seeing a LOT of failing xfstests after applying this patch (testing against various NFS versions over TCP with AUTH_SYS): +-------------+-----------+-------------+-------------+-------------+ | testcase | tcp-sys-3 | tcp-sys-4.0 | tcp-sys-4.1 | tcp-sys-4.2 | +-------------+-----------+-------------+-------------+-------------+ | generic/091 | failure | failure | failure | failure | | generic/130 | failure | failure | failure | failure | | generic/139 | skipped | skipped | skipped | failure | | generic/143 | skipped | skipped | skipped | failure | | generic/154 | skipped | skipped | skipped | failure | | generic/155 | skipped | skipped | skipped | failure | | generic/183 | skipped | skipped | skipped | failure | | generic/188 | skipped | skipped | skipped | failure | | generic/190 | skipped | skipped | skipped | failure | | generic/196 | skipped | skipped | skipped | failure | | generic/198 | failure | failure | failure | failure | | generic/203 | skipped | skipped | skipped | failure | | generic/214 | skipped | skipped | skipped | failure | | generic/240 | failure | failure | failure | failure | | generic/263 | failure | failure | failure | failure | | generic/287 | skipped | skipped | skipped | failure | | generic/290 | skipped | skipped | skipped | failure | | generic/292 | skipped | skipped | skipped | failure | | generic/330 | skipped | skipped | skipped | failure | | generic/444 | failure | skipped | skipped | skipped | | generic/450 | failure | failure | failure | failure | | generic/451 | failure | failure | failure | failure | | generic/586 | skipped | skipped | skipped | failure | | generic/647 | failure | failure | failure | failure | | generic/708 | failure | failure | failure | failure | | generic/729 | failure | failure | failure | failure | | generic/760 | failure | failure | failure | failure | +-------------+-----------+-------------+-------------+-------------+ I'm curious if you've run xfstests against your changes, and if you see the same failures? Thanks, Anna > > Signed-off-by: Pranjal Shrivastava <[email protected]> > --- > fs/nfs/direct.c | 36 +++++++++++++++++++++++++++++------- > 1 file changed, 29 insertions(+), 7 deletions(-) > > diff --git a/fs/nfs/direct.c b/fs/nfs/direct.c > index 59002c150f23..93e1af9ec36b 100644 > --- a/fs/nfs/direct.c > +++ b/fs/nfs/direct.c > @@ -194,23 +194,45 @@ static ssize_t nfs_direct_extract_pages(struct > nfs_direct_req *dreq, > return result; > > npages = (result + pgbase + PAGE_SIZE - 1) >> PAGE_SHIFT; > - for (i = 0; i < npages; i++) { > + for (i = 0; i < npages; ) { > + unsigned int chunk_len, folio_offset; > + unsigned int nr_to_add = 1; > struct nfs_page *req; > - unsigned int req_len = min_t(size_t, result - bytes, PAGE_SIZE - pgbase); > + struct folio *folio; > > - req = nfs_page_create_from_page(dreq->ctx, pagevec[i], > - pinned, pgbase, *pos, > - req_len); > + folio = page_folio(pagevec[i]); > + folio_offset = (folio_page_idx(folio, pagevec[i]) << PAGE_SHIFT) + pgbase; > + chunk_len = min_t(size_t, result - bytes, PAGE_SIZE - pgbase); > + > + while (i + nr_to_add < npages) { > + struct page *next_page = pagevec[i + nr_to_add]; > + struct page *prev_page = pagevec[i + nr_to_add - 1]; > + > + if (page_folio(next_page) != folio || > + next_page != prev_page + 1) > + break; > + > + chunk_len += min_t(size_t, result - bytes - chunk_len, PAGE_SIZE); > + nr_to_add++; > + } > + > + req = nfs_page_create_from_folio(dreq->ctx, folio, > + pinned, folio_offset, > + chunk_len); > if (IS_ERR(req)) { > if (!bytes) > bytes = PTR_ERR(req); > break; > } > > + req->wb_index = *pos >> PAGE_SHIFT; > + req->wb_offset = *pos; > + > list_add_tail(&req->wb_list, list); > pgbase = 0; > - bytes += req_len; > - *pos += req_len; > + bytes += chunk_len; > + *pos += chunk_len; > + i += nr_to_add; > } > > if (i < npages) { > -- > 2.54.0.1013.g208068f2d8-goog