On Thu, Apr 12, 2018 at 10:36:21AM +0100, Matt Redfearn wrote: > Processors implementing the MIPS MT ASE may have performance counters > implemented per core or per TC. Processors implemented by MIPS > Technologies signify presence per TC through a bit in the implementation > specific Config7 register. Currently the code which probes for their > presence blindly reads a magic number corresponding to this bit, despite > it potentially having a different meaning in the CPU implementation. > > The test of Config7.PTC was previously enabled when CONFIG_BMIPS5000 was > enabled. However, according to [florian], the BMIPS5000 manual does not > define this bit, so we can assume it is 0 and the feature is not > supported. > > Introduce probe_mipsmt_pertccounters() to probe for the presence of per > TC counters. This detects the ases implemented in the CPU, and reads any > implementation specific bit flagging their presence. In the case of MIPS > implementations, this bit is Config7.PTC. A definition of this bit is > added in mipsregs.h for MIPS Technologies. No other implementations > support this feature. > > Signed-off-by: Matt Redfearn <matt.redfearn@xxxxxxxx> > --- > > Changes in v2: None > > arch/mips/include/asm/mipsregs.h | 5 +++++ > arch/mips/kernel/perf_event_mipsxx.c | 29 ++++++++++++++++++++++++++++- > 2 files changed, 33 insertions(+), 1 deletion(-) > > diff --git a/arch/mips/include/asm/mipsregs.h b/arch/mips/include/asm/mipsregs.h > index 858752dac337..a4baaaa02bc8 100644 > --- a/arch/mips/include/asm/mipsregs.h > +++ b/arch/mips/include/asm/mipsregs.h > @@ -684,6 +684,11 @@ > #define MIPS_CONF7_IAR (_ULCAST_(1) << 10) > #define MIPS_CONF7_AR (_ULCAST_(1) << 16) > > +/* Config7 Bits specific to MIPS Technologies. */ > + > +/* Performance counters implemented Per TC */ > +#define MTI_CONF7_PTC (_ULCAST_(1) << 19) > + > /* WatchLo* register definitions */ > #define MIPS_WATCHLO_IRW (_ULCAST_(0x7) << 0) > > diff --git a/arch/mips/kernel/perf_event_mipsxx.c b/arch/mips/kernel/perf_event_mipsxx.c > index 6668f67a61c3..f3ec4a36921d 100644 > --- a/arch/mips/kernel/perf_event_mipsxx.c > +++ b/arch/mips/kernel/perf_event_mipsxx.c > @@ -1708,6 +1708,33 @@ static const struct mips_perf_event *xlp_pmu_map_raw_event(u64 config) > return &raw_event; > } > > +#ifdef CONFIG_MIPS_PERF_SHARED_TC_COUNTERS > +/* > + * The MIPS MT ASE specifies that performance counters may be implemented > + * per core or per TC. If implemented per TC then all Linux CPUs have their > + * own unique counters. If implemented per core, then VPEs in the core must > + * treat the counters as a shared resource. > + * Probe for the presence of per-TC counters > + */ > +static int probe_mipsmt_pertccounters(void) > +{ > + struct cpuinfo_mips *c = ¤t_cpu_data; > + > + /* Non-MT cores by definition cannot implement per-TC counters */ > + if (!cpu_has_mipsmt) > + return 0; > + > + switch (c->processor_id & PRID_COMP_MASK) { > + case PRID_COMP_MIPS: > + /* MTI implementations use CONFIG7.PTC to signify presence */ > + return read_c0_config7() & MTI_CONF7_PTC; > + default: > + break; > + } > + return 0; > +} > +#endif /* CONFIG_MIPS_PERF_SHARED_TC_COUNTERS */ > + > static int __init > init_hw_perf_events(void) > { > @@ -1723,7 +1750,7 @@ init_hw_perf_events(void) > } > > #ifdef CONFIG_MIPS_PERF_SHARED_TC_COUNTERS > - cpu_has_mipsmt_pertccounters = read_c0_config7() & (1<<19); > + cpu_has_mipsmt_pertccounters = probe_mipsmt_pertccounters(); Similar code also exists in arch/mips/oprofile/op_model_mipsxx.c. Perhaps it is time to unify it into more standard places, i.e. asm/cpu-features.h and cpu-probe.c. Cheers James
Attachment:
signature.asc
Description: Digital signature