OSDN Git Service

93a41ca96b8e0c6f0f927b20209c58c676a98384
[android-x86/kernel.git] / tools / perf / util / pmu.c
1 #include <linux/list.h>
2 #include <sys/types.h>
3 #include <unistd.h>
4 #include <stdio.h>
5 #include <stdbool.h>
6 #include <stdarg.h>
7 #include <dirent.h>
8 #include <api/fs/fs.h>
9 #include <locale.h>
10 #include "util.h"
11 #include "pmu.h"
12 #include "parse-events.h"
13 #include "cpumap.h"
14
15 #define UNIT_MAX_LEN    31 /* max length for event unit name */
16
17 struct perf_pmu_alias {
18         char *name;
19         struct list_head terms; /* HEAD struct parse_events_term -> list */
20         struct list_head list;  /* ELEM */
21         char unit[UNIT_MAX_LEN+1];
22         double scale;
23 };
24
25 struct perf_pmu_format {
26         char *name;
27         int value;
28         DECLARE_BITMAP(bits, PERF_PMU_FORMAT_BITS);
29         struct list_head list;
30 };
31
32 #define EVENT_SOURCE_DEVICE_PATH "/bus/event_source/devices/"
33
34 int perf_pmu_parse(struct list_head *list, char *name);
35 extern FILE *perf_pmu_in;
36
37 static LIST_HEAD(pmus);
38
39 /*
40  * Parse & process all the sysfs attributes located under
41  * the directory specified in 'dir' parameter.
42  */
43 int perf_pmu__format_parse(char *dir, struct list_head *head)
44 {
45         struct dirent *evt_ent;
46         DIR *format_dir;
47         int ret = 0;
48
49         format_dir = opendir(dir);
50         if (!format_dir)
51                 return -EINVAL;
52
53         while (!ret && (evt_ent = readdir(format_dir))) {
54                 char path[PATH_MAX];
55                 char *name = evt_ent->d_name;
56                 FILE *file;
57
58                 if (!strcmp(name, ".") || !strcmp(name, ".."))
59                         continue;
60
61                 snprintf(path, PATH_MAX, "%s/%s", dir, name);
62
63                 ret = -EINVAL;
64                 file = fopen(path, "r");
65                 if (!file)
66                         break;
67
68                 perf_pmu_in = file;
69                 ret = perf_pmu_parse(head, name);
70                 fclose(file);
71         }
72
73         closedir(format_dir);
74         return ret;
75 }
76
77 /*
78  * Reading/parsing the default pmu format definition, which should be
79  * located at:
80  * /sys/bus/event_source/devices/<dev>/format as sysfs group attributes.
81  */
82 static int pmu_format(const char *name, struct list_head *format)
83 {
84         struct stat st;
85         char path[PATH_MAX];
86         const char *sysfs = sysfs__mountpoint();
87
88         if (!sysfs)
89                 return -1;
90
91         snprintf(path, PATH_MAX,
92                  "%s" EVENT_SOURCE_DEVICE_PATH "%s/format", sysfs, name);
93
94         if (stat(path, &st) < 0)
95                 return 0;       /* no error if format does not exist */
96
97         if (perf_pmu__format_parse(path, format))
98                 return -1;
99
100         return 0;
101 }
102
103 static int perf_pmu__parse_scale(struct perf_pmu_alias *alias, char *dir, char *name)
104 {
105         struct stat st;
106         ssize_t sret;
107         char scale[128];
108         int fd, ret = -1;
109         char path[PATH_MAX];
110         const char *lc;
111
112         snprintf(path, PATH_MAX, "%s/%s.scale", dir, name);
113
114         fd = open(path, O_RDONLY);
115         if (fd == -1)
116                 return -1;
117
118         if (fstat(fd, &st) < 0)
119                 goto error;
120
121         sret = read(fd, scale, sizeof(scale)-1);
122         if (sret < 0)
123                 goto error;
124
125         scale[sret] = '\0';
126         /*
127          * save current locale
128          */
129         lc = setlocale(LC_NUMERIC, NULL);
130
131         /*
132          * force to C locale to ensure kernel
133          * scale string is converted correctly.
134          * kernel uses default C locale.
135          */
136         setlocale(LC_NUMERIC, "C");
137
138         alias->scale = strtod(scale, NULL);
139
140         /* restore locale */
141         setlocale(LC_NUMERIC, lc);
142
143         ret = 0;
144 error:
145         close(fd);
146         return ret;
147 }
148
149 static int perf_pmu__parse_unit(struct perf_pmu_alias *alias, char *dir, char *name)
150 {
151         char path[PATH_MAX];
152         ssize_t sret;
153         int fd;
154
155         snprintf(path, PATH_MAX, "%s/%s.unit", dir, name);
156
157         fd = open(path, O_RDONLY);
158         if (fd == -1)
159                 return -1;
160
161                 sret = read(fd, alias->unit, UNIT_MAX_LEN);
162         if (sret < 0)
163                 goto error;
164
165         close(fd);
166
167         alias->unit[sret] = '\0';
168
169         return 0;
170 error:
171         close(fd);
172         alias->unit[0] = '\0';
173         return -1;
174 }
175
176 static int perf_pmu__new_alias(struct list_head *list, char *dir, char *name, FILE *file)
177 {
178         struct perf_pmu_alias *alias;
179         char buf[256];
180         int ret;
181
182         ret = fread(buf, 1, sizeof(buf), file);
183         if (ret == 0)
184                 return -EINVAL;
185         buf[ret] = 0;
186
187         alias = malloc(sizeof(*alias));
188         if (!alias)
189                 return -ENOMEM;
190
191         INIT_LIST_HEAD(&alias->terms);
192         alias->scale = 1.0;
193         alias->unit[0] = '\0';
194
195         ret = parse_events_terms(&alias->terms, buf);
196         if (ret) {
197                 free(alias);
198                 return ret;
199         }
200
201         alias->name = strdup(name);
202         /*
203          * load unit name and scale if available
204          */
205         perf_pmu__parse_unit(alias, dir, name);
206         perf_pmu__parse_scale(alias, dir, name);
207
208         list_add_tail(&alias->list, list);
209
210         return 0;
211 }
212
213 static inline bool pmu_alias_info_file(char *name)
214 {
215         size_t len;
216
217         len = strlen(name);
218         if (len > 5 && !strcmp(name + len - 5, ".unit"))
219                 return true;
220         if (len > 6 && !strcmp(name + len - 6, ".scale"))
221                 return true;
222
223         return false;
224 }
225
226 /*
227  * Process all the sysfs attributes located under the directory
228  * specified in 'dir' parameter.
229  */
230 static int pmu_aliases_parse(char *dir, struct list_head *head)
231 {
232         struct dirent *evt_ent;
233         DIR *event_dir;
234         int ret = 0;
235
236         event_dir = opendir(dir);
237         if (!event_dir)
238                 return -EINVAL;
239
240         while (!ret && (evt_ent = readdir(event_dir))) {
241                 char path[PATH_MAX];
242                 char *name = evt_ent->d_name;
243                 FILE *file;
244
245                 if (!strcmp(name, ".") || !strcmp(name, ".."))
246                         continue;
247
248                 /*
249                  * skip info files parsed in perf_pmu__new_alias()
250                  */
251                 if (pmu_alias_info_file(name))
252                         continue;
253
254                 snprintf(path, PATH_MAX, "%s/%s", dir, name);
255
256                 ret = -EINVAL;
257                 file = fopen(path, "r");
258                 if (!file)
259                         break;
260
261                 ret = perf_pmu__new_alias(head, dir, name, file);
262                 fclose(file);
263         }
264
265         closedir(event_dir);
266         return ret;
267 }
268
269 /*
270  * Reading the pmu event aliases definition, which should be located at:
271  * /sys/bus/event_source/devices/<dev>/events as sysfs group attributes.
272  */
273 static int pmu_aliases(const char *name, struct list_head *head)
274 {
275         struct stat st;
276         char path[PATH_MAX];
277         const char *sysfs = sysfs__mountpoint();
278
279         if (!sysfs)
280                 return -1;
281
282         snprintf(path, PATH_MAX,
283                  "%s/bus/event_source/devices/%s/events", sysfs, name);
284
285         if (stat(path, &st) < 0)
286                 return 0;        /* no error if 'events' does not exist */
287
288         if (pmu_aliases_parse(path, head))
289                 return -1;
290
291         return 0;
292 }
293
294 static int pmu_alias_terms(struct perf_pmu_alias *alias,
295                            struct list_head *terms)
296 {
297         struct parse_events_term *term, *cloned;
298         LIST_HEAD(list);
299         int ret;
300
301         list_for_each_entry(term, &alias->terms, list) {
302                 ret = parse_events_term__clone(&cloned, term);
303                 if (ret) {
304                         parse_events__free_terms(&list);
305                         return ret;
306                 }
307                 list_add_tail(&cloned->list, &list);
308         }
309         list_splice(&list, terms);
310         return 0;
311 }
312
313 /*
314  * Reading/parsing the default pmu type value, which should be
315  * located at:
316  * /sys/bus/event_source/devices/<dev>/type as sysfs attribute.
317  */
318 static int pmu_type(const char *name, __u32 *type)
319 {
320         struct stat st;
321         char path[PATH_MAX];
322         FILE *file;
323         int ret = 0;
324         const char *sysfs = sysfs__mountpoint();
325
326         if (!sysfs)
327                 return -1;
328
329         snprintf(path, PATH_MAX,
330                  "%s" EVENT_SOURCE_DEVICE_PATH "%s/type", sysfs, name);
331
332         if (stat(path, &st) < 0)
333                 return -1;
334
335         file = fopen(path, "r");
336         if (!file)
337                 return -EINVAL;
338
339         if (1 != fscanf(file, "%u", type))
340                 ret = -1;
341
342         fclose(file);
343         return ret;
344 }
345
346 /* Add all pmus in sysfs to pmu list: */
347 static void pmu_read_sysfs(void)
348 {
349         char path[PATH_MAX];
350         DIR *dir;
351         struct dirent *dent;
352         const char *sysfs = sysfs__mountpoint();
353
354         if (!sysfs)
355                 return;
356
357         snprintf(path, PATH_MAX,
358                  "%s" EVENT_SOURCE_DEVICE_PATH, sysfs);
359
360         dir = opendir(path);
361         if (!dir)
362                 return;
363
364         while ((dent = readdir(dir))) {
365                 if (!strcmp(dent->d_name, ".") || !strcmp(dent->d_name, ".."))
366                         continue;
367                 /* add to static LIST_HEAD(pmus): */
368                 perf_pmu__find(dent->d_name);
369         }
370
371         closedir(dir);
372 }
373
374 static struct cpu_map *pmu_cpumask(const char *name)
375 {
376         struct stat st;
377         char path[PATH_MAX];
378         FILE *file;
379         struct cpu_map *cpus;
380         const char *sysfs = sysfs__mountpoint();
381
382         if (!sysfs)
383                 return NULL;
384
385         snprintf(path, PATH_MAX,
386                  "%s/bus/event_source/devices/%s/cpumask", sysfs, name);
387
388         if (stat(path, &st) < 0)
389                 return NULL;
390
391         file = fopen(path, "r");
392         if (!file)
393                 return NULL;
394
395         cpus = cpu_map__read(file);
396         fclose(file);
397         return cpus;
398 }
399
400 struct perf_event_attr *__attribute__((weak))
401 perf_pmu__get_default_config(struct perf_pmu *pmu __maybe_unused)
402 {
403         return NULL;
404 }
405
406 static struct perf_pmu *pmu_lookup(const char *name)
407 {
408         struct perf_pmu *pmu;
409         LIST_HEAD(format);
410         LIST_HEAD(aliases);
411         __u32 type;
412
413         /*
414          * The pmu data we store & need consists of the pmu
415          * type value and format definitions. Load both right
416          * now.
417          */
418         if (pmu_format(name, &format))
419                 return NULL;
420
421         if (pmu_aliases(name, &aliases))
422                 return NULL;
423
424         if (pmu_type(name, &type))
425                 return NULL;
426
427         pmu = zalloc(sizeof(*pmu));
428         if (!pmu)
429                 return NULL;
430
431         pmu->cpus = pmu_cpumask(name);
432
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);
438         pmu->type = type;
439         list_add_tail(&pmu->list, &pmus);
440
441         pmu->default_config = perf_pmu__get_default_config(pmu);
442
443         return pmu;
444 }
445
446 static struct perf_pmu *pmu_find(const char *name)
447 {
448         struct perf_pmu *pmu;
449
450         list_for_each_entry(pmu, &pmus, list)
451                 if (!strcmp(pmu->name, name))
452                         return pmu;
453
454         return NULL;
455 }
456
457 struct perf_pmu *perf_pmu__scan(struct perf_pmu *pmu)
458 {
459         /*
460          * pmu iterator: If pmu is NULL, we start at the begin,
461          * otherwise return the next pmu. Returns NULL on end.
462          */
463         if (!pmu) {
464                 pmu_read_sysfs();
465                 pmu = list_prepare_entry(pmu, &pmus, list);
466         }
467         list_for_each_entry_continue(pmu, &pmus, list)
468                 return pmu;
469         return NULL;
470 }
471
472 struct perf_pmu *perf_pmu__find(const char *name)
473 {
474         struct perf_pmu *pmu;
475
476         /*
477          * Once PMU is loaded it stays in the list,
478          * so we keep us from multiple reading/parsing
479          * the pmu format definitions.
480          */
481         pmu = pmu_find(name);
482         if (pmu)
483                 return pmu;
484
485         return pmu_lookup(name);
486 }
487
488 static struct perf_pmu_format *
489 pmu_find_format(struct list_head *formats, char *name)
490 {
491         struct perf_pmu_format *format;
492
493         list_for_each_entry(format, formats, list)
494                 if (!strcmp(format->name, name))
495                         return format;
496
497         return NULL;
498 }
499
500 /*
501  * Sets value based on the format definition (format parameter)
502  * and unformated value (value parameter).
503  */
504 static void pmu_format_value(unsigned long *format, __u64 value, __u64 *v,
505                              bool zero)
506 {
507         unsigned long fbit, vbit;
508
509         for (fbit = 0, vbit = 0; fbit < PERF_PMU_FORMAT_BITS; fbit++) {
510
511                 if (!test_bit(fbit, format))
512                         continue;
513
514                 if (value & (1llu << vbit++))
515                         *v |= (1llu << fbit);
516                 else if (zero)
517                         *v &= ~(1llu << fbit);
518         }
519 }
520
521 /*
522  * Setup one of config[12] attr members based on the
523  * user input data - term parameter.
524  */
525 static int pmu_config_term(struct list_head *formats,
526                            struct perf_event_attr *attr,
527                            struct parse_events_term *term,
528                            bool zero)
529 {
530         struct perf_pmu_format *format;
531         __u64 *vp;
532
533         /*
534          * Support only for hardcoded and numnerial terms.
535          * Hardcoded terms should be already in, so nothing
536          * to be done for them.
537          */
538         if (parse_events__is_hardcoded_term(term))
539                 return 0;
540
541         if (term->type_val != PARSE_EVENTS__TERM_TYPE_NUM)
542                 return -EINVAL;
543
544         format = pmu_find_format(formats, term->config);
545         if (!format)
546                 return -EINVAL;
547
548         switch (format->value) {
549         case PERF_PMU_FORMAT_VALUE_CONFIG:
550                 vp = &attr->config;
551                 break;
552         case PERF_PMU_FORMAT_VALUE_CONFIG1:
553                 vp = &attr->config1;
554                 break;
555         case PERF_PMU_FORMAT_VALUE_CONFIG2:
556                 vp = &attr->config2;
557                 break;
558         default:
559                 return -EINVAL;
560         }
561
562         /*
563          * XXX If we ever decide to go with string values for
564          * non-hardcoded terms, here's the place to translate
565          * them into value.
566          */
567         pmu_format_value(format->bits, term->val.num, vp, zero);
568         return 0;
569 }
570
571 int perf_pmu__config_terms(struct list_head *formats,
572                            struct perf_event_attr *attr,
573                            struct list_head *head_terms,
574                            bool zero)
575 {
576         struct parse_events_term *term;
577
578         list_for_each_entry(term, head_terms, list)
579                 if (pmu_config_term(formats, attr, term, zero))
580                         return -EINVAL;
581
582         return 0;
583 }
584
585 /*
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
589  */
590 int perf_pmu__config(struct perf_pmu *pmu, struct perf_event_attr *attr,
591                      struct list_head *head_terms)
592 {
593         bool zero = !!pmu->default_config;
594
595         attr->type = pmu->type;
596         return perf_pmu__config_terms(&pmu->format, attr, head_terms, zero);
597 }
598
599 static struct perf_pmu_alias *pmu_find_alias(struct perf_pmu *pmu,
600                                              struct parse_events_term *term)
601 {
602         struct perf_pmu_alias *alias;
603         char *name;
604
605         if (parse_events__is_hardcoded_term(term))
606                 return NULL;
607
608         if (term->type_val == PARSE_EVENTS__TERM_TYPE_NUM) {
609                 if (term->val.num != 1)
610                         return NULL;
611                 if (pmu_find_format(&pmu->format, term->config))
612                         return NULL;
613                 name = term->config;
614         } else if (term->type_val == PARSE_EVENTS__TERM_TYPE_STR) {
615                 if (strcasecmp(term->config, "event"))
616                         return NULL;
617                 name = term->val.str;
618         } else {
619                 return NULL;
620         }
621
622         list_for_each_entry(alias, &pmu->aliases, list) {
623                 if (!strcasecmp(alias->name, name))
624                         return alias;
625         }
626         return NULL;
627 }
628
629
630 static int check_unit_scale(struct perf_pmu_alias *alias,
631                             const char **unit, double *scale)
632 {
633         /*
634          * Only one term in event definition can
635          * define unit and scale, fail if there's
636          * more than one.
637          */
638         if ((*unit && alias->unit) ||
639             (*scale && alias->scale))
640                 return -EINVAL;
641
642         if (alias->unit)
643                 *unit = alias->unit;
644
645         if (alias->scale)
646                 *scale = alias->scale;
647
648         return 0;
649 }
650
651 /*
652  * Find alias in the terms list and replace it with the terms
653  * defined for the alias
654  */
655 int perf_pmu__check_alias(struct perf_pmu *pmu, struct list_head *head_terms,
656                           struct perf_pmu_info *info)
657 {
658         struct parse_events_term *term, *h;
659         struct perf_pmu_alias *alias;
660         int ret;
661
662         /*
663          * Mark unit and scale as not set
664          * (different from default values, see below)
665          */
666         info->unit   = NULL;
667         info->scale  = 0.0;
668
669         list_for_each_entry_safe(term, h, head_terms, list) {
670                 alias = pmu_find_alias(pmu, term);
671                 if (!alias)
672                         continue;
673                 ret = pmu_alias_terms(alias, &term->list);
674                 if (ret)
675                         return ret;
676
677                 ret = check_unit_scale(alias, &info->unit, &info->scale);
678                 if (ret)
679                         return ret;
680
681                 list_del(&term->list);
682                 free(term);
683         }
684
685         /*
686          * if no unit or scale foundin aliases, then
687          * set defaults as for evsel
688          * unit cannot left to NULL
689          */
690         if (info->unit == NULL)
691                 info->unit   = "";
692
693         if (info->scale == 0.0)
694                 info->scale  = 1.0;
695
696         return 0;
697 }
698
699 int perf_pmu__new_format(struct list_head *list, char *name,
700                          int config, unsigned long *bits)
701 {
702         struct perf_pmu_format *format;
703
704         format = zalloc(sizeof(*format));
705         if (!format)
706                 return -ENOMEM;
707
708         format->name = strdup(name);
709         format->value = config;
710         memcpy(format->bits, bits, sizeof(format->bits));
711
712         list_add_tail(&format->list, list);
713         return 0;
714 }
715
716 void perf_pmu__set_format(unsigned long *bits, long from, long to)
717 {
718         long b;
719
720         if (!to)
721                 to = from;
722
723         memset(bits, 0, BITS_TO_BYTES(PERF_PMU_FORMAT_BITS));
724         for (b = from; b <= to; b++)
725                 set_bit(b, bits);
726 }
727
728 static char *format_alias(char *buf, int len, struct perf_pmu *pmu,
729                           struct perf_pmu_alias *alias)
730 {
731         snprintf(buf, len, "%s/%s/", pmu->name, alias->name);
732         return buf;
733 }
734
735 static char *format_alias_or(char *buf, int len, struct perf_pmu *pmu,
736                              struct perf_pmu_alias *alias)
737 {
738         snprintf(buf, len, "%s OR %s/%s/", alias->name, pmu->name, alias->name);
739         return buf;
740 }
741
742 static int cmp_string(const void *a, const void *b)
743 {
744         const char * const *as = a;
745         const char * const *bs = b;
746         return strcmp(*as, *bs);
747 }
748
749 void print_pmu_events(const char *event_glob, bool name_only)
750 {
751         struct perf_pmu *pmu;
752         struct perf_pmu_alias *alias;
753         char buf[1024];
754         int printed = 0;
755         int len, j;
756         char **aliases;
757
758         pmu = NULL;
759         len = 0;
760         while ((pmu = perf_pmu__scan(pmu)) != NULL)
761                 list_for_each_entry(alias, &pmu->aliases, list)
762                         len++;
763         aliases = malloc(sizeof(char *) * len);
764         if (!aliases)
765                 return;
766         pmu = NULL;
767         j = 0;
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");
772
773                         if (event_glob != NULL &&
774                             !(strglobmatch(name, event_glob) ||
775                               (!is_cpu && strglobmatch(alias->name,
776                                                        event_glob))))
777                                 continue;
778                         aliases[j] = name;
779                         if (is_cpu && !name_only)
780                                 aliases[j] = format_alias_or(buf, sizeof(buf),
781                                                               pmu, alias);
782                         aliases[j] = strdup(aliases[j]);
783                         j++;
784                 }
785         len = j;
786         qsort(aliases, len, sizeof(char *), cmp_string);
787         for (j = 0; j < len; j++) {
788                 if (name_only) {
789                         printf("%s ", aliases[j]);
790                         continue;
791                 }
792                 printf("  %-50s [Kernel PMU event]\n", aliases[j]);
793                 zfree(&aliases[j]);
794                 printed++;
795         }
796         if (printed)
797                 printf("\n");
798         free(aliases);
799 }
800
801 bool pmu_have_event(const char *pname, const char *name)
802 {
803         struct perf_pmu *pmu;
804         struct perf_pmu_alias *alias;
805
806         pmu = NULL;
807         while ((pmu = perf_pmu__scan(pmu)) != NULL) {
808                 if (strcmp(pname, pmu->name))
809                         continue;
810                 list_for_each_entry(alias, &pmu->aliases, list)
811                         if (!strcmp(alias->name, name))
812                                 return true;
813         }
814         return false;
815 }
816
817 static FILE *perf_pmu__open_file(struct perf_pmu *pmu, const char *name)
818 {
819         struct stat st;
820         char path[PATH_MAX];
821         const char *sysfs;
822
823         sysfs = sysfs__mountpoint();
824         if (!sysfs)
825                 return NULL;
826
827         snprintf(path, PATH_MAX,
828                  "%s" EVENT_SOURCE_DEVICE_PATH "%s/%s", sysfs, pmu->name, name);
829
830         if (stat(path, &st) < 0)
831                 return NULL;
832
833         return fopen(path, "r");
834 }
835
836 int perf_pmu__scan_file(struct perf_pmu *pmu, const char *name, const char *fmt,
837                         ...)
838 {
839         va_list args;
840         FILE *file;
841         int ret = EOF;
842
843         va_start(args, fmt);
844         file = perf_pmu__open_file(pmu, name);
845         if (file) {
846                 ret = vfscanf(file, fmt, args);
847                 fclose(file);
848         }
849         va_end(args);
850         return ret;
851 }