1 #include <linux/list.h>
12 #include "parse-events.h"
15 #define UNIT_MAX_LEN 31 /* max length for event unit name */
17 struct perf_pmu_alias {
19 struct list_head terms; /* HEAD struct parse_events_term -> list */
20 struct list_head list; /* ELEM */
21 char unit[UNIT_MAX_LEN+1];
25 struct perf_pmu_format {
28 DECLARE_BITMAP(bits, PERF_PMU_FORMAT_BITS);
29 struct list_head list;
32 #define EVENT_SOURCE_DEVICE_PATH "/bus/event_source/devices/"
34 int perf_pmu_parse(struct list_head *list, char *name);
35 extern FILE *perf_pmu_in;
37 static LIST_HEAD(pmus);
40 * Parse & process all the sysfs attributes located under
41 * the directory specified in 'dir' parameter.
43 int perf_pmu__format_parse(char *dir, struct list_head *head)
45 struct dirent *evt_ent;
49 format_dir = opendir(dir);
53 while (!ret && (evt_ent = readdir(format_dir))) {
55 char *name = evt_ent->d_name;
58 if (!strcmp(name, ".") || !strcmp(name, ".."))
61 snprintf(path, PATH_MAX, "%s/%s", dir, name);
64 file = fopen(path, "r");
69 ret = perf_pmu_parse(head, name);
78 * Reading/parsing the default pmu format definition, which should be
80 * /sys/bus/event_source/devices/<dev>/format as sysfs group attributes.
82 static int pmu_format(const char *name, struct list_head *format)
86 const char *sysfs = sysfs__mountpoint();
91 snprintf(path, PATH_MAX,
92 "%s" EVENT_SOURCE_DEVICE_PATH "%s/format", sysfs, name);
94 if (stat(path, &st) < 0)
95 return 0; /* no error if format does not exist */
97 if (perf_pmu__format_parse(path, format))
103 static int perf_pmu__parse_scale(struct perf_pmu_alias *alias, char *dir, char *name)
112 snprintf(path, PATH_MAX, "%s/%s.scale", dir, name);
114 fd = open(path, O_RDONLY);
118 if (fstat(fd, &st) < 0)
121 sret = read(fd, scale, sizeof(scale)-1);
127 * save current locale
129 lc = setlocale(LC_NUMERIC, NULL);
132 * force to C locale to ensure kernel
133 * scale string is converted correctly.
134 * kernel uses default C locale.
136 setlocale(LC_NUMERIC, "C");
138 alias->scale = strtod(scale, NULL);
141 setlocale(LC_NUMERIC, lc);
149 static int perf_pmu__parse_unit(struct perf_pmu_alias *alias, char *dir, char *name)
155 snprintf(path, PATH_MAX, "%s/%s.unit", dir, name);
157 fd = open(path, O_RDONLY);
161 sret = read(fd, alias->unit, UNIT_MAX_LEN);
167 alias->unit[sret] = '\0';
172 alias->unit[0] = '\0';
176 static int perf_pmu__new_alias(struct list_head *list, char *dir, char *name, FILE *file)
178 struct perf_pmu_alias *alias;
182 ret = fread(buf, 1, sizeof(buf), file);
187 alias = malloc(sizeof(*alias));
191 INIT_LIST_HEAD(&alias->terms);
193 alias->unit[0] = '\0';
195 ret = parse_events_terms(&alias->terms, buf);
201 alias->name = strdup(name);
203 * load unit name and scale if available
205 perf_pmu__parse_unit(alias, dir, name);
206 perf_pmu__parse_scale(alias, dir, name);
208 list_add_tail(&alias->list, list);
213 static inline bool pmu_alias_info_file(char *name)
218 if (len > 5 && !strcmp(name + len - 5, ".unit"))
220 if (len > 6 && !strcmp(name + len - 6, ".scale"))
227 * Process all the sysfs attributes located under the directory
228 * specified in 'dir' parameter.
230 static int pmu_aliases_parse(char *dir, struct list_head *head)
232 struct dirent *evt_ent;
236 event_dir = opendir(dir);
240 while (!ret && (evt_ent = readdir(event_dir))) {
242 char *name = evt_ent->d_name;
245 if (!strcmp(name, ".") || !strcmp(name, ".."))
249 * skip info files parsed in perf_pmu__new_alias()
251 if (pmu_alias_info_file(name))
254 snprintf(path, PATH_MAX, "%s/%s", dir, name);
257 file = fopen(path, "r");
261 ret = perf_pmu__new_alias(head, dir, name, file);
270 * Reading the pmu event aliases definition, which should be located at:
271 * /sys/bus/event_source/devices/<dev>/events as sysfs group attributes.
273 static int pmu_aliases(const char *name, struct list_head *head)
277 const char *sysfs = sysfs__mountpoint();
282 snprintf(path, PATH_MAX,
283 "%s/bus/event_source/devices/%s/events", sysfs, name);
285 if (stat(path, &st) < 0)
286 return 0; /* no error if 'events' does not exist */
288 if (pmu_aliases_parse(path, head))
294 static int pmu_alias_terms(struct perf_pmu_alias *alias,
295 struct list_head *terms)
297 struct parse_events_term *term, *cloned;
301 list_for_each_entry(term, &alias->terms, list) {
302 ret = parse_events_term__clone(&cloned, term);
304 parse_events__free_terms(&list);
307 list_add_tail(&cloned->list, &list);
309 list_splice(&list, terms);
314 * Reading/parsing the default pmu type value, which should be
316 * /sys/bus/event_source/devices/<dev>/type as sysfs attribute.
318 static int pmu_type(const char *name, __u32 *type)
324 const char *sysfs = sysfs__mountpoint();
329 snprintf(path, PATH_MAX,
330 "%s" EVENT_SOURCE_DEVICE_PATH "%s/type", sysfs, name);
332 if (stat(path, &st) < 0)
335 file = fopen(path, "r");
339 if (1 != fscanf(file, "%u", type))
346 /* Add all pmus in sysfs to pmu list: */
347 static void pmu_read_sysfs(void)
352 const char *sysfs = sysfs__mountpoint();
357 snprintf(path, PATH_MAX,
358 "%s" EVENT_SOURCE_DEVICE_PATH, sysfs);
364 while ((dent = readdir(dir))) {
365 if (!strcmp(dent->d_name, ".") || !strcmp(dent->d_name, ".."))
367 /* add to static LIST_HEAD(pmus): */
368 perf_pmu__find(dent->d_name);
374 static struct cpu_map *pmu_cpumask(const char *name)
379 struct cpu_map *cpus;
380 const char *sysfs = sysfs__mountpoint();
385 snprintf(path, PATH_MAX,
386 "%s/bus/event_source/devices/%s/cpumask", sysfs, name);
388 if (stat(path, &st) < 0)
391 file = fopen(path, "r");
395 cpus = cpu_map__read(file);
400 struct perf_event_attr *__attribute__((weak))
401 perf_pmu__get_default_config(struct perf_pmu *pmu __maybe_unused)
406 static struct perf_pmu *pmu_lookup(const char *name)
408 struct perf_pmu *pmu;
414 * The pmu data we store & need consists of the pmu
415 * type value and format definitions. Load both right
418 if (pmu_format(name, &format))
421 if (pmu_aliases(name, &aliases))
424 if (pmu_type(name, &type))
427 pmu = zalloc(sizeof(*pmu));
431 pmu->cpus = pmu_cpumask(name);
433 INIT_LIST_HEAD(&pmu->format);
434 INIT_LIST_HEAD(&pmu->aliases);
435 list_splice(&format, &pmu->format);
436 list_splice(&aliases, &pmu->aliases);
437 pmu->name = strdup(name);
439 list_add_tail(&pmu->list, &pmus);
441 pmu->default_config = perf_pmu__get_default_config(pmu);
446 static struct perf_pmu *pmu_find(const char *name)
448 struct perf_pmu *pmu;
450 list_for_each_entry(pmu, &pmus, list)
451 if (!strcmp(pmu->name, name))
457 struct perf_pmu *perf_pmu__scan(struct perf_pmu *pmu)
460 * pmu iterator: If pmu is NULL, we start at the begin,
461 * otherwise return the next pmu. Returns NULL on end.
465 pmu = list_prepare_entry(pmu, &pmus, list);
467 list_for_each_entry_continue(pmu, &pmus, list)
472 struct perf_pmu *perf_pmu__find(const char *name)
474 struct perf_pmu *pmu;
477 * Once PMU is loaded it stays in the list,
478 * so we keep us from multiple reading/parsing
479 * the pmu format definitions.
481 pmu = pmu_find(name);
485 return pmu_lookup(name);
488 static struct perf_pmu_format *
489 pmu_find_format(struct list_head *formats, char *name)
491 struct perf_pmu_format *format;
493 list_for_each_entry(format, formats, list)
494 if (!strcmp(format->name, name))
501 * Sets value based on the format definition (format parameter)
502 * and unformated value (value parameter).
504 static void pmu_format_value(unsigned long *format, __u64 value, __u64 *v,
507 unsigned long fbit, vbit;
509 for (fbit = 0, vbit = 0; fbit < PERF_PMU_FORMAT_BITS; fbit++) {
511 if (!test_bit(fbit, format))
514 if (value & (1llu << vbit++))
515 *v |= (1llu << fbit);
517 *v &= ~(1llu << fbit);
522 * Setup one of config[12] attr members based on the
523 * user input data - term parameter.
525 static int pmu_config_term(struct list_head *formats,
526 struct perf_event_attr *attr,
527 struct parse_events_term *term,
530 struct perf_pmu_format *format;
534 * Support only for hardcoded and numnerial terms.
535 * Hardcoded terms should be already in, so nothing
536 * to be done for them.
538 if (parse_events__is_hardcoded_term(term))
541 if (term->type_val != PARSE_EVENTS__TERM_TYPE_NUM)
544 format = pmu_find_format(formats, term->config);
548 switch (format->value) {
549 case PERF_PMU_FORMAT_VALUE_CONFIG:
552 case PERF_PMU_FORMAT_VALUE_CONFIG1:
555 case PERF_PMU_FORMAT_VALUE_CONFIG2:
563 * XXX If we ever decide to go with string values for
564 * non-hardcoded terms, here's the place to translate
567 pmu_format_value(format->bits, term->val.num, vp, zero);
571 int perf_pmu__config_terms(struct list_head *formats,
572 struct perf_event_attr *attr,
573 struct list_head *head_terms,
576 struct parse_events_term *term;
578 list_for_each_entry(term, head_terms, list)
579 if (pmu_config_term(formats, attr, term, zero))
586 * Configures event's 'attr' parameter based on the:
587 * 1) users input - specified in terms parameter
588 * 2) pmu format definitions - specified by pmu parameter
590 int perf_pmu__config(struct perf_pmu *pmu, struct perf_event_attr *attr,
591 struct list_head *head_terms)
593 bool zero = !!pmu->default_config;
595 attr->type = pmu->type;
596 return perf_pmu__config_terms(&pmu->format, attr, head_terms, zero);
599 static struct perf_pmu_alias *pmu_find_alias(struct perf_pmu *pmu,
600 struct parse_events_term *term)
602 struct perf_pmu_alias *alias;
605 if (parse_events__is_hardcoded_term(term))
608 if (term->type_val == PARSE_EVENTS__TERM_TYPE_NUM) {
609 if (term->val.num != 1)
611 if (pmu_find_format(&pmu->format, term->config))
614 } else if (term->type_val == PARSE_EVENTS__TERM_TYPE_STR) {
615 if (strcasecmp(term->config, "event"))
617 name = term->val.str;
622 list_for_each_entry(alias, &pmu->aliases, list) {
623 if (!strcasecmp(alias->name, name))
630 static int check_unit_scale(struct perf_pmu_alias *alias,
631 const char **unit, double *scale)
634 * Only one term in event definition can
635 * define unit and scale, fail if there's
638 if ((*unit && alias->unit) ||
639 (*scale && alias->scale))
646 *scale = alias->scale;
652 * Find alias in the terms list and replace it with the terms
653 * defined for the alias
655 int perf_pmu__check_alias(struct perf_pmu *pmu, struct list_head *head_terms,
656 struct perf_pmu_info *info)
658 struct parse_events_term *term, *h;
659 struct perf_pmu_alias *alias;
663 * Mark unit and scale as not set
664 * (different from default values, see below)
669 list_for_each_entry_safe(term, h, head_terms, list) {
670 alias = pmu_find_alias(pmu, term);
673 ret = pmu_alias_terms(alias, &term->list);
677 ret = check_unit_scale(alias, &info->unit, &info->scale);
681 list_del(&term->list);
686 * if no unit or scale foundin aliases, then
687 * set defaults as for evsel
688 * unit cannot left to NULL
690 if (info->unit == NULL)
693 if (info->scale == 0.0)
699 int perf_pmu__new_format(struct list_head *list, char *name,
700 int config, unsigned long *bits)
702 struct perf_pmu_format *format;
704 format = zalloc(sizeof(*format));
708 format->name = strdup(name);
709 format->value = config;
710 memcpy(format->bits, bits, sizeof(format->bits));
712 list_add_tail(&format->list, list);
716 void perf_pmu__set_format(unsigned long *bits, long from, long to)
723 memset(bits, 0, BITS_TO_BYTES(PERF_PMU_FORMAT_BITS));
724 for (b = from; b <= to; b++)
728 static char *format_alias(char *buf, int len, struct perf_pmu *pmu,
729 struct perf_pmu_alias *alias)
731 snprintf(buf, len, "%s/%s/", pmu->name, alias->name);
735 static char *format_alias_or(char *buf, int len, struct perf_pmu *pmu,
736 struct perf_pmu_alias *alias)
738 snprintf(buf, len, "%s OR %s/%s/", alias->name, pmu->name, alias->name);
742 static int cmp_string(const void *a, const void *b)
744 const char * const *as = a;
745 const char * const *bs = b;
746 return strcmp(*as, *bs);
749 void print_pmu_events(const char *event_glob, bool name_only)
751 struct perf_pmu *pmu;
752 struct perf_pmu_alias *alias;
760 while ((pmu = perf_pmu__scan(pmu)) != NULL)
761 list_for_each_entry(alias, &pmu->aliases, list)
763 aliases = malloc(sizeof(char *) * len);
768 while ((pmu = perf_pmu__scan(pmu)) != NULL)
769 list_for_each_entry(alias, &pmu->aliases, list) {
770 char *name = format_alias(buf, sizeof(buf), pmu, alias);
771 bool is_cpu = !strcmp(pmu->name, "cpu");
773 if (event_glob != NULL &&
774 !(strglobmatch(name, event_glob) ||
775 (!is_cpu && strglobmatch(alias->name,
779 if (is_cpu && !name_only)
780 aliases[j] = format_alias_or(buf, sizeof(buf),
782 aliases[j] = strdup(aliases[j]);
786 qsort(aliases, len, sizeof(char *), cmp_string);
787 for (j = 0; j < len; j++) {
789 printf("%s ", aliases[j]);
792 printf(" %-50s [Kernel PMU event]\n", aliases[j]);
801 bool pmu_have_event(const char *pname, const char *name)
803 struct perf_pmu *pmu;
804 struct perf_pmu_alias *alias;
807 while ((pmu = perf_pmu__scan(pmu)) != NULL) {
808 if (strcmp(pname, pmu->name))
810 list_for_each_entry(alias, &pmu->aliases, list)
811 if (!strcmp(alias->name, name))
817 static FILE *perf_pmu__open_file(struct perf_pmu *pmu, const char *name)
823 sysfs = sysfs__mountpoint();
827 snprintf(path, PATH_MAX,
828 "%s" EVENT_SOURCE_DEVICE_PATH "%s/%s", sysfs, pmu->name, name);
830 if (stat(path, &st) < 0)
833 return fopen(path, "r");
836 int perf_pmu__scan_file(struct perf_pmu *pmu, const char *name, const char *fmt,
844 file = perf_pmu__open_file(pmu, name);
846 ret = vfscanf(file, fmt, args);