diff options
Diffstat (limited to 'tools/perf/builtin-trace.c')
-rw-r--r-- | tools/perf/builtin-trace.c | 78 |
1 files changed, 60 insertions, 18 deletions
diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index adbf28183560..f5b3a1e9c1dd 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -19,6 +19,7 @@ #include <traceevent/event-parse.h> #include <api/fs/tracing_path.h> #include <bpf/bpf.h> +#include "util/bpf_map.h" #include "builtin.h" #include "util/cgroup.h" #include "util/color.h" @@ -29,6 +30,8 @@ #include "util/evlist.h" #include <subcmd/exec-cmd.h> #include "util/machine.h" +#include "util/map.h" +#include "util/symbol.h" #include "util/path.h" #include "util/session.h" #include "util/thread.h" @@ -85,6 +88,9 @@ struct trace { *augmented; } events; } syscalls; + struct { + struct bpf_map *map; + } dump; struct record_opts opts; struct perf_evlist *evlist; struct machine *host; @@ -1039,6 +1045,9 @@ static const size_t trace__entry_str_size = 2048; static struct file *thread_trace__files_entry(struct thread_trace *ttrace, int fd) { + if (fd < 0) + return NULL; + if (fd > ttrace->files.max) { struct file *nfiles = realloc(ttrace->files.table, (fd + 1) * sizeof(struct file)); @@ -1758,6 +1767,7 @@ static int trace__printf_interrupted_entry(struct trace *trace) { struct thread_trace *ttrace; size_t printed; + int len; if (trace->failure_only || trace->current == NULL) return 0; @@ -1768,9 +1778,14 @@ static int trace__printf_interrupted_entry(struct trace *trace) return 0; printed = trace__fprintf_entry_head(trace, trace->current, 0, false, ttrace->entry_time, trace->output); - printed += fprintf(trace->output, ")%-*s ...\n", trace->args_alignment, ttrace->entry_str); - ttrace->entry_pending = false; + printed += len = fprintf(trace->output, "%s)", ttrace->entry_str); + + if (len < trace->args_alignment - 4) + printed += fprintf(trace->output, "%-*s", trace->args_alignment - 4 - len, " "); + printed += fprintf(trace->output, " ...\n"); + + ttrace->entry_pending = false; ++trace->nr_events_printed; return printed; @@ -2026,9 +2041,10 @@ static int trace__sys_exit(struct trace *trace, struct perf_evsel *evsel, if (ttrace->entry_pending) { printed = fprintf(trace->output, "%s", ttrace->entry_str); } else { - fprintf(trace->output, " ... ["); + printed += fprintf(trace->output, " ... ["); color_fprintf(trace->output, PERF_COLOR_YELLOW, "continued"); - fprintf(trace->output, "]: %s()", sc->name); + printed += 9; + printed += fprintf(trace->output, "]: %s()", sc->name); } printed++; /* the closing ')' */ @@ -2507,19 +2523,30 @@ static size_t trace__fprintf_thread_summary(struct trace *trace, FILE *fp); static bool perf_evlist__add_vfs_getname(struct perf_evlist *evlist) { - struct perf_evsel *evsel = perf_evsel__newtp("probe", "vfs_getname"); + bool found = false; + struct perf_evsel *evsel, *tmp; + struct parse_events_error err = { .idx = 0, }; + int ret = parse_events(evlist, "probe:vfs_getname*", &err); - if (IS_ERR(evsel)) + if (ret) return false; - if (perf_evsel__field(evsel, "pathname") == NULL) { + evlist__for_each_entry_safe(evlist, evsel, tmp) { + if (!strstarts(perf_evsel__name(evsel), "probe:vfs_getname")) + continue; + + if (perf_evsel__field(evsel, "pathname")) { + evsel->handler = trace__vfs_getname; + found = true; + continue; + } + + list_del_init(&evsel->node); + evsel->evlist = NULL; perf_evsel__delete(evsel); - return false; } - evsel->handler = trace__vfs_getname; - perf_evlist__add(evlist, evsel); - return true; + return found; } static struct perf_evsel *perf_evsel__new_pgfault(u64 config) @@ -2748,7 +2775,8 @@ static int trace__set_filter_loop_pids(struct trace *trace) if (parent == NULL) break; - if (!strcmp(thread__comm_str(parent), "sshd")) { + if (!strcmp(thread__comm_str(parent), "sshd") || + strstarts(thread__comm_str(parent), "gnome-terminal")) { pids[nr++] = parent->tid; break; } @@ -2973,6 +3001,9 @@ static int trace__run(struct trace *trace, int argc, const char **argv) if (err < 0) goto out_error_apply_filters; + if (trace->dump.map) + bpf_map__fprintf(trace->dump.map, trace->output); + err = perf_evlist__mmap(evlist, trace->opts.mmap_pages); if (err < 0) goto out_error_mmap; @@ -3123,11 +3154,9 @@ static int trace__replay(struct trace *trace) { "probe:vfs_getname", trace__vfs_getname, }, }; struct perf_data data = { - .file = { - .path = input_name, - }, - .mode = PERF_DATA_MODE_READ, - .force = trace->force, + .path = input_name, + .mode = PERF_DATA_MODE_READ, + .force = trace->force, }; struct perf_session *session; struct perf_evsel *evsel; @@ -3662,6 +3691,7 @@ int cmd_trace(int argc, const char **argv) .max_stack = UINT_MAX, .max_events = ULONG_MAX, }; + const char *map_dump_str = NULL; const char *output_name = NULL; const struct option trace_options[] = { OPT_CALLBACK('e', "event", &trace, "event", @@ -3694,6 +3724,9 @@ int cmd_trace(int argc, const char **argv) OPT_CALLBACK(0, "duration", &trace, "float", "show only events with duration > N.M ms", trace__set_duration), +#ifdef HAVE_LIBBPF_SUPPORT + OPT_STRING(0, "map-dump", &map_dump_str, "BPF map", "BPF map to periodically dump"), +#endif OPT_BOOLEAN(0, "sched", &trace.sched, "show blocking scheduler events"), OPT_INCR('v', "verbose", &verbose, "be more verbose"), OPT_BOOLEAN('T', "time", &trace.full_time, @@ -3788,6 +3821,14 @@ int cmd_trace(int argc, const char **argv) err = -1; + if (map_dump_str) { + trace.dump.map = bpf__find_map_by_name(map_dump_str); + if (trace.dump.map == NULL) { + pr_err("ERROR: BPF map \"%s\" not found\n", map_dump_str); + goto out; + } + } + if (trace.trace_pgfaults) { trace.opts.sample_address = true; trace.opts.sample_time = true; @@ -3847,7 +3888,8 @@ int cmd_trace(int argc, const char **argv) goto init_augmented_syscall_tp; } - if (strcmp(perf_evsel__name(evsel), "raw_syscalls:sys_enter") == 0) { + if (trace.syscalls.events.augmented->priv == NULL && + strstr(perf_evsel__name(evsel), "syscalls:sys_enter")) { struct perf_evsel *augmented = trace.syscalls.events.augmented; if (perf_evsel__init_augmented_syscall_tp(augmented, evsel) || perf_evsel__init_augmented_syscall_tp_args(augmented)) |