summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2022-10-30 13:50:39 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2022-10-31 14:14:32 -0700
commit87f9406d812f49a86e27d4854e76c66ae4c848e8 (patch)
treebee505badbd4d11aed322c05cb26a453594aee9c
parent62f70d93f7f35684de03a4f55219fc0bebd7396d (diff)
downloadlinux-87f9406d812f49a86e27d4854e76c66ae4c848e8.tar.bz2
mm: inline simpler case of page_remove_file_rmap()
Now that we have a simplified special case of 'page_remove_rmap()' that doesn't deal with the 'compound' case and always gets a file-mapped (ie not anonymous) page, it ended up doing just lock_page_memcg(page); page_remove_file_rmap(page, false); unlock_page_memcg(page); but 'page_remove_file_rmap()' is actually trivial when 'compound' is false. So just inline that non-compound case in the caller, and - like we did in the previous commit for the anon pages - only do the memcg locking for the parts that actually matter: the page statistics. Also, as the previous commit did for anonymous pages, knowing we only get called for the last-level page table entries allows for a further simplification: we can get rid of the 'PageHuge(page)' case too. You can't map a huge-page in a pte without splitting it (and the full code in the generic page_remove_file_rmap() function has a comment to that effect: "hugetlb pages are always mapped with pmds"). That means that the page_zap_file_rmap() case of that whole function is really small and trivial. Link: https://lore.kernel.org/all/B88D3073-440A-41C7-95F4-895D3F657EF2@gmail.com/ Cc: Nadav Amit <nadav.amit@gmail.com> Cc: Peter Zijlstra <peterz@infradead.org> Cc: John Hubbard <jhubbard@nvidia.com> Cc: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r--mm/rmap.c5
1 files changed, 4 insertions, 1 deletions
diff --git a/mm/rmap.c b/mm/rmap.c
index 71a5365f23f3..69de6c833d5c 100644
--- a/mm/rmap.c
+++ b/mm/rmap.c
@@ -1426,8 +1426,11 @@ static void page_remove_anon_compound_rmap(struct page *page)
*/
void page_zap_file_rmap(struct page *page)
{
+ if (!atomic_add_negative(-1, &page->_mapcount))
+ return;
+
lock_page_memcg(page);
- page_remove_file_rmap(page, false);
+ __dec_lruvec_page_state(page, NR_FILE_MAPPED);
unlock_page_memcg(page);
}