All of lore.kernel.org
 help / color / mirror / Atom feed
From: Dev Jain <dev.jain@arm.com>
To: akpm@linux-foundation.org, david@kernel.org, ljs@kernel.org,
	hughd@google.com, chrisl@kernel.org, kasong@tencent.com,
	davem@davemloft.net, andreas@gaisler.com
Cc: Dev Jain <dev.jain@arm.com>,
	riel@surriel.com, liam@infradead.org, vbabka@kernel.org,
	harry@kernel.org, jannh@google.com, lance.yang@linux.dev,
	baolin.wang@linux.alibaba.com, shikemeng@huaweicloud.com,
	nphamcs@gmail.com, baoquan.he@linux.dev, baohua@kernel.org,
	youngjun.park@lge.com, linux-mm@kvack.org,
	linux-kernel@vger.kernel.org, rppt@kernel.org, surenb@google.com,
	mhocko@suse.com, pfalcato@suse.de, jgg@ziepe.ca,
	thuth@redhat.com, sparclinux@vger.kernel.org,
	ryan.roberts@arm.com, anshuman.khandual@arm.com
Subject: [PATCH v3 9/9] mm, sparc: batch arch_unmap_one()
Date: Thu, 24 Sep 2026 13:09:37 +0000	[thread overview]
Message-ID: <20260924131106.1730494-10-dev.jain@arm.com> (raw)
In-Reply-To: <20260924131106.1730494-1-dev.jain@arm.com>

The anonymous large-folio unmap batching path can clear and replace
multiple PTEs at once, but architectures like sparc need arch_unmap_one()
to preserve per-page metadata before swap entries are installed.
sparc uses this hook to save ADI tags.

Extend arch_unmap_one() to operate on a pte range.

sparc uses the count to walk the PTE range and save ADI tags for entries
carrying _PAGE_MCD_4V. There is no reverse operation for a partially
saved range: saving ADI tags only records a copy for later restore, so
if a later entry fails and the core keeps the original PTEs, there is
no architectural state to unsave.

Signed-off-by: Dev Jain <dev.jain@arm.com>
---
 arch/sparc/include/asm/pgtable_64.h | 10 +++++++---
 arch/sparc/kernel/adi_64.c          | 21 +++++++++++++++++++++
 include/linux/pgtable.h             |  6 +++---
 mm/rmap.c                           | 11 +++--------
 4 files changed, 34 insertions(+), 14 deletions(-)

diff --git a/arch/sparc/include/asm/pgtable_64.h b/arch/sparc/include/asm/pgtable_64.h
index 44d1333065a6a..f7dd1872884e4 100644
--- a/arch/sparc/include/asm/pgtable_64.h
+++ b/arch/sparc/include/asm/pgtable_64.h
@@ -1037,6 +1037,9 @@ void adi_restore_tags(struct mm_struct *mm, struct vm_area_struct *vma,
 int adi_save_tags(struct mm_struct *mm, struct vm_area_struct *vma,
 		  unsigned long addr, pte_t oldpte);
 
+int adi_save_tags_range(struct mm_struct *mm, struct vm_area_struct *vma,
+			unsigned long addr, pte_t oldpte, unsigned long nr);
+
 #define __HAVE_ARCH_DO_SWAP_PAGE
 static inline void arch_do_swap_page(struct mm_struct *mm,
 				     struct vm_area_struct *vma,
@@ -1057,10 +1060,11 @@ static inline void arch_do_swap_page(struct mm_struct *mm,
 #define __HAVE_ARCH_UNMAP_ONE
 static inline int arch_unmap_one(struct mm_struct *mm,
 				 struct vm_area_struct *vma,
-				 unsigned long addr, pte_t oldpte)
+				 unsigned long addr, pte_t oldpte,
+				 unsigned long nr)
 {
-	if (adi_state.enabled && (pte_val(oldpte) & _PAGE_MCD_4V))
-		return adi_save_tags(mm, vma, addr, oldpte);
+	if (adi_state.enabled)
+		return adi_save_tags_range(mm, vma, addr, oldpte, nr);
 	return 0;
 }
 
diff --git a/arch/sparc/kernel/adi_64.c b/arch/sparc/kernel/adi_64.c
index 18036a43cf568..ffa378accefe3 100644
--- a/arch/sparc/kernel/adi_64.c
+++ b/arch/sparc/kernel/adi_64.c
@@ -9,6 +9,7 @@
 #include <linux/init.h>
 #include <linux/slab.h>
 #include <linux/mm_types.h>
+#include <linux/pgtable.h>
 #include <asm/mdesc.h>
 #include <asm/adi_64.h>
 #include <asm/mmu_64.h>
@@ -394,3 +395,23 @@ int adi_save_tags(struct mm_struct *mm, struct vm_area_struct *vma,
 
 	return 0;
 }
+
+int adi_save_tags_range(struct mm_struct *mm, struct vm_area_struct *vma,
+			unsigned long addr, pte_t oldpte, unsigned long nr)
+{
+	unsigned long i;
+
+	for (i = 0; i < nr; i++, addr += PAGE_SIZE,
+	     oldpte = pte_next_pfn(oldpte)) {
+		int ret;
+
+		if (!(pte_val(oldpte) & _PAGE_MCD_4V))
+			continue;
+
+		ret = adi_save_tags(mm, vma, addr, oldpte);
+		if (ret)
+			return ret;
+	}
+
+	return 0;
+}
diff --git a/include/linux/pgtable.h b/include/linux/pgtable.h
index e3c8ab96941c5..d5c78dc938760 100644
--- a/include/linux/pgtable.h
+++ b/include/linux/pgtable.h
@@ -1431,12 +1431,12 @@ static inline void arch_do_swap_page_nr(struct mm_struct *mm,
  * restored when the page is swapped back in. SPARC M7 and newer
  * processors support an ADI (Application Data Integrity) tag for the
  * page as metadata for the page. arch_unmap_one() can save this
- * metadata on a swap-out of a page.
+ * metadata on swap-out of one or more pages.
  */
 static inline int arch_unmap_one(struct mm_struct *mm,
 				  struct vm_area_struct *vma,
-				  unsigned long addr,
-				  pte_t orig_pte)
+				  unsigned long addr, pte_t orig_pte,
+				  unsigned long nr)
 {
 	return 0;
 }
diff --git a/mm/rmap.c b/mm/rmap.c
index cdda9efd80bc3..774ddc75194b1 100644
--- a/mm/rmap.c
+++ b/mm/rmap.c
@@ -1959,6 +1959,7 @@ static inline unsigned int folio_unmap_pte_batch(struct folio *folio,
 
 	if (flags & TTU_HWPOISON)
 		return 1;
+
 	if (!folio_test_large(folio))
 		return 1;
 
@@ -1969,11 +1970,6 @@ static inline unsigned int folio_unmap_pte_batch(struct folio *folio,
 	if (pte_unused(pte))
 		return 1;
 
-#ifdef __HAVE_ARCH_UNMAP_ONE
-	if (folio_test_anon(folio) && folio_test_swapbacked(folio))
-		return 1;
-#endif
-
 	/*
 	 * If unmap fails, we need to restore the ptes. To avoid accidentally
 	 * upgrading write permissions for ptes that were not originally
@@ -2168,8 +2164,7 @@ static bool __ttu_anon_swapbacked_folio(struct vm_area_struct *vma,
 	 * architectures where we could have PFN swap PTEs,
 	 * so we'll not check/care.
 	 */
-	if (arch_unmap_one(mm, vma, address, pteval) < 0) {
-		VM_WARN_ON(nr_pages != 1);
+	if (arch_unmap_one(mm, vma, address, pteval, nr_pages) < 0) {
 		folio_put_swap_pages(folio, page, nr_pages);
 		return false;
 	}
@@ -2746,7 +2741,7 @@ static bool try_to_migrate_one(struct folio *folio, struct vm_area_struct *vma,
 			 * architectures where we could have PFN swap PTEs,
 			 * so we'll not check/care.
 			 */
-			if (arch_unmap_one(mm, vma, address, pteval) < 0) {
+			if (arch_unmap_one(mm, vma, address, pteval, 1) < 0) {
 				if (folio_test_hugetlb(folio))
 					set_huge_pte_at(mm, address, pvmw.pte,
 							pteval, hsz);
-- 
2.43.0



  parent reply	other threads:[~2026-09-24 13:12 UTC|newest]

Thread overview: 21+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-09-24 13:09 [PATCH v3 0/9] Optimize anonymous swapbacked large folio unmapping Dev Jain
2026-09-24 13:09 ` [PATCH v3 1/9] mm/swapfile: add batched version of folio_dup_swap Dev Jain
2026-09-29  9:20   ` Kairui Song
2026-09-24 13:09 ` [PATCH v3 2/9] mm/swapfile: add batched version of folio_put_swap Dev Jain
2026-09-29  9:22   ` Kairui Song
2026-09-24 13:09 ` [PATCH v3 3/9] mm: move anon-exclusive batch helper to rmap.h Dev Jain
2026-09-24 21:02   ` Barry Song
2026-09-25 10:18     ` Dev Jain
2026-09-24 13:09 ` [PATCH v3 4/9] mm/rmap: Add batched version of folio_try_share_anon_rmap_pte Dev Jain
2026-09-25  5:30   ` Barry Song
2026-09-25 11:09     ` Dev Jain
2026-09-25 12:03       ` Barry Song
2026-09-24 13:09 ` [PATCH v3 5/9] mm/internal: rename swap offset helpers to softleaf offset Dev Jain
2026-09-24 13:09 ` [PATCH v3 6/9] mm/internal: add set_softleaf_ptes Dev Jain
2026-09-24 13:09 ` [PATCH v3 7/9] mm/memory: use set_softleaf_ptes for uffd-wp markers Dev Jain
2026-09-24 13:09 ` [PATCH v3 8/9] mm/rmap: batch unmap anonymous swap-backed large folios Dev Jain
2026-09-25  6:15   ` Barry Song
2026-09-25 11:25     ` Dev Jain
2026-09-26 12:37       ` Dev Jain
2026-09-24 13:09 ` Dev Jain [this message]
2026-10-02 10:15 ` [PATCH v3 0/9] Optimize anonymous swapbacked large folio unmapping David Hildenbrand (Arm)

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260924131106.1730494-10-dev.jain@arm.com \
    --to=dev.jain@arm.com \
    --cc=akpm@linux-foundation.org \
    --cc=andreas@gaisler.com \
    --cc=anshuman.khandual@arm.com \
    --cc=baohua@kernel.org \
    --cc=baolin.wang@linux.alibaba.com \
    --cc=baoquan.he@linux.dev \
    --cc=chrisl@kernel.org \
    --cc=davem@davemloft.net \
    --cc=david@kernel.org \
    --cc=harry@kernel.org \
    --cc=hughd@google.com \
    --cc=jannh@google.com \
    --cc=jgg@ziepe.ca \
    --cc=kasong@tencent.com \
    --cc=lance.yang@linux.dev \
    --cc=liam@infradead.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-mm@kvack.org \
    --cc=ljs@kernel.org \
    --cc=mhocko@suse.com \
    --cc=nphamcs@gmail.com \
    --cc=pfalcato@suse.de \
    --cc=riel@surriel.com \
    --cc=rppt@kernel.org \
    --cc=ryan.roberts@arm.com \
    --cc=shikemeng@huaweicloud.com \
    --cc=sparclinux@vger.kernel.org \
    --cc=surenb@google.com \
    --cc=thuth@redhat.com \
    --cc=vbabka@kernel.org \
    --cc=youngjun.park@lge.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.