diff options
author | Arnaldo Carvalho de Melo <acme@redhat.com> | 2011-02-17 12:38:58 -0500 |
---|---|---|
committer | Arnaldo Carvalho de Melo <acme@redhat.com> | 2011-02-17 12:38:58 -0500 |
commit | 668b8788f497b2386402daeca583d6300240d41d (patch) | |
tree | 7e931ce5240c6a13b29510a854f90f07dc4629c5 /tools | |
parent | 74cfc17dc1a69c37ce6c8a76c1ce84bcb796eb0e (diff) |
perf list: Allow filtering list of events
The man page has the details, here are some examples:
[root@emilia ~]# perf list *fault* *:*wait*
List of pre-defined events (to be used in -e):
page-faults OR faults [Software event]
minor-faults [Software event]
major-faults [Software event]
alignment-faults [Software event]
emulation-faults [Software event]
radeon:radeon_fence_wait_begin [Tracepoint event]
radeon:radeon_fence_wait_end [Tracepoint event]
writeback:wbc_writeback_wait [Tracepoint event]
writeback:wbc_balance_dirty_wait [Tracepoint event]
writeback:writeback_congestion_wait [Tracepoint event]
writeback:writeback_wait_iff_congested [Tracepoint event]
sched:sched_wait_task [Tracepoint event]
sched:sched_process_wait [Tracepoint event]
sched:sched_stat_wait [Tracepoint event]
sched:sched_stat_iowait [Tracepoint event]
syscalls:sys_enter_epoll_wait [Tracepoint event]
syscalls:sys_exit_epoll_wait [Tracepoint event]
syscalls:sys_enter_epoll_pwait [Tracepoint event]
syscalls:sys_exit_epoll_pwait [Tracepoint event]
syscalls:sys_enter_rt_sigtimedwait [Tracepoint event]
syscalls:sys_exit_rt_sigtimedwait [Tracepoint event]
syscalls:sys_enter_waitid [Tracepoint event]
syscalls:sys_exit_waitid [Tracepoint event]
syscalls:sys_enter_wait4 [Tracepoint event]
syscalls:sys_exit_wait4 [Tracepoint event]
syscalls:sys_enter_waitpid [Tracepoint event]
syscalls:sys_exit_waitpid [Tracepoint event]
[root@emilia ~]#
Suggested-by: Ingo Molnar <mingo@elte.hu>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Cc: Tom Zanussi <tzanussi@gmail.com>
LKML-Reference: <new-submission>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Diffstat (limited to 'tools')
-rw-r--r-- | tools/perf/Documentation/perf-list.txt | 23 | ||||
-rw-r--r-- | tools/perf/builtin-list.c | 43 | ||||
-rw-r--r-- | tools/perf/util/parse-events.c | 94 | ||||
-rw-r--r-- | tools/perf/util/parse-events.h | 5 |
4 files changed, 142 insertions, 23 deletions
diff --git a/tools/perf/Documentation/perf-list.txt b/tools/perf/Documentation/perf-list.txt index 399751befeed..7a527f7e9da9 100644 --- a/tools/perf/Documentation/perf-list.txt +++ b/tools/perf/Documentation/perf-list.txt | |||
@@ -8,7 +8,7 @@ perf-list - List all symbolic event types | |||
8 | SYNOPSIS | 8 | SYNOPSIS |
9 | -------- | 9 | -------- |
10 | [verse] | 10 | [verse] |
11 | 'perf list' | 11 | 'perf list' [hw|sw|cache|tracepoint|event_glob] |
12 | 12 | ||
13 | DESCRIPTION | 13 | DESCRIPTION |
14 | ----------- | 14 | ----------- |
@@ -63,7 +63,26 @@ details. Some of them are referenced in the SEE ALSO section below. | |||
63 | 63 | ||
64 | OPTIONS | 64 | OPTIONS |
65 | ------- | 65 | ------- |
66 | None | 66 | |
67 | Without options all known events will be listed. | ||
68 | |||
69 | To limit the list use: | ||
70 | |||
71 | . 'hw' or 'hardware' to list hardware events such as cache-misses, etc. | ||
72 | |||
73 | . 'sw' or 'software' to list software events such as context switches, etc. | ||
74 | |||
75 | . 'cache' or 'hwcache' to list hardware cache events such as L1-dcache-loads, etc. | ||
76 | |||
77 | . 'tracepoint' to list all tracepoint events, alternatively use | ||
78 | 'subsys_glob:event_glob' to filter by tracepoint subsystems such as sched, | ||
79 | block, etc. | ||
80 | |||
81 | . If none of the above is matched, it will apply the supplied glob to all | ||
82 | events, printing the ones that match. | ||
83 | |||
84 | One or more types can be used at the same time, listing the events for the | ||
85 | types specified. | ||
67 | 86 | ||
68 | SEE ALSO | 87 | SEE ALSO |
69 | -------- | 88 | -------- |
diff --git a/tools/perf/builtin-list.c b/tools/perf/builtin-list.c index d88c6961274c..6313b6eb3ebb 100644 --- a/tools/perf/builtin-list.c +++ b/tools/perf/builtin-list.c | |||
@@ -5,6 +5,7 @@ | |||
5 | * | 5 | * |
6 | * Copyright (C) 2009, Thomas Gleixner <tglx@linutronix.de> | 6 | * Copyright (C) 2009, Thomas Gleixner <tglx@linutronix.de> |
7 | * Copyright (C) 2008-2009, Red Hat Inc, Ingo Molnar <mingo@redhat.com> | 7 | * Copyright (C) 2008-2009, Red Hat Inc, Ingo Molnar <mingo@redhat.com> |
8 | * Copyright (C) 2011, Red Hat Inc, Arnaldo Carvalho de Melo <acme@redhat.com> | ||
8 | */ | 9 | */ |
9 | #include "builtin.h" | 10 | #include "builtin.h" |
10 | 11 | ||
@@ -13,9 +14,47 @@ | |||
13 | #include "util/parse-events.h" | 14 | #include "util/parse-events.h" |
14 | #include "util/cache.h" | 15 | #include "util/cache.h" |
15 | 16 | ||
16 | int cmd_list(int argc __used, const char **argv __used, const char *prefix __used) | 17 | int cmd_list(int argc, const char **argv, const char *prefix __used) |
17 | { | 18 | { |
18 | setup_pager(); | 19 | setup_pager(); |
19 | print_events(); | 20 | |
21 | if (argc == 1) | ||
22 | print_events(NULL); | ||
23 | else { | ||
24 | int i; | ||
25 | |||
26 | for (i = 1; i < argc; ++i) { | ||
27 | if (i > 1) | ||
28 | putchar('\n'); | ||
29 | if (strncmp(argv[i], "tracepoint", 10) == 0) | ||
30 | print_tracepoint_events(NULL, NULL); | ||
31 | else if (strcmp(argv[i], "hw") == 0 || | ||
32 | strcmp(argv[i], "hardware") == 0) | ||
33 | print_events_type(PERF_TYPE_HARDWARE); | ||
34 | else if (strcmp(argv[i], "sw") == 0 || | ||
35 | strcmp(argv[i], "software") == 0) | ||
36 | print_events_type(PERF_TYPE_SOFTWARE); | ||
37 | else if (strcmp(argv[i], "cache") == 0 || | ||
38 | strcmp(argv[i], "hwcache") == 0) | ||
39 | print_hwcache_events(NULL); | ||
40 | else { | ||
41 | char *sep = strchr(argv[i], ':'), *s; | ||
42 | int sep_idx; | ||
43 | |||
44 | if (sep == NULL) { | ||
45 | print_events(argv[i]); | ||
46 | continue; | ||
47 | } | ||
48 | sep_idx = sep - argv[i]; | ||
49 | s = strdup(argv[i]); | ||
50 | if (s == NULL) | ||
51 | return -1; | ||
52 | |||
53 | s[sep_idx] = '\0'; | ||
54 | print_tracepoint_events(s, s + sep_idx + 1); | ||
55 | free(s); | ||
56 | } | ||
57 | } | ||
58 | } | ||
20 | return 0; | 59 | return 0; |
21 | } | 60 | } |
diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c index 80a3dd5ef573..54a7e2634d58 100644 --- a/tools/perf/util/parse-events.c +++ b/tools/perf/util/parse-events.c | |||
@@ -858,7 +858,7 @@ static const char * const event_type_descriptors[] = { | |||
858 | * Print the events from <debugfs_mount_point>/tracing/events | 858 | * Print the events from <debugfs_mount_point>/tracing/events |
859 | */ | 859 | */ |
860 | 860 | ||
861 | static void print_tracepoint_events(void) | 861 | void print_tracepoint_events(const char *subsys_glob, const char *event_glob) |
862 | { | 862 | { |
863 | DIR *sys_dir, *evt_dir; | 863 | DIR *sys_dir, *evt_dir; |
864 | struct dirent *sys_next, *evt_next, sys_dirent, evt_dirent; | 864 | struct dirent *sys_next, *evt_next, sys_dirent, evt_dirent; |
@@ -873,6 +873,9 @@ static void print_tracepoint_events(void) | |||
873 | return; | 873 | return; |
874 | 874 | ||
875 | for_each_subsystem(sys_dir, sys_dirent, sys_next) { | 875 | for_each_subsystem(sys_dir, sys_dirent, sys_next) { |
876 | if (subsys_glob != NULL && | ||
877 | !strglobmatch(sys_dirent.d_name, subsys_glob)) | ||
878 | continue; | ||
876 | 879 | ||
877 | snprintf(dir_path, MAXPATHLEN, "%s/%s", debugfs_path, | 880 | snprintf(dir_path, MAXPATHLEN, "%s/%s", debugfs_path, |
878 | sys_dirent.d_name); | 881 | sys_dirent.d_name); |
@@ -881,6 +884,10 @@ static void print_tracepoint_events(void) | |||
881 | continue; | 884 | continue; |
882 | 885 | ||
883 | for_each_event(sys_dirent, evt_dir, evt_dirent, evt_next) { | 886 | for_each_event(sys_dirent, evt_dir, evt_dirent, evt_next) { |
887 | if (event_glob != NULL && | ||
888 | !strglobmatch(evt_dirent.d_name, event_glob)) | ||
889 | continue; | ||
890 | |||
884 | snprintf(evt_path, MAXPATHLEN, "%s:%s", | 891 | snprintf(evt_path, MAXPATHLEN, "%s:%s", |
885 | sys_dirent.d_name, evt_dirent.d_name); | 892 | sys_dirent.d_name, evt_dirent.d_name); |
886 | printf(" %-42s [%s]\n", evt_path, | 893 | printf(" %-42s [%s]\n", evt_path, |
@@ -932,13 +939,61 @@ int is_valid_tracepoint(const char *event_string) | |||
932 | return 0; | 939 | return 0; |
933 | } | 940 | } |
934 | 941 | ||
942 | void print_events_type(u8 type) | ||
943 | { | ||
944 | struct event_symbol *syms = event_symbols; | ||
945 | unsigned int i; | ||
946 | char name[64]; | ||
947 | |||
948 | for (i = 0; i < ARRAY_SIZE(event_symbols); i++, syms++) { | ||
949 | if (type != syms->type) | ||
950 | continue; | ||
951 | |||
952 | if (strlen(syms->alias)) | ||
953 | snprintf(name, sizeof(name), "%s OR %s", | ||
954 | syms->symbol, syms->alias); | ||
955 | else | ||
956 | snprintf(name, sizeof(name), "%s", syms->symbol); | ||
957 | |||
958 | printf(" %-42s [%s]\n", name, | ||
959 | event_type_descriptors[type]); | ||
960 | } | ||
961 | } | ||
962 | |||
963 | int print_hwcache_events(const char *event_glob) | ||
964 | { | ||
965 | unsigned int type, op, i, printed = 0; | ||
966 | |||
967 | for (type = 0; type < PERF_COUNT_HW_CACHE_MAX; type++) { | ||
968 | for (op = 0; op < PERF_COUNT_HW_CACHE_OP_MAX; op++) { | ||
969 | /* skip invalid cache type */ | ||
970 | if (!is_cache_op_valid(type, op)) | ||
971 | continue; | ||
972 | |||
973 | for (i = 0; i < PERF_COUNT_HW_CACHE_RESULT_MAX; i++) { | ||
974 | char *name = event_cache_name(type, op, i); | ||
975 | |||
976 | if (event_glob != NULL && | ||
977 | !strglobmatch(name, event_glob)) | ||
978 | continue; | ||
979 | |||
980 | printf(" %-42s [%s]\n", name, | ||
981 | event_type_descriptors[PERF_TYPE_HW_CACHE]); | ||
982 | ++printed; | ||
983 | } | ||
984 | } | ||
985 | } | ||
986 | |||
987 | return printed; | ||
988 | } | ||
989 | |||
935 | /* | 990 | /* |
936 | * Print the help text for the event symbols: | 991 | * Print the help text for the event symbols: |
937 | */ | 992 | */ |
938 | void print_events(void) | 993 | void print_events(const char *event_glob) |
939 | { | 994 | { |
940 | struct event_symbol *syms = event_symbols; | 995 | struct event_symbol *syms = event_symbols; |
941 | unsigned int i, type, op, prev_type = -1; | 996 | unsigned int i, type, prev_type = -1, printed = 0, ntypes_printed = 0; |
942 | char name[40]; | 997 | char name[40]; |
943 | 998 | ||
944 | printf("\n"); | 999 | printf("\n"); |
@@ -947,8 +1002,16 @@ void print_events(void) | |||
947 | for (i = 0; i < ARRAY_SIZE(event_symbols); i++, syms++) { | 1002 | for (i = 0; i < ARRAY_SIZE(event_symbols); i++, syms++) { |
948 | type = syms->type; | 1003 | type = syms->type; |
949 | 1004 | ||
950 | if (type != prev_type) | 1005 | if (type != prev_type && printed) { |
951 | printf("\n"); | 1006 | printf("\n"); |
1007 | printed = 0; | ||
1008 | ntypes_printed++; | ||
1009 | } | ||
1010 | |||
1011 | if (event_glob != NULL && | ||
1012 | !(strglobmatch(syms->symbol, event_glob) || | ||
1013 | (syms->alias && strglobmatch(syms->alias, event_glob)))) | ||
1014 | continue; | ||
952 | 1015 | ||
953 | if (strlen(syms->alias)) | 1016 | if (strlen(syms->alias)) |
954 | sprintf(name, "%s OR %s", syms->symbol, syms->alias); | 1017 | sprintf(name, "%s OR %s", syms->symbol, syms->alias); |
@@ -958,22 +1021,17 @@ void print_events(void) | |||
958 | event_type_descriptors[type]); | 1021 | event_type_descriptors[type]); |
959 | 1022 | ||
960 | prev_type = type; | 1023 | prev_type = type; |
1024 | ++printed; | ||
961 | } | 1025 | } |
962 | 1026 | ||
963 | printf("\n"); | 1027 | if (ntypes_printed) { |
964 | for (type = 0; type < PERF_COUNT_HW_CACHE_MAX; type++) { | 1028 | printed = 0; |
965 | for (op = 0; op < PERF_COUNT_HW_CACHE_OP_MAX; op++) { | 1029 | printf("\n"); |
966 | /* skip invalid cache type */ | ||
967 | if (!is_cache_op_valid(type, op)) | ||
968 | continue; | ||
969 | |||
970 | for (i = 0; i < PERF_COUNT_HW_CACHE_RESULT_MAX; i++) { | ||
971 | printf(" %-42s [%s]\n", | ||
972 | event_cache_name(type, op, i), | ||
973 | event_type_descriptors[PERF_TYPE_HW_CACHE]); | ||
974 | } | ||
975 | } | ||
976 | } | 1030 | } |
1031 | print_hwcache_events(event_glob); | ||
1032 | |||
1033 | if (event_glob != NULL) | ||
1034 | return; | ||
977 | 1035 | ||
978 | printf("\n"); | 1036 | printf("\n"); |
979 | printf(" %-42s [%s]\n", | 1037 | printf(" %-42s [%s]\n", |
@@ -986,7 +1044,7 @@ void print_events(void) | |||
986 | event_type_descriptors[PERF_TYPE_BREAKPOINT]); | 1044 | event_type_descriptors[PERF_TYPE_BREAKPOINT]); |
987 | printf("\n"); | 1045 | printf("\n"); |
988 | 1046 | ||
989 | print_tracepoint_events(); | 1047 | print_tracepoint_events(NULL, NULL); |
990 | 1048 | ||
991 | exit(129); | 1049 | exit(129); |
992 | } | 1050 | } |
diff --git a/tools/perf/util/parse-events.h b/tools/perf/util/parse-events.h index cf7e94abb676..212f88e07a9c 100644 --- a/tools/perf/util/parse-events.h +++ b/tools/perf/util/parse-events.h | |||
@@ -28,7 +28,10 @@ extern int parse_filter(const struct option *opt, const char *str, int unset); | |||
28 | 28 | ||
29 | #define EVENTS_HELP_MAX (128*1024) | 29 | #define EVENTS_HELP_MAX (128*1024) |
30 | 30 | ||
31 | extern void print_events(void); | 31 | void print_events(const char *event_glob); |
32 | void print_events_type(u8 type); | ||
33 | void print_tracepoint_events(const char *subsys_glob, const char *event_glob); | ||
34 | int print_hwcache_events(const char *event_glob); | ||
32 | extern int is_valid_tracepoint(const char *event_string); | 35 | extern int is_valid_tracepoint(const char *event_string); |
33 | 36 | ||
34 | extern char debugfs_path[]; | 37 | extern char debugfs_path[]; |