perf pmu: Add a perf_pmu__fake object to use with __parse_events()
[linux-2.6-microblaze.git] / tools / perf / util / pmu.c
1 // SPDX-License-Identifier: GPL-2.0
2 #include <linux/list.h>
3 #include <linux/compiler.h>
4 #include <linux/string.h>
5 #include <linux/zalloc.h>
6 #include <subcmd/pager.h>
7 #include <sys/types.h>
8 #include <errno.h>
9 #include <fcntl.h>
10 #include <sys/stat.h>
11 #include <unistd.h>
12 #include <stdio.h>
13 #include <stdbool.h>
14 #include <stdarg.h>
15 #include <dirent.h>
16 #include <api/fs/fs.h>
17 #include <locale.h>
18 #include <regex.h>
19 #include <perf/cpumap.h>
20 #include "debug.h"
21 #include "evsel.h"
22 #include "pmu.h"
23 #include "parse-events.h"
24 #include "header.h"
25 #include "string2.h"
26 #include "strbuf.h"
27 #include "fncache.h"
28
29 struct perf_pmu perf_pmu__fake;
30
31 struct perf_pmu_format {
32         char *name;
33         int value;
34         DECLARE_BITMAP(bits, PERF_PMU_FORMAT_BITS);
35         struct list_head list;
36 };
37
38 int perf_pmu_parse(struct list_head *list, char *name);
39 extern FILE *perf_pmu_in;
40
41 static LIST_HEAD(pmus);
42
43 /*
44  * Parse & process all the sysfs attributes located under
45  * the directory specified in 'dir' parameter.
46  */
47 int perf_pmu__format_parse(char *dir, struct list_head *head)
48 {
49         struct dirent *evt_ent;
50         DIR *format_dir;
51         int ret = 0;
52
53         format_dir = opendir(dir);
54         if (!format_dir)
55                 return -EINVAL;
56
57         while (!ret && (evt_ent = readdir(format_dir))) {
58                 char path[PATH_MAX];
59                 char *name = evt_ent->d_name;
60                 FILE *file;
61
62                 if (!strcmp(name, ".") || !strcmp(name, ".."))
63                         continue;
64
65                 snprintf(path, PATH_MAX, "%s/%s", dir, name);
66
67                 ret = -EINVAL;
68                 file = fopen(path, "r");
69                 if (!file)
70                         break;
71
72                 perf_pmu_in = file;
73                 ret = perf_pmu_parse(head, name);
74                 fclose(file);
75         }
76
77         closedir(format_dir);
78         return ret;
79 }
80
81 /*
82  * Reading/parsing the default pmu format definition, which should be
83  * located at:
84  * /sys/bus/event_source/devices/<dev>/format as sysfs group attributes.
85  */
86 static int pmu_format(const char *name, struct list_head *format)
87 {
88         char path[PATH_MAX];
89         const char *sysfs = sysfs__mountpoint();
90
91         if (!sysfs)
92                 return -1;
93
94         snprintf(path, PATH_MAX,
95                  "%s" EVENT_SOURCE_DEVICE_PATH "%s/format", sysfs, name);
96
97         if (!file_available(path))
98                 return 0;
99
100         if (perf_pmu__format_parse(path, format))
101                 return -1;
102
103         return 0;
104 }
105
106 int perf_pmu__convert_scale(const char *scale, char **end, double *sval)
107 {
108         char *lc;
109         int ret = 0;
110
111         /*
112          * save current locale
113          */
114         lc = setlocale(LC_NUMERIC, NULL);
115
116         /*
117          * The lc string may be allocated in static storage,
118          * so get a dynamic copy to make it survive setlocale
119          * call below.
120          */
121         lc = strdup(lc);
122         if (!lc) {
123                 ret = -ENOMEM;
124                 goto out;
125         }
126
127         /*
128          * force to C locale to ensure kernel
129          * scale string is converted correctly.
130          * kernel uses default C locale.
131          */
132         setlocale(LC_NUMERIC, "C");
133
134         *sval = strtod(scale, end);
135
136 out:
137         /* restore locale */
138         setlocale(LC_NUMERIC, lc);
139         free(lc);
140         return ret;
141 }
142
143 static int perf_pmu__parse_scale(struct perf_pmu_alias *alias, char *dir, char *name)
144 {
145         struct stat st;
146         ssize_t sret;
147         char scale[128];
148         int fd, ret = -1;
149         char path[PATH_MAX];
150
151         scnprintf(path, PATH_MAX, "%s/%s.scale", dir, name);
152
153         fd = open(path, O_RDONLY);
154         if (fd == -1)
155                 return -1;
156
157         if (fstat(fd, &st) < 0)
158                 goto error;
159
160         sret = read(fd, scale, sizeof(scale)-1);
161         if (sret < 0)
162                 goto error;
163
164         if (scale[sret - 1] == '\n')
165                 scale[sret - 1] = '\0';
166         else
167                 scale[sret] = '\0';
168
169         ret = perf_pmu__convert_scale(scale, NULL, &alias->scale);
170 error:
171         close(fd);
172         return ret;
173 }
174
175 static int perf_pmu__parse_unit(struct perf_pmu_alias *alias, char *dir, char *name)
176 {
177         char path[PATH_MAX];
178         ssize_t sret;
179         int fd;
180
181         scnprintf(path, PATH_MAX, "%s/%s.unit", dir, name);
182
183         fd = open(path, O_RDONLY);
184         if (fd == -1)
185                 return -1;
186
187         sret = read(fd, alias->unit, UNIT_MAX_LEN);
188         if (sret < 0)
189                 goto error;
190
191         close(fd);
192
193         if (alias->unit[sret - 1] == '\n')
194                 alias->unit[sret - 1] = '\0';
195         else
196                 alias->unit[sret] = '\0';
197
198         return 0;
199 error:
200         close(fd);
201         alias->unit[0] = '\0';
202         return -1;
203 }
204
205 static int
206 perf_pmu__parse_per_pkg(struct perf_pmu_alias *alias, char *dir, char *name)
207 {
208         char path[PATH_MAX];
209         int fd;
210
211         scnprintf(path, PATH_MAX, "%s/%s.per-pkg", dir, name);
212
213         fd = open(path, O_RDONLY);
214         if (fd == -1)
215                 return -1;
216
217         close(fd);
218
219         alias->per_pkg = true;
220         return 0;
221 }
222
223 static int perf_pmu__parse_snapshot(struct perf_pmu_alias *alias,
224                                     char *dir, char *name)
225 {
226         char path[PATH_MAX];
227         int fd;
228
229         scnprintf(path, PATH_MAX, "%s/%s.snapshot", dir, name);
230
231         fd = open(path, O_RDONLY);
232         if (fd == -1)
233                 return -1;
234
235         alias->snapshot = true;
236         close(fd);
237         return 0;
238 }
239
240 static void perf_pmu_assign_str(char *name, const char *field, char **old_str,
241                                 char **new_str)
242 {
243         if (!*old_str)
244                 goto set_new;
245
246         if (*new_str) { /* Have new string, check with old */
247                 if (strcasecmp(*old_str, *new_str))
248                         pr_debug("alias %s differs in field '%s'\n",
249                                  name, field);
250                 zfree(old_str);
251         } else          /* Nothing new --> keep old string */
252                 return;
253 set_new:
254         *old_str = *new_str;
255         *new_str = NULL;
256 }
257
258 static void perf_pmu_update_alias(struct perf_pmu_alias *old,
259                                   struct perf_pmu_alias *newalias)
260 {
261         perf_pmu_assign_str(old->name, "desc", &old->desc, &newalias->desc);
262         perf_pmu_assign_str(old->name, "long_desc", &old->long_desc,
263                             &newalias->long_desc);
264         perf_pmu_assign_str(old->name, "topic", &old->topic, &newalias->topic);
265         perf_pmu_assign_str(old->name, "metric_expr", &old->metric_expr,
266                             &newalias->metric_expr);
267         perf_pmu_assign_str(old->name, "metric_name", &old->metric_name,
268                             &newalias->metric_name);
269         perf_pmu_assign_str(old->name, "value", &old->str, &newalias->str);
270         old->scale = newalias->scale;
271         old->per_pkg = newalias->per_pkg;
272         old->snapshot = newalias->snapshot;
273         memcpy(old->unit, newalias->unit, sizeof(old->unit));
274 }
275
276 /* Delete an alias entry. */
277 static void perf_pmu_free_alias(struct perf_pmu_alias *newalias)
278 {
279         zfree(&newalias->name);
280         zfree(&newalias->desc);
281         zfree(&newalias->long_desc);
282         zfree(&newalias->topic);
283         zfree(&newalias->str);
284         zfree(&newalias->metric_expr);
285         zfree(&newalias->metric_name);
286         parse_events_terms__purge(&newalias->terms);
287         free(newalias);
288 }
289
290 /* Merge an alias, search in alias list. If this name is already
291  * present merge both of them to combine all information.
292  */
293 static bool perf_pmu_merge_alias(struct perf_pmu_alias *newalias,
294                                  struct list_head *alist)
295 {
296         struct perf_pmu_alias *a;
297
298         list_for_each_entry(a, alist, list) {
299                 if (!strcasecmp(newalias->name, a->name)) {
300                         perf_pmu_update_alias(a, newalias);
301                         perf_pmu_free_alias(newalias);
302                         return true;
303                 }
304         }
305         return false;
306 }
307
308 static int __perf_pmu__new_alias(struct list_head *list, char *dir, char *name,
309                                  char *desc, char *val,
310                                  char *long_desc, char *topic,
311                                  char *unit, char *perpkg,
312                                  char *metric_expr,
313                                  char *metric_name,
314                                  char *deprecated)
315 {
316         struct parse_events_term *term;
317         struct perf_pmu_alias *alias;
318         int ret;
319         int num;
320         char newval[256];
321
322         alias = malloc(sizeof(*alias));
323         if (!alias)
324                 return -ENOMEM;
325
326         INIT_LIST_HEAD(&alias->terms);
327         alias->scale = 1.0;
328         alias->unit[0] = '\0';
329         alias->per_pkg = false;
330         alias->snapshot = false;
331         alias->deprecated = false;
332
333         ret = parse_events_terms(&alias->terms, val);
334         if (ret) {
335                 pr_err("Cannot parse alias %s: %d\n", val, ret);
336                 free(alias);
337                 return ret;
338         }
339
340         /* Scan event and remove leading zeroes, spaces, newlines, some
341          * platforms have terms specified as
342          * event=0x0091 (read from files ../<PMU>/events/<FILE>
343          * and terms specified as event=0x91 (read from JSON files).
344          *
345          * Rebuild string to make alias->str member comparable.
346          */
347         memset(newval, 0, sizeof(newval));
348         ret = 0;
349         list_for_each_entry(term, &alias->terms, list) {
350                 if (ret)
351                         ret += scnprintf(newval + ret, sizeof(newval) - ret,
352                                          ",");
353                 if (term->type_val == PARSE_EVENTS__TERM_TYPE_NUM)
354                         ret += scnprintf(newval + ret, sizeof(newval) - ret,
355                                          "%s=%#x", term->config, term->val.num);
356                 else if (term->type_val == PARSE_EVENTS__TERM_TYPE_STR)
357                         ret += scnprintf(newval + ret, sizeof(newval) - ret,
358                                          "%s=%s", term->config, term->val.str);
359         }
360
361         alias->name = strdup(name);
362         if (dir) {
363                 /*
364                  * load unit name and scale if available
365                  */
366                 perf_pmu__parse_unit(alias, dir, name);
367                 perf_pmu__parse_scale(alias, dir, name);
368                 perf_pmu__parse_per_pkg(alias, dir, name);
369                 perf_pmu__parse_snapshot(alias, dir, name);
370         }
371
372         alias->metric_expr = metric_expr ? strdup(metric_expr) : NULL;
373         alias->metric_name = metric_name ? strdup(metric_name): NULL;
374         alias->desc = desc ? strdup(desc) : NULL;
375         alias->long_desc = long_desc ? strdup(long_desc) :
376                                 desc ? strdup(desc) : NULL;
377         alias->topic = topic ? strdup(topic) : NULL;
378         if (unit) {
379                 if (perf_pmu__convert_scale(unit, &unit, &alias->scale) < 0)
380                         return -1;
381                 snprintf(alias->unit, sizeof(alias->unit), "%s", unit);
382         }
383         alias->per_pkg = perpkg && sscanf(perpkg, "%d", &num) == 1 && num == 1;
384         alias->str = strdup(newval);
385
386         if (deprecated)
387                 alias->deprecated = true;
388
389         if (!perf_pmu_merge_alias(alias, list))
390                 list_add_tail(&alias->list, list);
391
392         return 0;
393 }
394
395 static int perf_pmu__new_alias(struct list_head *list, char *dir, char *name, FILE *file)
396 {
397         char buf[256];
398         int ret;
399
400         ret = fread(buf, 1, sizeof(buf), file);
401         if (ret == 0)
402                 return -EINVAL;
403
404         buf[ret] = 0;
405
406         /* Remove trailing newline from sysfs file */
407         strim(buf);
408
409         return __perf_pmu__new_alias(list, dir, name, NULL, buf, NULL, NULL, NULL,
410                                      NULL, NULL, NULL, NULL);
411 }
412
413 static inline bool pmu_alias_info_file(char *name)
414 {
415         size_t len;
416
417         len = strlen(name);
418         if (len > 5 && !strcmp(name + len - 5, ".unit"))
419                 return true;
420         if (len > 6 && !strcmp(name + len - 6, ".scale"))
421                 return true;
422         if (len > 8 && !strcmp(name + len - 8, ".per-pkg"))
423                 return true;
424         if (len > 9 && !strcmp(name + len - 9, ".snapshot"))
425                 return true;
426
427         return false;
428 }
429
430 /*
431  * Process all the sysfs attributes located under the directory
432  * specified in 'dir' parameter.
433  */
434 static int pmu_aliases_parse(char *dir, struct list_head *head)
435 {
436         struct dirent *evt_ent;
437         DIR *event_dir;
438
439         event_dir = opendir(dir);
440         if (!event_dir)
441                 return -EINVAL;
442
443         while ((evt_ent = readdir(event_dir))) {
444                 char path[PATH_MAX];
445                 char *name = evt_ent->d_name;
446                 FILE *file;
447
448                 if (!strcmp(name, ".") || !strcmp(name, ".."))
449                         continue;
450
451                 /*
452                  * skip info files parsed in perf_pmu__new_alias()
453                  */
454                 if (pmu_alias_info_file(name))
455                         continue;
456
457                 scnprintf(path, PATH_MAX, "%s/%s", dir, name);
458
459                 file = fopen(path, "r");
460                 if (!file) {
461                         pr_debug("Cannot open %s\n", path);
462                         continue;
463                 }
464
465                 if (perf_pmu__new_alias(head, dir, name, file) < 0)
466                         pr_debug("Cannot set up %s\n", name);
467                 fclose(file);
468         }
469
470         closedir(event_dir);
471         return 0;
472 }
473
474 /*
475  * Reading the pmu event aliases definition, which should be located at:
476  * /sys/bus/event_source/devices/<dev>/events as sysfs group attributes.
477  */
478 static int pmu_aliases(const char *name, struct list_head *head)
479 {
480         char path[PATH_MAX];
481         const char *sysfs = sysfs__mountpoint();
482
483         if (!sysfs)
484                 return -1;
485
486         snprintf(path, PATH_MAX,
487                  "%s/bus/event_source/devices/%s/events", sysfs, name);
488
489         if (!file_available(path))
490                 return 0;
491
492         if (pmu_aliases_parse(path, head))
493                 return -1;
494
495         return 0;
496 }
497
498 static int pmu_alias_terms(struct perf_pmu_alias *alias,
499                            struct list_head *terms)
500 {
501         struct parse_events_term *term, *cloned;
502         LIST_HEAD(list);
503         int ret;
504
505         list_for_each_entry(term, &alias->terms, list) {
506                 ret = parse_events_term__clone(&cloned, term);
507                 if (ret) {
508                         parse_events_terms__purge(&list);
509                         return ret;
510                 }
511                 /*
512                  * Weak terms don't override command line options,
513                  * which we don't want for implicit terms in aliases.
514                  */
515                 cloned->weak = true;
516                 list_add_tail(&cloned->list, &list);
517         }
518         list_splice(&list, terms);
519         return 0;
520 }
521
522 /*
523  * Reading/parsing the default pmu type value, which should be
524  * located at:
525  * /sys/bus/event_source/devices/<dev>/type as sysfs attribute.
526  */
527 static int pmu_type(const char *name, __u32 *type)
528 {
529         char path[PATH_MAX];
530         FILE *file;
531         int ret = 0;
532         const char *sysfs = sysfs__mountpoint();
533
534         if (!sysfs)
535                 return -1;
536
537         snprintf(path, PATH_MAX,
538                  "%s" EVENT_SOURCE_DEVICE_PATH "%s/type", sysfs, name);
539
540         if (access(path, R_OK) < 0)
541                 return -1;
542
543         file = fopen(path, "r");
544         if (!file)
545                 return -EINVAL;
546
547         if (1 != fscanf(file, "%u", type))
548                 ret = -1;
549
550         fclose(file);
551         return ret;
552 }
553
554 /* Add all pmus in sysfs to pmu list: */
555 static void pmu_read_sysfs(void)
556 {
557         char path[PATH_MAX];
558         DIR *dir;
559         struct dirent *dent;
560         const char *sysfs = sysfs__mountpoint();
561
562         if (!sysfs)
563                 return;
564
565         snprintf(path, PATH_MAX,
566                  "%s" EVENT_SOURCE_DEVICE_PATH, sysfs);
567
568         dir = opendir(path);
569         if (!dir)
570                 return;
571
572         while ((dent = readdir(dir))) {
573                 if (!strcmp(dent->d_name, ".") || !strcmp(dent->d_name, ".."))
574                         continue;
575                 /* add to static LIST_HEAD(pmus): */
576                 perf_pmu__find(dent->d_name);
577         }
578
579         closedir(dir);
580 }
581
582 static struct perf_cpu_map *__pmu_cpumask(const char *path)
583 {
584         FILE *file;
585         struct perf_cpu_map *cpus;
586
587         file = fopen(path, "r");
588         if (!file)
589                 return NULL;
590
591         cpus = perf_cpu_map__read(file);
592         fclose(file);
593         return cpus;
594 }
595
596 /*
597  * Uncore PMUs have a "cpumask" file under sysfs. CPU PMUs (e.g. on arm/arm64)
598  * may have a "cpus" file.
599  */
600 #define CPUS_TEMPLATE_UNCORE    "%s/bus/event_source/devices/%s/cpumask"
601 #define CPUS_TEMPLATE_CPU       "%s/bus/event_source/devices/%s/cpus"
602
603 static struct perf_cpu_map *pmu_cpumask(const char *name)
604 {
605         char path[PATH_MAX];
606         struct perf_cpu_map *cpus;
607         const char *sysfs = sysfs__mountpoint();
608         const char *templates[] = {
609                 CPUS_TEMPLATE_UNCORE,
610                 CPUS_TEMPLATE_CPU,
611                 NULL
612         };
613         const char **template;
614
615         if (!sysfs)
616                 return NULL;
617
618         for (template = templates; *template; template++) {
619                 snprintf(path, PATH_MAX, *template, sysfs, name);
620                 cpus = __pmu_cpumask(path);
621                 if (cpus)
622                         return cpus;
623         }
624
625         return NULL;
626 }
627
628 static bool pmu_is_uncore(const char *name)
629 {
630         char path[PATH_MAX];
631         const char *sysfs;
632
633         sysfs = sysfs__mountpoint();
634         snprintf(path, PATH_MAX, CPUS_TEMPLATE_UNCORE, sysfs, name);
635         return file_available(path);
636 }
637
638 /*
639  *  PMU CORE devices have different name other than cpu in sysfs on some
640  *  platforms.
641  *  Looking for possible sysfs files to identify the arm core device.
642  */
643 static int is_arm_pmu_core(const char *name)
644 {
645         char path[PATH_MAX];
646         const char *sysfs = sysfs__mountpoint();
647
648         if (!sysfs)
649                 return 0;
650
651         /* Look for cpu sysfs (specific to arm) */
652         scnprintf(path, PATH_MAX, "%s/bus/event_source/devices/%s/cpus",
653                                 sysfs, name);
654         return file_available(path);
655 }
656
657 static char *perf_pmu__getcpuid(struct perf_pmu *pmu)
658 {
659         char *cpuid;
660         static bool printed;
661
662         cpuid = getenv("PERF_CPUID");
663         if (cpuid)
664                 cpuid = strdup(cpuid);
665         if (!cpuid)
666                 cpuid = get_cpuid_str(pmu);
667         if (!cpuid)
668                 return NULL;
669
670         if (!printed) {
671                 pr_debug("Using CPUID %s\n", cpuid);
672                 printed = true;
673         }
674         return cpuid;
675 }
676
677 struct pmu_events_map *perf_pmu__find_map(struct perf_pmu *pmu)
678 {
679         struct pmu_events_map *map;
680         char *cpuid = perf_pmu__getcpuid(pmu);
681         int i;
682
683         /* on some platforms which uses cpus map, cpuid can be NULL for
684          * PMUs other than CORE PMUs.
685          */
686         if (!cpuid)
687                 return NULL;
688
689         i = 0;
690         for (;;) {
691                 map = &pmu_events_map[i++];
692                 if (!map->table) {
693                         map = NULL;
694                         break;
695                 }
696
697                 if (!strcmp_cpuid_str(map->cpuid, cpuid))
698                         break;
699         }
700         free(cpuid);
701         return map;
702 }
703
704 bool pmu_uncore_alias_match(const char *pmu_name, const char *name)
705 {
706         char *tmp = NULL, *tok, *str;
707         bool res;
708
709         str = strdup(pmu_name);
710         if (!str)
711                 return false;
712
713         /*
714          * uncore alias may be from different PMU with common prefix
715          */
716         tok = strtok_r(str, ",", &tmp);
717         if (strncmp(pmu_name, tok, strlen(tok))) {
718                 res = false;
719                 goto out;
720         }
721
722         /*
723          * Match more complex aliases where the alias name is a comma-delimited
724          * list of tokens, orderly contained in the matching PMU name.
725          *
726          * Example: For alias "socket,pmuname" and PMU "socketX_pmunameY", we
727          *          match "socket" in "socketX_pmunameY" and then "pmuname" in
728          *          "pmunameY".
729          */
730         for (; tok; name += strlen(tok), tok = strtok_r(NULL, ",", &tmp)) {
731                 name = strstr(name, tok);
732                 if (!name) {
733                         res = false;
734                         goto out;
735                 }
736         }
737
738         res = true;
739 out:
740         free(str);
741         return res;
742 }
743
744 /*
745  * From the pmu_events_map, find the table of PMU events that corresponds
746  * to the current running CPU. Then, add all PMU events from that table
747  * as aliases.
748  */
749 void pmu_add_cpu_aliases_map(struct list_head *head, struct perf_pmu *pmu,
750                              struct pmu_events_map *map)
751 {
752         int i;
753         const char *name = pmu->name;
754         /*
755          * Found a matching PMU events table. Create aliases
756          */
757         i = 0;
758         while (1) {
759                 const char *cpu_name = is_arm_pmu_core(name) ? name : "cpu";
760                 struct pmu_event *pe = &map->table[i++];
761                 const char *pname = pe->pmu ? pe->pmu : cpu_name;
762
763                 if (!pe->name) {
764                         if (pe->metric_group || pe->metric_name)
765                                 continue;
766                         break;
767                 }
768
769                 if (pmu_is_uncore(name) &&
770                     pmu_uncore_alias_match(pname, name))
771                         goto new_alias;
772
773                 if (strcmp(pname, name))
774                         continue;
775
776 new_alias:
777                 /* need type casts to override 'const' */
778                 __perf_pmu__new_alias(head, NULL, (char *)pe->name,
779                                 (char *)pe->desc, (char *)pe->event,
780                                 (char *)pe->long_desc, (char *)pe->topic,
781                                 (char *)pe->unit, (char *)pe->perpkg,
782                                 (char *)pe->metric_expr,
783                                 (char *)pe->metric_name,
784                                 (char *)pe->deprecated);
785         }
786 }
787
788 static void pmu_add_cpu_aliases(struct list_head *head, struct perf_pmu *pmu)
789 {
790         struct pmu_events_map *map;
791
792         map = perf_pmu__find_map(pmu);
793         if (!map)
794                 return;
795
796         pmu_add_cpu_aliases_map(head, pmu, map);
797 }
798
799 struct perf_event_attr * __weak
800 perf_pmu__get_default_config(struct perf_pmu *pmu __maybe_unused)
801 {
802         return NULL;
803 }
804
805 static int pmu_max_precise(const char *name)
806 {
807         char path[PATH_MAX];
808         int max_precise = -1;
809
810         scnprintf(path, PATH_MAX,
811                  "bus/event_source/devices/%s/caps/max_precise",
812                  name);
813
814         sysfs__read_int(path, &max_precise);
815         return max_precise;
816 }
817
818 static struct perf_pmu *pmu_lookup(const char *name)
819 {
820         struct perf_pmu *pmu;
821         LIST_HEAD(format);
822         LIST_HEAD(aliases);
823         __u32 type;
824
825         /*
826          * The pmu data we store & need consists of the pmu
827          * type value and format definitions. Load both right
828          * now.
829          */
830         if (pmu_format(name, &format))
831                 return NULL;
832
833         /*
834          * Check the type first to avoid unnecessary work.
835          */
836         if (pmu_type(name, &type))
837                 return NULL;
838
839         if (pmu_aliases(name, &aliases))
840                 return NULL;
841
842         pmu = zalloc(sizeof(*pmu));
843         if (!pmu)
844                 return NULL;
845
846         pmu->cpus = pmu_cpumask(name);
847         pmu->name = strdup(name);
848         pmu->type = type;
849         pmu->is_uncore = pmu_is_uncore(name);
850         pmu->max_precise = pmu_max_precise(name);
851         pmu_add_cpu_aliases(&aliases, pmu);
852
853         INIT_LIST_HEAD(&pmu->format);
854         INIT_LIST_HEAD(&pmu->aliases);
855         INIT_LIST_HEAD(&pmu->caps);
856         list_splice(&format, &pmu->format);
857         list_splice(&aliases, &pmu->aliases);
858         list_add_tail(&pmu->list, &pmus);
859
860         pmu->default_config = perf_pmu__get_default_config(pmu);
861
862         return pmu;
863 }
864
865 static struct perf_pmu *pmu_find(const char *name)
866 {
867         struct perf_pmu *pmu;
868
869         list_for_each_entry(pmu, &pmus, list)
870                 if (!strcmp(pmu->name, name))
871                         return pmu;
872
873         return NULL;
874 }
875
876 struct perf_pmu *perf_pmu__find_by_type(unsigned int type)
877 {
878         struct perf_pmu *pmu;
879
880         list_for_each_entry(pmu, &pmus, list)
881                 if (pmu->type == type)
882                         return pmu;
883
884         return NULL;
885 }
886
887 struct perf_pmu *perf_pmu__scan(struct perf_pmu *pmu)
888 {
889         /*
890          * pmu iterator: If pmu is NULL, we start at the begin,
891          * otherwise return the next pmu. Returns NULL on end.
892          */
893         if (!pmu) {
894                 pmu_read_sysfs();
895                 pmu = list_prepare_entry(pmu, &pmus, list);
896         }
897         list_for_each_entry_continue(pmu, &pmus, list)
898                 return pmu;
899         return NULL;
900 }
901
902 struct perf_pmu *evsel__find_pmu(struct evsel *evsel)
903 {
904         struct perf_pmu *pmu = NULL;
905
906         while ((pmu = perf_pmu__scan(pmu)) != NULL) {
907                 if (pmu->type == evsel->core.attr.type)
908                         break;
909         }
910
911         return pmu;
912 }
913
914 bool evsel__is_aux_event(struct evsel *evsel)
915 {
916         struct perf_pmu *pmu = evsel__find_pmu(evsel);
917
918         return pmu && pmu->auxtrace;
919 }
920
921 struct perf_pmu *perf_pmu__find(const char *name)
922 {
923         struct perf_pmu *pmu;
924
925         /*
926          * Once PMU is loaded it stays in the list,
927          * so we keep us from multiple reading/parsing
928          * the pmu format definitions.
929          */
930         pmu = pmu_find(name);
931         if (pmu)
932                 return pmu;
933
934         return pmu_lookup(name);
935 }
936
937 static struct perf_pmu_format *
938 pmu_find_format(struct list_head *formats, const char *name)
939 {
940         struct perf_pmu_format *format;
941
942         list_for_each_entry(format, formats, list)
943                 if (!strcmp(format->name, name))
944                         return format;
945
946         return NULL;
947 }
948
949 __u64 perf_pmu__format_bits(struct list_head *formats, const char *name)
950 {
951         struct perf_pmu_format *format = pmu_find_format(formats, name);
952         __u64 bits = 0;
953         int fbit;
954
955         if (!format)
956                 return 0;
957
958         for_each_set_bit(fbit, format->bits, PERF_PMU_FORMAT_BITS)
959                 bits |= 1ULL << fbit;
960
961         return bits;
962 }
963
964 int perf_pmu__format_type(struct list_head *formats, const char *name)
965 {
966         struct perf_pmu_format *format = pmu_find_format(formats, name);
967
968         if (!format)
969                 return -1;
970
971         return format->value;
972 }
973
974 /*
975  * Sets value based on the format definition (format parameter)
976  * and unformated value (value parameter).
977  */
978 static void pmu_format_value(unsigned long *format, __u64 value, __u64 *v,
979                              bool zero)
980 {
981         unsigned long fbit, vbit;
982
983         for (fbit = 0, vbit = 0; fbit < PERF_PMU_FORMAT_BITS; fbit++) {
984
985                 if (!test_bit(fbit, format))
986                         continue;
987
988                 if (value & (1llu << vbit++))
989                         *v |= (1llu << fbit);
990                 else if (zero)
991                         *v &= ~(1llu << fbit);
992         }
993 }
994
995 static __u64 pmu_format_max_value(const unsigned long *format)
996 {
997         int w;
998
999         w = bitmap_weight(format, PERF_PMU_FORMAT_BITS);
1000         if (!w)
1001                 return 0;
1002         if (w < 64)
1003                 return (1ULL << w) - 1;
1004         return -1;
1005 }
1006
1007 /*
1008  * Term is a string term, and might be a param-term. Try to look up it's value
1009  * in the remaining terms.
1010  * - We have a term like "base-or-format-term=param-term",
1011  * - We need to find the value supplied for "param-term" (with param-term named
1012  *   in a config string) later on in the term list.
1013  */
1014 static int pmu_resolve_param_term(struct parse_events_term *term,
1015                                   struct list_head *head_terms,
1016                                   __u64 *value)
1017 {
1018         struct parse_events_term *t;
1019
1020         list_for_each_entry(t, head_terms, list) {
1021                 if (t->type_val == PARSE_EVENTS__TERM_TYPE_NUM &&
1022                     t->config && !strcmp(t->config, term->config)) {
1023                         t->used = true;
1024                         *value = t->val.num;
1025                         return 0;
1026                 }
1027         }
1028
1029         if (verbose > 0)
1030                 printf("Required parameter '%s' not specified\n", term->config);
1031
1032         return -1;
1033 }
1034
1035 static char *pmu_formats_string(struct list_head *formats)
1036 {
1037         struct perf_pmu_format *format;
1038         char *str = NULL;
1039         struct strbuf buf = STRBUF_INIT;
1040         unsigned i = 0;
1041
1042         if (!formats)
1043                 return NULL;
1044
1045         /* sysfs exported terms */
1046         list_for_each_entry(format, formats, list)
1047                 if (strbuf_addf(&buf, i++ ? ",%s" : "%s", format->name) < 0)
1048                         goto error;
1049
1050         str = strbuf_detach(&buf, NULL);
1051 error:
1052         strbuf_release(&buf);
1053
1054         return str;
1055 }
1056
1057 /*
1058  * Setup one of config[12] attr members based on the
1059  * user input data - term parameter.
1060  */
1061 static int pmu_config_term(const char *pmu_name,
1062                            struct list_head *formats,
1063                            struct perf_event_attr *attr,
1064                            struct parse_events_term *term,
1065                            struct list_head *head_terms,
1066                            bool zero, struct parse_events_error *err)
1067 {
1068         struct perf_pmu_format *format;
1069         __u64 *vp;
1070         __u64 val, max_val;
1071
1072         /*
1073          * If this is a parameter we've already used for parameterized-eval,
1074          * skip it in normal eval.
1075          */
1076         if (term->used)
1077                 return 0;
1078
1079         /*
1080          * Hardcoded terms should be already in, so nothing
1081          * to be done for them.
1082          */
1083         if (parse_events__is_hardcoded_term(term))
1084                 return 0;
1085
1086         format = pmu_find_format(formats, term->config);
1087         if (!format) {
1088                 char *pmu_term = pmu_formats_string(formats);
1089                 char *unknown_term;
1090                 char *help_msg;
1091
1092                 if (asprintf(&unknown_term,
1093                                 "unknown term '%s' for pmu '%s'",
1094                                 term->config, pmu_name) < 0)
1095                         unknown_term = NULL;
1096                 help_msg = parse_events_formats_error_string(pmu_term);
1097                 if (err) {
1098                         parse_events__handle_error(err, term->err_term,
1099                                                    unknown_term,
1100                                                    help_msg);
1101                 } else {
1102                         pr_debug("%s (%s)\n", unknown_term, help_msg);
1103                         free(unknown_term);
1104                 }
1105                 free(pmu_term);
1106                 return -EINVAL;
1107         }
1108
1109         switch (format->value) {
1110         case PERF_PMU_FORMAT_VALUE_CONFIG:
1111                 vp = &attr->config;
1112                 break;
1113         case PERF_PMU_FORMAT_VALUE_CONFIG1:
1114                 vp = &attr->config1;
1115                 break;
1116         case PERF_PMU_FORMAT_VALUE_CONFIG2:
1117                 vp = &attr->config2;
1118                 break;
1119         default:
1120                 return -EINVAL;
1121         }
1122
1123         /*
1124          * Either directly use a numeric term, or try to translate string terms
1125          * using event parameters.
1126          */
1127         if (term->type_val == PARSE_EVENTS__TERM_TYPE_NUM) {
1128                 if (term->no_value &&
1129                     bitmap_weight(format->bits, PERF_PMU_FORMAT_BITS) > 1) {
1130                         if (err) {
1131                                 parse_events__handle_error(err, term->err_val,
1132                                            strdup("no value assigned for term"),
1133                                            NULL);
1134                         }
1135                         return -EINVAL;
1136                 }
1137
1138                 val = term->val.num;
1139         } else if (term->type_val == PARSE_EVENTS__TERM_TYPE_STR) {
1140                 if (strcmp(term->val.str, "?")) {
1141                         if (verbose > 0) {
1142                                 pr_info("Invalid sysfs entry %s=%s\n",
1143                                                 term->config, term->val.str);
1144                         }
1145                         if (err) {
1146                                 parse_events__handle_error(err, term->err_val,
1147                                         strdup("expected numeric value"),
1148                                         NULL);
1149                         }
1150                         return -EINVAL;
1151                 }
1152
1153                 if (pmu_resolve_param_term(term, head_terms, &val))
1154                         return -EINVAL;
1155         } else
1156                 return -EINVAL;
1157
1158         max_val = pmu_format_max_value(format->bits);
1159         if (val > max_val) {
1160                 if (err) {
1161                         char *err_str;
1162
1163                         parse_events__handle_error(err, term->err_val,
1164                                 asprintf(&err_str,
1165                                     "value too big for format, maximum is %llu",
1166                                     (unsigned long long)max_val) < 0
1167                                     ? strdup("value too big for format")
1168                                     : err_str,
1169                                     NULL);
1170                         return -EINVAL;
1171                 }
1172                 /*
1173                  * Assume we don't care if !err, in which case the value will be
1174                  * silently truncated.
1175                  */
1176         }
1177
1178         pmu_format_value(format->bits, val, vp, zero);
1179         return 0;
1180 }
1181
1182 int perf_pmu__config_terms(const char *pmu_name, struct list_head *formats,
1183                            struct perf_event_attr *attr,
1184                            struct list_head *head_terms,
1185                            bool zero, struct parse_events_error *err)
1186 {
1187         struct parse_events_term *term;
1188
1189         list_for_each_entry(term, head_terms, list) {
1190                 if (pmu_config_term(pmu_name, formats, attr, term, head_terms,
1191                                     zero, err))
1192                         return -EINVAL;
1193         }
1194
1195         return 0;
1196 }
1197
1198 /*
1199  * Configures event's 'attr' parameter based on the:
1200  * 1) users input - specified in terms parameter
1201  * 2) pmu format definitions - specified by pmu parameter
1202  */
1203 int perf_pmu__config(struct perf_pmu *pmu, struct perf_event_attr *attr,
1204                      struct list_head *head_terms,
1205                      struct parse_events_error *err)
1206 {
1207         bool zero = !!pmu->default_config;
1208
1209         attr->type = pmu->type;
1210         return perf_pmu__config_terms(pmu->name, &pmu->format, attr,
1211                                       head_terms, zero, err);
1212 }
1213
1214 static struct perf_pmu_alias *pmu_find_alias(struct perf_pmu *pmu,
1215                                              struct parse_events_term *term)
1216 {
1217         struct perf_pmu_alias *alias;
1218         char *name;
1219
1220         if (parse_events__is_hardcoded_term(term))
1221                 return NULL;
1222
1223         if (term->type_val == PARSE_EVENTS__TERM_TYPE_NUM) {
1224                 if (term->val.num != 1)
1225                         return NULL;
1226                 if (pmu_find_format(&pmu->format, term->config))
1227                         return NULL;
1228                 name = term->config;
1229         } else if (term->type_val == PARSE_EVENTS__TERM_TYPE_STR) {
1230                 if (strcasecmp(term->config, "event"))
1231                         return NULL;
1232                 name = term->val.str;
1233         } else {
1234                 return NULL;
1235         }
1236
1237         list_for_each_entry(alias, &pmu->aliases, list) {
1238                 if (!strcasecmp(alias->name, name))
1239                         return alias;
1240         }
1241         return NULL;
1242 }
1243
1244
1245 static int check_info_data(struct perf_pmu_alias *alias,
1246                            struct perf_pmu_info *info)
1247 {
1248         /*
1249          * Only one term in event definition can
1250          * define unit, scale and snapshot, fail
1251          * if there's more than one.
1252          */
1253         if ((info->unit && alias->unit[0]) ||
1254             (info->scale && alias->scale) ||
1255             (info->snapshot && alias->snapshot))
1256                 return -EINVAL;
1257
1258         if (alias->unit[0])
1259                 info->unit = alias->unit;
1260
1261         if (alias->scale)
1262                 info->scale = alias->scale;
1263
1264         if (alias->snapshot)
1265                 info->snapshot = alias->snapshot;
1266
1267         return 0;
1268 }
1269
1270 /*
1271  * Find alias in the terms list and replace it with the terms
1272  * defined for the alias
1273  */
1274 int perf_pmu__check_alias(struct perf_pmu *pmu, struct list_head *head_terms,
1275                           struct perf_pmu_info *info)
1276 {
1277         struct parse_events_term *term, *h;
1278         struct perf_pmu_alias *alias;
1279         int ret;
1280
1281         info->per_pkg = false;
1282
1283         /*
1284          * Mark unit and scale as not set
1285          * (different from default values, see below)
1286          */
1287         info->unit     = NULL;
1288         info->scale    = 0.0;
1289         info->snapshot = false;
1290         info->metric_expr = NULL;
1291         info->metric_name = NULL;
1292
1293         list_for_each_entry_safe(term, h, head_terms, list) {
1294                 alias = pmu_find_alias(pmu, term);
1295                 if (!alias)
1296                         continue;
1297                 ret = pmu_alias_terms(alias, &term->list);
1298                 if (ret)
1299                         return ret;
1300
1301                 ret = check_info_data(alias, info);
1302                 if (ret)
1303                         return ret;
1304
1305                 if (alias->per_pkg)
1306                         info->per_pkg = true;
1307                 info->metric_expr = alias->metric_expr;
1308                 info->metric_name = alias->metric_name;
1309
1310                 list_del_init(&term->list);
1311                 parse_events_term__delete(term);
1312         }
1313
1314         /*
1315          * if no unit or scale foundin aliases, then
1316          * set defaults as for evsel
1317          * unit cannot left to NULL
1318          */
1319         if (info->unit == NULL)
1320                 info->unit   = "";
1321
1322         if (info->scale == 0.0)
1323                 info->scale  = 1.0;
1324
1325         return 0;
1326 }
1327
1328 int perf_pmu__new_format(struct list_head *list, char *name,
1329                          int config, unsigned long *bits)
1330 {
1331         struct perf_pmu_format *format;
1332
1333         format = zalloc(sizeof(*format));
1334         if (!format)
1335                 return -ENOMEM;
1336
1337         format->name = strdup(name);
1338         format->value = config;
1339         memcpy(format->bits, bits, sizeof(format->bits));
1340
1341         list_add_tail(&format->list, list);
1342         return 0;
1343 }
1344
1345 void perf_pmu__set_format(unsigned long *bits, long from, long to)
1346 {
1347         long b;
1348
1349         if (!to)
1350                 to = from;
1351
1352         memset(bits, 0, BITS_TO_BYTES(PERF_PMU_FORMAT_BITS));
1353         for (b = from; b <= to; b++)
1354                 set_bit(b, bits);
1355 }
1356
1357 static int sub_non_neg(int a, int b)
1358 {
1359         if (b > a)
1360                 return 0;
1361         return a - b;
1362 }
1363
1364 static char *format_alias(char *buf, int len, struct perf_pmu *pmu,
1365                           struct perf_pmu_alias *alias)
1366 {
1367         struct parse_events_term *term;
1368         int used = snprintf(buf, len, "%s/%s", pmu->name, alias->name);
1369
1370         list_for_each_entry(term, &alias->terms, list) {
1371                 if (term->type_val == PARSE_EVENTS__TERM_TYPE_STR)
1372                         used += snprintf(buf + used, sub_non_neg(len, used),
1373                                         ",%s=%s", term->config,
1374                                         term->val.str);
1375         }
1376
1377         if (sub_non_neg(len, used) > 0) {
1378                 buf[used] = '/';
1379                 used++;
1380         }
1381         if (sub_non_neg(len, used) > 0) {
1382                 buf[used] = '\0';
1383                 used++;
1384         } else
1385                 buf[len - 1] = '\0';
1386
1387         return buf;
1388 }
1389
1390 static char *format_alias_or(char *buf, int len, struct perf_pmu *pmu,
1391                              struct perf_pmu_alias *alias)
1392 {
1393         snprintf(buf, len, "%s OR %s/%s/", alias->name, pmu->name, alias->name);
1394         return buf;
1395 }
1396
1397 struct sevent {
1398         char *name;
1399         char *desc;
1400         char *topic;
1401         char *str;
1402         char *pmu;
1403         char *metric_expr;
1404         char *metric_name;
1405 };
1406
1407 static int cmp_sevent(const void *a, const void *b)
1408 {
1409         const struct sevent *as = a;
1410         const struct sevent *bs = b;
1411
1412         /* Put extra events last */
1413         if (!!as->desc != !!bs->desc)
1414                 return !!as->desc - !!bs->desc;
1415         if (as->topic && bs->topic) {
1416                 int n = strcmp(as->topic, bs->topic);
1417
1418                 if (n)
1419                         return n;
1420         }
1421         return strcmp(as->name, bs->name);
1422 }
1423
1424 static void wordwrap(char *s, int start, int max, int corr)
1425 {
1426         int column = start;
1427         int n;
1428
1429         while (*s) {
1430                 int wlen = strcspn(s, " \t");
1431
1432                 if (column + wlen >= max && column > start) {
1433                         printf("\n%*s", start, "");
1434                         column = start + corr;
1435                 }
1436                 n = printf("%s%.*s", column > start ? " " : "", wlen, s);
1437                 if (n <= 0)
1438                         break;
1439                 s += wlen;
1440                 column += n;
1441                 s = skip_spaces(s);
1442         }
1443 }
1444
1445 bool is_pmu_core(const char *name)
1446 {
1447         return !strcmp(name, "cpu") || is_arm_pmu_core(name);
1448 }
1449
1450 void print_pmu_events(const char *event_glob, bool name_only, bool quiet_flag,
1451                         bool long_desc, bool details_flag, bool deprecated)
1452 {
1453         struct perf_pmu *pmu;
1454         struct perf_pmu_alias *alias;
1455         char buf[1024];
1456         int printed = 0;
1457         int len, j;
1458         struct sevent *aliases;
1459         int numdesc = 0;
1460         int columns = pager_get_columns();
1461         char *topic = NULL;
1462
1463         pmu = NULL;
1464         len = 0;
1465         while ((pmu = perf_pmu__scan(pmu)) != NULL) {
1466                 list_for_each_entry(alias, &pmu->aliases, list)
1467                         len++;
1468                 if (pmu->selectable)
1469                         len++;
1470         }
1471         aliases = zalloc(sizeof(struct sevent) * len);
1472         if (!aliases)
1473                 goto out_enomem;
1474         pmu = NULL;
1475         j = 0;
1476         while ((pmu = perf_pmu__scan(pmu)) != NULL) {
1477                 list_for_each_entry(alias, &pmu->aliases, list) {
1478                         char *name = alias->desc ? alias->name :
1479                                 format_alias(buf, sizeof(buf), pmu, alias);
1480                         bool is_cpu = !strcmp(pmu->name, "cpu");
1481
1482                         if (alias->deprecated && !deprecated)
1483                                 continue;
1484
1485                         if (event_glob != NULL &&
1486                             !(strglobmatch_nocase(name, event_glob) ||
1487                               (!is_cpu && strglobmatch_nocase(alias->name,
1488                                                        event_glob)) ||
1489                               (alias->topic &&
1490                                strglobmatch_nocase(alias->topic, event_glob))))
1491                                 continue;
1492
1493                         if (is_cpu && !name_only && !alias->desc)
1494                                 name = format_alias_or(buf, sizeof(buf), pmu, alias);
1495
1496                         aliases[j].name = name;
1497                         if (is_cpu && !name_only && !alias->desc)
1498                                 aliases[j].name = format_alias_or(buf,
1499                                                                   sizeof(buf),
1500                                                                   pmu, alias);
1501                         aliases[j].name = strdup(aliases[j].name);
1502                         if (!aliases[j].name)
1503                                 goto out_enomem;
1504
1505                         aliases[j].desc = long_desc ? alias->long_desc :
1506                                                 alias->desc;
1507                         aliases[j].topic = alias->topic;
1508                         aliases[j].str = alias->str;
1509                         aliases[j].pmu = pmu->name;
1510                         aliases[j].metric_expr = alias->metric_expr;
1511                         aliases[j].metric_name = alias->metric_name;
1512                         j++;
1513                 }
1514                 if (pmu->selectable &&
1515                     (event_glob == NULL || strglobmatch(pmu->name, event_glob))) {
1516                         char *s;
1517                         if (asprintf(&s, "%s//", pmu->name) < 0)
1518                                 goto out_enomem;
1519                         aliases[j].name = s;
1520                         j++;
1521                 }
1522         }
1523         len = j;
1524         qsort(aliases, len, sizeof(struct sevent), cmp_sevent);
1525         for (j = 0; j < len; j++) {
1526                 /* Skip duplicates */
1527                 if (j > 0 && !strcmp(aliases[j].name, aliases[j - 1].name))
1528                         continue;
1529                 if (name_only) {
1530                         printf("%s ", aliases[j].name);
1531                         continue;
1532                 }
1533                 if (aliases[j].desc && !quiet_flag) {
1534                         if (numdesc++ == 0)
1535                                 printf("\n");
1536                         if (aliases[j].topic && (!topic ||
1537                                         strcmp(topic, aliases[j].topic))) {
1538                                 printf("%s%s:\n", topic ? "\n" : "",
1539                                                 aliases[j].topic);
1540                                 topic = aliases[j].topic;
1541                         }
1542                         printf("  %-50s\n", aliases[j].name);
1543                         printf("%*s", 8, "[");
1544                         wordwrap(aliases[j].desc, 8, columns, 0);
1545                         printf("]\n");
1546                         if (details_flag) {
1547                                 printf("%*s%s/%s/ ", 8, "", aliases[j].pmu, aliases[j].str);
1548                                 if (aliases[j].metric_name)
1549                                         printf(" MetricName: %s", aliases[j].metric_name);
1550                                 if (aliases[j].metric_expr)
1551                                         printf(" MetricExpr: %s", aliases[j].metric_expr);
1552                                 putchar('\n');
1553                         }
1554                 } else
1555                         printf("  %-50s [Kernel PMU event]\n", aliases[j].name);
1556                 printed++;
1557         }
1558         if (printed && pager_in_use())
1559                 printf("\n");
1560 out_free:
1561         for (j = 0; j < len; j++)
1562                 zfree(&aliases[j].name);
1563         zfree(&aliases);
1564         return;
1565
1566 out_enomem:
1567         printf("FATAL: not enough memory to print PMU events\n");
1568         if (aliases)
1569                 goto out_free;
1570 }
1571
1572 bool pmu_have_event(const char *pname, const char *name)
1573 {
1574         struct perf_pmu *pmu;
1575         struct perf_pmu_alias *alias;
1576
1577         pmu = NULL;
1578         while ((pmu = perf_pmu__scan(pmu)) != NULL) {
1579                 if (strcmp(pname, pmu->name))
1580                         continue;
1581                 list_for_each_entry(alias, &pmu->aliases, list)
1582                         if (!strcmp(alias->name, name))
1583                                 return true;
1584         }
1585         return false;
1586 }
1587
1588 static FILE *perf_pmu__open_file(struct perf_pmu *pmu, const char *name)
1589 {
1590         char path[PATH_MAX];
1591         const char *sysfs;
1592
1593         sysfs = sysfs__mountpoint();
1594         if (!sysfs)
1595                 return NULL;
1596
1597         snprintf(path, PATH_MAX,
1598                  "%s" EVENT_SOURCE_DEVICE_PATH "%s/%s", sysfs, pmu->name, name);
1599         if (!file_available(path))
1600                 return NULL;
1601         return fopen(path, "r");
1602 }
1603
1604 int perf_pmu__scan_file(struct perf_pmu *pmu, const char *name, const char *fmt,
1605                         ...)
1606 {
1607         va_list args;
1608         FILE *file;
1609         int ret = EOF;
1610
1611         va_start(args, fmt);
1612         file = perf_pmu__open_file(pmu, name);
1613         if (file) {
1614                 ret = vfscanf(file, fmt, args);
1615                 fclose(file);
1616         }
1617         va_end(args);
1618         return ret;
1619 }
1620
1621 static int perf_pmu__new_caps(struct list_head *list, char *name, char *value)
1622 {
1623         struct perf_pmu_caps *caps = zalloc(sizeof(*caps));
1624
1625         if (!caps)
1626                 return -ENOMEM;
1627
1628         caps->name = strdup(name);
1629         if (!caps->name)
1630                 goto free_caps;
1631         caps->value = strndup(value, strlen(value) - 1);
1632         if (!caps->value)
1633                 goto free_name;
1634         list_add_tail(&caps->list, list);
1635         return 0;
1636
1637 free_name:
1638         zfree(caps->name);
1639 free_caps:
1640         free(caps);
1641
1642         return -ENOMEM;
1643 }
1644
1645 /*
1646  * Reading/parsing the given pmu capabilities, which should be located at:
1647  * /sys/bus/event_source/devices/<dev>/caps as sysfs group attributes.
1648  * Return the number of capabilities
1649  */
1650 int perf_pmu__caps_parse(struct perf_pmu *pmu)
1651 {
1652         struct stat st;
1653         char caps_path[PATH_MAX];
1654         const char *sysfs = sysfs__mountpoint();
1655         DIR *caps_dir;
1656         struct dirent *evt_ent;
1657         int nr_caps = 0;
1658
1659         if (!sysfs)
1660                 return -1;
1661
1662         snprintf(caps_path, PATH_MAX,
1663                  "%s" EVENT_SOURCE_DEVICE_PATH "%s/caps", sysfs, pmu->name);
1664
1665         if (stat(caps_path, &st) < 0)
1666                 return 0;       /* no error if caps does not exist */
1667
1668         caps_dir = opendir(caps_path);
1669         if (!caps_dir)
1670                 return -EINVAL;
1671
1672         while ((evt_ent = readdir(caps_dir)) != NULL) {
1673                 char path[PATH_MAX + NAME_MAX + 1];
1674                 char *name = evt_ent->d_name;
1675                 char value[128];
1676                 FILE *file;
1677
1678                 if (!strcmp(name, ".") || !strcmp(name, ".."))
1679                         continue;
1680
1681                 snprintf(path, sizeof(path), "%s/%s", caps_path, name);
1682
1683                 file = fopen(path, "r");
1684                 if (!file)
1685                         continue;
1686
1687                 if (!fgets(value, sizeof(value), file) ||
1688                     (perf_pmu__new_caps(&pmu->caps, name, value) < 0)) {
1689                         fclose(file);
1690                         continue;
1691                 }
1692
1693                 nr_caps++;
1694                 fclose(file);
1695         }
1696
1697         closedir(caps_dir);
1698
1699         return nr_caps;
1700 }