diff options
| author | Arnaldo Carvalho de Melo <acme@redhat.com> | 2019-02-19 14:17:33 -0500 |
|---|---|---|
| committer | Arnaldo Carvalho de Melo <acme@redhat.com> | 2019-02-19 14:35:45 -0500 |
| commit | ff7a4f98d52cd3f13b1f4f6f22208498b0c113f7 (patch) | |
| tree | e98e852c537459f89057d81a0e67efc5e2b4a2ec | |
| parent | d19f856479feef7c1383f02b87688563a0ef7a14 (diff) | |
perf trace: Allow dumping a BPF map after setting up BPF events
Initial use case:
Dumping the maps setup by tools/perf/examples/bpf/augmented_raw_syscalls.c,
which so far are just booleans, showing just non-zeroed entries:
# cat ~/.perfconfig
[llvm]
dump-obj = true
clang-opt = -g
[trace]
#add_events = /home/acme/git/perf/tools/perf/examples/bpf/augmented_raw_syscalls.o
add_events = /wb/augmented_raw_syscalls.o
$ date
Tue Feb 19 16:29:33 -03 2019
$ ls -la /wb/augmented_raw_syscalls.o
-rwxr-xr-x. 1 root root 14048 Jan 24 12:09 /wb/augmented_raw_syscalls.o
$ file /wb/augmented_raw_syscalls.o
/wb/augmented_raw_syscalls.o: ELF 64-bit LSB relocatable, eBPF, version 1 (SYSV), with debug_info, not stripped
$
# trace -e recvmmsg,sendmmsg --map-dump foobar
ERROR: BPF map "foobar" not found
# trace -e recvmmsg,sendmmsg --map-dump filtered_pids
ERROR: BPF map "filtered_pids" not found
# trace -e recvmmsg,sendmmsg --map-dump pids_filtered
[2583] = 1,
[2267] = 1,
^Z
[1]+ Stopped trace -e recvmmsg,sendmmsg --map-dump pids_filtered
# pidof trace
2267
# ps ax|grep gnome-terminal|grep -v grep
2583 ? Ssl 58:33 /usr/libexec/gnome-terminal-server
^C
# trace -e recvmmsg,sendmmsg --map-dump syscalls
[299] = 1,
[307] = 1,
^C
# grep x64_recvmmsg arch/x86/entry/syscalls/syscall_64.tbl
299 64 recvmmsg __x64_sys_recvmmsg
# grep x64_sendmmsg arch/x86/entry/syscalls/syscall_64.tbl
307 64 sendmmsg __x64_sys_sendmmsg
#
Next step probably will be something like 'perf stat's --interval-print and
--interval-clear.
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Alexei Starovoitov <ast@kernel.org>
Cc: Daniel Borkmann <daniel@iogearbox.net>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Martin KaFai Lau <kafai@fb.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Yonghong Song <yhs@fb.com>
Link: https://lkml.kernel.org/n/tip-ztxj25rtx37ixo9cfajt8ocy@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
| -rw-r--r-- | tools/perf/Documentation/perf-trace.txt | 8 | ||||
| -rw-r--r-- | tools/perf/builtin-trace.c | 19 |
2 files changed, 27 insertions, 0 deletions
diff --git a/tools/perf/Documentation/perf-trace.txt b/tools/perf/Documentation/perf-trace.txt index 631e687be4eb..fc6e43262c41 100644 --- a/tools/perf/Documentation/perf-trace.txt +++ b/tools/perf/Documentation/perf-trace.txt | |||
| @@ -210,6 +210,14 @@ the thread executes on the designated CPUs. Default is to monitor all CPUs. | |||
| 210 | may happen, for instance, when a thread gets migrated to a different CPU | 210 | may happen, for instance, when a thread gets migrated to a different CPU |
| 211 | while processing a syscall. | 211 | while processing a syscall. |
| 212 | 212 | ||
| 213 | --map-dump:: | ||
| 214 | Dump BPF maps setup by events passed via -e, for instance the augmented_raw_syscalls | ||
| 215 | living in tools/perf/examples/bpf/augmented_raw_syscalls.c. For now this | ||
| 216 | dumps just boolean map values and integer keys, in time this will print in hex | ||
| 217 | by default and use BTF when available, as well as use functions to do pretty | ||
| 218 | printing using the existing 'perf trace' syscall arg beautifiers to map integer | ||
| 219 | arguments to strings (pid to comm, syscall id to syscall name, etc). | ||
| 220 | |||
| 213 | 221 | ||
| 214 | PAGEFAULTS | 222 | PAGEFAULTS |
| 215 | ---------- | 223 | ---------- |
diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index 68a01e624ad3..1a11fe656afc 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c | |||
| @@ -19,6 +19,7 @@ | |||
| 19 | #include <traceevent/event-parse.h> | 19 | #include <traceevent/event-parse.h> |
| 20 | #include <api/fs/tracing_path.h> | 20 | #include <api/fs/tracing_path.h> |
| 21 | #include <bpf/bpf.h> | 21 | #include <bpf/bpf.h> |
| 22 | #include "util/bpf_map.h" | ||
| 22 | #include "builtin.h" | 23 | #include "builtin.h" |
| 23 | #include "util/cgroup.h" | 24 | #include "util/cgroup.h" |
| 24 | #include "util/color.h" | 25 | #include "util/color.h" |
| @@ -87,6 +88,9 @@ struct trace { | |||
| 87 | *augmented; | 88 | *augmented; |
| 88 | } events; | 89 | } events; |
| 89 | } syscalls; | 90 | } syscalls; |
| 91 | struct { | ||
| 92 | struct bpf_map *map; | ||
| 93 | } dump; | ||
| 90 | struct record_opts opts; | 94 | struct record_opts opts; |
| 91 | struct perf_evlist *evlist; | 95 | struct perf_evlist *evlist; |
| 92 | struct machine *host; | 96 | struct machine *host; |
| @@ -2997,6 +3001,9 @@ static int trace__run(struct trace *trace, int argc, const char **argv) | |||
| 2997 | if (err < 0) | 3001 | if (err < 0) |
| 2998 | goto out_error_apply_filters; | 3002 | goto out_error_apply_filters; |
| 2999 | 3003 | ||
| 3004 | if (trace->dump.map) | ||
| 3005 | bpf_map__fprintf(trace->dump.map, trace->output); | ||
| 3006 | |||
| 3000 | err = perf_evlist__mmap(evlist, trace->opts.mmap_pages); | 3007 | err = perf_evlist__mmap(evlist, trace->opts.mmap_pages); |
| 3001 | if (err < 0) | 3008 | if (err < 0) |
| 3002 | goto out_error_mmap; | 3009 | goto out_error_mmap; |
| @@ -3686,6 +3693,7 @@ int cmd_trace(int argc, const char **argv) | |||
| 3686 | .max_stack = UINT_MAX, | 3693 | .max_stack = UINT_MAX, |
| 3687 | .max_events = ULONG_MAX, | 3694 | .max_events = ULONG_MAX, |
| 3688 | }; | 3695 | }; |
| 3696 | const char *map_dump_str = NULL; | ||
| 3689 | const char *output_name = NULL; | 3697 | const char *output_name = NULL; |
| 3690 | const struct option trace_options[] = { | 3698 | const struct option trace_options[] = { |
| 3691 | OPT_CALLBACK('e', "event", &trace, "event", | 3699 | OPT_CALLBACK('e', "event", &trace, "event", |
| @@ -3718,6 +3726,9 @@ int cmd_trace(int argc, const char **argv) | |||
| 3718 | OPT_CALLBACK(0, "duration", &trace, "float", | 3726 | OPT_CALLBACK(0, "duration", &trace, "float", |
| 3719 | "show only events with duration > N.M ms", | 3727 | "show only events with duration > N.M ms", |
| 3720 | trace__set_duration), | 3728 | trace__set_duration), |
| 3729 | #ifdef HAVE_LIBBPF_SUPPORT | ||
| 3730 | OPT_STRING(0, "map-dump", &map_dump_str, "BPF map", "BPF map to periodically dump"), | ||
| 3731 | #endif | ||
| 3721 | OPT_BOOLEAN(0, "sched", &trace.sched, "show blocking scheduler events"), | 3732 | OPT_BOOLEAN(0, "sched", &trace.sched, "show blocking scheduler events"), |
| 3722 | OPT_INCR('v', "verbose", &verbose, "be more verbose"), | 3733 | OPT_INCR('v', "verbose", &verbose, "be more verbose"), |
| 3723 | OPT_BOOLEAN('T', "time", &trace.full_time, | 3734 | OPT_BOOLEAN('T', "time", &trace.full_time, |
| @@ -3812,6 +3823,14 @@ int cmd_trace(int argc, const char **argv) | |||
| 3812 | 3823 | ||
| 3813 | err = -1; | 3824 | err = -1; |
| 3814 | 3825 | ||
| 3826 | if (map_dump_str) { | ||
| 3827 | trace.dump.map = bpf__find_map_by_name(map_dump_str); | ||
| 3828 | if (trace.dump.map == NULL) { | ||
| 3829 | pr_err("ERROR: BPF map \"%s\" not found\n", map_dump_str); | ||
| 3830 | goto out; | ||
| 3831 | } | ||
| 3832 | } | ||
| 3833 | |||
| 3815 | if (trace.trace_pgfaults) { | 3834 | if (trace.trace_pgfaults) { |
| 3816 | trace.opts.sample_address = true; | 3835 | trace.opts.sample_address = true; |
| 3817 | trace.opts.sample_time = true; | 3836 | trace.opts.sample_time = true; |
