]> git.proxmox.com Git - mirror_ubuntu-jammy-kernel.git/commitdiff
arch/tlb: Clean up simple architectures
authorPeter Zijlstra <peterz@infradead.org>
Tue, 4 Sep 2018 15:04:07 +0000 (17:04 +0200)
committerIngo Molnar <mingo@kernel.org>
Wed, 3 Apr 2019 08:32:54 +0000 (10:32 +0200)
For the architectures that do not implement their own tlb_flush() but
do already use the generic mmu_gather, there are two options:

 1) the platform has an efficient flush_tlb_range() and
    asm-generic/tlb.h doesn't need any overrides at all.

 2) the platform lacks an efficient flush_tlb_range() and
    we select MMU_GATHER_NO_RANGE to minimize full invalidates.

Convert all 'simple' architectures to one of these two forms.

alpha:     has no range invalidate -> 2
arc:     already used flush_tlb_range() -> 1
c6x:     has no range invalidate -> 2
hexagon:    has an efficient flush_tlb_range() -> 1
            (flush_tlb_mm() is in fact a full range invalidate,
     so no need to shoot down everything)
m68k:     has inefficient flush_tlb_range() -> 2
microblaze: has no flush_tlb_range() -> 2
mips:     has efficient flush_tlb_range() -> 1
    (even though it currently seems to use flush_tlb_mm())
nds32:     already uses flush_tlb_range() -> 1
nios2:     has inefficient flush_tlb_range() -> 2
    (no limit on range iteration)
openrisc:   has inefficient flush_tlb_range() -> 2
    (no limit on range iteration)
parisc:     already uses flush_tlb_range() -> 1
sparc32:    already uses flush_tlb_range() -> 1
unicore32:  has inefficient flush_tlb_range() -> 2
    (no limit on range iteration)
xtensa:     has efficient flush_tlb_range() -> 1

Note this also fixes a bug in the existing code for a number
platforms. Those platforms that did:

  tlb_end_vma() -> if (!full_mm) flush_tlb_*()
  tlb_flush -> if (full_mm) flush_tlb_mm()

missed the case of shift_arg_pages(), which doesn't have @fullmm set,
nor calls into tlb_*vma(), but still frees page-tables and thus needs
an invalidate. The new code handles this by detecting a non-empty
range, and either issuing the matching range invalidate or a full
invalidate, depending on the capabilities.

No change in behavior intended.

Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Andy Lutomirski <luto@kernel.org>
Cc: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
Cc: Borislav Petkov <bp@alien8.de>
Cc: Dave Hansen <dave.hansen@linux.intel.com>
Cc: David S. Miller <davem@davemloft.net>
Cc: Greentime Hu <green.hu@gmail.com>
Cc: Guan Xuetao <gxt@pku.edu.cn>
Cc: H. Peter Anvin <hpa@zytor.com>
Cc: Helge Deller <deller@gmx.de>
Cc: Jonas Bonn <jonas@southpole.se>
Cc: Ley Foon Tan <lftan@altera.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Mark Salter <msalter@redhat.com>
Cc: Max Filippov <jcmvbkbc@gmail.com>
Cc: Michal Simek <monstr@monstr.eu>
Cc: Nick Piggin <npiggin@gmail.com>
Cc: Paul Burton <paul.burton@mips.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Richard Henderson <rth@twiddle.net>
Cc: Richard Kuo <rkuo@codeaurora.org>
Cc: Rik van Riel <riel@surriel.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Vineet Gupta <vgupta@synopsys.com>
Cc: Will Deacon <will.deacon@arm.com>
Signed-off-by: Ingo Molnar <mingo@kernel.org>
22 files changed:
arch/alpha/Kconfig
arch/alpha/include/asm/tlb.h
arch/arc/include/asm/tlb.h
arch/c6x/Kconfig
arch/c6x/include/asm/tlb.h
arch/h8300/include/asm/tlb.h
arch/hexagon/include/asm/tlb.h
arch/m68k/Kconfig
arch/m68k/include/asm/tlb.h
arch/microblaze/Kconfig
arch/microblaze/include/asm/tlb.h
arch/mips/include/asm/tlb.h
arch/nds32/include/asm/tlb.h
arch/nios2/Kconfig
arch/nios2/include/asm/tlb.h
arch/openrisc/Kconfig
arch/openrisc/include/asm/tlb.h
arch/parisc/include/asm/tlb.h
arch/sparc/include/asm/tlb_32.h
arch/unicore32/Kconfig
arch/unicore32/include/asm/tlb.h
arch/xtensa/include/asm/tlb.h

index 584a6e1148539682a34a4c480c3f5252ee169267..c7c976eb64074b443b0821775201ba3f91abcc57 100644 (file)
@@ -36,6 +36,7 @@ config ALPHA
        select ODD_RT_SIGACTION
        select OLD_SIGSUSPEND
        select CPU_NO_EFFICIENT_FFS if !ALPHA_EV67
+       select MMU_GATHER_NO_RANGE
        help
          The Alpha is a 64-bit general-purpose processor designed and
          marketed by the Digital Equipment Corporation of blessed memory,
index 8f5042b61875fdd4c308f2b3e3accab95ff571e8..4f79e331af5ea4237ba8200867bf2161f1676d7c 100644 (file)
@@ -2,12 +2,6 @@
 #ifndef _ALPHA_TLB_H
 #define _ALPHA_TLB_H
 
-#define tlb_start_vma(tlb, vma)                        do { } while (0)
-#define tlb_end_vma(tlb, vma)                  do { } while (0)
-#define __tlb_remove_tlb_entry(tlb, pte, addr) do { } while (0)
-
-#define tlb_flush(tlb)                         flush_tlb_mm((tlb)->mm)
-
 #include <asm-generic/tlb.h>
 
 #define __pte_free_tlb(tlb, pte, address)              pte_free((tlb)->mm, pte)
index 7af2b373ebe753e5c7f4bb4290d250dd45209924..90cac97643a46949fd00f3d2678eebb4a10c525b 100644 (file)
@@ -9,29 +9,6 @@
 #ifndef _ASM_ARC_TLB_H
 #define _ASM_ARC_TLB_H
 
-#define tlb_flush(tlb)                         \
-do {                                           \
-       if (tlb->fullmm)                        \
-               flush_tlb_mm((tlb)->mm);        \
-} while (0)
-
-/*
- * This pair is called at time of munmap/exit to flush cache and TLB entries
- * for mappings being torn down.
- * 1) cache-flush part -implemented via tlb_start_vma( ) for VIPT aliasing D$
- * 2) tlb-flush part - implemted via tlb_end_vma( ) flushes the TLB range
- *
- * Note, read http://lkml.org/lkml/2004/1/15/6
- */
-
-#define tlb_end_vma(tlb, vma)                                          \
-do {                                                                   \
-       if (!tlb->fullmm)                                               \
-               flush_tlb_range(vma, vma->vm_start, vma->vm_end);       \
-} while (0)
-
-#define __tlb_remove_tlb_entry(tlb, ptep, address)
-
 #include <linux/pagemap.h>
 #include <asm-generic/tlb.h>
 
index e5cd3c5f8399ce1cb055315083db5b2f4873a1fe..3bb75e674161ccf345125ba6a74186b214db4408 100644 (file)
@@ -20,6 +20,7 @@ config C6X
        select GENERIC_CLOCKEVENTS
        select MODULES_USE_ELF_RELA
        select ARCH_NO_COHERENT_DMA_MMAP
+       select MMU_GATHER_NO_RANGE if MMU
 
 config MMU
        def_bool n
index 34525dea1356645c12a4c3c9b6d1a5f57eec3851..240ba0febb57b7407070df4e52f6ae2c346a42c4 100644 (file)
@@ -2,8 +2,6 @@
 #ifndef _ASM_C6X_TLB_H
 #define _ASM_C6X_TLB_H
 
-#define tlb_flush(tlb) flush_tlb_mm((tlb)->mm)
-
 #include <asm-generic/tlb.h>
 
 #endif /* _ASM_C6X_TLB_H */
index 98f344279904a684d367c4d55556c06bab3e74ab..d8201ca312061d96d9409fd27efc87cddf384196 100644 (file)
@@ -2,8 +2,6 @@
 #ifndef __H8300_TLB_H__
 #define __H8300_TLB_H__
 
-#define tlb_flush(tlb) do { } while (0)
-
 #include <asm-generic/tlb.h>
 
 #endif
index 2f00772cc08a551df873985b29647ac388fb1e55..f71c4ba83614c38187fd5ca0a5e24bb5ff71749d 100644 (file)
 #include <linux/pagemap.h>
 #include <asm/tlbflush.h>
 
-/*
- * We don't need any special per-pte or per-vma handling...
- */
-#define tlb_start_vma(tlb, vma)                                do { } while (0)
-#define tlb_end_vma(tlb, vma)                          do { } while (0)
-#define __tlb_remove_tlb_entry(tlb, ptep, address)     do { } while (0)
-
-/*
- * .. because we flush the whole mm when it fills up
- */
-#define tlb_flush(tlb)         flush_tlb_mm((tlb)->mm)
-
 #include <asm-generic/tlb.h>
 
 #endif
index b54206408f91b9693581c9b6a139324a659cf361..4e37efbc92961acf82cdb3f59ab2b3e4348bcefb 100644 (file)
@@ -28,6 +28,7 @@ config M68K
        select OLD_SIGSUSPEND3
        select OLD_SIGACTION
        select ARCH_DISCARD_MEMBLOCK
+       select MMU_GATHER_NO_RANGE if MMU
 
 config CPU_BIG_ENDIAN
        def_bool y
index b4b9efb6f963be8761e0cdc830be3cb5fb3bf3ab..3c81f6adfc8b36b26f53fea65941072707c9778f 100644 (file)
@@ -2,20 +2,6 @@
 #ifndef _M68K_TLB_H
 #define _M68K_TLB_H
 
-/*
- * m68k doesn't need any special per-pte or
- * per-vma handling..
- */
-#define tlb_start_vma(tlb, vma)        do { } while (0)
-#define tlb_end_vma(tlb, vma)  do { } while (0)
-#define __tlb_remove_tlb_entry(tlb, ptep, address)     do { } while (0)
-
-/*
- * .. because we flush the whole mm when it
- * fills up.
- */
-#define tlb_flush(tlb)         flush_tlb_mm((tlb)->mm)
-
 #include <asm-generic/tlb.h>
 
 #endif /* _M68K_TLB_H */
index a51b965b3b82359f5feb15aaef1529cdbaa0f32a..321e398ab6b51d107066c65af395d4061bcc338e 100644 (file)
@@ -41,6 +41,7 @@ config MICROBLAZE
        select TRACING_SUPPORT
        select VIRT_TO_BUS
        select CPU_NO_EFFICIENT_FFS
+       select MMU_GATHER_NO_RANGE if MMU
 
 # Endianness selection
 choice
index 99b6ded54849e2327e7593592c14aa73adee1429..628a78ee0a720975f6413cba6d32a9e342812345 100644 (file)
 #ifndef _ASM_MICROBLAZE_TLB_H
 #define _ASM_MICROBLAZE_TLB_H
 
-#define tlb_flush(tlb) flush_tlb_mm((tlb)->mm)
-
 #include <linux/pagemap.h>
-
-#ifdef CONFIG_MMU
-#define tlb_start_vma(tlb, vma)                do { } while (0)
-#define tlb_end_vma(tlb, vma)          do { } while (0)
-#define __tlb_remove_tlb_entry(tlb, pte, address) do { } while (0)
-#endif
-
 #include <asm-generic/tlb.h>
 
 #endif /* _ASM_MICROBLAZE_TLB_H */
index 32b8a8187733d147eff57214ef184bfbabda9dd8..90f3ad76d9e0b03761ceec49eca71605065d1465 100644 (file)
@@ -5,14 +5,6 @@
 #include <asm/cpu-features.h>
 #include <asm/mipsregs.h>
 
-#define tlb_end_vma(tlb, vma) do { } while (0)
-#define __tlb_remove_tlb_entry(tlb, ptep, address) do { } while (0)
-
-/*
- * .. because we flush the whole mm when it fills up.
- */
-#define tlb_flush(tlb) flush_tlb_mm((tlb)->mm)
-
 #define _UNIQUE_ENTRYHI(base, idx)                                     \
                (((base) + ((idx) << (PAGE_SHIFT + 1))) |               \
                 (cpu_has_tlbinv ? MIPS_ENTRYHI_EHINV : 0))
index 0bf7c94823819a851c0b5be0a04b0d7521909062..d5ae571c8d303f4e87350e3a9644df4469ec4da2 100644 (file)
@@ -4,16 +4,6 @@
 #ifndef __ASMNDS32_TLB_H
 #define __ASMNDS32_TLB_H
 
-#define tlb_end_vma(tlb,vma)                           \
-       do {                                            \
-               if(!tlb->fullmm)                        \
-                       flush_tlb_range(vma, vma->vm_start, vma->vm_end); \
-       } while (0)
-
-#define __tlb_remove_tlb_entry(tlb, pte, addr) do { } while (0)
-
-#define tlb_flush(tlb) flush_tlb_mm((tlb)->mm)
-
 #include <asm-generic/tlb.h>
 
 #define __pte_free_tlb(tlb, pte, addr) pte_free((tlb)->mm, pte)
index 4ef15a61b7bc33ee199a84fb6c8ef36be2a9deac..3633f81443678bf12886616302b276350be623b5 100644 (file)
@@ -24,6 +24,7 @@ config NIOS2
        select USB_ARCH_HAS_HCD if USB_SUPPORT
        select CPU_NO_EFFICIENT_FFS
        select ARCH_DISCARD_MEMBLOCK
+       select MMU_GATHER_NO_RANGE if MMU
 
 config GENERIC_CSUM
        def_bool y
index 9b518c6d0f622efb5d5dcce3009a7a7733f2b82d..f9f2e27e32dd5e7768ba9a63faac98b18516f41d 100644 (file)
 #ifndef _ASM_NIOS2_TLB_H
 #define _ASM_NIOS2_TLB_H
 
-#define tlb_flush(tlb) flush_tlb_mm((tlb)->mm)
-
 extern void set_mmu_pid(unsigned long pid);
 
-#define tlb_end_vma(tlb, vma)  do { } while (0)
-#define __tlb_remove_tlb_entry(tlb, ptep, address)     do { } while (0)
+/*
+ * NIOS32 does have flush_tlb_range(), but it lacks a limit and fallback to
+ * full mm invalidation. So use flush_tlb_mm() for everything.
+ */
 
 #include <linux/pagemap.h>
 #include <asm-generic/tlb.h>
index a5e361fbb75a01400681b6238b21a7eea18b9607..c6cf8a49a0ab5a2178be0872622118055cec11de 100644 (file)
@@ -36,6 +36,7 @@ config OPENRISC
        select OMPIC if SMP
        select ARCH_WANT_FRAME_POINTERS
        select GENERIC_IRQ_MULTI_HANDLER
+       select MMU_GATHER_NO_RANGE if MMU
 
 config CPU_BIG_ENDIAN
        def_bool y
index fa4376a4515d14a8921ae7c3e382c0ee6398952e..92d8a42098849dcffcc5ceb07dc8c15b00f992c9 100644 (file)
 #define __ASM_OPENRISC_TLB_H__
 
 /*
- * or32 doesn't need any special per-pte or
- * per-vma handling..
+ * OpenRISC doesn't have an efficient flush_tlb_range() so use flush_tlb_mm()
+ * for everything.
  */
-#define tlb_start_vma(tlb, vma) do { } while (0)
-#define tlb_end_vma(tlb, vma) do { } while (0)
-#define __tlb_remove_tlb_entry(tlb, ptep, address) do { } while (0)
 
-#define tlb_flush(tlb) flush_tlb_mm((tlb)->mm)
 #include <linux/pagemap.h>
 #include <asm-generic/tlb.h>
 
index b1984f9cd3af4340b33795a44065b4b6f60631a8..8c0446b04c9e17f593cac1d4fa3671658766038d 100644 (file)
@@ -2,19 +2,6 @@
 #ifndef _PARISC_TLB_H
 #define _PARISC_TLB_H
 
-#define tlb_flush(tlb)                 \
-do {   if ((tlb)->fullmm)              \
-               flush_tlb_mm((tlb)->mm);\
-} while (0)
-
-#define tlb_end_vma(tlb, vma)  \
-do {   if (!(tlb)->fullmm)     \
-               flush_tlb_range(vma, vma->vm_start, vma->vm_end); \
-} while (0)
-
-#define __tlb_remove_tlb_entry(tlb, pte, address) \
-       do { } while (0)
-
 #include <asm-generic/tlb.h>
 
 #define __pmd_free_tlb(tlb, pmd, addr) pmd_free((tlb)->mm, pmd)
index 68d817273de878cc495ed053734df3b5fb0f7c56..5cd28a8793e3975aef8e7389ec232068fb6feffb 100644 (file)
@@ -2,19 +2,6 @@
 #ifndef _SPARC_TLB_H
 #define _SPARC_TLB_H
 
-#define tlb_end_vma(tlb, vma) \
-do {                                                           \
-       flush_tlb_range(vma, vma->vm_start, vma->vm_end);       \
-} while (0)
-
-#define __tlb_remove_tlb_entry(tlb, pte, address) \
-       do { } while (0)
-
-#define tlb_flush(tlb) \
-do {                                                           \
-       flush_tlb_mm((tlb)->mm);                                \
-} while (0)
-
 #include <asm-generic/tlb.h>
 
 #endif /* _SPARC_TLB_H */
index 817d82608712ab6f603edd6514c16c2744b08584..d83c8f70900d11424a4b10eefe791d4adabe179c 100644 (file)
@@ -20,6 +20,7 @@ config UNICORE32
        select GENERIC_IOMAP
        select MODULES_USE_ELF_REL
        select NEED_DMA_MAP_STATE
+       select MMU_GATHER_NO_RANGE if MMU
        help
          UniCore-32 is 32-bit Instruction Set Architecture,
          including a series of low-power-consumption RISC chip
index 9cca15cdae94c706508968a5131acadbba4ca4e6..00a8477333f6db4d745d4da8ef3f7cb28807b838 100644 (file)
 #ifndef __UNICORE_TLB_H__
 #define __UNICORE_TLB_H__
 
-#define tlb_start_vma(tlb, vma)                                do { } while (0)
-#define tlb_end_vma(tlb, vma)                          do { } while (0)
-#define __tlb_remove_tlb_entry(tlb, ptep, address)     do { } while (0)
-#define tlb_flush(tlb) flush_tlb_mm((tlb)->mm)
+/*
+ * unicore32 lacks an efficient flush_tlb_range(), use flush_tlb_mm().
+ */
 
 #define __pte_free_tlb(tlb, pte, addr)                         \
        do {                                                    \
index 1a93e350382e71ae9835d0257e79e8d387f8f83f..50889935138ad2170b1e4c57aaccbf9551fdf997 100644 (file)
 #include <asm/cache.h>
 #include <asm/page.h>
 
-#if (DCACHE_WAY_SIZE <= PAGE_SIZE)
-
-# define tlb_end_vma(tlb,vma)                  do { } while (0)
-
-#else
-
-# define tlb_end_vma(tlb, vma)                                               \
-       do {                                                                  \
-               if (!tlb->fullmm)                                             \
-                       flush_tlb_range(vma, vma->vm_start, vma->vm_end);     \
-       } while(0)
-
-#endif
-
-#define __tlb_remove_tlb_entry(tlb,pte,addr)   do { } while (0)
-#define tlb_flush(tlb)                         flush_tlb_mm((tlb)->mm)
-
 #include <asm-generic/tlb.h>
 
 #define __pte_free_tlb(tlb, pte, address)      pte_free((tlb)->mm, pte)