aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/util/parse-events.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/perf/util/parse-events.c')
-rw-r--r--tools/perf/util/parse-events.c147
1 files changed, 92 insertions, 55 deletions
diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c
index 044178408783..a587d41ae3c9 100644
--- a/tools/perf/util/parse-events.c
+++ b/tools/perf/util/parse-events.c
@@ -1,23 +1,21 @@
1 1
2#include "../perf.h"
3#include "util.h" 2#include "util.h"
3#include "../perf.h"
4#include "parse-options.h" 4#include "parse-options.h"
5#include "parse-events.h" 5#include "parse-events.h"
6#include "exec_cmd.h" 6#include "exec_cmd.h"
7#include "string.h" 7#include "string.h"
8#include "cache.h" 8#include "cache.h"
9 9
10extern char *strcasestr(const char *haystack, const char *needle);
11
12int nr_counters; 10int nr_counters;
13 11
14struct perf_counter_attr attrs[MAX_COUNTERS]; 12struct perf_counter_attr attrs[MAX_COUNTERS];
15 13
16struct event_symbol { 14struct event_symbol {
17 u8 type; 15 u8 type;
18 u64 config; 16 u64 config;
19 char *symbol; 17 const char *symbol;
20 char *alias; 18 const char *alias;
21}; 19};
22 20
23char debugfs_path[MAXPATHLEN]; 21char debugfs_path[MAXPATHLEN];
@@ -51,7 +49,7 @@ static struct event_symbol event_symbols[] = {
51#define PERF_COUNTER_TYPE(config) __PERF_COUNTER_FIELD(config, TYPE) 49#define PERF_COUNTER_TYPE(config) __PERF_COUNTER_FIELD(config, TYPE)
52#define PERF_COUNTER_ID(config) __PERF_COUNTER_FIELD(config, EVENT) 50#define PERF_COUNTER_ID(config) __PERF_COUNTER_FIELD(config, EVENT)
53 51
54static char *hw_event_names[] = { 52static const char *hw_event_names[] = {
55 "cycles", 53 "cycles",
56 "instructions", 54 "instructions",
57 "cache-references", 55 "cache-references",
@@ -61,7 +59,7 @@ static char *hw_event_names[] = {
61 "bus-cycles", 59 "bus-cycles",
62}; 60};
63 61
64static char *sw_event_names[] = { 62static const char *sw_event_names[] = {
65 "cpu-clock-msecs", 63 "cpu-clock-msecs",
66 "task-clock-msecs", 64 "task-clock-msecs",
67 "page-faults", 65 "page-faults",
@@ -73,7 +71,7 @@ static char *sw_event_names[] = {
73 71
74#define MAX_ALIASES 8 72#define MAX_ALIASES 8
75 73
76static char *hw_cache[][MAX_ALIASES] = { 74static const char *hw_cache[][MAX_ALIASES] = {
77 { "L1-dcache", "l1-d", "l1d", "L1-data", }, 75 { "L1-dcache", "l1-d", "l1d", "L1-data", },
78 { "L1-icache", "l1-i", "l1i", "L1-instruction", }, 76 { "L1-icache", "l1-i", "l1i", "L1-instruction", },
79 { "LLC", "L2" }, 77 { "LLC", "L2" },
@@ -82,13 +80,13 @@ static char *hw_cache[][MAX_ALIASES] = {
82 { "branch", "branches", "bpu", "btb", "bpc", }, 80 { "branch", "branches", "bpu", "btb", "bpc", },
83}; 81};
84 82
85static char *hw_cache_op[][MAX_ALIASES] = { 83static const char *hw_cache_op[][MAX_ALIASES] = {
86 { "load", "loads", "read", }, 84 { "load", "loads", "read", },
87 { "store", "stores", "write", }, 85 { "store", "stores", "write", },
88 { "prefetch", "prefetches", "speculative-read", "speculative-load", }, 86 { "prefetch", "prefetches", "speculative-read", "speculative-load", },
89}; 87};
90 88
91static char *hw_cache_result[][MAX_ALIASES] = { 89static const char *hw_cache_result[][MAX_ALIASES] = {
92 { "refs", "Reference", "ops", "access", }, 90 { "refs", "Reference", "ops", "access", },
93 { "misses", "miss", }, 91 { "misses", "miss", },
94}; 92};
@@ -113,11 +111,9 @@ static unsigned long hw_cache_stat[C(MAX)] = {
113 [C(BPU)] = (CACHE_READ), 111 [C(BPU)] = (CACHE_READ),
114}; 112};
115 113
116#define for_each_subsystem(sys_dir, sys_dirent, sys_next, file, st) \ 114#define for_each_subsystem(sys_dir, sys_dirent, sys_next) \
117 while (!readdir_r(sys_dir, &sys_dirent, &sys_next) && sys_next) \ 115 while (!readdir_r(sys_dir, &sys_dirent, &sys_next) && sys_next) \
118 if (snprintf(file, MAXPATHLEN, "%s/%s", debugfs_path, \ 116 if (sys_dirent.d_type == DT_DIR && \
119 sys_dirent.d_name) && \
120 (!stat(file, &st)) && (S_ISDIR(st.st_mode)) && \
121 (strcmp(sys_dirent.d_name, ".")) && \ 117 (strcmp(sys_dirent.d_name, ".")) && \
122 (strcmp(sys_dirent.d_name, ".."))) 118 (strcmp(sys_dirent.d_name, "..")))
123 119
@@ -136,11 +132,9 @@ static int tp_event_has_id(struct dirent *sys_dir, struct dirent *evt_dir)
136 return 0; 132 return 0;
137} 133}
138 134
139#define for_each_event(sys_dirent, evt_dir, evt_dirent, evt_next, file, st) \ 135#define for_each_event(sys_dirent, evt_dir, evt_dirent, evt_next) \
140 while (!readdir_r(evt_dir, &evt_dirent, &evt_next) && evt_next) \ 136 while (!readdir_r(evt_dir, &evt_dirent, &evt_next) && evt_next) \
141 if (snprintf(file, MAXPATHLEN, "%s/%s/%s", debugfs_path, \ 137 if (evt_dirent.d_type == DT_DIR && \
142 sys_dirent.d_name, evt_dirent.d_name) && \
143 (!stat(file, &st)) && (S_ISDIR(st.st_mode)) && \
144 (strcmp(evt_dirent.d_name, ".")) && \ 138 (strcmp(evt_dirent.d_name, ".")) && \
145 (strcmp(evt_dirent.d_name, "..")) && \ 139 (strcmp(evt_dirent.d_name, "..")) && \
146 (!tp_event_has_id(&sys_dirent, &evt_dirent))) 140 (!tp_event_has_id(&sys_dirent, &evt_dirent)))
@@ -158,34 +152,39 @@ int valid_debugfs_mount(const char *debugfs)
158 return 0; 152 return 0;
159} 153}
160 154
161static char *tracepoint_id_to_name(u64 config) 155struct tracepoint_path *tracepoint_id_to_path(u64 config)
162{ 156{
163 static char tracepoint_name[2 * MAX_EVENT_LENGTH]; 157 struct tracepoint_path *path = NULL;
164 DIR *sys_dir, *evt_dir; 158 DIR *sys_dir, *evt_dir;
165 struct dirent *sys_next, *evt_next, sys_dirent, evt_dirent; 159 struct dirent *sys_next, *evt_next, sys_dirent, evt_dirent;
166 struct stat st;
167 char id_buf[4]; 160 char id_buf[4];
168 int fd; 161 int sys_dir_fd, fd;
169 u64 id; 162 u64 id;
170 char evt_path[MAXPATHLEN]; 163 char evt_path[MAXPATHLEN];
171 164
172 if (valid_debugfs_mount(debugfs_path)) 165 if (valid_debugfs_mount(debugfs_path))
173 return "unkown"; 166 return NULL;
174 167
175 sys_dir = opendir(debugfs_path); 168 sys_dir = opendir(debugfs_path);
176 if (!sys_dir) 169 if (!sys_dir)
177 goto cleanup; 170 goto cleanup;
178 171 sys_dir_fd = dirfd(sys_dir);
179 for_each_subsystem(sys_dir, sys_dirent, sys_next, evt_path, st) { 172
180 evt_dir = opendir(evt_path); 173 for_each_subsystem(sys_dir, sys_dirent, sys_next) {
181 if (!evt_dir) 174 int dfd = openat(sys_dir_fd, sys_dirent.d_name,
182 goto cleanup; 175 O_RDONLY|O_DIRECTORY), evt_dir_fd;
183 for_each_event(sys_dirent, evt_dir, evt_dirent, evt_next, 176 if (dfd == -1)
184 evt_path, st) { 177 continue;
185 snprintf(evt_path, MAXPATHLEN, "%s/%s/%s/id", 178 evt_dir = fdopendir(dfd);
186 debugfs_path, sys_dirent.d_name, 179 if (!evt_dir) {
180 close(dfd);
181 continue;
182 }
183 evt_dir_fd = dirfd(evt_dir);
184 for_each_event(sys_dirent, evt_dir, evt_dirent, evt_next) {
185 snprintf(evt_path, MAXPATHLEN, "%s/id",
187 evt_dirent.d_name); 186 evt_dirent.d_name);
188 fd = open(evt_path, O_RDONLY); 187 fd = openat(evt_dir_fd, evt_path, O_RDONLY);
189 if (fd < 0) 188 if (fd < 0)
190 continue; 189 continue;
191 if (read(fd, id_buf, sizeof(id_buf)) < 0) { 190 if (read(fd, id_buf, sizeof(id_buf)) < 0) {
@@ -197,10 +196,23 @@ static char *tracepoint_id_to_name(u64 config)
197 if (id == config) { 196 if (id == config) {
198 closedir(evt_dir); 197 closedir(evt_dir);
199 closedir(sys_dir); 198 closedir(sys_dir);
200 snprintf(tracepoint_name, 2 * MAX_EVENT_LENGTH, 199 path = calloc(1, sizeof(path));
201 "%s:%s", sys_dirent.d_name, 200 path->system = malloc(MAX_EVENT_LENGTH);
202 evt_dirent.d_name); 201 if (!path->system) {
203 return tracepoint_name; 202 free(path);
203 return NULL;
204 }
205 path->name = malloc(MAX_EVENT_LENGTH);
206 if (!path->name) {
207 free(path->system);
208 free(path);
209 return NULL;
210 }
211 strncpy(path->system, sys_dirent.d_name,
212 MAX_EVENT_LENGTH);
213 strncpy(path->name, evt_dirent.d_name,
214 MAX_EVENT_LENGTH);
215 return path;
204 } 216 }
205 } 217 }
206 closedir(evt_dir); 218 closedir(evt_dir);
@@ -208,7 +220,25 @@ static char *tracepoint_id_to_name(u64 config)
208 220
209cleanup: 221cleanup:
210 closedir(sys_dir); 222 closedir(sys_dir);
211 return "unkown"; 223 return NULL;
224}
225
226#define TP_PATH_LEN (MAX_EVENT_LENGTH * 2 + 1)
227static const char *tracepoint_id_to_name(u64 config)
228{
229 static char buf[TP_PATH_LEN];
230 struct tracepoint_path *path;
231
232 path = tracepoint_id_to_path(config);
233 if (path) {
234 snprintf(buf, TP_PATH_LEN, "%s:%s", path->system, path->name);
235 free(path->name);
236 free(path->system);
237 free(path);
238 } else
239 snprintf(buf, TP_PATH_LEN, "%s:%s", "unknown", "unknown");
240
241 return buf;
212} 242}
213 243
214static int is_cache_op_valid(u8 cache_type, u8 cache_op) 244static int is_cache_op_valid(u8 cache_type, u8 cache_op)
@@ -235,7 +265,7 @@ static char *event_cache_name(u8 cache_type, u8 cache_op, u8 cache_result)
235 return name; 265 return name;
236} 266}
237 267
238char *event_name(int counter) 268const char *event_name(int counter)
239{ 269{
240 u64 config = attrs[counter].config; 270 u64 config = attrs[counter].config;
241 int type = attrs[counter].type; 271 int type = attrs[counter].type;
@@ -243,7 +273,7 @@ char *event_name(int counter)
243 return __event_name(type, config); 273 return __event_name(type, config);
244} 274}
245 275
246char *__event_name(int type, u64 config) 276const char *__event_name(int type, u64 config)
247{ 277{
248 static char buf[32]; 278 static char buf[32];
249 279
@@ -294,7 +324,7 @@ char *__event_name(int type, u64 config)
294 return "unknown"; 324 return "unknown";
295} 325}
296 326
297static int parse_aliases(const char **str, char *names[][MAX_ALIASES], int size) 327static int parse_aliases(const char **str, const char *names[][MAX_ALIASES], int size)
298{ 328{
299 int i, j; 329 int i, j;
300 int n, longest = -1; 330 int n, longest = -1;
@@ -598,7 +628,7 @@ static void print_tracepoint_events(void)
598{ 628{
599 DIR *sys_dir, *evt_dir; 629 DIR *sys_dir, *evt_dir;
600 struct dirent *sys_next, *evt_next, sys_dirent, evt_dirent; 630 struct dirent *sys_next, *evt_next, sys_dirent, evt_dirent;
601 struct stat st; 631 int sys_dir_fd;
602 char evt_path[MAXPATHLEN]; 632 char evt_path[MAXPATHLEN];
603 633
604 if (valid_debugfs_mount(debugfs_path)) 634 if (valid_debugfs_mount(debugfs_path))
@@ -607,16 +637,23 @@ static void print_tracepoint_events(void)
607 sys_dir = opendir(debugfs_path); 637 sys_dir = opendir(debugfs_path);
608 if (!sys_dir) 638 if (!sys_dir)
609 goto cleanup; 639 goto cleanup;
610 640 sys_dir_fd = dirfd(sys_dir);
611 for_each_subsystem(sys_dir, sys_dirent, sys_next, evt_path, st) { 641
612 evt_dir = opendir(evt_path); 642 for_each_subsystem(sys_dir, sys_dirent, sys_next) {
613 if (!evt_dir) 643 int dfd = openat(sys_dir_fd, sys_dirent.d_name,
614 goto cleanup; 644 O_RDONLY|O_DIRECTORY), evt_dir_fd;
615 for_each_event(sys_dirent, evt_dir, evt_dirent, evt_next, 645 if (dfd == -1)
616 evt_path, st) { 646 continue;
647 evt_dir = fdopendir(dfd);
648 if (!evt_dir) {
649 close(dfd);
650 continue;
651 }
652 evt_dir_fd = dirfd(evt_dir);
653 for_each_event(sys_dirent, evt_dir, evt_dirent, evt_next) {
617 snprintf(evt_path, MAXPATHLEN, "%s:%s", 654 snprintf(evt_path, MAXPATHLEN, "%s:%s",
618 sys_dirent.d_name, evt_dirent.d_name); 655 sys_dirent.d_name, evt_dirent.d_name);
619 fprintf(stderr, " %-40s [%s]\n", evt_path, 656 fprintf(stderr, " %-42s [%s]\n", evt_path,
620 event_type_descriptors[PERF_TYPE_TRACEPOINT+1]); 657 event_type_descriptors[PERF_TYPE_TRACEPOINT+1]);
621 } 658 }
622 closedir(evt_dir); 659 closedir(evt_dir);
@@ -650,7 +687,7 @@ void print_events(void)
650 sprintf(name, "%s OR %s", syms->symbol, syms->alias); 687 sprintf(name, "%s OR %s", syms->symbol, syms->alias);
651 else 688 else
652 strcpy(name, syms->symbol); 689 strcpy(name, syms->symbol);
653 fprintf(stderr, " %-40s [%s]\n", name, 690 fprintf(stderr, " %-42s [%s]\n", name,
654 event_type_descriptors[type]); 691 event_type_descriptors[type]);
655 692
656 prev_type = type; 693 prev_type = type;
@@ -664,7 +701,7 @@ void print_events(void)
664 continue; 701 continue;
665 702
666 for (i = 0; i < PERF_COUNT_HW_CACHE_RESULT_MAX; i++) { 703 for (i = 0; i < PERF_COUNT_HW_CACHE_RESULT_MAX; i++) {
667 fprintf(stderr, " %-40s [%s]\n", 704 fprintf(stderr, " %-42s [%s]\n",
668 event_cache_name(type, op, i), 705 event_cache_name(type, op, i),
669 event_type_descriptors[4]); 706 event_type_descriptors[4]);
670 } 707 }
@@ -672,7 +709,7 @@ void print_events(void)
672 } 709 }
673 710
674 fprintf(stderr, "\n"); 711 fprintf(stderr, "\n");
675 fprintf(stderr, " %-40s [raw hardware event descriptor]\n", 712 fprintf(stderr, " %-42s [raw hardware event descriptor]\n",
676 "rNNN"); 713 "rNNN");
677 fprintf(stderr, "\n"); 714 fprintf(stderr, "\n");
678 715