diff options
| author | Ingo Molnar <mingo@kernel.org> | 2018-05-19 07:32:27 -0400 |
|---|---|---|
| committer | Ingo Molnar <mingo@kernel.org> | 2018-05-19 07:32:53 -0400 |
| commit | 2996123e7e589d78e73cfeb7e7f14d49127eb1b0 (patch) | |
| tree | 03858af094a74f2a0b6c09de1f6f231fcb9334ee | |
| parent | 5aafae8d097e2161ee5c6a12ad532100f8885d2b (diff) | |
| parent | 19422a9f2a3be7f3a046285ffae4cbb571aa853a (diff) | |
Merge tag 'perf-core-for-mingo-4.18-20180519' of git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux into perf/core
Pull perf/core improvements and fixes from Arnaldo Carvalho de Melo:
- Record min/max LBR cycles (>= Skylake) and add 'perf annotate' TUI
hotkey to show it (c) (Jin Yao)
- Fix machine->kernel_start for PTI on x86 (Adrian Hunter)
- Make machine->env->arch always available, e.g. in 'perf top', not
just when reading that info from perf.data files (Adrian Hunter)
- Reduce the number of files read at 'perf' start, leaving information such as
cacheline size, tracefs mount point determination, max_stack, etc, to be
lazily read as tools needs then (Arnaldo Carvalho de Melo)
- Fix up BPF include and examples install messages (Arnaldo Carvalho de Melo)
- Fix up callchain addresses and symbol offsets in 'perf script', to help
correlating with objdump output (Sandipan Das)
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Signed-off-by: Ingo Molnar <mingo@kernel.org>
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 | 16 | static char tracing_mnt[PATH_MAX] = "/sys/kernel/debug"; | |
| 17 | char tracing_mnt[PATH_MAX] = "/sys/kernel/debug"; | 17 | static char tracing_path[PATH_MAX] = "/sys/kernel/debug/tracing"; |
| 18 | char tracing_path[PATH_MAX] = "/sys/kernel/debug/tracing"; | 18 | static char tracing_events_path[PATH_MAX] = "/sys/kernel/debug/tracing/events"; |
| 19 | char tracing_events_path[PATH_MAX] = "/sys/kernel/debug/tracing/events"; | ||
| 20 | |||
| 21 | 19 | ||
| 22 | static void __tracing_path_set(const char *tracing, const char *mountpoint) | 20 | static 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 | ||
| 88 | char *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 | |||
| 98 | void put_events_file(char *file) | ||
| 99 | { | ||
| 100 | free(file); | ||
| 101 | } | ||
| 102 | |||
| 103 | DIR *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 | |||
| 90 | int tracing_path__strerror_open_tp(int err, char *buf, size_t size, | 116 | int 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 | ||
| 7 | extern char tracing_path[]; | 8 | DIR *tracing_events__opendir(void); |
| 8 | extern char tracing_events_path[]; | ||
| 9 | 9 | ||
| 10 | void tracing_path_set(const char *mountpoint); | 10 | void tracing_path_set(const char *mountpoint); |
| 11 | const char *tracing_path_mount(void); | 11 | const char *tracing_path_mount(void); |
| @@ -13,5 +13,10 @@ const char *tracing_path_mount(void); | |||
| 13 | char *get_tracing_file(const char *name); | 13 | char *get_tracing_file(const char *name); |
| 14 | void put_tracing_file(char *file); | 14 | void put_tracing_file(char *file); |
| 15 | 15 | ||
| 16 | char *get_events_file(const char *name); | ||
| 17 | void put_events_file(char *file); | ||
| 18 | |||
| 19 | #define zput_events_file(ptr) ({ free(*ptr); *ptr = NULL; }) | ||
| 20 | |||
| 16 | int tracing_path__strerror_open_tp(int err, char *buf, size_t size, const char *sys, const char *name); | 21 | int 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 | |||
| 770 | ifndef NO_LIBBPF | 770 | ifndef 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' |
| 777 | endif | 779 | endif |
| 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 | ||
| 427 | static 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 | |||
| 434 | int main(int argc, const char **argv) | 424 | int 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 | |||
| 16 | trace_libc_inet_pton_backtrace() { | 16 | trace_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 | ||
| 65 | struct annotation_options { | 66 | struct 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 | ||
| 240 | static inline int annotation__cycles_width(struct annotation *notes) | 246 | static 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 | ||
| 710 | static 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 | |||
| 710 | int perf_config(config_fn_t fn, void *data) | 718 | int 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 | ||
| 738 | void perf_config__init(void) | ||
| 739 | { | ||
| 740 | if (config_set == NULL) | ||
| 741 | config_set = perf_config_set__new(); | ||
| 742 | } | ||
| 743 | |||
| 744 | void perf_config__exit(void) | 746 | void 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); | |||
| 38 | void perf_config_set__delete(struct perf_config_set *set); | 38 | void perf_config_set__delete(struct perf_config_set *set); |
| 39 | int perf_config_set__collect(struct perf_config_set *set, const char *file_name, | 39 | int 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); |
| 41 | void perf_config__init(void); | ||
| 42 | void perf_config__exit(void); | 41 | void perf_config__exit(void); |
| 43 | void perf_config__refresh(void); | 42 | void 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 | ||
| 96 | static 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 | |||
| 109 | const char *perf_env__raw_arch(struct perf_env *env) | ||
| 110 | { | ||
| 111 | return env && !perf_env__read_arch(env) ? env->arch : "unknown"; | ||
| 112 | } | ||
| 113 | |||
| 96 | void cpu_cache_level__free(struct cpu_cache_level *cache) | 114 | void 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); | |||
| 76 | void cpu_cache_level__free(struct cpu_cache_level *cache); | 76 | void cpu_cache_level__free(struct cpu_cache_level *cache); |
| 77 | 77 | ||
| 78 | const char *perf_env__arch(struct perf_env *env); | 78 | const char *perf_env__arch(struct perf_env *env); |
| 79 | const 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 | */ | ||
| 2303 | bool machine__is(struct machine *machine, const char *arch) | ||
| 2304 | { | ||
| 2305 | return machine && !strcmp(perf_env__raw_arch(machine->env), arch); | ||
| 2306 | } | ||
| 2307 | |||
| 2299 | int machine__get_kernel_start(struct machine *machine) | 2308 | int 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 | ||
| 191 | bool machine__is(struct machine *machine, const char *arch); | ||
| 192 | |||
| 191 | struct thread *__machine__findnew_thread(struct machine *machine, pid_t pid, pid_t tid); | 193 | struct thread *__machine__findnew_thread(struct machine *machine, pid_t pid, pid_t tid); |
| 192 | struct thread *machine__findnew_thread(struct machine *machine, pid_t pid, pid_t tid); | 194 | struct 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 | ||
| 159 | static int tp_event_has_id(struct dirent *sys_dir, struct dirent *evt_dir) | 159 | static 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); |
| 245 | next: | ||
| 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 | ||
| 2100 | restart: | 2108 | restart: |
| 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); |
| 2152 | next: | ||
| 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); |
| 2225 | next: | ||
| 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) | |||
| 186 | static inline u64 cl_address(u64 address) | 186 | static 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 | ||
| 192 | static inline u64 cl_offset(u64 address) | 192 | static 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 | ||
| 198 | enum sort_mode { | 198 | enum 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 | ||
| 104 | static int record_header_files(void) | 104 | static 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; |
| 156 | out: | 155 | out: |
| 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) | |||
| 75 | static struct event_format* | 75 | static struct event_format* |
| 76 | tp_format(const char *sys, const char *name) | 76 | tp_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 | ||
| 40 | unsigned int page_size; | 40 | unsigned int page_size; |
| 41 | int 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 | ||
| 45 | static 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 | |||
| 52 | int cacheline_size(void) | ||
| 53 | { | ||
| 54 | static int size; | ||
| 55 | |||
| 56 | if (!size) | ||
| 57 | cache_line_size(&size); | ||
| 58 | |||
| 59 | return size; | ||
| 60 | } | ||
| 42 | 61 | ||
| 43 | int sysctl_perf_event_max_stack = PERF_MAX_STACK_DEPTH; | 62 | int sysctl_perf_event_max_stack = PERF_MAX_STACK_DEPTH; |
| 44 | int sysctl_perf_event_max_contexts_per_stack = PERF_MAX_CONTEXTS_PER_STACK; | 63 | int sysctl_perf_event_max_contexts_per_stack = PERF_MAX_CONTEXTS_PER_STACK; |
| 45 | 64 | ||
| 65 | int 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 | |||
| 46 | bool test_attr__enabled; | 78 | bool test_attr__enabled; |
| 47 | 79 | ||
| 48 | bool perf_host = true; | 80 | bool 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); | |||
| 43 | int hex2u64(const char *ptr, u64 *val); | 43 | int hex2u64(const char *ptr, u64 *val); |
| 44 | 44 | ||
| 45 | extern unsigned int page_size; | 45 | extern unsigned int page_size; |
| 46 | extern int cacheline_size; | 46 | int __pure cacheline_size(void); |
| 47 | |||
| 48 | int sysctl__max_stack(void); | ||
| 47 | 49 | ||
| 48 | int fetch_kernel_version(unsigned int *puint, | 50 | int fetch_kernel_version(unsigned int *puint, |
| 49 | char *str, size_t str_sz); | 51 | char *str, size_t str_sz); |
