aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/mm/tlb.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86/mm/tlb.c')
-rw-r--r--arch/x86/mm/tlb.c64
1 files changed, 6 insertions, 58 deletions
diff --git a/arch/x86/mm/tlb.c b/arch/x86/mm/tlb.c
index 658bf0090565..0f3d0cea4d00 100644
--- a/arch/x86/mm/tlb.c
+++ b/arch/x86/mm/tlb.c
@@ -30,7 +30,6 @@
30 30
31atomic64_t last_mm_ctx_id = ATOMIC64_INIT(1); 31atomic64_t last_mm_ctx_id = ATOMIC64_INIT(1);
32 32
33DEFINE_STATIC_KEY_TRUE(tlb_use_lazy_mode);
34 33
35static void choose_new_asid(struct mm_struct *next, u64 next_tlb_gen, 34static void choose_new_asid(struct mm_struct *next, u64 next_tlb_gen,
36 u16 *new_asid, bool *need_flush) 35 u16 *new_asid, bool *need_flush)
@@ -147,8 +146,8 @@ void switch_mm_irqs_off(struct mm_struct *prev, struct mm_struct *next,
147 this_cpu_write(cpu_tlbstate.is_lazy, false); 146 this_cpu_write(cpu_tlbstate.is_lazy, false);
148 147
149 if (real_prev == next) { 148 if (real_prev == next) {
150 VM_BUG_ON(this_cpu_read(cpu_tlbstate.ctxs[prev_asid].ctx_id) != 149 VM_WARN_ON(this_cpu_read(cpu_tlbstate.ctxs[prev_asid].ctx_id) !=
151 next->context.ctx_id); 150 next->context.ctx_id);
152 151
153 /* 152 /*
154 * We don't currently support having a real mm loaded without 153 * We don't currently support having a real mm loaded without
@@ -213,6 +212,9 @@ void switch_mm_irqs_off(struct mm_struct *prev, struct mm_struct *next,
213} 212}
214 213
215/* 214/*
215 * Please ignore the name of this function. It should be called
216 * switch_to_kernel_thread().
217 *
216 * enter_lazy_tlb() is a hint from the scheduler that we are entering a 218 * enter_lazy_tlb() is a hint from the scheduler that we are entering a
217 * kernel thread or other context without an mm. Acceptable implementations 219 * kernel thread or other context without an mm. Acceptable implementations
218 * include doing nothing whatsoever, switching to init_mm, or various clever 220 * include doing nothing whatsoever, switching to init_mm, or various clever
@@ -227,7 +229,7 @@ void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk)
227 if (this_cpu_read(cpu_tlbstate.loaded_mm) == &init_mm) 229 if (this_cpu_read(cpu_tlbstate.loaded_mm) == &init_mm)
228 return; 230 return;
229 231
230 if (static_branch_unlikely(&tlb_use_lazy_mode)) { 232 if (tlb_defer_switch_to_init_mm()) {
231 /* 233 /*
232 * There's a significant optimization that may be possible 234 * There's a significant optimization that may be possible
233 * here. We have accurate enough TLB flush tracking that we 235 * here. We have accurate enough TLB flush tracking that we
@@ -626,57 +628,3 @@ static int __init create_tlb_single_page_flush_ceiling(void)
626 return 0; 628 return 0;
627} 629}
628late_initcall(create_tlb_single_page_flush_ceiling); 630late_initcall(create_tlb_single_page_flush_ceiling);
629
630static ssize_t tlblazy_read_file(struct file *file, char __user *user_buf,
631 size_t count, loff_t *ppos)
632{
633 char buf[2];
634
635 buf[0] = static_branch_likely(&tlb_use_lazy_mode) ? '1' : '0';
636 buf[1] = '\n';
637
638 return simple_read_from_buffer(user_buf, count, ppos, buf, 2);
639}
640
641static ssize_t tlblazy_write_file(struct file *file,
642 const char __user *user_buf, size_t count, loff_t *ppos)
643{
644 bool val;
645
646 if (kstrtobool_from_user(user_buf, count, &val))
647 return -EINVAL;
648
649 if (val)
650 static_branch_enable(&tlb_use_lazy_mode);
651 else
652 static_branch_disable(&tlb_use_lazy_mode);
653
654 return count;
655}
656
657static const struct file_operations fops_tlblazy = {
658 .read = tlblazy_read_file,
659 .write = tlblazy_write_file,
660 .llseek = default_llseek,
661};
662
663static int __init init_tlb_use_lazy_mode(void)
664{
665 if (boot_cpu_has(X86_FEATURE_PCID)) {
666 /*
667 * Heuristic: with PCID on, switching to and from
668 * init_mm is reasonably fast, but remote flush IPIs
669 * as expensive as ever, so turn off lazy TLB mode.
670 *
671 * We can't do this in setup_pcid() because static keys
672 * haven't been initialized yet, and it would blow up
673 * badly.
674 */
675 static_branch_disable(&tlb_use_lazy_mode);
676 }
677
678 debugfs_create_file("tlb_use_lazy_mode", S_IRUSR | S_IWUSR,
679 arch_debugfs_dir, NULL, &fops_tlblazy);
680 return 0;
681}
682late_initcall(init_tlb_use_lazy_mode);