mm/filemap.c | 2 ++ 1 file changed, 2 insertions(+)
From: Wenjie Qi <qiwenjie@xiaomi.com>
filemap_map_pages() maps uptodate folios speculatively without going
through the normal filemap lookup that clears dropbehind. As a result,
a neighboring dropbehind folio can acquire a PTE and the mapped-folio
completion guard will retain it even if that PTE is never accessed.
Skip still-dropbehind folios in next_uptodate_folio(). If the skipped
folio covers the fault address, do_read_fault() falls back to
filemap_fault(), where the normal lookup clears dropbehind and updates
WB_DONTCACHE_DIRTY accounting before mapping it. Speculative neighbors
remain unmapped and can be discarded when I/O completes. Normal folios
continue to use fault-around.
Dropbehind is folio-wide, so a fault into any subpage retains the whole
large folio through the normal fault path.
Signed-off-by: Wenjie Qi <qiwenjie@xiaomi.com>
---
Tested on XFS over a 5-second dm-delay target in QEMU:
- neighbor-dontcache: the target remained unmapped and was evicted.
- target-dontcache: the directly faulted target was mapped and retained.
- neighbor-normal: the target was fault-around mapped and retained.
- unmapped-dontcache: the target remained unmapped and was evicted.
All cases completed writeback, validated data, and kept dmesg clean.
mm/filemap.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/mm/filemap.c b/mm/filemap.c
index 00fd89cf6f550..c123de583b3e1 100644
--- a/mm/filemap.c
+++ b/mm/filemap.c
@@ -3769,6 +3769,8 @@ static struct folio *next_uptodate_folio(struct xa_state *xas,
goto unlock;
if (!folio_test_uptodate(folio))
goto unlock;
+ if (folio_test_dropbehind(folio))
+ goto unlock;
max_idx = DIV_ROUND_UP(i_size_read(mapping->host), PAGE_SIZE);
if (xas->xa_index >= max_idx)
goto unlock;
--
2.43.0
On Sun, Aug 30, 2026 at 07:48:45PM +0800, Wenjie Qi wrote: > From: Wenjie Qi <qiwenjie@xiaomi.com> > > filemap_map_pages() maps uptodate folios speculatively without going > through the normal filemap lookup that clears dropbehind. As a result, > a neighboring dropbehind folio can acquire a PTE and the mapped-folio > completion guard will retain it even if that PTE is never accessed. > > Skip still-dropbehind folios in next_uptodate_folio(). If the skipped > folio covers the fault address, do_read_fault() falls back to > filemap_fault(), where the normal lookup clears dropbehind and updates > WB_DONTCACHE_DIRTY accounting before mapping it. Speculative neighbors > remain unmapped and can be discarded when I/O completes. Normal folios > continue to use fault-around. > > Dropbehind is folio-wide, so a fault into any subpage retains the whole > large folio through the normal fault path. I don't think we should do this. Even if a folio is brought in through fault-around, it still indicates some conflict between dropbehind and another user, which indicates that the dropbehind hint was wrong.
© 2016 - 2026 Red Hat, Inc.