Commit e9e44c87 authored by Barry Song's avatar Barry Song Committed by Liu Shixin
Browse files

mm: extend rmap flags arguments for folio_add_new_anon_rmap

mainline inclusion
from mainline-v6.11-rc1
commit 15bde4abab734c687c1f81704886aba3a70c268e
category: feature
bugzilla: https://gitee.com/openeuler/kernel/issues/IAJ5MT

Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=15bde4abab734c687c1f81704886aba3a70c268e

--------------------------------

Patch series "mm: clarify folio_add_new_anon_rmap() and
__folio_add_anon_rmap()", v2.

This patchset is preparatory work for mTHP swapin.

folio_add_new_anon_rmap() assumes that new anon rmaps are always
exclusive.  However, this assumption doesn’t hold true for cases like
do_swap_page(), where a new anon might be added to the swapcache and is
not necessarily exclusive.

The patchset extends the rmap flags to allow folio_add_new_anon_rmap() to
handle both exclusive and non-exclusive new anon folios.  The
do_swap_page() function is updated to use this extended API with rmap
flags.  Consequently, all new anon folios now consistently use
folio_add_new_anon_rmap().  The special case for !folio_test_anon() in
__folio_add_anon_rmap() can be safely removed.

In conclusion, new anon folios always use folio_add_new_anon_rmap(),
regardless of exclusivity.  Old anon folios continue to use
__folio_add_anon_rmap() via folio_add_anon_rmap_pmd() and
folio_add_anon_rmap_ptes().

This patch (of 3):

In the case of a swap-in, a new anonymous folio is not necessarily
exclusive.  This patch updates the rmap flags to allow a new anonymous
folio to be treated as either exclusive or non-exclusive.  To maintain the
existing behavior, we always use EXCLUSIVE as the default setting.

[akpm@linux-foundation.org: cleanup and constifications per David and akpm]
[v-songbaohua@oppo.com: fix missing doc for flags of folio_add_new_anon_rmap()]
  Link: https://lkml.kernel.org/r/20240619210641.62542-1-21cnbao@gmail.com
[v-songbaohua@oppo.com: enhance doc for extend rmap flags arguments for folio_add_new_anon_rmap]
  Link: https://lkml.kernel.org/r/20240622030256.43775-1-21cnbao@gmail.com
Link: https://lkml.kernel.org/r/20240617231137.80726-1-21cnbao@gmail.com
Link: https://lkml.kernel.org/r/20240617231137.80726-2-21cnbao@gmail.com


Signed-off-by: default avatarBarry Song <v-songbaohua@oppo.com>
Suggested-by: default avatarDavid Hildenbrand <david@redhat.com>
Tested-by: default avatarShuai Yuan <yuanshuai@oppo.com>
Acked-by: default avatarDavid Hildenbrand <david@redhat.com>
Cc: Baolin Wang <baolin.wang@linux.alibaba.com>
Cc: Chris Li <chrisl@kernel.org>
Cc: "Huang, Ying" <ying.huang@intel.com>
Cc: Matthew Wilcox (Oracle) <willy@infradead.org>
Cc: Michal Hocko <mhocko@suse.com>
Cc: Ryan Roberts <ryan.roberts@arm.com>
Cc: Suren Baghdasaryan <surenb@google.com>
Cc: Yang Shi <shy828301@gmail.com>
Cc: Yosry Ahmed <yosryahmed@google.com>
Cc: Yu Zhao <yuzhao@google.com>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Conflicts:
	kernel/events/uprobes.c
	mm/khugepaged.c
	mm/memory.c
	mm/migrate_device.c
	mm/rmap.c
	mm/userswap.c
[ Context conflicts in uprobes.c, khugepaged.c, memory.c migrate_device.c
  with commit 3a5a643c852a
  Context conflicts in memory.c due to miss commit f7842747d13d
  Context conflicts in rmap.c due to miss commit 05c5323b2a34
  Fix folio_add_new_anon_rmap() in userswap.c ]
Signed-off-by: default avatarLiu Shixin <liushixin2@huawei.com>
parent 286201c8
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -236,7 +236,7 @@ void folio_add_anon_rmap_ptes(struct folio *, struct page *, int nr_pages,
void folio_add_anon_rmap_pmd(struct folio *, struct page *,
		struct vm_area_struct *, unsigned long address, rmap_t flags);
void folio_add_new_anon_rmap(struct folio *, struct vm_area_struct *,
		unsigned long address);
		unsigned long address, rmap_t flags);
void folio_add_file_rmap_ptes(struct folio *, struct page *, int nr_pages,
		struct vm_area_struct *);
#define folio_add_file_rmap_pte(folio, page, vma) \
+1 −1
Original line number Diff line number Diff line
@@ -182,7 +182,7 @@ static int __replace_page(struct vm_area_struct *vma, unsigned long addr,
	if (new_page) {
		folio_get(new_folio);
		add_reliable_folio_counter(new_folio, mm, folio_nr_pages(new_folio));
		folio_add_new_anon_rmap(new_folio, vma, addr);
		folio_add_new_anon_rmap(new_folio, vma, addr, RMAP_EXCLUSIVE);
		folio_add_lru_vma(new_folio, vma);
	} else
		/* no new page, just dec_mm_counter for old_page */
+1 −1
Original line number Diff line number Diff line
@@ -1187,7 +1187,7 @@ static vm_fault_t __do_huge_pmd_anonymous_page(struct vm_fault *vmf,

		entry = mk_huge_pmd(page, vma->vm_page_prot);
		entry = maybe_pmd_mkwrite(pmd_mkdirty(entry), vma);
		folio_add_new_anon_rmap(folio, vma, haddr);
		folio_add_new_anon_rmap(folio, vma, haddr, RMAP_EXCLUSIVE);
		folio_add_lru_vma(folio, vma);
		pgtable_trans_huge_deposit(vma->vm_mm, vmf->pmd, pgtable);
		set_pmd_at(vma->vm_mm, haddr, vmf->pmd, entry);
+1 −1
Original line number Diff line number Diff line
@@ -1258,7 +1258,7 @@ static int collapse_huge_page(struct mm_struct *mm, unsigned long address,
	spin_lock(pmd_ptl);
	BUG_ON(!pmd_none(*pmd));
	add_reliable_page_counter(hpage, vma->vm_mm, HPAGE_PMD_NR);
	folio_add_new_anon_rmap(folio, vma, address);
	folio_add_new_anon_rmap(folio, vma, address, RMAP_EXCLUSIVE);
	folio_add_lru_vma(folio, vma);
	pgtable_trans_huge_deposit(mm, pmd, pgtable);
	set_pmd_at(mm, address, pmd, _pmd);
+5 −5
Original line number Diff line number Diff line
@@ -923,7 +923,7 @@ copy_present_page(struct vm_area_struct *dst_vma, struct vm_area_struct *src_vma
	*prealloc = NULL;
	copy_user_highpage(&new_folio->page, page, addr, src_vma);
	__folio_mark_uptodate(new_folio);
	folio_add_new_anon_rmap(new_folio, dst_vma, addr);
	folio_add_new_anon_rmap(new_folio, dst_vma, addr, RMAP_EXCLUSIVE);
	folio_add_lru_vma(new_folio, dst_vma);
	rss[MM_ANONPAGES]++;

@@ -3363,7 +3363,7 @@ static vm_fault_t wp_page_copy(struct vm_fault *vmf)
		 * some TLBs while the old PTE remains in others.
		 */
		ptep_clear_flush(vma, vmf->address, vmf->pte);
		folio_add_new_anon_rmap(new_folio, vma, vmf->address);
		folio_add_new_anon_rmap(new_folio, vma, vmf->address, RMAP_EXCLUSIVE);
		folio_add_lru_vma(new_folio, vma);
		/*
		 * We call the notify macro here because, when using secondary
@@ -4293,7 +4293,7 @@ vm_fault_t do_swap_page(struct vm_fault *vmf)

	/* ksm created a completely new copy */
	if (unlikely(folio != swapcache && swapcache)) {
		folio_add_new_anon_rmap(folio, vma, address);
		folio_add_new_anon_rmap(folio, vma, address, RMAP_EXCLUSIVE);
		folio_add_lru_vma(folio, vma);
	} else {
		folio_add_anon_rmap_ptes(folio, page, nr_pages, vma, address,
@@ -4549,7 +4549,7 @@ static vm_fault_t do_anonymous_page(struct vm_fault *vmf)
	count_mthp_stat(folio_order(folio), MTHP_STAT_ANON_FAULT_ALLOC);
#endif
	add_reliable_folio_counter(folio, vma->vm_mm, nr_pages);
	folio_add_new_anon_rmap(folio, vma, addr);
	folio_add_new_anon_rmap(folio, vma, addr, RMAP_EXCLUSIVE);
	folio_add_lru_vma(folio, vma);
setpte:
	if (vmf_orig_pte_uffd_wp(vmf))
@@ -4749,7 +4749,7 @@ void set_pte_range(struct vm_fault *vmf, struct folio *folio,
	add_reliable_folio_counter(folio, vma->vm_mm, nr);
	if (write && !(vma->vm_flags & VM_SHARED)) {
		VM_BUG_ON_FOLIO(nr != 1, folio);
		folio_add_new_anon_rmap(folio, vma, addr);
		folio_add_new_anon_rmap(folio, vma, addr, RMAP_EXCLUSIVE);
		folio_add_lru_vma(folio, vma);
	} else {
		folio_add_file_rmap_ptes(folio, page, nr, vma);
Loading