Skip to content

Commit

Permalink
perf pmu-events: Add pmu_events_table__find_event()
Browse files Browse the repository at this point in the history
jevents stores events sorted by name. Add a find function that will
binary search event names avoiding the need to linearly search through
events.

Add a test in tests/pmu-events.c. If the PMU or event aren't found -1000
is returned. If the event is found but no callback function given, 0 is
returned.

This allows the find function also act as a test for existence.

Signed-off-by: Ian Rogers <irogers@google.com>
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Gaosheng Cui <cuigaosheng1@huawei.com>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: James Clark <james.clark@arm.com>
Cc: Jing Zhang <renyu.zj@linux.alibaba.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: John Garry <john.g.garry@oracle.com>
Cc: Kajol Jain <kjain@linux.ibm.com>
Cc: Kan Liang <kan.liang@linux.intel.com>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Ravi Bangoria <ravi.bangoria@amd.com>
Cc: Rob Herring <robh@kernel.org>
Link: https://lore.kernel.org/r/20230824041330.266337-9-irogers@google.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
  • Loading branch information
Ian Rogers authored and Arnaldo Carvalho de Melo committed Aug 24, 2023
1 parent e3edd6c commit 3d50454
Show file tree
Hide file tree
Showing 4 changed files with 90 additions and 0 deletions.
16 changes: 16 additions & 0 deletions tools/perf/pmu-events/empty-pmu-events.c
Original file line number Diff line number Diff line change
Expand Up @@ -282,6 +282,22 @@ int pmu_events_table__for_each_event(const struct pmu_events_table *table, struc
return 0;
}

int pmu_events_table__find_event(const struct pmu_events_table *table,
struct perf_pmu *pmu,
const char *name,
pmu_event_iter_fn fn,
void *data)
{
for (const struct pmu_event *pe = &table->entries[0]; pe->name; pe++) {
if (pmu && !pmu__name_match(pmu, pe->pmu))
continue;

if (!strcasecmp(pe->name, name))
return fn(pe, table, data);
}
return -1000;
}

int pmu_metrics_table__for_each_metric(const struct pmu_metrics_table *table, pmu_metric_iter_fn fn,
void *data)
{
Expand Down
64 changes: 64 additions & 0 deletions tools/perf/pmu-events/jevents.py
Original file line number Diff line number Diff line change
Expand Up @@ -825,6 +825,49 @@ def print_system_mapping_table() -> None:
return 0;
}
static int pmu_events_table__find_event_pmu(const struct pmu_events_table *table,
const struct pmu_table_entry *pmu,
const char *name,
pmu_event_iter_fn fn,
void *data)
{
struct pmu_event pe = {
.pmu = &big_c_string[pmu->pmu_name.offset],
};
int low = 0, high = pmu->num_entries - 1;
while (low <= high) {
int cmp, mid = (low + high) / 2;
decompress_event(pmu->entries[mid].offset, &pe);
if (!pe.name && !name)
goto do_call;
if (!pe.name && name) {
low = mid + 1;
continue;
}
if (pe.name && !name) {
high = mid - 1;
continue;
}
cmp = strcasecmp(pe.name, name);
if (cmp < 0) {
low = mid + 1;
continue;
}
if (cmp > 0) {
high = mid - 1;
continue;
}
do_call:
return fn ? fn(&pe, table, data) : 0;
}
return -1000;
}
int pmu_events_table__for_each_event(const struct pmu_events_table *table,
struct perf_pmu *pmu,
pmu_event_iter_fn fn,
Expand All @@ -845,6 +888,27 @@ def print_system_mapping_table() -> None:
return 0;
}
int pmu_events_table__find_event(const struct pmu_events_table *table,
struct perf_pmu *pmu,
const char *name,
pmu_event_iter_fn fn,
void *data)
{
for (size_t i = 0; i < table->num_pmus; i++) {
const struct pmu_table_entry *table_pmu = &table->pmus[i];
const char *pmu_name = &big_c_string[table_pmu->pmu_name.offset];
int ret;
if (!pmu__name_match(pmu, pmu_name))
continue;
ret = pmu_events_table__find_event_pmu(table, table_pmu, name, fn, data);
if (ret != -1000)
return ret;
}
return -1000;
}
static int pmu_metrics_table__for_each_metric_pmu(const struct pmu_metrics_table *table,
const struct pmu_table_entry *pmu,
pmu_metric_iter_fn fn,
Expand Down
5 changes: 5 additions & 0 deletions tools/perf/pmu-events/pmu-events.h
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,11 @@ int pmu_events_table__for_each_event(const struct pmu_events_table *table,
struct perf_pmu *pmu,
pmu_event_iter_fn fn,
void *data);
int pmu_events_table__find_event(const struct pmu_events_table *table,
struct perf_pmu *pmu,
const char *name,
pmu_event_iter_fn fn,
void *data);
int pmu_metrics_table__for_each_metric(const struct pmu_metrics_table *table, pmu_metric_iter_fn fn,
void *data);

Expand Down
5 changes: 5 additions & 0 deletions tools/perf/tests/pmu-events.c
Original file line number Diff line number Diff line change
Expand Up @@ -546,6 +546,11 @@ static int __test_core_pmu_event_aliases(char *pmu_name, int *count)

pmu_add_cpu_aliases_table(pmu, table);

res = pmu_events_table__find_event(table, pmu, "bp_l1_btb_correct", NULL, NULL);
if (res != 0) {
pr_debug("Missing test event in test architecture");
return res;
}
for (; *test_event_table; test_event_table++) {
struct perf_pmu_test_event test_event = **test_event_table;
struct pmu_event const *event = &test_event.event;
Expand Down

0 comments on commit 3d50454

Please sign in to comment.