Skip to content

Commit

Permalink
MIPS: Initialise MAARs on secondary CPUs
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
paulburton authored and nkskjames committed Jan 13, 2016
1 parent b0b6c70 commit 410cb92
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 3 deletions.
9 changes: 9 additions & 0 deletions arch/mips/include/asm/maar.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 2 additions & 0 deletions arch/mips/kernel/smp.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 */

Expand Down Expand Up @@ -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
Expand Down
28 changes: 25 additions & 3 deletions arch/mips/mm/init.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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;
Expand All @@ -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++) {
Expand All @@ -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);
Expand All @@ -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++;
}
}
}

Expand Down

0 comments on commit 410cb92

Please sign in to comment.