Linux filesystem development
 help / color / mirror / Atom feed
* [RFC PATCH 0/5] mm: sub-folio dirty tracking for PTE-mapped mmap writes
@ 2026-09-03 18:29 Kiryl Shutsemau
  2026-09-03 18:29 ` [RFC PATCH 1/5] mm: let folio_mkclean() report which pages had dirty PTEs Kiryl Shutsemau
                   ` (5 more replies)
  0 siblings, 6 replies; 8+ messages in thread
From: Kiryl Shutsemau @ 2026-09-03 18:29 UTC (permalink / raw)
  To: akpm, Matthew Wilcox (Oracle), David Hildenbrand
  Cc: Lorenzo Stoakes, Liam R. Howlett, Vlastimil Babka, Mike Rapoport,
	Suren Baghdasaryan, Michal Hocko, Jan Kara, Rik van Riel,
	Harry Yoo, Lance Yang, Jann Horn, Alexander Viro,
	Christian Brauner, Darrick J. Wong, Carlos Maiolino, Usama Arif,
	Pedro Falcato, linux-mm, linux-fsdevel, linux-xfs, linux-kernel,
	kernel-team, Kiryl Shutsemau (Meta)

From: "Kiryl Shutsemau (Meta)" <kas@kernel.org>

A store through a shared file mapping dirties the whole folio. With large
page cache folios that turns a 4K store into 2M of writeback: one dirty
bit per folio, and writeback has no way to know which part changed.

XFS already knows better. iomap tracks dirty state per block and
iomap_writeback_folio() submits only the dirty ranges, and the buffered
write path sets just the range it copied. Only the mmap path throws that
away, because iomap_dirty_folio() covers the whole folio.

Narrowing the dirtying at page_mkwrite() time does not work on its own:
set_pte_range() batch-maps a whole folio writable on the first shared
write fault, so the stores that follow never fault and never reach the
filesystem.

So harvest the hardware instead. folio_clear_dirty_for_io() already calls
folio_mkclean(), whose rmap walk reads pte_dirty() for every entry of the
folio and throws it away. Those bits are the only record of which parts
of a large folio were written through a mapping. Collect them there and
hand the filesystem the runs that were dirty, through a new
a_ops->dirty_folio_range().

All of this is about PTE-mapped folios. A PMD-mapped folio has a single
dirty bit for the 2M it maps, so there is nothing finer to harvest, and
it keeps writing back whole. Keeping shared write faults off PMDs is a
separate patch and not part of this posting.

On a 512M file in 2M folios on XFS, storing one byte per folio and
calling msync() wrote 512M before and writes 1M after, with identical
minor fault counts.

Not addressed here:

 - Dirty accounting stays folio-granular. A 4K store still counts as 2M
   against dirty_ratio and balance_dirty_pages().
 - iomap_page_mkwrite() still allocates blocks for the whole folio.
 - Filesystems without per-block dirty state see no change.

Kiryl Shutsemau (Meta) (5):
  mm: let folio_mkclean() report which pages had dirty PTEs
  mm: add a_ops->dirty_folio_range() and use the mkclean dirty harvest
  mm: keep the mmap dirty range down to the faulting page
  iomap: narrow page_mkwrite() dirtying to the faulting page
  xfs: track mmap dirty state per block

 fs/iomap/buffered-io.c | 37 +++++++++++++-----
 fs/xfs/xfs_aops.c      |  2 +-
 include/linux/fs.h     |  3 ++
 include/linux/iomap.h  |  2 +
 include/linux/mm.h     |  1 +
 include/linux/rmap.h   |  7 ++++
 mm/memory.c            | 58 ++++++++++++++++++++++++++--
 mm/page-writeback.c    | 87 +++++++++++++++++++++++++++++++++++++++---
 mm/rmap.c              | 56 +++++++++++++++++++++------
 9 files changed, 222 insertions(+), 31 deletions(-)


base-commit: 0a0d1d55dad570724bf8c7ea83409639cfb4be9b
-- 
2.54.0


^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2026-09-03 21:19 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-09-03 18:29 [RFC PATCH 0/5] mm: sub-folio dirty tracking for PTE-mapped mmap writes Kiryl Shutsemau
2026-09-03 18:29 ` [RFC PATCH 1/5] mm: let folio_mkclean() report which pages had dirty PTEs Kiryl Shutsemau
2026-09-03 18:29 ` [RFC PATCH 2/5] mm: add a_ops->dirty_folio_range() and use the mkclean dirty harvest Kiryl Shutsemau
2026-09-03 18:29 ` [RFC PATCH 3/5] mm: keep the mmap dirty range down to the faulting page Kiryl Shutsemau
2026-09-03 18:29 ` [RFC PATCH 4/5] iomap: narrow page_mkwrite() dirtying " Kiryl Shutsemau
2026-09-03 18:29 ` [RFC PATCH 5/5] xfs: track mmap dirty state per block Kiryl Shutsemau
2026-09-03 19:55 ` [RFC PATCH 0/5] mm: sub-folio dirty tracking for PTE-mapped mmap writes Pedro Falcato
2026-09-03 21:18   ` Kiryl Shutsemau

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox