1 #include <linux/hw_breakpoint.h>
14 #include "parse-events-bison.h"
15 #define YY_EXTRA_TYPE int
16 #include "parse-events-flex.h"
19 #define MAX_NAME_LEN 100
27 extern int parse_events_debug;
33 .symbol =
"cpu-cycles",
37 .symbol =
"instructions",
41 .symbol =
"cache-references",
45 .symbol =
"cache-misses",
49 .symbol =
"branch-instructions",
53 .symbol =
"branch-misses",
57 .symbol =
"bus-cycles",
61 .symbol =
"stalled-cycles-frontend",
62 .alias =
"idle-cycles-frontend",
65 .symbol =
"stalled-cycles-backend",
66 .alias =
"idle-cycles-backend",
69 .symbol =
"ref-cycles",
76 .symbol =
"cpu-clock",
80 .symbol =
"task-clock",
84 .symbol =
"page-faults",
88 .symbol =
"context-switches",
92 .symbol =
"cpu-migrations",
93 .alias =
"migrations",
96 .symbol =
"minor-faults",
100 .symbol =
"major-faults",
104 .symbol =
"alignment-faults",
108 .symbol =
"emulation-faults",
113 #define __PERF_EVENT_FIELD(config, name) \
114 ((config & PERF_EVENT_##name##_MASK) >> PERF_EVENT_##name##_SHIFT)
116 #define PERF_EVENT_RAW(config) __PERF_EVENT_FIELD(config, RAW)
117 #define PERF_EVENT_CONFIG(config) __PERF_EVENT_FIELD(config, CONFIG)
118 #define PERF_EVENT_TYPE(config) __PERF_EVENT_FIELD(config, TYPE)
119 #define PERF_EVENT_ID(config) __PERF_EVENT_FIELD(config, EVENT)
121 #define for_each_subsystem(sys_dir, sys_dirent, sys_next) \
122 while (!readdir_r(sys_dir, &sys_dirent, &sys_next) && sys_next) \
123 if (sys_dirent.d_type == DT_DIR && \
124 (strcmp(sys_dirent.d_name, ".")) && \
125 (strcmp(sys_dirent.d_name, "..")))
127 static int tp_event_has_id(
struct dirent *sys_dir,
struct dirent *evt_dir)
133 sys_dir->d_name, evt_dir->d_name);
142 #define for_each_event(sys_dirent, evt_dir, evt_dirent, evt_next) \
143 while (!readdir_r(evt_dir, &evt_dirent, &evt_next) && evt_next) \
144 if (evt_dirent.d_type == DT_DIR && \
145 (strcmp(evt_dirent.d_name, ".")) && \
146 (strcmp(evt_dirent.d_name, "..")) && \
147 (!tp_event_has_id(&sys_dirent, &evt_dirent)))
149 #define MAX_EVENT_LENGTH 512
155 DIR *sys_dir, *evt_dir;
156 struct dirent *sys_next, *evt_next, sys_dirent, evt_dirent;
174 evt_dir = opendir(dir_path);
185 if (
read(fd, id_buf,
sizeof(id_buf)) < 0) {
194 path =
zalloc(
sizeof(*path));
233 return "hardware-cache";
244 static int __add_event(
struct list_head **_list,
int *
idx,
252 list =
malloc(
sizeof(*list));
255 INIT_LIST_HEAD(list);
268 evsel->
name = strdup(name);
274 static int add_event(
struct list_head **_list,
int *idx,
277 return __add_event(_list, idx, attr, name,
NULL);
285 for (i = 0; i <
size; i++) {
286 for (j = 0; j < PERF_EVSEL__MAX_ALIASES && names[
i][
j]; j++) {
288 if (n > longest && !
strncasecmp(str, names[i][j], n))
299 char *
type,
char *op_result1,
char *op_result2)
304 char *op_result[2] = { op_result1, op_result2 };
313 if (cache_type == -1)
318 for (i = 0; (i < 2) && (op_result[i]); i++) {
319 char *str = op_result[
i];
333 if (cache_result == -1) {
336 if (cache_result >= 0)
350 if (cache_result == -1)
353 memset(&attr, 0,
sizeof(attr));
354 attr.
config = cache_type | (
cache_op << 8) | (cache_result << 16);
356 return add_event(list, idx, &attr, name);
359 static int add_tracepoint(
struct list_head **listp,
int *idx,
360 char *sys_name,
char *evt_name)
366 list =
malloc(
sizeof(*list));
369 INIT_LIST_HEAD(list);
383 static int add_tracepoint_multi(
struct list_head **list,
int *idx,
384 char *sys_name,
char *evt_name)
392 evt_dir = opendir(evt_path);
394 perror(
"Can't open event dir");
398 while (!ret && (evt_ent = readdir(evt_dir))) {
399 if (!
strcmp(evt_ent->d_name,
".")
400 || !
strcmp(evt_ent->d_name,
"..")
401 || !
strcmp(evt_ent->d_name,
"enable")
402 || !
strcmp(evt_ent->d_name,
"filter"))
408 ret = add_tracepoint(list, idx, sys_name, evt_ent->d_name);
424 add_tracepoint_multi(list, idx, sys, event) :
425 add_tracepoint(list, idx, sys, event);
433 for (i = 0; i < 3; i++) {
434 if (!type || !type[i])
437 #define CHECK_SET_TYPE(bit) \
439 if (attr->bp_type & bit) \
442 attr->bp_type |= bit; \
460 #undef CHECK_SET_TYPE
469 void *
ptr,
char *type)
473 memset(&attr, 0,
sizeof(attr));
476 if (parse_breakpoint_type(type, &attr))
491 return add_event(list, idx, &attr,
NULL);
497 #define CHECK_TYPE_VAL(type) \
499 if (PARSE_EVENTS__TERM_TYPE_ ## type != term->type_val) \
534 #undef CHECK_TYPE_VAL
543 if (config_term(attr, term) && fail)
555 memset(&attr, 0,
sizeof(attr));
560 config_attr(&attr, head_config, 1))
563 return add_event(list, idx, &attr,
NULL);
571 static char *pmu_event_name(
struct list_head *head_terms)
576 if (parse_events__is_name_term(term))
592 memset(&attr, 0,
sizeof(attr));
601 config_attr(&attr, head_config, 0);
606 return __add_event(list, idx, &attr, pmu_event_name(head_config),
633 list_splice_tail(list_event, list_all);
650 int eu = evsel ? evsel->
attr.exclude_user : 0;
651 int ek = evsel ? evsel->
attr.exclude_kernel : 0;
652 int eh = evsel ? evsel->
attr.exclude_hv : 0;
653 int eH = evsel ? evsel->
attr.exclude_host : 0;
654 int eG = evsel ? evsel->
attr.exclude_guest : 0;
655 int precise = evsel ? evsel->
attr.precise_ip : 0;
657 int exclude = eu | ek | eh;
658 int exclude_GH = evsel ? evsel->
exclude_GH : 0;
665 if (evsel && !exclude_GH)
668 memset(mod, 0,
sizeof(*mod));
673 exclude = eu = ek = eh = 1;
675 }
else if (*str ==
'k') {
677 exclude = eu = ek = eh = 1;
679 }
else if (*str ==
'h') {
681 exclude = eu = ek = eh = 1;
683 }
else if (*str ==
'G') {
685 exclude_GH = eG = eH = 1;
687 }
else if (*str ==
'H') {
689 exclude_GH = eG = eH = 1;
691 }
else if (*str ==
'p') {
733 if (!add && get_event_modifier(&mod, str,
NULL))
738 if (add && get_event_modifier(&mod, str, evsel))
741 evsel->
attr.exclude_user = mod.
eu;
742 evsel->
attr.exclude_kernel = mod.
ek;
743 evsel->
attr.exclude_hv = mod.
eh;
745 evsel->
attr.exclude_host = mod.
eH;
746 evsel->
attr.exclude_guest = mod.
eG;
759 evsel->
name = strdup(name);
765 static int parse_events__scanner(
const char *str,
void *
data,
int start_token)
771 ret = parse_events_lex_init_extra(start_token, &scanner);
775 buffer = parse_events__scan_string(str, scanner);
778 parse_events_debug = 1;
782 parse_events__flush_buffer(buffer, scanner);
783 parse_events__delete_buffer(buffer, scanner);
784 parse_events_lex_destroy(scanner);
798 ret = parse_events__scanner(str, &data, PE_START_TERMS);
800 list_splice(data.
terms, terms);
818 ret = parse_events__scanner(str, &data, PE_START_EVENTS);
830 fprintf(stderr,
"invalid or unsupported event: '%s'\n", str);
831 fprintf(stderr,
"Run 'perf list' for a list of valid events\n");
849 last = perf_evlist__last(evlist);
853 "-F option should follow a -e tracepoint option\n");
857 last->filter = strdup(str);
859 fprintf(stderr,
"not enough memory to hold filter string\n");
866 static const char *
const event_type_descriptors[] = {
870 "Hardware cache event",
871 "Raw hardware event descriptor",
872 "Hardware breakpoint",
882 DIR *sys_dir, *evt_dir;
883 struct dirent *sys_next, *evt_next, sys_dirent, evt_dirent;
895 if (subsys_glob !=
NULL &&
901 evt_dir = opendir(dir_path);
906 if (event_glob !=
NULL &&
911 printf(
"%s:%s ", sys_dirent.d_name, evt_dirent.d_name);
916 sys_dirent.d_name, evt_dirent.d_name);
917 printf(
" %-50s [%s]\n", evt_path,
931 DIR *sys_dir, *evt_dir;
932 struct dirent *sys_next, *evt_next, sys_dirent, evt_dirent;
947 evt_dir = opendir(dir_path);
953 sys_dirent.d_name, evt_dirent.d_name);
954 if (!
strcmp(evt_path, event_string)) {
966 static void __print_events_type(
u8 type,
struct event_symbol *syms,
972 for (i = 0; i <
max ; i++, syms++) {
974 snprintf(name,
sizeof(name),
"%s OR %s",
979 printf(
" %-50s [%s]\n", name,
980 event_type_descriptors[type]);
994 unsigned int type,
op,
i, printed = 0;
1005 name,
sizeof(name));
1012 printf(
" %-50s [%s]\n", name,
1022 static void print_symbol_events(
const char *event_glob,
unsigned type,
1026 unsigned i, printed = 0;
1029 for (i = 0; i <
max; i++, syms++) {
1031 if (event_glob !=
NULL &&
1046 printf(
" %-50s [%s]\n", name, event_type_descriptors[type]);
1062 printf(
"List of pre-defined events (to be used in -e):\n");
1073 if (event_glob !=
NULL)
1082 "cpu/t1=v1[,t2=v2,t3 ...]/modifier",
1083 event_type_descriptors[PERF_TYPE_RAW]);
1084 printf(
" (see 'perf list --help' on how to encode it)\n");
1088 "mem:<addr>[:access]",
1102 int type_term,
char *
config,
1107 term =
zalloc(
sizeof(*term));
1111 INIT_LIST_HEAD(&term->
list);
1132 int type_term,
char *config,
u64 num)
1139 int type_term,
char *config,
char *str)