aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/mm
diff options
context:
space:
mode:
authorAlex Shi <alex.shi@intel.com>2012-06-27 21:02:20 -0400
committerH. Peter Anvin <hpa@zytor.com>2012-06-27 22:29:10 -0400
commit3df3212f9722c7e45c723b9ea231a04ba4dbc47c (patch)
treecb93a81efb12b91813ed69e86bc5be24ca31de9d /arch/x86/mm
parentc4211f42d3e66875298a5e26a75109878c80f15b (diff)
x86/tlb: add tlb_flushall_shift knob into debugfs
kernel will replace cr3 rewrite with invlpg when tlb_flush_entries <= active_tlb_entries / 2^tlb_flushall_factor if tlb_flushall_factor is -1, kernel won't do this replacement. User can modify its value according to specific CPU/applications. Thanks for Borislav providing the help message of CONFIG_DEBUG_TLBFLUSH. Signed-off-by: Alex Shi <alex.shi@intel.com> Link: http://lkml.kernel.org/r/1340845344-27557-6-git-send-email-alex.shi@intel.com Signed-off-by: H. Peter Anvin <hpa@zytor.com>
Diffstat (limited to 'arch/x86/mm')
-rw-r--r--arch/x86/mm/tlb.c51
1 files changed, 51 insertions, 0 deletions
diff --git a/arch/x86/mm/tlb.c b/arch/x86/mm/tlb.c
index 2939f2f9edbb..5911f61e300e 100644
--- a/arch/x86/mm/tlb.c
+++ b/arch/x86/mm/tlb.c
@@ -12,6 +12,7 @@
12#include <asm/cache.h> 12#include <asm/cache.h>
13#include <asm/apic.h> 13#include <asm/apic.h>
14#include <asm/uv/uv.h> 14#include <asm/uv/uv.h>
15#include <linux/debugfs.h>
15 16
16DEFINE_PER_CPU_SHARED_ALIGNED(struct tlb_state, cpu_tlbstate) 17DEFINE_PER_CPU_SHARED_ALIGNED(struct tlb_state, cpu_tlbstate)
17 = { &init_mm, 0, }; 18 = { &init_mm, 0, };
@@ -430,3 +431,53 @@ void flush_tlb_all(void)
430{ 431{
431 on_each_cpu(do_flush_tlb_all, NULL, 1); 432 on_each_cpu(do_flush_tlb_all, NULL, 1);
432} 433}
434
435#ifdef CONFIG_DEBUG_TLBFLUSH
436static ssize_t tlbflush_read_file(struct file *file, char __user *user_buf,
437 size_t count, loff_t *ppos)
438{
439 char buf[32];
440 unsigned int len;
441
442 len = sprintf(buf, "%hd\n", tlb_flushall_shift);
443 return simple_read_from_buffer(user_buf, count, ppos, buf, len);
444}
445
446static ssize_t tlbflush_write_file(struct file *file,
447 const char __user *user_buf, size_t count, loff_t *ppos)
448{
449 char buf[32];
450 ssize_t len;
451 s8 shift;
452
453 len = min(count, sizeof(buf) - 1);
454 if (copy_from_user(buf, user_buf, len))
455 return -EFAULT;
456
457 buf[len] = '\0';
458 if (kstrtos8(buf, 0, &shift))
459 return -EINVAL;
460
461 if (shift > 64)
462 return -EINVAL;
463
464 tlb_flushall_shift = shift;
465 return count;
466}
467
468static const struct file_operations fops_tlbflush = {
469 .read = tlbflush_read_file,
470 .write = tlbflush_write_file,
471 .llseek = default_llseek,
472};
473
474static int __cpuinit create_tlb_flushall_shift(void)
475{
476 if (cpu_has_invlpg) {
477 debugfs_create_file("tlb_flushall_shift", S_IRUSR | S_IWUSR,
478 arch_debugfs_dir, NULL, &fops_tlbflush);
479 }
480 return 0;
481}
482late_initcall(create_tlb_flushall_shift);
483#endif