MIPS: Initialise MAARs on secondary CPUs
MAARs should be initialised on each CPU (or rather, core) in the system in order to achieve consistent behaviour & performance. Previously they have only been initialised on the boot CPU which leads to performance problems if tasks are later scheduled on a secondary CPU, particularly if those tasks make use of unaligned vector accesses where some CPUs don't handle any cases in hardware for non-speculative memory regions. Fix this by recording the MAAR configuration from the boot CPU and applying it to secondary CPUs as part of their bringup. Reported-by: Doug Gilmore <doug.gilmore@imgtec.com> Signed-off-by: Paul Burton <paul.burton@imgtec.com> Cc: linux-mips@linux-mips.org Cc: Rusty Russell <rusty@rustcorp.com.au> Cc: Steven J. Hill <Steven.Hill@imgtec.com> Cc: Andrew Bresticker <abrestic@chromium.org> Cc: Bjorn Helgaas <bhelgaas@google.com> Cc: David Hildenbrand <dahi@linux.vnet.ibm.com> Cc: linux-kernel@vger.kernel.org Cc: Aaro Koskinen <aaro.koskinen@iki.fi> Cc: James Hogan <james.hogan@imgtec.com> Cc: Ingo Molnar <mingo@kernel.org> Cc: Markos Chandras <markos.chandras@imgtec.com> Cc: Hemmo Nieminen <hemmo.nieminen@iki.fi> Cc: Alex Smith <alex.smith@imgtec.com> Cc: Peter Zijlstra (Intel) <peterz@infradead.org> Patchwork: https://patchwork.linux-mips.org/patch/11239/ Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
This commit is contained in:
parent
651ca7f4da
commit
e060f6ed28
3 changed files with 36 additions and 3 deletions
|
@ -65,6 +65,15 @@ static inline void write_maar_pair(unsigned idx, phys_addr_t lower,
|
|||
back_to_back_c0_hazard();
|
||||
}
|
||||
|
||||
/**
|
||||
* maar_init() - initialise MAARs
|
||||
*
|
||||
* Performs initialisation of MAARs for the current CPU, making use of the
|
||||
* platforms implementation of platform_maar_init where necessary and
|
||||
* duplicating the setup it provides on secondary CPUs.
|
||||
*/
|
||||
extern void maar_init(void);
|
||||
|
||||
/**
|
||||
* struct maar_config - MAAR configuration data
|
||||
* @lower: The lowest address that the MAAR pair will affect. Must be
|
||||
|
|
|
@ -42,6 +42,7 @@
|
|||
#include <asm/mmu_context.h>
|
||||
#include <asm/time.h>
|
||||
#include <asm/setup.h>
|
||||
#include <asm/maar.h>
|
||||
|
||||
cpumask_t cpu_callin_map; /* Bitmask of started secondaries */
|
||||
|
||||
|
@ -157,6 +158,7 @@ asmlinkage void start_secondary(void)
|
|||
mips_clockevent_init();
|
||||
mp_ops->init_secondary();
|
||||
cpu_report();
|
||||
maar_init();
|
||||
|
||||
/*
|
||||
* XXX parity protection should be folded in here when it's converted
|
||||
|
|
|
@ -44,6 +44,7 @@
|
|||
#include <asm/pgalloc.h>
|
||||
#include <asm/tlb.h>
|
||||
#include <asm/fixmap.h>
|
||||
#include <asm/maar.h>
|
||||
|
||||
/*
|
||||
* We have up to 8 empty zeroed pages so we can map one of the right colour
|
||||
|
@ -288,10 +289,14 @@ unsigned __weak platform_maar_init(unsigned num_pairs)
|
|||
return num_configured;
|
||||
}
|
||||
|
||||
static void maar_init(void)
|
||||
void maar_init(void)
|
||||
{
|
||||
unsigned num_maars, used, i;
|
||||
phys_addr_t lower, upper, attr;
|
||||
static struct {
|
||||
struct maar_config cfgs[3];
|
||||
unsigned used;
|
||||
} recorded = { { { 0 } }, 0 };
|
||||
|
||||
if (!cpu_has_maar)
|
||||
return;
|
||||
|
@ -304,8 +309,14 @@ static void maar_init(void)
|
|||
/* MAARs should be in pairs */
|
||||
WARN_ON(num_maars % 2);
|
||||
|
||||
/* Configure the required MAARs */
|
||||
used = platform_maar_init(num_maars / 2);
|
||||
/* Set MAARs using values we recorded already */
|
||||
if (recorded.used) {
|
||||
used = maar_config(recorded.cfgs, recorded.used, num_maars / 2);
|
||||
BUG_ON(used != recorded.used);
|
||||
} else {
|
||||
/* Configure the required MAARs */
|
||||
used = platform_maar_init(num_maars / 2);
|
||||
}
|
||||
|
||||
/* Disable any further MAARs */
|
||||
for (i = (used * 2); i < num_maars; i++) {
|
||||
|
@ -315,6 +326,9 @@ static void maar_init(void)
|
|||
back_to_back_c0_hazard();
|
||||
}
|
||||
|
||||
if (recorded.used)
|
||||
return;
|
||||
|
||||
pr_info("MAAR configuration:\n");
|
||||
for (i = 0; i < num_maars; i += 2) {
|
||||
write_c0_maari(i);
|
||||
|
@ -341,6 +355,14 @@ static void maar_init(void)
|
|||
pr_cont(" speculate");
|
||||
|
||||
pr_cont("\n");
|
||||
|
||||
/* Record the setup for use on secondary CPUs */
|
||||
if (used <= ARRAY_SIZE(recorded.cfgs)) {
|
||||
recorded.cfgs[recorded.used].lower = lower;
|
||||
recorded.cfgs[recorded.used].upper = upper;
|
||||
recorded.cfgs[recorded.used].attrs = attr;
|
||||
recorded.used++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue