x86/mm/tlb: Add freed_tables argument to flush_tlb_mm_range
authorRik van Riel <riel@surriel.com>
Wed, 26 Sep 2018 03:58:42 +0000 (23:58 -0400)
committerPeter Zijlstra <peterz@infradead.org>
Tue, 9 Oct 2018 14:51:12 +0000 (16:51 +0200)
Add an argument to flush_tlb_mm_range to indicate whether page tables
are about to be freed after this TLB flush. This allows for an
optimization of flush_tlb_mm_range to skip CPUs in lazy TLB mode.

No functional changes.

Cc: npiggin@gmail.com
Cc: mingo@kernel.org
Cc: will.deacon@arm.com
Cc: songliubraving@fb.com
Cc: kernel-team@fb.com
Cc: luto@kernel.org
Cc: hpa@zytor.com
Signed-off-by: Rik van Riel <riel@surriel.com>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Link: http://lkml.kernel.org/r/20180926035844.1420-6-riel@surriel.com
arch/x86/include/asm/tlb.h
arch/x86/include/asm/tlbflush.h
arch/x86/kernel/ldt.c
arch/x86/kernel/vm86_32.c
arch/x86/mm/tlb.c

index afbe7d1e68cf530c58de3727be492f6f0acd2bc0..404b8b1d44f5899bb2db788a5aee7c588445748d 100644 (file)
@@ -20,7 +20,7 @@ static inline void tlb_flush(struct mmu_gather *tlb)
                end = tlb->end;
        }
 
-       flush_tlb_mm_range(tlb->mm, start, end, stride_shift);
+       flush_tlb_mm_range(tlb->mm, start, end, stride_shift, tlb->freed_tables);
 }
 
 /*
index d6c0cd9e95915621177c342420f2dd90ec30d1ca..1dea9860ce5b493902871d32c99cd8ac0460bc59 100644 (file)
@@ -536,22 +536,24 @@ struct flush_tlb_info {
 
 #define local_flush_tlb() __flush_tlb()
 
-#define flush_tlb_mm(mm)       flush_tlb_mm_range(mm, 0UL, TLB_FLUSH_ALL, 0UL)
+#define flush_tlb_mm(mm)                                               \
+               flush_tlb_mm_range(mm, 0UL, TLB_FLUSH_ALL, 0UL, true)
 
 #define flush_tlb_range(vma, start, end)                               \
        flush_tlb_mm_range((vma)->vm_mm, start, end,                    \
                           ((vma)->vm_flags & VM_HUGETLB)               \
                                ? huge_page_shift(hstate_vma(vma))      \
-                               : PAGE_SHIFT)
+                               : PAGE_SHIFT, false)
 
 extern void flush_tlb_all(void);
 extern void flush_tlb_mm_range(struct mm_struct *mm, unsigned long start,
-                               unsigned long end, unsigned int stride_shift);
+                               unsigned long end, unsigned int stride_shift,
+                               bool freed_tables);
 extern void flush_tlb_kernel_range(unsigned long start, unsigned long end);
 
 static inline void flush_tlb_page(struct vm_area_struct *vma, unsigned long a)
 {
-       flush_tlb_mm_range(vma->vm_mm, a, a + PAGE_SIZE, PAGE_SHIFT);
+       flush_tlb_mm_range(vma->vm_mm, a, a + PAGE_SIZE, PAGE_SHIFT, false);
 }
 
 void native_flush_tlb_others(const struct cpumask *cpumask,
index 7fdb2414ca65c7bd61e0e073b89e5abf93dd9c04..ab18e0884dc6fdfb6e403760921b3dc87d7ff592 100644 (file)
@@ -273,7 +273,7 @@ map_ldt_struct(struct mm_struct *mm, struct ldt_struct *ldt, int slot)
        map_ldt_struct_to_user(mm);
 
        va = (unsigned long)ldt_slot_va(slot);
-       flush_tlb_mm_range(mm, va, va + LDT_SLOT_STRIDE, PAGE_SHIFT);
+       flush_tlb_mm_range(mm, va, va + LDT_SLOT_STRIDE, PAGE_SHIFT, false);
 
        ldt->slot = slot;
        return 0;
index 52fed70f671eb59c315d3b1eb92836d09a06ac79..c2fd39752da886776f0ff9a32b7acef157f12e6a 100644 (file)
@@ -199,7 +199,7 @@ static void mark_screen_rdonly(struct mm_struct *mm)
        pte_unmap_unlock(pte, ptl);
 out:
        up_write(&mm->mmap_sem);
-       flush_tlb_mm_range(mm, 0xA0000, 0xA0000 + 32*PAGE_SIZE, PAGE_SHIFT);
+       flush_tlb_mm_range(mm, 0xA0000, 0xA0000 + 32*PAGE_SIZE, PAGE_SHIFT, false);
 }
 
 
index 9fb30d27854b559020d6489eb12ecc92ac23e189..14bf39fc0447a91a54ea595f3d4b0b2c12b172dc 100644 (file)
@@ -609,7 +609,8 @@ void native_flush_tlb_others(const struct cpumask *cpumask,
 static unsigned long tlb_single_page_flush_ceiling __read_mostly = 33;
 
 void flush_tlb_mm_range(struct mm_struct *mm, unsigned long start,
-                               unsigned long end, unsigned int stride_shift)
+                               unsigned long end, unsigned int stride_shift,
+                               bool freed_tables)
 {
        int cpu;