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(-)
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
On Thu, 3 Sep 2026 19:29:38 +0100 Kiryl Shutsemau <kirill@shutemov.name> wrote: > 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. Hi Kiryl, The motivation makes sense to me. I will look into the patches. Just wanted to check, the above xfs example, is that on an ARM host? Thanks, Usama > > 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 > >
On Wed, Sep 09, 2026 at 03:02:39AM -0700, Usama Arif wrote: > On Thu, 3 Sep 2026 19:29:38 +0100 Kiryl Shutsemau <kirill@shutemov.name> wrote: > > > 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. > > Hi Kiryl, > > The motivation makes sense to me. I will look into the patches. > > Just wanted to check, the above xfs example, is that on an ARM host? No, that was x86. But the math is the same on any arch with 2M THP/mTHP in page cache and 4k PAGE_SIZE. -- Kiryl Shutsemau / Kirill A. Shutemov
On Thu, Sep 03, 2026 at 07:29:38PM +0100, Kiryl Shutsemau wrote: > 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(). Boris pointed me to Matthew's proposal to remove ->dirty_folio: https://lore.kernel.org/all/aoyWln-Gt-yvZQkE@casper.infradead.org I agree that the current ->dirty_folio() makes little sense and that dirtying the folio can be bundled into ->page_mkwrite(), as they are matched 1-to-1. My proposal makes the distinction between making the folio writable and making it dirty meaningful. ->page_mkwrite() allocates whatever is needed on the filesystem side to track dirty state and drive writeback for the *folio*, while ->dirty_folio_range() marks part of the folio dirty. We can still drop ->dirty_folio(). A filesystem can provide ->dirty_folio_range() if it wants fine-grained (sub-folio) dirty tracking. A separate question is whether we want to avoid installing a writable PMD entry for filesystems that want fine-grained dirty tracking. I have a patch for this, but it deserves a separate discussion once we agree that we want this for PTE-mapped folios first. Any feedback? > 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 / Kirill A. Shutemov
On Mon, Sep 07, 2026 at 11:15:15AM +0100, Kiryl Shutsemau wrote: > Boris pointed me to Matthew's proposal to remove ->dirty_folio: > > https://lore.kernel.org/all/aoyWln-Gt-yvZQkE@casper.infradead.org Thanks, Boris ;-) > I agree that the current ->dirty_folio() makes little sense and that > dirtying the folio can be bundled into ->page_mkwrite(), as they are > matched 1-to-1. > > My proposal makes the distinction between making the folio writable and > making it dirty meaningful. ->page_mkwrite() allocates whatever is needed > on the filesystem side to track dirty state and drive writeback for the > *folio*, while ->dirty_folio_range() marks part of the folio dirty. Why do you think that's a meaningful distinction? We create a writable PTE because we've taken a page fault for write. There's probably a few naoseconds where the PTE is writable+clean before it becomes writable+dirty, but even then sometimes we do both pte_mkwrite() and pte_mkdirty() as an optimisation in the write fault path. > We can still drop ->dirty_folio(). A filesystem can provide > ->dirty_folio_range() if it wants fine-grained (sub-folio) dirty > tracking. > > A separate question is whether we want to avoid installing a writable PMD > entry for filesystems that want fine-grained dirty tracking. I have a > patch for this, but it deserves a separate discussion once we agree that we > want this for PTE-mapped folios first. > > Any feedback? It's very odd to be optimising for shared-writable-mmap. This is a horrid model for I/O. https://cs.brown.edu/people/acrotty/pubs/p13-crotty.pdf
On Wed, Sep 16, 2026 at 05:27:42PM +0100, Matthew Wilcox wrote: > On Mon, Sep 07, 2026 at 11:15:15AM +0100, Kiryl Shutsemau wrote: > > Boris pointed me to Matthew's proposal to remove ->dirty_folio: > > > > https://lore.kernel.org/all/aoyWln-Gt-yvZQkE@casper.infradead.org > > Thanks, Boris ;-) > > > I agree that the current ->dirty_folio() makes little sense and that > > dirtying the folio can be bundled into ->page_mkwrite(), as they are > > matched 1-to-1. > > > > My proposal makes the distinction between making the folio writable and > > making it dirty meaningful. ->page_mkwrite() allocates whatever is needed > > on the filesystem side to track dirty state and drive writeback for the > > *folio*, while ->dirty_folio_range() marks part of the folio dirty. > > Why do you think that's a meaningful distinction? We create a writable > PTE because we've taken a page fault for write. There's probably a few > naoseconds where the PTE is writable+clean before it becomes > writable+dirty, but even then sometimes we do both pte_mkwrite() and > pte_mkdirty() as an optimisation in the write fault path. This is true for the PTE that the fault was for. But we don't necessarily want to dirty the other 511 pages at the same time. The basic idea is to make the whole folio writable at fault and shift dirtying to be per-PTE on write to it. > > We can still drop ->dirty_folio(). A filesystem can provide > > ->dirty_folio_range() if it wants fine-grained (sub-folio) dirty > > tracking. > > > > A separate question is whether we want to avoid installing a writable PMD > > entry for filesystems that want fine-grained dirty tracking. I have a > > patch for this, but it deserves a separate discussion once we agree that we > > want this for PTE-mapped folios first. > > > > Any feedback? > > It's very odd to be optimising for shared-writable-mmap. This is a > horrid model for I/O. https://cs.brown.edu/people/acrotty/pubs/p13-crotty.pdf Sure. But not everybody got the memo[1] :P I think it worth considering if we want to make large folio adoption smoother. [1] https://www.reddit.com/r/bcachefs/comments/1vepk4a/comment/p1sn4v1/ -- Kiryl Shutsemau / Kirill A. Shutemov
On Wed, Sep 16, 2026 at 06:09:17PM +0100, Kiryl Shutsemau wrote: > On Wed, Sep 16, 2026 at 05:27:42PM +0100, Matthew Wilcox wrote: > > On Mon, Sep 07, 2026 at 11:15:15AM +0100, Kiryl Shutsemau wrote: > > > My proposal makes the distinction between making the folio writable and > > > making it dirty meaningful. ->page_mkwrite() allocates whatever is needed > > > on the filesystem side to track dirty state and drive writeback for the > > > *folio*, while ->dirty_folio_range() marks part of the folio dirty. > > > > Why do you think that's a meaningful distinction? We create a writable > > PTE because we've taken a page fault for write. There's probably a few > > naoseconds where the PTE is writable+clean before it becomes > > writable+dirty, but even then sometimes we do both pte_mkwrite() and > > pte_mkdirty() as an optimisation in the write fault path. > > This is true for the PTE that the fault was for. But we don't necessarily > want to dirty the other 511 pages at the same time. > > The basic idea is to make the whole folio writable at fault and shift > dirtying to be per-PTE on write to it. Hmm. Is that something that filesystem people want? I suspect not. I think they'd prefer to be told when we write-fault on each page. But let's see if we can gather feedback from FS people. > > It's very odd to be optimising for shared-writable-mmap. This is a > > horrid model for I/O. https://cs.brown.edu/people/acrotty/pubs/p13-crotty.pdf > > Sure. > > But not everybody got the memo[1] :P > > I think it worth considering if we want to make large folio adoption > smoother. > > [1] https://www.reddit.com/r/bcachefs/comments/1vepk4a/comment/p1sn4v1/ Since I'm an idiot, I'm not inclined to be helpful. But I think my proposal does fix this; we call page_mkwrite() for each page fault and then the filesystem knows which pages are actually dirty without having to be told under the PTL when they can't reserve space.
On Wed 16-09-26 18:19:29, Matthew Wilcox wrote: > On Wed, Sep 16, 2026 at 06:09:17PM +0100, Kiryl Shutsemau wrote: > > On Wed, Sep 16, 2026 at 05:27:42PM +0100, Matthew Wilcox wrote: > > > On Mon, Sep 07, 2026 at 11:15:15AM +0100, Kiryl Shutsemau wrote: > > > > My proposal makes the distinction between making the folio writable and > > > > making it dirty meaningful. ->page_mkwrite() allocates whatever is needed > > > > on the filesystem side to track dirty state and drive writeback for the > > > > *folio*, while ->dirty_folio_range() marks part of the folio dirty. > > > > > > Why do you think that's a meaningful distinction? We create a writable > > > PTE because we've taken a page fault for write. There's probably a few > > > naoseconds where the PTE is writable+clean before it becomes > > > writable+dirty, but even then sometimes we do both pte_mkwrite() and > > > pte_mkdirty() as an optimisation in the write fault path. > > > > This is true for the PTE that the fault was for. But we don't necessarily > > want to dirty the other 511 pages at the same time. > > > > The basic idea is to make the whole folio writable at fault and shift > > dirtying to be per-PTE on write to it. > > Hmm. Is that something that filesystem people want? I suspect not. > I think they'd prefer to be told when we write-fault on each page. > But let's see if we can gather feedback from FS people. Well, learning about write-fault of each page is certainly a simpler model for filesystems to deal with. What Kirill currently does is that the fs learns about write-fault of the whole folio (so it prepares space for it) but then dirtying happens only for some pages (so under the rest of the folio just remain unwritten extents / delalloc reservations). Filesystems can accommodate that although it will currently somewhat upset ext4's delayed allocation reservation system. We will have there unreclaimable in-memory extents tracking these reservations and on inode eviction we'll complain they were never used. What might get ugly with current Kirill's approach is if some simpler filesystem doesn't have a concept of unwritten extents and delayed allocation (like old ext2 or vfat) but still allocates blocks in .page_mkwrite to make sure we don't hit ENOSPC / EDQUOT during writeback. Then it implicitely relies on current MM behavior of calling .page_mkwrite only on pages that cannot be evicted without writeback - if the eviction happens, we've just exposed uninitialized on disk data. In fact this is what would happen with current ext4 when you turn off delalloc and have old indirect-block based inode format, except that ext4 is careful enough to dirty all the buffers underlying the folio (and the folio itself) on its own so there's no data exposure, we just loose Kirill's optimization. So overall I don't find unsolvable issues with this but it will certainly require some tweaking on fs side. Honza -- Jan Kara <jack@suse.com> SUSE Labs, CR
On Thu, Sep 03, 2026 at 07:29:38PM +0100, Kiryl Shutsemau wrote: > 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. > Hmm, I believe Willy already had some patches; I don't know what came of them (I think he's out for now). > 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. Help me out here: in which case does this happen? page fault handling is a mess... I think page_mkwrite is always called, no? in do_shared_fault(). > > 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(). I think this goes against what we're trying to pull off. We want a single method of dirtying folios, not 3. Ideally(tm) we would have a single mkwrite interface. > > 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. But the effects are definitely nice though :) > > Not addressed here: > > - Dirty accounting stays folio-granular. A 4K store still counts as 2M > against dirty_ratio and balance_dirty_pages(). That is correct; I don't think doing subpage accounting makes any sense, the whole folio is still dirty, and for reclaim purposes can't be thrown away (unless you added gnarly split logic for file folios as well). > - 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 > -- Pedro
On Thu, Sep 03, 2026 at 08:55:36PM +0100, Pedro Falcato wrote:
> On Thu, Sep 03, 2026 at 07:29:38PM +0100, Kiryl Shutsemau wrote:
> > 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.
>
> Help me out here: in which case does this happen? page fault handling is a
> mess... I think page_mkwrite is always called, no? in do_shared_fault().
It is always called, but once per folio, not once per page. It is the
filesystem's chance to preallocate whatever it needs to track dirty
state for the *folio*.
Later finish_fault() maps the folio. It tries to map it fully when it
can, so a write fault creates up to 512 writable PTEs on x86. And we
really do need to map the folio fully whenever we can. Otherwise we
significantly undercount mlocked memory. See commit 19773df031bc
("mm/fault: try to map the entire file folio in finish_fault()").
And once the whole folio is mapped with writable PTEs we cannot narrow
the dirtying to a subset of pages. Any of them can turn dirty at any
time, with nothing to record it.
--
Kiryl Shutsemau / Kirill A. Shutemov
On 9/3/26 20:29, Kiryl Shutsemau wrote: > 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. Just a note that with things like cont-pte we see the trend that we only have a single logical dirty bit for the entire coalesced PTE. Similar to having only a single dirty bit for a PMD-mapped THP. -- Cheers, David
© 2016 - 2026 Red Hat, Inc.