1 #include <linux/list.h>
12 #include "parse-events.h"
15 struct perf_pmu_format {
18 DECLARE_BITMAP(bits, PERF_PMU_FORMAT_BITS);
19 struct list_head list;
22 #define EVENT_SOURCE_DEVICE_PATH "/bus/event_source/devices/"
24 int perf_pmu_parse(struct list_head *list, char *name);
25 extern FILE *perf_pmu_in;
27 static LIST_HEAD(pmus);
30 * Parse & process all the sysfs attributes located under
31 * the directory specified in 'dir' parameter.
33 int perf_pmu__format_parse(char *dir, struct list_head *head)
35 struct dirent *evt_ent;
39 format_dir = opendir(dir);
43 while (!ret && (evt_ent = readdir(format_dir))) {
45 char *name = evt_ent->d_name;
48 if (!strcmp(name, ".") || !strcmp(name, ".."))
51 snprintf(path, PATH_MAX, "%s/%s", dir, name);
54 file = fopen(path, "r");
59 ret = perf_pmu_parse(head, name);
68 * Reading/parsing the default pmu format definition, which should be
70 * /sys/bus/event_source/devices/<dev>/format as sysfs group attributes.
72 static int pmu_format(const char *name, struct list_head *format)
76 const char *sysfs = sysfs__mountpoint();
81 snprintf(path, PATH_MAX,
82 "%s" EVENT_SOURCE_DEVICE_PATH "%s/format", sysfs, name);
84 if (stat(path, &st) < 0)
85 return 0; /* no error if format does not exist */
87 if (perf_pmu__format_parse(path, format))
93 static int perf_pmu__parse_scale(struct perf_pmu_alias *alias, char *dir, char *name)
102 snprintf(path, PATH_MAX, "%s/%s.scale", dir, name);
104 fd = open(path, O_RDONLY);
108 if (fstat(fd, &st) < 0)
111 sret = read(fd, scale, sizeof(scale)-1);
115 if (scale[sret - 1] == '\n')
116 scale[sret - 1] = '\0';
121 * save current locale
123 lc = setlocale(LC_NUMERIC, NULL);
126 * force to C locale to ensure kernel
127 * scale string is converted correctly.
128 * kernel uses default C locale.
130 setlocale(LC_NUMERIC, "C");
132 alias->scale = strtod(scale, NULL);
135 setlocale(LC_NUMERIC, lc);
143 static int perf_pmu__parse_unit(struct perf_pmu_alias *alias, char *dir, char *name)
149 snprintf(path, PATH_MAX, "%s/%s.unit", dir, name);
151 fd = open(path, O_RDONLY);
155 sret = read(fd, alias->unit, UNIT_MAX_LEN);
161 if (alias->unit[sret - 1] == '\n')
162 alias->unit[sret - 1] = '\0';
164 alias->unit[sret] = '\0';
169 alias->unit[0] = '\0';
174 perf_pmu__parse_per_pkg(struct perf_pmu_alias *alias, char *dir, char *name)
179 snprintf(path, PATH_MAX, "%s/%s.per-pkg", dir, name);
181 fd = open(path, O_RDONLY);
187 alias->per_pkg = true;
191 static int perf_pmu__parse_snapshot(struct perf_pmu_alias *alias,
192 char *dir, char *name)
197 snprintf(path, PATH_MAX, "%s/%s.snapshot", dir, name);
199 fd = open(path, O_RDONLY);
203 alias->snapshot = true;
208 static int perf_pmu__new_alias(struct list_head *list, char *dir, char *name, FILE *file)
210 struct perf_pmu_alias *alias;
214 ret = fread(buf, 1, sizeof(buf), file);
219 alias = malloc(sizeof(*alias));
223 INIT_LIST_HEAD(&alias->terms);
225 alias->unit[0] = '\0';
226 alias->per_pkg = false;
228 ret = parse_events_terms(&alias->terms, buf);
234 alias->name = strdup(name);
236 * load unit name and scale if available
238 perf_pmu__parse_unit(alias, dir, name);
239 perf_pmu__parse_scale(alias, dir, name);
240 perf_pmu__parse_per_pkg(alias, dir, name);
241 perf_pmu__parse_snapshot(alias, dir, name);
243 list_add_tail(&alias->list, list);
248 static inline bool pmu_alias_info_file(char *name)
253 if (len > 5 && !strcmp(name + len - 5, ".unit"))
255 if (len > 6 && !strcmp(name + len - 6, ".scale"))
257 if (len > 8 && !strcmp(name + len - 8, ".per-pkg"))
259 if (len > 9 && !strcmp(name + len - 9, ".snapshot"))
266 * Process all the sysfs attributes located under the directory
267 * specified in 'dir' parameter.
269 static int pmu_aliases_parse(char *dir, struct list_head *head)
271 struct dirent *evt_ent;
275 event_dir = opendir(dir);
279 while (!ret && (evt_ent = readdir(event_dir))) {
281 char *name = evt_ent->d_name;
284 if (!strcmp(name, ".") || !strcmp(name, ".."))
288 * skip info files parsed in perf_pmu__new_alias()
290 if (pmu_alias_info_file(name))
293 snprintf(path, PATH_MAX, "%s/%s", dir, name);
296 file = fopen(path, "r");
300 ret = perf_pmu__new_alias(head, dir, name, file);
309 * Reading the pmu event aliases definition, which should be located at:
310 * /sys/bus/event_source/devices/<dev>/events as sysfs group attributes.
312 static int pmu_aliases(const char *name, struct list_head *head)
316 const char *sysfs = sysfs__mountpoint();
321 snprintf(path, PATH_MAX,
322 "%s/bus/event_source/devices/%s/events", sysfs, name);
324 if (stat(path, &st) < 0)
325 return 0; /* no error if 'events' does not exist */
327 if (pmu_aliases_parse(path, head))
333 static int pmu_alias_terms(struct perf_pmu_alias *alias,
334 struct list_head *terms)
336 struct parse_events_term *term, *cloned;
340 list_for_each_entry(term, &alias->terms, list) {
341 ret = parse_events_term__clone(&cloned, term);
343 parse_events__free_terms(&list);
346 list_add_tail(&cloned->list, &list);
348 list_splice(&list, terms);
353 * Reading/parsing the default pmu type value, which should be
355 * /sys/bus/event_source/devices/<dev>/type as sysfs attribute.
357 static int pmu_type(const char *name, __u32 *type)
363 const char *sysfs = sysfs__mountpoint();
368 snprintf(path, PATH_MAX,
369 "%s" EVENT_SOURCE_DEVICE_PATH "%s/type", sysfs, name);
371 if (stat(path, &st) < 0)
374 file = fopen(path, "r");
378 if (1 != fscanf(file, "%u", type))
385 /* Add all pmus in sysfs to pmu list: */
386 static void pmu_read_sysfs(void)
391 const char *sysfs = sysfs__mountpoint();
396 snprintf(path, PATH_MAX,
397 "%s" EVENT_SOURCE_DEVICE_PATH, sysfs);
403 while ((dent = readdir(dir))) {
404 if (!strcmp(dent->d_name, ".") || !strcmp(dent->d_name, ".."))
406 /* add to static LIST_HEAD(pmus): */
407 perf_pmu__find(dent->d_name);
413 static struct cpu_map *pmu_cpumask(const char *name)
418 struct cpu_map *cpus;
419 const char *sysfs = sysfs__mountpoint();
424 snprintf(path, PATH_MAX,
425 "%s/bus/event_source/devices/%s/cpumask", sysfs, name);
427 if (stat(path, &st) < 0)
430 file = fopen(path, "r");
434 cpus = cpu_map__read(file);
439 struct perf_event_attr *__attribute__((weak))
440 perf_pmu__get_default_config(struct perf_pmu *pmu __maybe_unused)
445 static struct perf_pmu *pmu_lookup(const char *name)
447 struct perf_pmu *pmu;
452 /* No support for intel_bts or intel_pt so disallow them */
453 if (!strcmp(name, "intel_bts") || !strcmp(name, "intel_pt"))
457 * The pmu data we store & need consists of the pmu
458 * type value and format definitions. Load both right
461 if (pmu_format(name, &format))
464 if (pmu_aliases(name, &aliases))
467 if (pmu_type(name, &type))
470 pmu = zalloc(sizeof(*pmu));
474 pmu->cpus = pmu_cpumask(name);
476 INIT_LIST_HEAD(&pmu->format);
477 INIT_LIST_HEAD(&pmu->aliases);
478 list_splice(&format, &pmu->format);
479 list_splice(&aliases, &pmu->aliases);
480 pmu->name = strdup(name);
482 list_add_tail(&pmu->list, &pmus);
484 pmu->default_config = perf_pmu__get_default_config(pmu);
489 static struct perf_pmu *pmu_find(const char *name)
491 struct perf_pmu *pmu;
493 list_for_each_entry(pmu, &pmus, list)
494 if (!strcmp(pmu->name, name))
500 struct perf_pmu *perf_pmu__scan(struct perf_pmu *pmu)
503 * pmu iterator: If pmu is NULL, we start at the begin,
504 * otherwise return the next pmu. Returns NULL on end.
508 pmu = list_prepare_entry(pmu, &pmus, list);
510 list_for_each_entry_continue(pmu, &pmus, list)
515 struct perf_pmu *perf_pmu__find(const char *name)
517 struct perf_pmu *pmu;
520 * Once PMU is loaded it stays in the list,
521 * so we keep us from multiple reading/parsing
522 * the pmu format definitions.
524 pmu = pmu_find(name);
528 return pmu_lookup(name);
531 static struct perf_pmu_format *
532 pmu_find_format(struct list_head *formats, char *name)
534 struct perf_pmu_format *format;
536 list_for_each_entry(format, formats, list)
537 if (!strcmp(format->name, name))
544 * Sets value based on the format definition (format parameter)
545 * and unformated value (value parameter).
547 static void pmu_format_value(unsigned long *format, __u64 value, __u64 *v,
550 unsigned long fbit, vbit;
552 for (fbit = 0, vbit = 0; fbit < PERF_PMU_FORMAT_BITS; fbit++) {
554 if (!test_bit(fbit, format))
557 if (value & (1llu << vbit++))
558 *v |= (1llu << fbit);
560 *v &= ~(1llu << fbit);
565 * Term is a string term, and might be a param-term. Try to look up it's value
566 * in the remaining terms.
567 * - We have a term like "base-or-format-term=param-term",
568 * - We need to find the value supplied for "param-term" (with param-term named
569 * in a config string) later on in the term list.
571 static int pmu_resolve_param_term(struct parse_events_term *term,
572 struct list_head *head_terms,
575 struct parse_events_term *t;
577 list_for_each_entry(t, head_terms, list) {
578 if (t->type_val == PARSE_EVENTS__TERM_TYPE_NUM) {
579 if (!strcmp(t->config, term->config)) {
588 printf("Required parameter '%s' not specified\n", term->config);
593 static char *formats_error_string(struct list_head *formats)
595 struct perf_pmu_format *format;
597 static const char *static_terms = "config,config1,config2,name,period,branch_type\n";
600 if (!asprintf(&str, "valid terms:"))
603 /* sysfs exported terms */
604 list_for_each_entry(format, formats, list) {
605 char c = i++ ? ',' : ' ';
608 if (!asprintf(&str, "%s%c%s", err, c, format->name))
615 if (!asprintf(&str, "%s,%s", err, static_terms))
626 * Setup one of config[12] attr members based on the
627 * user input data - term parameter.
629 static int pmu_config_term(struct list_head *formats,
630 struct perf_event_attr *attr,
631 struct parse_events_term *term,
632 struct list_head *head_terms,
633 bool zero, struct parse_events_error *err)
635 struct perf_pmu_format *format;
640 * If this is a parameter we've already used for parameterized-eval,
641 * skip it in normal eval.
647 * Hardcoded terms should be already in, so nothing
648 * to be done for them.
650 if (parse_events__is_hardcoded_term(term))
653 format = pmu_find_format(formats, term->config);
656 printf("Invalid event/parameter '%s'\n", term->config);
658 err->idx = term->err_term;
659 err->str = strdup("unknown term");
660 err->help = formats_error_string(formats);
665 switch (format->value) {
666 case PERF_PMU_FORMAT_VALUE_CONFIG:
669 case PERF_PMU_FORMAT_VALUE_CONFIG1:
672 case PERF_PMU_FORMAT_VALUE_CONFIG2:
680 * Either directly use a numeric term, or try to translate string terms
681 * using event parameters.
683 if (term->type_val == PARSE_EVENTS__TERM_TYPE_NUM)
685 else if (term->type_val == PARSE_EVENTS__TERM_TYPE_STR) {
686 if (strcmp(term->val.str, "?")) {
688 pr_info("Invalid sysfs entry %s=%s\n",
689 term->config, term->val.str);
692 err->idx = term->err_val;
693 err->str = strdup("expected numeric value");
698 if (pmu_resolve_param_term(term, head_terms, &val))
703 pmu_format_value(format->bits, val, vp, zero);
707 int perf_pmu__config_terms(struct list_head *formats,
708 struct perf_event_attr *attr,
709 struct list_head *head_terms,
710 bool zero, struct parse_events_error *err)
712 struct parse_events_term *term;
714 list_for_each_entry(term, head_terms, list) {
715 if (pmu_config_term(formats, attr, term, head_terms,
724 * Configures event's 'attr' parameter based on the:
725 * 1) users input - specified in terms parameter
726 * 2) pmu format definitions - specified by pmu parameter
728 int perf_pmu__config(struct perf_pmu *pmu, struct perf_event_attr *attr,
729 struct list_head *head_terms,
730 struct parse_events_error *err)
732 bool zero = !!pmu->default_config;
734 attr->type = pmu->type;
735 return perf_pmu__config_terms(&pmu->format, attr, head_terms,
739 static struct perf_pmu_alias *pmu_find_alias(struct perf_pmu *pmu,
740 struct parse_events_term *term)
742 struct perf_pmu_alias *alias;
745 if (parse_events__is_hardcoded_term(term))
748 if (term->type_val == PARSE_EVENTS__TERM_TYPE_NUM) {
749 if (term->val.num != 1)
751 if (pmu_find_format(&pmu->format, term->config))
754 } else if (term->type_val == PARSE_EVENTS__TERM_TYPE_STR) {
755 if (strcasecmp(term->config, "event"))
757 name = term->val.str;
762 list_for_each_entry(alias, &pmu->aliases, list) {
763 if (!strcasecmp(alias->name, name))
770 static int check_info_data(struct perf_pmu_alias *alias,
771 struct perf_pmu_info *info)
774 * Only one term in event definition can
775 * define unit, scale and snapshot, fail
776 * if there's more than one.
778 if ((info->unit && alias->unit) ||
779 (info->scale && alias->scale) ||
780 (info->snapshot && alias->snapshot))
784 info->unit = alias->unit;
787 info->scale = alias->scale;
790 info->snapshot = alias->snapshot;
796 * Find alias in the terms list and replace it with the terms
797 * defined for the alias
799 int perf_pmu__check_alias(struct perf_pmu *pmu, struct list_head *head_terms,
800 struct perf_pmu_info *info)
802 struct parse_events_term *term, *h;
803 struct perf_pmu_alias *alias;
806 info->per_pkg = false;
809 * Mark unit and scale as not set
810 * (different from default values, see below)
814 info->snapshot = false;
816 list_for_each_entry_safe(term, h, head_terms, list) {
817 alias = pmu_find_alias(pmu, term);
820 ret = pmu_alias_terms(alias, &term->list);
824 ret = check_info_data(alias, info);
829 info->per_pkg = true;
831 list_del(&term->list);
836 * if no unit or scale foundin aliases, then
837 * set defaults as for evsel
838 * unit cannot left to NULL
840 if (info->unit == NULL)
843 if (info->scale == 0.0)
849 int perf_pmu__new_format(struct list_head *list, char *name,
850 int config, unsigned long *bits)
852 struct perf_pmu_format *format;
854 format = zalloc(sizeof(*format));
858 format->name = strdup(name);
859 format->value = config;
860 memcpy(format->bits, bits, sizeof(format->bits));
862 list_add_tail(&format->list, list);
866 void perf_pmu__set_format(unsigned long *bits, long from, long to)
873 memset(bits, 0, BITS_TO_BYTES(PERF_PMU_FORMAT_BITS));
874 for (b = from; b <= to; b++)
878 static int sub_non_neg(int a, int b)
885 static char *format_alias(char *buf, int len, struct perf_pmu *pmu,
886 struct perf_pmu_alias *alias)
888 struct parse_events_term *term;
889 int used = snprintf(buf, len, "%s/%s", pmu->name, alias->name);
891 list_for_each_entry(term, &alias->terms, list) {
892 if (term->type_val == PARSE_EVENTS__TERM_TYPE_STR)
893 used += snprintf(buf + used, sub_non_neg(len, used),
894 ",%s=%s", term->config,
898 if (sub_non_neg(len, used) > 0) {
902 if (sub_non_neg(len, used) > 0) {
911 static char *format_alias_or(char *buf, int len, struct perf_pmu *pmu,
912 struct perf_pmu_alias *alias)
914 snprintf(buf, len, "%s OR %s/%s/", alias->name, pmu->name, alias->name);
918 static int cmp_string(const void *a, const void *b)
920 const char * const *as = a;
921 const char * const *bs = b;
922 return strcmp(*as, *bs);
925 void print_pmu_events(const char *event_glob, bool name_only)
927 struct perf_pmu *pmu;
928 struct perf_pmu_alias *alias;
936 while ((pmu = perf_pmu__scan(pmu)) != NULL) {
937 list_for_each_entry(alias, &pmu->aliases, list)
942 aliases = zalloc(sizeof(char *) * len);
947 while ((pmu = perf_pmu__scan(pmu)) != NULL) {
948 list_for_each_entry(alias, &pmu->aliases, list) {
949 char *name = format_alias(buf, sizeof(buf), pmu, alias);
950 bool is_cpu = !strcmp(pmu->name, "cpu");
952 if (event_glob != NULL &&
953 !(strglobmatch(name, event_glob) ||
954 (!is_cpu && strglobmatch(alias->name,
958 if (is_cpu && !name_only)
959 name = format_alias_or(buf, sizeof(buf), pmu, alias);
961 aliases[j] = strdup(name);
962 if (aliases[j] == NULL)
966 if (pmu->selectable) {
968 if (asprintf(&s, "%s//", pmu->name) < 0)
975 qsort(aliases, len, sizeof(char *), cmp_string);
976 for (j = 0; j < len; j++) {
978 printf("%s ", aliases[j]);
981 printf(" %-50s [Kernel PMU event]\n", aliases[j]);
987 for (j = 0; j < len; j++)
993 printf("FATAL: not enough memory to print PMU events\n");
998 bool pmu_have_event(const char *pname, const char *name)
1000 struct perf_pmu *pmu;
1001 struct perf_pmu_alias *alias;
1004 while ((pmu = perf_pmu__scan(pmu)) != NULL) {
1005 if (strcmp(pname, pmu->name))
1007 list_for_each_entry(alias, &pmu->aliases, list)
1008 if (!strcmp(alias->name, name))
1014 static FILE *perf_pmu__open_file(struct perf_pmu *pmu, const char *name)
1017 char path[PATH_MAX];
1020 sysfs = sysfs__mountpoint();
1024 snprintf(path, PATH_MAX,
1025 "%s" EVENT_SOURCE_DEVICE_PATH "%s/%s", sysfs, pmu->name, name);
1027 if (stat(path, &st) < 0)
1030 return fopen(path, "r");
1033 int perf_pmu__scan_file(struct perf_pmu *pmu, const char *name, const char *fmt,
1040 va_start(args, fmt);
1041 file = perf_pmu__open_file(pmu, name);
1043 ret = vfscanf(file, fmt, args);