aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--tools/include/linux/compiler-gcc.h3
-rw-r--r--tools/lib/api/fs/tracing_path.c40
-rw-r--r--tools/lib/api/fs/tracing_path.h9
-rw-r--r--tools/perf/Makefile.perf2
-rw-r--r--tools/perf/builtin-script.c26
-rw-r--r--tools/perf/builtin-top.c2
-rw-r--r--tools/perf/builtin-trace.c2
-rw-r--r--tools/perf/perf.c24
-rw-r--r--tools/perf/tests/parse-events.c9
-rwxr-xr-xtools/perf/tests/shell/record+probe_libc_inet_pton.sh12
-rw-r--r--tools/perf/ui/browsers/annotate.c8
-rw-r--r--tools/perf/util/annotate.c51
-rw-r--r--tools/perf/util/annotate.h11
-rw-r--r--tools/perf/util/config.c16
-rw-r--r--tools/perf/util/config.h1
-rw-r--r--tools/perf/util/env.c18
-rw-r--r--tools/perf/util/env.h2
-rw-r--r--tools/perf/util/evsel.c2
-rw-r--r--tools/perf/util/machine.c18
-rw-r--r--tools/perf/util/machine.h2
-rw-r--r--tools/perf/util/parse-events.c73
-rw-r--r--tools/perf/util/probe-file.c3
-rw-r--r--tools/perf/util/sort.c4
-rw-r--r--tools/perf/util/sort.h4
-rw-r--r--tools/perf/util/trace-event-info.c11
-rw-r--r--tools/perf/util/trace-event.c8
-rw-r--r--tools/perf/util/util.c34
-rw-r--r--tools/perf/util/util.h4
28 files changed, 279 insertions, 120 deletions
diff --git a/tools/include/linux/compiler-gcc.h b/tools/include/linux/compiler-gcc.h
index a3a4427441bf..70fe61295733 100644
--- a/tools/include/linux/compiler-gcc.h
+++ b/tools/include/linux/compiler-gcc.h
@@ -21,6 +21,9 @@
21/* &a[0] degrades to a pointer: a different type from an array */ 21/* &a[0] degrades to a pointer: a different type from an array */
22#define __must_be_array(a) BUILD_BUG_ON_ZERO(__same_type((a), &(a)[0])) 22#define __must_be_array(a) BUILD_BUG_ON_ZERO(__same_type((a), &(a)[0]))
23 23
24#ifndef __pure
25#define __pure __attribute__((pure))
26#endif
24#define noinline __attribute__((noinline)) 27#define noinline __attribute__((noinline))
25#ifndef __packed 28#ifndef __packed
26#define __packed __attribute__((packed)) 29#define __packed __attribute__((packed))
diff --git a/tools/lib/api/fs/tracing_path.c b/tools/lib/api/fs/tracing_path.c
index 7b7fd0b18551..120037496f77 100644
--- a/tools/lib/api/fs/tracing_path.c
+++ b/tools/lib/api/fs/tracing_path.c
@@ -13,11 +13,9 @@
13 13
14#include "tracing_path.h" 14#include "tracing_path.h"
15 15
16 16static char tracing_mnt[PATH_MAX] = "/sys/kernel/debug";
17char tracing_mnt[PATH_MAX] = "/sys/kernel/debug"; 17static char tracing_path[PATH_MAX] = "/sys/kernel/debug/tracing";
18char tracing_path[PATH_MAX] = "/sys/kernel/debug/tracing"; 18static char tracing_events_path[PATH_MAX] = "/sys/kernel/debug/tracing/events";
19char tracing_events_path[PATH_MAX] = "/sys/kernel/debug/tracing/events";
20
21 19
22static void __tracing_path_set(const char *tracing, const char *mountpoint) 20static void __tracing_path_set(const char *tracing, const char *mountpoint)
23{ 21{
@@ -76,7 +74,7 @@ char *get_tracing_file(const char *name)
76{ 74{
77 char *file; 75 char *file;
78 76
79 if (asprintf(&file, "%s/%s", tracing_path, name) < 0) 77 if (asprintf(&file, "%s/%s", tracing_path_mount(), name) < 0)
80 return NULL; 78 return NULL;
81 79
82 return file; 80 return file;
@@ -87,6 +85,34 @@ void put_tracing_file(char *file)
87 free(file); 85 free(file);
88} 86}
89 87
88char *get_events_file(const char *name)
89{
90 char *file;
91
92 if (asprintf(&file, "%s/events/%s", tracing_path_mount(), name) < 0)
93 return NULL;
94
95 return file;
96}
97
98void put_events_file(char *file)
99{
100 free(file);
101}
102
103DIR *tracing_events__opendir(void)
104{
105 DIR *dir = NULL;
106 char *path = get_tracing_file("events");
107
108 if (path) {
109 dir = opendir(path);
110 put_events_file(path);
111 }
112
113 return dir;
114}
115
90int tracing_path__strerror_open_tp(int err, char *buf, size_t size, 116int tracing_path__strerror_open_tp(int err, char *buf, size_t size,
91 const char *sys, const char *name) 117 const char *sys, const char *name)
92{ 118{
@@ -129,7 +155,7 @@ int tracing_path__strerror_open_tp(int err, char *buf, size_t size,
129 snprintf(buf, size, 155 snprintf(buf, size,
130 "Error:\tNo permissions to read %s/%s\n" 156 "Error:\tNo permissions to read %s/%s\n"
131 "Hint:\tTry 'sudo mount -o remount,mode=755 %s'\n", 157 "Hint:\tTry 'sudo mount -o remount,mode=755 %s'\n",
132 tracing_events_path, filename, tracing_mnt); 158 tracing_events_path, filename, tracing_path_mount());
133 } 159 }
134 break; 160 break;
135 default: 161 default:
diff --git a/tools/lib/api/fs/tracing_path.h b/tools/lib/api/fs/tracing_path.h
index 0066f06cc381..a19136b086dc 100644
--- a/tools/lib/api/fs/tracing_path.h
+++ b/tools/lib/api/fs/tracing_path.h
@@ -3,9 +3,9 @@
3#define __API_FS_TRACING_PATH_H 3#define __API_FS_TRACING_PATH_H
4 4
5#include <linux/types.h> 5#include <linux/types.h>
6#include <dirent.h>
6 7
7extern char tracing_path[]; 8DIR *tracing_events__opendir(void);
8extern char tracing_events_path[];
9 9
10void tracing_path_set(const char *mountpoint); 10void tracing_path_set(const char *mountpoint);
11const char *tracing_path_mount(void); 11const char *tracing_path_mount(void);
@@ -13,5 +13,10 @@ const char *tracing_path_mount(void);
13char *get_tracing_file(const char *name); 13char *get_tracing_file(const char *name);
14void put_tracing_file(char *file); 14void put_tracing_file(char *file);
15 15
16char *get_events_file(const char *name);
17void put_events_file(char *file);
18
19#define zput_events_file(ptr) ({ free(*ptr); *ptr = NULL; })
20
16int tracing_path__strerror_open_tp(int err, char *buf, size_t size, const char *sys, const char *name); 21int tracing_path__strerror_open_tp(int err, char *buf, size_t size, const char *sys, const char *name);
17#endif /* __API_FS_TRACING_PATH_H */ 22#endif /* __API_FS_TRACING_PATH_H */
diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf
index c63a3971d719..ecc9fc952655 100644
--- a/tools/perf/Makefile.perf
+++ b/tools/perf/Makefile.perf
@@ -770,9 +770,11 @@ endif
770ifndef NO_LIBBPF 770ifndef NO_LIBBPF
771 $(call QUIET_INSTALL, lib) \ 771 $(call QUIET_INSTALL, lib) \
772 $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(perf_include_instdir_SQ)/bpf' 772 $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(perf_include_instdir_SQ)/bpf'
773 $(call QUIET_INSTALL, include/bpf) \
773 $(INSTALL) include/bpf/*.h '$(DESTDIR_SQ)$(perf_include_instdir_SQ)/bpf' 774 $(INSTALL) include/bpf/*.h '$(DESTDIR_SQ)$(perf_include_instdir_SQ)/bpf'
774 $(call QUIET_INSTALL, lib) \ 775 $(call QUIET_INSTALL, lib) \
775 $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(perf_examples_instdir_SQ)/bpf' 776 $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(perf_examples_instdir_SQ)/bpf'
777 $(call QUIET_INSTALL, examples/bpf) \
776 $(INSTALL) examples/bpf/*.c '$(DESTDIR_SQ)$(perf_examples_instdir_SQ)/bpf' 778 $(INSTALL) examples/bpf/*.c '$(DESTDIR_SQ)$(perf_examples_instdir_SQ)/bpf'
777endif 779endif
778 $(call QUIET_INSTALL, perf-archive) \ 780 $(call QUIET_INSTALL, perf-archive) \
diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c
index fa2c7a288750..cefc8813e91e 100644
--- a/tools/perf/builtin-script.c
+++ b/tools/perf/builtin-script.c
@@ -153,8 +153,8 @@ static struct {
153 .fields = PERF_OUTPUT_COMM | PERF_OUTPUT_TID | 153 .fields = PERF_OUTPUT_COMM | PERF_OUTPUT_TID |
154 PERF_OUTPUT_CPU | PERF_OUTPUT_TIME | 154 PERF_OUTPUT_CPU | PERF_OUTPUT_TIME |
155 PERF_OUTPUT_EVNAME | PERF_OUTPUT_IP | 155 PERF_OUTPUT_EVNAME | PERF_OUTPUT_IP |
156 PERF_OUTPUT_SYM | PERF_OUTPUT_DSO | 156 PERF_OUTPUT_SYM | PERF_OUTPUT_SYMOFFSET |
157 PERF_OUTPUT_PERIOD, 157 PERF_OUTPUT_DSO | PERF_OUTPUT_PERIOD,
158 158
159 .invalid_fields = PERF_OUTPUT_TRACE | PERF_OUTPUT_BPF_OUTPUT, 159 .invalid_fields = PERF_OUTPUT_TRACE | PERF_OUTPUT_BPF_OUTPUT,
160 }, 160 },
@@ -165,8 +165,9 @@ static struct {
165 .fields = PERF_OUTPUT_COMM | PERF_OUTPUT_TID | 165 .fields = PERF_OUTPUT_COMM | PERF_OUTPUT_TID |
166 PERF_OUTPUT_CPU | PERF_OUTPUT_TIME | 166 PERF_OUTPUT_CPU | PERF_OUTPUT_TIME |
167 PERF_OUTPUT_EVNAME | PERF_OUTPUT_IP | 167 PERF_OUTPUT_EVNAME | PERF_OUTPUT_IP |
168 PERF_OUTPUT_SYM | PERF_OUTPUT_DSO | 168 PERF_OUTPUT_SYM | PERF_OUTPUT_SYMOFFSET |
169 PERF_OUTPUT_PERIOD | PERF_OUTPUT_BPF_OUTPUT, 169 PERF_OUTPUT_DSO | PERF_OUTPUT_PERIOD |
170 PERF_OUTPUT_BPF_OUTPUT,
170 171
171 .invalid_fields = PERF_OUTPUT_TRACE, 172 .invalid_fields = PERF_OUTPUT_TRACE,
172 }, 173 },
@@ -185,10 +186,10 @@ static struct {
185 .fields = PERF_OUTPUT_COMM | PERF_OUTPUT_TID | 186 .fields = PERF_OUTPUT_COMM | PERF_OUTPUT_TID |
186 PERF_OUTPUT_CPU | PERF_OUTPUT_TIME | 187 PERF_OUTPUT_CPU | PERF_OUTPUT_TIME |
187 PERF_OUTPUT_EVNAME | PERF_OUTPUT_IP | 188 PERF_OUTPUT_EVNAME | PERF_OUTPUT_IP |
188 PERF_OUTPUT_SYM | PERF_OUTPUT_DSO | 189 PERF_OUTPUT_SYM | PERF_OUTPUT_SYMOFFSET |
189 PERF_OUTPUT_PERIOD | PERF_OUTPUT_ADDR | 190 PERF_OUTPUT_DSO | PERF_OUTPUT_PERIOD |
190 PERF_OUTPUT_DATA_SRC | PERF_OUTPUT_WEIGHT | 191 PERF_OUTPUT_ADDR | PERF_OUTPUT_DATA_SRC |
191 PERF_OUTPUT_PHYS_ADDR, 192 PERF_OUTPUT_WEIGHT | PERF_OUTPUT_PHYS_ADDR,
192 193
193 .invalid_fields = PERF_OUTPUT_TRACE | PERF_OUTPUT_BPF_OUTPUT, 194 .invalid_fields = PERF_OUTPUT_TRACE | PERF_OUTPUT_BPF_OUTPUT,
194 }, 195 },
@@ -199,8 +200,8 @@ static struct {
199 .fields = PERF_OUTPUT_COMM | PERF_OUTPUT_TID | 200 .fields = PERF_OUTPUT_COMM | PERF_OUTPUT_TID |
200 PERF_OUTPUT_CPU | PERF_OUTPUT_TIME | 201 PERF_OUTPUT_CPU | PERF_OUTPUT_TIME |
201 PERF_OUTPUT_EVNAME | PERF_OUTPUT_IP | 202 PERF_OUTPUT_EVNAME | PERF_OUTPUT_IP |
202 PERF_OUTPUT_SYM | PERF_OUTPUT_DSO | 203 PERF_OUTPUT_SYM | PERF_OUTPUT_SYMOFFSET |
203 PERF_OUTPUT_PERIOD, 204 PERF_OUTPUT_DSO | PERF_OUTPUT_PERIOD,
204 205
205 .invalid_fields = PERF_OUTPUT_TRACE | PERF_OUTPUT_BPF_OUTPUT, 206 .invalid_fields = PERF_OUTPUT_TRACE | PERF_OUTPUT_BPF_OUTPUT,
206 }, 207 },
@@ -211,8 +212,8 @@ static struct {
211 .fields = PERF_OUTPUT_COMM | PERF_OUTPUT_TID | 212 .fields = PERF_OUTPUT_COMM | PERF_OUTPUT_TID |
212 PERF_OUTPUT_CPU | PERF_OUTPUT_TIME | 213 PERF_OUTPUT_CPU | PERF_OUTPUT_TIME |
213 PERF_OUTPUT_EVNAME | PERF_OUTPUT_IP | 214 PERF_OUTPUT_EVNAME | PERF_OUTPUT_IP |
214 PERF_OUTPUT_SYM | PERF_OUTPUT_DSO | 215 PERF_OUTPUT_SYM | PERF_OUTPUT_SYMOFFSET |
215 PERF_OUTPUT_SYNTH, 216 PERF_OUTPUT_DSO | PERF_OUTPUT_SYNTH,
216 217
217 .invalid_fields = PERF_OUTPUT_TRACE | PERF_OUTPUT_BPF_OUTPUT, 218 .invalid_fields = PERF_OUTPUT_TRACE | PERF_OUTPUT_BPF_OUTPUT,
218 }, 219 },
@@ -544,6 +545,7 @@ static int perf_session__check_output_opt(struct perf_session *session)
544 if (attr->sample_type & PERF_SAMPLE_CALLCHAIN) { 545 if (attr->sample_type & PERF_SAMPLE_CALLCHAIN) {
545 output[j].fields |= PERF_OUTPUT_IP; 546 output[j].fields |= PERF_OUTPUT_IP;
546 output[j].fields |= PERF_OUTPUT_SYM; 547 output[j].fields |= PERF_OUTPUT_SYM;
548 output[j].fields |= PERF_OUTPUT_SYMOFFSET;
547 output[j].fields |= PERF_OUTPUT_DSO; 549 output[j].fields |= PERF_OUTPUT_DSO;
548 set_print_ip_opts(attr); 550 set_print_ip_opts(attr);
549 goto out; 551 goto out;
diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c
index 3c061c57afb6..7a349fcd3864 100644
--- a/tools/perf/builtin-top.c
+++ b/tools/perf/builtin-top.c
@@ -1264,7 +1264,7 @@ int cmd_top(int argc, const char **argv)
1264 .proc_map_timeout = 500, 1264 .proc_map_timeout = 500,
1265 .overwrite = 1, 1265 .overwrite = 1,
1266 }, 1266 },
1267 .max_stack = sysctl_perf_event_max_stack, 1267 .max_stack = sysctl__max_stack(),
1268 .sym_pcnt_filter = 5, 1268 .sym_pcnt_filter = 5,
1269 .nr_threads_synthesize = UINT_MAX, 1269 .nr_threads_synthesize = UINT_MAX,
1270 }; 1270 };
diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c
index c7effcfc40ed..560aed7da36a 100644
--- a/tools/perf/builtin-trace.c
+++ b/tools/perf/builtin-trace.c
@@ -3162,7 +3162,7 @@ int cmd_trace(int argc, const char **argv)
3162 mmap_pages_user_set = false; 3162 mmap_pages_user_set = false;
3163 3163
3164 if (trace.max_stack == UINT_MAX) { 3164 if (trace.max_stack == UINT_MAX) {
3165 trace.max_stack = input_name ? PERF_MAX_STACK_DEPTH : sysctl_perf_event_max_stack; 3165 trace.max_stack = input_name ? PERF_MAX_STACK_DEPTH : sysctl__max_stack();
3166 max_stack_user_set = false; 3166 max_stack_user_set = false;
3167 } 3167 }
3168 3168
diff --git a/tools/perf/perf.c b/tools/perf/perf.c
index 20a08cb32332..51c81509a315 100644
--- a/tools/perf/perf.c
+++ b/tools/perf/perf.c
@@ -238,7 +238,7 @@ static int handle_options(const char ***argv, int *argc, int *envchanged)
238 (*argc)--; 238 (*argc)--;
239 } else if (strstarts(cmd, CMD_DEBUGFS_DIR)) { 239 } else if (strstarts(cmd, CMD_DEBUGFS_DIR)) {
240 tracing_path_set(cmd + strlen(CMD_DEBUGFS_DIR)); 240 tracing_path_set(cmd + strlen(CMD_DEBUGFS_DIR));
241 fprintf(stderr, "dir: %s\n", tracing_path); 241 fprintf(stderr, "dir: %s\n", tracing_path_mount());
242 if (envchanged) 242 if (envchanged)
243 *envchanged = 1; 243 *envchanged = 1;
244 } else if (!strcmp(cmd, "--list-cmds")) { 244 } else if (!strcmp(cmd, "--list-cmds")) {
@@ -421,22 +421,11 @@ void pthread__unblock_sigwinch(void)
421 pthread_sigmask(SIG_UNBLOCK, &set, NULL); 421 pthread_sigmask(SIG_UNBLOCK, &set, NULL);
422} 422}
423 423
424#ifdef _SC_LEVEL1_DCACHE_LINESIZE
425#define cache_line_size(cacheline_sizep) *cacheline_sizep = sysconf(_SC_LEVEL1_DCACHE_LINESIZE)
426#else
427static void cache_line_size(int *cacheline_sizep)
428{
429 if (sysfs__read_int("devices/system/cpu/cpu0/cache/index0/coherency_line_size", cacheline_sizep))
430 pr_debug("cannot determine cache line size");
431}
432#endif
433
434int main(int argc, const char **argv) 424int main(int argc, const char **argv)
435{ 425{
436 int err; 426 int err;
437 const char *cmd; 427 const char *cmd;
438 char sbuf[STRERR_BUFSIZE]; 428 char sbuf[STRERR_BUFSIZE];
439 int value;
440 429
441 /* libsubcmd init */ 430 /* libsubcmd init */
442 exec_cmd_init("perf", PREFIX, PERF_EXEC_PATH, EXEC_PATH_ENVIRONMENT); 431 exec_cmd_init("perf", PREFIX, PERF_EXEC_PATH, EXEC_PATH_ENVIRONMENT);
@@ -444,13 +433,6 @@ int main(int argc, const char **argv)
444 433
445 /* The page_size is placed in util object. */ 434 /* The page_size is placed in util object. */
446 page_size = sysconf(_SC_PAGE_SIZE); 435 page_size = sysconf(_SC_PAGE_SIZE);
447 cache_line_size(&cacheline_size);
448
449 if (sysctl__read_int("kernel/perf_event_max_stack", &value) == 0)
450 sysctl_perf_event_max_stack = value;
451
452 if (sysctl__read_int("kernel/perf_event_max_contexts_per_stack", &value) == 0)
453 sysctl_perf_event_max_contexts_per_stack = value;
454 436
455 cmd = extract_argv0_path(argv[0]); 437 cmd = extract_argv0_path(argv[0]);
456 if (!cmd) 438 if (!cmd)
@@ -458,15 +440,11 @@ int main(int argc, const char **argv)
458 440
459 srandom(time(NULL)); 441 srandom(time(NULL));
460 442
461 perf_config__init();
462 err = perf_config(perf_default_config, NULL); 443 err = perf_config(perf_default_config, NULL);
463 if (err) 444 if (err)
464 return err; 445 return err;
465 set_buildid_dir(NULL); 446 set_buildid_dir(NULL);
466 447
467 /* get debugfs/tracefs mount point from /proc/mounts */
468 tracing_path_mount();
469
470 /* 448 /*
471 * "perf-xxxx" is the same as "perf xxxx", but we obviously: 449 * "perf-xxxx" is the same as "perf xxxx", but we obviously:
472 * 450 *
diff --git a/tools/perf/tests/parse-events.c b/tools/perf/tests/parse-events.c
index 6829dd416a99..b9ebe15afb13 100644
--- a/tools/perf/tests/parse-events.c
+++ b/tools/perf/tests/parse-events.c
@@ -1323,12 +1323,12 @@ static int count_tracepoints(void)
1323 DIR *events_dir; 1323 DIR *events_dir;
1324 int cnt = 0; 1324 int cnt = 0;
1325 1325
1326 events_dir = opendir(tracing_events_path); 1326 events_dir = tracing_events__opendir();
1327 1327
1328 TEST_ASSERT_VAL("Can't open events dir", events_dir); 1328 TEST_ASSERT_VAL("Can't open events dir", events_dir);
1329 1329
1330 while ((events_ent = readdir(events_dir))) { 1330 while ((events_ent = readdir(events_dir))) {
1331 char sys_path[PATH_MAX]; 1331 char *sys_path;
1332 struct dirent *sys_ent; 1332 struct dirent *sys_ent;
1333 DIR *sys_dir; 1333 DIR *sys_dir;
1334 1334
@@ -1339,8 +1339,8 @@ static int count_tracepoints(void)
1339 || !strcmp(events_ent->d_name, "header_page")) 1339 || !strcmp(events_ent->d_name, "header_page"))
1340 continue; 1340 continue;
1341 1341
1342 scnprintf(sys_path, PATH_MAX, "%s/%s", 1342 sys_path = get_events_file(events_ent->d_name);
1343 tracing_events_path, events_ent->d_name); 1343 TEST_ASSERT_VAL("Can't get sys path", sys_path);
1344 1344
1345 sys_dir = opendir(sys_path); 1345 sys_dir = opendir(sys_path);
1346 TEST_ASSERT_VAL("Can't open sys dir", sys_dir); 1346 TEST_ASSERT_VAL("Can't open sys dir", sys_dir);
@@ -1356,6 +1356,7 @@ static int count_tracepoints(void)
1356 } 1356 }
1357 1357
1358 closedir(sys_dir); 1358 closedir(sys_dir);
1359 put_events_file(sys_path);
1359 } 1360 }
1360 1361
1361 closedir(events_dir); 1362 closedir(events_dir);
diff --git a/tools/perf/tests/shell/record+probe_libc_inet_pton.sh b/tools/perf/tests/shell/record+probe_libc_inet_pton.sh
index ee86473643be..650b208f700f 100755
--- a/tools/perf/tests/shell/record+probe_libc_inet_pton.sh
+++ b/tools/perf/tests/shell/record+probe_libc_inet_pton.sh
@@ -16,18 +16,18 @@ nm -g $libc 2>/dev/null | fgrep -q inet_pton || exit 254
16trace_libc_inet_pton_backtrace() { 16trace_libc_inet_pton_backtrace() {
17 idx=0 17 idx=0
18 expected[0]="ping[][0-9 \.:]+probe_libc:inet_pton: \([[:xdigit:]]+\)" 18 expected[0]="ping[][0-9 \.:]+probe_libc:inet_pton: \([[:xdigit:]]+\)"
19 expected[1]=".*inet_pton[[:space:]]\($libc|inlined\)$" 19 expected[1]=".*inet_pton\+0x[[:xdigit:]]+[[:space:]]\($libc|inlined\)$"
20 case "$(uname -m)" in 20 case "$(uname -m)" in
21 s390x) 21 s390x)
22 eventattr='call-graph=dwarf,max-stack=4' 22 eventattr='call-graph=dwarf,max-stack=4'
23 expected[2]="gaih_inet.*[[:space:]]\($libc|inlined\)$" 23 expected[2]="gaih_inet.*\+0x[[:xdigit:]]+[[:space:]]\($libc|inlined\)$"
24 expected[3]="(__GI_)?getaddrinfo[[:space:]]\($libc|inlined\)$" 24 expected[3]="(__GI_)?getaddrinfo\+0x[[:xdigit:]]+[[:space:]]\($libc|inlined\)$"
25 expected[4]="main[[:space:]]\(.*/bin/ping.*\)$" 25 expected[4]="main\+0x[[:xdigit:]]+[[:space:]]\(.*/bin/ping.*\)$"
26 ;; 26 ;;
27 *) 27 *)
28 eventattr='max-stack=3' 28 eventattr='max-stack=3'
29 expected[2]="getaddrinfo[[:space:]]\($libc\)$" 29 expected[2]="getaddrinfo\+0x[[:xdigit:]]+[[:space:]]\($libc\)$"
30 expected[3]=".*\(.*/bin/ping.*\)$" 30 expected[3]=".*\+0x[[:xdigit:]]+[[:space:]]\(.*/bin/ping.*\)$"
31 ;; 31 ;;
32 esac 32 esac
33 33
diff --git a/tools/perf/ui/browsers/annotate.c b/tools/perf/ui/browsers/annotate.c
index 3781d74088a7..8be40fa903aa 100644
--- a/tools/perf/ui/browsers/annotate.c
+++ b/tools/perf/ui/browsers/annotate.c
@@ -695,6 +695,7 @@ static int annotate_browser__run(struct annotate_browser *browser,
695 "O Bump offset level (jump targets -> +call -> all -> cycle thru)\n" 695 "O Bump offset level (jump targets -> +call -> all -> cycle thru)\n"
696 "s Toggle source code view\n" 696 "s Toggle source code view\n"
697 "t Circulate percent, total period, samples view\n" 697 "t Circulate percent, total period, samples view\n"
698 "c Show min/max cycle\n"
698 "/ Search string\n" 699 "/ Search string\n"
699 "k Toggle line numbers\n" 700 "k Toggle line numbers\n"
700 "P Print to [symbol_name].annotation file.\n" 701 "P Print to [symbol_name].annotation file.\n"
@@ -791,6 +792,13 @@ show_sup_ins:
791 notes->options->show_total_period = true; 792 notes->options->show_total_period = true;
792 annotation__update_column_widths(notes); 793 annotation__update_column_widths(notes);
793 continue; 794 continue;
795 case 'c':
796 if (notes->options->show_minmax_cycle)
797 notes->options->show_minmax_cycle = false;
798 else
799 notes->options->show_minmax_cycle = true;
800 annotation__update_column_widths(notes);
801 continue;
794 case K_LEFT: 802 case K_LEFT:
795 case K_ESC: 803 case K_ESC:
796 case 'q': 804 case 'q':
diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c
index 5d74a30fe00f..6612c7f90af4 100644
--- a/tools/perf/util/annotate.c
+++ b/tools/perf/util/annotate.c
@@ -760,6 +760,15 @@ static int __symbol__account_cycles(struct annotation *notes,
760 ch[offset].num_aggr++; 760 ch[offset].num_aggr++;
761 ch[offset].cycles_aggr += cycles; 761 ch[offset].cycles_aggr += cycles;
762 762
763 if (cycles > ch[offset].cycles_max)
764 ch[offset].cycles_max = cycles;
765
766 if (ch[offset].cycles_min) {
767 if (cycles && cycles < ch[offset].cycles_min)
768 ch[offset].cycles_min = cycles;
769 } else
770 ch[offset].cycles_min = cycles;
771
763 if (!have_start && ch[offset].have_start) 772 if (!have_start && ch[offset].have_start)
764 return 0; 773 return 0;
765 if (ch[offset].num) { 774 if (ch[offset].num) {
@@ -953,8 +962,11 @@ void annotation__compute_ipc(struct annotation *notes, size_t size)
953 if (ch->have_start) 962 if (ch->have_start)
954 annotation__count_and_fill(notes, ch->start, offset, ch); 963 annotation__count_and_fill(notes, ch->start, offset, ch);
955 al = notes->offsets[offset]; 964 al = notes->offsets[offset];
956 if (al && ch->num_aggr) 965 if (al && ch->num_aggr) {
957 al->cycles = ch->cycles_aggr / ch->num_aggr; 966 al->cycles = ch->cycles_aggr / ch->num_aggr;
967 al->cycles_max = ch->cycles_max;
968 al->cycles_min = ch->cycles_min;
969 }
958 notes->have_cycles = true; 970 notes->have_cycles = true;
959 } 971 }
960 } 972 }
@@ -2486,13 +2498,38 @@ static void __annotation_line__write(struct annotation_line *al, struct annotati
2486 else 2498 else
2487 obj__printf(obj, "%*s ", ANNOTATION__IPC_WIDTH - 1, "IPC"); 2499 obj__printf(obj, "%*s ", ANNOTATION__IPC_WIDTH - 1, "IPC");
2488 2500
2489 if (al->cycles) 2501 if (!notes->options->show_minmax_cycle) {
2490 obj__printf(obj, "%*" PRIu64 " ", 2502 if (al->cycles)
2503 obj__printf(obj, "%*" PRIu64 " ",
2491 ANNOTATION__CYCLES_WIDTH - 1, al->cycles); 2504 ANNOTATION__CYCLES_WIDTH - 1, al->cycles);
2492 else if (!show_title) 2505 else if (!show_title)
2493 obj__printf(obj, "%*s", ANNOTATION__CYCLES_WIDTH, " "); 2506 obj__printf(obj, "%*s",
2494 else 2507 ANNOTATION__CYCLES_WIDTH, " ");
2495 obj__printf(obj, "%*s ", ANNOTATION__CYCLES_WIDTH - 1, "Cycle"); 2508 else
2509 obj__printf(obj, "%*s ",
2510 ANNOTATION__CYCLES_WIDTH - 1,
2511 "Cycle");
2512 } else {
2513 if (al->cycles) {
2514 char str[32];
2515
2516 scnprintf(str, sizeof(str),
2517 "%" PRIu64 "(%" PRIu64 "/%" PRIu64 ")",
2518 al->cycles, al->cycles_min,
2519 al->cycles_max);
2520
2521 obj__printf(obj, "%*s ",
2522 ANNOTATION__MINMAX_CYCLES_WIDTH - 1,
2523 str);
2524 } else if (!show_title)
2525 obj__printf(obj, "%*s",
2526 ANNOTATION__MINMAX_CYCLES_WIDTH,
2527 " ");
2528 else
2529 obj__printf(obj, "%*s ",
2530 ANNOTATION__MINMAX_CYCLES_WIDTH - 1,
2531 "Cycle(min/max)");
2532 }
2496 } 2533 }
2497 2534
2498 obj__printf(obj, " "); 2535 obj__printf(obj, " ");
diff --git a/tools/perf/util/annotate.h b/tools/perf/util/annotate.h
index f28a9e43421d..5080b6dd98b8 100644
--- a/tools/perf/util/annotate.h
+++ b/tools/perf/util/annotate.h
@@ -61,6 +61,7 @@ bool ins__is_fused(struct arch *arch, const char *ins1, const char *ins2);
61 61
62#define ANNOTATION__IPC_WIDTH 6 62#define ANNOTATION__IPC_WIDTH 6
63#define ANNOTATION__CYCLES_WIDTH 6 63#define ANNOTATION__CYCLES_WIDTH 6
64#define ANNOTATION__MINMAX_CYCLES_WIDTH 19
64 65
65struct annotation_options { 66struct annotation_options {
66 bool hide_src_code, 67 bool hide_src_code,
@@ -69,7 +70,8 @@ struct annotation_options {
69 show_linenr, 70 show_linenr,
70 show_nr_jumps, 71 show_nr_jumps,
71 show_nr_samples, 72 show_nr_samples,
72 show_total_period; 73 show_total_period,
74 show_minmax_cycle;
73 u8 offset_level; 75 u8 offset_level;
74}; 76};
75 77
@@ -105,6 +107,8 @@ struct annotation_line {
105 int jump_sources; 107 int jump_sources;
106 float ipc; 108 float ipc;
107 u64 cycles; 109 u64 cycles;
110 u64 cycles_max;
111 u64 cycles_min;
108 size_t privsize; 112 size_t privsize;
109 char *path; 113 char *path;
110 u32 idx; 114 u32 idx;
@@ -186,6 +190,8 @@ struct cyc_hist {
186 u64 start; 190 u64 start;
187 u64 cycles; 191 u64 cycles;
188 u64 cycles_aggr; 192 u64 cycles_aggr;
193 u64 cycles_max;
194 u64 cycles_min;
189 u32 num; 195 u32 num;
190 u32 num_aggr; 196 u32 num_aggr;
191 u8 have_start; 197 u8 have_start;
@@ -239,6 +245,9 @@ struct annotation {
239 245
240static inline int annotation__cycles_width(struct annotation *notes) 246static inline int annotation__cycles_width(struct annotation *notes)
241{ 247{
248 if (notes->have_cycles && notes->options->show_minmax_cycle)
249 return ANNOTATION__IPC_WIDTH + ANNOTATION__MINMAX_CYCLES_WIDTH;
250
242 return notes->have_cycles ? ANNOTATION__IPC_WIDTH + ANNOTATION__CYCLES_WIDTH : 0; 251 return notes->have_cycles ? ANNOTATION__IPC_WIDTH + ANNOTATION__CYCLES_WIDTH : 0;
243} 252}
244 253
diff --git a/tools/perf/util/config.c b/tools/perf/util/config.c
index 84eb9393c7db..5ac157056cdf 100644
--- a/tools/perf/util/config.c
+++ b/tools/perf/util/config.c
@@ -707,6 +707,14 @@ struct perf_config_set *perf_config_set__new(void)
707 return set; 707 return set;
708} 708}
709 709
710static int perf_config__init(void)
711{
712 if (config_set == NULL)
713 config_set = perf_config_set__new();
714
715 return config_set == NULL;
716}
717
710int perf_config(config_fn_t fn, void *data) 718int perf_config(config_fn_t fn, void *data)
711{ 719{
712 int ret = 0; 720 int ret = 0;
@@ -714,7 +722,7 @@ int perf_config(config_fn_t fn, void *data)
714 struct perf_config_section *section; 722 struct perf_config_section *section;
715 struct perf_config_item *item; 723 struct perf_config_item *item;
716 724
717 if (config_set == NULL) 725 if (config_set == NULL && perf_config__init())
718 return -1; 726 return -1;
719 727
720 perf_config_set__for_each_entry(config_set, section, item) { 728 perf_config_set__for_each_entry(config_set, section, item) {
@@ -735,12 +743,6 @@ int perf_config(config_fn_t fn, void *data)
735 return ret; 743 return ret;
736} 744}
737 745
738void perf_config__init(void)
739{
740 if (config_set == NULL)
741 config_set = perf_config_set__new();
742}
743
744void perf_config__exit(void) 746void perf_config__exit(void)
745{ 747{
746 perf_config_set__delete(config_set); 748 perf_config_set__delete(config_set);
diff --git a/tools/perf/util/config.h b/tools/perf/util/config.h
index baf82bf227ac..bd0a5897c76a 100644
--- a/tools/perf/util/config.h
+++ b/tools/perf/util/config.h
@@ -38,7 +38,6 @@ struct perf_config_set *perf_config_set__new(void);
38void perf_config_set__delete(struct perf_config_set *set); 38void perf_config_set__delete(struct perf_config_set *set);
39int perf_config_set__collect(struct perf_config_set *set, const char *file_name, 39int perf_config_set__collect(struct perf_config_set *set, const char *file_name,
40 const char *var, const char *value); 40 const char *var, const char *value);
41void perf_config__init(void);
42void perf_config__exit(void); 41void perf_config__exit(void);
43void perf_config__refresh(void); 42void perf_config__refresh(void);
44 43
diff --git a/tools/perf/util/env.c b/tools/perf/util/env.c
index 4c842762e3f2..319fb0a0d05e 100644
--- a/tools/perf/util/env.c
+++ b/tools/perf/util/env.c
@@ -93,6 +93,24 @@ int perf_env__read_cpu_topology_map(struct perf_env *env)
93 return 0; 93 return 0;
94} 94}
95 95
96static int perf_env__read_arch(struct perf_env *env)
97{
98 struct utsname uts;
99
100 if (env->arch)
101 return 0;
102
103 if (!uname(&uts))
104 env->arch = strdup(uts.machine);
105
106 return env->arch ? 0 : -ENOMEM;
107}
108
109const char *perf_env__raw_arch(struct perf_env *env)
110{
111 return env && !perf_env__read_arch(env) ? env->arch : "unknown";
112}
113
96void cpu_cache_level__free(struct cpu_cache_level *cache) 114void cpu_cache_level__free(struct cpu_cache_level *cache)
97{ 115{
98 free(cache->type); 116 free(cache->type);
diff --git a/tools/perf/util/env.h b/tools/perf/util/env.h
index c4ef2e523367..62e193948608 100644
--- a/tools/perf/util/env.h
+++ b/tools/perf/util/env.h
@@ -76,4 +76,6 @@ int perf_env__read_cpu_topology_map(struct perf_env *env);
76void cpu_cache_level__free(struct cpu_cache_level *cache); 76void cpu_cache_level__free(struct cpu_cache_level *cache);
77 77
78const char *perf_env__arch(struct perf_env *env); 78const char *perf_env__arch(struct perf_env *env);
79const char *perf_env__raw_arch(struct perf_env *env);
80
79#endif /* __PERF_ENV_H */ 81#endif /* __PERF_ENV_H */
diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c
index 4cd2cf93f726..150db5ed7400 100644
--- a/tools/perf/util/evsel.c
+++ b/tools/perf/util/evsel.c
@@ -2862,7 +2862,7 @@ int perf_evsel__open_strerror(struct perf_evsel *evsel, struct target *target,
2862 return scnprintf(msg, size, 2862 return scnprintf(msg, size,
2863 "Not enough memory to setup event with callchain.\n" 2863 "Not enough memory to setup event with callchain.\n"
2864 "Hint: Try tweaking /proc/sys/kernel/perf_event_max_stack\n" 2864 "Hint: Try tweaking /proc/sys/kernel/perf_event_max_stack\n"
2865 "Hint: Current value: %d", sysctl_perf_event_max_stack); 2865 "Hint: Current value: %d", sysctl__max_stack());
2866 break; 2866 break;
2867 case ENODEV: 2867 case ENODEV:
2868 if (target->cpu_list) 2868 if (target->cpu_list)
diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c
index 72a351613d85..e011a7160380 100644
--- a/tools/perf/util/machine.c
+++ b/tools/perf/util/machine.c
@@ -1764,7 +1764,7 @@ static int add_callchain_ip(struct thread *thread,
1764 } 1764 }
1765 1765
1766 srcline = callchain_srcline(al.map, al.sym, al.addr); 1766 srcline = callchain_srcline(al.map, al.sym, al.addr);
1767 return callchain_cursor_append(cursor, al.addr, al.map, al.sym, 1767 return callchain_cursor_append(cursor, ip, al.map, al.sym,
1768 branch, flags, nr_loop_iter, 1768 branch, flags, nr_loop_iter,
1769 iter_cycles, branch_from, srcline); 1769 iter_cycles, branch_from, srcline);
1770} 1770}
@@ -2296,6 +2296,15 @@ int machine__set_current_tid(struct machine *machine, int cpu, pid_t pid,
2296 return 0; 2296 return 0;
2297} 2297}
2298 2298
2299/*
2300 * Compares the raw arch string. N.B. see instead perf_env__arch() if a
2301 * normalized arch is needed.
2302 */
2303bool machine__is(struct machine *machine, const char *arch)
2304{
2305 return machine && !strcmp(perf_env__raw_arch(machine->env), arch);
2306}
2307
2299int machine__get_kernel_start(struct machine *machine) 2308int machine__get_kernel_start(struct machine *machine)
2300{ 2309{
2301 struct map *map = machine__kernel_map(machine); 2310 struct map *map = machine__kernel_map(machine);
@@ -2312,7 +2321,12 @@ int machine__get_kernel_start(struct machine *machine)
2312 machine->kernel_start = 1ULL << 63; 2321 machine->kernel_start = 1ULL << 63;
2313 if (map) { 2322 if (map) {
2314 err = map__load(map); 2323 err = map__load(map);
2315 if (!err) 2324 /*
2325 * On x86_64, PTI entry trampolines are less than the
2326 * start of kernel text, but still above 2^63. So leave
2327 * kernel_start = 1ULL << 63 for x86_64.
2328 */
2329 if (!err && !machine__is(machine, "x86_64"))
2316 machine->kernel_start = map->start; 2330 machine->kernel_start = map->start;
2317 } 2331 }
2318 return err; 2332 return err;
diff --git a/tools/perf/util/machine.h b/tools/perf/util/machine.h
index 388fb4741c54..b31d33b5aa2a 100644
--- a/tools/perf/util/machine.h
+++ b/tools/perf/util/machine.h
@@ -188,6 +188,8 @@ static inline bool machine__is_host(struct machine *machine)
188 return machine ? machine->pid == HOST_KERNEL_ID : false; 188 return machine ? machine->pid == HOST_KERNEL_ID : false;
189} 189}
190 190
191bool machine__is(struct machine *machine, const char *arch);
192
191struct thread *__machine__findnew_thread(struct machine *machine, pid_t pid, pid_t tid); 193struct thread *__machine__findnew_thread(struct machine *machine, pid_t pid, pid_t tid);
192struct thread *machine__findnew_thread(struct machine *machine, pid_t pid, pid_t tid); 194struct thread *machine__findnew_thread(struct machine *machine, pid_t pid, pid_t tid);
193 195
diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c
index 2fc4ee8b86c1..15eec49e71a1 100644
--- a/tools/perf/util/parse-events.c
+++ b/tools/perf/util/parse-events.c
@@ -156,13 +156,12 @@ struct event_symbol event_symbols_sw[PERF_COUNT_SW_MAX] = {
156 (strcmp(sys_dirent->d_name, ".")) && \ 156 (strcmp(sys_dirent->d_name, ".")) && \
157 (strcmp(sys_dirent->d_name, ".."))) 157 (strcmp(sys_dirent->d_name, "..")))
158 158
159static int tp_event_has_id(struct dirent *sys_dir, struct dirent *evt_dir) 159static int tp_event_has_id(const char *dir_path, struct dirent *evt_dir)
160{ 160{
161 char evt_path[MAXPATHLEN]; 161 char evt_path[MAXPATHLEN];
162 int fd; 162 int fd;
163 163
164 snprintf(evt_path, MAXPATHLEN, "%s/%s/%s/id", tracing_events_path, 164 snprintf(evt_path, MAXPATHLEN, "%s/%s/id", dir_path, evt_dir->d_name);
165 sys_dir->d_name, evt_dir->d_name);
166 fd = open(evt_path, O_RDONLY); 165 fd = open(evt_path, O_RDONLY);
167 if (fd < 0) 166 if (fd < 0)
168 return -EINVAL; 167 return -EINVAL;
@@ -171,12 +170,12 @@ static int tp_event_has_id(struct dirent *sys_dir, struct dirent *evt_dir)
171 return 0; 170 return 0;
172} 171}
173 172
174#define for_each_event(sys_dirent, evt_dir, evt_dirent) \ 173#define for_each_event(dir_path, evt_dir, evt_dirent) \
175 while ((evt_dirent = readdir(evt_dir)) != NULL) \ 174 while ((evt_dirent = readdir(evt_dir)) != NULL) \
176 if (evt_dirent->d_type == DT_DIR && \ 175 if (evt_dirent->d_type == DT_DIR && \
177 (strcmp(evt_dirent->d_name, ".")) && \ 176 (strcmp(evt_dirent->d_name, ".")) && \
178 (strcmp(evt_dirent->d_name, "..")) && \ 177 (strcmp(evt_dirent->d_name, "..")) && \
179 (!tp_event_has_id(sys_dirent, evt_dirent))) 178 (!tp_event_has_id(dir_path, evt_dirent)))
180 179
181#define MAX_EVENT_LENGTH 512 180#define MAX_EVENT_LENGTH 512
182 181
@@ -190,21 +189,21 @@ struct tracepoint_path *tracepoint_id_to_path(u64 config)
190 int fd; 189 int fd;
191 u64 id; 190 u64 id;
192 char evt_path[MAXPATHLEN]; 191 char evt_path[MAXPATHLEN];
193 char dir_path[MAXPATHLEN]; 192 char *dir_path;
194 193
195 sys_dir = opendir(tracing_events_path); 194 sys_dir = tracing_events__opendir();
196 if (!sys_dir) 195 if (!sys_dir)
197 return NULL; 196 return NULL;
198 197
199 for_each_subsystem(sys_dir, sys_dirent) { 198 for_each_subsystem(sys_dir, sys_dirent) {
200 199 dir_path = get_events_file(sys_dirent->d_name);
201 snprintf(dir_path, MAXPATHLEN, "%s/%s", tracing_events_path, 200 if (!dir_path)
202 sys_dirent->d_name); 201 continue;
203 evt_dir = opendir(dir_path); 202 evt_dir = opendir(dir_path);
204 if (!evt_dir) 203 if (!evt_dir)
205 continue; 204 goto next;
206 205
207 for_each_event(sys_dirent, evt_dir, evt_dirent) { 206 for_each_event(dir_path, evt_dir, evt_dirent) {
208 207
209 scnprintf(evt_path, MAXPATHLEN, "%s/%s/id", dir_path, 208 scnprintf(evt_path, MAXPATHLEN, "%s/%s/id", dir_path,
210 evt_dirent->d_name); 209 evt_dirent->d_name);
@@ -218,6 +217,7 @@ struct tracepoint_path *tracepoint_id_to_path(u64 config)
218 close(fd); 217 close(fd);
219 id = atoll(id_buf); 218 id = atoll(id_buf);
220 if (id == config) { 219 if (id == config) {
220 put_events_file(dir_path);
221 closedir(evt_dir); 221 closedir(evt_dir);
222 closedir(sys_dir); 222 closedir(sys_dir);
223 path = zalloc(sizeof(*path)); 223 path = zalloc(sizeof(*path));
@@ -242,6 +242,8 @@ struct tracepoint_path *tracepoint_id_to_path(u64 config)
242 } 242 }
243 } 243 }
244 closedir(evt_dir); 244 closedir(evt_dir);
245next:
246 put_events_file(dir_path);
245 } 247 }
246 248
247 closedir(sys_dir); 249 closedir(sys_dir);
@@ -512,14 +514,19 @@ static int add_tracepoint_multi_event(struct list_head *list, int *idx,
512 struct parse_events_error *err, 514 struct parse_events_error *err,
513 struct list_head *head_config) 515 struct list_head *head_config)
514{ 516{
515 char evt_path[MAXPATHLEN]; 517 char *evt_path;
516 struct dirent *evt_ent; 518 struct dirent *evt_ent;
517 DIR *evt_dir; 519 DIR *evt_dir;
518 int ret = 0, found = 0; 520 int ret = 0, found = 0;
519 521
520 snprintf(evt_path, MAXPATHLEN, "%s/%s", tracing_events_path, sys_name); 522 evt_path = get_events_file(sys_name);
523 if (!evt_path) {
524 tracepoint_error(err, errno, sys_name, evt_name);
525 return -1;
526 }
521 evt_dir = opendir(evt_path); 527 evt_dir = opendir(evt_path);
522 if (!evt_dir) { 528 if (!evt_dir) {
529 put_events_file(evt_path);
523 tracepoint_error(err, errno, sys_name, evt_name); 530 tracepoint_error(err, errno, sys_name, evt_name);
524 return -1; 531 return -1;
525 } 532 }
@@ -545,6 +552,7 @@ static int add_tracepoint_multi_event(struct list_head *list, int *idx,
545 ret = -1; 552 ret = -1;
546 } 553 }
547 554
555 put_events_file(evt_path);
548 closedir(evt_dir); 556 closedir(evt_dir);
549 return ret; 557 return ret;
550} 558}
@@ -570,7 +578,7 @@ static int add_tracepoint_multi_sys(struct list_head *list, int *idx,
570 DIR *events_dir; 578 DIR *events_dir;
571 int ret = 0; 579 int ret = 0;
572 580
573 events_dir = opendir(tracing_events_path); 581 events_dir = tracing_events__opendir();
574 if (!events_dir) { 582 if (!events_dir) {
575 tracepoint_error(err, errno, sys_name, evt_name); 583 tracepoint_error(err, errno, sys_name, evt_name);
576 return -1; 584 return -1;
@@ -2092,13 +2100,13 @@ void print_tracepoint_events(const char *subsys_glob, const char *event_glob,
2092 DIR *sys_dir, *evt_dir; 2100 DIR *sys_dir, *evt_dir;
2093 struct dirent *sys_dirent, *evt_dirent; 2101 struct dirent *sys_dirent, *evt_dirent;
2094 char evt_path[MAXPATHLEN]; 2102 char evt_path[MAXPATHLEN];
2095 char dir_path[MAXPATHLEN]; 2103 char *dir_path;
2096 char **evt_list = NULL; 2104 char **evt_list = NULL;
2097 unsigned int evt_i = 0, evt_num = 0; 2105 unsigned int evt_i = 0, evt_num = 0;
2098 bool evt_num_known = false; 2106 bool evt_num_known = false;
2099 2107
2100restart: 2108restart:
2101 sys_dir = opendir(tracing_events_path); 2109 sys_dir = tracing_events__opendir();
2102 if (!sys_dir) 2110 if (!sys_dir)
2103 return; 2111 return;
2104 2112
@@ -2113,13 +2121,14 @@ restart:
2113 !strglobmatch(sys_dirent->d_name, subsys_glob)) 2121 !strglobmatch(sys_dirent->d_name, subsys_glob))
2114 continue; 2122 continue;
2115 2123
2116 snprintf(dir_path, MAXPATHLEN, "%s/%s", tracing_events_path, 2124 dir_path = get_events_file(sys_dirent->d_name);
2117 sys_dirent->d_name); 2125 if (!dir_path)
2126 continue;
2118 evt_dir = opendir(dir_path); 2127 evt_dir = opendir(dir_path);
2119 if (!evt_dir) 2128 if (!evt_dir)
2120 continue; 2129 goto next;
2121 2130
2122 for_each_event(sys_dirent, evt_dir, evt_dirent) { 2131 for_each_event(dir_path, evt_dir, evt_dirent) {
2123 if (event_glob != NULL && 2132 if (event_glob != NULL &&
2124 !strglobmatch(evt_dirent->d_name, event_glob)) 2133 !strglobmatch(evt_dirent->d_name, event_glob))
2125 continue; 2134 continue;
@@ -2133,11 +2142,15 @@ restart:
2133 sys_dirent->d_name, evt_dirent->d_name); 2142 sys_dirent->d_name, evt_dirent->d_name);
2134 2143
2135 evt_list[evt_i] = strdup(evt_path); 2144 evt_list[evt_i] = strdup(evt_path);
2136 if (evt_list[evt_i] == NULL) 2145 if (evt_list[evt_i] == NULL) {
2146 put_events_file(dir_path);
2137 goto out_close_evt_dir; 2147 goto out_close_evt_dir;
2148 }
2138 evt_i++; 2149 evt_i++;
2139 } 2150 }
2140 closedir(evt_dir); 2151 closedir(evt_dir);
2152next:
2153 put_events_file(dir_path);
2141 } 2154 }
2142 closedir(sys_dir); 2155 closedir(sys_dir);
2143 2156
@@ -2185,21 +2198,21 @@ int is_valid_tracepoint(const char *event_string)
2185 DIR *sys_dir, *evt_dir; 2198 DIR *sys_dir, *evt_dir;
2186 struct dirent *sys_dirent, *evt_dirent; 2199 struct dirent *sys_dirent, *evt_dirent;
2187 char evt_path[MAXPATHLEN]; 2200 char evt_path[MAXPATHLEN];
2188 char dir_path[MAXPATHLEN]; 2201 char *dir_path;
2189 2202
2190 sys_dir = opendir(tracing_events_path); 2203 sys_dir = tracing_events__opendir();
2191 if (!sys_dir) 2204 if (!sys_dir)
2192 return 0; 2205 return 0;
2193 2206
2194 for_each_subsystem(sys_dir, sys_dirent) { 2207 for_each_subsystem(sys_dir, sys_dirent) {
2195 2208 dir_path = get_events_file(sys_dirent->d_name);
2196 snprintf(dir_path, MAXPATHLEN, "%s/%s", tracing_events_path, 2209 if (!dir_path)
2197 sys_dirent->d_name); 2210 continue;
2198 evt_dir = opendir(dir_path); 2211 evt_dir = opendir(dir_path);
2199 if (!evt_dir) 2212 if (!evt_dir)
2200 continue; 2213 goto next;
2201 2214
2202 for_each_event(sys_dirent, evt_dir, evt_dirent) { 2215 for_each_event(dir_path, evt_dir, evt_dirent) {
2203 snprintf(evt_path, MAXPATHLEN, "%s:%s", 2216 snprintf(evt_path, MAXPATHLEN, "%s:%s",
2204 sys_dirent->d_name, evt_dirent->d_name); 2217 sys_dirent->d_name, evt_dirent->d_name);
2205 if (!strcmp(evt_path, event_string)) { 2218 if (!strcmp(evt_path, event_string)) {
@@ -2209,6 +2222,8 @@ int is_valid_tracepoint(const char *event_string)
2209 } 2222 }
2210 } 2223 }
2211 closedir(evt_dir); 2224 closedir(evt_dir);
2225next:
2226 put_events_file(dir_path);
2212 } 2227 }
2213 closedir(sys_dir); 2228 closedir(sys_dir);
2214 return 0; 2229 return 0;
diff --git a/tools/perf/util/probe-file.c b/tools/perf/util/probe-file.c
index 4ae1123c6794..b76088fadf3d 100644
--- a/tools/perf/util/probe-file.c
+++ b/tools/perf/util/probe-file.c
@@ -84,8 +84,7 @@ int open_trace_file(const char *trace_file, bool readwrite)
84 char buf[PATH_MAX]; 84 char buf[PATH_MAX];
85 int ret; 85 int ret;
86 86
87 ret = e_snprintf(buf, PATH_MAX, "%s/%s", 87 ret = e_snprintf(buf, PATH_MAX, "%s/%s", tracing_path_mount(), trace_file);
88 tracing_path, trace_file);
89 if (ret >= 0) { 88 if (ret >= 0) {
90 pr_debug("Opening %s write=%d\n", buf, readwrite); 89 pr_debug("Opening %s write=%d\n", buf, readwrite);
91 if (readwrite && !probe_event_dry_run) 90 if (readwrite && !probe_event_dry_run)
diff --git a/tools/perf/util/sort.c b/tools/perf/util/sort.c
index e65903a695a6..4058ade352a5 100644
--- a/tools/perf/util/sort.c
+++ b/tools/perf/util/sort.c
@@ -2582,7 +2582,7 @@ int sort_dimension__add(struct perf_hpp_list *list, const char *tok,
2582 if (sort__mode != SORT_MODE__MEMORY) 2582 if (sort__mode != SORT_MODE__MEMORY)
2583 return -EINVAL; 2583 return -EINVAL;
2584 2584
2585 if (sd->entry == &sort_mem_dcacheline && cacheline_size == 0) 2585 if (sd->entry == &sort_mem_dcacheline && cacheline_size() == 0)
2586 return -EINVAL; 2586 return -EINVAL;
2587 2587
2588 if (sd->entry == &sort_mem_daddr_sym) 2588 if (sd->entry == &sort_mem_daddr_sym)
@@ -2628,7 +2628,7 @@ static int setup_sort_list(struct perf_hpp_list *list, char *str,
2628 if (*tok) { 2628 if (*tok) {
2629 ret = sort_dimension__add(list, tok, evlist, level); 2629 ret = sort_dimension__add(list, tok, evlist, level);
2630 if (ret == -EINVAL) { 2630 if (ret == -EINVAL) {
2631 if (!cacheline_size && !strncasecmp(tok, "dcacheline", strlen(tok))) 2631 if (!cacheline_size() && !strncasecmp(tok, "dcacheline", strlen(tok)))
2632 pr_err("The \"dcacheline\" --sort key needs to know the cacheline size and it couldn't be determined on this system"); 2632 pr_err("The \"dcacheline\" --sort key needs to know the cacheline size and it couldn't be determined on this system");
2633 else 2633 else
2634 pr_err("Invalid --sort key: `%s'", tok); 2634 pr_err("Invalid --sort key: `%s'", tok);
diff --git a/tools/perf/util/sort.h b/tools/perf/util/sort.h
index 035b62e2c60b..9e6896293bbd 100644
--- a/tools/perf/util/sort.h
+++ b/tools/perf/util/sort.h
@@ -186,13 +186,13 @@ static inline float hist_entry__get_percent_limit(struct hist_entry *he)
186static inline u64 cl_address(u64 address) 186static inline u64 cl_address(u64 address)
187{ 187{
188 /* return the cacheline of the address */ 188 /* return the cacheline of the address */
189 return (address & ~(cacheline_size - 1)); 189 return (address & ~(cacheline_size() - 1));
190} 190}
191 191
192static inline u64 cl_offset(u64 address) 192static inline u64 cl_offset(u64 address)
193{ 193{
194 /* return the cacheline of the address */ 194 /* return the cacheline of the address */
195 return (address & (cacheline_size - 1)); 195 return (address & (cacheline_size() - 1));
196} 196}
197 197
198enum sort_mode { 198enum sort_mode {
diff --git a/tools/perf/util/trace-event-info.c b/tools/perf/util/trace-event-info.c
index d7f2113462fb..c85d0d1a65ed 100644
--- a/tools/perf/util/trace-event-info.c
+++ b/tools/perf/util/trace-event-info.c
@@ -103,11 +103,10 @@ out:
103 103
104static int record_header_files(void) 104static int record_header_files(void)
105{ 105{
106 char *path; 106 char *path = get_events_file("header_page");
107 struct stat st; 107 struct stat st;
108 int err = -EIO; 108 int err = -EIO;
109 109
110 path = get_tracing_file("events/header_page");
111 if (!path) { 110 if (!path) {
112 pr_debug("can't get tracing/events/header_page"); 111 pr_debug("can't get tracing/events/header_page");
113 return -ENOMEM; 112 return -ENOMEM;
@@ -128,9 +127,9 @@ static int record_header_files(void)
128 goto out; 127 goto out;
129 } 128 }
130 129
131 put_tracing_file(path); 130 put_events_file(path);
132 131
133 path = get_tracing_file("events/header_event"); 132 path = get_events_file("header_event");
134 if (!path) { 133 if (!path) {
135 pr_debug("can't get tracing/events/header_event"); 134 pr_debug("can't get tracing/events/header_event");
136 err = -ENOMEM; 135 err = -ENOMEM;
@@ -154,7 +153,7 @@ static int record_header_files(void)
154 153
155 err = 0; 154 err = 0;
156out: 155out:
157 put_tracing_file(path); 156 put_events_file(path);
158 return err; 157 return err;
159} 158}
160 159
@@ -243,7 +242,7 @@ static int record_ftrace_files(struct tracepoint_path *tps)
243 char *path; 242 char *path;
244 int ret; 243 int ret;
245 244
246 path = get_tracing_file("events/ftrace"); 245 path = get_events_file("ftrace");
247 if (!path) { 246 if (!path) {
248 pr_debug("can't get tracing/events/ftrace"); 247 pr_debug("can't get tracing/events/ftrace");
249 return -ENOMEM; 248 return -ENOMEM;
diff --git a/tools/perf/util/trace-event.c b/tools/perf/util/trace-event.c
index 16a776371d03..1aa368603268 100644
--- a/tools/perf/util/trace-event.c
+++ b/tools/perf/util/trace-event.c
@@ -75,6 +75,7 @@ void trace_event__cleanup(struct trace_event *t)
75static struct event_format* 75static struct event_format*
76tp_format(const char *sys, const char *name) 76tp_format(const char *sys, const char *name)
77{ 77{
78 char *tp_dir = get_events_file(sys);
78 struct pevent *pevent = tevent.pevent; 79 struct pevent *pevent = tevent.pevent;
79 struct event_format *event = NULL; 80 struct event_format *event = NULL;
80 char path[PATH_MAX]; 81 char path[PATH_MAX];
@@ -82,8 +83,11 @@ tp_format(const char *sys, const char *name)
82 char *data; 83 char *data;
83 int err; 84 int err;
84 85
85 scnprintf(path, PATH_MAX, "%s/%s/%s/format", 86 if (!tp_dir)
86 tracing_events_path, sys, name); 87 return ERR_PTR(-errno);
88
89 scnprintf(path, PATH_MAX, "%s/%s/format", tp_dir, name);
90 put_events_file(tp_dir);
87 91
88 err = filename__read_str(path, &data, &size); 92 err = filename__read_str(path, &data, &size);
89 if (err) 93 if (err)
diff --git a/tools/perf/util/util.c b/tools/perf/util/util.c
index 1019bbc5dbd8..eac5b858a371 100644
--- a/tools/perf/util/util.c
+++ b/tools/perf/util/util.c
@@ -38,11 +38,43 @@ void perf_set_multithreaded(void)
38} 38}
39 39
40unsigned int page_size; 40unsigned int page_size;
41int cacheline_size; 41
42#ifdef _SC_LEVEL1_DCACHE_LINESIZE
43#define cache_line_size(cacheline_sizep) *cacheline_sizep = sysconf(_SC_LEVEL1_DCACHE_LINESIZE)
44#else
45static void cache_line_size(int *cacheline_sizep)
46{
47 if (sysfs__read_int("devices/system/cpu/cpu0/cache/index0/coherency_line_size", cacheline_sizep))
48 pr_debug("cannot determine cache line size");
49}
50#endif
51
52int cacheline_size(void)
53{
54 static int size;
55
56 if (!size)
57 cache_line_size(&size);
58
59 return size;
60}
42 61
43int sysctl_perf_event_max_stack = PERF_MAX_STACK_DEPTH; 62int sysctl_perf_event_max_stack = PERF_MAX_STACK_DEPTH;
44int sysctl_perf_event_max_contexts_per_stack = PERF_MAX_CONTEXTS_PER_STACK; 63int sysctl_perf_event_max_contexts_per_stack = PERF_MAX_CONTEXTS_PER_STACK;
45 64
65int sysctl__max_stack(void)
66{
67 int value;
68
69 if (sysctl__read_int("kernel/perf_event_max_stack", &value) == 0)
70 sysctl_perf_event_max_stack = value;
71
72 if (sysctl__read_int("kernel/perf_event_max_contexts_per_stack", &value) == 0)
73 sysctl_perf_event_max_contexts_per_stack = value;
74
75 return sysctl_perf_event_max_stack;
76}
77
46bool test_attr__enabled; 78bool test_attr__enabled;
47 79
48bool perf_host = true; 80bool perf_host = true;
diff --git a/tools/perf/util/util.h b/tools/perf/util/util.h
index c9626c206208..dc58254a2b69 100644
--- a/tools/perf/util/util.h
+++ b/tools/perf/util/util.h
@@ -43,7 +43,9 @@ size_t hex_width(u64 v);
43int hex2u64(const char *ptr, u64 *val); 43int hex2u64(const char *ptr, u64 *val);
44 44
45extern unsigned int page_size; 45extern unsigned int page_size;
46extern int cacheline_size; 46int __pure cacheline_size(void);
47
48int sysctl__max_stack(void);
47 49
48int fetch_kernel_version(unsigned int *puint, 50int fetch_kernel_version(unsigned int *puint,
49 char *str, size_t str_sz); 51 char *str, size_t str_sz);