mirror of
https://github.com/torvalds/linux.git
synced 2024-11-15 08:31:55 +00:00
perf pmu-events: Add pmu_events_table__find_event()
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>
This commit is contained in:
parent
e3edd6cf63
commit
3d5045492a
@ -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)
|
||||
{
|
||||
|
@ -825,6 +825,49 @@ static int pmu_events_table__for_each_event_pmu(const struct pmu_events_table *t
|
||||
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,
|
||||
@ -845,6 +888,27 @@ int pmu_events_table__for_each_event(const struct pmu_events_table *table,
|
||||
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,
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user