aboutsummaryrefslogtreecommitdiffstats
path: root/mm/filemap.c
diff options
context:
space:
mode:
authorDavid Howells <[email protected]>2023-06-28 10:48:51 +0000
committerAndrew Morton <[email protected]>2023-08-18 17:12:12 +0000
commit0201ebf274a306a6ebb95e5dc2d6a0a27c737cac (patch)
treef419d3eba3454f01be5f2be92697d796af49bccd /mm/filemap.c
parentrmap: pass the folio to __page_check_anon_rmap() (diff)
downloadkernel-0201ebf274a306a6ebb95e5dc2d6a0a27c737cac.tar.gz
kernel-0201ebf274a306a6ebb95e5dc2d6a0a27c737cac.zip
mm: merge folio_has_private()/filemap_release_folio() call pairs
Patch series "mm, netfs, fscache: Stop read optimisation when folio removed from pagecache", v7. This fixes an optimisation in fscache whereby we don't read from the cache for a particular file until we know that there's data there that we don't have in the pagecache. The problem is that I'm no longer using PG_fscache (aka PG_private_2) to indicate that the page is cached and so I don't get a notification when a cached page is dropped from the pagecache. The first patch merges some folio_has_private() and filemap_release_folio() pairs and introduces a helper, folio_needs_release(), to indicate if a release is required. The second patch is the actual fix. Following Willy's suggestions[1], it adds an AS_RELEASE_ALWAYS flag to an address_space that will make filemap_release_folio() always call ->release_folio(), even if PG_private/PG_private_2 aren't set. folio_needs_release() is altered to add a check for this. This patch (of 2): Make filemap_release_folio() check folio_has_private(). Then, in most cases, where a call to folio_has_private() is immediately followed by a call to filemap_release_folio(), we can get rid of the test in the pair. There are a couple of sites in mm/vscan.c that this can't so easily be done. In shrink_folio_list(), there are actually three cases (something different is done for incompletely invalidated buffers), but filemap_release_folio() elides two of them. In shrink_active_list(), we don't have have the folio lock yet, so the check allows us to avoid locking the page unnecessarily. A wrapper function to check if a folio needs release is provided for those places that still need to do it in the mm/ directory. This will acquire additional parts to the condition in a future patch. After this, the only remaining caller of folio_has_private() outside of mm/ is a check in fuse. Link: https://lkml.kernel.org/r/[email protected] Link: https://lkml.kernel.org/r/[email protected] Reported-by: Rohith Surabattula <[email protected]> Suggested-by: Matthew Wilcox <[email protected]> Signed-off-by: David Howells <[email protected]> Cc: Matthew Wilcox <[email protected]> Cc: Linus Torvalds <[email protected]> Cc: Steve French <[email protected]> Cc: Shyam Prasad N <[email protected]> Cc: Rohith Surabattula <[email protected]> Cc: Dave Wysochanski <[email protected]> Cc: Dominique Martinet <[email protected]> Cc: Ilya Dryomov <[email protected]> Cc: "Theodore Ts'o" <[email protected]> Cc: Andreas Dilger <[email protected]> Cc: Xiubo Li <[email protected]> Cc: Jingbo Xu <[email protected]> Signed-off-by: Andrew Morton <[email protected]>
Diffstat (limited to 'mm/filemap.c')
-rw-r--r--mm/filemap.c2
1 files changed, 2 insertions, 0 deletions
diff --git a/mm/filemap.c b/mm/filemap.c
index 93e495d2d477..dd022b065614 100644
--- a/mm/filemap.c
+++ b/mm/filemap.c
@@ -4073,6 +4073,8 @@ bool filemap_release_folio(struct folio *folio, gfp_t gfp)
struct address_space * const mapping = folio->mapping;
BUG_ON(!folio_test_locked(folio));
+ if (!folio_needs_release(folio))
+ return true;
if (folio_test_writeback(folio))
return false;