summaryrefslogtreecommitdiff
path: root/tools/perf/pmu-events/empty-pmu-events.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/perf/pmu-events/empty-pmu-events.c')
-rw-r--r--tools/perf/pmu-events/empty-pmu-events.c204
1 files changed, 194 insertions, 10 deletions
diff --git a/tools/perf/pmu-events/empty-pmu-events.c b/tools/perf/pmu-events/empty-pmu-events.c
index 77e655c6f116..5ed8c0aa4817 100644
--- a/tools/perf/pmu-events/empty-pmu-events.c
+++ b/tools/perf/pmu-events/empty-pmu-events.c
@@ -6,6 +6,10 @@
* The test cpu/soc is provided for testing.
*/
#include "pmu-events/pmu-events.h"
+#include "util/header.h"
+#include "util/pmu.h"
+#include <string.h>
+#include <stddef.h>
static const struct pmu_event pme_test_soc_cpu[] = {
{
@@ -102,24 +106,109 @@ static const struct pmu_event pme_test_soc_cpu[] = {
.topic = "branch",
},
{
+ .metric_expr = "1 / IPC",
+ .metric_name = "CPI",
+ },
+ {
+ .metric_expr = "inst_retired.any / cpu_clk_unhalted.thread",
+ .metric_name = "IPC",
+ .metric_group = "group1",
+ },
+ {
+ .metric_expr = "idq_uops_not_delivered.core / (4 * (( ( cpu_clk_unhalted.thread / 2 ) * "
+ "( 1 + cpu_clk_unhalted.one_thread_active / cpu_clk_unhalted.ref_xclk ) )))",
+ .metric_name = "Frontend_Bound_SMT",
+ },
+ {
+ .metric_expr = "l1d\\-loads\\-misses / inst_retired.any",
+ .metric_name = "dcache_miss_cpi",
+ },
+ {
+ .metric_expr = "l1i\\-loads\\-misses / inst_retired.any",
+ .metric_name = "icache_miss_cycles",
+ },
+ {
+ .metric_expr = "(dcache_miss_cpi + icache_miss_cycles)",
+ .metric_name = "cache_miss_cycles",
+ .metric_group = "group1",
+ },
+ {
+ .metric_expr = "l2_rqsts.demand_data_rd_hit + l2_rqsts.pf_hit + l2_rqsts.rfo_hit",
+ .metric_name = "DCache_L2_All_Hits",
+ },
+ {
+ .metric_expr = "max(l2_rqsts.all_demand_data_rd - l2_rqsts.demand_data_rd_hit, 0) + "
+ "l2_rqsts.pf_miss + l2_rqsts.rfo_miss",
+ .metric_name = "DCache_L2_All_Miss",
+ },
+ {
+ .metric_expr = "dcache_l2_all_hits + dcache_l2_all_miss",
+ .metric_name = "DCache_L2_All",
+ },
+ {
+ .metric_expr = "d_ratio(dcache_l2_all_hits, dcache_l2_all)",
+ .metric_name = "DCache_L2_Hits",
+ },
+ {
+ .metric_expr = "d_ratio(dcache_l2_all_miss, dcache_l2_all)",
+ .metric_name = "DCache_L2_Misses",
+ },
+ {
+ .metric_expr = "ipc + M2",
+ .metric_name = "M1",
+ },
+ {
+ .metric_expr = "ipc + M1",
+ .metric_name = "M2",
+ },
+ {
+ .metric_expr = "1/M3",
+ .metric_name = "M3",
+ },
+ {
+ .metric_expr = "64 * l1d.replacement / 1000000000 / duration_time",
+ .metric_name = "L1D_Cache_Fill_BW",
+ },
+ {
.name = 0,
.event = 0,
.desc = 0,
},
};
-const struct pmu_events_map pmu_events_map[] = {
+/* Struct used to make the PMU event table implementation opaque to callers. */
+struct pmu_events_table {
+ const struct pmu_event *entries;
+};
+
+/*
+ * Map a CPU to its table of PMU events. The CPU is identified by the
+ * cpuid field, which is an arch-specific identifier for the CPU.
+ * The identifier specified in tools/perf/pmu-events/arch/xxx/mapfile
+ * must match the get_cpuid_str() in tools/perf/arch/xxx/util/header.c)
+ *
+ * The cpuid can contain any character other than the comma.
+ */
+struct pmu_events_map {
+ const char *arch;
+ const char *cpuid;
+ const struct pmu_events_table table;
+};
+
+/*
+ * Global table mapping each known CPU for the architecture to its
+ * table of PMU events.
+ */
+static const struct pmu_events_map pmu_events_map[] = {
{
+ .arch = "testarch",
.cpuid = "testcpu",
- .version = "v1",
- .type = "core",
- .table = pme_test_soc_cpu,
+ .table = { pme_test_soc_cpu },
},
{
+ .arch = 0,
.cpuid = 0,
- .version = 0,
- .type = 0,
- .table = 0,
+ .table = { 0 },
},
};
@@ -147,12 +236,107 @@ static const struct pmu_event pme_test_soc_sys[] = {
},
};
-const struct pmu_sys_events pmu_sys_event_tables[] = {
+struct pmu_sys_events {
+ const char *name;
+ const struct pmu_events_table table;
+};
+
+static const struct pmu_sys_events pmu_sys_event_tables[] = {
{
- .table = pme_test_soc_sys,
+ .table = { pme_test_soc_sys },
.name = "pme_test_soc_sys",
},
{
- .table = 0
+ .table = { 0 }
},
};
+
+int pmu_events_table_for_each_event(const struct pmu_events_table *table, pmu_event_iter_fn fn,
+ void *data)
+{
+ for (const struct pmu_event *pe = &table->entries[0];
+ pe->name || pe->metric_group || pe->metric_name;
+ pe++) {
+ int ret = fn(pe, table, data);
+
+ if (ret)
+ return ret;
+ }
+ return 0;
+}
+
+const struct pmu_events_table *perf_pmu__find_table(struct perf_pmu *pmu)
+{
+ const struct pmu_events_table *table = NULL;
+ char *cpuid = perf_pmu__getcpuid(pmu);
+ int i;
+
+ /* on some platforms which uses cpus map, cpuid can be NULL for
+ * PMUs other than CORE PMUs.
+ */
+ if (!cpuid)
+ return NULL;
+
+ i = 0;
+ for (;;) {
+ const struct pmu_events_map *map = &pmu_events_map[i++];
+
+ if (!map->cpuid)
+ break;
+
+ if (!strcmp_cpuid_str(map->cpuid, cpuid)) {
+ table = &map->table;
+ break;
+ }
+ }
+ free(cpuid);
+ return table;
+}
+
+const struct pmu_events_table *find_core_events_table(const char *arch, const char *cpuid)
+{
+ for (const struct pmu_events_map *tables = &pmu_events_map[0];
+ tables->arch;
+ tables++) {
+ if (!strcmp(tables->arch, arch) && !strcmp_cpuid_str(tables->cpuid, cpuid))
+ return &tables->table;
+ }
+ return NULL;
+}
+
+int pmu_for_each_core_event(pmu_event_iter_fn fn, void *data)
+{
+ for (const struct pmu_events_map *tables = &pmu_events_map[0];
+ tables->arch;
+ tables++) {
+ int ret = pmu_events_table_for_each_event(&tables->table, fn, data);
+
+ if (ret)
+ return ret;
+ }
+ return 0;
+}
+
+const struct pmu_events_table *find_sys_events_table(const char *name)
+{
+ for (const struct pmu_sys_events *tables = &pmu_sys_event_tables[0];
+ tables->name;
+ tables++) {
+ if (!strcmp(tables->name, name))
+ return &tables->table;
+ }
+ return NULL;
+}
+
+int pmu_for_each_sys_event(pmu_event_iter_fn fn, void *data)
+{
+ for (const struct pmu_sys_events *tables = &pmu_sys_event_tables[0];
+ tables->name;
+ tables++) {
+ int ret = pmu_events_table_for_each_event(&tables->table, fn, data);
+
+ if (ret)
+ return ret;
+ }
+ return 0;
+}