From: Pranjal Shrivastava <praan@google.com>
To: Trond Myklebust <trondmy@kernel.org>
Cc: linux-nfs@vger.kernel.org, linux-kernel@vger.kernel.org,
Anna Schumaker <anna@kernel.org>, Christoph Hellwig <hch@lst.de>,
Christoph Hellwig <hch@infradead.org>,
Shivaji Kant <shivajikant@google.com>
Subject: Re: [PATCH v2 6/7] nfs: Optimize direct I/O to use folios for requests
Date: Tue, 16 Jun 2026 17:23:48 +0000 [thread overview]
Message-ID: <ajGGpDvzZdkGtSbN@google.com> (raw)
In-Reply-To: <7ee3bcfdd6126c93cbb1c219bf601182b95c10d9.camel@kernel.org>
On Tue, Jun 16, 2026 at 11:29:13AM -0400, Trond Myklebust wrote:
Hi Trond
> On Tue, 2026-06-16 at 13:39 +0000, 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.
> >
> > Signed-off-by: Pranjal Shrivastava <praan@google.com>
> > ---
> > fs/nfs/direct.c | 47 +++++++++++++++++++++++++++++++++++++----------
> > 1 file changed, 37 insertions(+), 10 deletions(-)
> >
> > diff --git a/fs/nfs/direct.c b/fs/nfs/direct.c
> > index e2a93cfb6c72..ddc6b27f5315 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]);
>
> I'm clearly missing something. The memory pointed to by these pages can
> be any arbitrary user space (or kernel space) memory region. It could
> be mapped device memory, for instance.
>
> So why can you assume that page_folio() will resolve to a valid folio
> here?
AFAIU, the MM subsystem explicitly ensures that every valid struct page
is part of a folio. The documentation for page_folio() explicitly
states [1]:
"Every page is part of a folio. This function cannot be called on a
NULL pointer."
Since iov_iter_extract_pages() only returns pages that are successfully
pinned and tracked by the kernel, we are guaranteed that pagevec[i]
points to a valid struct page and thus a valid folio.
Regarding device-mapped memory, ZONE_DEVICE pages have also been
refactored to support folios recently (e.g. free_zone_device_folio() [2])
If the memory is not part of a large compound page, page_folio() simply
returns the struct page pointer cast to a struct folio * [3]. In this
case, the folio size is effectively 1, and our extraction loop correctly
handles it as a single-page request unless it identifies physical
contiguity within the same folio.
The only other thing to take care was folio_split which applies
specifically when the caller does not hold a reference on the page.
However, in our case (NFS) the iov_iter_extract_pages() has already
pinned the folio via GUP by this point which ensures that the folio
cannot be split or freed under us, making the page_folio() call and the
subsequent aggregation logic safe.
Finally, in cases where device memory is NOT backed by struct page
(e.g. dmabuf or PFN-based mappings via remap_pfn_range), the buffers
are already unsupported for NFS Direct I/O today. The underlying page
pinning (GUP) would fail with -EFAULT in check_vma_flags() [4] even
before reaching this point.
Given the above guarantees by the kernel, we can ensure that this
resolves to a valid folio at this point in the file-system.
Thanks,
Praan
[1] https://elixir.bootlin.com/linux/v7.1-rc6/source/include/linux/page-flags.h#L291
[2] https://elixir.bootlin.com/linux/v7.1-rc6/source/mm/memremap.c#L416
[3] https://elixir.bootlin.com/linux/v7.1-rc6/source/include/linux/page-flags.h#L234
[4] https://elixir.bootlin.com/linux/v7.1-rc6/source/mm/gup.c#L1208
next prev parent reply other threads:[~2026-06-16 17:23 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-06-16 13:39 [PATCH v2 0/7] nfs: Modernize Direct I/O path Pranjal Shrivastava
2026-06-16 13:39 ` [PATCH v2 1/7] nfs: make nfs_page pin-aware Pranjal Shrivastava
2026-06-16 13:39 ` [PATCH v2 2/7] nfs: Track number of pinned pages in nfs_page Pranjal Shrivastava
2026-06-16 13:39 ` [PATCH v2 3/7] nfs: Introduce nfs_release_request_list helper Pranjal Shrivastava
2026-06-16 13:39 ` [PATCH v2 4/7] nfs: migrate direct I/O to iov_iter_extract_pages Pranjal Shrivastava
2026-06-16 13:39 ` [PATCH v2 5/7] nfs: introduce nfs_direct_extract_pages helper Pranjal Shrivastava
2026-06-16 13:39 ` [PATCH v2 6/7] nfs: Optimize direct I/O to use folios for requests Pranjal Shrivastava
2026-06-16 15:29 ` Trond Myklebust
2026-06-16 17:23 ` Pranjal Shrivastava [this message]
2026-06-16 13:40 ` [PATCH v2 7/7] nfs: Cleanup the nfs_page_create_from_page helper Pranjal Shrivastava
2026-06-16 14:15 ` [PATCH v2 0/7] nfs: Modernize Direct I/O path Pranjal Shrivastava
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=ajGGpDvzZdkGtSbN@google.com \
--to=praan@google.com \
--cc=anna@kernel.org \
--cc=hch@infradead.org \
--cc=hch@lst.de \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-nfs@vger.kernel.org \
--cc=shivajikant@google.com \
--cc=trondmy@kernel.org \
/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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox