asm-generic/tlb, arch: Provide CONFIG_HAVE_MMU_GATHER_PAGE_SIZE
authorPeter Zijlstra <peterz@infradead.org>
Fri, 31 Aug 2018 12:46:08 +0000 (14:46 +0200)
committerIngo Molnar <mingo@kernel.org>
Wed, 3 Apr 2019 08:32:40 +0000 (10:32 +0200)
Move the mmu_gather::page_size things into the generic code instead of
PowerPC specific bits.

No change in behavior intended.

Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Acked-by: Will Deacon <will.deacon@arm.com>
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: H. Peter Anvin <hpa@zytor.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Nick Piggin <npiggin@gmail.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Rik van Riel <riel@surriel.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Ingo Molnar <mingo@kernel.org>
14 files changed:
arch/Kconfig
arch/arm/include/asm/tlb.h
arch/ia64/include/asm/tlb.h
arch/powerpc/Kconfig
arch/powerpc/include/asm/tlb.h
arch/s390/include/asm/tlb.h
arch/sh/include/asm/tlb.h
arch/um/include/asm/tlb.h
include/asm-generic/tlb.h
mm/huge_memory.c
mm/hugetlb.c
mm/madvise.c
mm/memory.c
mm/mmu_gather.c

index 33687dd..cdc7f3d 100644 (file)
@@ -386,6 +386,9 @@ config HAVE_RCU_TABLE_FREE
 config HAVE_RCU_TABLE_INVALIDATE
        bool
 
+config HAVE_MMU_GATHER_PAGE_SIZE
+       bool
+
 config ARCH_HAVE_NMI_SAFE_CMPXCHG
        bool
 
index f854148..d644c3c 100644 (file)
@@ -286,8 +286,7 @@ tlb_remove_pmd_tlb_entry(struct mmu_gather *tlb, pmd_t *pmdp, unsigned long addr
 
 #define tlb_migrate_finish(mm)         do { } while (0)
 
-#define tlb_remove_check_page_size_change tlb_remove_check_page_size_change
-static inline void tlb_remove_check_page_size_change(struct mmu_gather *tlb,
+static inline void tlb_change_page_size(struct mmu_gather *tlb,
                                                     unsigned int page_size)
 {
 }
index 516355a..bf8985f 100644 (file)
@@ -282,8 +282,7 @@ do {                                                        \
 #define tlb_remove_huge_tlb_entry(h, tlb, ptep, address)       \
        tlb_remove_tlb_entry(tlb, ptep, address)
 
-#define tlb_remove_check_page_size_change tlb_remove_check_page_size_change
-static inline void tlb_remove_check_page_size_change(struct mmu_gather *tlb,
+static inline void tlb_change_page_size(struct mmu_gather *tlb,
                                                     unsigned int page_size)
 {
 }
index 2d0be82..a7aa4fe 100644 (file)
@@ -218,6 +218,7 @@ config PPC
        select HAVE_PERF_REGS
        select HAVE_PERF_USER_STACK_DUMP
        select HAVE_RCU_TABLE_FREE              if SMP
+       select HAVE_MMU_GATHER_PAGE_SIZE
        select HAVE_REGS_AND_STACK_ACCESS_API
        select HAVE_RELIABLE_STACKTRACE         if PPC_BOOK3S_64 && CPU_LITTLE_ENDIAN
        select HAVE_SYSCALL_TRACEPOINTS
index e24c67d..b018e9f 100644 (file)
@@ -27,7 +27,6 @@
 #define tlb_start_vma(tlb, vma)        do { } while (0)
 #define tlb_end_vma(tlb, vma)  do { } while (0)
 #define __tlb_remove_tlb_entry __tlb_remove_tlb_entry
-#define tlb_remove_check_page_size_change tlb_remove_check_page_size_change
 
 extern void tlb_flush(struct mmu_gather *tlb);
 
@@ -46,22 +45,6 @@ static inline void __tlb_remove_tlb_entry(struct mmu_gather *tlb, pte_t *ptep,
 #endif
 }
 
-static inline void tlb_remove_check_page_size_change(struct mmu_gather *tlb,
-                                                    unsigned int page_size)
-{
-       if (!tlb->page_size)
-               tlb->page_size = page_size;
-       else if (tlb->page_size != page_size) {
-               if (!tlb->fullmm)
-                       tlb_flush_mmu(tlb);
-               /*
-                * update the page size after flush for the new
-                * mmu_gather.
-                */
-               tlb->page_size = page_size;
-       }
-}
-
 #ifdef CONFIG_SMP
 static inline int mm_is_core_local(struct mm_struct *mm)
 {
index b31c779..9941a14 100644 (file)
@@ -180,9 +180,7 @@ static inline void pud_free_tlb(struct mmu_gather *tlb, pud_t *pud,
 #define tlb_remove_huge_tlb_entry(h, tlb, ptep, address)       \
        tlb_remove_tlb_entry(tlb, ptep, address)
 
-#define tlb_remove_check_page_size_change tlb_remove_check_page_size_change
-static inline void tlb_remove_check_page_size_change(struct mmu_gather *tlb,
-                                                    unsigned int page_size)
+static inline void tlb_change_page_size(struct mmu_gather *tlb, unsigned int page_size)
 {
 }
 
index 77abe19..af7c9d8 100644 (file)
@@ -127,9 +127,7 @@ static inline void tlb_remove_page_size(struct mmu_gather *tlb,
        return tlb_remove_page(tlb, page);
 }
 
-#define tlb_remove_check_page_size_change tlb_remove_check_page_size_change
-static inline void tlb_remove_check_page_size_change(struct mmu_gather *tlb,
-                                                    unsigned int page_size)
+static inline void tlb_change_page_size(struct mmu_gather *tlb, unsigned int page_size)
 {
 }
 
index dce6db1..6463f3a 100644 (file)
@@ -146,9 +146,7 @@ static inline void tlb_remove_page_size(struct mmu_gather *tlb,
 #define tlb_remove_huge_tlb_entry(h, tlb, ptep, address)       \
        tlb_remove_tlb_entry(tlb, ptep, address)
 
-#define tlb_remove_check_page_size_change tlb_remove_check_page_size_change
-static inline void tlb_remove_check_page_size_change(struct mmu_gather *tlb,
-                                                    unsigned int page_size)
+static inline void tlb_change_page_size(struct mmu_gather *tlb, unsigned int page_size)
 {
 }
 
index f1594ba..e75620e 100644 (file)
@@ -61,7 +61,7 @@
  *    tlb_remove_page() and tlb_remove_page_size() imply the call to
  *    tlb_flush_mmu() when required and has no return value.
  *
- *  - tlb_remove_check_page_size_change()
+ *  - tlb_change_page_size()
  *
  *    call before __tlb_remove_page*() to set the current page-size; implies a
  *    possible tlb_flush_mmu() call.
  *
  * Additionally there are a few opt-in features:
  *
+ *  HAVE_MMU_GATHER_PAGE_SIZE
+ *
+ *  This ensures we call tlb_flush() every time tlb_change_page_size() actually
+ *  changes the size and provides mmu_gather::page_size to tlb_flush().
+ *
  *  HAVE_RCU_TABLE_FREE
  *
  *  This provides tlb_remove_table(), to be used instead of tlb_remove_page()
@@ -239,11 +244,15 @@ struct mmu_gather {
        unsigned int            cleared_puds : 1;
        unsigned int            cleared_p4ds : 1;
 
+       unsigned int            batch_count;
+
        struct mmu_gather_batch *active;
        struct mmu_gather_batch local;
        struct page             *__pages[MMU_GATHER_BUNDLE];
-       unsigned int            batch_count;
-       int page_size;
+
+#ifdef CONFIG_HAVE_MMU_GATHER_PAGE_SIZE
+       unsigned int page_size;
+#endif
 };
 
 void arch_tlb_gather_mmu(struct mmu_gather *tlb,
@@ -309,21 +318,18 @@ static inline void tlb_remove_page(struct mmu_gather *tlb, struct page *page)
        return tlb_remove_page_size(tlb, page, PAGE_SIZE);
 }
 
-#ifndef tlb_remove_check_page_size_change
-#define tlb_remove_check_page_size_change tlb_remove_check_page_size_change
-static inline void tlb_remove_check_page_size_change(struct mmu_gather *tlb,
+static inline void tlb_change_page_size(struct mmu_gather *tlb,
                                                     unsigned int page_size)
 {
-       /*
-        * We don't care about page size change, just update
-        * mmu_gather page size here so that debug checks
-        * doesn't throw false warning.
-        */
-#ifdef CONFIG_DEBUG_VM
+#ifdef CONFIG_HAVE_MMU_GATHER_PAGE_SIZE
+       if (tlb->page_size && tlb->page_size != page_size) {
+               if (!tlb->fullmm)
+                       tlb_flush_mmu(tlb);
+       }
+
        tlb->page_size = page_size;
 #endif
 }
-#endif
 
 static inline unsigned long tlb_get_unmap_shift(struct mmu_gather *tlb)
 {
index 404acdc..76b7511 100644 (file)
@@ -1641,7 +1641,7 @@ bool madvise_free_huge_pmd(struct mmu_gather *tlb, struct vm_area_struct *vma,
        struct mm_struct *mm = tlb->mm;
        bool ret = false;
 
-       tlb_remove_check_page_size_change(tlb, HPAGE_PMD_SIZE);
+       tlb_change_page_size(tlb, HPAGE_PMD_SIZE);
 
        ptl = pmd_trans_huge_lock(pmd, vma);
        if (!ptl)
@@ -1717,7 +1717,7 @@ int zap_huge_pmd(struct mmu_gather *tlb, struct vm_area_struct *vma,
        pmd_t orig_pmd;
        spinlock_t *ptl;
 
-       tlb_remove_check_page_size_change(tlb, HPAGE_PMD_SIZE);
+       tlb_change_page_size(tlb, HPAGE_PMD_SIZE);
 
        ptl = __pmd_trans_huge_lock(pmd, vma);
        if (!ptl)
index 97b1e02..3fc37a6 100644 (file)
@@ -3353,7 +3353,7 @@ void __unmap_hugepage_range(struct mmu_gather *tlb, struct vm_area_struct *vma,
         * This is a hugetlb vma, all the pte entries should point
         * to huge page.
         */
-       tlb_remove_check_page_size_change(tlb, sz);
+       tlb_change_page_size(tlb, sz);
        tlb_start_vma(tlb, vma);
 
        /*
index 21a7881..bb3a455 100644 (file)
@@ -328,7 +328,7 @@ static int madvise_free_pte_range(pmd_t *pmd, unsigned long addr,
        if (pmd_trans_unstable(pmd))
                return 0;
 
-       tlb_remove_check_page_size_change(tlb, PAGE_SIZE);
+       tlb_change_page_size(tlb, PAGE_SIZE);
        orig_pte = pte = pte_offset_map_lock(mm, pmd, addr, &ptl);
        flush_tlb_batched_pending(mm);
        arch_enter_lazy_mmu_mode();
index ab650c2..1aa5c03 100644 (file)
@@ -356,7 +356,7 @@ void free_pgd_range(struct mmu_gather *tlb,
         * We add page table cache pages with PAGE_SIZE,
         * (see pte_free_tlb()), flush the tlb if we need
         */
-       tlb_remove_check_page_size_change(tlb, PAGE_SIZE);
+       tlb_change_page_size(tlb, PAGE_SIZE);
        pgd = pgd_offset(tlb->mm, addr);
        do {
                next = pgd_addr_end(addr, end);
@@ -1046,7 +1046,7 @@ static unsigned long zap_pte_range(struct mmu_gather *tlb,
        pte_t *pte;
        swp_entry_t entry;
 
-       tlb_remove_check_page_size_change(tlb, PAGE_SIZE);
+       tlb_change_page_size(tlb, PAGE_SIZE);
 again:
        init_rss_vec(rss);
        start_pte = pte_offset_map_lock(mm, pmd, addr, &ptl);
index f2f03c6..14dfc97 100644 (file)
@@ -58,7 +58,9 @@ void arch_tlb_gather_mmu(struct mmu_gather *tlb, struct mm_struct *mm,
 #ifdef CONFIG_HAVE_RCU_TABLE_FREE
        tlb->batch = NULL;
 #endif
+#ifdef CONFIG_HAVE_MMU_GATHER_PAGE_SIZE
        tlb->page_size = 0;
+#endif
 
        __tlb_reset_range(tlb);
 }
@@ -121,7 +123,10 @@ bool __tlb_remove_page_size(struct mmu_gather *tlb, struct page *page, int page_
        struct mmu_gather_batch *batch;
 
        VM_BUG_ON(!tlb->end);
+
+#ifdef CONFIG_HAVE_MMU_GATHER_PAGE_SIZE
        VM_WARN_ON(tlb->page_size != page_size);
+#endif
 
        batch = tlb->active;
        /*