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);
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to