From d8a28dde36068f94dee7c2ee7e92d556661d4eca Mon Sep 17 00:00:00 2001 From: David Hildenbrand Date: Mon, 2 Oct 2023 16:29:47 +0200 Subject: [PATCH] BACKPORT: mm/rmap: move SetPageAnonExclusive() out of page_move_anon_rmap() Patch series "mm/rmap: convert page_move_anon_rmap() to folio_move_anon_rmap()". Convert page_move_anon_rmap() to folio_move_anon_rmap(), letting the callers handle PageAnonExclusive. I'm including cleanup patch #3 because it fits into the picture and can be done cleaner by the conversion. This patch (of 3): Let's move it into the caller: there is a difference between whether an anon folio can only be mapped by one process (e.g., into one VMA), and whether it is truly exclusive (e.g., no references -- including GUP -- from other processes). Further, for large folios the page might not actually be pointing at the head page of the folio, so it better be handled in the caller. This is a preparation for converting page_move_anon_rmap() to consume a folio. Link: https://lkml.kernel.org/r/20231002142949.235104-1-david@redhat.com Link: https://lkml.kernel.org/r/20231002142949.235104-2-david@redhat.com Signed-off-by: David Hildenbrand Reviewed-by: Suren Baghdasaryan Reviewed-by: Vishal Moola (Oracle) Cc: Mike Kravetz Cc: Muchun Song Cc: Matthew Wilcox Signed-off-by: Andrew Morton Conflicts: 1. mm/hugetlb.c [Due to page_mapcount() instead of folio_mapcount() and folio_test_anon() instead of PageAnon()] (cherry picked from commit 5ca432896a4ce6d69fffc3298b24c0dd9bdb871f) Bug: 413428616 Bug: 313807618 Change-Id: Ibd29fec4d2a521d5ffc0782effd855cde9687a78 Signed-off-by: Suren Baghdasaryan Signed-off-by: Lokesh Gidra --- mm/huge_memory.c | 1 + mm/hugetlb.c | 4 +++- mm/memory.c | 1 + mm/rmap.c | 1 - 4 files changed, 5 insertions(+), 2 deletions(-) diff --git a/mm/huge_memory.c b/mm/huge_memory.c index 90a9052b8384..531e47b6eed3 100644 --- a/mm/huge_memory.c +++ b/mm/huge_memory.c @@ -1372,6 +1372,7 @@ vm_fault_t do_huge_pmd_wp_page(struct vm_fault *vmf) pmd_t entry; page_move_anon_rmap(page, vma); + SetPageAnonExclusive(page); folio_unlock(folio); reuse: if (unlikely(unshare)) { diff --git a/mm/hugetlb.c b/mm/hugetlb.c index 4b517a75f8fe..011effee5f62 100644 --- a/mm/hugetlb.c +++ b/mm/hugetlb.c @@ -5581,8 +5581,10 @@ retry_avoidcopy: * owner and can reuse this page. */ if (page_mapcount(old_page) == 1 && PageAnon(old_page)) { - if (!PageAnonExclusive(old_page)) + if (!PageAnonExclusive(old_page)) { page_move_anon_rmap(old_page, vma); + SetPageAnonExclusive(old_page); + } if (likely(!unshare)) set_huge_ptep_writable(vma, haddr, ptep); diff --git a/mm/memory.c b/mm/memory.c index ee80a70947f8..921de73f5b21 100644 --- a/mm/memory.c +++ b/mm/memory.c @@ -3561,6 +3561,7 @@ static vm_fault_t do_wp_page(struct vm_fault *vmf) * sunglasses. Hit it. */ page_move_anon_rmap(vmf->page, vma); + SetPageAnonExclusive(vmf->page); folio_unlock(folio); reuse: if (unlikely(unshare)) { diff --git a/mm/rmap.c b/mm/rmap.c index 992502845a7d..c80af87c3376 100644 --- a/mm/rmap.c +++ b/mm/rmap.c @@ -1140,7 +1140,6 @@ void page_move_anon_rmap(struct page *page, struct vm_area_struct *vma) * folio_test_anon()) will not see one without the other. */ WRITE_ONCE(folio->mapping, anon_vma); - SetPageAnonExclusive(page); } /**