Re: [PATCH v3 1/3] NFSD: avoid DONTCACHE for misaligned ends of misaligned DIO WRITE

Chuck Lever
2025-11-05T14:58:44Z

On 11/5/25 1:19 AM, Mike Snitzer wrote:
> NFSD_IO_DIRECT can easily improve streaming misaligned WRITE
> performance if it uses buffered IO (without DONTCACHE) for the
> misaligned end segment(s) and O_DIRECT for the aligned middle
> segment's IO.
>
> On one capable testbed, this commit improved streaming 47008 byte
> write performance from 0.3433 GB/s to 1.26 GB/s.
>
> Signed-off-by: Mike Snitzer <snitzer@kernel.org>
> ---
> fs/nfsd/vfs.c | 10 +++++++++-
> 1 file changed, 9 insertions(+), 1 deletion(-)
>
> v3: drop unrelated change to avoid DONTCACHE if READ is less than 32K

The direct code path now handles the "no support for direct I/O" case
in exactly one spot: the "no_dio" label in nfsd_write_dio_iters_init().

So it seems to me that it would be slightly friendlier overall to not
set DONTCACHE in nfsd_direct_write(), but then set it just after the
"no_dio" label. The nf pointer is available in the nfsd_write_dio_args
structure.

> diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c
> index 701dd261c252..075d7162eb2e 100644
> --- a/fs/nfsd/vfs.c
> +++ b/fs/nfsd/vfs.c
> @@ -1347,6 +1347,14 @@ nfsd_write_dio_iters_init(struct bio_vec *bvec, unsigned int nvecs,
> ++args->nsegs;
> }
>
> + /*
> + * Don't use IOCB_DONTCACHE if misaligned DIO (args->nsegs > 1),
> + * because IO for misaligned segments can benefit from the page
> + * cache (e.g. when handling streaming misaligned IO).
> + */
> + if (args->nsegs > 1 && (args->flags_buffered & IOCB_DONTCACHE))
> + args->flags_buffered &= ~IOCB_DONTCACHE;
> +
> return;
>
> no_dio:
> @@ -1400,7 +1408,7 @@ nfsd_direct_write(struct svc_rqst *rqstp, struct svc_fh *fhp,
>
> /*
> * IOCB_DONTCACHE preserves the intent of NFSD_IO_DIRECT when
> - * writing unaligned segments or handling fallback I/O.
> + * falling back to buffered IO if entire WRITE is unaligned.
> */
> args.flags_buffered = kiocb->ki_flags;
> if (args.nf->nf_file->f_op->fop_flags & FOP_DONTCACHE)

--
Chuck Lever