=== NOT FOR MERGE YET === This adds the support for ARCH_WANT_BATCHED_UNMAP_TLB_FLUSH. More details are added to the cover letter.
--- arch/powerpc/Kconfig | 1 + arch/powerpc/include/asm/book3s/64/tlbflush.h | 5 +++ arch/powerpc/include/asm/tlbbatch.h | 14 ++++++++ arch/powerpc/mm/book3s64/radix_tlb.c | 32 +++++++++++++++++++ 4 files changed, 52 insertions(+) create mode 100644 arch/powerpc/include/asm/tlbbatch.h diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index 0b8b2e3a6381..c3a23c1894dd 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig @@ -171,6 +171,7 @@ config PPC select ARCH_USE_CMPXCHG_LOCKREF if PPC64 select ARCH_USE_MEMTEST select ARCH_USE_QUEUED_RWLOCKS if PPC_QUEUED_SPINLOCKS + select ARCH_WANT_BATCHED_UNMAP_TLB_FLUSH if PPC64 && PPC_BOOK3S_64 select ARCH_WANT_DEFAULT_BPF_JIT select ARCH_WANT_DEFAULT_TOPDOWN_MMAP_LAYOUT select ARCH_WANT_IPC_PARSE_VERSION diff --git a/arch/powerpc/include/asm/book3s/64/tlbflush.h b/arch/powerpc/include/asm/book3s/64/tlbflush.h index fd642b729775..f872537715e7 100644 --- a/arch/powerpc/include/asm/book3s/64/tlbflush.h +++ b/arch/powerpc/include/asm/book3s/64/tlbflush.h @@ -222,4 +222,9 @@ static inline bool cputlb_use_tlbie(void) return tlbie_enabled; } +bool arch_tlbbatch_should_defer(struct mm_struct *mm); +void arch_tlbbatch_add_pending(struct arch_tlbflush_unmap_batch *batch, + struct mm_struct *mm, unsigned long uaddr); +void arch_flush_tlb_batched_pending(struct mm_struct *mm); +void arch_tlbbatch_flush(struct arch_tlbflush_unmap_batch *batch); #endif /* _ASM_POWERPC_BOOK3S_64_TLBFLUSH_H */ diff --git a/arch/powerpc/include/asm/tlbbatch.h b/arch/powerpc/include/asm/tlbbatch.h new file mode 100644 index 000000000000..fa738462a242 --- /dev/null +++ b/arch/powerpc/include/asm/tlbbatch.h @@ -0,0 +1,14 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (C) 2024 IBM Corporation. + */ +#ifndef _ASM_POWERPC_TLBBATCH_H +#define _ASM_POWERPC_TLBBATCH_H + +#include <linux/cpumask.h> + +struct arch_tlbflush_unmap_batch { + struct cpumask cpumask; +}; + +#endif /* _ASM_POWERPC_TLBBATCH_H */ diff --git a/arch/powerpc/mm/book3s64/radix_tlb.c b/arch/powerpc/mm/book3s64/radix_tlb.c index 9e1f6558d026..2b1b2f7429fc 100644 --- a/arch/powerpc/mm/book3s64/radix_tlb.c +++ b/arch/powerpc/mm/book3s64/radix_tlb.c @@ -11,6 +11,7 @@ #include <linux/mmu_context.h> #include <linux/sched/mm.h> #include <linux/debugfs.h> +#include <linux/smp.h> #include <asm/ppc-opcode.h> #include <asm/tlb.h> @@ -1585,3 +1586,34 @@ static int __init create_tlb_single_page_flush_ceiling(void) } late_initcall(create_tlb_single_page_flush_ceiling); +#ifdef CONFIG_ARCH_WANT_BATCHED_UNMAP_TLB_FLUSH +bool arch_tlbbatch_should_defer(struct mm_struct *mm) +{ + if (!radix_enabled()) + return false; + return true; +} + +void arch_tlbbatch_add_pending(struct arch_tlbflush_unmap_batch *batch, + struct mm_struct *mm, + unsigned long uaddr) +{ + cpumask_or(&batch->cpumask, &batch->cpumask, mm_cpumask(mm)); +} + +void arch_flush_tlb_batched_pending(struct mm_struct *mm) +{ + flush_tlb_mm(mm); +} + +static inline void tlbiel_flush_all_lpid(void *arg) +{ + tlbiel_all_lpid(true); +} + +void arch_tlbbatch_flush(struct arch_tlbflush_unmap_batch *batch) +{ + on_each_cpu_mask(&batch->cpumask, tlbiel_flush_all_lpid, NULL, 1); + cpumask_clear(&batch->cpumask); +} +#endif -- 2.46.0