aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/util/parse-events.c
diff options
context:
space:
mode:
authorGlenn Elliott <gelliott@cs.unc.edu>2012-03-04 19:47:13 -0500
committerGlenn Elliott <gelliott@cs.unc.edu>2012-03-04 19:47:13 -0500
commitc71c03bda1e86c9d5198c5d83f712e695c4f2a1e (patch)
treeecb166cb3e2b7e2adb3b5e292245fefd23381ac8 /tools/perf/util/parse-events.c
parentea53c912f8a86a8567697115b6a0d8152beee5c8 (diff)
parent6a00f206debf8a5c8899055726ad127dbeeed098 (diff)
Merge branch 'mpi-master' into wip-k-fmlpwip-k-fmlp
Conflicts: litmus/sched_cedf.c
Diffstat (limited to 'tools/perf/util/parse-events.c')
-rw-r--r--tools/perf/util/parse-events.c388
1 files changed, 258 insertions, 130 deletions
diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c
index 4af5bd59cfd1..41982c373faf 100644
--- a/tools/perf/util/parse-events.c
+++ b/tools/perf/util/parse-events.c
@@ -1,6 +1,8 @@
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"
5#include "evsel.h"
4#include "parse-options.h" 6#include "parse-options.h"
5#include "parse-events.h" 7#include "parse-events.h"
6#include "exec_cmd.h" 8#include "exec_cmd.h"
@@ -10,11 +12,6 @@
10#include "header.h" 12#include "header.h"
11#include "debugfs.h" 13#include "debugfs.h"
12 14
13int nr_counters;
14
15struct perf_event_attr attrs[MAX_COUNTERS];
16char *filters[MAX_COUNTERS];
17
18struct event_symbol { 15struct event_symbol {
19 u8 type; 16 u8 type;
20 u64 config; 17 u64 config;
@@ -34,34 +31,36 @@ char debugfs_path[MAXPATHLEN];
34#define CSW(x) .type = PERF_TYPE_SOFTWARE, .config = PERF_COUNT_SW_##x 31#define CSW(x) .type = PERF_TYPE_SOFTWARE, .config = PERF_COUNT_SW_##x
35 32
36static struct event_symbol event_symbols[] = { 33static struct event_symbol event_symbols[] = {
37 { CHW(CPU_CYCLES), "cpu-cycles", "cycles" }, 34 { CHW(CPU_CYCLES), "cpu-cycles", "cycles" },
38 { CHW(INSTRUCTIONS), "instructions", "" }, 35 { CHW(STALLED_CYCLES_FRONTEND), "stalled-cycles-frontend", "idle-cycles-frontend" },
39 { CHW(CACHE_REFERENCES), "cache-references", "" }, 36 { CHW(STALLED_CYCLES_BACKEND), "stalled-cycles-backend", "idle-cycles-backend" },
40 { CHW(CACHE_MISSES), "cache-misses", "" }, 37 { CHW(INSTRUCTIONS), "instructions", "" },
41 { CHW(BRANCH_INSTRUCTIONS), "branch-instructions", "branches" }, 38 { CHW(CACHE_REFERENCES), "cache-references", "" },
42 { CHW(BRANCH_MISSES), "branch-misses", "" }, 39 { CHW(CACHE_MISSES), "cache-misses", "" },
43 { CHW(BUS_CYCLES), "bus-cycles", "" }, 40 { CHW(BRANCH_INSTRUCTIONS), "branch-instructions", "branches" },
44 41 { CHW(BRANCH_MISSES), "branch-misses", "" },
45 { CSW(CPU_CLOCK), "cpu-clock", "" }, 42 { CHW(BUS_CYCLES), "bus-cycles", "" },
46 { CSW(TASK_CLOCK), "task-clock", "" }, 43
47 { CSW(PAGE_FAULTS), "page-faults", "faults" }, 44 { CSW(CPU_CLOCK), "cpu-clock", "" },
48 { CSW(PAGE_FAULTS_MIN), "minor-faults", "" }, 45 { CSW(TASK_CLOCK), "task-clock", "" },
49 { CSW(PAGE_FAULTS_MAJ), "major-faults", "" }, 46 { CSW(PAGE_FAULTS), "page-faults", "faults" },
50 { CSW(CONTEXT_SWITCHES), "context-switches", "cs" }, 47 { CSW(PAGE_FAULTS_MIN), "minor-faults", "" },
51 { CSW(CPU_MIGRATIONS), "cpu-migrations", "migrations" }, 48 { CSW(PAGE_FAULTS_MAJ), "major-faults", "" },
52 { CSW(ALIGNMENT_FAULTS), "alignment-faults", "" }, 49 { CSW(CONTEXT_SWITCHES), "context-switches", "cs" },
53 { CSW(EMULATION_FAULTS), "emulation-faults", "" }, 50 { CSW(CPU_MIGRATIONS), "cpu-migrations", "migrations" },
51 { CSW(ALIGNMENT_FAULTS), "alignment-faults", "" },
52 { CSW(EMULATION_FAULTS), "emulation-faults", "" },
54}; 53};
55 54
56#define __PERF_EVENT_FIELD(config, name) \ 55#define __PERF_EVENT_FIELD(config, name) \
57 ((config & PERF_EVENT_##name##_MASK) >> PERF_EVENT_##name##_SHIFT) 56 ((config & PERF_EVENT_##name##_MASK) >> PERF_EVENT_##name##_SHIFT)
58 57
59#define PERF_EVENT_RAW(config) __PERF_EVENT_FIELD(config, RAW) 58#define PERF_EVENT_RAW(config) __PERF_EVENT_FIELD(config, RAW)
60#define PERF_EVENT_CONFIG(config) __PERF_EVENT_FIELD(config, CONFIG) 59#define PERF_EVENT_CONFIG(config) __PERF_EVENT_FIELD(config, CONFIG)
61#define PERF_EVENT_TYPE(config) __PERF_EVENT_FIELD(config, TYPE) 60#define PERF_EVENT_TYPE(config) __PERF_EVENT_FIELD(config, TYPE)
62#define PERF_EVENT_ID(config) __PERF_EVENT_FIELD(config, EVENT) 61#define PERF_EVENT_ID(config) __PERF_EVENT_FIELD(config, EVENT)
63 62
64static const char *hw_event_names[] = { 63static const char *hw_event_names[PERF_COUNT_HW_MAX] = {
65 "cycles", 64 "cycles",
66 "instructions", 65 "instructions",
67 "cache-references", 66 "cache-references",
@@ -69,11 +68,13 @@ static const char *hw_event_names[] = {
69 "branches", 68 "branches",
70 "branch-misses", 69 "branch-misses",
71 "bus-cycles", 70 "bus-cycles",
71 "stalled-cycles-frontend",
72 "stalled-cycles-backend",
72}; 73};
73 74
74static const char *sw_event_names[] = { 75static const char *sw_event_names[PERF_COUNT_SW_MAX] = {
75 "cpu-clock-msecs", 76 "cpu-clock",
76 "task-clock-msecs", 77 "task-clock",
77 "page-faults", 78 "page-faults",
78 "context-switches", 79 "context-switches",
79 "CPU-migrations", 80 "CPU-migrations",
@@ -266,10 +267,35 @@ static char *event_cache_name(u8 cache_type, u8 cache_op, u8 cache_result)
266 return name; 267 return name;
267} 268}
268 269
269const char *event_name(int counter) 270const char *event_type(int type)
270{ 271{
271 u64 config = attrs[counter].config; 272 switch (type) {
272 int type = attrs[counter].type; 273 case PERF_TYPE_HARDWARE:
274 return "hardware";
275
276 case PERF_TYPE_SOFTWARE:
277 return "software";
278
279 case PERF_TYPE_TRACEPOINT:
280 return "tracepoint";
281
282 case PERF_TYPE_HW_CACHE:
283 return "hardware-cache";
284
285 default:
286 break;
287 }
288
289 return "unknown";
290}
291
292const char *event_name(struct perf_evsel *evsel)
293{
294 u64 config = evsel->attr.config;
295 int type = evsel->attr.type;
296
297 if (evsel->name)
298 return evsel->name;
273 299
274 return __event_name(type, config); 300 return __event_name(type, config);
275} 301}
@@ -279,13 +305,13 @@ const char *__event_name(int type, u64 config)
279 static char buf[32]; 305 static char buf[32];
280 306
281 if (type == PERF_TYPE_RAW) { 307 if (type == PERF_TYPE_RAW) {
282 sprintf(buf, "raw 0x%llx", config); 308 sprintf(buf, "raw 0x%" PRIx64, config);
283 return buf; 309 return buf;
284 } 310 }
285 311
286 switch (type) { 312 switch (type) {
287 case PERF_TYPE_HARDWARE: 313 case PERF_TYPE_HARDWARE:
288 if (config < PERF_COUNT_HW_MAX) 314 if (config < PERF_COUNT_HW_MAX && hw_event_names[config])
289 return hw_event_names[config]; 315 return hw_event_names[config];
290 return "unknown-hardware"; 316 return "unknown-hardware";
291 317
@@ -311,7 +337,7 @@ const char *__event_name(int type, u64 config)
311 } 337 }
312 338
313 case PERF_TYPE_SOFTWARE: 339 case PERF_TYPE_SOFTWARE:
314 if (config < PERF_COUNT_SW_MAX) 340 if (config < PERF_COUNT_SW_MAX && sw_event_names[config])
315 return sw_event_names[config]; 341 return sw_event_names[config];
316 return "unknown-software"; 342 return "unknown-software";
317 343
@@ -434,7 +460,7 @@ parse_single_tracepoint_event(char *sys_name,
434 id = atoll(id_buf); 460 id = atoll(id_buf);
435 attr->config = id; 461 attr->config = id;
436 attr->type = PERF_TYPE_TRACEPOINT; 462 attr->type = PERF_TYPE_TRACEPOINT;
437 *strp = evt_name + evt_length; 463 *strp += strlen(sys_name) + evt_length + 1; /* + 1 for the ':' */
438 464
439 attr->sample_type |= PERF_SAMPLE_RAW; 465 attr->sample_type |= PERF_SAMPLE_RAW;
440 attr->sample_type |= PERF_SAMPLE_TIME; 466 attr->sample_type |= PERF_SAMPLE_TIME;
@@ -449,8 +475,8 @@ parse_single_tracepoint_event(char *sys_name,
449/* sys + ':' + event + ':' + flags*/ 475/* sys + ':' + event + ':' + flags*/
450#define MAX_EVOPT_LEN (MAX_EVENT_LENGTH * 2 + 2 + 128) 476#define MAX_EVOPT_LEN (MAX_EVENT_LENGTH * 2 + 2 + 128)
451static enum event_result 477static enum event_result
452parse_multiple_tracepoint_event(char *sys_name, const char *evt_exp, 478parse_multiple_tracepoint_event(const struct option *opt, char *sys_name,
453 char *flags) 479 const char *evt_exp, char *flags)
454{ 480{
455 char evt_path[MAXPATHLEN]; 481 char evt_path[MAXPATHLEN];
456 struct dirent *evt_ent; 482 struct dirent *evt_ent;
@@ -483,19 +509,19 @@ parse_multiple_tracepoint_event(char *sys_name, const char *evt_exp,
483 if (len < 0) 509 if (len < 0)
484 return EVT_FAILED; 510 return EVT_FAILED;
485 511
486 if (parse_events(NULL, event_opt, 0)) 512 if (parse_events(opt, event_opt, 0))
487 return EVT_FAILED; 513 return EVT_FAILED;
488 } 514 }
489 515
490 return EVT_HANDLED_ALL; 516 return EVT_HANDLED_ALL;
491} 517}
492 518
493 519static enum event_result
494static enum event_result parse_tracepoint_event(const char **strp, 520parse_tracepoint_event(const struct option *opt, const char **strp,
495 struct perf_event_attr *attr) 521 struct perf_event_attr *attr)
496{ 522{
497 const char *evt_name; 523 const char *evt_name;
498 char *flags; 524 char *flags = NULL, *comma_loc;
499 char sys_name[MAX_EVENT_LENGTH]; 525 char sys_name[MAX_EVENT_LENGTH];
500 unsigned int sys_length, evt_length; 526 unsigned int sys_length, evt_length;
501 527
@@ -514,6 +540,11 @@ static enum event_result parse_tracepoint_event(const char **strp,
514 sys_name[sys_length] = '\0'; 540 sys_name[sys_length] = '\0';
515 evt_name = evt_name + 1; 541 evt_name = evt_name + 1;
516 542
543 comma_loc = strchr(evt_name, ',');
544 if (comma_loc) {
545 /* take the event name up to the comma */
546 evt_name = strndup(evt_name, comma_loc - evt_name);
547 }
517 flags = strchr(evt_name, ':'); 548 flags = strchr(evt_name, ':');
518 if (flags) { 549 if (flags) {
519 /* split it out: */ 550 /* split it out: */
@@ -524,14 +555,14 @@ static enum event_result parse_tracepoint_event(const char **strp,
524 evt_length = strlen(evt_name); 555 evt_length = strlen(evt_name);
525 if (evt_length >= MAX_EVENT_LENGTH) 556 if (evt_length >= MAX_EVENT_LENGTH)
526 return EVT_FAILED; 557 return EVT_FAILED;
527
528 if (strpbrk(evt_name, "*?")) { 558 if (strpbrk(evt_name, "*?")) {
529 *strp = evt_name + evt_length; 559 *strp += strlen(sys_name) + evt_length + 1; /* 1 == the ':' */
530 return parse_multiple_tracepoint_event(sys_name, evt_name, 560 return parse_multiple_tracepoint_event(opt, sys_name, evt_name,
531 flags); 561 flags);
532 } else 562 } else {
533 return parse_single_tracepoint_event(sys_name, evt_name, 563 return parse_single_tracepoint_event(sys_name, evt_name,
534 evt_length, attr, strp); 564 evt_length, attr, strp);
565 }
535} 566}
536 567
537static enum event_result 568static enum event_result
@@ -621,13 +652,15 @@ static int check_events(const char *str, unsigned int i)
621 int n; 652 int n;
622 653
623 n = strlen(event_symbols[i].symbol); 654 n = strlen(event_symbols[i].symbol);
624 if (!strncmp(str, event_symbols[i].symbol, n)) 655 if (!strncasecmp(str, event_symbols[i].symbol, n))
625 return n; 656 return n;
626 657
627 n = strlen(event_symbols[i].alias); 658 n = strlen(event_symbols[i].alias);
628 if (n) 659 if (n) {
629 if (!strncmp(str, event_symbols[i].alias, n)) 660 if (!strncasecmp(str, event_symbols[i].alias, n))
630 return n; 661 return n;
662 }
663
631 return 0; 664 return 0;
632} 665}
633 666
@@ -691,15 +724,22 @@ parse_numeric_event(const char **strp, struct perf_event_attr *attr)
691 return EVT_FAILED; 724 return EVT_FAILED;
692} 725}
693 726
694static enum event_result 727static int
695parse_event_modifier(const char **strp, struct perf_event_attr *attr) 728parse_event_modifier(const char **strp, struct perf_event_attr *attr)
696{ 729{
697 const char *str = *strp; 730 const char *str = *strp;
698 int exclude = 0; 731 int exclude = 0;
699 int eu = 0, ek = 0, eh = 0, precise = 0; 732 int eu = 0, ek = 0, eh = 0, precise = 0;
700 733
701 if (*str++ != ':') 734 if (!*str)
702 return 0; 735 return 0;
736
737 if (*str == ',')
738 return 0;
739
740 if (*str++ != ':')
741 return -1;
742
703 while (*str) { 743 while (*str) {
704 if (*str == 'u') { 744 if (*str == 'u') {
705 if (!exclude) 745 if (!exclude)
@@ -720,14 +760,16 @@ parse_event_modifier(const char **strp, struct perf_event_attr *attr)
720 760
721 ++str; 761 ++str;
722 } 762 }
723 if (str >= *strp + 2) { 763 if (str < *strp + 2)
724 *strp = str; 764 return -1;
725 attr->exclude_user = eu; 765
726 attr->exclude_kernel = ek; 766 *strp = str;
727 attr->exclude_hv = eh; 767
728 attr->precise_ip = precise; 768 attr->exclude_user = eu;
729 return 1; 769 attr->exclude_kernel = ek;
730 } 770 attr->exclude_hv = eh;
771 attr->precise_ip = precise;
772
731 return 0; 773 return 0;
732} 774}
733 775
@@ -736,11 +778,12 @@ parse_event_modifier(const char **strp, struct perf_event_attr *attr)
736 * Symbolic names are (almost) exactly matched. 778 * Symbolic names are (almost) exactly matched.
737 */ 779 */
738static enum event_result 780static enum event_result
739parse_event_symbols(const char **str, struct perf_event_attr *attr) 781parse_event_symbols(const struct option *opt, const char **str,
782 struct perf_event_attr *attr)
740{ 783{
741 enum event_result ret; 784 enum event_result ret;
742 785
743 ret = parse_tracepoint_event(str, attr); 786 ret = parse_tracepoint_event(opt, str, attr);
744 if (ret != EVT_FAILED) 787 if (ret != EVT_FAILED)
745 goto modifier; 788 goto modifier;
746 789
@@ -769,52 +812,27 @@ parse_event_symbols(const char **str, struct perf_event_attr *attr)
769 return EVT_FAILED; 812 return EVT_FAILED;
770 813
771modifier: 814modifier:
772 parse_event_modifier(str, attr); 815 if (parse_event_modifier(str, attr) < 0) {
773 816 fprintf(stderr, "invalid event modifier: '%s'\n", *str);
774 return ret; 817 fprintf(stderr, "Run 'perf list' for a list of valid events and modifiers\n");
775}
776
777static int store_event_type(const char *orgname)
778{
779 char filename[PATH_MAX], *c;
780 FILE *file;
781 int id, n;
782 818
783 sprintf(filename, "%s/", debugfs_path); 819 return EVT_FAILED;
784 strncat(filename, orgname, strlen(orgname));
785 strcat(filename, "/id");
786
787 c = strchr(filename, ':');
788 if (c)
789 *c = '/';
790
791 file = fopen(filename, "r");
792 if (!file)
793 return 0;
794 n = fscanf(file, "%i", &id);
795 fclose(file);
796 if (n < 1) {
797 pr_err("cannot store event ID\n");
798 return -EINVAL;
799 } 820 }
800 return perf_header__push_event(id, orgname); 821
822 return ret;
801} 823}
802 824
803int parse_events(const struct option *opt __used, const char *str, int unset __used) 825int parse_events(const struct option *opt, const char *str, int unset __used)
804{ 826{
827 struct perf_evlist *evlist = *(struct perf_evlist **)opt->value;
805 struct perf_event_attr attr; 828 struct perf_event_attr attr;
806 enum event_result ret; 829 enum event_result ret;
807 830 const char *ostr;
808 if (strchr(str, ':'))
809 if (store_event_type(str) < 0)
810 return -1;
811 831
812 for (;;) { 832 for (;;) {
813 if (nr_counters == MAX_COUNTERS) 833 ostr = str;
814 return -1;
815
816 memset(&attr, 0, sizeof(attr)); 834 memset(&attr, 0, sizeof(attr));
817 ret = parse_event_symbols(&str, &attr); 835 ret = parse_event_symbols(opt, &str, &attr);
818 if (ret == EVT_FAILED) 836 if (ret == EVT_FAILED)
819 return -1; 837 return -1;
820 838
@@ -822,8 +840,16 @@ int parse_events(const struct option *opt __used, const char *str, int unset __u
822 return -1; 840 return -1;
823 841
824 if (ret != EVT_HANDLED_ALL) { 842 if (ret != EVT_HANDLED_ALL) {
825 attrs[nr_counters] = attr; 843 struct perf_evsel *evsel;
826 nr_counters++; 844 evsel = perf_evsel__new(&attr, evlist->nr_entries);
845 if (evsel == NULL)
846 return -1;
847 perf_evlist__add(evlist, evsel);
848
849 evsel->name = calloc(str - ostr + 1, 1);
850 if (!evsel->name)
851 return -1;
852 strncpy(evsel->name, ostr, str - ostr);
827 } 853 }
828 854
829 if (*str == 0) 855 if (*str == 0)
@@ -837,24 +863,26 @@ int parse_events(const struct option *opt __used, const char *str, int unset __u
837 return 0; 863 return 0;
838} 864}
839 865
840int parse_filter(const struct option *opt __used, const char *str, 866int parse_filter(const struct option *opt, const char *str,
841 int unset __used) 867 int unset __used)
842{ 868{
843 int i = nr_counters - 1; 869 struct perf_evlist *evlist = *(struct perf_evlist **)opt->value;
844 int len = strlen(str); 870 struct perf_evsel *last = NULL;
871
872 if (evlist->nr_entries > 0)
873 last = list_entry(evlist->entries.prev, struct perf_evsel, node);
845 874
846 if (i < 0 || attrs[i].type != PERF_TYPE_TRACEPOINT) { 875 if (last == NULL || last->attr.type != PERF_TYPE_TRACEPOINT) {
847 fprintf(stderr, 876 fprintf(stderr,
848 "-F option should follow a -e tracepoint option\n"); 877 "-F option should follow a -e tracepoint option\n");
849 return -1; 878 return -1;
850 } 879 }
851 880
852 filters[i] = malloc(len + 1); 881 last->filter = strdup(str);
853 if (!filters[i]) { 882 if (last->filter == NULL) {
854 fprintf(stderr, "not enough memory to hold filter string\n"); 883 fprintf(stderr, "not enough memory to hold filter string\n");
855 return -1; 884 return -1;
856 } 885 }
857 strcpy(filters[i], str);
858 886
859 return 0; 887 return 0;
860} 888}
@@ -872,7 +900,7 @@ static const char * const event_type_descriptors[] = {
872 * Print the events from <debugfs_mount_point>/tracing/events 900 * Print the events from <debugfs_mount_point>/tracing/events
873 */ 901 */
874 902
875static void print_tracepoint_events(void) 903void print_tracepoint_events(const char *subsys_glob, const char *event_glob)
876{ 904{
877 DIR *sys_dir, *evt_dir; 905 DIR *sys_dir, *evt_dir;
878 struct dirent *sys_next, *evt_next, sys_dirent, evt_dirent; 906 struct dirent *sys_next, *evt_next, sys_dirent, evt_dirent;
@@ -887,6 +915,9 @@ static void print_tracepoint_events(void)
887 return; 915 return;
888 916
889 for_each_subsystem(sys_dir, sys_dirent, sys_next) { 917 for_each_subsystem(sys_dir, sys_dirent, sys_next) {
918 if (subsys_glob != NULL &&
919 !strglobmatch(sys_dirent.d_name, subsys_glob))
920 continue;
890 921
891 snprintf(dir_path, MAXPATHLEN, "%s/%s", debugfs_path, 922 snprintf(dir_path, MAXPATHLEN, "%s/%s", debugfs_path,
892 sys_dirent.d_name); 923 sys_dirent.d_name);
@@ -895,9 +926,13 @@ static void print_tracepoint_events(void)
895 continue; 926 continue;
896 927
897 for_each_event(sys_dirent, evt_dir, evt_dirent, evt_next) { 928 for_each_event(sys_dirent, evt_dir, evt_dirent, evt_next) {
929 if (event_glob != NULL &&
930 !strglobmatch(evt_dirent.d_name, event_glob))
931 continue;
932
898 snprintf(evt_path, MAXPATHLEN, "%s:%s", 933 snprintf(evt_path, MAXPATHLEN, "%s:%s",
899 sys_dirent.d_name, evt_dirent.d_name); 934 sys_dirent.d_name, evt_dirent.d_name);
900 printf(" %-42s [%s]\n", evt_path, 935 printf(" %-50s [%s]\n", evt_path,
901 event_type_descriptors[PERF_TYPE_TRACEPOINT]); 936 event_type_descriptors[PERF_TYPE_TRACEPOINT]);
902 } 937 }
903 closedir(evt_dir); 938 closedir(evt_dir);
@@ -906,34 +941,71 @@ static void print_tracepoint_events(void)
906} 941}
907 942
908/* 943/*
909 * Print the help text for the event symbols: 944 * Check whether event is in <debugfs_mount_point>/tracing/events
910 */ 945 */
911void print_events(void) 946
947int is_valid_tracepoint(const char *event_string)
912{ 948{
913 struct event_symbol *syms = event_symbols; 949 DIR *sys_dir, *evt_dir;
914 unsigned int i, type, op, prev_type = -1; 950 struct dirent *sys_next, *evt_next, sys_dirent, evt_dirent;
915 char name[40]; 951 char evt_path[MAXPATHLEN];
952 char dir_path[MAXPATHLEN];
916 953
917 printf("\n"); 954 if (debugfs_valid_mountpoint(debugfs_path))
918 printf("List of pre-defined events (to be used in -e):\n"); 955 return 0;
919 956
920 for (i = 0; i < ARRAY_SIZE(event_symbols); i++, syms++) { 957 sys_dir = opendir(debugfs_path);
921 type = syms->type; 958 if (!sys_dir)
959 return 0;
922 960
923 if (type != prev_type) 961 for_each_subsystem(sys_dir, sys_dirent, sys_next) {
924 printf("\n"); 962
963 snprintf(dir_path, MAXPATHLEN, "%s/%s", debugfs_path,
964 sys_dirent.d_name);
965 evt_dir = opendir(dir_path);
966 if (!evt_dir)
967 continue;
968
969 for_each_event(sys_dirent, evt_dir, evt_dirent, evt_next) {
970 snprintf(evt_path, MAXPATHLEN, "%s:%s",
971 sys_dirent.d_name, evt_dirent.d_name);
972 if (!strcmp(evt_path, event_string)) {
973 closedir(evt_dir);
974 closedir(sys_dir);
975 return 1;
976 }
977 }
978 closedir(evt_dir);
979 }
980 closedir(sys_dir);
981 return 0;
982}
983
984void print_events_type(u8 type)
985{
986 struct event_symbol *syms = event_symbols;
987 unsigned int i;
988 char name[64];
989
990 for (i = 0; i < ARRAY_SIZE(event_symbols); i++, syms++) {
991 if (type != syms->type)
992 continue;
925 993
926 if (strlen(syms->alias)) 994 if (strlen(syms->alias))
927 sprintf(name, "%s OR %s", syms->symbol, syms->alias); 995 snprintf(name, sizeof(name), "%s OR %s",
996 syms->symbol, syms->alias);
928 else 997 else
929 strcpy(name, syms->symbol); 998 snprintf(name, sizeof(name), "%s", syms->symbol);
930 printf(" %-42s [%s]\n", name,
931 event_type_descriptors[type]);
932 999
933 prev_type = type; 1000 printf(" %-50s [%s]\n", name,
1001 event_type_descriptors[type]);
934 } 1002 }
1003}
1004
1005int print_hwcache_events(const char *event_glob)
1006{
1007 unsigned int type, op, i, printed = 0;
935 1008
936 printf("\n");
937 for (type = 0; type < PERF_COUNT_HW_CACHE_MAX; type++) { 1009 for (type = 0; type < PERF_COUNT_HW_CACHE_MAX; type++) {
938 for (op = 0; op < PERF_COUNT_HW_CACHE_OP_MAX; op++) { 1010 for (op = 0; op < PERF_COUNT_HW_CACHE_OP_MAX; op++) {
939 /* skip invalid cache type */ 1011 /* skip invalid cache type */
@@ -941,25 +1013,81 @@ void print_events(void)
941 continue; 1013 continue;
942 1014
943 for (i = 0; i < PERF_COUNT_HW_CACHE_RESULT_MAX; i++) { 1015 for (i = 0; i < PERF_COUNT_HW_CACHE_RESULT_MAX; i++) {
944 printf(" %-42s [%s]\n", 1016 char *name = event_cache_name(type, op, i);
945 event_cache_name(type, op, i), 1017
1018 if (event_glob != NULL && !strglobmatch(name, event_glob))
1019 continue;
1020
1021 printf(" %-50s [%s]\n", name,
946 event_type_descriptors[PERF_TYPE_HW_CACHE]); 1022 event_type_descriptors[PERF_TYPE_HW_CACHE]);
1023 ++printed;
947 } 1024 }
948 } 1025 }
949 } 1026 }
950 1027
1028 return printed;
1029}
1030
1031#define MAX_NAME_LEN 100
1032
1033/*
1034 * Print the help text for the event symbols:
1035 */
1036void print_events(const char *event_glob)
1037{
1038 unsigned int i, type, prev_type = -1, printed = 0, ntypes_printed = 0;
1039 struct event_symbol *syms = event_symbols;
1040 char name[MAX_NAME_LEN];
1041
1042 printf("\n");
1043 printf("List of pre-defined events (to be used in -e):\n");
1044
1045 for (i = 0; i < ARRAY_SIZE(event_symbols); i++, syms++) {
1046 type = syms->type;
1047
1048 if (type != prev_type && printed) {
1049 printf("\n");
1050 printed = 0;
1051 ntypes_printed++;
1052 }
1053
1054 if (event_glob != NULL &&
1055 !(strglobmatch(syms->symbol, event_glob) ||
1056 (syms->alias && strglobmatch(syms->alias, event_glob))))
1057 continue;
1058
1059 if (strlen(syms->alias))
1060 snprintf(name, MAX_NAME_LEN, "%s OR %s", syms->symbol, syms->alias);
1061 else
1062 strncpy(name, syms->symbol, MAX_NAME_LEN);
1063 printf(" %-50s [%s]\n", name,
1064 event_type_descriptors[type]);
1065
1066 prev_type = type;
1067 ++printed;
1068 }
1069
1070 if (ntypes_printed) {
1071 printed = 0;
1072 printf("\n");
1073 }
1074 print_hwcache_events(event_glob);
1075
1076 if (event_glob != NULL)
1077 return;
1078
951 printf("\n"); 1079 printf("\n");
952 printf(" %-42s [%s]\n", 1080 printf(" %-50s [%s]\n",
953 "rNNN (see 'perf list --help' on how to encode it)", 1081 "rNNN (see 'perf list --help' on how to encode it)",
954 event_type_descriptors[PERF_TYPE_RAW]); 1082 event_type_descriptors[PERF_TYPE_RAW]);
955 printf("\n"); 1083 printf("\n");
956 1084
957 printf(" %-42s [%s]\n", 1085 printf(" %-50s [%s]\n",
958 "mem:<addr>[:access]", 1086 "mem:<addr>[:access]",
959 event_type_descriptors[PERF_TYPE_BREAKPOINT]); 1087 event_type_descriptors[PERF_TYPE_BREAKPOINT]);
960 printf("\n"); 1088 printf("\n");
961 1089
962 print_tracepoint_events(); 1090 print_tracepoint_events(NULL, NULL);
963 1091
964 exit(129); 1092 exit(129);
965} 1093}