2 #include <linux/hw_breakpoint.h> 10 #include <sys/param.h> 15 #include <subcmd/parse-options.h> 17 #include <subcmd/exec-cmd.h> 25 #include <api/fs/tracing_path.h> 27 #define YY_EXTRA_TYPE int 37 #define MAX_NAME_LEN 100 40 extern int parse_events_debug;
44 struct list_head *head_terms __maybe_unused);
56 [PERF_COUNT_HW_CPU_CYCLES] = {
60 [PERF_COUNT_HW_INSTRUCTIONS] = {
61 .symbol =
"instructions",
64 [PERF_COUNT_HW_CACHE_REFERENCES] = {
65 .symbol =
"cache-references",
68 [PERF_COUNT_HW_CACHE_MISSES] = {
69 .symbol =
"cache-misses",
72 [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = {
73 .symbol =
"branch-instructions",
76 [PERF_COUNT_HW_BRANCH_MISSES] = {
77 .symbol =
"branch-misses",
80 [PERF_COUNT_HW_BUS_CYCLES] = {
81 .symbol =
"bus-cycles",
84 [PERF_COUNT_HW_STALLED_CYCLES_FRONTEND] = {
85 .symbol =
"stalled-cycles-frontend",
86 .alias =
"idle-cycles-frontend",
88 [PERF_COUNT_HW_STALLED_CYCLES_BACKEND] = {
89 .symbol =
"stalled-cycles-backend",
90 .alias =
"idle-cycles-backend",
92 [PERF_COUNT_HW_REF_CPU_CYCLES] = {
93 .symbol =
"ref-cycles",
99 [PERF_COUNT_SW_CPU_CLOCK] = {
103 [PERF_COUNT_SW_TASK_CLOCK] = {
104 .symbol =
"task-clock",
107 [PERF_COUNT_SW_PAGE_FAULTS] = {
108 .symbol =
"page-faults",
111 [PERF_COUNT_SW_CONTEXT_SWITCHES] = {
112 .symbol =
"context-switches",
115 [PERF_COUNT_SW_CPU_MIGRATIONS] = {
116 .symbol =
"cpu-migrations",
117 .alias =
"migrations",
119 [PERF_COUNT_SW_PAGE_FAULTS_MIN] = {
120 .symbol =
"minor-faults",
123 [PERF_COUNT_SW_PAGE_FAULTS_MAJ] = {
124 .symbol =
"major-faults",
127 [PERF_COUNT_SW_ALIGNMENT_FAULTS] = {
128 .symbol =
"alignment-faults",
131 [PERF_COUNT_SW_EMULATION_FAULTS] = {
132 .symbol =
"emulation-faults",
135 [PERF_COUNT_SW_DUMMY] = {
139 [PERF_COUNT_SW_BPF_OUTPUT] = {
140 .symbol =
"bpf-output",
145 #define __PERF_EVENT_FIELD(config, name) \ 146 ((config & PERF_EVENT_##name##_MASK) >> PERF_EVENT_##name##_SHIFT) 148 #define PERF_EVENT_RAW(config) __PERF_EVENT_FIELD(config, RAW) 149 #define PERF_EVENT_CONFIG(config) __PERF_EVENT_FIELD(config, CONFIG) 150 #define PERF_EVENT_TYPE(config) __PERF_EVENT_FIELD(config, TYPE) 151 #define PERF_EVENT_ID(config) __PERF_EVENT_FIELD(config, EVENT) 153 #define for_each_subsystem(sys_dir, sys_dirent) \ 154 while ((sys_dirent = readdir(sys_dir)) != NULL) \ 155 if (sys_dirent->d_type == DT_DIR && \ 156 (strcmp(sys_dirent->d_name, ".")) && \ 157 (strcmp(sys_dirent->d_name, ".."))) 161 char evt_path[MAXPATHLEN];
164 snprintf(evt_path, MAXPATHLEN,
"%s/%s/id", dir_path, evt_dir->d_name);
165 fd = open(evt_path, O_RDONLY);
173 #define for_each_event(dir_path, evt_dir, evt_dirent) \ 174 while ((evt_dirent = readdir(evt_dir)) != NULL) \ 175 if (evt_dirent->d_type == DT_DIR && \ 176 (strcmp(evt_dirent->d_name, ".")) && \ 177 (strcmp(evt_dirent->d_name, "..")) && \ 178 (!tp_event_has_id(dir_path, evt_dirent))) 180 #define MAX_EVENT_LENGTH 512 186 DIR *sys_dir, *evt_dir;
187 struct dirent *sys_dirent, *evt_dirent;
191 char evt_path[MAXPATHLEN];
194 sys_dir = tracing_events__opendir();
199 dir_path = get_events_file(sys_dirent->d_name);
202 evt_dir = opendir(dir_path);
208 scnprintf(evt_path, MAXPATHLEN,
"%s/%s/id", dir_path,
210 fd = open(evt_path, O_RDONLY);
213 if (read(fd, id_buf,
sizeof(id_buf)) < 0) {
220 put_events_file(dir_path);
223 path =
zalloc(
sizeof(*path));
237 strncpy(path->
system, sys_dirent->d_name,
239 strncpy(path->
name, evt_dirent->d_name,
246 put_events_file(dir_path);
256 char *
str = strchr(name,
':');
258 if (path == NULL || str == NULL) {
263 path->
system = strndup(name, str - name);
264 path->
name = strdup(str+1);
266 if (path->
system == NULL || path->
name == NULL) {
278 case PERF_TYPE_HARDWARE:
281 case PERF_TYPE_SOFTWARE:
284 case PERF_TYPE_TRACEPOINT:
287 case PERF_TYPE_HW_CACHE:
288 return "hardware-cache";
309 list_for_each_entry(term, head_terms,
list)
318 struct perf_event_attr *
attr,
338 evsel->
name = strdup(name);
343 list_add_tail(&evsel->
node, list);
348 struct perf_event_attr *
attr,
char *
name,
349 struct list_head *config_terms)
351 return __add_event(list, idx, attr, name, NULL, config_terms,
false) ? 0 : -ENOMEM;
359 for (i = 0; i <
size; i++) {
360 for (j = 0; j < PERF_EVSEL__MAX_ALIASES && names[i][j]; j++) {
361 n = strlen(names[i][j]);
362 if (n > longest && !strncasecmp(str, names[i][j], n))
379 struct list_head *head,
384 char *type,
char *op_result1,
char *op_result2,
386 struct list_head *head_config)
388 struct perf_event_attr attr;
391 int cache_type = -1, cache_op = -1, cache_result = -1;
392 char *op_result[2] = { op_result1, op_result2 };
400 PERF_COUNT_HW_CACHE_MAX);
401 if (cache_type == -1)
407 for (i = 0; (i < 2) && (op_result[i]); i++) {
408 char *
str = op_result[i];
412 if (cache_op == -1) {
414 PERF_COUNT_HW_CACHE_OP_MAX);
422 if (cache_result == -1) {
424 PERF_COUNT_HW_CACHE_RESULT_MAX);
425 if (cache_result >= 0)
434 cache_op = PERF_COUNT_HW_CACHE_OP_READ;
439 if (cache_result == -1)
440 cache_result = PERF_COUNT_HW_CACHE_RESULT_ACCESS;
442 memset(&attr, 0,
sizeof(attr));
443 attr.config = cache_type | (cache_op << 8) | (cache_result << 16);
444 attr.type = PERF_TYPE_HW_CACHE;
454 return add_event(list, idx, &attr, config_name ? : name, &config_terms);
458 const char *sys,
const char *
name)
473 e->
str = strdup(
"can't access trace events");
476 e->
str = strdup(
"unknown tracepoint");
479 e->
str = strdup(
"failed to add tracepoint");
483 tracing_path__strerror_open_tp(err, help,
sizeof(help), sys, name);
484 e->
help = strdup(help);
488 const char *sys_name,
const char *evt_name,
490 struct list_head *head_config)
497 return PTR_ERR(evsel);
508 list_add_tail(&evsel->
node, list);
513 const char *sys_name,
const char *evt_name,
515 struct list_head *head_config)
518 struct dirent *evt_ent;
520 int ret = 0, found = 0;
522 evt_path = get_events_file(sys_name);
527 evt_dir = opendir(evt_path);
529 put_events_file(evt_path);
534 while (!ret && (evt_ent = readdir(evt_dir))) {
535 if (!strcmp(evt_ent->d_name,
".")
536 || !strcmp(evt_ent->d_name,
"..")
537 || !strcmp(evt_ent->d_name,
"enable")
538 || !strcmp(evt_ent->d_name,
"filter"))
555 put_events_file(evt_path);
561 const char *sys_name,
const char *evt_name,
563 struct list_head *head_config)
565 return strpbrk(evt_name,
"*?") ?
573 const char *sys_name,
const char *evt_name,
575 struct list_head *head_config)
577 struct dirent *events_ent;
581 events_dir = tracing_events__opendir();
587 while (!ret && (events_ent = readdir(events_dir))) {
588 if (!strcmp(events_ent->d_name,
".")
589 || !strcmp(events_ent->d_name,
"..")
590 || !strcmp(events_ent->d_name,
"enable")
591 || !strcmp(events_ent->d_name,
"header_event")
592 || !strcmp(events_ent->d_name,
"header_page"))
599 evt_name, err, head_config);
602 closedir(events_dir);
618 struct list_head *
list = param->
list;
622 pr_debug(
"add bpf event %s:%s and attach bpf program %d\n",
626 event, parse_state->
error,
631 pr_debug(
"Failed to add BPF event %s:%s\n",
633 list_for_each_entry_safe(evsel, tmp, &new_evsels,
node) {
634 list_del(&evsel->
node);
639 pr_debug(
"adding %s:%s\n", group, event);
641 list_for_each_entry(pos, &new_evsels,
node) {
646 list_splice(&new_evsels, list);
651 struct list_head *
list,
652 struct bpf_object *obj,
658 static bool registered_unprobe_atexit =
false;
660 if (IS_ERR(obj) || !obj) {
661 snprintf(errbuf,
sizeof(errbuf),
662 "Internal error: load bpf obj with NULL");
672 if (!registered_unprobe_atexit) {
674 registered_unprobe_atexit =
true;
691 snprintf(errbuf,
sizeof(errbuf),
692 "Attach events in BPF object failed");
698 parse_state->
error->
help = strdup(
"(add -v to see detail)");
699 parse_state->
error->
str = strdup(errbuf);
705 struct bpf_object *obj,
711 if (!head_config || list_empty(head_config))
714 list_for_each_entry(term, head_config,
list) {
719 snprintf(errbuf,
sizeof(errbuf),
720 "Invalid config term for BPF object");
721 errbuf[BUFSIZ - 1] =
'\0';
724 parse_state->
error->
str = strdup(errbuf);
731 &error_pos, err, errbuf,
734 "Hint:\tValid config terms:\n" 735 " \tmap:[<arraymap>].value<indices>=[value]\n" 736 " \tmap:[<eventmap>].event<indices>=[event]\n" 738 " \twhere <indices> is something like [0,3...5] or [all]\n" 739 " \t(add -v to see detail)");
740 parse_state->
error->
str = strdup(errbuf);
763 struct list_head *obj_head_config)
775 list_for_each_entry_safe(term, temp, evt_head_config,
list)
777 list_move_tail(&term->
list, obj_head_config);
781 struct list_head *
list,
787 struct bpf_object *obj;
800 snprintf(errbuf,
sizeof(errbuf),
801 "BPF support is not compiled");
808 parse_state->
error->
help = strdup(
"(add -v to see detail)");
809 parse_state->
error->
str = strdup(errbuf);
823 list_splice_tail(&obj_head_config, head_config);
832 for (i = 0; i < 3; i++) {
833 if (!type || !type[i])
836 #define CHECK_SET_TYPE(bit) \ 838 if (attr->bp_type & bit) \ 841 attr->bp_type |= bit; \ 859 #undef CHECK_SET_TYPE 862 attr->bp_type = HW_BREAKPOINT_R | HW_BREAKPOINT_W;
868 void *ptr,
char *type, u64 len)
870 struct perf_event_attr attr;
872 memset(&attr, 0,
sizeof(attr));
873 attr.bp_addr = (
unsigned long) ptr;
880 if (attr.bp_type == HW_BREAKPOINT_X)
883 len = HW_BREAKPOINT_LEN_4;
888 attr.type = PERF_TYPE_BREAKPOINT;
889 attr.sample_period = 1;
891 return add_event(list, idx, &attr, NULL, NULL);
904 err->
str = strdup(
"expected numeric value");
906 err->
str = strdup(
"expected string value");
940 err->
str = strdup(
"Invalid term_type");
958 if (asprintf(&err->
str,
"'%s' is not usable in 'perf stat'",
974 #define CHECK_TYPE_VAL(type) \ 976 if (check_type_val(term, err, PARSE_EVENTS__TERM_TYPE_ ## type)) \ 983 attr->config = term->
val.
num;
987 attr->config1 = term->
val.
num;
991 attr->config2 = term->
val.
num;
1001 if (strcmp(term->
val.
str,
"no") &&
1003 err->
str = strdup(
"invalid branch sample type");
1011 err->
str = strdup(
"expected 0 or 1");
1041 err->
str = strdup(
"unknown term");
1059 #undef CHECK_TYPE_VAL 1093 err->
str = strdup(
"unknown term");
1094 err->
help = strdup(
"valid terms: call-graph,stack-size\n");
1103 struct list_head *head,
1109 list_for_each_entry(term, head,
list)
1110 if (config_term(attr, term, err))
1117 struct list_head *head_terms __maybe_unused)
1119 #define ADD_CONFIG_TERM(__type, __name, __val) \ 1121 struct perf_evsel_config_term *__t; \ 1123 __t = zalloc(sizeof(*__t)); \ 1127 INIT_LIST_HEAD(&__t->list); \ 1128 __t->type = PERF_EVSEL__CONFIG_TERM_ ## __type; \ 1129 __t->val.__name = __val; \ 1130 __t->weak = term->weak; \ 1131 list_add_tail(&__t->list, head_terms); \ 1136 list_for_each_entry(term, head_config,
list) {
1178 #undef ADD_EVSEL_CONFIG 1183 const char *sys,
const char *
event,
1188 struct perf_event_attr attr;
1195 if (strpbrk(sys,
"*?"))
1204 struct list_head *
list,
1208 struct perf_event_attr attr;
1211 memset(&attr, 0,
sizeof(attr));
1229 struct list_head *
list,
char *
name,
1231 bool auto_merge_stats,
1234 struct perf_event_attr attr;
1239 bool use_uncore_alias;
1244 if (asprintf(&err->
str,
1245 "Cannot find PMU `%s'. Missing kernel support?",
1253 sizeof(
struct perf_event_attr));
1255 memset(&attr, 0,
sizeof(attr));
1258 use_uncore_alias = (pmu->
is_uncore && use_alias);
1261 attr.type = pmu->
type;
1262 evsel =
__add_event(list, &parse_state->
idx, &attr, NULL, pmu, NULL, auto_merge_stats);
1290 &config_terms, auto_merge_stats);
1302 return evsel ? 0 : -ENOMEM;
1306 char *
str,
struct list_head **listp)
1308 struct list_head *head;
1310 struct list_head *
list;
1316 list =
malloc(
sizeof(
struct list_head));
1319 INIT_LIST_HEAD(list);
1323 list_for_each_entry(alias, &pmu->
aliases, list) {
1324 if (!strcasecmp(alias->
name, str)) {
1325 head =
malloc(
sizeof(
struct list_head));
1328 INIT_LIST_HEAD(head);
1330 str, 1,
false, &str, NULL) < 0)
1332 list_add_tail(&term->
list, head);
1364 char *end_a, *end_b;
1366 end_a = strrchr(pmu_name_a,
'_');
1367 end_b = strrchr(pmu_name_b,
'_');
1369 if (!end_a || !end_b)
1372 if ((end_a - pmu_name_a) != (end_b - pmu_name_b))
1375 return (strncmp(pmu_name_a, pmu_name_b, end_a - pmu_name_a) == 0);
1384 bool is_leader =
true;
1385 int i, nr_pmu = 0, total_members, ret = 0;
1389 total_members = evsel->
idx - leader->
idx + 1;
1391 leaders = calloc(total_members,
sizeof(uintptr_t));
1392 if (WARN_ON(!leaders))
1422 WARN_ON(strcmp(leader->
name, evsel->
name));
1425 leaders[nr_pmu++] = (uintptr_t) evsel;
1429 if (nr_pmu == total_members) {
1454 for (i = 0; i < nr_pmu; i++) {
1457 evsel->
group_name = name ? strdup(name) : NULL;
1475 if (list_empty(list)) {
1476 WARN_ONCE(
true,
"WARNING: failed to set leader: empty list");
1485 leader->
group_name = name ? strdup(name) : NULL;
1490 struct list_head *list_all)
1497 list_splice_tail(list_event, list_all);
1519 int eu = evsel ? evsel->
attr.exclude_user : 0;
1520 int ek = evsel ? evsel->
attr.exclude_kernel : 0;
1521 int eh = evsel ? evsel->
attr.exclude_hv : 0;
1522 int eH = evsel ? evsel->
attr.exclude_host : 0;
1523 int eG = evsel ? evsel->
attr.exclude_guest : 0;
1524 int eI = evsel ? evsel->
attr.exclude_idle : 0;
1525 int precise = evsel ? evsel->
attr.precise_ip : 0;
1526 int precise_max = 0;
1528 int pinned = evsel ? evsel->
attr.pinned : 0;
1530 int exclude = eu | ek | eh;
1531 int exclude_GH = evsel ? evsel->
exclude_GH : 0;
1534 memset(mod, 0,
sizeof(*mod));
1539 exclude = eu = ek = eh = 1;
1541 }
else if (*str ==
'k') {
1543 exclude = eu = ek = eh = 1;
1545 }
else if (*str ==
'h') {
1547 exclude = eu = ek = eh = 1;
1549 }
else if (*str ==
'G') {
1551 exclude_GH = eG = eH = 1;
1553 }
else if (*str ==
'H') {
1555 exclude_GH = eG = eH = 1;
1557 }
else if (*str ==
'I') {
1559 }
else if (*str ==
'p') {
1564 }
else if (*str ==
'P') {
1566 }
else if (*str ==
'S') {
1568 }
else if (*str ==
'D') {
1570 }
else if (*str ==
'W') {
1616 if (strlen(str) > (
sizeof(
"ukhGHpppPSDIW") - 1))
1620 if (*p !=
'p' && strchr(p + 1, *p))
1646 evsel->
attr.exclude_user = mod.
eu;
1647 evsel->
attr.exclude_kernel = mod.
ek;
1648 evsel->
attr.exclude_hv = mod.
eh;
1650 evsel->
attr.exclude_host = mod.
eH;
1651 evsel->
attr.exclude_guest = mod.
eG;
1652 evsel->
attr.exclude_idle = mod.
eI;
1671 evsel->
name = strdup(name);
1693 p = perf_pmu_events_list + i;
1696 zfree(&perf_pmu_events_list);
1697 perf_pmu_events_list_num = 0;
1701 #define SET_SYMBOL(str, stype) \ 1723 if (strchr(alias->
name,
'-'))
1734 if (!perf_pmu_events_list)
1743 char *tmp = strchr(alias->
name,
'-');
1757 qsort(perf_pmu_events_list, len,
1782 r = bsearch(&p, perf_pmu_events_list,
1802 parse_events_debug = 1;
1824 list_splice(parse_state.
terms, terms);
1837 .
list = LIST_HEAD_INIT(parse_state.
list),
1849 if (list_empty(&parse_state.
list)) {
1850 WARN_ONCE(
true,
"WARNING: event parser found nothing\n");
1870 #define MAX_WIDTH 1000 1882 const char *
str =
"invalid or unsupported event: ";
1884 char *buf = (
char *) event;
1890 int len_event = strlen(event);
1891 int len_str, max_len, cut = 0;
1897 int max_err_idx = 13;
1903 str =
"event syntax error: ";
1904 len_str = strlen(str);
1905 max_len = width - len_str;
1910 if (err->
idx > max_err_idx)
1911 cut = err->
idx - max_err_idx;
1913 strncpy(buf, event + cut, max_len);
1917 buf[0] = buf[1] =
'.';
1919 if ((len_event - cut) > max_len) {
1920 buf[max_len - 1] = buf[max_len - 2] =
'.';
1924 idx = len_str + err->
idx - cut;
1927 fprintf(stderr,
"%s'%s'\n", str, buf);
1929 fprintf(stderr,
"%*s\\___ %s\n", idx + 1,
"", err->
str);
1931 fprintf(stderr,
"\n%s\n", err->
help);
1940 int unset __maybe_unused)
1948 fprintf(stderr,
"Run 'perf list' for a list of valid events\n");
1973 err = (*func)(last, arg);
1979 if (last->node.prev == &evlist->
entries)
1989 const char *
str = arg;
1991 int nr_addr_filters = 0;
1997 if (evsel->
attr.type == PERF_TYPE_TRACEPOINT) {
2000 "not enough memory to hold filter string\n");
2008 if (pmu->
type == evsel->
attr.type) {
2015 "%d", &nr_addr_filters);
2017 if (!nr_addr_filters)
2022 "not enough memory to hold filter string\n");
2030 "--filter option should follow a -e tracepoint or HW tracer option\n");
2036 int unset __maybe_unused)
2045 const void *arg __maybe_unused)
2047 char new_filter[64];
2049 if (evsel == NULL || evsel->
attr.type != PERF_TYPE_TRACEPOINT) {
2051 "--exclude-perf option should follow a -e tracepoint option\n");
2055 snprintf(new_filter,
sizeof(new_filter),
"common_pid != %d", getpid());
2059 "not enough memory to hold filter string\n");
2067 const char *arg __maybe_unused,
2068 int unset __maybe_unused)
2080 "Hardware cache event",
2081 "Raw hardware event descriptor",
2082 "Hardware breakpoint",
2087 const char *
const *as = a;
2088 const char *
const *bs = b;
2090 return strcmp(*as, *bs);
2100 DIR *sys_dir, *evt_dir;
2101 struct dirent *sys_dirent, *evt_dirent;
2102 char evt_path[MAXPATHLEN];
2104 char **evt_list = NULL;
2105 unsigned int evt_i = 0, evt_num = 0;
2106 bool evt_num_known =
false;
2109 sys_dir = tracing_events__opendir();
2113 if (evt_num_known) {
2114 evt_list =
zalloc(
sizeof(
char *) * evt_num);
2116 goto out_close_sys_dir;
2120 if (subsys_glob != NULL &&
2124 dir_path = get_events_file(sys_dirent->d_name);
2127 evt_dir = opendir(dir_path);
2132 if (event_glob != NULL &&
2136 if (!evt_num_known) {
2141 snprintf(evt_path, MAXPATHLEN,
"%s:%s",
2142 sys_dirent->d_name, evt_dirent->d_name);
2144 evt_list[evt_i] = strdup(evt_path);
2145 if (evt_list[evt_i] == NULL) {
2146 put_events_file(dir_path);
2147 goto out_close_evt_dir;
2153 put_events_file(dir_path);
2157 if (!evt_num_known) {
2158 evt_num_known =
true;
2161 qsort(evt_list, evt_num,
sizeof(
char *),
cmp_string);
2163 while (evt_i < evt_num) {
2165 printf(
"%s ", evt_list[evt_i++]);
2168 printf(
" %-50s [%s]\n", evt_list[evt_i++],
2169 event_type_descriptors[PERF_TYPE_TRACEPOINT]);
2171 if (evt_num && pager_in_use())
2176 for (evt_i = 0; evt_i < evt_num; evt_i++)
2177 zfree(&evt_list[evt_i]);
2186 printf(
"FATAL: not enough memory to print %s\n",
2187 event_type_descriptors[PERF_TYPE_TRACEPOINT]);
2198 DIR *sys_dir, *evt_dir;
2199 struct dirent *sys_dirent, *evt_dirent;
2200 char evt_path[MAXPATHLEN];
2203 sys_dir = tracing_events__opendir();
2208 dir_path = get_events_file(sys_dirent->d_name);
2211 evt_dir = opendir(dir_path);
2216 snprintf(evt_path, MAXPATHLEN,
"%s:%s",
2217 sys_dirent->d_name, evt_dirent->d_name);
2218 if (!strcmp(evt_path, event_string)) {
2226 put_events_file(dir_path);
2237 struct perf_event_attr attr = {
2250 ret = open_return >= 0;
2252 if (open_return == -EACCES) {
2260 evsel->
attr.exclude_kernel = 1;
2274 struct strlist *bidlist, *sdtlist;
2277 char *buf, *path, *ptr = NULL;
2278 bool show_detail =
false;
2283 pr_debug(
"Failed to allocate new strlist for SDT\n");
2288 pr_debug(
"Failed to get buildids: %d\n", errno);
2295 list_for_each_entry(ent, &pcache->
entries,
node) {
2304 ret = asprintf(&buf,
"%s:%s@%s", ent->
pev.
group,
2314 buf = strchr(nd->
s,
'@');
2318 printf(
"%s ", nd->
s);
2323 ptr = strchr(nd2->
s,
'@');
2326 if (strcmp(nd->
s, nd2->
s) == 0)
2331 ret = asprintf(&buf,
"%s@%s(%.12s)", nd->
s, path, buf);
2333 printf(
" %-50s [%s]\n", buf,
"SDT event");
2337 printf(
" %-50s [%s]\n", nd->
s,
"SDT event");
2339 if (strcmp(nd->
s, nd2->
s) != 0)
2340 show_detail =
false;
2350 unsigned int type, op, i, evt_i = 0, evt_num = 0;
2352 char **evt_list = NULL;
2353 bool evt_num_known =
false;
2356 if (evt_num_known) {
2357 evt_list =
zalloc(
sizeof(
char *) * evt_num);
2362 for (type = 0; type < PERF_COUNT_HW_CACHE_MAX; type++) {
2363 for (op = 0; op < PERF_COUNT_HW_CACHE_OP_MAX; op++) {
2368 for (i = 0; i < PERF_COUNT_HW_CACHE_RESULT_MAX; i++) {
2370 name,
sizeof(name));
2371 if (event_glob != NULL && !
strglobmatch(name, event_glob))
2375 type | (op << 8) | (i << 16)))
2378 if (!evt_num_known) {
2383 evt_list[evt_i] = strdup(name);
2384 if (evt_list[evt_i] == NULL)
2391 if (!evt_num_known) {
2392 evt_num_known =
true;
2395 qsort(evt_list, evt_num,
sizeof(
char *),
cmp_string);
2397 while (evt_i < evt_num) {
2399 printf(
"%s ", evt_list[evt_i++]);
2402 printf(
" %-50s [%s]\n", evt_list[evt_i++],
2403 event_type_descriptors[PERF_TYPE_HW_CACHE]);
2405 if (evt_num && pager_in_use())
2410 for (evt_i = 0; evt_i < evt_num; evt_i++)
2411 zfree(&evt_list[evt_i]);
2416 printf(
"FATAL: not enough memory to print %s\n", event_type_descriptors[PERF_TYPE_HW_CACHE]);
2426 unsigned int i, evt_i = 0, evt_num = 0;
2428 char **evt_list = NULL;
2429 bool evt_num_known =
false;
2432 if (evt_num_known) {
2433 evt_list =
zalloc(
sizeof(
char *) * evt_num);
2439 for (i = 0; i < max; i++, syms++) {
2441 if (event_glob != NULL && syms->
symbol != NULL &&
2449 if (!evt_num_known) {
2454 if (!name_only && strlen(syms->
alias))
2459 evt_list[evt_i] = strdup(name);
2460 if (evt_list[evt_i] == NULL)
2465 if (!evt_num_known) {
2466 evt_num_known =
true;
2469 qsort(evt_list, evt_num,
sizeof(
char *),
cmp_string);
2471 while (evt_i < evt_num) {
2473 printf(
"%s ", evt_list[evt_i++]);
2476 printf(
" %-50s [%s]\n", evt_list[evt_i++], event_type_descriptors[type]);
2478 if (evt_num && pager_in_use())
2483 for (evt_i = 0; evt_i < evt_num; evt_i++)
2484 zfree(&evt_list[evt_i]);
2489 printf(
"FATAL: not enough memory to print %s\n", event_type_descriptors[type]);
2501 event_symbols_hw, PERF_COUNT_HW_MAX, name_only);
2504 event_symbols_sw, PERF_COUNT_SW_MAX, name_only);
2511 if (event_glob != NULL)
2515 printf(
" %-50s [%s]\n",
2517 event_type_descriptors[PERF_TYPE_RAW]);
2518 printf(
" %-50s [%s]\n",
2519 "cpu/t1=v1[,t2=v2,t3 ...]/modifier",
2520 event_type_descriptors[PERF_TYPE_RAW]);
2522 printf(
" (see 'man perf-list' on how to encode it)\n\n");
2524 printf(
" %-50s [%s]\n",
2525 "mem:<addr>[/len][:access]",
2526 event_type_descriptors[PERF_TYPE_BREAKPOINT]);
2549 term =
malloc(
sizeof(*term));
2554 INIT_LIST_HEAD(&term->
list);
2576 void *loc_term_,
void *loc_val_)
2578 YYLTYPE *loc_term = loc_term_;
2590 return new_term(term, &temp, NULL, num);
2595 void *loc_term_,
void *loc_val_)
2597 YYLTYPE *loc_term = loc_term_;
2608 return new_term(term, &temp, str, 0);
2612 char *
config,
unsigned idx)
2618 .config = config ?: (
char *)
"event",
2621 BUG_ON(idx >= PERF_COUNT_HW_MAX);
2622 sym = &event_symbols_hw[idx];
2642 struct list_head **
new)
2652 *
new =
malloc(
sizeof(
struct list_head));
2655 INIT_LIST_HEAD(*
new);
2657 list_for_each_entry (term, old,
list) {
2661 list_add_tail(&n->
list, *
new);
2670 list_for_each_entry_safe(term, h, terms,
list) {
2673 list_del_init(&term->
list);
2692 int idx,
const char *
str)
2699 err->
str = strdup(str);
2700 WARN_ONCE(!err->
str,
"WARNING: failed to allocate error string");
2719 if (strlen(buf) + strlen(name) + 2 >= buf_sz)
2739 (
sizeof(
"no-overwrite") - 1)];
2743 if (additional_terms) {
2744 if (asprintf(&str,
"valid terms: %s,%s",
2745 additional_terms, static_terms) < 0)
2748 if (asprintf(&str,
"valid terms: %s", static_terms) < 0)
static const char * config_term_names[__PARSE_EVENTS__TERM_TYPE_NR]
void print_sdt_events(const char *subsys_glob, const char *event_glob, bool name_only)
void print_pmu_events(const char *event_glob, bool name_only, bool quiet_flag, bool long_desc, bool details_flag)
char * build_id_cache__origname(const char *sbuild_id)
int perf_evsel__append_tp_filter(struct perf_evsel *evsel, const char *filter)
void parse_events__clear_array(struct parse_events_array *a)
void event_attr_init(struct perf_event_attr *attr)
int parse_events_copy_term_list(struct list_head *old, struct list_head **new)
static int get_term_width(void)
static int config_term_pmu(struct perf_event_attr *attr, struct parse_events_term *term, struct parse_events_error *err)
int parse_events_name(struct list_head *list, char *name)
const char * perf_evsel__hw_cache_result[PERF_COUNT_HW_CACHE_RESULT_MAX][PERF_EVSEL__MAX_ALIASES]
#define CHECK_SET_TYPE(bit)
int parse_filter(const struct option *opt, const char *str, int unset __maybe_unused)
static int add_bpf_event(const char *group, const char *event, int fd, void *_param)
bool perf_evsel__is_cache_op_valid(u8 type, u8 op)
void parse_events_terms__purge(struct list_head *terms)
YY_BUFFER_STATE parse_events__scan_string(yyconst char *yy_str, yyscan_t yyscanner)
int parse_events_terms(struct list_head *terms, const char *str)
void print_events(const char *event_glob, bool name_only, bool quiet_flag, bool long_desc, bool details_flag)
int exclude_perf(const struct option *opt, const char *arg __maybe_unused, int unset __maybe_unused)
static LIST_HEAD(page_alloc_sort_input)
void parse_events_terms__delete(struct list_head *terms)
struct perf_evsel * perf_evsel__new_idx(struct perf_event_attr *attr, int idx)
static int new_term(struct parse_events_term **_term, struct parse_events_term *temp, char *str, u64 num)
static int parse_events_config_bpf(struct parse_events_state *parse_state, struct bpf_object *obj, struct list_head *head_config)
int bpf__strerror_probe(struct bpf_object *obj __maybe_unused, int err, char *buf, size_t size)
void print_tracepoint_events(const char *subsys_glob, const char *event_glob, bool name_only)
static int parse_events__set_leader_for_uncore_aliase(char *name, struct list_head *list, struct parse_events_state *parse_state)
const char * perf_evsel__hw_cache_op[PERF_COUNT_HW_CACHE_OP_MAX][PERF_EVSEL__MAX_ALIASES]
static int add_event(struct list_head *list, int *idx, struct perf_event_attr *attr, char *name, struct list_head *config_terms)
int bpf__config_obj(struct bpf_object *obj, struct parse_events_term *term, struct perf_evlist *evlist, int *error_pos)
struct list_head * head_config
void parse_events__flush_buffer(YY_BUFFER_STATE b, yyscan_t yyscanner)
int bpf__probe(struct bpf_object *obj)
int strlist__add(struct strlist *slist, const char *new_entry)
static struct perf_pmu_event_symbol * perf_pmu_events_list
struct event_symbol event_symbols_hw[PERF_COUNT_HW_MAX]
int perf_pmu__scan_file(struct perf_pmu *pmu, const char *name, const char *fmt,...)
void perf_evsel__delete(struct perf_evsel *evsel)
static bool config_term_avail(int term_type, struct parse_events_error *err)
void perf_evlist__splice_list_tail(struct perf_evlist *evlist, struct list_head *list)
static int term(yyscan_t scanner, int type)
static int add_tracepoint_multi_event(struct list_head *list, int *idx, const char *sys_name, const char *evt_name, struct parse_events_error *err, struct list_head *head_config)
struct perf_event_attr * default_config
int bpf__strerror_config_obj(struct bpf_object *obj __maybe_unused, struct parse_events_term *term __maybe_unused, struct perf_evlist *evlist __maybe_unused, int *error_pos __maybe_unused, int err, char *buf, size_t size)
bool strglobmatch(const char *str, const char *pat)
static int parse_breakpoint_type(const char *type, struct perf_event_attr *attr)
static int get_event_modifier(struct event_modifier *mod, char *str, struct perf_evsel *evsel)
struct perf_evlist * evlist
static int config_term_common(struct perf_event_attr *attr, struct parse_events_term *term, struct parse_events_error *err)
static int perf_pmu_events_list_num
struct thread_map * thread_map__new_by_tid(pid_t tid)
int parse_events__modifier_event(struct list_head *list, char *str, bool add)
int parse_events_load_bpf_obj(struct parse_events_state *parse_state, struct list_head *list, struct bpf_object *obj, struct list_head *head_config)
static int tp_event_has_id(const char *dir_path, struct dirent *evt_dir)
struct event_symbol event_symbols_sw[PERF_COUNT_SW_MAX]
static int foreach_evsel_in_last_glob(struct perf_evlist *evlist, int(*func)(struct perf_evsel *evsel, const void *arg), const void *arg)
x86 movsq based memset() in arch/x86/lib/memset_64.S") MEMSET_FN(memset_erms
static void perf_pmu__parse_init(void)
int bpf__strerror_load(struct bpf_object *obj, int err, char *buf, size_t size)
union parse_events_term::@132 val
int parse_events_multi_pmu_add(struct parse_events_state *parse_state, char *str, struct list_head **listp)
#define CHECK_TYPE_VAL(type)
int parse_events(struct perf_evlist *evlist, const char *str, struct parse_events_error *err)
struct parse_events_array array
struct perf_pmu * perf_pmu__scan(struct perf_pmu *pmu)
#define PERF_EVSEL__MAX_ALIASES
int perf_evsel__append_addr_filter(struct perf_evsel *evsel, const char *filter)
enum perf_pmu_event_symbol_type type
int print_hwcache_events(const char *event_glob, bool name_only)
int __perf_evsel__hw_cache_type_op_res_name(u8 type, u8 op, u8 result, char *bf, size_t size)
#define for_each_subsystem(sys_dir, sys_dirent)
struct bpf_object * bpf__prepare_load(const char *filename, bool source)
static int cmp_string(const void *a, const void *b)
int parse_events_add_cache(struct list_head *list, int *idx, char *type, char *op_result1, char *op_result2, struct parse_events_error *err, struct list_head *head_config)
const char * event_type(int type)
struct tracepoint_path * tracepoint_id_to_path(u64 config)
static int add_tracepoint_multi_sys(struct list_head *list, int *idx, const char *sys_name, const char *evt_name, struct parse_events_error *err, struct list_head *head_config)
static bool is_event_supported(u8 type, unsigned config)
#define pr_debug(fmt,...)
int bpf__foreach_event(struct bpf_object *obj, bpf_prog_iter_callback_t func, void *arg)
bool cmdline_group_boundary
int parse_events__is_hardcoded_term(struct parse_events_term *term)
static void perf_pmu__parse_cleanup(void)
int parse_events_term__str(struct parse_events_term **term, int type_term, char *config, char *str, void *loc_term_, void *loc_val_)
int parse_events_add_tracepoint(struct list_head *list, int *idx, const char *sys, const char *event, struct parse_events_error *err, struct list_head *head_config)
int is_valid_tracepoint(const char *event_string)
static int comp_pmu(const void *p1, const void *p2)
struct parse_events_error * error
#define ADD_CONFIG_TERM(__type, __name, __val)
static int add_tracepoint(struct list_head *list, int *idx, const char *sys_name, const char *evt_name, struct parse_events_error *err, struct list_head *head_config)
void print_symbol_events(const char *event_glob, unsigned type, struct event_symbol *syms, unsigned max, bool name_only)
int bpf__load(struct bpf_object *obj)
static int str(yyscan_t scanner, int token)
int parse_events_add_numeric(struct parse_events_state *parse_state, struct list_head *list, u32 type, u64 config, struct list_head *head_config)
#define strlist__for_each_entry(pos, slist)
int parse_events_lex_destroy(yyscan_t yyscanner)
int bpf__strerror_prepare_load(const char *filename, bool source, int err, char *buf, size_t size)
int perf_pmu__config(struct perf_pmu *pmu, struct perf_event_attr *attr, struct list_head *head_terms, struct parse_events_error *err)
void parse_events_evlist_error(struct parse_events_state *parse_state, int idx, const char *str)
#define __evlist__for_each_entry(list, evsel)
static int get_config_terms(struct list_head *head_config, struct list_head *head_terms __maybe_unused)
struct probe_cache * probe_cache__new(const char *target, struct nsinfo *nsi)
void parse_events__delete_buffer(YY_BUFFER_STATE b, yyscan_t yyscanner)
struct parse_events_state * parse_state
#define SET_SYMBOL(str, stype)
int parse_events_parse(void *parse_state, void *scanner)
struct list_head config_terms
static int set_filter(struct perf_evsel *evsel, const void *arg)
struct tracepoint_path * tracepoint_name_to_path(const char *name)
x86 movsq based memcpy() in arch/x86/lib/memcpy_64.S") MEMCPY_FN(memcpy_erms
struct cpu_map * own_cpus
enum perf_pmu_event_symbol_type perf_pmu__parse_check(const char *name)
void parse_events__set_leader(char *name, struct list_head *list, struct parse_events_state *parse_state)
static int config_attr(struct perf_event_attr *attr, struct list_head *head, struct parse_events_error *err, config_term_func_t config_term)
#define for_each_event(dir_path, evt_dir, evt_dirent)
void get_term_dimensions(struct winsize *ws)
static int parse_events__is_name_term(struct parse_events_term *term)
int parse_events_term__clone(struct parse_events_term **new, struct parse_events_term *term)
void probe_cache__delete(struct probe_cache *pcache)
int parse_events_lex_init_extra(YY_EXTRA_TYPE user_defined, yyscan_t *scanner)
static struct perf_evsel * perf_evsel__new(struct perf_event_attr *attr)
struct perf_pmu * perf_pmu__find(const char *name)
int perf_evsel__open(struct perf_evsel *evsel, struct cpu_map *cpus, struct thread_map *threads)
int parse_branch_str(const char *str, __u64 *mode)
void __perf_evlist__set_leader(struct list_head *list)
perf_pmu_event_symbol_type
int parse_events_add_pmu(struct parse_events_state *parse_state, struct list_head *list, char *name, struct list_head *head_config, bool auto_merge_stats, bool use_alias)
int perf_pmu__check_alias(struct perf_pmu *pmu, struct list_head *head_terms, struct perf_pmu_info *info)
int parse_events__modifier_group(struct list_head *list, char *event_mod)
int parse_events_option(const struct option *opt, const char *str, int unset __maybe_unused)
static struct str_node * strlist__next(struct str_node *sn)
static int parse_aliases(char *str, const char *names[][PERF_EVSEL__MAX_ALIASES], int size)
int parse_events_add_breakpoint(struct list_head *list, int *idx, void *ptr, char *type, u64 len)
struct perf_evsel * leader
static const char *const event_type_descriptors[]
static char * get_config_name(struct list_head *head_terms)
struct perf_probe_event pev
static int sym(yyscan_t scanner, int type, int config)
struct perf_evsel * perf_evsel__newtp_idx(const char *sys, const char *name, int idx)
void strlist__delete(struct strlist *slist)
char * parse_events_formats_error_string(char *additional_terms)
void parse_events__shrink_config_terms(void)
static void tracepoint_error(struct parse_events_error *e, int err, const char *sys, const char *name)
const char * perf_evsel__hw_cache[PERF_COUNT_HW_CACHE_MAX][PERF_EVSEL__MAX_ALIASES]
struct strlist * build_id_cache__list_all(bool validonly)
static struct perf_evsel * __add_event(struct list_head *list, int *idx, struct perf_event_attr *attr, char *name, struct perf_pmu *pmu, struct list_head *config_terms, bool auto_merge_stats)
static bool config_term_shrinked
void parse_events_print_error(struct parse_events_error *err, const char *event)
static int check_modifier(char *str)
static bool perf_evsel__is_group_leader(const struct perf_evsel *evsel)
void parse_events_update_lists(struct list_head *list_event, struct list_head *list_all)
static int add_exclude_perf_filter(struct perf_evsel *evsel, const void *arg __maybe_unused)
static struct perf_evsel * perf_evlist__last(struct perf_evlist *evlist)
int parse_events_term__num(struct parse_events_term **term, int type_term, char *config, u64 num, bool no_value, void *loc_term_, void *loc_val_)
static void config_terms_list(char *buf, size_t buf_sz)
static void split_bpf_config_terms(struct list_head *evt_head_config, struct list_head *obj_head_config)
static int add_tracepoint_event(struct list_head *list, int *idx, const char *sys_name, const char *evt_name, struct parse_events_error *err, struct list_head *head_config)
static bool is_same_uncore_block(const char *pmu_name_a, const char *pmu_name_b)
static int parse_events__scanner(const char *str, void *parse_state, int start_token)
int parse_events_term__sym_hw(struct parse_events_term **term, char *config, unsigned idx)
struct strlist * strlist__new(const char *list, const struct strlist_config *config)
int config_term_func_t(struct perf_event_attr *attr, struct parse_events_term *term, struct parse_events_error *err)
void metricgroup__print(bool metrics, bool metricgroups, char *filter, bool raw)
static int check_type_val(struct parse_events_term *term, struct parse_events_error *err, int type)
struct perf_event_attr attr
struct parse_events_array::@131 * ranges
struct cpu_map * cpu_map__get(struct cpu_map *map)
void static void * zalloc(size_t size)
int parse_events_load_bpf(struct parse_events_state *parse_state, struct list_head *list, char *bpf_file_name, bool source, struct list_head *head_config)
static int config_term_tracepoint(struct perf_event_attr *attr, struct parse_events_term *term, struct parse_events_error *err)