summaryrefslogtreecommitdiffstats
path: root/sys/dev/hwpmc
diff options
context:
space:
mode:
authordavide <davide@FreeBSD.org>2013-04-30 15:31:45 +0000
committerdavide <davide@FreeBSD.org>2013-04-30 15:31:45 +0000
commite45f362b6b9f7a79fbc1eece543182e2bab1a561 (patch)
tree2c7e11d0a971e87cfc1482611ede9e0e624a6104 /sys/dev/hwpmc
parent51cb2d085ac71a290ad7c3ce0247bf9539f42349 (diff)
downloadFreeBSD-src-e45f362b6b9f7a79fbc1eece543182e2bab1a561.zip
FreeBSD-src-e45f362b6b9f7a79fbc1eece543182e2bab1a561.tar.gz
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
Diffstat (limited to 'sys/dev/hwpmc')
-rw-r--r--sys/dev/hwpmc/hwpmc_core.c51
-rw-r--r--sys/dev/hwpmc/pmc_events.h23
2 files changed, 49 insertions, 25 deletions
diff --git a/sys/dev/hwpmc/hwpmc_core.c b/sys/dev/hwpmc/hwpmc_core.c
index 287a652..1f0b784 100644
--- a/sys/dev/hwpmc/hwpmc_core.c
+++ b/sys/dev/hwpmc/hwpmc_core.c
@@ -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 pmc *pm,
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
diff --git a/sys/dev/hwpmc/pmc_events.h b/sys/dev/hwpmc/pmc_events.h
index 8d664f5..b8c97c6 100644
--- a/sys/dev/hwpmc/pmc_events.h
+++ b/sys/dev/hwpmc/pmc_events.h
@@ -468,6 +468,13 @@ __PMC_EV_ALIAS("unhalted-reference-cycles", IAF_CPU_CLK_UNHALTED_REF)
* 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.
OpenPOWER on IntegriCloud