Hi, On Tue, Jan 26, 2016 at 09:26:23PM +0800, Huacai Chen wrote: > Loongson-3 maintains cache coherency by hardware. So we introduce a cpu > feature named cpu_has_coherent_cache and use it to modify MIPS's cache > flushing functions. This is rather ambiguous (the phrase "cache coherency" can be associated with dcache coherency between cores). Are you saying that the icache is coherent with the dcache, such that writes to dcache are immediately visible to instruction fetches on all CPUs in the system without any icache flushing? If so, I think that needs clarifying, e.g. cpu_has_coherent_icache. Perhaps it should be a flag of icache along with MIPS_CACHE_IC_F_DC too which is already intended to avoid the dcache flushes, but not necessary the icache flushes. Cheers James > > Signed-off-by: Huacai Chen <chenhc@xxxxxxxxxx> > --- > arch/mips/include/asm/cpu-features.h | 3 +++ > arch/mips/include/asm/cpu.h | 1 + > .../asm/mach-loongson64/cpu-feature-overrides.h | 1 + > arch/mips/mm/c-r4k.c | 21 +++++++++++++++++++++ > 4 files changed, 26 insertions(+) > > diff --git a/arch/mips/include/asm/cpu-features.h b/arch/mips/include/asm/cpu-features.h > index e0ba50a..1ec3dea 100644 > --- a/arch/mips/include/asm/cpu-features.h > +++ b/arch/mips/include/asm/cpu-features.h > @@ -148,6 +148,9 @@ > #ifndef cpu_has_xpa > #define cpu_has_xpa (cpu_data[0].options & MIPS_CPU_XPA) > #endif > +#ifndef cpu_has_coherent_cache > +#define cpu_has_coherent_cache (cpu_data[0].options & MIPS_CPU_CACHE_COHERENT) > +#endif > #ifndef cpu_has_vtag_icache > #define cpu_has_vtag_icache (cpu_data[0].icache.flags & MIPS_CACHE_VTAG) > #endif > diff --git a/arch/mips/include/asm/cpu.h b/arch/mips/include/asm/cpu.h > index 5f50551..28471f0 100644 > --- a/arch/mips/include/asm/cpu.h > +++ b/arch/mips/include/asm/cpu.h > @@ -391,6 +391,7 @@ enum cpu_type_enum { > #define MIPS_CPU_NAN_LEGACY 0x40000000000ull /* Legacy NaN implemented */ > #define MIPS_CPU_NAN_2008 0x80000000000ull /* 2008 NaN implemented */ > #define MIPS_CPU_LDPTE 0x100000000000ull /* CPU has ldpte/lddir instructions */ > +#define MIPS_CPU_CACHE_COHERENT 0x200000000000ull /* CPU maintains cache coherency by hardware */ > > /* > * CPU ASE encodings > diff --git a/arch/mips/include/asm/mach-loongson64/cpu-feature-overrides.h b/arch/mips/include/asm/mach-loongson64/cpu-feature-overrides.h > index c3406db..647d952 100644 > --- a/arch/mips/include/asm/mach-loongson64/cpu-feature-overrides.h > +++ b/arch/mips/include/asm/mach-loongson64/cpu-feature-overrides.h > @@ -46,6 +46,7 @@ > #define cpu_has_local_ebase 0 > > #define cpu_has_wsbh IS_ENABLED(CONFIG_CPU_LOONGSON3) > +#define cpu_has_coherent_cache IS_ENABLED(CONFIG_CPU_LOONGSON3) > #define cpu_hwrena_impl_bits 0xc0000000 > > #endif /* __ASM_MACH_LOONGSON64_CPU_FEATURE_OVERRIDES_H */ > diff --git a/arch/mips/mm/c-r4k.c b/arch/mips/mm/c-r4k.c > index 2abc73d..65fb28c 100644 > --- a/arch/mips/mm/c-r4k.c > +++ b/arch/mips/mm/c-r4k.c > @@ -429,6 +429,9 @@ static void r4k_blast_scache_setup(void) > > static inline void local_r4k___flush_cache_all(void * args) > { > + if (cpu_has_coherent_cache) > + return; > + > switch (current_cpu_type()) { > case CPU_LOONGSON2: > case CPU_LOONGSON3: > @@ -457,6 +460,9 @@ static inline void local_r4k___flush_cache_all(void * args) > > static void r4k___flush_cache_all(void) > { > + if (cpu_has_coherent_cache) > + return; > + > r4k_on_each_cpu(local_r4k___flush_cache_all, NULL); > } > > @@ -503,6 +509,9 @@ static void r4k_flush_cache_range(struct vm_area_struct *vma, > { > int exec = vma->vm_flags & VM_EXEC; > > + if (cpu_has_coherent_cache) > + return; > + > if (cpu_has_dc_aliases || (exec && !cpu_has_ic_fills_f_dc)) > r4k_on_each_cpu(local_r4k_flush_cache_range, vma); > } > @@ -627,6 +636,9 @@ static void r4k_flush_cache_page(struct vm_area_struct *vma, > { > struct flush_cache_page_args args; > > + if (cpu_has_coherent_cache) > + return; > + > args.vma = vma; > args.addr = addr; > args.pfn = pfn; > @@ -636,11 +648,17 @@ static void r4k_flush_cache_page(struct vm_area_struct *vma, > > static inline void local_r4k_flush_data_cache_page(void * addr) > { > + if (cpu_has_coherent_cache) > + return; > + > r4k_blast_dcache_page((unsigned long) addr); > } > > static void r4k_flush_data_cache_page(unsigned long addr) > { > + if (cpu_has_coherent_cache) > + return; > + > if (in_atomic()) > local_r4k_flush_data_cache_page((void *)addr); > else > @@ -825,6 +843,9 @@ static void local_r4k_flush_cache_sigtramp(void * arg) > > static void r4k_flush_cache_sigtramp(unsigned long addr) > { > + if (cpu_has_coherent_cache) > + return; > + > r4k_on_each_cpu(local_r4k_flush_cache_sigtramp, (void *) addr); > } > > -- > 2.4.6 > > > > >
Attachment:
signature.asc
Description: Digital signature