diff options
Diffstat (limited to 'tools/perf/util/machine.c')
-rw-r--r-- | tools/perf/util/machine.c | 92 |
1 files changed, 46 insertions, 46 deletions
diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c index 2d51badfbf2e..2531b373f2cf 100644 --- a/tools/perf/util/machine.c +++ b/tools/perf/util/machine.c @@ -37,6 +37,7 @@ #include <internal/lib.h> // page_size #include "cgroup.h" #include "arm64-frame-pointer-unwind-support.h" +#include <api/io_dir.h> #include <linux/ctype.h> #include <symbol/kallsyms.h> @@ -94,6 +95,8 @@ int machine__init(struct machine *machine, const char *root_dir, pid_t pid) machine->comm_exec = false; machine->kernel_start = 0; machine->vmlinux_map = NULL; + /* There is no initial context switch in, so we start at 1. */ + machine->parallelism = 1; machine->root_dir = strdup(root_dir); if (machine->root_dir == NULL) @@ -677,8 +680,11 @@ int machine__process_aux_output_hw_id_event(struct machine *machine __maybe_unus int machine__process_switch_event(struct machine *machine __maybe_unused, union perf_event *event) { + bool out = event->header.misc & PERF_RECORD_MISC_SWITCH_OUT; + if (dump_trace) perf_event__fprintf_switch(event, stdout); + machine->parallelism += out ? -1 : 1; return 0; } @@ -712,7 +718,7 @@ static int machine__process_ksymbol_register(struct machine *machine, map__set_start(map, event->ksymbol.addr); map__set_end(map, map__start(map) + event->ksymbol.len); - err = maps__insert(machine__kernel_maps(machine), map); + err = maps__fixup_overlap_and_insert(machine__kernel_maps(machine), map); if (err) { err = -ENOMEM; goto out; @@ -773,6 +779,10 @@ int machine__process_ksymbol(struct machine *machine __maybe_unused, if (dump_trace) perf_event__fprintf_ksymbol(event, stdout); + /* no need to process non-JIT BPF as it cannot get samples */ + if (event->ksymbol.len == 0) + return 0; + if (event->ksymbol.flags & PERF_RECORD_KSYMBOL_FLAGS_UNREGISTER) return machine__process_ksymbol_unregister(machine, event, sample); @@ -886,26 +896,6 @@ size_t machines__fprintf_dsos_buildid(struct machines *machines, FILE *fp, return ret; } -size_t machine__fprintf_vmlinux_path(struct machine *machine, FILE *fp) -{ - int i; - size_t printed = 0; - struct dso *kdso = machine__kernel_dso(machine); - - if (dso__has_build_id(kdso)) { - char filename[PATH_MAX]; - - if (dso__build_id_filename(kdso, filename, sizeof(filename), false)) - printed += fprintf(fp, "[0] %s\n", filename); - } - - for (i = 0; i < vmlinux_path__nr_entries; ++i) { - printed += fprintf(fp, "[%d] %s\n", i + dso__has_build_id(kdso), - vmlinux_path[i]); - } - return printed; -} - struct machine_fprintf_cb_args { FILE *fp; size_t printed; @@ -1352,27 +1342,24 @@ static int maps__set_module_path(struct maps *maps, const char *path, struct kmo return 0; } -static int maps__set_modules_path_dir(struct maps *maps, const char *dir_name, int depth) +static int maps__set_modules_path_dir(struct maps *maps, char *path, size_t path_size, int depth) { - struct dirent *dent; - DIR *dir = opendir(dir_name); + struct io_dirent64 *dent; + struct io_dir iod; + size_t root_len = strlen(path); int ret = 0; - if (!dir) { - pr_debug("%s: cannot open %s dir\n", __func__, dir_name); + io_dir__init(&iod, open(path, O_CLOEXEC | O_DIRECTORY | O_RDONLY)); + if (iod.dirfd < 0) { + pr_debug("%s: cannot open %s dir\n", __func__, path); return -1; } - - while ((dent = readdir(dir)) != NULL) { - char path[PATH_MAX]; - struct stat st; - - /*sshfs might return bad dent->d_type, so we have to stat*/ - path__join(path, sizeof(path), dir_name, dent->d_name); - if (stat(path, &st)) - continue; - - if (S_ISDIR(st.st_mode)) { + /* Bounds check, should never happen. */ + if (root_len >= path_size) + return -1; + path[root_len++] = '/'; + while ((dent = io_dir__readdir(&iod)) != NULL) { + if (io_dir__is_dir(&iod, dent)) { if (!strcmp(dent->d_name, ".") || !strcmp(dent->d_name, "..")) continue; @@ -1384,7 +1371,12 @@ static int maps__set_modules_path_dir(struct maps *maps, const char *dir_name, i continue; } - ret = maps__set_modules_path_dir(maps, path, depth + 1); + /* Bounds check, should never happen. */ + if (root_len + strlen(dent->d_name) >= path_size) + continue; + + strcpy(path + root_len, dent->d_name); + ret = maps__set_modules_path_dir(maps, path, path_size, depth + 1); if (ret < 0) goto out; } else { @@ -1394,9 +1386,14 @@ static int maps__set_modules_path_dir(struct maps *maps, const char *dir_name, i if (ret) goto out; - if (m.kmod) - ret = maps__set_module_path(maps, path, &m); + if (m.kmod) { + /* Bounds check, should never happen. */ + if (root_len + strlen(dent->d_name) < path_size) { + strcpy(path + root_len, dent->d_name); + ret = maps__set_module_path(maps, path, &m); + } + } zfree(&m.name); if (ret) @@ -1405,7 +1402,7 @@ static int maps__set_modules_path_dir(struct maps *maps, const char *dir_name, i } out: - closedir(dir); + close(iod.dirfd); return ret; } @@ -1422,7 +1419,8 @@ static int machine__set_modules_path(struct machine *machine) machine->root_dir, version); free(version); - return maps__set_modules_path_dir(machine__kernel_maps(machine), modules_path, 0); + return maps__set_modules_path_dir(machine__kernel_maps(machine), + modules_path, sizeof(modules_path), 0); } int __weak arch__fix_module_text_start(u64 *start __maybe_unused, u64 *size __maybe_unused, @@ -1468,8 +1466,6 @@ static int machine__create_modules(struct machine *machine) if (modules__parse(modules, machine, machine__create_module)) return -1; - maps__fixup_end(machine__kernel_maps(machine)); - if (!machine__set_modules_path(machine)) return 0; @@ -1563,6 +1559,8 @@ int machine__create_kernel_maps(struct machine *machine) } } + maps__fixup_end(machine__kernel_maps(machine)); + out_put: dso__put(kernel); return ret; @@ -1900,6 +1898,8 @@ int machine__process_exit_event(struct machine *machine, union perf_event *event if (dump_trace) perf_event__fprintf_task(event, stdout); + /* There is no context switch out before exit, so we decrement here. */ + machine->parallelism--; if (thread != NULL) { if (symbol_conf.keep_exited_threads) thread__set_exited(thread, /*exited=*/true); @@ -2929,8 +2929,8 @@ static int thread__resolve_callchain_unwind(struct thread *thread, return 0; /* Bail out if nothing was captured. */ - if ((!sample->user_regs.regs) || - (!sample->user_stack.size)) + if (!sample->user_regs || !sample->user_regs->regs || + !sample->user_stack.size) return 0; if (!symbols) |