if (!pe) {
/* Update an event from sysfs with json data. */
if (pmu->events_table) {
- pmu_events_table__find_event(pmu->events_table, pmu, name,
- update_alias, alias);
+ if (pmu_events_table__find_event(pmu->events_table, pmu, name,
+ update_alias, alias) == 0)
+ pmu->loaded_json_aliases++;
}
}
"%s=%s", term->config, term->val.str);
}
alias->str = strdup(newval);
+ if (!pe)
+ pmu->sysfs_aliases++;
+ else
+ pmu->loaded_json_aliases++;
list_add_tail(&alias->list, &pmu->aliases);
return 0;
}
if (!pmu->events_table)
return;
+ if (pmu->cpu_aliases_added)
+ return;
+
pmu_add_cpu_aliases_table(pmu, pmu->events_table);
+ pmu->cpu_aliases_added = true;
}
static int pmu_add_sys_aliases_iter_fn(const struct pmu_event *pe,
pmu->id = pmu_id(name);
pmu->max_precise = pmu_max_precise(dirfd, pmu);
pmu->events_table = perf_pmu__find_events_table(pmu);
- pmu_add_cpu_aliases(pmu);
pmu_add_sys_aliases(pmu);
list_add_tail(&pmu->list, pmus);
static struct perf_pmu_alias *pmu_find_alias(struct perf_pmu *pmu,
struct parse_events_term *term)
{
+ struct perf_pmu_alias *alias;
char *name;
if (parse_events__is_hardcoded_term(term))
return NULL;
}
- return perf_pmu__find_alias(pmu, name);
+ alias = perf_pmu__find_alias(pmu, name);
+ if (alias || pmu->cpu_aliases_added)
+ return alias;
+
+ /* Alias doesn't exist, try to get it from the json events. */
+ if (pmu->events_table &&
+ pmu_events_table__find_event(pmu->events_table, pmu, name,
+ pmu_add_cpu_aliases_map_callback,
+ pmu) == 0) {
+ alias = perf_pmu__find_alias(pmu, name);
+ }
+ return alias;
}
return !pmu->is_core || perf_pmus__num_core_pmus() == 1;
}
-bool perf_pmu__have_event(const struct perf_pmu *pmu, const char *name)
+bool perf_pmu__have_event(struct perf_pmu *pmu, const char *name)
{
- return perf_pmu__find_alias(pmu, name) != NULL;
+ if (perf_pmu__find_alias(pmu, name) != NULL)
+ return true;
+ if (pmu->cpu_aliases_added || !pmu->events_table)
+ return false;
+ return pmu_events_table__find_event(pmu->events_table, pmu, name, NULL, NULL) == 0;
}
-size_t perf_pmu__num_events(const struct perf_pmu *pmu)
+size_t perf_pmu__num_events(struct perf_pmu *pmu)
{
- struct list_head *list;
- size_t nr = 0;
+ size_t nr = pmu->sysfs_aliases;
- list_for_each(list, &pmu->aliases)
- nr++;
+ if (pmu->cpu_aliases_added)
+ nr += pmu->loaded_json_aliases;
+ else if (pmu->events_table)
+ nr += pmu_events_table__num_events(pmu->events_table, pmu) - pmu->loaded_json_aliases;
return pmu->selectable ? nr + 1 : nr;
}
return buf;
}
-int perf_pmu__for_each_event(const struct perf_pmu *pmu, void *state, pmu_event_callback cb)
+int perf_pmu__for_each_event(struct perf_pmu *pmu, void *state, pmu_event_callback cb)
{
char buf[1024];
struct perf_pmu_alias *event;
};
int ret = 0;
+ pmu_add_cpu_aliases(pmu);
list_for_each_entry(event, &pmu->aliases, list) {
size_t buf_used;
* @events_table: The events table for json events in pmu-events.c.
*/
const struct pmu_events_table *events_table;
+ /** @sysfs_aliases: Number of sysfs aliases loaded. */
+ uint32_t sysfs_aliases;
+ /** @sysfs_aliases: Number of json event aliases loaded. */
+ uint32_t loaded_json_aliases;
+ /**
+ * @cpu_aliases_added: Have all json events table entries for the PMU
+ * been added?
+ */
+ bool cpu_aliases_added;
/** @caps_initialized: Has the list caps been initialized? */
bool caps_initialized;
/** @nr_caps: The length of the list caps. */
bool is_pmu_core(const char *name);
bool perf_pmu__supports_legacy_cache(const struct perf_pmu *pmu);
bool perf_pmu__auto_merge_stats(const struct perf_pmu *pmu);
-bool perf_pmu__have_event(const struct perf_pmu *pmu, const char *name);
-size_t perf_pmu__num_events(const struct perf_pmu *pmu);
-int perf_pmu__for_each_event(const struct perf_pmu *pmu, void *state, pmu_event_callback cb);
+bool perf_pmu__have_event(struct perf_pmu *pmu, const char *name);
+size_t perf_pmu__num_events(struct perf_pmu *pmu);
+int perf_pmu__for_each_event(struct perf_pmu *pmu, void *state, pmu_event_callback cb);
bool pmu__name_match(const struct perf_pmu *pmu, const char *pmu_name);
/**