aboutsummaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
authorFrederic Weisbecker <fweisbec@gmail.com>2012-08-09 10:31:52 -0400
committerArnaldo Carvalho de Melo <acme@redhat.com>2012-08-09 14:59:26 -0400
commita3277d2d5a0d5d9492993ab68af8a8dc96760dd1 (patch)
treee9c621444e7a31b801b5c57753409bab0a46484e /tools
parent98a4179c9aa1e99adf5103e6e0d05f563d902de1 (diff)
perf tools: Support for events bash completion
Add basic bash completion for the -e option in record, top and stat subcommands. Only hardware, software and tracepoint events are supported. Breakpoints, raw events and events grouping completion need more thinking. Signed-off-by: Frederic Weisbecker <fweisbec@gmail.com> Cc: David Ahern <dsahern@gmail.com> Cc: Ingo Molnar <mingo@kernel.org> Cc: Jiri Olsa <jolsa@redhat.com> Cc: Namhyung Kim <namhyung@gmail.com> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Cc: Stephane Eranian <eranian@google.com> Link: http://lkml.kernel.org/r/1344522713-27951-3-git-send-email-fweisbec@gmail.com Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Diffstat (limited to 'tools')
-rw-r--r--tools/perf/bash_completion6
-rw-r--r--tools/perf/builtin-list.c14
-rw-r--r--tools/perf/util/parse-events.c70
-rw-r--r--tools/perf/util/parse-events.h7
4 files changed, 61 insertions, 36 deletions
diff --git a/tools/perf/bash_completion b/tools/perf/bash_completion
index 9a31fa5ed2a9..1958fa539d0f 100644
--- a/tools/perf/bash_completion
+++ b/tools/perf/bash_completion
@@ -6,7 +6,7 @@ _perf()
6 local cur cmd 6 local cur cmd
7 7
8 COMPREPLY=() 8 COMPREPLY=()
9 _get_comp_words_by_ref cur 9 _get_comp_words_by_ref cur prev
10 10
11 cmd=${COMP_WORDS[0]} 11 cmd=${COMP_WORDS[0]}
12 12
@@ -14,6 +14,10 @@ _perf()
14 if [ $COMP_CWORD -eq 1 ]; then 14 if [ $COMP_CWORD -eq 1 ]; then
15 cmds=$($cmd --list-cmds) 15 cmds=$($cmd --list-cmds)
16 COMPREPLY=( $( compgen -W '$cmds' -- "$cur" ) ) 16 COMPREPLY=( $( compgen -W '$cmds' -- "$cur" ) )
17 # List possible events for -e option
18 elif [[ $prev == "-e" && "${COMP_WORDS[1]}" == @(record|stat|top) ]]; then
19 cmds=$($cmd list --raw-dump)
20 COMPREPLY=( $( compgen -W '$cmds' -- "$cur" ) )
17 # Fall down to list regular files 21 # Fall down to list regular files
18 else 22 else
19 _filedir 23 _filedir
diff --git a/tools/perf/builtin-list.c b/tools/perf/builtin-list.c
index 6313b6eb3ebb..bdcff81b532a 100644
--- a/tools/perf/builtin-list.c
+++ b/tools/perf/builtin-list.c
@@ -19,15 +19,15 @@ int cmd_list(int argc, const char **argv, const char *prefix __used)
19 setup_pager(); 19 setup_pager();
20 20
21 if (argc == 1) 21 if (argc == 1)
22 print_events(NULL); 22 print_events(NULL, false);
23 else { 23 else {
24 int i; 24 int i;
25 25
26 for (i = 1; i < argc; ++i) { 26 for (i = 1; i < argc; ++i) {
27 if (i > 1) 27 if (i > 2)
28 putchar('\n'); 28 putchar('\n');
29 if (strncmp(argv[i], "tracepoint", 10) == 0) 29 if (strncmp(argv[i], "tracepoint", 10) == 0)
30 print_tracepoint_events(NULL, NULL); 30 print_tracepoint_events(NULL, NULL, false);
31 else if (strcmp(argv[i], "hw") == 0 || 31 else if (strcmp(argv[i], "hw") == 0 ||
32 strcmp(argv[i], "hardware") == 0) 32 strcmp(argv[i], "hardware") == 0)
33 print_events_type(PERF_TYPE_HARDWARE); 33 print_events_type(PERF_TYPE_HARDWARE);
@@ -36,13 +36,15 @@ int cmd_list(int argc, const char **argv, const char *prefix __used)
36 print_events_type(PERF_TYPE_SOFTWARE); 36 print_events_type(PERF_TYPE_SOFTWARE);
37 else if (strcmp(argv[i], "cache") == 0 || 37 else if (strcmp(argv[i], "cache") == 0 ||
38 strcmp(argv[i], "hwcache") == 0) 38 strcmp(argv[i], "hwcache") == 0)
39 print_hwcache_events(NULL); 39 print_hwcache_events(NULL, false);
40 else if (strcmp(argv[i], "--raw-dump") == 0)
41 print_events(NULL, true);
40 else { 42 else {
41 char *sep = strchr(argv[i], ':'), *s; 43 char *sep = strchr(argv[i], ':'), *s;
42 int sep_idx; 44 int sep_idx;
43 45
44 if (sep == NULL) { 46 if (sep == NULL) {
45 print_events(argv[i]); 47 print_events(argv[i], false);
46 continue; 48 continue;
47 } 49 }
48 sep_idx = sep - argv[i]; 50 sep_idx = sep - argv[i];
@@ -51,7 +53,7 @@ int cmd_list(int argc, const char **argv, const char *prefix __used)
51 return -1; 53 return -1;
52 54
53 s[sep_idx] = '\0'; 55 s[sep_idx] = '\0';
54 print_tracepoint_events(s, s + sep_idx + 1); 56 print_tracepoint_events(s, s + sep_idx + 1, false);
55 free(s); 57 free(s);
56 } 58 }
57 } 59 }
diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c
index 8bdfa3e5c8c7..3ec4bfcd3f9c 100644
--- a/tools/perf/util/parse-events.c
+++ b/tools/perf/util/parse-events.c
@@ -799,7 +799,8 @@ static const char * const event_type_descriptors[] = {
799 * Print the events from <debugfs_mount_point>/tracing/events 799 * Print the events from <debugfs_mount_point>/tracing/events
800 */ 800 */
801 801
802void print_tracepoint_events(const char *subsys_glob, const char *event_glob) 802void print_tracepoint_events(const char *subsys_glob, const char *event_glob,
803 bool name_only)
803{ 804{
804 DIR *sys_dir, *evt_dir; 805 DIR *sys_dir, *evt_dir;
805 struct dirent *sys_next, *evt_next, sys_dirent, evt_dirent; 806 struct dirent *sys_next, *evt_next, sys_dirent, evt_dirent;
@@ -829,6 +830,11 @@ void print_tracepoint_events(const char *subsys_glob, const char *event_glob)
829 !strglobmatch(evt_dirent.d_name, event_glob)) 830 !strglobmatch(evt_dirent.d_name, event_glob))
830 continue; 831 continue;
831 832
833 if (name_only) {
834 printf("%s:%s ", sys_dirent.d_name, evt_dirent.d_name);
835 continue;
836 }
837
832 snprintf(evt_path, MAXPATHLEN, "%s:%s", 838 snprintf(evt_path, MAXPATHLEN, "%s:%s",
833 sys_dirent.d_name, evt_dirent.d_name); 839 sys_dirent.d_name, evt_dirent.d_name);
834 printf(" %-50s [%s]\n", evt_path, 840 printf(" %-50s [%s]\n", evt_path,
@@ -906,7 +912,7 @@ void print_events_type(u8 type)
906 __print_events_type(type, event_symbols_hw, PERF_COUNT_HW_MAX); 912 __print_events_type(type, event_symbols_hw, PERF_COUNT_HW_MAX);
907} 913}
908 914
909int print_hwcache_events(const char *event_glob) 915int print_hwcache_events(const char *event_glob, bool name_only)
910{ 916{
911 unsigned int type, op, i, printed = 0; 917 unsigned int type, op, i, printed = 0;
912 char name[64]; 918 char name[64];
@@ -923,8 +929,11 @@ int print_hwcache_events(const char *event_glob)
923 if (event_glob != NULL && !strglobmatch(name, event_glob)) 929 if (event_glob != NULL && !strglobmatch(name, event_glob))
924 continue; 930 continue;
925 931
926 printf(" %-50s [%s]\n", name, 932 if (name_only)
927 event_type_descriptors[PERF_TYPE_HW_CACHE]); 933 printf("%s ", name);
934 else
935 printf(" %-50s [%s]\n", name,
936 event_type_descriptors[PERF_TYPE_HW_CACHE]);
928 ++printed; 937 ++printed;
929 } 938 }
930 } 939 }
@@ -934,7 +943,8 @@ int print_hwcache_events(const char *event_glob)
934} 943}
935 944
936static void print_symbol_events(const char *event_glob, unsigned type, 945static void print_symbol_events(const char *event_glob, unsigned type,
937 struct event_symbol *syms, unsigned max) 946 struct event_symbol *syms, unsigned max,
947 bool name_only)
938{ 948{
939 unsigned i, printed = 0; 949 unsigned i, printed = 0;
940 char name[MAX_NAME_LEN]; 950 char name[MAX_NAME_LEN];
@@ -946,6 +956,11 @@ static void print_symbol_events(const char *event_glob, unsigned type,
946 (syms->alias && strglobmatch(syms->alias, event_glob)))) 956 (syms->alias && strglobmatch(syms->alias, event_glob))))
947 continue; 957 continue;
948 958
959 if (name_only) {
960 printf("%s ", syms->symbol);
961 continue;
962 }
963
949 if (strlen(syms->alias)) 964 if (strlen(syms->alias))
950 snprintf(name, MAX_NAME_LEN, "%s OR %s", syms->symbol, syms->alias); 965 snprintf(name, MAX_NAME_LEN, "%s OR %s", syms->symbol, syms->alias);
951 else 966 else
@@ -963,39 +978,42 @@ static void print_symbol_events(const char *event_glob, unsigned type,
963/* 978/*
964 * Print the help text for the event symbols: 979 * Print the help text for the event symbols:
965 */ 980 */
966void print_events(const char *event_glob) 981void print_events(const char *event_glob, bool name_only)
967{ 982{
968 983 if (!name_only) {
969 printf("\n"); 984 printf("\n");
970 printf("List of pre-defined events (to be used in -e):\n"); 985 printf("List of pre-defined events (to be used in -e):\n");
986 }
971 987
972 print_symbol_events(event_glob, PERF_TYPE_HARDWARE, 988 print_symbol_events(event_glob, PERF_TYPE_HARDWARE,
973 event_symbols_hw, PERF_COUNT_HW_MAX); 989 event_symbols_hw, PERF_COUNT_HW_MAX, name_only);
974 990
975 print_symbol_events(event_glob, PERF_TYPE_SOFTWARE, 991 print_symbol_events(event_glob, PERF_TYPE_SOFTWARE,
976 event_symbols_sw, PERF_COUNT_SW_MAX); 992 event_symbols_sw, PERF_COUNT_SW_MAX, name_only);
977 993
978 print_hwcache_events(event_glob); 994 print_hwcache_events(event_glob, name_only);
979 995
980 if (event_glob != NULL) 996 if (event_glob != NULL)
981 return; 997 return;
982 998
983 printf("\n"); 999 if (!name_only) {
984 printf(" %-50s [%s]\n", 1000 printf("\n");
985 "rNNN", 1001 printf(" %-50s [%s]\n",
986 event_type_descriptors[PERF_TYPE_RAW]); 1002 "rNNN",
987 printf(" %-50s [%s]\n", 1003 event_type_descriptors[PERF_TYPE_RAW]);
988 "cpu/t1=v1[,t2=v2,t3 ...]/modifier", 1004 printf(" %-50s [%s]\n",
989 event_type_descriptors[PERF_TYPE_RAW]); 1005 "cpu/t1=v1[,t2=v2,t3 ...]/modifier",
990 printf(" (see 'perf list --help' on how to encode it)\n"); 1006 event_type_descriptors[PERF_TYPE_RAW]);
991 printf("\n"); 1007 printf(" (see 'perf list --help' on how to encode it)\n");
992 1008 printf("\n");
993 printf(" %-50s [%s]\n", 1009
994 "mem:<addr>[:access]", 1010 printf(" %-50s [%s]\n",
1011 "mem:<addr>[:access]",
995 event_type_descriptors[PERF_TYPE_BREAKPOINT]); 1012 event_type_descriptors[PERF_TYPE_BREAKPOINT]);
996 printf("\n"); 1013 printf("\n");
1014 }
997 1015
998 print_tracepoint_events(NULL, NULL); 1016 print_tracepoint_events(NULL, NULL, name_only);
999} 1017}
1000 1018
1001int parse_events__is_hardcoded_term(struct parse_events__term *term) 1019int parse_events__is_hardcoded_term(struct parse_events__term *term)
diff --git a/tools/perf/util/parse-events.h b/tools/perf/util/parse-events.h
index 163aad404619..00416d7fd012 100644
--- a/tools/perf/util/parse-events.h
+++ b/tools/perf/util/parse-events.h
@@ -96,10 +96,11 @@ void parse_events_update_lists(struct list_head *list_event,
96void parse_events_error(void *data, void *scanner, char const *msg); 96void parse_events_error(void *data, void *scanner, char const *msg);
97int parse_events__test(void); 97int parse_events__test(void);
98 98
99void print_events(const char *event_glob); 99void print_events(const char *event_glob, bool name_only);
100void print_events_type(u8 type); 100void print_events_type(u8 type);
101void print_tracepoint_events(const char *subsys_glob, const char *event_glob); 101void print_tracepoint_events(const char *subsys_glob, const char *event_glob,
102int print_hwcache_events(const char *event_glob); 102 bool name_only);
103int print_hwcache_events(const char *event_glob, bool name_only);
103extern int is_valid_tracepoint(const char *event_string); 104extern int is_valid_tracepoint(const char *event_string);
104 105
105extern int valid_debugfs_mount(const char *debugfs); 106extern int valid_debugfs_mount(const char *debugfs);