#include <string.h>
#include <stddef.h>
-static const struct pmu_event pme_test_soc_cpu[] = {
+static const struct pmu_event pmu_events__test_soc_cpu[] = {
{
.name = "l3_cache_rd",
.event = "event=0x40",
.topic = "branch",
},
{
+ .name = 0,
+ .event = 0,
+ .desc = 0,
+ },
+};
+
+static const struct pmu_metric pmu_metrics__test_soc_cpu[] = {
+ {
.metric_expr = "1 / IPC",
.metric_name = "CPI",
},
.metric_name = "L1D_Cache_Fill_BW",
},
{
- .name = 0,
- .event = 0,
- .desc = 0,
+ .metric_expr = 0,
+ .metric_name = 0,
},
};
struct pmu_events_map {
const char *arch;
const char *cpuid;
- const struct pmu_events_table table;
+ const struct pmu_events_table event_table;
+ const struct pmu_metrics_table metric_table;
};
/*
{
.arch = "testarch",
.cpuid = "testcpu",
- .table = { pme_test_soc_cpu },
+ .event_table = { pmu_events__test_soc_cpu },
+ .metric_table = { pmu_metrics__test_soc_cpu },
},
{
.arch = 0,
.cpuid = 0,
- .table = { 0 },
+ .event_table = { 0 },
+ .metric_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_expr; pe++) {
- int ret;
+ for (const struct pmu_event *pe = &table->entries[0]; pe->name; pe++) {
+ int ret = fn(pe, table, data);
- if (!pe->name)
- continue;
- ret = fn(pe, table, data);
if (ret)
return ret;
}
{
struct pmu_metrics_table *table = (struct pmu_metrics_table *)etable;
- for (const struct pmu_metric *pm = &table->entries[0]; pm->name || pm->metric_expr; pm++) {
- int ret;
+ for (const struct pmu_metric *pm = &table->entries[0]; pm->metric_expr; pm++) {
+ int ret = fn(pm, etable, data);
- if (!pm->metric_expr)
- continue;
- ret = fn(pm, etable, 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 *perf_pmu__find_events_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->event_table;
+ break;
+ }
+ }
+ free(cpuid);
+ return table;
+}
+
+const struct pmu_events_table *perf_pmu__find_metrics_table(struct perf_pmu *pmu)
{
const struct pmu_events_table *table = NULL;
char *cpuid = perf_pmu__getcpuid(pmu);
break;
if (!strcmp_cpuid_str(map->cpuid, cpuid)) {
- table = &map->table;
+ table = (const struct pmu_events_table *)&map->metric_table;
break;
}
}
tables->arch;
tables++) {
if (!strcmp(tables->arch, arch) && !strcmp_cpuid_str(tables->cpuid, cpuid))
- return &tables->table;
+ return &tables->event_table;
+ }
+ return NULL;
+}
+
+const struct pmu_events_table *find_core_metrics_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 (const struct pmu_events_table *)&tables->metric_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);
+ int ret = pmu_events_table_for_each_event(&tables->event_table, fn, data);
if (ret)
return ret;
for (const struct pmu_events_map *tables = &pmu_events_map[0];
tables->arch;
tables++) {
- int ret = pmu_events_table_for_each_metric(&tables->table, fn, data);
+ int ret = pmu_events_table_for_each_metric(
+ (const struct pmu_events_table *)&tables->metric_table, fn, data);
if (ret)
return ret;