Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 5 Aug 2010 20:40:13 +0000 (UTC)
From:      "George V. Neville-Neil" <gnn@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-7@freebsd.org
Subject:   svn commit: r210895 - stable/7/sys/dev/hwpmc
Message-ID:  <201008052040.o75KeEiX099948@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: gnn
Date: Thu Aug  5 20:40:13 2010
New Revision: 210895
URL: http://svn.freebsd.org/changeset/base/210895

Log:
  MFC: 210621
  
  Make sure that we clear the correct bits when we turn off
  a PMC.  It was possible that we could have turned a bit on but
  never cleared it.
  
  Extend the calls to rdmsr() to all necessary functions, not
  just those which previously caused a panic.
  
  Pointed out by: jhb@

Modified:
  stable/7/sys/dev/hwpmc/hwpmc_core.c
  stable/7/sys/dev/hwpmc/hwpmc_core.h
Directory Properties:
  stable/7/sys/   (props changed)
  stable/7/sys/cddl/contrib/opensolaris/   (props changed)
  stable/7/sys/contrib/dev/acpica/   (props changed)
  stable/7/sys/contrib/pf/   (props changed)

Modified: stable/7/sys/dev/hwpmc/hwpmc_core.c
==============================================================================
--- stable/7/sys/dev/hwpmc/hwpmc_core.c	Thu Aug  5 20:39:52 2010	(r210894)
+++ stable/7/sys/dev/hwpmc/hwpmc_core.c	Thu Aug  5 20:40:13 2010	(r210895)
@@ -168,13 +168,13 @@ core_pcpu_fini(struct pmc_mdep *md, int 
 	core_ri = md->pmd_classdep[PMC_MDEP_CLASS_INDEX_IAP].pcd_ri;
 
 	for (n = 0; n < npmc; n++) {
-		msr = rdmsr(IAP_EVSEL0 + n);
-		wrmsr(IAP_EVSEL0 + n, msr & ~IAP_EVSEL_MASK);
+		msr = rdmsr(IAP_EVSEL0 + n) & ~IAP_EVSEL_MASK;
+		wrmsr(IAP_EVSEL0 + n, msr);
 	}
 
 	if (core_cputype != PMC_CPU_INTEL_CORE) {
-		msr = rdmsr(IAF_CTRL);
-		wrmsr(IAF_CTRL, msr & ~IAF_CTRL_MASK);
+		msr = rdmsr(IAF_CTRL) & ~IAF_CTRL_MASK;
+		wrmsr(IAF_CTRL, msr);
 		npmc += md->pmd_classdep[PMC_MDEP_CLASS_INDEX_IAF].pcd_num;
 	}
 
@@ -392,13 +392,13 @@ iaf_start_pmc(int cpu, int ri)
 
 	iafc->pc_iafctrl |= pm->pm_md.pm_iaf.pm_iaf_ctrl;
 
- 	msr = rdmsr(IAF_CTRL);
+ 	msr = rdmsr(IAF_CTRL) & ~IAF_CTRL_MASK;
  	wrmsr(IAF_CTRL, msr | (iafc->pc_iafctrl & IAF_CTRL_MASK));
 
 	do {
 		iafc->pc_resync = 0;
 		iafc->pc_globalctrl |= (1ULL << (ri + IAF_OFFSET));
- 		msr = rdmsr(IA_GLOBAL_CTRL);
+ 		msr = rdmsr(IA_GLOBAL_CTRL) & ~IAF_GLOBAL_CTRL_MASK;
  		wrmsr(IA_GLOBAL_CTRL, msr | (iafc->pc_globalctrl & 
  					     IAF_GLOBAL_CTRL_MASK));
 	} while (iafc->pc_resync != 0);
@@ -434,13 +434,13 @@ iaf_stop_pmc(int cpu, int ri)
 	iafc->pc_iafctrl &= ~fc;
 
 	PMCDBG(MDP,STO,1,"iaf-stop iafctrl=%x", iafc->pc_iafctrl);
- 	msr = rdmsr(IAF_CTRL);
+ 	msr = rdmsr(IAF_CTRL) & ~IAF_CTRL_MASK;
  	wrmsr(IAF_CTRL, msr | (iafc->pc_iafctrl & IAF_CTRL_MASK));
 
 	do {
 		iafc->pc_resync = 0;
 		iafc->pc_globalctrl &= ~(1ULL << (ri + IAF_OFFSET));
- 		msr = rdmsr(IA_GLOBAL_CTRL);
+ 		msr = rdmsr(IA_GLOBAL_CTRL) & ~IAF_GLOBAL_CTRL_MASK;
  		wrmsr(IA_GLOBAL_CTRL, msr | (iafc->pc_globalctrl &
  					     IAF_GLOBAL_CTRL_MASK));
 	} while (iafc->pc_resync != 0);
@@ -473,10 +473,14 @@ iaf_write_pmc(int cpu, int ri, pmc_value
 	if (PMC_IS_SAMPLING_MODE(PMC_TO_MODE(pm)))
 		v = iaf_reload_count_to_perfctr_value(v);
 
-	msr = rdmsr(IAF_CTRL);
-	wrmsr(IAF_CTRL, msr & ~IAF_CTRL_MASK);
+	/* Turn off fixed counters */
+	msr = rdmsr(IAF_CTRL) & ~IAF_CTRL_MASK;
+	wrmsr(IAF_CTRL, msr); 
+
 	wrmsr(IAF_CTR0 + ri, v & ((1ULL << core_iaf_width) - 1));
-	msr = rdmsr(IAF_CTRL);
+
+	/* Turn on fixed counters */
+	msr = rdmsr(IAF_CTRL) & ~IAF_CTRL_MASK;
 	wrmsr(IAF_CTRL, msr | (cc->pc_iafctrl & IAF_CTRL_MASK));
 
 	PMCDBG(MDP,WRI,1, "iaf-write cpu=%d ri=%d msr=0x%x v=%jx iafctrl=%jx "
@@ -1910,15 +1914,17 @@ iap_stop_pmc(int cpu, int ri)
 
 	PMCDBG(MDP,STO,1, "iap-stop cpu=%d ri=%d", cpu, ri);
 
-	msr = rdmsr(IAP_EVSEL0 + ri);
-	wrmsr(IAP_EVSEL0 + ri, msr & IAP_EVSEL_MASK);	/* stop hw */
+	msr = rdmsr(IAP_EVSEL0 + ri) & ~IAP_EVSEL_MASK;
+	wrmsr(IAP_EVSEL0 + ri, msr);	/* stop hw */
 
 	if (core_cputype == PMC_CPU_INTEL_CORE)
 		return (0);
 
+	msr = 0;
 	do {
 		cc->pc_resync = 0;
 		cc->pc_globalctrl &= ~(1ULL << ri);
+		msr = rdmsr(IA_GLOBAL_CTRL) & ~IA_GLOBAL_CTRL_MASK;
 		wrmsr(IA_GLOBAL_CTRL, cc->pc_globalctrl);
 	} while (cc->pc_resync != 0);
 
@@ -2004,7 +2010,7 @@ core_intr(int cpu, struct trapframe *tf)
 	struct pmc *pm;
 	struct core_cpu *cc;
 	int error, found_interrupt, ri;
-	uint64_t msr = 0;
+	uint64_t msr;
 
 	PMCDBG(MDP,INT, 1, "cpu=%d tf=0x%p um=%d", cpu, (void *) tf,
 	    TRAPF_USERMODE(tf));
@@ -2036,15 +2042,15 @@ core_intr(int cpu, struct trapframe *tf)
 		 * Stop the counter, reload it but only restart it if
 		 * the PMC is not stalled.
 		 */
-		msr = rdmsr(IAP_EVSEL0 + ri);
-		wrmsr(IAP_EVSEL0 + ri, msr & ~IAP_EVSEL_MASK);
+		msr = rdmsr(IAP_EVSEL0 + ri) & ~IAP_EVSEL_MASK;
+		wrmsr(IAP_EVSEL0 + ri, msr);
 		wrmsr(IAP_PMC0 + ri, v);
 
 		if (error)
 			continue;
 
-		wrmsr(IAP_EVSEL0 + ri,
-		    pm->pm_md.pm_iap.pm_iap_evsel | IAP_EN);
+		wrmsr(IAP_EVSEL0 + ri, msr | (pm->pm_md.pm_iap.pm_iap_evsel | 
+					      IAP_EN));
 	}
 
 	if (found_interrupt)
@@ -2060,7 +2066,7 @@ static int
 core2_intr(int cpu, struct trapframe *tf)
 {
 	int error, found_interrupt, n;
-	uint64_t flag, intrstatus, intrenable;
+	uint64_t flag, intrstatus, intrenable, msr;
 	struct pmc *pm;
 	struct core_cpu *cc;
 	pmc_value_t v;
@@ -2091,7 +2097,8 @@ core2_intr(int cpu, struct trapframe *tf
 	/*
 	 * Stop PMCs and clear overflow status bits.
 	 */
-	wrmsr(IA_GLOBAL_CTRL, 0);
+	msr = rdmsr(IA_GLOBAL_CTRL) & ~IA_GLOBAL_CTRL_MASK;
+	wrmsr(IA_GLOBAL_CTRL, msr);
 	wrmsr(IA_GLOBAL_OVF_CTRL, intrenable |
 	    IA_GLOBAL_STATUS_FLAG_OVFBUF |
 	    IA_GLOBAL_STATUS_FLAG_CONDCHG);
@@ -2162,7 +2169,7 @@ core2_intr(int cpu, struct trapframe *tf
 
 	cc->pc_globalctrl |= intrenable;
 
-	wrmsr(IA_GLOBAL_CTRL, cc->pc_globalctrl);
+	wrmsr(IA_GLOBAL_CTRL, cc->pc_globalctrl & IA_GLOBAL_CTRL_MASK);
 
 	PMCDBG(MDP,INT, 1, "cpu=%d fixedctrl=%jx globalctrl=%jx status=%jx "
 	    "ovf=%jx", cpu, (uintmax_t) rdmsr(IAF_CTRL),

Modified: stable/7/sys/dev/hwpmc/hwpmc_core.h
==============================================================================
--- stable/7/sys/dev/hwpmc/hwpmc_core.h	Thu Aug  5 20:39:52 2010	(r210894)
+++ stable/7/sys/dev/hwpmc/hwpmc_core.h	Thu Aug  5 20:40:13 2010	(r210895)
@@ -144,6 +144,12 @@ struct pmc_md_iap_op_pmcallocate {
 /* The mask is only for the fixed porttion of the register. */
 #define	IAF_GLOBAL_CTRL_MASK			0x0000000700000000
 
+/* The mask is only for the programmable porttion of the register. */
+#define IAP_GLOBAL_CTRL_MASK			0x00000000ffffffff
+
+/* The mask is for both the fixed and programmable porttions of the register. */
+#define IA_GLOBAL_CTRL_MASK			0x00000007ffffffff
+
 #define	IA_GLOBAL_OVF_CTRL			0x390
 
 #define	IA_GLOBAL_STATUS_FLAG_CONDCHG		(1ULL << 63)



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