aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/util/parse-events.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/perf/util/parse-events.c')
-rw-r--r--tools/perf/util/parse-events.c230
1 files changed, 130 insertions, 100 deletions
diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c
index 5cb6f4bde905..952b4ae3d954 100644
--- a/tools/perf/util/parse-events.c
+++ b/tools/perf/util/parse-events.c
@@ -1,6 +1,7 @@
1#include "../../../include/linux/hw_breakpoint.h" 1#include "../../../include/linux/hw_breakpoint.h"
2#include "util.h" 2#include "util.h"
3#include "../perf.h" 3#include "../perf.h"
4#include "evlist.h"
4#include "evsel.h" 5#include "evsel.h"
5#include "parse-options.h" 6#include "parse-options.h"
6#include "parse-events.h" 7#include "parse-events.h"
@@ -11,10 +12,6 @@
11#include "header.h" 12#include "header.h"
12#include "debugfs.h" 13#include "debugfs.h"
13 14
14int nr_counters;
15
16LIST_HEAD(evsel_list);
17
18struct event_symbol { 15struct event_symbol {
19 u8 type; 16 u8 type;
20 u64 config; 17 u64 config;
@@ -266,11 +263,36 @@ static char *event_cache_name(u8 cache_type, u8 cache_op, u8 cache_result)
266 return name; 263 return name;
267} 264}
268 265
266const char *event_type(int type)
267{
268 switch (type) {
269 case PERF_TYPE_HARDWARE:
270 return "hardware";
271
272 case PERF_TYPE_SOFTWARE:
273 return "software";
274
275 case PERF_TYPE_TRACEPOINT:
276 return "tracepoint";
277
278 case PERF_TYPE_HW_CACHE:
279 return "hardware-cache";
280
281 default:
282 break;
283 }
284
285 return "unknown";
286}
287
269const char *event_name(struct perf_evsel *evsel) 288const char *event_name(struct perf_evsel *evsel)
270{ 289{
271 u64 config = evsel->attr.config; 290 u64 config = evsel->attr.config;
272 int type = evsel->attr.type; 291 int type = evsel->attr.type;
273 292
293 if (evsel->name)
294 return evsel->name;
295
274 return __event_name(type, config); 296 return __event_name(type, config);
275} 297}
276 298
@@ -279,7 +301,7 @@ const char *__event_name(int type, u64 config)
279 static char buf[32]; 301 static char buf[32];
280 302
281 if (type == PERF_TYPE_RAW) { 303 if (type == PERF_TYPE_RAW) {
282 sprintf(buf, "raw 0x%llx", config); 304 sprintf(buf, "raw 0x%" PRIx64, config);
283 return buf; 305 return buf;
284 } 306 }
285 307
@@ -449,8 +471,8 @@ parse_single_tracepoint_event(char *sys_name,
449/* sys + ':' + event + ':' + flags*/ 471/* sys + ':' + event + ':' + flags*/
450#define MAX_EVOPT_LEN (MAX_EVENT_LENGTH * 2 + 2 + 128) 472#define MAX_EVOPT_LEN (MAX_EVENT_LENGTH * 2 + 2 + 128)
451static enum event_result 473static enum event_result
452parse_multiple_tracepoint_event(char *sys_name, const char *evt_exp, 474parse_multiple_tracepoint_event(const struct option *opt, char *sys_name,
453 char *flags) 475 const char *evt_exp, char *flags)
454{ 476{
455 char evt_path[MAXPATHLEN]; 477 char evt_path[MAXPATHLEN];
456 struct dirent *evt_ent; 478 struct dirent *evt_ent;
@@ -483,41 +505,16 @@ parse_multiple_tracepoint_event(char *sys_name, const char *evt_exp,
483 if (len < 0) 505 if (len < 0)
484 return EVT_FAILED; 506 return EVT_FAILED;
485 507
486 if (parse_events(NULL, event_opt, 0)) 508 if (parse_events(opt, event_opt, 0))
487 return EVT_FAILED; 509 return EVT_FAILED;
488 } 510 }
489 511
490 return EVT_HANDLED_ALL; 512 return EVT_HANDLED_ALL;
491} 513}
492 514
493static int store_event_type(const char *orgname) 515static enum event_result
494{ 516parse_tracepoint_event(const struct option *opt, const char **strp,
495 char filename[PATH_MAX], *c; 517 struct perf_event_attr *attr)
496 FILE *file;
497 int id, n;
498
499 sprintf(filename, "%s/", debugfs_path);
500 strncat(filename, orgname, strlen(orgname));
501 strcat(filename, "/id");
502
503 c = strchr(filename, ':');
504 if (c)
505 *c = '/';
506
507 file = fopen(filename, "r");
508 if (!file)
509 return 0;
510 n = fscanf(file, "%i", &id);
511 fclose(file);
512 if (n < 1) {
513 pr_err("cannot store event ID\n");
514 return -EINVAL;
515 }
516 return perf_header__push_event(id, orgname);
517}
518
519static enum event_result parse_tracepoint_event(const char **strp,
520 struct perf_event_attr *attr)
521{ 518{
522 const char *evt_name; 519 const char *evt_name;
523 char *flags = NULL, *comma_loc; 520 char *flags = NULL, *comma_loc;
@@ -555,13 +552,10 @@ static enum event_result parse_tracepoint_event(const char **strp,
555 if (evt_length >= MAX_EVENT_LENGTH) 552 if (evt_length >= MAX_EVENT_LENGTH)
556 return EVT_FAILED; 553 return EVT_FAILED;
557 if (strpbrk(evt_name, "*?")) { 554 if (strpbrk(evt_name, "*?")) {
558 *strp += strlen(sys_name) + evt_length; 555 *strp += strlen(sys_name) + evt_length + 1; /* 1 == the ':' */
559 return parse_multiple_tracepoint_event(sys_name, evt_name, 556 return parse_multiple_tracepoint_event(opt, sys_name, evt_name,
560 flags); 557 flags);
561 } else { 558 } else {
562 if (store_event_type(evt_name) < 0)
563 return EVT_FAILED;
564
565 return parse_single_tracepoint_event(sys_name, evt_name, 559 return parse_single_tracepoint_event(sys_name, evt_name,
566 evt_length, attr, strp); 560 evt_length, attr, strp);
567 } 561 }
@@ -769,11 +763,12 @@ parse_event_modifier(const char **strp, struct perf_event_attr *attr)
769 * Symbolic names are (almost) exactly matched. 763 * Symbolic names are (almost) exactly matched.
770 */ 764 */
771static enum event_result 765static enum event_result
772parse_event_symbols(const char **str, struct perf_event_attr *attr) 766parse_event_symbols(const struct option *opt, const char **str,
767 struct perf_event_attr *attr)
773{ 768{
774 enum event_result ret; 769 enum event_result ret;
775 770
776 ret = parse_tracepoint_event(str, attr); 771 ret = parse_tracepoint_event(opt, str, attr);
777 if (ret != EVT_FAILED) 772 if (ret != EVT_FAILED)
778 goto modifier; 773 goto modifier;
779 774
@@ -807,14 +802,17 @@ modifier:
807 return ret; 802 return ret;
808} 803}
809 804
810int parse_events(const struct option *opt __used, const char *str, int unset __used) 805int parse_events(const struct option *opt, const char *str, int unset __used)
811{ 806{
807 struct perf_evlist *evlist = *(struct perf_evlist **)opt->value;
812 struct perf_event_attr attr; 808 struct perf_event_attr attr;
813 enum event_result ret; 809 enum event_result ret;
810 const char *ostr;
814 811
815 for (;;) { 812 for (;;) {
813 ostr = str;
816 memset(&attr, 0, sizeof(attr)); 814 memset(&attr, 0, sizeof(attr));
817 ret = parse_event_symbols(&str, &attr); 815 ret = parse_event_symbols(opt, &str, &attr);
818 if (ret == EVT_FAILED) 816 if (ret == EVT_FAILED)
819 return -1; 817 return -1;
820 818
@@ -823,12 +821,15 @@ int parse_events(const struct option *opt __used, const char *str, int unset __u
823 821
824 if (ret != EVT_HANDLED_ALL) { 822 if (ret != EVT_HANDLED_ALL) {
825 struct perf_evsel *evsel; 823 struct perf_evsel *evsel;
826 evsel = perf_evsel__new(&attr, 824 evsel = perf_evsel__new(&attr, evlist->nr_entries);
827 nr_counters);
828 if (evsel == NULL) 825 if (evsel == NULL)
829 return -1; 826 return -1;
830 list_add_tail(&evsel->node, &evsel_list); 827 perf_evlist__add(evlist, evsel);
831 ++nr_counters; 828
829 evsel->name = calloc(str - ostr + 1, 1);
830 if (!evsel->name)
831 return -1;
832 strncpy(evsel->name, ostr, str - ostr);
832 } 833 }
833 834
834 if (*str == 0) 835 if (*str == 0)
@@ -842,13 +843,14 @@ int parse_events(const struct option *opt __used, const char *str, int unset __u
842 return 0; 843 return 0;
843} 844}
844 845
845int parse_filter(const struct option *opt __used, const char *str, 846int parse_filter(const struct option *opt, const char *str,
846 int unset __used) 847 int unset __used)
847{ 848{
849 struct perf_evlist *evlist = *(struct perf_evlist **)opt->value;
848 struct perf_evsel *last = NULL; 850 struct perf_evsel *last = NULL;
849 851
850 if (!list_empty(&evsel_list)) 852 if (evlist->nr_entries > 0)
851 last = list_entry(evsel_list.prev, struct perf_evsel, node); 853 last = list_entry(evlist->entries.prev, struct perf_evsel, node);
852 854
853 if (last == NULL || last->attr.type != PERF_TYPE_TRACEPOINT) { 855 if (last == NULL || last->attr.type != PERF_TYPE_TRACEPOINT) {
854 fprintf(stderr, 856 fprintf(stderr,
@@ -878,7 +880,7 @@ static const char * const event_type_descriptors[] = {
878 * Print the events from <debugfs_mount_point>/tracing/events 880 * Print the events from <debugfs_mount_point>/tracing/events
879 */ 881 */
880 882
881static void print_tracepoint_events(void) 883void print_tracepoint_events(const char *subsys_glob, const char *event_glob)
882{ 884{
883 DIR *sys_dir, *evt_dir; 885 DIR *sys_dir, *evt_dir;
884 struct dirent *sys_next, *evt_next, sys_dirent, evt_dirent; 886 struct dirent *sys_next, *evt_next, sys_dirent, evt_dirent;
@@ -893,6 +895,9 @@ static void print_tracepoint_events(void)
893 return; 895 return;
894 896
895 for_each_subsystem(sys_dir, sys_dirent, sys_next) { 897 for_each_subsystem(sys_dir, sys_dirent, sys_next) {
898 if (subsys_glob != NULL &&
899 !strglobmatch(sys_dirent.d_name, subsys_glob))
900 continue;
896 901
897 snprintf(dir_path, MAXPATHLEN, "%s/%s", debugfs_path, 902 snprintf(dir_path, MAXPATHLEN, "%s/%s", debugfs_path,
898 sys_dirent.d_name); 903 sys_dirent.d_name);
@@ -901,6 +906,10 @@ static void print_tracepoint_events(void)
901 continue; 906 continue;
902 907
903 for_each_event(sys_dirent, evt_dir, evt_dirent, evt_next) { 908 for_each_event(sys_dirent, evt_dir, evt_dirent, evt_next) {
909 if (event_glob != NULL &&
910 !strglobmatch(evt_dirent.d_name, event_glob))
911 continue;
912
904 snprintf(evt_path, MAXPATHLEN, "%s:%s", 913 snprintf(evt_path, MAXPATHLEN, "%s:%s",
905 sys_dirent.d_name, evt_dirent.d_name); 914 sys_dirent.d_name, evt_dirent.d_name);
906 printf(" %-42s [%s]\n", evt_path, 915 printf(" %-42s [%s]\n", evt_path,
@@ -952,13 +961,61 @@ int is_valid_tracepoint(const char *event_string)
952 return 0; 961 return 0;
953} 962}
954 963
964void print_events_type(u8 type)
965{
966 struct event_symbol *syms = event_symbols;
967 unsigned int i;
968 char name[64];
969
970 for (i = 0; i < ARRAY_SIZE(event_symbols); i++, syms++) {
971 if (type != syms->type)
972 continue;
973
974 if (strlen(syms->alias))
975 snprintf(name, sizeof(name), "%s OR %s",
976 syms->symbol, syms->alias);
977 else
978 snprintf(name, sizeof(name), "%s", syms->symbol);
979
980 printf(" %-42s [%s]\n", name,
981 event_type_descriptors[type]);
982 }
983}
984
985int print_hwcache_events(const char *event_glob)
986{
987 unsigned int type, op, i, printed = 0;
988
989 for (type = 0; type < PERF_COUNT_HW_CACHE_MAX; type++) {
990 for (op = 0; op < PERF_COUNT_HW_CACHE_OP_MAX; op++) {
991 /* skip invalid cache type */
992 if (!is_cache_op_valid(type, op))
993 continue;
994
995 for (i = 0; i < PERF_COUNT_HW_CACHE_RESULT_MAX; i++) {
996 char *name = event_cache_name(type, op, i);
997
998 if (event_glob != NULL &&
999 !strglobmatch(name, event_glob))
1000 continue;
1001
1002 printf(" %-42s [%s]\n", name,
1003 event_type_descriptors[PERF_TYPE_HW_CACHE]);
1004 ++printed;
1005 }
1006 }
1007 }
1008
1009 return printed;
1010}
1011
955/* 1012/*
956 * Print the help text for the event symbols: 1013 * Print the help text for the event symbols:
957 */ 1014 */
958void print_events(void) 1015void print_events(const char *event_glob)
959{ 1016{
960 struct event_symbol *syms = event_symbols; 1017 struct event_symbol *syms = event_symbols;
961 unsigned int i, type, op, prev_type = -1; 1018 unsigned int i, type, prev_type = -1, printed = 0, ntypes_printed = 0;
962 char name[40]; 1019 char name[40];
963 1020
964 printf("\n"); 1021 printf("\n");
@@ -967,8 +1024,16 @@ void print_events(void)
967 for (i = 0; i < ARRAY_SIZE(event_symbols); i++, syms++) { 1024 for (i = 0; i < ARRAY_SIZE(event_symbols); i++, syms++) {
968 type = syms->type; 1025 type = syms->type;
969 1026
970 if (type != prev_type) 1027 if (type != prev_type && printed) {
971 printf("\n"); 1028 printf("\n");
1029 printed = 0;
1030 ntypes_printed++;
1031 }
1032
1033 if (event_glob != NULL &&
1034 !(strglobmatch(syms->symbol, event_glob) ||
1035 (syms->alias && strglobmatch(syms->alias, event_glob))))
1036 continue;
972 1037
973 if (strlen(syms->alias)) 1038 if (strlen(syms->alias))
974 sprintf(name, "%s OR %s", syms->symbol, syms->alias); 1039 sprintf(name, "%s OR %s", syms->symbol, syms->alias);
@@ -978,22 +1043,17 @@ void print_events(void)
978 event_type_descriptors[type]); 1043 event_type_descriptors[type]);
979 1044
980 prev_type = type; 1045 prev_type = type;
1046 ++printed;
981 } 1047 }
982 1048
983 printf("\n"); 1049 if (ntypes_printed) {
984 for (type = 0; type < PERF_COUNT_HW_CACHE_MAX; type++) { 1050 printed = 0;
985 for (op = 0; op < PERF_COUNT_HW_CACHE_OP_MAX; op++) { 1051 printf("\n");
986 /* skip invalid cache type */
987 if (!is_cache_op_valid(type, op))
988 continue;
989
990 for (i = 0; i < PERF_COUNT_HW_CACHE_RESULT_MAX; i++) {
991 printf(" %-42s [%s]\n",
992 event_cache_name(type, op, i),
993 event_type_descriptors[PERF_TYPE_HW_CACHE]);
994 }
995 }
996 } 1052 }
1053 print_hwcache_events(event_glob);
1054
1055 if (event_glob != NULL)
1056 return;
997 1057
998 printf("\n"); 1058 printf("\n");
999 printf(" %-42s [%s]\n", 1059 printf(" %-42s [%s]\n",
@@ -1006,37 +1066,7 @@ void print_events(void)
1006 event_type_descriptors[PERF_TYPE_BREAKPOINT]); 1066 event_type_descriptors[PERF_TYPE_BREAKPOINT]);
1007 printf("\n"); 1067 printf("\n");
1008 1068
1009 print_tracepoint_events(); 1069 print_tracepoint_events(NULL, NULL);
1010 1070
1011 exit(129); 1071 exit(129);
1012} 1072}
1013
1014int perf_evsel_list__create_default(void)
1015{
1016 struct perf_evsel *evsel;
1017 struct perf_event_attr attr;
1018
1019 memset(&attr, 0, sizeof(attr));
1020 attr.type = PERF_TYPE_HARDWARE;
1021 attr.config = PERF_COUNT_HW_CPU_CYCLES;
1022
1023 evsel = perf_evsel__new(&attr, 0);
1024
1025 if (evsel == NULL)
1026 return -ENOMEM;
1027
1028 list_add(&evsel->node, &evsel_list);
1029 ++nr_counters;
1030 return 0;
1031}
1032
1033void perf_evsel_list__delete(void)
1034{
1035 struct perf_evsel *pos, *n;
1036
1037 list_for_each_entry_safe(pos, n, &evsel_list, node) {
1038 list_del_init(&pos->node);
1039 perf_evsel__delete(pos);
1040 }
1041 nr_counters = 0;
1042}