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 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.