Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 7 Dec 2009 20:47:33 +0000 (UTC)
From:      Fabien Thomas <fabient@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: r200235 - stable/7/lib/libpmc
Message-ID:  <200912072047.nB7KlXVp065610@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: fabient
Date: Mon Dec  7 20:47:33 2009
New Revision: 200235
URL: http://svn.freebsd.org/changeset/base/200235

Log:
  MFC 198433:
  Not all Intel Core (TM) CPUs implement PMC_CLASS_IAF fixed-function
  counters.  For such CPUs, use an alternate mapping of convenience
  names to events supported by PMC_CLASS_IAP programmable counters.

Modified:
  stable/7/lib/libpmc/libpmc.c
Directory Properties:
  stable/7/lib/libpmc/   (props changed)

Modified: stable/7/lib/libpmc/libpmc.c
==============================================================================
--- stable/7/lib/libpmc/libpmc.c	Mon Dec  7 20:46:22 2009	(r200234)
+++ stable/7/lib/libpmc/libpmc.c	Mon Dec  7 20:47:33 2009	(r200235)
@@ -442,6 +442,10 @@ static struct pmc_event_alias core_alias
 /*
  * Intel Core2 (Family 6, Model F), Core2Extreme (Family 6, Model 17H)
  * and Atom (Family 6, model 1CH) PMCs.
+ *
+ * We map aliases to events on the fixed-function counters if these
+ * are present.  Note that not all CPUs in this family contain fixed-function
+ * counters.
  */
 
 static struct pmc_event_alias core2_aliases[] = {
@@ -454,8 +458,22 @@ static struct pmc_event_alias core2_alia
 	EV_ALIAS("unhalted-cycles",	"iaf-cpu-clk-unhalted.core"),
 	EV_ALIAS(NULL, NULL)
 };
-#define	atom_aliases	core2_aliases
-#define corei7_aliases	core2_aliases
+
+static struct pmc_event_alias core2_aliases_without_iaf[] = {
+	EV_ALIAS("branches",		"iap-br-inst-retired.any"),
+	EV_ALIAS("branch-mispredicts",	"iap-br-inst-retired.mispred"),
+	EV_ALIAS("cycles",		"tsc-tsc"),
+	EV_ALIAS("ic-misses",		"iap-l1i-misses"),
+	EV_ALIAS("instructions",	"iap-inst-retired.any_p"),
+	EV_ALIAS("interrupts",		"iap-hw-int-rcv"),
+	EV_ALIAS("unhalted-cycles",	"iap-cpu-clk-unhalted.core_p"),
+	EV_ALIAS(NULL, NULL)
+};
+
+#define	atom_aliases			core2_aliases
+#define	atom_aliases_without_iaf	core2_aliases_without_iaf
+#define corei7_aliases			core2_aliases
+#define corei7_aliases_without_iaf	core2_aliases_without_iaf
 
 #define	IAF_KW_OS		"os"
 #define	IAF_KW_USR		"usr"
@@ -2379,6 +2397,10 @@ pmc_init(void)
 	uint32_t abi_version;
 	struct module_stat pmc_modstat;
 	struct pmc_op_getcpuinfo op_cpu_info;
+#if defined(__amd64__) || defined(__i386__)
+	int cpu_has_iaf_counters;
+	unsigned int t;
+#endif
 
 	if (pmc_syscall != -1) /* already inited */
 		return (0);
@@ -2420,6 +2442,8 @@ pmc_init(void)
 	if (pmc_class_table == NULL)
 		return (-1);
 
+	for (n = 0; n < PMC_CLASS_TABLE_SIZE; n++)
+		pmc_class_table[n] = NULL;
 
 	/*
 	 * Fill in the class table.
@@ -2427,6 +2451,14 @@ pmc_init(void)
 	n = 0;
 #if defined(__amd64__) || defined(__i386__)
 	pmc_class_table[n++] = &tsc_class_table_descr;
+
+	/*
+ 	 * Check if this CPU has fixed function counters.
+	 */
+	cpu_has_iaf_counters = 0;
+	for (t = 0; t < cpu_info.pm_nclass; t++)
+		if (cpu_info.pm_classes[t].pm_class == PMC_CLASS_IAF)
+			cpu_has_iaf_counters = 1;
 #endif
 
 #define	PMC_MDEP_INIT(C) do {					\
@@ -2436,6 +2468,16 @@ pmc_init(void)
 		    PMC_TABLE_SIZE(C##_pmc_classes);		\
 	} while (0)
 
+#define	PMC_MDEP_INIT_INTEL_V2(C) do {					\
+		PMC_MDEP_INIT(C);					\
+		if (cpu_has_iaf_counters) 				\
+			pmc_class_table[n++] = &iaf_class_table_descr;	\
+		else							\
+			pmc_mdep_event_aliases =			\
+				C##_aliases_without_iaf;		\
+		pmc_class_table[n] = &C##_class_table_descr;		\
+	} while (0)
+
 	/* Configure the event name parser. */
 	switch (cpu_info.pm_cputype) {
 #if defined(__i386__)
@@ -2461,24 +2503,17 @@ pmc_init(void)
 		pmc_class_table[n] = &k8_class_table_descr;
 		break;
 	case PMC_CPU_INTEL_ATOM:
-		PMC_MDEP_INIT(atom);
-		pmc_class_table[n++] = &iaf_class_table_descr;
-		pmc_class_table[n]   = &atom_class_table_descr;
+		PMC_MDEP_INIT_INTEL_V2(atom);
 		break;
 	case PMC_CPU_INTEL_CORE:
 		PMC_MDEP_INIT(core);
-		pmc_class_table[n] = &core_class_table_descr;
 		break;
 	case PMC_CPU_INTEL_CORE2:
 	case PMC_CPU_INTEL_CORE2EXTREME:
-		PMC_MDEP_INIT(core2);
-		pmc_class_table[n++] = &iaf_class_table_descr;
-		pmc_class_table[n]   = &core2_class_table_descr;
+		PMC_MDEP_INIT_INTEL_V2(core2);
 		break;
 	case PMC_CPU_INTEL_COREI7:
-		PMC_MDEP_INIT(corei7);
-		pmc_class_table[n++] = &iaf_class_table_descr;
-		pmc_class_table[n]   = &corei7_class_table_descr;
+		PMC_MDEP_INIT_INTEL_V2(corei7);
 		break;
 	case PMC_CPU_INTEL_PIV:
 		PMC_MDEP_INIT(p4);



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