Re: [PATCH v1 6/7] nfs: Optimize direct I/O to use folios for requests

From: Pranjal Shrivastava

Date: Tue Jun 16 2026 - 10:22:14 EST


On Thu, Jun 04, 2026 at 07:59:14AM +0000, Pranjal Shrivastava wrote:
> On Wed, Jun 03, 2026 at 03:14:35PM -0400, Anna Schumaker wrote:
> > 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?
> >

Hi Anna,

I was able to run xfstests [1] and identify the issues. I've fixed those
issues and posted a v2 [2]. I don't see any failure, here's a run v2:

./check generic/091 generic/130 generic/139 generic/143 generic/154 \
generic/155 generic/183 generic/188 generic/190 generic/196 \
generic/198 generic/203 generic/214 generic/240 generic/263 \
generic/287 generic/290 generic/292 generic/330 generic/444 \
generic/450 generic/451 generic/586 generic/647 generic/708 \
generic/729 generic/760

SECTION -- rdma3
=========================
Ran: generic/091 generic/130 generic/139 generic/143 generic/154
generic/155 generic/183 generic/188 generic/190 generic/196
generic/198 generic/203 generic/214 generic/240 generic/263
generic/287 generic/290 generic/292 generic/330 generic/444
generic/450 generic/451 generic/586 generic/647 generic/708
generic/729 generic/760
Not run: generic/183 generic/188 generic/190 generic/196 generic/203 generic/287 generic/290 generic/292 generic/330 generic/444
Passed all 27 tests

SECTION -- rdma40
=========================
Ran: generic/091 generic/130 generic/139 generic/143 generic/154
generic/155 generic/183 generic/188 generic/190 generic/196
generic/198 generic/203 generic/214 generic/240 generic/263
generic/287 generic/290 generic/292 generic/330 generic/444
generic/450 generic/451 generic/586 generic/647 generic/708
generic/729 generic/760
Not run: generic/183 generic/188 generic/190 generic/196 generic/203 generic/287 generic/290 generic/292 generic/330 generic/444
Passed all 27 tests

SECTION -- rdma41
=========================
Ran: generic/091 generic/130 generic/139 generic/143 generic/154
generic/155 generic/183 generic/188 generic/190 generic/196
generic/198 generic/203 generic/214 generic/240 generic/263
generic/287 generic/290 generic/292 generic/330 generic/444
generic/450 generic/451 generic/586 generic/647 generic/708
generic/729 generic/760
Not run: generic/183 generic/188 generic/190 generic/196 generic/203 generic/287 generic/290 generic/292 generic/330 generic/444
Passed all 27 tests

SECTION -- rdma42
=========================
Ran: generic/091 generic/130 generic/139 generic/143 generic/154
generic/155 generic/183 generic/188 generic/190 generic/196
generic/198 generic/203 generic/214 generic/240 generic/263
generic/287 generic/290 generic/292 generic/330 generic/444
generic/450 generic/451 generic/586 generic/647 generic/708
generic/729 generic/760
Not run: generic/444
Passed all 27 tests

SECTION -- tcp3
=========================
Ran: generic/091 generic/130 generic/139 generic/143 generic/154
generic/155 generic/183 generic/188 generic/190 generic/196
generic/198 generic/203 generic/214 generic/240 generic/263
generic/287 generic/290 generic/292 generic/330 generic/444
generic/450 generic/451 generic/586 generic/647 generic/708
generic/729 generic/760
Not run: generic/183 generic/188 generic/190 generic/196 generic/203 generic/287 generic/290 generic/292 generic/330 generic/444
Passed all 27 tests

SECTION -- tcp40
=========================
Ran: generic/091 generic/130 generic/139 generic/143 generic/154
generic/155 generic/183 generic/188 generic/190 generic/196
generic/198 generic/203 generic/214 generic/240 generic/263
generic/287 generic/290 generic/292 generic/330 generic/444
generic/450 generic/451 generic/586 generic/647 generic/708
generic/729 generic/760
Not run: generic/183 generic/188 generic/190 generic/196 generic/203 generic/287 generic/290 generic/292 generic/330 generic/444
Passed all 27 tests

SECTION -- tcp41
=========================
Ran: generic/091 generic/130 generic/139 generic/143 generic/154
generic/155 generic/183 generic/188 generic/190 generic/196
generic/198 generic/203 generic/214 generic/240 generic/263
generic/287 generic/290 generic/292 generic/330 generic/444
generic/450 generic/451 generic/586 generic/647 generic/708
generic/729 generic/760
Not run: generic/183 generic/188 generic/190 generic/196 generic/203 generic/287 generic/290 generic/292 generic/330 generic/444
Passed all 27 tests

SECTION -- tcp42
=========================
Ran: generic/091 generic/130 generic/139 generic/143 generic/154
generic/155 generic/183 generic/188 generic/190 generic/196
generic/198 generic/203 generic/214 generic/240 generic/263
generic/287 generic/290 generic/292 generic/330 generic/444
generic/450 generic/451 generic/586 generic/647 generic/708
generic/729 generic/760
Not run: generic/444
Passed all 27 tests

I couldn't figure out the tool used to generate that table, so I wrote
a small script [3] that picked up logs from each run in results/* dir.

$ python3 display.py results/*/check.log

+--------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+
| testcase | rdma-sys-3 | rdma-sys-4.0 | rdma-sys-4.1 | rdma-sys-4.2 | tcp-sys-3 | tcp-sys-4.0 | tcp-sys-4.1 | tcp-sys-4.2 |
+--------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+
| generic/091 | pass | pass | pass | pass | pass | pass | pass | pass |
| generic/130 | pass | pass | pass | pass | pass | pass | pass | pass |
| generic/139 | pass | pass | pass | pass | pass | pass | pass | pass |
| generic/143 | pass | pass | pass | pass | pass | pass | pass | pass |
| generic/154 | pass | pass | pass | pass | pass | pass | pass | pass |
| generic/155 | pass | pass | pass | pass | pass | pass | pass | pass |
| generic/183 | skipped | skipped | skipped | pass | skipped | skipped | skipped | pass |
| generic/188 | skipped | skipped | skipped | pass | skipped | skipped | skipped | pass |
| generic/190 | skipped | skipped | skipped | pass | skipped | skipped | skipped | pass |
| generic/196 | skipped | skipped | skipped | pass | skipped | skipped | skipped | pass |
| generic/198 | pass | pass | pass | pass | pass | pass | pass | pass |
| generic/203 | skipped | skipped | skipped | pass | skipped | skipped | skipped | pass |
| generic/214 | pass | pass | pass | pass | pass | pass | pass | pass |
| generic/240 | pass | pass | pass | pass | pass | pass | pass | pass |
| generic/263 | pass | pass | pass | pass | pass | pass | pass | pass |
| generic/287 | skipped | skipped | skipped | pass | skipped | skipped | skipped | pass |
| generic/290 | skipped | skipped | skipped | pass | skipped | skipped | skipped | pass |
| generic/292 | skipped | skipped | skipped | pass | skipped | skipped | skipped | pass |
| generic/330 | skipped | skipped | skipped | pass | skipped | skipped | skipped | pass |
| generic/444 | skipped | skipped | skipped | skipped | skipped | skipped | skipped | skipped |
| generic/450 | pass | pass | pass | pass | pass | pass | pass | pass |
| generic/451 | pass | pass | pass | pass | pass | pass | pass | pass |
| generic/586 | pass | pass | pass | pass | pass | pass | pass | pass |
| generic/647 | pass | pass | pass | pass | pass | pass | pass | pass |
| generic/708 | pass | pass | pass | pass | pass | pass | pass | pass |
| generic/729 | pass | pass | pass | pass | pass | pass | pass | pass |
| generic/760 | pass | pass | pass | pass | pass | pass | pass | pass |
+--------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+

Thanks,
Praan

[1] https://git.kernel.org/pub/scm/fs/xfs/xfstests-dev.git
[2] https://lore.kernel.org/all/20260616134000.2733403-1-praan@xxxxxxxxxx/
[3] https://github.com/pran005/tools/blob/main/display.py