Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 20 Mar 2019 13:13:50 +0000 (UTC)
From:      Konstantin Belousov <kib@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-11@freebsd.org
Subject:   svn commit: r345326 - stable/11/sys/dev/hwpmc
Message-ID:  <201903201313.x2KDDojj084629@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
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);
 }



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201903201313.x2KDDojj084629>