diff options
author | Paul Walmsley <paul.walmsley@sifive.com> | 2019-11-23 03:58:32 +0100 |
---|---|---|
committer | Paul Walmsley <paul.walmsley@sifive.com> | 2019-11-23 03:58:32 +0100 |
commit | e8cad25b7e8ac8a1ecd7d7243cbea9cfa7049bee (patch) | |
tree | fd9261b2ee8c1e7a2ea509f8042f76eafb39210c /arch/riscv | |
parent | Merge branch 'next/isa-string' into for-next (diff) | |
parent | RISC-V: Issue a tlb page flush if possible (diff) | |
download | linux-e8cad25b7e8ac8a1ecd7d7243cbea9cfa7049bee.tar.xz linux-e8cad25b7e8ac8a1ecd7d7243cbea9cfa7049bee.zip |
Merge branch 'next/tlb-opt' into for-next
Diffstat (limited to 'arch/riscv')
-rw-r--r-- | arch/riscv/mm/tlbflush.c | 25 |
1 files changed, 23 insertions, 2 deletions
diff --git a/arch/riscv/mm/tlbflush.c b/arch/riscv/mm/tlbflush.c index 24cd33d2c48f..720b443c4528 100644 --- a/arch/riscv/mm/tlbflush.c +++ b/arch/riscv/mm/tlbflush.c @@ -2,6 +2,7 @@ #include <linux/mm.h> #include <linux/smp.h> +#include <linux/sched.h> #include <asm/sbi.h> void flush_tlb_all(void) @@ -9,13 +10,33 @@ void flush_tlb_all(void) sbi_remote_sfence_vma(NULL, 0, -1); } +/* + * This function must not be called with cmask being null. + * Kernel may panic if cmask is NULL. + */ static void __sbi_tlb_flush_range(struct cpumask *cmask, unsigned long start, unsigned long size) { struct cpumask hmask; + unsigned int cpuid; - riscv_cpuid_to_hartid_mask(cmask, &hmask); - sbi_remote_sfence_vma(hmask.bits, start, size); + if (cpumask_empty(cmask)) + return; + + cpuid = get_cpu(); + + if (cpumask_any_but(cmask, cpuid) >= nr_cpu_ids) { + /* local cpu is the only cpu present in cpumask */ + if (size <= PAGE_SIZE) + local_flush_tlb_page(start); + else + local_flush_tlb_all(); + } else { + riscv_cpuid_to_hartid_mask(cmask, &hmask); + sbi_remote_sfence_vma(cpumask_bits(&hmask), start, size); + } + + put_cpu(); } void flush_tlb_mm(struct mm_struct *mm) |