[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <fa317f33283b29bb14d49f4ff17b21c2db5c88b7.1734526570.git.zhengqi.arch@bytedance.com>
Date: Wed, 18 Dec 2024 21:04:51 +0800
From: Qi Zheng <zhengqi.arch@...edance.com>
To: peterz@...radead.org,
tglx@...utronix.de,
david@...hat.com,
jannh@...gle.com,
hughd@...gle.com,
yuzhao@...gle.com,
willy@...radead.org,
muchun.song@...ux.dev,
vbabka@...nel.org,
lorenzo.stoakes@...cle.com,
akpm@...ux-foundation.org,
rientjes@...gle.com,
vishal.moola@...il.com
Cc: linux-mm@...ck.org,
linux-kernel@...r.kernel.org,
Qi Zheng <zhengqi.arch@...edance.com>
Subject: [PATCH v2 15/15] mm: pgtable: introduce generic pagetable_dtor_free()
The pte_free(), pmd_free(), __pud_free() and __p4d_free() in
asm-generic/pgalloc.h and the generic __tlb_remove_table() are actually
the same, so let's introduce pagetable_dtor_free() to deduplicate them.
In addition, the pagetable_dtor_free() in s390 actually does the same
thing, so let's s390 also calls generic pagetable_dtor_free().
Signed-off-by: Qi Zheng <zhengqi.arch@...edance.com>
Suggested-by: Peter Zijlstra (Intel) <peterz@...radead.org>
---
arch/s390/mm/pgalloc.c | 18 ++++++------------
include/asm-generic/pgalloc.h | 23 ++++-------------------
include/asm-generic/tlb.h | 5 +----
include/linux/mm.h | 8 ++++++++
4 files changed, 19 insertions(+), 35 deletions(-)
diff --git a/arch/s390/mm/pgalloc.c b/arch/s390/mm/pgalloc.c
index 3e002dea6278f..1e0727be48eaf 100644
--- a/arch/s390/mm/pgalloc.c
+++ b/arch/s390/mm/pgalloc.c
@@ -180,32 +180,26 @@ unsigned long *page_table_alloc(struct mm_struct *mm)
return table;
}
-static void pagetable_dtor_free(struct ptdesc *ptdesc)
-{
- pagetable_dtor(ptdesc);
- pagetable_free(ptdesc);
-}
-
void page_table_free(struct mm_struct *mm, unsigned long *table)
{
- struct ptdesc *ptdesc = virt_to_ptdesc(table);
+ struct page *page = virt_to_page(table);
- pagetable_dtor_free(ptdesc);
+ pagetable_dtor_free(page);
}
#ifdef CONFIG_TRANSPARENT_HUGEPAGE
static void pte_free_now(struct rcu_head *head)
{
- struct ptdesc *ptdesc = container_of(head, struct ptdesc, pt_rcu_head);
+ struct page *page = container_of(head, struct page, rcu_head);
- pagetable_dtor_free(ptdesc);
+ pagetable_dtor_free(page);
}
void pte_free_defer(struct mm_struct *mm, pgtable_t pgtable)
{
- struct ptdesc *ptdesc = virt_to_ptdesc(pgtable);
+ struct page *page = virt_to_page(pgtable);
- call_rcu(&ptdesc->pt_rcu_head, pte_free_now);
+ call_rcu(&page->rcu_head, pte_free_now);
/*
* THPs are not allowed for KVM guests. Warn if pgste ever reaches here.
* Turn to the generic pte_free_defer() version once gmap is removed.
diff --git a/include/asm-generic/pgalloc.h b/include/asm-generic/pgalloc.h
index 3673e9c29504e..370f5b579ff88 100644
--- a/include/asm-generic/pgalloc.h
+++ b/include/asm-generic/pgalloc.h
@@ -107,10 +107,7 @@ static inline pgtable_t pte_alloc_one_noprof(struct mm_struct *mm)
*/
static inline void pte_free(struct mm_struct *mm, struct page *pte_page)
{
- struct ptdesc *ptdesc = page_ptdesc(pte_page);
-
- pagetable_dtor(ptdesc);
- pagetable_free(ptdesc);
+ pagetable_dtor_free(pte_page);
}
@@ -150,11 +147,7 @@ static inline pmd_t *pmd_alloc_one_noprof(struct mm_struct *mm, unsigned long ad
#ifndef __HAVE_ARCH_PMD_FREE
static inline void pmd_free(struct mm_struct *mm, pmd_t *pmd)
{
- struct ptdesc *ptdesc = virt_to_ptdesc(pmd);
-
- BUG_ON((unsigned long)pmd & (PAGE_SIZE-1));
- pagetable_dtor(ptdesc);
- pagetable_free(ptdesc);
+ pagetable_dtor_free(virt_to_page(pmd));
}
#endif
@@ -199,11 +192,7 @@ static inline pud_t *pud_alloc_one_noprof(struct mm_struct *mm, unsigned long ad
static inline void __pud_free(struct mm_struct *mm, pud_t *pud)
{
- struct ptdesc *ptdesc = virt_to_ptdesc(pud);
-
- BUG_ON((unsigned long)pud & (PAGE_SIZE-1));
- pagetable_dtor(ptdesc);
- pagetable_free(ptdesc);
+ pagetable_dtor_free(virt_to_page(pud));
}
#ifndef __HAVE_ARCH_PUD_FREE
@@ -254,11 +243,7 @@ static inline p4d_t *p4d_alloc_one_noprof(struct mm_struct *mm, unsigned long ad
static inline void __p4d_free(struct mm_struct *mm, p4d_t *p4d)
{
- struct ptdesc *ptdesc = virt_to_ptdesc(p4d);
-
- BUG_ON((unsigned long)p4d & (PAGE_SIZE-1));
- pagetable_dtor(ptdesc);
- pagetable_free(ptdesc);
+ pagetable_dtor_free(virt_to_page(p4d));
}
#ifndef __HAVE_ARCH_P4D_FREE
diff --git a/include/asm-generic/tlb.h b/include/asm-generic/tlb.h
index 583e95568f52b..ef25169523602 100644
--- a/include/asm-generic/tlb.h
+++ b/include/asm-generic/tlb.h
@@ -211,10 +211,7 @@ struct mmu_table_batch {
#ifndef __HAVE_ARCH_TLB_REMOVE_TABLE
static inline void __tlb_remove_table(void *table)
{
- struct ptdesc *ptdesc = page_ptdesc((struct page *)table);
-
- pagetable_dtor(ptdesc);
- pagetable_free(ptdesc);
+ pagetable_dtor_free(table);
}
#endif
diff --git a/include/linux/mm.h b/include/linux/mm.h
index 736215c428293..f2d04eec66076 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -3095,6 +3095,14 @@ static inline void pagetable_dtor(struct ptdesc *ptdesc)
lruvec_stat_sub_folio(folio, NR_PAGETABLE);
}
+static inline void pagetable_dtor_free(void *table)
+{
+ struct ptdesc *ptdesc = page_ptdesc((struct page *)table);
+
+ pagetable_dtor(ptdesc);
+ pagetable_free(ptdesc);
+}
+
static inline bool pagetable_pte_ctor(struct ptdesc *ptdesc)
{
struct folio *folio = ptdesc_folio(ptdesc);
--
2.20.1
Powered by blists - more mailing lists