1 #include <linux/list.h>
10 #include "parse-events.h"
13 #define UNIT_MAX_LEN 31 /* max length for event unit name */
15 struct perf_pmu_alias
{
17 struct list_head terms
;
18 struct list_head list
;
19 char unit
[UNIT_MAX_LEN
+1];
23 struct perf_pmu_format
{
26 DECLARE_BITMAP(bits
, PERF_PMU_FORMAT_BITS
);
27 struct list_head list
;
30 #define EVENT_SOURCE_DEVICE_PATH "/bus/event_source/devices/"
32 int perf_pmu_parse(struct list_head
*list
, char *name
);
33 extern FILE *perf_pmu_in
;
35 static LIST_HEAD(pmus
);
38 * Parse & process all the sysfs attributes located under
39 * the directory specified in 'dir' parameter.
41 int perf_pmu__format_parse(char *dir
, struct list_head
*head
)
43 struct dirent
*evt_ent
;
47 format_dir
= opendir(dir
);
51 while (!ret
&& (evt_ent
= readdir(format_dir
))) {
53 char *name
= evt_ent
->d_name
;
56 if (!strcmp(name
, ".") || !strcmp(name
, ".."))
59 snprintf(path
, PATH_MAX
, "%s/%s", dir
, name
);
62 file
= fopen(path
, "r");
67 ret
= perf_pmu_parse(head
, name
);
76 * Reading/parsing the default pmu format definition, which should be
78 * /sys/bus/event_source/devices/<dev>/format as sysfs group attributes.
80 static int pmu_format(const char *name
, struct list_head
*format
)
84 const char *sysfs
= sysfs__mountpoint();
89 snprintf(path
, PATH_MAX
,
90 "%s" EVENT_SOURCE_DEVICE_PATH
"%s/format", sysfs
, name
);
92 if (stat(path
, &st
) < 0)
93 return 0; /* no error if format does not exist */
95 if (perf_pmu__format_parse(path
, format
))
101 static int perf_pmu__parse_scale(struct perf_pmu_alias
*alias
, char *dir
, char *name
)
110 snprintf(path
, PATH_MAX
, "%s/%s.scale", dir
, name
);
112 fd
= open(path
, O_RDONLY
);
116 if (fstat(fd
, &st
) < 0)
119 sret
= read(fd
, scale
, sizeof(scale
)-1);
125 * save current locale
127 lc
= setlocale(LC_NUMERIC
, NULL
);
130 * force to C locale to ensure kernel
131 * scale string is converted correctly.
132 * kernel uses default C locale.
134 setlocale(LC_NUMERIC
, "C");
136 alias
->scale
= strtod(scale
, NULL
);
139 setlocale(LC_NUMERIC
, lc
);
147 static int perf_pmu__parse_unit(struct perf_pmu_alias
*alias
, char *dir
, char *name
)
153 snprintf(path
, PATH_MAX
, "%s/%s.unit", dir
, name
);
155 fd
= open(path
, O_RDONLY
);
159 sret
= read(fd
, alias
->unit
, UNIT_MAX_LEN
);
165 alias
->unit
[sret
] = '\0';
170 alias
->unit
[0] = '\0';
174 static int perf_pmu__new_alias(struct list_head
*list
, char *dir
, char *name
, FILE *file
)
176 struct perf_pmu_alias
*alias
;
180 ret
= fread(buf
, 1, sizeof(buf
), file
);
185 alias
= malloc(sizeof(*alias
));
189 INIT_LIST_HEAD(&alias
->terms
);
191 alias
->unit
[0] = '\0';
193 ret
= parse_events_terms(&alias
->terms
, buf
);
199 alias
->name
= strdup(name
);
201 * load unit name and scale if available
203 perf_pmu__parse_unit(alias
, dir
, name
);
204 perf_pmu__parse_scale(alias
, dir
, name
);
206 list_add_tail(&alias
->list
, list
);
212 * Process all the sysfs attributes located under the directory
213 * specified in 'dir' parameter.
215 static int pmu_aliases_parse(char *dir
, struct list_head
*head
)
217 struct dirent
*evt_ent
;
222 event_dir
= opendir(dir
);
226 while (!ret
&& (evt_ent
= readdir(event_dir
))) {
228 char *name
= evt_ent
->d_name
;
231 if (!strcmp(name
, ".") || !strcmp(name
, ".."))
235 * skip .unit and .scale info files
236 * parsed in perf_pmu__new_alias()
239 if (len
> 5 && !strcmp(name
+ len
- 5, ".unit"))
241 if (len
> 6 && !strcmp(name
+ len
- 6, ".scale"))
244 snprintf(path
, PATH_MAX
, "%s/%s", dir
, name
);
247 file
= fopen(path
, "r");
251 ret
= perf_pmu__new_alias(head
, dir
, name
, file
);
260 * Reading the pmu event aliases definition, which should be located at:
261 * /sys/bus/event_source/devices/<dev>/events as sysfs group attributes.
263 static int pmu_aliases(const char *name
, struct list_head
*head
)
267 const char *sysfs
= sysfs__mountpoint();
272 snprintf(path
, PATH_MAX
,
273 "%s/bus/event_source/devices/%s/events", sysfs
, name
);
275 if (stat(path
, &st
) < 0)
276 return 0; /* no error if 'events' does not exist */
278 if (pmu_aliases_parse(path
, head
))
284 static int pmu_alias_terms(struct perf_pmu_alias
*alias
,
285 struct list_head
*terms
)
287 struct parse_events_term
*term
, *cloned
;
291 list_for_each_entry(term
, &alias
->terms
, list
) {
292 ret
= parse_events_term__clone(&cloned
, term
);
294 parse_events__free_terms(&list
);
297 list_add_tail(&cloned
->list
, &list
);
299 list_splice(&list
, terms
);
304 * Reading/parsing the default pmu type value, which should be
306 * /sys/bus/event_source/devices/<dev>/type as sysfs attribute.
308 static int pmu_type(const char *name
, __u32
*type
)
314 const char *sysfs
= sysfs__mountpoint();
319 snprintf(path
, PATH_MAX
,
320 "%s" EVENT_SOURCE_DEVICE_PATH
"%s/type", sysfs
, name
);
322 if (stat(path
, &st
) < 0)
325 file
= fopen(path
, "r");
329 if (1 != fscanf(file
, "%u", type
))
336 /* Add all pmus in sysfs to pmu list: */
337 static void pmu_read_sysfs(void)
342 const char *sysfs
= sysfs__mountpoint();
347 snprintf(path
, PATH_MAX
,
348 "%s" EVENT_SOURCE_DEVICE_PATH
, sysfs
);
354 while ((dent
= readdir(dir
))) {
355 if (!strcmp(dent
->d_name
, ".") || !strcmp(dent
->d_name
, ".."))
357 /* add to static LIST_HEAD(pmus): */
358 perf_pmu__find(dent
->d_name
);
364 static struct cpu_map
*pmu_cpumask(const char *name
)
369 struct cpu_map
*cpus
;
370 const char *sysfs
= sysfs__mountpoint();
375 snprintf(path
, PATH_MAX
,
376 "%s/bus/event_source/devices/%s/cpumask", sysfs
, name
);
378 if (stat(path
, &st
) < 0)
381 file
= fopen(path
, "r");
385 cpus
= cpu_map__read(file
);
390 static struct perf_pmu
*pmu_lookup(const char *name
)
392 struct perf_pmu
*pmu
;
398 * The pmu data we store & need consists of the pmu
399 * type value and format definitions. Load both right
402 if (pmu_format(name
, &format
))
405 if (pmu_aliases(name
, &aliases
))
408 if (pmu_type(name
, &type
))
411 pmu
= zalloc(sizeof(*pmu
));
415 pmu
->cpus
= pmu_cpumask(name
);
417 INIT_LIST_HEAD(&pmu
->format
);
418 INIT_LIST_HEAD(&pmu
->aliases
);
419 list_splice(&format
, &pmu
->format
);
420 list_splice(&aliases
, &pmu
->aliases
);
421 pmu
->name
= strdup(name
);
423 list_add_tail(&pmu
->list
, &pmus
);
427 static struct perf_pmu
*pmu_find(const char *name
)
429 struct perf_pmu
*pmu
;
431 list_for_each_entry(pmu
, &pmus
, list
)
432 if (!strcmp(pmu
->name
, name
))
438 struct perf_pmu
*perf_pmu__scan(struct perf_pmu
*pmu
)
441 * pmu iterator: If pmu is NULL, we start at the begin,
442 * otherwise return the next pmu. Returns NULL on end.
446 pmu
= list_prepare_entry(pmu
, &pmus
, list
);
448 list_for_each_entry_continue(pmu
, &pmus
, list
)
453 struct perf_pmu
*perf_pmu__find(const char *name
)
455 struct perf_pmu
*pmu
;
458 * Once PMU is loaded it stays in the list,
459 * so we keep us from multiple reading/parsing
460 * the pmu format definitions.
462 pmu
= pmu_find(name
);
466 return pmu_lookup(name
);
469 static struct perf_pmu_format
*
470 pmu_find_format(struct list_head
*formats
, char *name
)
472 struct perf_pmu_format
*format
;
474 list_for_each_entry(format
, formats
, list
)
475 if (!strcmp(format
->name
, name
))
482 * Returns value based on the format definition (format parameter)
483 * and unformated value (value parameter).
485 * TODO maybe optimize a little ;)
487 static __u64
pmu_format_value(unsigned long *format
, __u64 value
)
489 unsigned long fbit
, vbit
;
492 for (fbit
= 0, vbit
= 0; fbit
< PERF_PMU_FORMAT_BITS
; fbit
++) {
494 if (!test_bit(fbit
, format
))
497 if (!(value
& (1llu << vbit
++)))
507 * Setup one of config[12] attr members based on the
508 * user input data - term parameter.
510 static int pmu_config_term(struct list_head
*formats
,
511 struct perf_event_attr
*attr
,
512 struct parse_events_term
*term
)
514 struct perf_pmu_format
*format
;
518 * Support only for hardcoded and numnerial terms.
519 * Hardcoded terms should be already in, so nothing
520 * to be done for them.
522 if (parse_events__is_hardcoded_term(term
))
525 if (term
->type_val
!= PARSE_EVENTS__TERM_TYPE_NUM
)
528 format
= pmu_find_format(formats
, term
->config
);
532 switch (format
->value
) {
533 case PERF_PMU_FORMAT_VALUE_CONFIG
:
536 case PERF_PMU_FORMAT_VALUE_CONFIG1
:
539 case PERF_PMU_FORMAT_VALUE_CONFIG2
:
547 * XXX If we ever decide to go with string values for
548 * non-hardcoded terms, here's the place to translate
551 *vp
|= pmu_format_value(format
->bits
, term
->val
.num
);
555 int perf_pmu__config_terms(struct list_head
*formats
,
556 struct perf_event_attr
*attr
,
557 struct list_head
*head_terms
)
559 struct parse_events_term
*term
;
561 list_for_each_entry(term
, head_terms
, list
)
562 if (pmu_config_term(formats
, attr
, term
))
569 * Configures event's 'attr' parameter based on the:
570 * 1) users input - specified in terms parameter
571 * 2) pmu format definitions - specified by pmu parameter
573 int perf_pmu__config(struct perf_pmu
*pmu
, struct perf_event_attr
*attr
,
574 struct list_head
*head_terms
)
576 attr
->type
= pmu
->type
;
577 return perf_pmu__config_terms(&pmu
->format
, attr
, head_terms
);
580 static struct perf_pmu_alias
*pmu_find_alias(struct perf_pmu
*pmu
,
581 struct parse_events_term
*term
)
583 struct perf_pmu_alias
*alias
;
586 if (parse_events__is_hardcoded_term(term
))
589 if (term
->type_val
== PARSE_EVENTS__TERM_TYPE_NUM
) {
590 if (term
->val
.num
!= 1)
592 if (pmu_find_format(&pmu
->format
, term
->config
))
595 } else if (term
->type_val
== PARSE_EVENTS__TERM_TYPE_STR
) {
596 if (strcasecmp(term
->config
, "event"))
598 name
= term
->val
.str
;
603 list_for_each_entry(alias
, &pmu
->aliases
, list
) {
604 if (!strcasecmp(alias
->name
, name
))
611 static int check_unit_scale(struct perf_pmu_alias
*alias
,
612 const char **unit
, double *scale
)
615 * Only one term in event definition can
616 * define unit and scale, fail if there's
619 if ((*unit
&& alias
->unit
) ||
620 (*scale
&& alias
->scale
))
627 *scale
= alias
->scale
;
633 * Find alias in the terms list and replace it with the terms
634 * defined for the alias
636 int perf_pmu__check_alias(struct perf_pmu
*pmu
, struct list_head
*head_terms
,
637 const char **unit
, double *scale
)
639 struct parse_events_term
*term
, *h
;
640 struct perf_pmu_alias
*alias
;
644 * Mark unit and scale as not set
645 * (different from default values, see below)
650 list_for_each_entry_safe(term
, h
, head_terms
, list
) {
651 alias
= pmu_find_alias(pmu
, term
);
654 ret
= pmu_alias_terms(alias
, &term
->list
);
658 ret
= check_unit_scale(alias
, unit
, scale
);
662 list_del(&term
->list
);
667 * if no unit or scale foundin aliases, then
668 * set defaults as for evsel
669 * unit cannot left to NULL
680 int perf_pmu__new_format(struct list_head
*list
, char *name
,
681 int config
, unsigned long *bits
)
683 struct perf_pmu_format
*format
;
685 format
= zalloc(sizeof(*format
));
689 format
->name
= strdup(name
);
690 format
->value
= config
;
691 memcpy(format
->bits
, bits
, sizeof(format
->bits
));
693 list_add_tail(&format
->list
, list
);
697 void perf_pmu__set_format(unsigned long *bits
, long from
, long to
)
704 memset(bits
, 0, BITS_TO_BYTES(PERF_PMU_FORMAT_BITS
));
705 for (b
= from
; b
<= to
; b
++)
709 static char *format_alias(char *buf
, int len
, struct perf_pmu
*pmu
,
710 struct perf_pmu_alias
*alias
)
712 snprintf(buf
, len
, "%s/%s/", pmu
->name
, alias
->name
);
716 static char *format_alias_or(char *buf
, int len
, struct perf_pmu
*pmu
,
717 struct perf_pmu_alias
*alias
)
719 snprintf(buf
, len
, "%s OR %s/%s/", alias
->name
, pmu
->name
, alias
->name
);
723 static int cmp_string(const void *a
, const void *b
)
725 const char * const *as
= a
;
726 const char * const *bs
= b
;
727 return strcmp(*as
, *bs
);
730 void print_pmu_events(const char *event_glob
, bool name_only
)
732 struct perf_pmu
*pmu
;
733 struct perf_pmu_alias
*alias
;
741 while ((pmu
= perf_pmu__scan(pmu
)) != NULL
)
742 list_for_each_entry(alias
, &pmu
->aliases
, list
)
744 aliases
= malloc(sizeof(char *) * len
);
749 while ((pmu
= perf_pmu__scan(pmu
)) != NULL
)
750 list_for_each_entry(alias
, &pmu
->aliases
, list
) {
751 char *name
= format_alias(buf
, sizeof(buf
), pmu
, alias
);
752 bool is_cpu
= !strcmp(pmu
->name
, "cpu");
754 if (event_glob
!= NULL
&&
755 !(strglobmatch(name
, event_glob
) ||
756 (!is_cpu
&& strglobmatch(alias
->name
,
760 if (is_cpu
&& !name_only
)
761 aliases
[j
] = format_alias_or(buf
, sizeof(buf
),
763 aliases
[j
] = strdup(aliases
[j
]);
767 qsort(aliases
, len
, sizeof(char *), cmp_string
);
768 for (j
= 0; j
< len
; j
++) {
770 printf("%s ", aliases
[j
]);
773 printf(" %-50s [Kernel PMU event]\n", aliases
[j
]);
782 bool pmu_have_event(const char *pname
, const char *name
)
784 struct perf_pmu
*pmu
;
785 struct perf_pmu_alias
*alias
;
788 while ((pmu
= perf_pmu__scan(pmu
)) != NULL
) {
789 if (strcmp(pname
, pmu
->name
))
791 list_for_each_entry(alias
, &pmu
->aliases
, list
)
792 if (!strcmp(alias
->name
, name
))