Linux-mm Archive on lore.kernel.org
 help / color / mirror / Atom feed
From: Jeff Layton <jlayton@kernel.org>
To: Mike Snitzer <snitzer@kernel.org>,
	Matthew Wilcox <willy@infradead.org>,
	linux-mm@kvack.org, linux-fsdevel@vger.kernel.org
Cc: Chuck Lever <cel@kernel.org>,
	linux-nfs@vger.kernel.org, NeilBrown	 <neil@brown.name>,
	Olga Kornievskaia <okorniev@redhat.com>,
	Dai Ngo	 <Dai.Ngo@oracle.com>, Tom Talpey <tom@talpey.com>,
	Christoph Hellwig <hch@lst.de>,  Jens Axboe <axboe@kernel.dk>,
	Jonathan Corbet <corbet@lwn.net>
Subject: Re: [PATCH v9 0/6] mm, iomap, NFSD: stop uncached writes reading back shared pages
Date: Tue, 27 Oct 2026 10:31:58 -0400	[thread overview]
Message-ID: <fc2ea8d6f2cd9ae83d38941f90386aac6638a497.camel@kernel.org> (raw)
In-Reply-To: <20261024221152.6965-1-snitzer@kernel.org>

On Sat, 2026-10-24 at 18:11 -0400, Mike Snitzer wrote:
> Hi,
> 
> Please consider this v9 for the v7.5 development cycle, so that it can
> go upstream in the v7.5 merge window.
> 
> An uncached (RWF_DONTCACHE) buffered write drops each page it writes
> once that page is written back.  A page the write covers only partly is
> shared with the neighbouring write.  Once the first of the two is
> written back, the second reads the page back from disk before it writes
> its part.  32 threads wrote interleaved records to one file on
> XFS (emulated 4Kn NVMe, 4 KiB pages).  Before and after 4/6:
> 
>   record  pwritev2() flags          4 KiB device       MiB/s
>   bytes                             reads per write
>                                     before   after     before  after
>   47008   RWF_DONTCACHE             0.97     0.0005    831     2281
>   47008   RWF_DONTCACHE|RWF_DSYNC   0.99     0.0005    601     1227
>   6000    RWF_DONTCACHE             0.97     0.0001    121      488
>   6000    RWF_DONTCACHE|RWF_DSYNC   0.99     0.0002     90      206
> 
> What is left after is metadata.  49152-byte records cover only whole
> pages, and they read 0.0005 per write either way.  The test program and
> script that produced this table, and how to run them, are in:
> https://lore.kernel.org/linux-nfs/atqJBS8MlYfeUU-t@kernel.org/
> 
> 4/6 has the page cache keep such a page for the write that completes
> it.  5/6 lets a writer that syncs its own write complete those pages
> itself once the sync is done.  NFSD does that for a stable WRITE.  6/6
> is the NFSD change that uses it.  2/6 reports the DONTCACHE dirty count
> in the bdi debugfs stats.  3/6 adds folio_mark_dropbehind(), which 4/6
> and 5/6 use.
> 
> 1/6 fixes 88d6f128d06d ("mm: track DONTCACHE dirty pages per
> bdi_writeback"), in v7.3.  A cached lookup that clears the dropbehind
> flag could uncount a folio that was never counted.  It could also leave
> a folio counted with nothing to uncount it.  The patch applies to v7.3
> as it is, if the mm side would rather take it alone.
> 
> v8 1/7 is not in this series.  As Chuck asked, I post it on its own.  It
> is a revised version of 80728157d1bd ("NFSD: cut a misaligned
> direct-mode WRITE at page boundaries") in cel/nfsd-testing.  This series
> applies on cel/nfsd-testing at 6d13b7f74eec ("NFSD: Map every
> NFS_ACLv2 reply status into aclstat2"), with or without that revision.
> Each patch builds with W=1 with no warnings.
> 
> 1/6 to 5/6 are mm, with small iomap changes in 4/6 and 5/6.  They are
> Cc'd to linux-mm and linux-fsdevel.  If the mm and iomap maintainers
> are agreeable, their acks would let Chuck take the series through the
> nfsd tree.  But whatever approach the maintainers prefer for this kind
> of cross-subsystem merge is obviously fine.
> 
> Changes since v8, from two independent sashiko reviews of v8: the one
> Jeff Layton relayed, and the one that sashiko-bot posted to linux-mm.
> Some findings were in both.
> - 1/6 and 3/6 (both reviews): a folio is counted in WB_DONTCACHE_DIRTY
>   only when both PG_dirty and its dirty tag are set.  v8 tested the tag
>   alone.  __folio_cancel_dirty() clears PG_dirty but leaves the tag, and
>   so does writeback that stops at EOF after folio_clear_dirty_for_io().
>   A folio that stays cached then keeps a stale tag.  1/6 uncounted such
>   a folio twice, and 3/6 counted it and never uncounted it.
> - 4/6, 5/6 and 6/6 (second review): with blocks smaller than the folio,
>   iomap tracks uptodate per block.  The edge that a write completes is
>   then not uptodate when the write finds it, so it was never marked and
>   stayed cached until reclaim.  This happens with 4 KiB blocks on 16 or
>   64 KiB pages.  The new folio_dontcache_edge_written() also accepts a
>   folio whose blocks outside this write are uptodate.
>   filemap_dontcache_edge_completes() takes the range that the write
>   covers, and 6/6 passes it.
> - 5/6 (second review): filemap_dontcache_edge_complete() now waits for
>   writeback in flight, which could not drop the folio.  It also kicks
>   DONTCACHE writeback when it marks a dirty folio.  The earlier kick
>   came before the mark.  It drops a clean folio that is not mapped
>   without a mark.  A mark that filemap_end_dropbehind() then cleared
>   outside the i_pages lock could leave WB_DONTCACHE_DIRTY counted.
> - 6/6 (both reviews): NFSD finds the edges that a buffered segment
>   shares by the mapping's smallest folio, as iomap does, not by page.
>   On 16 KiB blocks, a WRITE written as one buffered segment can have
>   page-aligned ends inside a block.  Nothing completed those edges.
>   NFSD also completes a segment's first edge only when the write
>   reached the end of the segment's bytes in that unit (first review).
> - 4/6 (first review): a paragraph on a limit.  4/6 marks the folio
>   before iomap validates the iomap.  A stale iomap stopped by a fatal
>   signal then leaves a mark on a folio that this write did not complete.
>   This costs one read-back and no data.
> - 2/6: unchanged.
> 
> Patches 1, 3, 4, 5 and 6 carry notes below the --- line.  The notes
> give each question from the v8 reviews, and the code, lock or check
> that answers it.  This includes the limits that the series keeps on
> purpose.
> 
> Before posting, I ran a third review of v9 locally, with Sashiko's
> review stages and the review prompts it uses.  It found no new
> problems.
> 
> Measured for 6/6 on 16 KiB-block XFS over the loop device.  Its
> dma_alignment is 511, so every TCP payload is memory-misaligned and
> NFSD writes each WRITE as one buffered segment.  32 writers of 12288-byte
> records, 1 GiB: v8 left all 32,736 pages of a 128 MiB file resident.
> v9 leaves 948 of 262,080 pages (0.4%) and reads 0.0003 blocks per
> record.  The v8 results hold.  In every run BdiDontcacheDirty was 0
> after the final sync.  That includes runs that mix uncached writes,
> cached writes and mmap stores on one file.  Every record verified.
> 
> I measured all of v9 again on 4 KiB pages, with XFS blocks of 1 KiB
> and 2 KiB over the loop device.  These blocks are smaller than the page.
> 32 writers wrote 47008-byte records, 1 GiB.  Uncached application writes
> left 0 of 261,850 pages resident.  NFSD left 497 (1 KiB blocks) and 349
> (2 KiB blocks).  LOCALIO left 854 and 949.  Every path read 0.0001
> blocks per record.  A kernel without these fixes, on a 128 MiB run with
> 1 KiB blocks, left about one page for every two records.  Uncached
> writes through NFSD, cached writes and mmap stores ran together on one
> file, with 4 KiB and 1 KiB blocks.  BdiDontcacheDirty was 0 after every
> round, and every record verified.  I did not test kernels with 16 KiB
> or 64 KiB pages.
> 
> v8: https://lore.kernel.org/linux-nfs/20261023024548.71123-1-snitzer@kernel.org/
> v7: https://lore.kernel.org/linux-nfs/20261020220346.28020-1-snitzer@kernel.org/
> v6: https://lore.kernel.org/linux-nfs/atbfEbgMU6UGkn2X@kernel.org/
> v5: https://lore.kernel.org/linux-nfs/20261019150725.1507-1-snitzer@kernel.org/
> v4: https://lore.kernel.org/linux-nfs/20261015233309.42999-1-snitzer@kernel.org/
> v3: https://lore.kernel.org/linux-nfs/20261001045502.48381-1-snitzer@kernel.org/
> v2: https://lore.kernel.org/linux-nfs/20260929231329.22018-1-snitzer@kernel.org/
> v1: https://lore.kernel.org/linux-nfs/20260929173423.16149-1-snitzer@kernel.org/
> 
> Thanks,
> Mike
> 
> Mike Snitzer (6):
>   mm: take a folio off WB_DONTCACHE_DIRTY only if it was counted there
>   mm: expose WB_DONTCACHE_DIRTY in bdi debugfs stats
>   mm: add folio_mark_dropbehind() to mark a folio dropbehind and account it
>   mm, iomap: keep a partly covered page until an uncached write completes it
>   mm, iomap: let an uncached writer complete its shared pages itself
>   NFSD: drop a shared boundary page only once both WRITEs have written it
> 
> 
>  .../filesystems/nfs/nfsd-io-modes.rst         |  17 ++
>  fs/iomap/buffered-io.c                        |  36 ++-
>  fs/iomap/trace.h                              |   3 +-
>  fs/nfsd/vfs.c                                 | 116 +++++++-
>  include/linux/fs.h                            |   8 +-
>  include/linux/iomap.h                         |   1 +
>  include/linux/pagemap.h                       |  14 +
>  mm/backing-dev.c                              |   6 +
>  mm/filemap.c                                  | 265 +++++++++++++++++-
>  9 files changed, 435 insertions(+), 31 deletions(-)
> 
> 
> base-commit: 6d13b7f74eec16e08d5e7f772ee119432a14ef2c

This all looks good to me at this point. This is a mixed mm and nfsd
set though. How do you envision this being merged?

Reviewed-by: Jeff Layton <jlayton@kernel.org>


  parent reply	other threads:[~2026-10-27 14:32 UTC|newest]

Thread overview: 14+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-10-24 22:11 [PATCH v9 0/6] mm, iomap, NFSD: stop uncached writes reading back shared pages Mike Snitzer
2026-10-24 22:11 ` [PATCH v9 1/6] mm: take a folio off WB_DONTCACHE_DIRTY only if it was counted there Mike Snitzer
2026-10-24 22:11 ` [PATCH v9 2/6] mm: expose WB_DONTCACHE_DIRTY in bdi debugfs stats Mike Snitzer
2026-10-24 22:11 ` [PATCH v9 3/6] mm: add folio_mark_dropbehind() to mark a folio dropbehind and account it Mike Snitzer
2026-10-25 22:12   ` sashiko-bot
2026-10-26  6:42     ` Mike Snitzer
2026-10-24 22:11 ` [PATCH v9 4/6] mm, iomap: keep a partly covered page until an uncached write completes it Mike Snitzer
2026-10-24 22:11 ` [PATCH v9 5/6] mm, iomap: let an uncached writer complete its shared pages itself Mike Snitzer
2026-10-24 22:11 ` [PATCH v9 6/6] NFSD: drop a shared boundary page only once both WRITEs have written it Mike Snitzer
2026-10-25 22:12   ` sashiko-bot
2026-10-26  6:45     ` Mike Snitzer
2026-10-27 14:31 ` Jeff Layton [this message]
2026-10-27 15:36   ` [PATCH v9 0/6] mm, iomap, NFSD: stop uncached writes reading back shared pages Chuck Lever
2026-10-28  5:12     ` 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=fc2ea8d6f2cd9ae83d38941f90386aac6638a497.camel@kernel.org \
    --to=jlayton@kernel.org \
    --cc=Dai.Ngo@oracle.com \
    --cc=axboe@kernel.dk \
    --cc=cel@kernel.org \
    --cc=corbet@lwn.net \
    --cc=hch@lst.de \
    --cc=linux-fsdevel@vger.kernel.org \
    --cc=linux-mm@kvack.org \
    --cc=linux-nfs@vger.kernel.org \
    --cc=neil@brown.name \
    --cc=okorniev@redhat.com \
    --cc=snitzer@kernel.org \
    --cc=tom@talpey.com \
    --cc=willy@infradead.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