summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWenjie Qi <qiwenjie@xiaomi.com>2026-08-30 01:36:12 +0800
committerAndrew Morton <akpm@linux-foundation.org>2026-09-05 11:47:48 -0700
commit848d2ce2fce15fbdc083fbf9691bfa72911033c4 (patch)
tree3e5e1bd0b0d8cfab5d65ecd1955fbba94e9ae149
parente1d469a8d6c63032a5aed3679a13a086b61bd5cc (diff)
downloadlinux-next-848d2ce2fce15fbdc083fbf9691bfa72911033c4.tar.gz
linux-next-848d2ce2fce15fbdc083fbf9691bfa72911033c4.zip
mm: filemap: retain mapped dropbehind folios
Fault-around can map ready dropbehind folios without going through the normal page-cache lookup that clears dropbehind. A mapping represents a competing cached user, so retain the folio instead of forcibly unmapping it when writeback completes. For a mapped folio, folio_unmap_invalidate() can call unmap_mapping_folio(), which takes i_mmap_rwsem and may sleep. Retaining mapped folios avoids this path when folio_end_dropbehind() runs in non-preemptible task context. Tal was able to trigger a sleeping-in-atomic warning due to this [1]. Unmapped dropbehind folios continue through the existing invalidation path. Link: https://lore.kernel.org/4aba05e1a2c3b61cb337d373eb9b7a8db4ddd822.1788024049.git.qiwenjie@xiaomi.com Link: https://lore.kernel.org/076bb01b-6fcf-4691-be8c-0e8507c9fe64@columbia.edu [1] Fixes: fb7d3bc41493 ("mm/filemap: drop streaming/uncached pages when writeback completes") Signed-off-by: Wenjie Qi <qiwenjie@xiaomi.com> Reviewed-by: Matthew Wilcox (Oracle) <willy@infradead.org> Reviewed-by: Tal Zussman <tz2294@columbia.edu> Tested-by: Tal Zussman <tz2294@columbia.edu> Cc: Barry Song <baohua@kernel.org> Cc: Jan Kara <jack@suse.cz> Cc: Jens Axboe <axboe@kernel.dk> Cc: Trond Myklebust <trond.myklebust@hammerspace.com> Cc: <stable@vger.kernel.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
-rw-r--r--mm/filemap.c2
1 files changed, 1 insertions, 1 deletions
diff --git a/mm/filemap.c b/mm/filemap.c
index 6afec636881f..00fd89cf6f55 100644
--- a/mm/filemap.c
+++ b/mm/filemap.c
@@ -1616,7 +1616,7 @@ static void filemap_end_dropbehind(struct folio *folio)
return;
if (!folio_test_clear_dropbehind(folio))
return;
- if (mapping)
+ if (mapping && !folio_mapped(folio))
folio_unmap_invalidate(mapping, folio, 0);
}