Lines Matching defs:pmu
20 #include "pmu.h"
24 #include <util/pmu-bison.h>
25 #include <util/pmu-flex.h>
38 /* An event loaded from /sys/devices/<pmu>/events. */
43 * An event loaded from a /sys/devices/<pmu>/identifier matched json
51 * pmu-events.c, created by parsing the pmu-events json files.
126 static int pmu_aliases_parse(struct perf_pmu *pmu);
169 static void perf_pmu_format__load(const struct perf_pmu *pmu, struct perf_pmu_format *format)
177 if (!perf_pmu__pathname_scnprintf(path, sizeof(path), pmu->name, "format"))
195 static int perf_pmu__format_parse(struct perf_pmu *pmu, int dirfd, bool eager_load)
212 format = perf_pmu__new_format(&pmu->format, name);
241 * Reading/parsing the default pmu format definition, which should be
245 static int pmu_format(struct perf_pmu *pmu, int dirfd, const char *name, bool eager_load)
254 if (perf_pmu__format_parse(pmu, fd, eager_load))
297 static int perf_pmu__parse_scale(struct perf_pmu *pmu, struct perf_pmu_alias *alias)
309 scnprintf(path + len, sizeof(path) - len, "%s/events/%s.scale", pmu->name, alias->name);
333 static int perf_pmu__parse_unit(struct perf_pmu *pmu, struct perf_pmu_alias *alias)
344 scnprintf(path + len, sizeof(path) - len, "%s/events/%s.unit", pmu->name, alias->name);
399 static void perf_pmu__parse_per_pkg(struct perf_pmu *pmu, struct perf_pmu_alias *alias)
401 alias->per_pkg = perf_pmu__parse_event_source_bool(pmu->name, alias->name, "per-pkg");
404 static void perf_pmu__parse_snapshot(struct perf_pmu *pmu, struct perf_pmu_alias *alias)
406 alias->snapshot = perf_pmu__parse_event_source_bool(pmu->name, alias->name, "snapshot");
421 static void perf_pmu__del_aliases(struct perf_pmu *pmu)
425 list_for_each_entry_safe(alias, tmp, &pmu->aliases, list) {
431 static struct perf_pmu_alias *perf_pmu__find_alias(struct perf_pmu *pmu,
437 if (load && !pmu->sysfs_aliases_loaded) {
450 has_sysfs_event = perf_pmu__file_exists(pmu, event_file_name);
455 has_sysfs_event = perf_pmu__file_exists(pmu, event_file_name);
458 pmu_aliases_parse(pmu);
461 list_for_each_entry(alias, &pmu->aliases, list) {
486 static void read_alias_info(struct perf_pmu *pmu, struct perf_pmu_alias *alias)
494 perf_pmu__parse_unit(pmu, alias);
495 perf_pmu__parse_scale(pmu, alias);
496 perf_pmu__parse_per_pkg(pmu, alias);
497 perf_pmu__parse_snapshot(pmu, alias);
501 struct perf_pmu *pmu;
512 read_alias_info(data->pmu, data->alias);
531 static int perf_pmu__new_alias(struct perf_pmu *pmu, const char *name,
540 if (perf_pmu__find_alias(pmu, name, /*load=*/ false)) {
551 if (pe->pmu && strcmp(pe->pmu, "default_core"))
552 pmu_name = pe->pmu;
590 if (pmu->events_table) {
593 .pmu = pmu,
596 if (pmu_events_table__find_event(pmu->events_table, pmu, name,
598 pmu->cpu_json_aliases++;
600 pmu->sysfs_aliases++;
603 pmu->cpu_json_aliases++;
606 pmu->sys_json_aliases++;
610 list_add_tail(&alias->list, &pmu->aliases);
632 * Reading the pmu event aliases definition, which should be located at:
635 static int __pmu_aliases_parse(struct perf_pmu *pmu, int events_dir_fd)
669 if (perf_pmu__new_alias(pmu, name, /*desc=*/ NULL,
677 pmu->sysfs_aliases_loaded = true;
681 static int pmu_aliases_parse(struct perf_pmu *pmu)
687 if (pmu->sysfs_aliases_loaded)
693 scnprintf(path + len, sizeof(path) - len, "%s/events", pmu->name);
697 pmu->sysfs_aliases_loaded = true;
700 ret = __pmu_aliases_parse(pmu, events_dir_fd);
705 static int pmu_aliases_parse_eager(struct perf_pmu *pmu, int sysfs_fd)
710 scnprintf(path, sizeof(path), "%s/events", pmu->name);
713 pmu->sysfs_aliases_loaded = true;
716 ret = __pmu_aliases_parse(pmu, events_dir_fd);
761 struct perf_pmu pmu = {.name = pmu_name};
766 file = perf_pmu__open_file_at(&pmu, dirfd, *template);
831 static size_t pmu_deduped_name_len(const struct perf_pmu *pmu, const char *name,
834 return skip_duplicate_pmus && !pmu->is_core
962 struct perf_pmu *pmu = vdata;
964 perf_pmu__new_alias(pmu, pe->name, pe->desc, pe->event, /*val_fd=*/ NULL,
973 void pmu_add_cpu_aliases_table(struct perf_pmu *pmu, const struct pmu_events_table *table)
975 pmu_events_table__for_each_event(table, pmu, pmu_add_cpu_aliases_map_callback, pmu);
978 static void pmu_add_cpu_aliases(struct perf_pmu *pmu)
980 if (!pmu->events_table)
983 if (pmu->cpu_aliases_added)
986 pmu_add_cpu_aliases_table(pmu, pmu->events_table);
987 pmu->cpu_aliases_added = true;
994 struct perf_pmu *pmu = vdata;
996 if (!pe->compat || !pe->pmu)
999 if (pmu_uncore_alias_match(pe->pmu, pmu->name) &&
1000 pmu_uncore_identifier_match(pe->compat, pmu->id)) {
1001 perf_pmu__new_alias(pmu,
1013 void pmu_add_sys_aliases(struct perf_pmu *pmu)
1015 if (!pmu->id)
1018 pmu_for_each_sys_event(pmu_add_sys_aliases_iter_fn, pmu);
1021 static char *pmu_find_alias_name(struct perf_pmu *pmu, int dirfd)
1023 FILE *file = perf_pmu__open_file_at(pmu, dirfd, "alias");
1044 static int pmu_max_precise(int dirfd, struct perf_pmu *pmu)
1048 perf_pmu__scan_file_at(pmu, dirfd, "caps/max_precise", "%d", &max_precise);
1053 perf_pmu__arch_init(struct perf_pmu *pmu)
1055 if (pmu->is_core)
1056 pmu->mem_events = perf_mem_events;
1062 struct perf_pmu *pmu;
1065 pmu = zalloc(sizeof(*pmu));
1066 if (!pmu)
1069 pmu->name = strdup(name);
1070 if (!pmu->name)
1077 if (perf_pmu__scan_file_at(pmu, dirfd, "type", "%u", &type) != 1)
1080 INIT_LIST_HEAD(&pmu->format);
1081 INIT_LIST_HEAD(&pmu->aliases);
1082 INIT_LIST_HEAD(&pmu->caps);
1085 * The pmu data we store & need consists of the pmu
1089 if (pmu_format(pmu, dirfd, name, eager_load))
1092 pmu->is_core = is_pmu_core(name);
1093 pmu->cpus = pmu_cpumask(dirfd, name, pmu->is_core);
1095 pmu->type = type;
1096 pmu->is_uncore = pmu_is_uncore(dirfd, name);
1097 if (pmu->is_uncore)
1098 pmu->id = pmu_id(name);
1099 pmu->max_precise = pmu_max_precise(dirfd, pmu);
1100 pmu->alias_name = pmu_find_alias_name(pmu, dirfd);
1101 pmu->events_table = perf_pmu__find_events_table(pmu);
1108 pmu_add_sys_aliases(pmu);
1109 list_add_tail(&pmu->list, pmus);
1111 perf_pmu__arch_init(pmu);
1114 pmu_aliases_parse_eager(pmu, dirfd);
1116 return pmu;
1118 zfree(&pmu->name);
1119 free(pmu);
1126 struct perf_pmu *pmu = zalloc(sizeof(*pmu));
1128 if (!pmu)
1131 pmu->name = strdup("cpu");
1132 if (!pmu->name) {
1133 free(pmu);
1137 pmu->is_core = true;
1138 pmu->type = PERF_TYPE_RAW;
1139 pmu->cpus = cpu_map__online();
1141 INIT_LIST_HEAD(&pmu->format);
1142 INIT_LIST_HEAD(&pmu->aliases);
1143 INIT_LIST_HEAD(&pmu->caps);
1144 list_add_tail(&pmu->list, core_pmus);
1145 return pmu;
1148 bool perf_pmu__is_fake(const struct perf_pmu *pmu)
1150 return pmu->type == PERF_PMU_TYPE_FAKE;
1153 void perf_pmu__warn_invalid_formats(struct perf_pmu *pmu)
1157 if (pmu->formats_checked)
1160 pmu->formats_checked = true;
1162 /* fake pmu doesn't have format list */
1163 if (perf_pmu__is_fake(pmu))
1166 list_for_each_entry(format, &pmu->format, list) {
1167 perf_pmu_format__load(pmu, format);
1171 pmu->name, format->name, format->value);
1179 struct perf_pmu *pmu;
1184 pmu = evsel__find_pmu(evsel);
1185 return pmu && pmu->auxtrace;
1197 void evsel__set_config_if_unset(struct perf_pmu *pmu, struct evsel *evsel,
1206 bits = perf_pmu__format_bits(pmu, config_name);
1229 __u64 perf_pmu__format_bits(struct perf_pmu *pmu, const char *name)
1231 struct perf_pmu_format *format = pmu_find_format(&pmu->format, name);
1244 int perf_pmu__format_type(struct perf_pmu *pmu, const char *name)
1246 struct perf_pmu_format *format = pmu_find_format(&pmu->format, name);
1251 perf_pmu_format__load(pmu, format);
1342 static int pmu_config_term(const struct perf_pmu *pmu,
1402 format = pmu_find_format(&pmu->format, term->config);
1404 char *pmu_term = pmu_formats_string(&pmu->format);
1409 "unknown term '%s' for pmu '%s'",
1410 term->config, pmu->name) < 0)
1424 perf_pmu_format__load(pmu, format);
1500 int perf_pmu__config_terms(const struct perf_pmu *pmu,
1508 if (perf_pmu__is_hwmon(pmu))
1509 return hwmon_pmu__config_terms(pmu, attr, terms, err);
1512 if (pmu_config_term(pmu, attr, term, terms, zero, apply_hardcoded, err))
1522 * 2) pmu format definitions - specified by pmu parameter
1524 int perf_pmu__config(struct perf_pmu *pmu, struct perf_event_attr *attr,
1529 bool zero = !!pmu->perf_event_attr_init_default;
1532 if (perf_pmu__is_fake(pmu))
1535 return perf_pmu__config_terms(pmu, attr, head_terms, zero, apply_hardcoded, err);
1538 static struct perf_pmu_alias *pmu_find_alias(struct perf_pmu *pmu,
1550 if (pmu_find_format(&pmu->format, term->config))
1562 alias = perf_pmu__find_alias(pmu, name, /*load=*/ true);
1563 if (alias || pmu->cpu_aliases_added)
1567 if (pmu->events_table &&
1568 pmu_events_table__find_event(pmu->events_table, pmu, name,
1570 pmu) == 0) {
1571 alias = perf_pmu__find_alias(pmu, name, /*load=*/ false);
1577 static int check_info_data(struct perf_pmu *pmu,
1583 read_alias_info(pmu, alias);
1624 int perf_pmu__check_alias(struct perf_pmu *pmu, struct parse_events_terms *head_terms,
1643 if (perf_pmu__is_hwmon(pmu)) {
1649 if (perf_pmu__is_fake(pmu))
1653 alias = pmu_find_alias(pmu, term);
1665 ret = check_info_data(pmu, alias, info, err, term->err_term);
1709 int perf_pmu__find_event(struct perf_pmu *pmu, const char *event, void *state, pmu_event_callback cb)
1718 return perf_pmu__for_each_event(pmu, /*skip_duplicate_pmus=*/ false,
1733 bool perf_pmu__has_format(const struct perf_pmu *pmu, const char *name)
1737 list_for_each_entry(format, &pmu->format, list) {
1744 int perf_pmu__for_each_format(struct perf_pmu *pmu, void *state, pmu_format_callback cb)
1778 list_for_each_entry(format, &pmu->format, list) {
1779 perf_pmu_format__load(pmu, format);
1784 if (!pmu->is_core)
1805 bool perf_pmu__supports_legacy_cache(const struct perf_pmu *pmu)
1807 return pmu->is_core;
1810 bool perf_pmu__auto_merge_stats(const struct perf_pmu *pmu)
1812 return !pmu->is_core || perf_pmus__num_core_pmus() == 1;
1815 bool perf_pmu__have_event(struct perf_pmu *pmu, const char *name)
1819 if (perf_pmu__is_tool(pmu) && tool_pmu__skip_event(name))
1821 if (perf_pmu__is_hwmon(pmu))
1822 return hwmon_pmu__have_event(pmu, name);
1823 if (perf_pmu__find_alias(pmu, name, /*load=*/ true) != NULL)
1825 if (pmu->cpu_aliases_added || !pmu->events_table)
1827 return pmu_events_table__find_event(pmu->events_table, pmu, name, NULL, NULL) == 0;
1830 size_t perf_pmu__num_events(struct perf_pmu *pmu)
1834 if (perf_pmu__is_hwmon(pmu))
1835 return hwmon_pmu__num_events(pmu);
1837 pmu_aliases_parse(pmu);
1838 nr = pmu->sysfs_aliases + pmu->sys_json_aliases;
1840 if (pmu->cpu_aliases_added)
1841 nr += pmu->cpu_json_aliases;
1842 else if (pmu->events_table)
1843 nr += pmu_events_table__num_events(pmu->events_table, pmu) - pmu->cpu_json_aliases;
1845 assert(pmu->cpu_json_aliases == 0);
1847 if (perf_pmu__is_tool(pmu))
1850 return pmu->selectable ? nr + 1 : nr;
1860 static char *format_alias(char *buf, int len, const struct perf_pmu *pmu,
1864 size_t pmu_name_len = pmu_deduped_name_len(pmu, pmu->name,
1866 int used = snprintf(buf, len, "%.*s/%s", (int)pmu_name_len, pmu->name, alias->name);
1888 int perf_pmu__for_each_event(struct perf_pmu *pmu, bool skip_duplicate_pmus,
1894 .pmu = pmu,
1900 if (perf_pmu__is_hwmon(pmu))
1901 return hwmon_pmu__for_each_event(pmu, state, cb);
1904 pmu_aliases_parse(pmu);
1905 pmu_add_cpu_aliases(pmu);
1906 list_for_each_entry(event, &pmu->aliases, list) {
1909 if (perf_pmu__is_tool(pmu) && tool_pmu__skip_event(event->name))
1912 info.pmu_name = event->pmu_name ?: pmu->name;
1913 pmu_name_len = pmu_deduped_name_len(pmu, info.pmu_name,
1920 info.name = format_alias(buf, sizeof(buf), pmu, event,
1922 if (pmu->is_core) {
1948 if (pmu->selectable) {
1950 snprintf(buf, sizeof(buf), "%s//", pmu->name);
1957 info.pmu_name = pmu->name;
1966 bool pmu__name_match(const struct perf_pmu *pmu, const char *pmu_name)
1968 return !strcmp(pmu->name, pmu_name) ||
1969 (pmu->is_uncore && pmu_uncore_alias_match(pmu_name, pmu->name)) ||
1974 (pmu->is_core && !strcmp(pmu_name, "default_core"));
1977 bool perf_pmu__is_software(const struct perf_pmu *pmu)
1985 if (pmu->is_core || pmu->is_uncore || pmu->auxtrace)
1987 switch (pmu->type) {
1998 if (!strcmp(pmu->name, known_sw_pmus[i]))
2004 FILE *perf_pmu__open_file(const struct perf_pmu *pmu, const char *name)
2008 if (!perf_pmu__pathname_scnprintf(path, sizeof(path), pmu->name, name) ||
2015 FILE *perf_pmu__open_file_at(const struct perf_pmu *pmu, int dirfd, const char *name)
2019 fd = perf_pmu__pathname_fd(dirfd, pmu->name, name, O_RDONLY);
2026 int perf_pmu__scan_file(const struct perf_pmu *pmu, const char *name, const char *fmt,
2034 file = perf_pmu__open_file(pmu, name);
2043 int perf_pmu__scan_file_at(const struct perf_pmu *pmu, int dirfd, const char *name,
2051 file = perf_pmu__open_file_at(pmu, dirfd, name);
2060 bool perf_pmu__file_exists(const struct perf_pmu *pmu, const char *name)
2064 if (!perf_pmu__pathname_scnprintf(path, sizeof(path), pmu->name, name))
2094 static void perf_pmu__del_caps(struct perf_pmu *pmu)
2098 list_for_each_entry_safe(caps, tmp, &pmu->caps, list) {
2107 * Reading/parsing the given pmu capabilities, which should be located at:
2111 int perf_pmu__caps_parse(struct perf_pmu *pmu)
2119 if (pmu->caps_initialized)
2120 return pmu->nr_caps;
2122 pmu->nr_caps = 0;
2124 if (!perf_pmu__pathname_scnprintf(caps_path, sizeof(caps_path), pmu->name, "caps"))
2128 pmu->caps_initialized = true;
2157 (perf_pmu__new_caps(&pmu->caps, name, value) < 0)) {
2162 pmu->nr_caps++;
2168 pmu->caps_initialized = true;
2169 return pmu->nr_caps;
2172 static void perf_pmu__compute_config_masks(struct perf_pmu *pmu)
2176 if (pmu->config_masks_computed)
2179 list_for_each_entry(format, &pmu->format, list) {
2186 pmu->config_masks_present = true;
2187 mask = &pmu->config_masks[format->value];
2192 pmu->config_masks_computed = true;
2195 void perf_pmu__warn_invalid_config(struct perf_pmu *pmu, __u64 config,
2202 perf_pmu__compute_config_masks(pmu);
2207 if (!pmu->config_masks_present)
2210 bits = config & ~pmu->config_masks[config_num];
2221 bool perf_pmu__match(const struct perf_pmu *pmu, const char *tok)
2223 const char *name = pmu->name;
2235 name = pmu->alias_name;
2296 void perf_pmu__delete(struct perf_pmu *pmu)
2298 if (perf_pmu__is_hwmon(pmu))
2299 hwmon_pmu__exit(pmu);
2301 perf_pmu__del_formats(&pmu->format);
2302 perf_pmu__del_aliases(pmu);
2303 perf_pmu__del_caps(pmu);
2305 perf_cpu_map__put(pmu->cpus);
2307 zfree(&pmu->name);
2308 zfree(&pmu->alias_name);
2309 zfree(&pmu->id);
2310 free(pmu);
2313 const char *perf_pmu__name_from_config(struct perf_pmu *pmu, u64 config)
2317 if (!pmu)
2320 pmu_aliases_parse(pmu);
2321 pmu_add_cpu_aliases(pmu);
2322 list_for_each_entry(event, &pmu->aliases, list) {
2325 int ret = perf_pmu__config(pmu, &attr, &event->terms, /*apply_hardcoded=*/true,