aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kernel/cpu/common.c
diff options
context:
space:
mode:
authorDave Hansen <dave.hansen@linux.intel.com>2014-07-31 11:40:55 -0400
committerH. Peter Anvin <hpa@linux.intel.com>2014-07-31 11:48:50 -0400
commite9f4e0a9fe2723078b7a1a1169828dd46a7b2f9e (patch)
treec16300d2f05f2fce6b7b70b2c6fed1ac58486129 /arch/x86/kernel/cpu/common.c
parent4995ab9cf512e9a6cc07dfd6b1d4e2fc48ce7fef (diff)
x86/mm: Rip out complicated, out-of-date, buggy TLB flushing
I think the flush_tlb_mm_range() code that tries to tune the flush sizes based on the CPU needs to get ripped out for several reasons: 1. It is obviously buggy. It uses mm->total_vm to judge the task's footprint in the TLB. It should certainly be using some measure of RSS, *NOT* ->total_vm since only resident memory can populate the TLB. 2. Haswell, and several other CPUs are missing from the intel_tlb_flushall_shift_set() function. Thus, it has been demonstrated to bitrot quickly in practice. 3. It is plain wrong in my vm: [ 0.037444] Last level iTLB entries: 4KB 0, 2MB 0, 4MB 0 [ 0.037444] Last level dTLB entries: 4KB 0, 2MB 0, 4MB 0 [ 0.037444] tlb_flushall_shift: 6 Which leads to it to never use invlpg. 4. The assumptions about TLB refill costs are wrong: http://lkml.kernel.org/r/1337782555-8088-3-git-send-email-alex.shi@intel.com (more on this in later patches) 5. I can not reproduce the original data: https://lkml.org/lkml/2012/5/17/59 I believe the sample times were too short. Running the benchmark in a loop yields times that vary quite a bit. Note that this leaves us with a static ceiling of 1 page. This is a conservative, dumb setting, and will be revised in a later patch. This also removes the code which attempts to predict whether we are flushing data or instructions. We expect instruction flushes to be relatively rare and not worth tuning for explicitly. Signed-off-by: Dave Hansen <dave.hansen@linux.intel.com> Link: http://lkml.kernel.org/r/20140731154055.ABC88E89@viggo.jf.intel.com Acked-by: Rik van Riel <riel@redhat.com> Acked-by: Mel Gorman <mgorman@suse.de> Signed-off-by: H. Peter Anvin <hpa@linux.intel.com>
Diffstat (limited to 'arch/x86/kernel/cpu/common.c')
-rw-r--r--arch/x86/kernel/cpu/common.c13
1 files changed, 2 insertions, 11 deletions
diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c
index 2cbbf88d8f2c..2c1782085121 100644
--- a/arch/x86/kernel/cpu/common.c
+++ b/arch/x86/kernel/cpu/common.c
@@ -480,26 +480,17 @@ u16 __read_mostly tlb_lld_2m[NR_INFO];
480u16 __read_mostly tlb_lld_4m[NR_INFO]; 480u16 __read_mostly tlb_lld_4m[NR_INFO];
481u16 __read_mostly tlb_lld_1g[NR_INFO]; 481u16 __read_mostly tlb_lld_1g[NR_INFO];
482 482
483/*
484 * tlb_flushall_shift shows the balance point in replacing cr3 write
485 * with multiple 'invlpg'. It will do this replacement when
486 * flush_tlb_lines <= active_lines/2^tlb_flushall_shift.
487 * If tlb_flushall_shift is -1, means the replacement will be disabled.
488 */
489s8 __read_mostly tlb_flushall_shift = -1;
490
491void cpu_detect_tlb(struct cpuinfo_x86 *c) 483void cpu_detect_tlb(struct cpuinfo_x86 *c)
492{ 484{
493 if (this_cpu->c_detect_tlb) 485 if (this_cpu->c_detect_tlb)
494 this_cpu->c_detect_tlb(c); 486 this_cpu->c_detect_tlb(c);
495 487
496 printk(KERN_INFO "Last level iTLB entries: 4KB %d, 2MB %d, 4MB %d\n" 488 printk(KERN_INFO "Last level iTLB entries: 4KB %d, 2MB %d, 4MB %d\n"
497 "Last level dTLB entries: 4KB %d, 2MB %d, 4MB %d, 1GB %d\n" 489 "Last level dTLB entries: 4KB %d, 2MB %d, 4MB %d, 1GB %d\n",
498 "tlb_flushall_shift: %d\n",
499 tlb_lli_4k[ENTRIES], tlb_lli_2m[ENTRIES], 490 tlb_lli_4k[ENTRIES], tlb_lli_2m[ENTRIES],
500 tlb_lli_4m[ENTRIES], tlb_lld_4k[ENTRIES], 491 tlb_lli_4m[ENTRIES], tlb_lld_4k[ENTRIES],
501 tlb_lld_2m[ENTRIES], tlb_lld_4m[ENTRIES], 492 tlb_lld_2m[ENTRIES], tlb_lld_4m[ENTRIES],
502 tlb_lld_1g[ENTRIES], tlb_flushall_shift); 493 tlb_lld_1g[ENTRIES]);
503} 494}
504 495
505void detect_ht(struct cpuinfo_x86 *c) 496void detect_ht(struct cpuinfo_x86 *c)