ARCv2: mm: TLB Miss optim: SMP builds can cache pgd pointer in mmu scratch reg
authorVineet Gupta <vgupta@synopsys.com>
Thu, 13 Nov 2014 13:57:24 +0000 (19:27 +0530)
committerVineet Gupta <vgupta@synopsys.com>
Mon, 28 Oct 2019 19:12:31 +0000 (12:12 -0700)
ARC700 exception (and intr handling) didn't have auto stack switching
thus had to rely on stashing a reg temporarily (to free it up) at a
known place in memory, allowing to code up the low level stack switching.
This however was not re-entrant in SMP which thus had to repurpose the
per-cpu MMU SCRATCH DATA register otherwise used to "cache" the task pdg
pointer (vs. reading it from mm struct)

The newer HS cores do have auto-stack switching and thus even SMP builds
can use the MMU SCRATCH reg as originally intended.

This patch fixes the restriction to ARC700 SMP builds only

Signed-off-by: Vineet Gupta <vgupta@synopsys.com>
arch/arc/include/asm/entry-compact.h
arch/arc/include/asm/mmu.h
arch/arc/include/asm/mmu_context.h
arch/arc/include/asm/pgtable.h
arch/arc/mm/tlb.c
arch/arc/mm/tlbex.S

index 66a2923..c3aa775 100644 (file)
  * to be saved again on kernel mode stack, as part of pt_regs.
  *-------------------------------------------------------------*/
 .macro PROLOG_FREEUP_REG       reg, mem
-#ifdef CONFIG_SMP
+#ifndef ARC_USE_SCRATCH_REG
        sr  \reg, [ARC_REG_SCRATCH_DATA0]
 #else
        st  \reg, [\mem]
 .endm
 
 .macro PROLOG_RESTORE_REG      reg, mem
-#ifdef CONFIG_SMP
+#ifndef ARC_USE_SCRATCH_REG
        lr  \reg, [ARC_REG_SCRATCH_DATA0]
 #else
        ld  \reg, [\mem]
index 98cadf1..0abacb8 100644 (file)
 #define ARC_REG_SCRATCH_DATA0  0x46c
 #endif
 
+#if defined(CONFIG_ISA_ARCV2) || !defined(CONFIG_SMP)
+#define        ARC_USE_SCRATCH_REG
+#endif
+
 /* Bits in MMU PID register */
 #define __TLB_ENABLE           (1 << 31)
 #define __PROG_ENABLE          (1 << 30)
index 0354708..3a5e6a5 100644 (file)
@@ -144,7 +144,7 @@ static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next,
         */
        cpumask_set_cpu(cpu, mm_cpumask(next));
 
-#ifndef CONFIG_SMP
+#ifdef ARC_USE_SCRATCH_REG
        /* PGD cached in MMU reg to avoid 3 mem lookups: task->mm->pgd */
        write_aux_reg(ARC_REG_SCRATCH_DATA0, next->pgd);
 #endif
index 7addd03..ea14a8b 100644 (file)
@@ -351,7 +351,7 @@ static inline void set_pte_at(struct mm_struct *mm, unsigned long addr,
  * Thus use this macro only when you are certain that "current" is current
  * e.g. when dealing with signal frame setup code etc
  */
-#ifndef CONFIG_SMP
+#ifdef ARC_USE_SCRATCH_REG
 #define pgd_offset_fast(mm, addr)      \
 ({                                     \
        pgd_t *pgd_base = (pgd_t *) read_aux_reg(ARC_REG_SCRATCH_DATA0);  \
index 10025e1..417f05a 100644 (file)
@@ -868,7 +868,7 @@ void arc_mmu_init(void)
        write_aux_reg(ARC_REG_PID, MMU_ENABLE);
 
        /* In smp we use this reg for interrupt 1 scratch */
-#ifndef CONFIG_SMP
+#ifdef ARC_USE_SCRATCH_REG
        /* swapper_pg_dir is the pgd for the kernel, used by vmalloc */
        write_aux_reg(ARC_REG_SCRATCH_DATA0, swapper_pg_dir);
 #endif
index c55d95d..d6fbded 100644 (file)
@@ -193,7 +193,7 @@ ex_saved_reg1:
 
        lr  r2, [efa]
 
-#ifndef CONFIG_SMP
+#ifdef ARC_USE_SCRATCH_REG
        lr  r1, [ARC_REG_SCRATCH_DATA0] ; current pgd
 #else
        GET_CURR_TASK_ON_CPU  r1