ARCv2: mm: TLB Miss optim: SMP builds can cache pgd pointer in mmu scratch reg

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>
This commit is contained in:
Vineet Gupta 2014-11-13 19:27:24 +05:30
parent 7b491c0b62
commit cfd9d70a85
6 changed files with 10 additions and 6 deletions

View File

@ -130,7 +130,7 @@
* to be saved again on kernel mode stack, as part of pt_regs. * to be saved again on kernel mode stack, as part of pt_regs.
*-------------------------------------------------------------*/ *-------------------------------------------------------------*/
.macro PROLOG_FREEUP_REG reg, mem .macro PROLOG_FREEUP_REG reg, mem
#ifdef CONFIG_SMP #ifndef ARC_USE_SCRATCH_REG
sr \reg, [ARC_REG_SCRATCH_DATA0] sr \reg, [ARC_REG_SCRATCH_DATA0]
#else #else
st \reg, [\mem] st \reg, [\mem]
@ -138,7 +138,7 @@
.endm .endm
.macro PROLOG_RESTORE_REG reg, mem .macro PROLOG_RESTORE_REG reg, mem
#ifdef CONFIG_SMP #ifndef ARC_USE_SCRATCH_REG
lr \reg, [ARC_REG_SCRATCH_DATA0] lr \reg, [ARC_REG_SCRATCH_DATA0]
#else #else
ld \reg, [\mem] ld \reg, [\mem]

View File

@ -40,6 +40,10 @@
#define ARC_REG_SCRATCH_DATA0 0x46c #define ARC_REG_SCRATCH_DATA0 0x46c
#endif #endif
#if defined(CONFIG_ISA_ARCV2) || !defined(CONFIG_SMP)
#define ARC_USE_SCRATCH_REG
#endif
/* Bits in MMU PID register */ /* Bits in MMU PID register */
#define __TLB_ENABLE (1 << 31) #define __TLB_ENABLE (1 << 31)
#define __PROG_ENABLE (1 << 30) #define __PROG_ENABLE (1 << 30)

View 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)); 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 */ /* PGD cached in MMU reg to avoid 3 mem lookups: task->mm->pgd */
write_aux_reg(ARC_REG_SCRATCH_DATA0, next->pgd); write_aux_reg(ARC_REG_SCRATCH_DATA0, next->pgd);
#endif #endif

View 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 * Thus use this macro only when you are certain that "current" is current
* e.g. when dealing with signal frame setup code etc * e.g. when dealing with signal frame setup code etc
*/ */
#ifndef CONFIG_SMP #ifdef ARC_USE_SCRATCH_REG
#define pgd_offset_fast(mm, addr) \ #define pgd_offset_fast(mm, addr) \
({ \ ({ \
pgd_t *pgd_base = (pgd_t *) read_aux_reg(ARC_REG_SCRATCH_DATA0); \ pgd_t *pgd_base = (pgd_t *) read_aux_reg(ARC_REG_SCRATCH_DATA0); \

View File

@ -868,7 +868,7 @@ void arc_mmu_init(void)
write_aux_reg(ARC_REG_PID, MMU_ENABLE); write_aux_reg(ARC_REG_PID, MMU_ENABLE);
/* In smp we use this reg for interrupt 1 scratch */ /* 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 */ /* swapper_pg_dir is the pgd for the kernel, used by vmalloc */
write_aux_reg(ARC_REG_SCRATCH_DATA0, swapper_pg_dir); write_aux_reg(ARC_REG_SCRATCH_DATA0, swapper_pg_dir);
#endif #endif

View File

@ -193,7 +193,7 @@ ex_saved_reg1:
lr r2, [efa] lr r2, [efa]
#ifndef CONFIG_SMP #ifdef ARC_USE_SCRATCH_REG
lr r1, [ARC_REG_SCRATCH_DATA0] ; current pgd lr r1, [ARC_REG_SCRATCH_DATA0] ; current pgd
#else #else
GET_CURR_TASK_ON_CPU r1 GET_CURR_TASK_ON_CPU r1