* [PATCH 0/5] remove tlb_remove_page_ptdesc()
@ 2025-01-23 13:26 Qi Zheng
2025-01-23 13:26 ` [PATCH 1/5] mm: pgtable: make generic tlb_remove_table() use struct ptdesc Qi Zheng
` (5 more replies)
0 siblings, 6 replies; 12+ messages in thread
From: Qi Zheng @ 2025-01-23 13:26 UTC (permalink / raw)
To: peterz, kevin.brodsky, riel, vishal.moola, david, jannh, hughd,
willy, yuzhao, muchun.song, akpm, will, aneesh.kumar, npiggin,
arnd, dave.hansen, rppt, alexghiti
Cc: linux-mm, linux-kernel, linux-csky, linux-hexagon, loongarch,
linux-m68k, linux-mips, linux-openrisc, linux-sh, linux-um, x86,
linux-riscv, Qi Zheng
Hi all,
As suggested by Peter Zijlstra below [1], this series aims to remove
tlb_remove_page_ptdesc().
: Fundamentally tlb_remove_page() is about removing *pages* as from a PTE,
: there should not be a page-table anywhere near here *ever*.
:
: Yes, some architectures use tlb_remove_page() for page-tables too, but
: that is more or less an implementation detail that can be fixed.
After this series, all architectures use tlb_remove_table() or tlb_remove_ptdesc()
to remove the page table pages. In the future, once all architectures using
tlb_remove_table() have also converted to using struct ptdesc (eg. powerpc), it
may be possible to use only tlb_remove_ptdesc().
Note: there will be some overlap between my patch #4 and Rik van Riel's patch #1 [2],
once his patch is merged into the next branch, I can rebase onto his patch.
And patch #4 can actually make x86 use tlb_remove_ptdesc(), but due to the
above situation, I have not done so yet.
This series is based on next-20250122.
Comments and suggestions are welcome!
Thanks,
Qi
[1]. https://lore.kernel.org/linux-mm/20250103111457.GC22934@noisy.programming.kicks-ass.net/
[2]. https://lore.kernel.org/lkml/20250123042447.2259648-2-riel@surriel.com/
Qi Zheng (5):
mm: pgtable: make generic tlb_remove_table() use struct ptdesc
mm: pgtable: convert some architectures to use tlb_remove_ptdesc()
riscv: pgtable: unconditionally use tlb_remove_ptdesc()
x86: pgtable: unconditionally use tlb_remove_table()
mm: pgtable: remove tlb_remove_page_ptdesc()
arch/csky/include/asm/pgalloc.h | 3 +--
arch/hexagon/include/asm/pgalloc.h | 3 +--
arch/loongarch/include/asm/pgalloc.h | 3 +--
arch/m68k/include/asm/sun3_pgalloc.h | 3 +--
arch/mips/include/asm/pgalloc.h | 3 +--
arch/nios2/include/asm/pgalloc.h | 9 ++++-----
arch/openrisc/include/asm/pgalloc.h | 3 +--
arch/riscv/include/asm/pgalloc.h | 26 ++++----------------------
arch/sh/include/asm/pgalloc.h | 3 +--
arch/um/include/asm/pgalloc.h | 9 +++------
arch/x86/kernel/paravirt.c | 17 +----------------
arch/x86/mm/pgtable.c | 11 -----------
include/asm-generic/tlb.h | 12 +++---------
13 files changed, 22 insertions(+), 83 deletions(-)
--
2.20.1
^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH 1/5] mm: pgtable: make generic tlb_remove_table() use struct ptdesc
2025-01-23 13:26 [PATCH 0/5] remove tlb_remove_page_ptdesc() Qi Zheng
@ 2025-01-23 13:26 ` Qi Zheng
2025-01-23 13:26 ` [PATCH 2/5] mm: pgtable: convert some architectures to use tlb_remove_ptdesc() Qi Zheng
` (4 subsequent siblings)
5 siblings, 0 replies; 12+ messages in thread
From: Qi Zheng @ 2025-01-23 13:26 UTC (permalink / raw)
To: peterz, kevin.brodsky, riel, vishal.moola, david, jannh, hughd,
willy, yuzhao, muchun.song, akpm, will, aneesh.kumar, npiggin,
arnd, dave.hansen, rppt, alexghiti
Cc: linux-mm, linux-kernel, linux-csky, linux-hexagon, loongarch,
linux-m68k, linux-mips, linux-openrisc, linux-sh, linux-um, x86,
linux-riscv, Qi Zheng
Now only arm will call tlb_remove_ptdesc()/tlb_remove_table() when
CONFIG_MMU_GATHER_TABLE_FREE is disabled. In this case, the type of the
table parameter is actually struct ptdesc * instead of struct page *.
Since struct ptdesc still overlaps with struct page and has not been
separated from it, forcing the table parameter to struct page * will not
cause any problems at this time. But this is definitely incorrect and
needs to be fixed. So just like the generic __tlb_remove_table(), let
generic tlb_remove_table() use struct ptdesc by default when
CONFIG_MMU_GATHER_TABLE_FREE is disabled.
Signed-off-by: Qi Zheng <zhengqi.arch@bytedance.com>
---
include/asm-generic/tlb.h | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/include/asm-generic/tlb.h b/include/asm-generic/tlb.h
index e402aef79c93e..10cdbe0e7adfe 100644
--- a/include/asm-generic/tlb.h
+++ b/include/asm-generic/tlb.h
@@ -228,10 +228,10 @@ static inline void tlb_remove_page(struct mmu_gather *tlb, struct page *page);
*/
static inline void tlb_remove_table(struct mmu_gather *tlb, void *table)
{
- struct page *page = (struct page *)table;
+ struct ptdesc *ptdesc = (struct ptdesc *)table;
- pagetable_dtor(page_ptdesc(page));
- tlb_remove_page(tlb, page);
+ pagetable_dtor(ptdesc);
+ tlb_remove_page(tlb, ptdesc_page(ptdesc));
}
#endif /* CONFIG_MMU_GATHER_TABLE_FREE */
--
2.20.1
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH 2/5] mm: pgtable: convert some architectures to use tlb_remove_ptdesc()
2025-01-23 13:26 [PATCH 0/5] remove tlb_remove_page_ptdesc() Qi Zheng
2025-01-23 13:26 ` [PATCH 1/5] mm: pgtable: make generic tlb_remove_table() use struct ptdesc Qi Zheng
@ 2025-01-23 13:26 ` Qi Zheng
2025-01-23 13:26 ` [PATCH 3/5] riscv: pgtable: unconditionally " Qi Zheng
` (3 subsequent siblings)
5 siblings, 0 replies; 12+ messages in thread
From: Qi Zheng @ 2025-01-23 13:26 UTC (permalink / raw)
To: peterz, kevin.brodsky, riel, vishal.moola, david, jannh, hughd,
willy, yuzhao, muchun.song, akpm, will, aneesh.kumar, npiggin,
arnd, dave.hansen, rppt, alexghiti
Cc: linux-mm, linux-kernel, linux-csky, linux-hexagon, loongarch,
linux-m68k, linux-mips, linux-openrisc, linux-sh, linux-um, x86,
linux-riscv, Qi Zheng
Now, the nine architectures of csky, hexagon, loongarch, m68k, mips,
nios2, openrisc, sh and um do not select CONFIG_MMU_GATHER_RCU_TABLE_FREE,
and just call pagetable_dtor() + tlb_remove_page_ptdesc() (the wrapper of
tlb_remove_page()). This is the same as the implementation of
tlb_remove_{ptdesc|table}() under !CONFIG_MMU_GATHER_TABLE_FREE, so
convert these architectures to use tlb_remove_ptdesc().
The ultimate goal is to make the architecture only use tlb_remove_ptdesc()
or tlb_remove_table() for page table pages.
Signed-off-by: Qi Zheng <zhengqi.arch@bytedance.com>
Suggested-by: Peter Zijlstra (Intel) <peterz@infradead.org>
---
arch/csky/include/asm/pgalloc.h | 3 +--
arch/hexagon/include/asm/pgalloc.h | 3 +--
arch/loongarch/include/asm/pgalloc.h | 3 +--
arch/m68k/include/asm/sun3_pgalloc.h | 3 +--
arch/mips/include/asm/pgalloc.h | 3 +--
arch/nios2/include/asm/pgalloc.h | 9 ++++-----
arch/openrisc/include/asm/pgalloc.h | 3 +--
arch/sh/include/asm/pgalloc.h | 3 +--
arch/um/include/asm/pgalloc.h | 9 +++------
9 files changed, 14 insertions(+), 25 deletions(-)
diff --git a/arch/csky/include/asm/pgalloc.h b/arch/csky/include/asm/pgalloc.h
index bf8400c28b5a3..9d2b50265a8d8 100644
--- a/arch/csky/include/asm/pgalloc.h
+++ b/arch/csky/include/asm/pgalloc.h
@@ -63,8 +63,7 @@ static inline pgd_t *pgd_alloc(struct mm_struct *mm)
#define __pte_free_tlb(tlb, pte, address) \
do { \
- pagetable_dtor(page_ptdesc(pte)); \
- tlb_remove_page_ptdesc(tlb, page_ptdesc(pte)); \
+ tlb_remove_ptdesc((tlb), page_ptdesc(pte)); \
} while (0)
extern void pagetable_init(void);
diff --git a/arch/hexagon/include/asm/pgalloc.h b/arch/hexagon/include/asm/pgalloc.h
index 1ee5f5f157ca7..3d35d2bc42534 100644
--- a/arch/hexagon/include/asm/pgalloc.h
+++ b/arch/hexagon/include/asm/pgalloc.h
@@ -89,8 +89,7 @@ static inline void pmd_populate_kernel(struct mm_struct *mm, pmd_t *pmd,
#define __pte_free_tlb(tlb, pte, addr) \
do { \
- pagetable_dtor((page_ptdesc(pte))); \
- tlb_remove_page_ptdesc((tlb), (page_ptdesc(pte))); \
+ tlb_remove_ptdesc((tlb), page_ptdesc(pte)); \
} while (0)
#endif
diff --git a/arch/loongarch/include/asm/pgalloc.h b/arch/loongarch/include/asm/pgalloc.h
index 7211dff8c969e..ac026146e7e95 100644
--- a/arch/loongarch/include/asm/pgalloc.h
+++ b/arch/loongarch/include/asm/pgalloc.h
@@ -57,8 +57,7 @@ static inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm)
#define __pte_free_tlb(tlb, pte, address) \
do { \
- pagetable_dtor(page_ptdesc(pte)); \
- tlb_remove_page_ptdesc((tlb), page_ptdesc(pte)); \
+ tlb_remove_ptdesc((tlb), page_ptdesc(pte)); \
} while (0)
#ifndef __PAGETABLE_PMD_FOLDED
diff --git a/arch/m68k/include/asm/sun3_pgalloc.h b/arch/m68k/include/asm/sun3_pgalloc.h
index f1ae4ed890db5..55a982ffb0457 100644
--- a/arch/m68k/include/asm/sun3_pgalloc.h
+++ b/arch/m68k/include/asm/sun3_pgalloc.h
@@ -19,8 +19,7 @@ extern const char bad_pmd_string[];
#define __pte_free_tlb(tlb, pte, addr) \
do { \
- pagetable_dtor(page_ptdesc(pte)); \
- tlb_remove_page_ptdesc((tlb), page_ptdesc(pte)); \
+ tlb_remove_ptdesc((tlb), page_ptdesc(pte)); \
} while (0)
static inline void pmd_populate_kernel(struct mm_struct *mm, pmd_t *pmd, pte_t *pte)
diff --git a/arch/mips/include/asm/pgalloc.h b/arch/mips/include/asm/pgalloc.h
index 26c7a6ede983c..7e73d2f913dd4 100644
--- a/arch/mips/include/asm/pgalloc.h
+++ b/arch/mips/include/asm/pgalloc.h
@@ -50,8 +50,7 @@ extern pgd_t *pgd_alloc(struct mm_struct *mm);
#define __pte_free_tlb(tlb, pte, address) \
do { \
- pagetable_dtor(page_ptdesc(pte)); \
- tlb_remove_page_ptdesc((tlb), page_ptdesc(pte)); \
+ tlb_remove_ptdesc((tlb), page_ptdesc(pte)); \
} while (0)
#ifndef __PAGETABLE_PMD_FOLDED
diff --git a/arch/nios2/include/asm/pgalloc.h b/arch/nios2/include/asm/pgalloc.h
index 12a536b7bfbd4..4b4a1766e2cc7 100644
--- a/arch/nios2/include/asm/pgalloc.h
+++ b/arch/nios2/include/asm/pgalloc.h
@@ -28,10 +28,9 @@ static inline void pmd_populate(struct mm_struct *mm, pmd_t *pmd,
extern pgd_t *pgd_alloc(struct mm_struct *mm);
-#define __pte_free_tlb(tlb, pte, addr) \
- do { \
- pagetable_dtor(page_ptdesc(pte)); \
- tlb_remove_page_ptdesc((tlb), (page_ptdesc(pte))); \
- } while (0)
+#define __pte_free_tlb(tlb, pte, addr) \
+do { \
+ tlb_remove_ptdesc((tlb), page_ptdesc(pte)); \
+} while (0)
#endif /* _ASM_NIOS2_PGALLOC_H */
diff --git a/arch/openrisc/include/asm/pgalloc.h b/arch/openrisc/include/asm/pgalloc.h
index 3372f4e6ab4b5..2964e26980a18 100644
--- a/arch/openrisc/include/asm/pgalloc.h
+++ b/arch/openrisc/include/asm/pgalloc.h
@@ -66,8 +66,7 @@ extern pte_t *pte_alloc_one_kernel(struct mm_struct *mm);
#define __pte_free_tlb(tlb, pte, addr) \
do { \
- pagetable_dtor(page_ptdesc(pte)); \
- tlb_remove_page_ptdesc((tlb), (page_ptdesc(pte))); \
+ tlb_remove_ptdesc((tlb), page_ptdesc(pte)); \
} while (0)
#endif
diff --git a/arch/sh/include/asm/pgalloc.h b/arch/sh/include/asm/pgalloc.h
index 96d938fdf2244..c376d4b708fda 100644
--- a/arch/sh/include/asm/pgalloc.h
+++ b/arch/sh/include/asm/pgalloc.h
@@ -34,8 +34,7 @@ static inline void pmd_populate(struct mm_struct *mm, pmd_t *pmd,
#define __pte_free_tlb(tlb, pte, addr) \
do { \
- pagetable_dtor(page_ptdesc(pte)); \
- tlb_remove_page_ptdesc((tlb), (page_ptdesc(pte))); \
+ tlb_remove_ptdesc((tlb), page_ptdesc(pte)); \
} while (0)
#endif /* __ASM_SH_PGALLOC_H */
diff --git a/arch/um/include/asm/pgalloc.h b/arch/um/include/asm/pgalloc.h
index f0af23c3aeb2b..a70151cfd11c9 100644
--- a/arch/um/include/asm/pgalloc.h
+++ b/arch/um/include/asm/pgalloc.h
@@ -27,24 +27,21 @@ extern pgd_t *pgd_alloc(struct mm_struct *);
#define __pte_free_tlb(tlb, pte, address) \
do { \
- pagetable_dtor(page_ptdesc(pte)); \
- tlb_remove_page_ptdesc((tlb), (page_ptdesc(pte))); \
+ tlb_remove_ptdesc((tlb), page_ptdesc(pte)); \
} while (0)
#if CONFIG_PGTABLE_LEVELS > 2
#define __pmd_free_tlb(tlb, pmd, address) \
do { \
- pagetable_dtor(virt_to_ptdesc(pmd)); \
- tlb_remove_page_ptdesc((tlb), virt_to_ptdesc(pmd)); \
+ tlb_remove_ptdesc((tlb), virt_to_ptdesc(pmd)); \
} while (0)
#if CONFIG_PGTABLE_LEVELS > 3
#define __pud_free_tlb(tlb, pud, address) \
do { \
- pagetable_dtor(virt_to_ptdesc(pud)); \
- tlb_remove_page_ptdesc((tlb), virt_to_ptdesc(pud)); \
+ tlb_remove_ptdesc((tlb), virt_to_ptdesc(pud)); \
} while (0)
#endif
--
2.20.1
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH 3/5] riscv: pgtable: unconditionally use tlb_remove_ptdesc()
2025-01-23 13:26 [PATCH 0/5] remove tlb_remove_page_ptdesc() Qi Zheng
2025-01-23 13:26 ` [PATCH 1/5] mm: pgtable: make generic tlb_remove_table() use struct ptdesc Qi Zheng
2025-01-23 13:26 ` [PATCH 2/5] mm: pgtable: convert some architectures to use tlb_remove_ptdesc() Qi Zheng
@ 2025-01-23 13:26 ` Qi Zheng
2025-01-23 13:26 ` [PATCH 4/5] x86: pgtable: unconditionally use tlb_remove_table() Qi Zheng
` (2 subsequent siblings)
5 siblings, 0 replies; 12+ messages in thread
From: Qi Zheng @ 2025-01-23 13:26 UTC (permalink / raw)
To: peterz, kevin.brodsky, riel, vishal.moola, david, jannh, hughd,
willy, yuzhao, muchun.song, akpm, will, aneesh.kumar, npiggin,
arnd, dave.hansen, rppt, alexghiti
Cc: linux-mm, linux-kernel, linux-csky, linux-hexagon, loongarch,
linux-m68k, linux-mips, linux-openrisc, linux-sh, linux-um, x86,
linux-riscv, Qi Zheng
To support fast gup, the commit 69be3fb111e7 ("riscv: enable
MMU_GATHER_RCU_TABLE_FREE for SMP && MMU") did the following:
1) use tlb_remove_page_ptdesc() for those platforms which use IPI to
perform TLB shootdown
2) use tlb_remove_ptdesc() for those platforms which use SBI to perform
TLB shootdown
The tlb_remove_page_ptdesc() is the wrapper of the tlb_remove_page(). By
design, the tlb_remove_page() should be used to remove a normal page from
a page table entry, and should not be used for page table pages.
The tlb_remove_ptdesc() is the wrapper of the tlb_remove_table(), which is
designed specifically for freeing page table pages. If the
CONFIG_MMU_GATHER_TABLE_FREE is enabled, the tlb_remove_table() will use
semi RCU to free page table pages, that is:
- batch table freeing: asynchronous free by RCU
- single table freeing: IPI + synchronous free
If the CONFIG_MMU_GATHER_TABLE_FREE is disabled, the tlb_remove_table()
will fall back to pagetable_dtor() + tlb_remove_page().
For case 1), since we need to perform TLB shootdown before freeing the
page table page, the local_irq_save() in fast gup can block the freeing
and protect the fast gup page walker. Therefore we can ensure safety by
just using tlb_remove_page_ptdesc(). In addition, we can also the
tlb_remove_ptdesc()/tlb_remove_table() to achieve it, and it doesn't
matter whether CONFIG_MMU_GATHER_RCU_TABLE_FREE is selected. And in
theory, the performance of freeing pages asynchronously via RCU will not
be lower than synchronous free.
For case 2), since local_irq_save() only disable S-privilege IPI irq but
not M-privilege's, which is used by the SBI implementation to perform TLB
shootdown, so we must select CONFIG_MMU_GATHER_RCU_TABLE_FREE and use
tlb_remove_ptdesc() to ensure safety. The riscv selects this config for
SMP && MMU, the CONFIG_RISCV_SBI is dependent on MMU. Therefore, only the
UP system may have the situation where CONFIG_MMU_GATHER_RCU_TABLE_FREE is
disabled but CONFIG_RISCV_SBI is enabled. But there is no freeing vs fast
gup race in the UP system.
So, in summary, we can use tlb_remove_ptdesc() to support fast gup in all
cases, and this interface is specifically designed for page table pages.
So let's use it unconditionally.
Signed-off-by: Qi Zheng <zhengqi.arch@bytedance.com>
Suggested-by: Peter Zijlstra (Intel) <peterz@infradead.org>
---
arch/riscv/include/asm/pgalloc.h | 26 ++++----------------------
1 file changed, 4 insertions(+), 22 deletions(-)
diff --git a/arch/riscv/include/asm/pgalloc.h b/arch/riscv/include/asm/pgalloc.h
index 3e2aebea6312d..770ce18a7328b 100644
--- a/arch/riscv/include/asm/pgalloc.h
+++ b/arch/riscv/include/asm/pgalloc.h
@@ -15,24 +15,6 @@
#define __HAVE_ARCH_PUD_FREE
#include <asm-generic/pgalloc.h>
-/*
- * While riscv platforms with riscv_ipi_for_rfence as true require an IPI to
- * perform TLB shootdown, some platforms with riscv_ipi_for_rfence as false use
- * SBI to perform TLB shootdown. To keep software pagetable walkers safe in this
- * case we switch to RCU based table free (MMU_GATHER_RCU_TABLE_FREE). See the
- * comment below 'ifdef CONFIG_MMU_GATHER_RCU_TABLE_FREE' in include/asm-generic/tlb.h
- * for more details.
- */
-static inline void riscv_tlb_remove_ptdesc(struct mmu_gather *tlb, void *pt)
-{
- if (riscv_use_sbi_for_rfence()) {
- tlb_remove_ptdesc(tlb, pt);
- } else {
- pagetable_dtor(pt);
- tlb_remove_page_ptdesc(tlb, pt);
- }
-}
-
static inline void pmd_populate_kernel(struct mm_struct *mm,
pmd_t *pmd, pte_t *pte)
{
@@ -108,14 +90,14 @@ static inline void __pud_free_tlb(struct mmu_gather *tlb, pud_t *pud,
unsigned long addr)
{
if (pgtable_l4_enabled)
- riscv_tlb_remove_ptdesc(tlb, virt_to_ptdesc(pud));
+ tlb_remove_ptdesc(tlb, virt_to_ptdesc(pud));
}
static inline void __p4d_free_tlb(struct mmu_gather *tlb, p4d_t *p4d,
unsigned long addr)
{
if (pgtable_l5_enabled)
- riscv_tlb_remove_ptdesc(tlb, virt_to_ptdesc(p4d));
+ tlb_remove_ptdesc(tlb, virt_to_ptdesc(p4d));
}
#endif /* __PAGETABLE_PMD_FOLDED */
@@ -143,7 +125,7 @@ static inline pgd_t *pgd_alloc(struct mm_struct *mm)
static inline void __pmd_free_tlb(struct mmu_gather *tlb, pmd_t *pmd,
unsigned long addr)
{
- riscv_tlb_remove_ptdesc(tlb, virt_to_ptdesc(pmd));
+ tlb_remove_ptdesc(tlb, virt_to_ptdesc(pmd));
}
#endif /* __PAGETABLE_PMD_FOLDED */
@@ -151,7 +133,7 @@ static inline void __pmd_free_tlb(struct mmu_gather *tlb, pmd_t *pmd,
static inline void __pte_free_tlb(struct mmu_gather *tlb, pgtable_t pte,
unsigned long addr)
{
- riscv_tlb_remove_ptdesc(tlb, page_ptdesc(pte));
+ tlb_remove_ptdesc(tlb, page_ptdesc(pte));
}
#endif /* CONFIG_MMU */
--
2.20.1
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH 4/5] x86: pgtable: unconditionally use tlb_remove_table()
2025-01-23 13:26 [PATCH 0/5] remove tlb_remove_page_ptdesc() Qi Zheng
` (2 preceding siblings ...)
2025-01-23 13:26 ` [PATCH 3/5] riscv: pgtable: unconditionally " Qi Zheng
@ 2025-01-23 13:26 ` Qi Zheng
2025-01-24 11:38 ` Peter Zijlstra
2025-01-23 13:26 ` [PATCH 5/5] mm: pgtable: remove tlb_remove_page_ptdesc() Qi Zheng
2025-01-24 11:47 ` [PATCH 0/5] " Peter Zijlstra
5 siblings, 1 reply; 12+ messages in thread
From: Qi Zheng @ 2025-01-23 13:26 UTC (permalink / raw)
To: peterz, kevin.brodsky, riel, vishal.moola, david, jannh, hughd,
willy, yuzhao, muchun.song, akpm, will, aneesh.kumar, npiggin,
arnd, dave.hansen, rppt, alexghiti
Cc: linux-mm, linux-kernel, linux-csky, linux-hexagon, loongarch,
linux-m68k, linux-mips, linux-openrisc, linux-sh, linux-um, x86,
linux-riscv, Qi Zheng
If the CONFIG_MMU_GATHER_TABLE_FREE is disabled, the tlb_remove_table()
will fall back to pagetable_dtor() + tlb_remove_page(). So let's use
tlb_remove_table() unconditionally to free page table pages.
Signed-off-by: Qi Zheng <zhengqi.arch@bytedance.com>
Suggested-by: Peter Zijlstra (Intel) <peterz@infradead.org>
---
arch/x86/kernel/paravirt.c | 17 +----------------
arch/x86/mm/pgtable.c | 11 -----------
2 files changed, 1 insertion(+), 27 deletions(-)
diff --git a/arch/x86/kernel/paravirt.c b/arch/x86/kernel/paravirt.c
index 1ccaa3397a670..527f5605aa3e5 100644
--- a/arch/x86/kernel/paravirt.c
+++ b/arch/x86/kernel/paravirt.c
@@ -59,21 +59,6 @@ void __init native_pv_lock_init(void)
static_branch_enable(&virt_spin_lock_key);
}
-#ifndef CONFIG_PT_RECLAIM
-static void native_tlb_remove_table(struct mmu_gather *tlb, void *table)
-{
- struct ptdesc *ptdesc = (struct ptdesc *)table;
-
- pagetable_dtor(ptdesc);
- tlb_remove_page(tlb, ptdesc_page(ptdesc));
-}
-#else
-static void native_tlb_remove_table(struct mmu_gather *tlb, void *table)
-{
- tlb_remove_table(tlb, table);
-}
-#endif
-
struct static_key paravirt_steal_enabled;
struct static_key paravirt_steal_rq_enabled;
@@ -195,7 +180,7 @@ struct paravirt_patch_template pv_ops = {
.mmu.flush_tlb_kernel = native_flush_tlb_global,
.mmu.flush_tlb_one_user = native_flush_tlb_one_user,
.mmu.flush_tlb_multi = native_flush_tlb_multi,
- .mmu.tlb_remove_table = native_tlb_remove_table,
+ .mmu.tlb_remove_table = tlb_remove_table,
.mmu.exit_mmap = paravirt_nop,
.mmu.notify_page_enc_status_changed = paravirt_nop,
diff --git a/arch/x86/mm/pgtable.c b/arch/x86/mm/pgtable.c
index 1fef5ad32d5a8..3bc8ad282b272 100644
--- a/arch/x86/mm/pgtable.c
+++ b/arch/x86/mm/pgtable.c
@@ -19,22 +19,11 @@ EXPORT_SYMBOL(physical_mask);
#endif
#ifndef CONFIG_PARAVIRT
-#ifndef CONFIG_PT_RECLAIM
-static inline
-void paravirt_tlb_remove_table(struct mmu_gather *tlb, void *table)
-{
- struct ptdesc *ptdesc = (struct ptdesc *)table;
-
- pagetable_dtor(ptdesc);
- tlb_remove_page(tlb, ptdesc_page(ptdesc));
-}
-#else
static inline
void paravirt_tlb_remove_table(struct mmu_gather *tlb, void *table)
{
tlb_remove_table(tlb, table);
}
-#endif /* !CONFIG_PT_RECLAIM */
#endif /* !CONFIG_PARAVIRT */
gfp_t __userpte_alloc_gfp = GFP_PGTABLE_USER | PGTABLE_HIGHMEM;
--
2.20.1
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH 5/5] mm: pgtable: remove tlb_remove_page_ptdesc()
2025-01-23 13:26 [PATCH 0/5] remove tlb_remove_page_ptdesc() Qi Zheng
` (3 preceding siblings ...)
2025-01-23 13:26 ` [PATCH 4/5] x86: pgtable: unconditionally use tlb_remove_table() Qi Zheng
@ 2025-01-23 13:26 ` Qi Zheng
2025-01-24 11:47 ` [PATCH 0/5] " Peter Zijlstra
5 siblings, 0 replies; 12+ messages in thread
From: Qi Zheng @ 2025-01-23 13:26 UTC (permalink / raw)
To: peterz, kevin.brodsky, riel, vishal.moola, david, jannh, hughd,
willy, yuzhao, muchun.song, akpm, will, aneesh.kumar, npiggin,
arnd, dave.hansen, rppt, alexghiti
Cc: linux-mm, linux-kernel, linux-csky, linux-hexagon, loongarch,
linux-m68k, linux-mips, linux-openrisc, linux-sh, linux-um, x86,
linux-riscv, Qi Zheng
The tlb_remove_ptdesc()/tlb_remove_table() is specially designed for page
table pages, and now all architectures have been converted to use it to
remove page table pages. So let's remove tlb_remove_page_ptdesc(), it
currently has no users and should not be used for page table pages.
Signed-off-by: Qi Zheng <zhengqi.arch@bytedance.com>
Suggested-by: Peter Zijlstra (Intel) <peterz@infradead.org>
---
include/asm-generic/tlb.h | 6 ------
1 file changed, 6 deletions(-)
diff --git a/include/asm-generic/tlb.h b/include/asm-generic/tlb.h
index 10cdbe0e7adfe..dec030cb12108 100644
--- a/include/asm-generic/tlb.h
+++ b/include/asm-generic/tlb.h
@@ -509,12 +509,6 @@ static inline void tlb_remove_ptdesc(struct mmu_gather *tlb, void *pt)
tlb_remove_table(tlb, pt);
}
-/* Like tlb_remove_ptdesc, but for page-like page directories. */
-static inline void tlb_remove_page_ptdesc(struct mmu_gather *tlb, struct ptdesc *pt)
-{
- tlb_remove_page(tlb, ptdesc_page(pt));
-}
-
static inline void tlb_change_page_size(struct mmu_gather *tlb,
unsigned int page_size)
{
--
2.20.1
^ permalink raw reply related [flat|nested] 12+ messages in thread
* Re: [PATCH 4/5] x86: pgtable: unconditionally use tlb_remove_table()
2025-01-23 13:26 ` [PATCH 4/5] x86: pgtable: unconditionally use tlb_remove_table() Qi Zheng
@ 2025-01-24 11:38 ` Peter Zijlstra
2025-01-24 13:00 ` Qi Zheng
0 siblings, 1 reply; 12+ messages in thread
From: Peter Zijlstra @ 2025-01-24 11:38 UTC (permalink / raw)
To: Qi Zheng
Cc: kevin.brodsky, riel, vishal.moola, david, jannh, hughd, willy,
yuzhao, muchun.song, akpm, will, aneesh.kumar, npiggin, arnd,
dave.hansen, rppt, alexghiti, linux-mm, linux-kernel, linux-csky,
linux-hexagon, loongarch, linux-m68k, linux-mips, linux-openrisc,
linux-sh, linux-um, x86, linux-riscv
On Thu, Jan 23, 2025 at 09:26:17PM +0800, Qi Zheng wrote:
> If the CONFIG_MMU_GATHER_TABLE_FREE is disabled, the tlb_remove_table()
> will fall back to pagetable_dtor() + tlb_remove_page(). So let's use
> tlb_remove_table() unconditionally to free page table pages.
>
> Signed-off-by: Qi Zheng <zhengqi.arch@bytedance.com>
> Suggested-by: Peter Zijlstra (Intel) <peterz@infradead.org>
I think we can clean up more :-)
diff --git a/arch/x86/hyperv/mmu.c b/arch/x86/hyperv/mmu.c
index cc8c3bd0e7c2..1f7c3082a36d 100644
--- a/arch/x86/hyperv/mmu.c
+++ b/arch/x86/hyperv/mmu.c
@@ -239,5 +239,4 @@ void hyperv_setup_mmu_ops(void)
pr_info("Using hypercall for remote TLB flush\n");
pv_ops.mmu.flush_tlb_multi = hyperv_flush_tlb_multi;
- pv_ops.mmu.tlb_remove_table = tlb_remove_table;
}
diff --git a/arch/x86/include/asm/paravirt.h b/arch/x86/include/asm/paravirt.h
index 041aff51eb50..38a632a282d4 100644
--- a/arch/x86/include/asm/paravirt.h
+++ b/arch/x86/include/asm/paravirt.h
@@ -91,11 +91,6 @@ static inline void __flush_tlb_multi(const struct cpumask *cpumask,
PVOP_VCALL2(mmu.flush_tlb_multi, cpumask, info);
}
-static inline void paravirt_tlb_remove_table(struct mmu_gather *tlb, void *table)
-{
- PVOP_VCALL2(mmu.tlb_remove_table, tlb, table);
-}
-
static inline void paravirt_arch_exit_mmap(struct mm_struct *mm)
{
PVOP_VCALL1(mmu.exit_mmap, mm);
diff --git a/arch/x86/include/asm/paravirt_types.h b/arch/x86/include/asm/paravirt_types.h
index fea56b04f436..e26633c00455 100644
--- a/arch/x86/include/asm/paravirt_types.h
+++ b/arch/x86/include/asm/paravirt_types.h
@@ -134,8 +134,6 @@ struct pv_mmu_ops {
void (*flush_tlb_multi)(const struct cpumask *cpus,
const struct flush_tlb_info *info);
- void (*tlb_remove_table)(struct mmu_gather *tlb, void *table);
-
/* Hook for intercepting the destruction of an mm_struct. */
void (*exit_mmap)(struct mm_struct *mm);
void (*notify_page_enc_status_changed)(unsigned long pfn, int npages, bool enc);
diff --git a/arch/x86/kernel/kvm.c b/arch/x86/kernel/kvm.c
index 7a422a6c5983..3be9b3342c67 100644
--- a/arch/x86/kernel/kvm.c
+++ b/arch/x86/kernel/kvm.c
@@ -838,7 +838,6 @@ static void __init kvm_guest_init(void)
#ifdef CONFIG_SMP
if (pv_tlb_flush_supported()) {
pv_ops.mmu.flush_tlb_multi = kvm_flush_tlb_multi;
- pv_ops.mmu.tlb_remove_table = tlb_remove_table;
pr_info("KVM setup pv remote TLB flush\n");
}
diff --git a/arch/x86/kernel/paravirt.c b/arch/x86/kernel/paravirt.c
index 527f5605aa3e..2aa251d0b308 100644
--- a/arch/x86/kernel/paravirt.c
+++ b/arch/x86/kernel/paravirt.c
@@ -180,7 +180,6 @@ struct paravirt_patch_template pv_ops = {
.mmu.flush_tlb_kernel = native_flush_tlb_global,
.mmu.flush_tlb_one_user = native_flush_tlb_one_user,
.mmu.flush_tlb_multi = native_flush_tlb_multi,
- .mmu.tlb_remove_table = tlb_remove_table,
.mmu.exit_mmap = paravirt_nop,
.mmu.notify_page_enc_status_changed = paravirt_nop,
diff --git a/arch/x86/mm/pgtable.c b/arch/x86/mm/pgtable.c
index 3bc8ad282b27..b1c1f72c1fd1 100644
--- a/arch/x86/mm/pgtable.c
+++ b/arch/x86/mm/pgtable.c
@@ -18,14 +18,6 @@ EXPORT_SYMBOL(physical_mask);
#define PGTABLE_HIGHMEM 0
#endif
-#ifndef CONFIG_PARAVIRT
-static inline
-void paravirt_tlb_remove_table(struct mmu_gather *tlb, void *table)
-{
- tlb_remove_table(tlb, table);
-}
-#endif /* !CONFIG_PARAVIRT */
-
gfp_t __userpte_alloc_gfp = GFP_PGTABLE_USER | PGTABLE_HIGHMEM;
pgtable_t pte_alloc_one(struct mm_struct *mm)
@@ -53,7 +45,7 @@ early_param("userpte", setup_userpte);
void ___pte_free_tlb(struct mmu_gather *tlb, struct page *pte)
{
paravirt_release_pte(page_to_pfn(pte));
- paravirt_tlb_remove_table(tlb, page_ptdesc(pte));
+ tlb_remove_table(tlb, page_ptdesc(pte));
}
#if CONFIG_PGTABLE_LEVELS > 2
@@ -67,21 +59,21 @@ void ___pmd_free_tlb(struct mmu_gather *tlb, pmd_t *pmd)
#ifdef CONFIG_X86_PAE
tlb->need_flush_all = 1;
#endif
- paravirt_tlb_remove_table(tlb, virt_to_ptdesc(pmd));
+ tlb_remove_table(tlb, virt_to_ptdesc(pmd));
}
#if CONFIG_PGTABLE_LEVELS > 3
void ___pud_free_tlb(struct mmu_gather *tlb, pud_t *pud)
{
paravirt_release_pud(__pa(pud) >> PAGE_SHIFT);
- paravirt_tlb_remove_table(tlb, virt_to_ptdesc(pud));
+ tlb_remove_table(tlb, virt_to_ptdesc(pud));
}
#if CONFIG_PGTABLE_LEVELS > 4
void ___p4d_free_tlb(struct mmu_gather *tlb, p4d_t *p4d)
{
paravirt_release_p4d(__pa(p4d) >> PAGE_SHIFT);
- paravirt_tlb_remove_table(tlb, virt_to_ptdesc(p4d));
+ tlb_remove_table(tlb, virt_to_ptdesc(p4d));
}
#endif /* CONFIG_PGTABLE_LEVELS > 4 */
#endif /* CONFIG_PGTABLE_LEVELS > 3 */
diff --git a/arch/x86/xen/mmu_pv.c b/arch/x86/xen/mmu_pv.c
index 2c70cd35e72c..a0b371557125 100644
--- a/arch/x86/xen/mmu_pv.c
+++ b/arch/x86/xen/mmu_pv.c
@@ -2141,7 +2141,6 @@ static const typeof(pv_ops) xen_mmu_ops __initconst = {
.flush_tlb_kernel = xen_flush_tlb,
.flush_tlb_one_user = xen_flush_tlb_one_user,
.flush_tlb_multi = xen_flush_tlb_multi,
- .tlb_remove_table = tlb_remove_table,
.pgd_alloc = xen_pgd_alloc,
.pgd_free = xen_pgd_free,
^ permalink raw reply related [flat|nested] 12+ messages in thread
* Re: [PATCH 0/5] remove tlb_remove_page_ptdesc()
2025-01-23 13:26 [PATCH 0/5] remove tlb_remove_page_ptdesc() Qi Zheng
` (4 preceding siblings ...)
2025-01-23 13:26 ` [PATCH 5/5] mm: pgtable: remove tlb_remove_page_ptdesc() Qi Zheng
@ 2025-01-24 11:47 ` Peter Zijlstra
2025-01-24 13:04 ` Qi Zheng
2025-02-08 7:22 ` Matthew Wilcox
5 siblings, 2 replies; 12+ messages in thread
From: Peter Zijlstra @ 2025-01-24 11:47 UTC (permalink / raw)
To: Qi Zheng
Cc: kevin.brodsky, riel, vishal.moola, david, jannh, hughd, willy,
yuzhao, muchun.song, akpm, will, aneesh.kumar, npiggin, arnd,
dave.hansen, rppt, alexghiti, linux-mm, linux-kernel, linux-csky,
linux-hexagon, loongarch, linux-m68k, linux-mips, linux-openrisc,
linux-sh, linux-um, x86, linux-riscv
On Thu, Jan 23, 2025 at 09:26:13PM +0800, Qi Zheng wrote:
> Hi all,
>
> As suggested by Peter Zijlstra below [1], this series aims to remove
> tlb_remove_page_ptdesc().
>
> : Fundamentally tlb_remove_page() is about removing *pages* as from a PTE,
> : there should not be a page-table anywhere near here *ever*.
> :
> : Yes, some architectures use tlb_remove_page() for page-tables too, but
> : that is more or less an implementation detail that can be fixed.
>
> After this series, all architectures use tlb_remove_table() or tlb_remove_ptdesc()
> to remove the page table pages. In the future, once all architectures using
> tlb_remove_table() have also converted to using struct ptdesc (eg. powerpc), it
> may be possible to use only tlb_remove_ptdesc().
Right, so I don't think Sparc and Power care to use ptdesc, they're
using non page page-tables.
At the very least we should do something like this, the only point of
having tlb_remove_ptdesc() is type safety, there really is no benefit
from it in any other way.
---
diff --git a/include/asm-generic/tlb.h b/include/asm-generic/tlb.h
index dec030cb1210..a6731328db6f 100644
--- a/include/asm-generic/tlb.h
+++ b/include/asm-generic/tlb.h
@@ -504,7 +504,7 @@ static inline void tlb_remove_page(struct mmu_gather *tlb, struct page *page)
return tlb_remove_page_size(tlb, page, PAGE_SIZE);
}
-static inline void tlb_remove_ptdesc(struct mmu_gather *tlb, void *pt)
+static inline void tlb_remove_ptdesc(struct mmu_gather *tlb, struct ptdesc *pt)
{
tlb_remove_table(tlb, pt);
}
^ permalink raw reply related [flat|nested] 12+ messages in thread
* Re: [PATCH 4/5] x86: pgtable: unconditionally use tlb_remove_table()
2025-01-24 11:38 ` Peter Zijlstra
@ 2025-01-24 13:00 ` Qi Zheng
2025-01-27 16:02 ` Peter Zijlstra
0 siblings, 1 reply; 12+ messages in thread
From: Qi Zheng @ 2025-01-24 13:00 UTC (permalink / raw)
To: Peter Zijlstra
Cc: kevin.brodsky, riel, vishal.moola, david, jannh, hughd, willy,
yuzhao, muchun.song, akpm, will, aneesh.kumar, npiggin, arnd,
dave.hansen, rppt, alexghiti, linux-mm, linux-kernel, linux-csky,
linux-hexagon, loongarch, linux-m68k, linux-mips, linux-openrisc,
linux-sh, linux-um, x86, linux-riscv
On 2025/1/24 19:38, Peter Zijlstra wrote:
> On Thu, Jan 23, 2025 at 09:26:17PM +0800, Qi Zheng wrote:
>> If the CONFIG_MMU_GATHER_TABLE_FREE is disabled, the tlb_remove_table()
>> will fall back to pagetable_dtor() + tlb_remove_page(). So let's use
>> tlb_remove_table() unconditionally to free page table pages.
>>
>> Signed-off-by: Qi Zheng <zhengqi.arch@bytedance.com>
>> Suggested-by: Peter Zijlstra (Intel) <peterz@infradead.org>
>
> I think we can clean up more :-)
Yes, but Rik van Riel has already done the same thing in his patch
series [1], so I was originally planning to wait for his patch to be
merged into the linux-next branch, and then rebase this series onto his
patch.
[1]. https://lore.kernel.org/lkml/20250120024104.1924753-1-riel@surriel.com/
Thanks!
>
>
> diff --git a/arch/x86/hyperv/mmu.c b/arch/x86/hyperv/mmu.c
> index cc8c3bd0e7c2..1f7c3082a36d 100644
> --- a/arch/x86/hyperv/mmu.c
> +++ b/arch/x86/hyperv/mmu.c
> @@ -239,5 +239,4 @@ void hyperv_setup_mmu_ops(void)
>
> pr_info("Using hypercall for remote TLB flush\n");
> pv_ops.mmu.flush_tlb_multi = hyperv_flush_tlb_multi;
> - pv_ops.mmu.tlb_remove_table = tlb_remove_table;
> }
> diff --git a/arch/x86/include/asm/paravirt.h b/arch/x86/include/asm/paravirt.h
> index 041aff51eb50..38a632a282d4 100644
> --- a/arch/x86/include/asm/paravirt.h
> +++ b/arch/x86/include/asm/paravirt.h
> @@ -91,11 +91,6 @@ static inline void __flush_tlb_multi(const struct cpumask *cpumask,
> PVOP_VCALL2(mmu.flush_tlb_multi, cpumask, info);
> }
>
> -static inline void paravirt_tlb_remove_table(struct mmu_gather *tlb, void *table)
> -{
> - PVOP_VCALL2(mmu.tlb_remove_table, tlb, table);
> -}
> -
> static inline void paravirt_arch_exit_mmap(struct mm_struct *mm)
> {
> PVOP_VCALL1(mmu.exit_mmap, mm);
> diff --git a/arch/x86/include/asm/paravirt_types.h b/arch/x86/include/asm/paravirt_types.h
> index fea56b04f436..e26633c00455 100644
> --- a/arch/x86/include/asm/paravirt_types.h
> +++ b/arch/x86/include/asm/paravirt_types.h
> @@ -134,8 +134,6 @@ struct pv_mmu_ops {
> void (*flush_tlb_multi)(const struct cpumask *cpus,
> const struct flush_tlb_info *info);
>
> - void (*tlb_remove_table)(struct mmu_gather *tlb, void *table);
> -
> /* Hook for intercepting the destruction of an mm_struct. */
> void (*exit_mmap)(struct mm_struct *mm);
> void (*notify_page_enc_status_changed)(unsigned long pfn, int npages, bool enc);
> diff --git a/arch/x86/kernel/kvm.c b/arch/x86/kernel/kvm.c
> index 7a422a6c5983..3be9b3342c67 100644
> --- a/arch/x86/kernel/kvm.c
> +++ b/arch/x86/kernel/kvm.c
> @@ -838,7 +838,6 @@ static void __init kvm_guest_init(void)
> #ifdef CONFIG_SMP
> if (pv_tlb_flush_supported()) {
> pv_ops.mmu.flush_tlb_multi = kvm_flush_tlb_multi;
> - pv_ops.mmu.tlb_remove_table = tlb_remove_table;
> pr_info("KVM setup pv remote TLB flush\n");
> }
>
> diff --git a/arch/x86/kernel/paravirt.c b/arch/x86/kernel/paravirt.c
> index 527f5605aa3e..2aa251d0b308 100644
> --- a/arch/x86/kernel/paravirt.c
> +++ b/arch/x86/kernel/paravirt.c
> @@ -180,7 +180,6 @@ struct paravirt_patch_template pv_ops = {
> .mmu.flush_tlb_kernel = native_flush_tlb_global,
> .mmu.flush_tlb_one_user = native_flush_tlb_one_user,
> .mmu.flush_tlb_multi = native_flush_tlb_multi,
> - .mmu.tlb_remove_table = tlb_remove_table,
>
> .mmu.exit_mmap = paravirt_nop,
> .mmu.notify_page_enc_status_changed = paravirt_nop,
> diff --git a/arch/x86/mm/pgtable.c b/arch/x86/mm/pgtable.c
> index 3bc8ad282b27..b1c1f72c1fd1 100644
> --- a/arch/x86/mm/pgtable.c
> +++ b/arch/x86/mm/pgtable.c
> @@ -18,14 +18,6 @@ EXPORT_SYMBOL(physical_mask);
> #define PGTABLE_HIGHMEM 0
> #endif
>
> -#ifndef CONFIG_PARAVIRT
> -static inline
> -void paravirt_tlb_remove_table(struct mmu_gather *tlb, void *table)
> -{
> - tlb_remove_table(tlb, table);
> -}
> -#endif /* !CONFIG_PARAVIRT */
> -
> gfp_t __userpte_alloc_gfp = GFP_PGTABLE_USER | PGTABLE_HIGHMEM;
>
> pgtable_t pte_alloc_one(struct mm_struct *mm)
> @@ -53,7 +45,7 @@ early_param("userpte", setup_userpte);
> void ___pte_free_tlb(struct mmu_gather *tlb, struct page *pte)
> {
> paravirt_release_pte(page_to_pfn(pte));
> - paravirt_tlb_remove_table(tlb, page_ptdesc(pte));
> + tlb_remove_table(tlb, page_ptdesc(pte));
> }
>
> #if CONFIG_PGTABLE_LEVELS > 2
> @@ -67,21 +59,21 @@ void ___pmd_free_tlb(struct mmu_gather *tlb, pmd_t *pmd)
> #ifdef CONFIG_X86_PAE
> tlb->need_flush_all = 1;
> #endif
> - paravirt_tlb_remove_table(tlb, virt_to_ptdesc(pmd));
> + tlb_remove_table(tlb, virt_to_ptdesc(pmd));
> }
>
> #if CONFIG_PGTABLE_LEVELS > 3
> void ___pud_free_tlb(struct mmu_gather *tlb, pud_t *pud)
> {
> paravirt_release_pud(__pa(pud) >> PAGE_SHIFT);
> - paravirt_tlb_remove_table(tlb, virt_to_ptdesc(pud));
> + tlb_remove_table(tlb, virt_to_ptdesc(pud));
> }
>
> #if CONFIG_PGTABLE_LEVELS > 4
> void ___p4d_free_tlb(struct mmu_gather *tlb, p4d_t *p4d)
> {
> paravirt_release_p4d(__pa(p4d) >> PAGE_SHIFT);
> - paravirt_tlb_remove_table(tlb, virt_to_ptdesc(p4d));
> + tlb_remove_table(tlb, virt_to_ptdesc(p4d));
> }
> #endif /* CONFIG_PGTABLE_LEVELS > 4 */
> #endif /* CONFIG_PGTABLE_LEVELS > 3 */
> diff --git a/arch/x86/xen/mmu_pv.c b/arch/x86/xen/mmu_pv.c
> index 2c70cd35e72c..a0b371557125 100644
> --- a/arch/x86/xen/mmu_pv.c
> +++ b/arch/x86/xen/mmu_pv.c
> @@ -2141,7 +2141,6 @@ static const typeof(pv_ops) xen_mmu_ops __initconst = {
> .flush_tlb_kernel = xen_flush_tlb,
> .flush_tlb_one_user = xen_flush_tlb_one_user,
> .flush_tlb_multi = xen_flush_tlb_multi,
> - .tlb_remove_table = tlb_remove_table,
>
> .pgd_alloc = xen_pgd_alloc,
> .pgd_free = xen_pgd_free,
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH 0/5] remove tlb_remove_page_ptdesc()
2025-01-24 11:47 ` [PATCH 0/5] " Peter Zijlstra
@ 2025-01-24 13:04 ` Qi Zheng
2025-02-08 7:22 ` Matthew Wilcox
1 sibling, 0 replies; 12+ messages in thread
From: Qi Zheng @ 2025-01-24 13:04 UTC (permalink / raw)
To: Peter Zijlstra
Cc: kevin.brodsky, riel, vishal.moola, david, jannh, hughd, willy,
yuzhao, muchun.song, akpm, will, aneesh.kumar, npiggin, arnd,
dave.hansen, rppt, alexghiti, linux-mm, linux-kernel, linux-csky,
linux-hexagon, loongarch, linux-m68k, linux-mips, linux-openrisc,
linux-sh, linux-um, x86, linux-riscv
On 2025/1/24 19:47, Peter Zijlstra wrote:
> On Thu, Jan 23, 2025 at 09:26:13PM +0800, Qi Zheng wrote:
>> Hi all,
>>
>> As suggested by Peter Zijlstra below [1], this series aims to remove
>> tlb_remove_page_ptdesc().
>>
>> : Fundamentally tlb_remove_page() is about removing *pages* as from a PTE,
>> : there should not be a page-table anywhere near here *ever*.
>> :
>> : Yes, some architectures use tlb_remove_page() for page-tables too, but
>> : that is more or less an implementation detail that can be fixed.
>>
>> After this series, all architectures use tlb_remove_table() or tlb_remove_ptdesc()
>> to remove the page table pages. In the future, once all architectures using
>> tlb_remove_table() have also converted to using struct ptdesc (eg. powerpc), it
>> may be possible to use only tlb_remove_ptdesc().
>
> Right, so I don't think Sparc and Power care to use ptdesc, they're
> using non page page-tables.
>
> At the very least we should do something like this, the only point of
> having tlb_remove_ptdesc() is type safety, there really is no benefit
> from it in any other way.
>
> ---
> diff --git a/include/asm-generic/tlb.h b/include/asm-generic/tlb.h
> index dec030cb1210..a6731328db6f 100644
> --- a/include/asm-generic/tlb.h
> +++ b/include/asm-generic/tlb.h
> @@ -504,7 +504,7 @@ static inline void tlb_remove_page(struct mmu_gather *tlb, struct page *page)
> return tlb_remove_page_size(tlb, page, PAGE_SIZE);
> }
>
> -static inline void tlb_remove_ptdesc(struct mmu_gather *tlb, void *pt)
> +static inline void tlb_remove_ptdesc(struct mmu_gather *tlb, struct ptdesc *pt)
> {
> tlb_remove_table(tlb, pt);
> }
Ah, make sense. I think this can be added to the patch #1.
Thanks!
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH 4/5] x86: pgtable: unconditionally use tlb_remove_table()
2025-01-24 13:00 ` Qi Zheng
@ 2025-01-27 16:02 ` Peter Zijlstra
0 siblings, 0 replies; 12+ messages in thread
From: Peter Zijlstra @ 2025-01-27 16:02 UTC (permalink / raw)
To: Qi Zheng
Cc: kevin.brodsky, riel, vishal.moola, david, jannh, hughd, willy,
yuzhao, muchun.song, akpm, will, aneesh.kumar, npiggin, arnd,
dave.hansen, rppt, alexghiti, linux-mm, linux-kernel, linux-csky,
linux-hexagon, loongarch, linux-m68k, linux-mips, linux-openrisc,
linux-sh, linux-um, x86, linux-riscv
On Fri, Jan 24, 2025 at 09:00:58PM +0800, Qi Zheng wrote:
>
>
> On 2025/1/24 19:38, Peter Zijlstra wrote:
> > On Thu, Jan 23, 2025 at 09:26:17PM +0800, Qi Zheng wrote:
> > > If the CONFIG_MMU_GATHER_TABLE_FREE is disabled, the tlb_remove_table()
> > > will fall back to pagetable_dtor() + tlb_remove_page(). So let's use
> > > tlb_remove_table() unconditionally to free page table pages.
> > >
> > > Signed-off-by: Qi Zheng <zhengqi.arch@bytedance.com>
> > > Suggested-by: Peter Zijlstra (Intel) <peterz@infradead.org>
> >
> > I think we can clean up more :-)
>
> Yes, but Rik van Riel has already done the same thing in his patch series
> [1], so I was originally planning to wait for his patch to be
> merged into the linux-next branch, and then rebase this series onto his
> patch.
Duh, yeah, I've actually seen those patches and totally forgot he did
that... -ETOOMUCHEMAIL :/
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH 0/5] remove tlb_remove_page_ptdesc()
2025-01-24 11:47 ` [PATCH 0/5] " Peter Zijlstra
2025-01-24 13:04 ` Qi Zheng
@ 2025-02-08 7:22 ` Matthew Wilcox
1 sibling, 0 replies; 12+ messages in thread
From: Matthew Wilcox @ 2025-02-08 7:22 UTC (permalink / raw)
To: Peter Zijlstra
Cc: Qi Zheng, kevin.brodsky, riel, vishal.moola, david, jannh, hughd,
yuzhao, muchun.song, akpm, will, aneesh.kumar, npiggin, arnd,
dave.hansen, rppt, alexghiti, linux-mm, linux-kernel, linux-csky,
linux-hexagon, loongarch, linux-m68k, linux-mips, linux-openrisc,
linux-sh, linux-um, x86, linux-riscv
On Fri, Jan 24, 2025 at 12:47:59PM +0100, Peter Zijlstra wrote:
> Right, so I don't think Sparc and Power care to use ptdesc, they're
> using non page page-tables.
i think you mean s390, not sparc. all architectures _use_ ptdescs,
it's just that s390 and ppc use fractional ptdescs rather than an
entire ptdesc for an individual page table.
eventually we can change that, but we're looking out perhaps five years
before we can allocate a ptdesc for a sub-PAGE_SIZE quantity.
^ permalink raw reply [flat|nested] 12+ messages in thread
end of thread, other threads:[~2025-02-08 7:23 UTC | newest]
Thread overview: 12+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-01-23 13:26 [PATCH 0/5] remove tlb_remove_page_ptdesc() Qi Zheng
2025-01-23 13:26 ` [PATCH 1/5] mm: pgtable: make generic tlb_remove_table() use struct ptdesc Qi Zheng
2025-01-23 13:26 ` [PATCH 2/5] mm: pgtable: convert some architectures to use tlb_remove_ptdesc() Qi Zheng
2025-01-23 13:26 ` [PATCH 3/5] riscv: pgtable: unconditionally " Qi Zheng
2025-01-23 13:26 ` [PATCH 4/5] x86: pgtable: unconditionally use tlb_remove_table() Qi Zheng
2025-01-24 11:38 ` Peter Zijlstra
2025-01-24 13:00 ` Qi Zheng
2025-01-27 16:02 ` Peter Zijlstra
2025-01-23 13:26 ` [PATCH 5/5] mm: pgtable: remove tlb_remove_page_ptdesc() Qi Zheng
2025-01-24 11:47 ` [PATCH 0/5] " Peter Zijlstra
2025-01-24 13:04 ` Qi Zheng
2025-02-08 7:22 ` Matthew Wilcox
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).