svn commit: r250103 - head/sys/dev/hwpmc

Davide Italiano davide at FreeBSD.org
Tue Apr 30 15:31:46 UTC 2013


Author: davide
Date: Tue Apr 30 15:31:45 2013
New Revision: 250103
URL: http://svnweb.freebsd.org/changeset/base/250103

Log:
  The Intel PMC architectural events have encodings which are identical to
  those of some non-architectural core events. This is not a problem in the
  general case as long as there's an 1:1 mapping between the two, but there
  are few exceptions. For example, 3CH_01H on Nehalem/Westmere represents
  both unhalted-reference-cycles and CPU_CLK_UNHALTED.REF_P.
  CPU_CLK_UNHALTED.REF_P on the aforementioned architectures does not measure
  reference (i.e. bus) but TSC, so there's the need to disambiguate.
  In order to avoid the namespace collision rename all the architectural
  events in a way they cannot be ambigous and refactor the architectural
  events handling function to reflect this change.
  While here, per Jim Harris request, rename
  iap_architectural_event_is_unsupported() to iap_event_is_architectural().
  
  Discussed with:	jimharris
  Reviewed by:	jimharris, gnn

Modified:
  head/sys/dev/hwpmc/hwpmc_core.c
  head/sys/dev/hwpmc/pmc_events.h

Modified: head/sys/dev/hwpmc/hwpmc_core.c
==============================================================================
--- head/sys/dev/hwpmc/hwpmc_core.c	Tue Apr 30 15:06:30 2013	(r250102)
+++ head/sys/dev/hwpmc/hwpmc_core.c	Tue Apr 30 15:31:45 2013	(r250103)
@@ -60,6 +60,10 @@ __FBSDID("$FreeBSD$");
     PMC_CAP_EDGE | PMC_CAP_THRESHOLD | PMC_CAP_READ | PMC_CAP_WRITE |	 \
     PMC_CAP_INVERT | PMC_CAP_QUALIFIER | PMC_CAP_PRECISE)
 
+#define	EV_IS_NOTARCH		0
+#define	EV_IS_ARCH_SUPP		1
+#define	EV_IS_ARCH_NOTSUPP	-1
+
 /*
  * "Architectural" events defined by Intel.  The values of these
  * symbols correspond to positions in the bitmask returned by
@@ -1723,43 +1727,53 @@ iap_pmc_has_overflowed(int ri)
 /*
  * Check an event against the set of supported architectural events.
  *
- * Returns 1 if the event is architectural and unsupported on this
- * CPU.  Returns 0 otherwise.
+ * If the event is not architectural EV_IS_NOTARCH is returned.
+ * If the event is architectural and supported on this CPU, the correct
+ * event+umask mapping is returned in map, and EV_IS_ARCH_SUPP is returned.
+ * Otherwise, the function returns EV_IS_ARCH_NOTSUPP.
  */
 
 static int
-iap_architectural_event_is_unsupported(enum pmc_event pe)
+iap_is_event_architectural(enum pmc_event pe, enum pmc_event *map)
 {
 	enum core_arch_events ae;
 
 	switch (pe) {
-	case PMC_EV_IAP_EVENT_3CH_00H:
+	case PMC_EV_IAP_ARCH_UNH_COR_CYC:
 		ae = CORE_AE_UNHALTED_CORE_CYCLES;
+		*map = PMC_EV_IAP_EVENT_C4H_00H;
 		break;
-	case PMC_EV_IAP_EVENT_C0H_00H:
+	case PMC_EV_IAP_ARCH_INS_RET:
 		ae = CORE_AE_INSTRUCTION_RETIRED;
+		*map = PMC_EV_IAP_EVENT_C0H_00H;
 		break;
-	case PMC_EV_IAP_EVENT_3CH_01H:
+	case PMC_EV_IAP_ARCH_UNH_REF_CYC:
 		ae = CORE_AE_UNHALTED_REFERENCE_CYCLES;
+		*map = PMC_EV_IAP_EVENT_3CH_01H;
 		break;
-	case PMC_EV_IAP_EVENT_2EH_4FH:
+	case PMC_EV_IAP_ARCH_LLC_REF:
 		ae = CORE_AE_LLC_REFERENCE;
+		*map = PMC_EV_IAP_EVENT_2EH_4FH;
 		break;
-	case PMC_EV_IAP_EVENT_2EH_41H:
+	case PMC_EV_IAP_ARCH_LLC_MIS:
 		ae = CORE_AE_LLC_MISSES;
+		*map = PMC_EV_IAP_EVENT_2EH_41H;
 		break;
-	case PMC_EV_IAP_EVENT_C4H_00H:
+	case PMC_EV_IAP_ARCH_BR_INS_RET:
 		ae = CORE_AE_BRANCH_INSTRUCTION_RETIRED;
+		*map = PMC_EV_IAP_EVENT_C4H_00H;
 		break;
-	case PMC_EV_IAP_EVENT_C5H_00H:
+	case PMC_EV_IAP_ARCH_BR_MIS_RET:
 		ae = CORE_AE_BRANCH_MISSES_RETIRED;
+		*map = PMC_EV_IAP_EVENT_C5H_00H;
 		break;
 
 	default:	/* Non architectural event. */
-		return (0);
+		return (EV_IS_NOTARCH);
 	}
 
-	return ((core_architectural_events & (1 << ae)) == 0);
+	return (((core_architectural_events & (1 << ae)) == 0) ? 
+	    EV_IS_ARCH_NOTSUPP : EV_IS_ARCH_SUPP);
 }
 
 static int
@@ -1917,8 +1931,8 @@ static int
 iap_allocate_pmc(int cpu, int ri, struct pmc *pm,
     const struct pmc_op_pmcallocate *a)
 {
-	int n, model;
-	enum pmc_event ev;
+	int arch, n, model;
+	enum pmc_event ev, map;
 	struct iap_event_descr *ie;
 	uint32_t c, caps, config, cpuflag, evsel, mask;
 
@@ -1932,10 +1946,13 @@ iap_allocate_pmc(int cpu, int ri, struct
 	if ((IAP_PMC_CAPS & caps) != caps)
 		return (EPERM);
 
-	ev = pm->pm_event;
-
-	if (iap_architectural_event_is_unsupported(ev))
+	arch = iap_is_event_architectural(pm->pm_event, &map);
+	if (arch == EV_IS_ARCH_NOTSUPP)
 		return (EOPNOTSUPP);
+	else if (arch == EV_IS_ARCH_SUPP)
+		ev = map;
+	else
+		ev = pm->pm_event;
 
 	/*
 	 * A small number of events are not supported in all the

Modified: head/sys/dev/hwpmc/pmc_events.h
==============================================================================
--- head/sys/dev/hwpmc/pmc_events.h	Tue Apr 30 15:06:30 2013	(r250102)
+++ head/sys/dev/hwpmc/pmc_events.h	Tue Apr 30 15:31:45 2013	(r250103)
@@ -468,6 +468,13 @@ __PMC_EV_ALIAS("unhalted-reference-cycle
  * the CPU model happens inside hwpmc(4).
  */
 #define	__PMC_EV_IAP()				\
+__PMC_EV(IAP, ARCH_BR_INS_RET)			\
+__PMC_EV(IAP, ARCH_BR_MIS_RET)			\
+__PMC_EV(IAP, ARCH_INS_RET)			\
+__PMC_EV(IAP, ARCH_LLC_MIS)			\
+__PMC_EV(IAP, ARCH_LLC_REF)			\
+__PMC_EV(IAP, ARCH_UNH_REF_CYC)			\
+__PMC_EV(IAP, ARCH_UNH_COR_CYC)			\
 __PMC_EV(IAP, EVENT_02H_01H)			\
 __PMC_EV(IAP, EVENT_02H_81H)			\
 __PMC_EV(IAP, EVENT_03H_00H)			\
@@ -1157,20 +1164,20 @@ __PMC_EV(IAP, EVENT_FDH_10H)			\
 __PMC_EV(IAP, EVENT_FDH_20H)			\
 __PMC_EV(IAP, EVENT_FDH_40H)
 
-#define	PMC_EV_IAP_FIRST	PMC_EV_IAP_EVENT_02H_01H
+#define	PMC_EV_IAP_FIRST	PMC_EV_IAP_ARCH_BR_INS_RET
 #define	PMC_EV_IAP_LAST		PMC_EV_IAP_EVENT_FDH_40H
 
 /*
  * Map "architectural" event names to event ids.
  */
 #define	__PMC_EV_ALIAS_INTEL_ARCHITECTURAL()				\
-__PMC_EV_ALIAS("branch-instruction-retired",	IAP_EVENT_C4H_00H)	\
-__PMC_EV_ALIAS("branch-misses-retired",		IAP_EVENT_C5H_00H)	\
-__PMC_EV_ALIAS("instruction-retired",		IAP_EVENT_C0H_00H)	\
-__PMC_EV_ALIAS("llc-misses",			IAP_EVENT_2EH_41H)	\
-__PMC_EV_ALIAS("llc-reference",			IAP_EVENT_2EH_4FH)	\
-__PMC_EV_ALIAS("unhalted-reference-cycles",	IAP_EVENT_3CH_01H)	\
-__PMC_EV_ALIAS("unhalted-core-cycles",		IAP_EVENT_3CH_00H)
+__PMC_EV_ALIAS("branch-instruction-retired",	IAP_ARCH_BR_INS_RET)	\
+__PMC_EV_ALIAS("branch-misses-retired",		IAP_ARCH_BR_MIS_RET)	\
+__PMC_EV_ALIAS("instruction-retired",		IAP_ARCH_INS_RET)	\
+__PMC_EV_ALIAS("llc-misses",			IAP_ARCH_LLC_MIS)	\
+__PMC_EV_ALIAS("llc-reference",			IAP_ARCH_LLC_REF)	\
+__PMC_EV_ALIAS("unhalted-reference-cycles",	IAP_ARCH_UNH_REF_CYC)	\
+__PMC_EV_ALIAS("unhalted-core-cycles",		IAP_ARCH_UNH_COR_CYC)
 
 /*
  * Aliases for Atom PMCs.


More information about the svn-src-head mailing list