svn commit: r345326 - stable/11/sys/dev/hwpmc
Konstantin Belousov
kib at FreeBSD.org
Wed Mar 20 13:13:51 UTC 2019
Author: kib
Date: Wed Mar 20 13:13:50 2019
New Revision: 345326
URL: https://svnweb.freebsd.org/changeset/base/345326
Log:
MFC r345078:
hwpmc/core: Adopt to upcoming Skylake TSX errata.
Modified:
stable/11/sys/dev/hwpmc/hwpmc_core.c
Directory Properties:
stable/11/ (props changed)
Modified: stable/11/sys/dev/hwpmc/hwpmc_core.c
==============================================================================
--- stable/11/sys/dev/hwpmc/hwpmc_core.c Wed Mar 20 13:10:47 2019 (r345325)
+++ stable/11/sys/dev/hwpmc/hwpmc_core.c Wed Mar 20 13:13:50 2019 (r345326)
@@ -35,6 +35,7 @@ __FBSDID("$FreeBSD$");
#include <sys/bus.h>
#include <sys/pmc.h>
#include <sys/pmckern.h>
+#include <sys/smp.h>
#include <sys/systm.h>
#include <machine/intr_machdep.h>
@@ -101,6 +102,9 @@ static int core_iap_width;
static int core_iap_npmc;
static int core_iap_wroffset;
+static u_int pmc_alloc_refs;
+static bool pmc_tsx_force_abort_set;
+
static int
core_pcpu_noop(struct pmc_mdep *md, int cpu)
{
@@ -214,6 +218,15 @@ iaf_reload_count_to_perfctr_value(pmc_value_t rlc)
return (1ULL << core_iaf_width) - rlc;
}
+static void
+tweak_tsx_force_abort(void *arg)
+{
+ u_int val;
+
+ val = (uintptr_t)arg;
+ wrmsr(MSR_TSX_FORCE_ABORT, val);
+}
+
static int
iaf_allocate_pmc(int cpu, int ri, struct pmc *pm,
const struct pmc_op_pmcallocate *a)
@@ -246,6 +259,13 @@ iaf_allocate_pmc(int cpu, int ri, struct pmc *pm,
if (ev == PMC_EV_IAF_CPU_CLK_UNHALTED_REF && ri != 2)
return (EINVAL);
+ pmc_alloc_refs++;
+ if ((cpu_stdext_feature3 & CPUID_STDEXT3_TSXFA) != 0 &&
+ !pmc_tsx_force_abort_set) {
+ pmc_tsx_force_abort_set = true;
+ smp_rendezvous(NULL, tweak_tsx_force_abort, NULL, (void *)1);
+ }
+
flags = a->pm_md.pm_iaf.pm_iaf_flags;
validflags = IAF_MASK;
@@ -381,6 +401,12 @@ iaf_release_pmc(int cpu, int ri, struct pmc *pmc)
KASSERT(core_pcpu[cpu]->pc_corepmcs[ri + core_iaf_ri].phw_pmc == NULL,
("[core,%d] PHW pmc non-NULL", __LINE__));
+
+ MPASS(pmc_alloc_refs > 0);
+ if (pmc_alloc_refs-- == 1 && pmc_tsx_force_abort_set) {
+ pmc_tsx_force_abort_set = false;
+ smp_rendezvous(NULL, tweak_tsx_force_abort, NULL, (void *)0);
+ }
return (0);
}
More information about the svn-src-stable
mailing list