On Tue, 2019-08-13 at 11:25 -0700, Paul Walmsley wrote: > Hi Atish, > > On Fri, 9 Aug 2019, Atish Patra wrote: > > > In RISC-V, tlb flush happens via SBI which is expensive. > > If the target cpumask contains a local hartid, some cost > > can be saved by issuing a local tlb flush as we do that > > in OpenSBI anyways. > > > > Signed-off-by: Atish Patra <atish.pa...@wdc.com> > > A few brief comments/questions beyond the ones that others have > mentioned: > > 1. At some point, some RISC-V systems may implement this SBI call in > hardware, rather than in software. Then this might wind up becoming > a > de-optimization. I don't think there's anything to do about that in > code > right now, but it might be worth adding a comment, and thinking about > how > that case might be handled in the platform specification group.
I am fine with adding a comment. But I did not understand why this would be deoptimization. I not exactly sure about the syntax of future TLB flush instructions. But if we have a hardware instruction for remote tlb flushing, it should be executed only for the harts other than current hart. Right ? > 2. If this patch masks or reduces the likelihood of hitting the > TLB-related crashes that we're seeing, we probably will want to hold > off > on merging this one until we're relatively certain that those other > problems have been fixed. > Yeah sure. I don't see any stress-ng error but still chasing down the glibc error. Regards, Atish > > > > --- > > arch/riscv/include/asm/tlbflush.h | 33 > > +++++++++++++++++++++++++++---- > > 1 file changed, 29 insertions(+), 4 deletions(-) > > > > diff --git a/arch/riscv/include/asm/tlbflush.h > > b/arch/riscv/include/asm/tlbflush.h > > index 687dd19735a7..b32ba4fa5888 100644 > > --- a/arch/riscv/include/asm/tlbflush.h > > +++ b/arch/riscv/include/asm/tlbflush.h > > @@ -8,6 +8,7 @@ > > #define _ASM_RISCV_TLBFLUSH_H > > > > #include <linux/mm_types.h> > > +#include <linux/sched.h> > > #include <asm/smp.h> > > > > /* > > @@ -46,14 +47,38 @@ static inline void remote_sfence_vma(struct > > cpumask *cmask, unsigned long start, > > unsigned long size) > > { > > struct cpumask hmask; > > + struct cpumask tmask; > > + int cpuid = smp_processor_id(); > > > > cpumask_clear(&hmask); > > - riscv_cpuid_to_hartid_mask(cmask, &hmask); > > - sbi_remote_sfence_vma(hmask.bits, start, size); > > + cpumask_clear(&tmask); > > + > > + if (cmask) > > + cpumask_copy(&tmask, cmask); > > + else > > + cpumask_copy(&tmask, cpu_online_mask); > > + > > + if (cpumask_test_cpu(cpuid, &tmask)) { > > + /* Save trap cost by issuing a local tlb flush here */ > > + if ((start == 0 && size == -1) || (size > PAGE_SIZE)) > > + local_flush_tlb_all(); > > + else if (size == PAGE_SIZE) > > + local_flush_tlb_page(start); > > + cpumask_clear_cpu(cpuid, &tmask); > > + } else if (cpumask_empty(&tmask)) { > > + /* cpumask is empty. So just do a local flush */ > > + local_flush_tlb_all(); > > + return; > > + } > > + > > + if (!cpumask_empty(&tmask)) { > > + riscv_cpuid_to_hartid_mask(&tmask, &hmask); > > + sbi_remote_sfence_vma(hmask.bits, start, size); > > + } > > } > > > > -#define flush_tlb_all() sbi_remote_sfence_vma(NULL, 0, -1) > > -#define flush_tlb_page(vma, addr) flush_tlb_range(vma, addr, 0) > > +#define flush_tlb_all() remote_sfence_vma(NULL, 0, -1) > > +#define flush_tlb_page(vma, addr) flush_tlb_range(vma, addr, > > (addr) + PAGE_SIZE) > > #define flush_tlb_range(vma, start, end) \ > > remote_sfence_vma(mm_cpumask((vma)->vm_mm), start, (end) - > > (start)) > > #define flush_tlb_mm(mm) \ > > -- > > 2.21.0 > > > > > > - Paul