From: Mike Snitzer <snitzer@kernel.org>
To: Chuck Lever <cel@kernel.org>, Jeff Layton <jlayton@kernel.org>
Cc: hch@lst.de, linux-nfs@vger.kernel.org
Subject: [PATCH v3 3/9] NFSD: add direct_misaligned_dontcache debugfs knob
Date: Thu, 1 Oct 2026 00:54:56 -0400 [thread overview]
Message-ID: <20261001045502.48381-4-snitzer@kernel.org> (raw)
In-Reply-To: <20261001045502.48381-1-snitzer@kernel.org>
From: Jonathan Flynn <jonathan.flynn@hammerspace.com>
The parts of a direct-mode WRITE that are not O_DIRECT, the misaligned
start and end of a split WRITE and a WRITE that is not split, are
issued IOCB_DONTCACHE when the file system supports it. That suits
the workloads a direct mode is chosen for, but it is a policy, not a
requirement: a workload that reads back or rewrites what it just wrote
is better served by those pages staying cached.
Add /sys/kernel/debug/nfsd/direct_misaligned_dontcache (default Y).
Set to N, those parts are issued as normal buffered I/O. The O_DIRECT
middle keeps IOCB_DONTCACHE either way. It sits beside
direct_misaligned_num_pages, which decides how much of a misaligned
WRITE is O_DIRECT; this knob decides how the rest is cached.
Signed-off-by: Jonathan Flynn <jonathan.flynn@hammerspace.com>
[snitzer: switched from a module parameter to a debugfs knob, moved
next to direct_misaligned_num_pages, documented in nfsd-io-modes.rst]
Assisted-by: Claude:claude-opus-5[1m]
Signed-off-by: Mike Snitzer <snitzer@kernel.org>
---
.../filesystems/nfs/nfsd-io-modes.rst | 18 +++++++++++++-----
fs/nfsd/debugfs.c | 12 ++++++++++++
fs/nfsd/nfsd.h | 1 +
fs/nfsd/vfs.c | 13 +++++++++----
4 files changed, 35 insertions(+), 9 deletions(-)
diff --git a/Documentation/filesystems/nfs/nfsd-io-modes.rst b/Documentation/filesystems/nfs/nfsd-io-modes.rst
index 0a67ce9244d38..9b1a9e7b09cef 100644
--- a/Documentation/filesystems/nfs/nfsd-io-modes.rst
+++ b/Documentation/filesystems/nfs/nfsd-io-modes.rst
@@ -126,11 +126,13 @@ Misaligned WRITE:
middle and end as needed. The large middle segment is DIO-aligned
and the start and/or end are misaligned. Buffered IO is used for the
misaligned segments and O_DIRECT is used for the middle DIO-aligned
- segment. If the filesystem supports FOP_DONTCACHE, every segment is
- marked DONTCACHE. The flag has no effect on the O_DIRECT segment
- unless the filesystem services it with buffered IO instead, as XFS
- does when it cannot invalidate page cache that overlaps the segment.
- The iomap_dio_invalidate_fail trace event reports such a fallback.
+ segment. If the filesystem supports FOP_DONTCACHE, the O_DIRECT
+ segment is marked DONTCACHE, and so are the misaligned segments
+ unless direct_misaligned_dontcache is N (below). The flag has no
+ effect on the O_DIRECT segment unless the filesystem services it
+ with buffered IO instead, as XFS does when it cannot invalidate page
+ cache that overlaps the segment. The iomap_dio_invalidate_fail trace
+ event reports such a fallback.
If NFSD does not split a misaligned WRITE, it issues the whole WRITE
as a single DONTCACHE buffered IO (normal buffered IO if the
@@ -145,6 +147,12 @@ Misaligned WRITE:
- the WRITE payload is not aligned in memory to the block device's
dma_alignment, so the middle cannot be O_DIRECT either.
+ Writing N to /sys/kernel/debug/nfsd/direct_misaligned_dontcache
+ (default Y) issues the start and end segments, and a WRITE that is
+ not split, as normal buffered IO instead of DONTCACHE, which suits a
+ workload that reads back or rewrites what it just wrote. The O_DIRECT
+ middle segment keeps its DONTCACHE flag either way.
+
Tracing:
The nfsd_read_direct trace event shows how NFSD expands any
misaligned READ to the next DIO-aligned block (on either end of the
diff --git a/fs/nfsd/debugfs.c b/fs/nfsd/debugfs.c
index 0b3ddf28d2849..d5b714dd0fbc6 100644
--- a/fs/nfsd/debugfs.c
+++ b/fs/nfsd/debugfs.c
@@ -151,6 +151,18 @@ void nfsd_debugfs_init(void)
*/
debugfs_create_u32("direct_misaligned_num_pages", 0644, nfsd_top_dir,
&nfsd_direct_misaligned_num_pages);
+
+ /*
+ * /sys/kernel/debug/nfsd/direct_misaligned_dontcache
+ *
+ * Y: the parts of a direct-mode WRITE that are not O_DIRECT use
+ * DONTCACHE buffered IO when the file system supports it
+ * N: those parts use normal buffered IO
+ *
+ * The default value of this setting is Y.
+ */
+ debugfs_create_bool("direct_misaligned_dontcache", 0644, nfsd_top_dir,
+ &nfsd_direct_misaligned_dontcache);
#ifdef CONFIG_NFSD_V4
debugfs_create_bool("delegated_timestamps", 0644, nfsd_top_dir,
&nfsd_delegts_enabled);
diff --git a/fs/nfsd/nfsd.h b/fs/nfsd/nfsd.h
index 70219d26b7404..1c17f96012523 100644
--- a/fs/nfsd/nfsd.h
+++ b/fs/nfsd/nfsd.h
@@ -146,6 +146,7 @@ enum {
extern u64 nfsd_io_cache_read __read_mostly;
extern u64 nfsd_io_cache_write __read_mostly;
extern u32 nfsd_direct_misaligned_num_pages __read_mostly;
+extern bool nfsd_direct_misaligned_dontcache __read_mostly;
bool nfsd_v4client(struct svc_rqst *rqstp);
diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c
index 0b39f53e041e1..1304953c684b7 100644
--- a/fs/nfsd/vfs.c
+++ b/fs/nfsd/vfs.c
@@ -54,6 +54,7 @@ bool nfsd_disable_splice_read __read_mostly;
u64 nfsd_io_cache_read __read_mostly = NFSD_IO_BUFFERED;
u64 nfsd_io_cache_write __read_mostly = NFSD_IO_BUFFERED;
u32 nfsd_direct_misaligned_num_pages __read_mostly = 2;
+bool nfsd_direct_misaligned_dontcache __read_mostly = true;
/**
* nfserrno - Map Linux errnos to NFS errnos
@@ -1304,10 +1305,13 @@ nfsd_write_dio_iters_init(struct nfsd_file *nf, struct bio_vec *bvec,
size_t prefix, middle, suffix;
loff_t offset = iocb->ki_pos;
unsigned int dontcache_flags = 0;
+ unsigned int buffered_flags;
unsigned int nsegs = 0;
if (nf->nf_file->f_op->fop_flags & FOP_DONTCACHE)
dontcache_flags = IOCB_DONTCACHE;
+ buffered_flags = READ_ONCE(nfsd_direct_misaligned_dontcache) ?
+ dontcache_flags : 0;
/*
* Check if direct I/O is feasible for this write request.
@@ -1334,7 +1338,7 @@ nfsd_write_dio_iters_init(struct nfsd_file *nf, struct bio_vec *bvec,
if (prefix) {
nfsd_write_dio_seg_init(&segments[nsegs], bvec,
nvecs, total, 0, prefix, iocb);
- segments[nsegs++].flags |= dontcache_flags;
+ segments[nsegs++].flags |= buffered_flags;
}
nfsd_write_dio_seg_init(&segments[nsegs], bvec, nvecs,
@@ -1355,7 +1359,7 @@ nfsd_write_dio_iters_init(struct nfsd_file *nf, struct bio_vec *bvec,
if (suffix) {
nfsd_write_dio_seg_init(&segments[nsegs], bvec, nvecs, total,
prefix + middle, suffix, iocb);
- segments[nsegs++].flags |= dontcache_flags;
+ segments[nsegs++].flags |= buffered_flags;
}
return nsegs;
@@ -1363,11 +1367,12 @@ nfsd_write_dio_iters_init(struct nfsd_file *nf, struct bio_vec *bvec,
no_dio:
/*
* Issue the whole WRITE as a single buffered segment, uncached when
- * the file system supports FOP_DONTCACHE.
+ * the file system supports FOP_DONTCACHE and
+ * direct_misaligned_dontcache is set.
*/
nfsd_write_dio_seg_init(&segments[0], bvec, nvecs, total, 0,
total, iocb);
- segments[0].flags |= dontcache_flags;
+ segments[0].flags |= buffered_flags;
return 1;
}
--
2.52.0
next prev parent reply other threads:[~2026-10-01 4:55 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-01 4:54 [PATCH v3 0/9] NFSD: keep direct-mode I/O out of the page cache Mike Snitzer
2026-10-01 4:54 ` [PATCH v3 1/9] NFSD: mark the direct middle of a split WRITE IOCB_DONTCACHE as well Mike Snitzer
2026-10-01 4:54 ` [PATCH v3 2/9] NFSD: only split a direct-mode WRITE for a worthwhile direct middle Mike Snitzer
2026-10-01 4:54 ` Mike Snitzer [this message]
2026-10-01 4:54 ` [PATCH v3 4/9] NFSD: do not use direct I/O for a READ smaller than its alignment Mike Snitzer
2026-10-01 4:54 ` [PATCH v3 5/9] NFSD: persist a synchronous direct-mode WRITE once, after all of its segments Mike Snitzer
2026-10-01 4:54 ` [PATCH v3 6/9] NFSD: keep boundary page of a split direct-mode WRITE until both writers complete Mike Snitzer
2026-10-01 4:55 ` [PATCH v3 7/9] NFSD: add tracing for how direct-mode READ and WRITE are serviced Mike Snitzer
2026-10-01 4:55 ` [PATCH v3 8/9] NFSD: Enable return of an updated stable_how to NFS clients Mike Snitzer
2026-10-01 4:55 ` [PATCH v3 9/9] NFSD: add direct-mode WRITE settings that persist each WRITE Mike Snitzer
2026-10-01 22:58 ` [PATCH v3 0/9] NFSD: keep direct-mode I/O out of the page cache Mike Snitzer
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=20261001045502.48381-4-snitzer@kernel.org \
--to=snitzer@kernel.org \
--cc=cel@kernel.org \
--cc=hch@lst.de \
--cc=jlayton@kernel.org \
--cc=linux-nfs@vger.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.