perf/core improvements and fixes
Subsystems (7)
Arnaldo Carvalho de Melo
maintainerHi Ingo,
Please consider pulling,
- Arnaldo
Test results at the end of this message, as usual.
The following changes since commit 9f6f941e25bad8fcffc24d10762962d62edba767:
Merge tag 'perf-core-for-mingo-4.11-20170117' of git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux into perf/core (2017-01-18 10:06:20 +0100)
are available in the git repository at:
git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux.git tags/perf-core-for-mingo-4.11-20170125
for you to fetch changes up to bb6457b8af267b92ba3e752d9ccb3a4d4965a912:
perf ftrace: Make 'function_graph' be the default tracer (2017-01-25 10:37:27 -0300)
----------------------------------------------------------------
perf/core improvements and fixes:
New features:
- Disassemble x86 branch stacks using "-F brstackasm" and Intel PT traces with "-F asm" in 'perf script' using Intel's XED library.
Since this is not widely available in pre-packaged forms in distros, it will not be automatically feature probed, needing to be explicitly enabled at perf build time using the XED=1 and optionally the XED_DIR make command line variables.
See the changeset log messages and committer notes to see it in action (Andi Kleen)
- Introduce 'perf ftrace' a perf front end to the kernel's ftrace function and function_graph tracer, defaulting to the "function_graph" tracer, more work will be done in reviving this effort, forward porting it from its initial patch submission (Namhyung Kim)
- Add 'e' and 'c' hotkeys to expand/collapse call chains for a single hist entry in the 'perf report' and 'perf top' TUI (Jiri Olsa)
Fixes:
- Fix wrong register name for arm64, used in 'perf probe' (He Kuang)
- Fix map offsets in relocation in libbpf (Joe Stringer)
- Fix looking up dwarf unwind stack info (Matija Glavinic Pecotic)
Infrastructure:
- libbpf prog functions sync with what is exported via uapi (Joe Stringer)
Trivial:
- Remove unnecessary checks and assignments in 'perf probe's try_to_find_absolute_address() (Markus Elfring)
----------------------------------------------------------------
Andi Kleen (5):
perf tools: Add probing for the XED disassembler library perf tools: Add one liner warning for disabled features perf tools: Add disassembler for x86 using the XED library perf script: Add support for printing assembler perf script: Add "brstackasm" output for branch stacks
Arnaldo Carvalho de Melo (3):
perf scripting perl: Do not die() when not founding event for a type perf tools: Propagate perf_config() errors
perf ftrace: Make 'function_graph' be the default tracer
He Kuang (1):
perf probe: Fix wrong register name for arm64
Jiri Olsa (4):
perf hists browser: Put hist_entry folding logic into single function perf hists browser: Add e/c hotkeys to expand/collapse callchain for current entry perf c2c report: Display Total records column in offset view
perf c2c report: Coalesce by default only by pid,iaddr
Joe Stringer (4):
tools lib bpf: Fix map offsets in relocation tools lib bpf: Define prog_type fns with macro tools lib bpf: Add set/is helpers for all prog types tools lib bpf: Add libbpf_get_error()
Markus Elfring (2):
perf probe: Delete an unnecessary check in try_to_find_absolute_address() perf probe: Delete an unnecessary assignment in try_to_find_absolute_address()
Matija Glavinic Pecotic (1):
perf unwind: Fix looking up dwarf unwind stack info
Namhyung Kim (3):
perf util: Save pid-cmdline mapping into tracing header perf util: Add more debug message on failure path perf ftrace: Introduce new 'ftrace' tool
tools/build/Makefile.feature | 4 +- tools/build/feature/Makefile | 6 +- tools/build/feature/test-all.c | 14 + tools/build/feature/test-xed.c | 9 + tools/lib/bpf/libbpf.c | 69 +++-- tools/lib/bpf/libbpf.h | 14 +- tools/perf/Build | 1 + tools/perf/Documentation/perf-c2c.txt | 2 +- tools/perf/Documentation/perf-ftrace.txt | 36 +++ tools/perf/Documentation/perf-script.txt | 15 +- tools/perf/Makefile.config | 29 ++ tools/perf/Makefile.perf | 3 + tools/perf/arch/arm64/include/dwarf-regs-table.h | 12 +- tools/perf/arch/x86/util/Build | 3 + tools/perf/arch/x86/util/dis.c | 86 ++++++ tools/perf/builtin-c2c.c | 3 +- tools/perf/builtin-ftrace.c | 243 +++++++++++++++ tools/perf/builtin-help.c | 6 +- tools/perf/builtin-kmem.c | 8 +- tools/perf/builtin-record.c | 4 +- tools/perf/builtin-report.c | 4 +- tools/perf/builtin-script.c | 338 ++++++++++++++++++++- tools/perf/builtin-top.c | 4 +- tools/perf/builtin.h | 1 + tools/perf/command-list.txt | 1 + tools/perf/perf.c | 16 +- tools/perf/tests/llvm.c | 2 +- tools/perf/ui/browsers/hists.c | 60 ++-- tools/perf/util/Build | 1 + tools/perf/util/callchain.c | 14 +- tools/perf/util/config.c | 9 +- tools/perf/util/data-convert-bt.c | 7 +- tools/perf/util/dis.c | 15 + tools/perf/util/dis.h | 23 ++ tools/perf/util/dso.c | 48 ++- tools/perf/util/header.c | 4 +- tools/perf/util/hist.c | 4 +- tools/perf/util/intel-pt.c | 4 +- tools/perf/util/llvm-utils.c | 4 +- tools/perf/util/probe-event.c | 11 +- .../perf/util/scripting-engines/trace-event-perl.c | 6 +- tools/perf/util/trace-event-info.c | 33 +- tools/perf/util/trace-event-parse.c | 17 ++ tools/perf/util/trace-event-read.c | 77 ++++- tools/perf/util/trace-event.h | 1 + tools/perf/util/unwind-libunwind-local.c | 54 +++- 46 files changed, 1192 insertions(+), 133 deletions(-) create mode 100644 tools/build/feature/test-xed.c create mode 100644 tools/perf/Documentation/perf-ftrace.txt create mode 100644 tools/perf/arch/x86/util/dis.c create mode 100644 tools/perf/builtin-ftrace.c create mode 100644 tools/perf/util/dis.c create mode 100644 tools/perf/util/dis.h
Test results:
The first ones are container (docker) based builds of tools/perf with and without libelf support, objtool where it is supported and samples/bpf/, ditto.
Several are cross builds, the ones with -x-ARCH, and the android one, and those may not have all the features built, due to lack of multi-arch devel packages, available and being used so far on just a few, like debian:experimental-x-{arm64,mipsel}.
The 'perf test' one will perform a variety of tests exercising tools/perf/util/, tools/lib/{bpf,traceevent,etc}, as well as run perf commands with a variety of command line event specifications to then intercept the sys_perf_event syscall to check that the perf_event_attr fields are set up as expected, among a variety of other unit tests.
Then there is the 'make -C tools/perf build-test' ones, that build tools/perf/ with a variety of feature sets, exercising the build with an incomplete set of features as well as with a complete one. It is planned to have it run on each of the containers mentioned above, using some container orchestration infrastructure. Get in contact if interested in helping having this in place.
# dm 1 alpine:3.4: Ok 2 android-ndk:r12b-arm: Ok 3 archlinux:latest: Ok 4 centos:5: Ok 5 centos:6: Ok 6 centos:7: Ok 7 debian:7: Ok 8 debian:8: Ok 9 debian:experimental: Ok 10 debian:experimental-x-arm64: Ok 11 debian:experimental-x-mips: Ok 12 debian:experimental-x-mips64: Ok 13 debian:experimental-x-mipsel: Ok 14 fedora:20: Ok 15 fedora:21: Ok 16 fedora:22: Ok 17 fedora:23: Ok 18 fedora:24: Ok 19 fedora:24-x-ARC-uClibc: Ok 20 fedora:25: Ok 21 fedora:rawhide: Ok 22 mageia:5: Ok 23 opensuse:13.2: Ok 24 opensuse:42.1: Ok 25 opensuse:tumbleweed: Ok 26 ubuntu:12.04.5: Ok 27 ubuntu:14.04.4-x-linaro-arm64: Ok 28 ubuntu:15.10: Ok 29 ubuntu:16.04: Ok 30 ubuntu:16.04-x-arm: Ok 31 ubuntu:16.04-x-arm64: Ok 32 ubuntu:16.04-x-powerpc: Ok 33 ubuntu:16.04-x-powerpc64: Ok 34 ubuntu:16.04-x-powerpc64el: Ok 35 ubuntu:16.04-x-s390: Ok 36 ubuntu:16.10: Ok #
# uname -a Linux jouet 4.9.0+ #2 SMP Wed Dec 21 11:54:44 BRT 2016 x86_64 x86_64 x86_64 GNU/Linux # perf test 1: vmlinux symtab matches kallsyms : Ok 2: Detect openat syscall event : Ok 3: Detect openat syscall event on all cpus : Ok 4: Read samples using the mmap interface : Ok 5: Parse event definition strings : Ok 6: PERF_RECORD_* events & perf_sample fields : Ok 7: Parse perf pmu format : Ok 8: DSO data read : Ok 9: DSO data cache : Ok 10: DSO data reopen : Ok 11: Roundtrip evsel->name : Ok 12: Parse sched tracepoints fields : Ok 13: syscalls:sys_enter_openat event fields : Ok 14: Setup struct perf_event_attr : Ok 15: Match and link multiple hists : Ok 16: 'import perf' in python : Ok 17: Breakpoint overflow signal handler : Ok 18: Breakpoint overflow sampling : Ok 19: Number of exit events of a simple workload : Ok 20: Software clock events period values : Ok 21: Object code reading : Ok 22: Sample parsing : Ok 23: Use a dummy software event to keep tracking: Ok 24: Parse with no sample_id_all bit set : Ok 25: Filter hist entries : Ok 26: Lookup mmap thread : Ok 27: Share thread mg : Ok 28: Sort output of hist entries : Ok 29: Cumulate child hist entries : Ok 30: Track with sched_switch : Ok 31: Filter fds with revents mask in a fdarray : Ok 32: Add fd to a fdarray, making it autogrow : Ok 33: kmod_path__parse : Ok 34: Thread map : Ok 35: LLVM search and compile : 35.1: Basic BPF llvm compile : Ok 35.2: kbuild searching : Ok 35.3: Compile source for BPF prologue generation: Ok 35.4: Compile source for BPF relocation : Ok 36: Session topology : Ok 37: BPF filter : 37.1: Basic BPF filtering : Ok 37.2: BPF prologue generation : Ok 37.3: BPF relocation checker : Ok 38: Synthesize thread map : Ok 39: Remove thread map : Ok 40: Synthesize cpu map : Ok 41: Synthesize stat config : Ok 42: Synthesize stat : Ok 43: Synthesize stat round : Ok 44: Synthesize attr update : Ok 45: Event times : Ok 46: Read backward ring buffer : Ok 47: Print cpu map : Ok 48: Probe SDT events : Ok 49: is_printable_array : Ok 50: Print bitmap : Ok 51: perf hooks : Ok 52: builtin clang support : Skip (not compiled in) 53: unit_number__scnprintf : Ok 54: x86 rdpmc : Ok 55: Convert perf time to TSC : Ok 56: DWARF unwind : Ok 57: x86 instruction decoder - new instructions : Ok 58: Intel cqm nmi context read : Skip #
$ make -C tools/perf build-test
make: Entering directory '/home/acme/git/linux/tools/perf'
- tarpkg: ./tests/perf-targz-src-pkg .
make_no_libbpf_O: make NO_LIBBPF=1
make_no_demangle_O: make NO_DEMANGLE=1
make_tags_O: make tags
make_no_libbionic_O: make NO_LIBBIONIC=1
make_help_O: make help
make_no_ui_O: make NO_NEWT=1 NO_SLANG=1 NO_GTK2=1
make_no_libnuma_O: make NO_LIBNUMA=1
make_no_libdw_dwarf_unwind_O: make NO_LIBDW_DWARF_UNWIND=1
make_no_libunwind_O: make NO_LIBUNWIND=1
make_no_newt_O: make NO_NEWT=1
make_install_prefix_slash_O: make install prefix=/tmp/krava/
make_no_auxtrace_O: make NO_AUXTRACE=1
make_install_prefix_O: make install prefix=/tmp/krava
make_with_clangllvm_O: make LIBCLANGLLVM=1
make_debug_O: make DEBUG=1
make_util_map_o_O: make util/map.o
make_no_libelf_O: make NO_LIBELF=1
make_install_bin_O: make install-bin
make_no_libpython_O: make NO_LIBPYTHON=1
make_install_O: make install
make_no_scripts_O: make NO_LIBPYTHON=1 NO_LIBPERL=1
make_no_gtk2_O: make NO_GTK2=1
make_pure_O: make
make_no_libperl_O: make NO_LIBPERL=1
make_no_slang_O: make NO_SLANG=1
make_no_backtrace_O: make NO_BACKTRACE=1
make_with_babeltrace_O: make LIBBABELTRACE=1
make_util_pmu_bison_o_O: make util/pmu-bison.o
make_no_libaudit_O: make NO_LIBAUDIT=1
make_clean_all_O: make clean all
make_perf_o_O: make perf.o
make_static_O: make LDFLAGS=-static
make_doc_O: make doc
make_minimal_O: make NO_LIBPERL=1 NO_LIBPYTHON=1 NO_NEWT=1 NO_GTK2=1 NO_DEMANGLE=1 NO_LIBELF=1 NO_LIBUNWIND=1 NO_BACKTRACE=1 NO_LIBNUMA=1 NO_LIBAUDIT=1 NO_LIBBIONIC=1 NO_LIBDW_DWARF_UNWIND=1 NO_AUXTRACE=1 NO_LIBBPF=1 NO_LIBCRYPTO=1 NO_SDT=1 NO_JVMTI=1
OK
make: Leaving directory '/home/acme/git/linux/tools/perf'
$ Arnaldo Carvalho de Melo
maintainerPATCH 1/23 perf unwind: Fix looking up dwarf unwind stack info
From: Matija Glavinic Pecotic <[email protected]>
Using perf with call graph method dwarf fails to provide backtrace support for stripped binary even though .gnu_debuglink points to *.dbg flavor with properly populated debug symbols.
Problem is reproduced on ARM (v7, v8), kernels 3.14.y, 4.4.y and 4.10.rc3. Perf is configured with libunwind, and unwind dwarf support [1]. Test code (stress_bt.c) can be found on [2].
Running (explicitly disable other unwinding methods):
$ gcc -g -o stress_bt -fomit-frame-pointer -fno-unwind-tables \ -fno-asynchronous-unwind-tables stress_bt.c $ perf record -N --call-graph dwarf ./stress_bt $ perf report
results in properly generated call graph. Stripping the binary and running it results with missing call graph. Expected result is to have call graph:
$ gcc -g -o stress_bt -fomit-frame-pointer -fno-unwind-tables \ -fno-asynchronous-unwind-tables stress_bt.c $ objcopy --only-keep-debug stress_bt stress_bt.dbg $ objcopy --strip-debug stress_bt $ objcopy --add-gnu-debuglink=stress_bt.dbg stress_bt $ perf record -N --call-graph dwarf ./stress_bt $ perf report
Problem is that perf doesn't try to read symbols pointed by gnu debuglink. Patch adds checking, and reading of the symbols from debuglink and symsrc. Order of the check is to first check within dso, then check whether symsrc is defined and try to read from it. Finally, debuglink is checked. Default locations of debug files are discussed in
[3] and [4]. Comments on RFC are on [5].
[1] https://wiki.linaro.org/LEG/Engineering/TOOLS/perf-callstack-unwinding
[2] [1]#Backtrace_stress_application
[3] https://sourceware.org/gdb/onlinedocs/gdb/Separate-Debug-Files.html
[4] https://sourceware.org/binutils/docs/binutils/objcopy.html
[5] https://lkml.org/lkml/2016/8/22/473
--- tools/perf/util/dso.c | 48 +++++++++++++++++++++------- tools/perf/util/unwind-libunwind-local.c | 54 +++++++++++++++++++++++++++++--- 2 files changed, 86 insertions(+), 16 deletions(-)
tools/perf/util/dso.c +37 -11
@@ -9,6 +9,13 @@#include "debug.h" #include "vdso.h" +static const char *const debuglink_paths[] = { +"%.0s%s" , +"%s/%s" , +"%s/.debug/%s" , +"/usr/lib/debug%s/%s" +}; +char dso__symtab_origin (const struct dso *dso) {static const char origin[] = {
@@ -44,24 +51,43 @@ int dso__read_binary_type_filename(const struct dso *dso,size_t len;switch (type) { -case DSO_BINARY_TYPE__DEBUGLINK : { -char *debuglink; +case DSO_BINARY_TYPE__DEBUGLINK : + { +const char *last_slash; +char dso_dir[PATH_MAX ]; +char symfile[PATH_MAX ]; +unsigned int i; len =__symbol__join_symfs (filename, size, dso->long_name); - debuglink = filename + len; -while (debuglink != filename && *debuglink !='/' ) - debuglink--; -if (*debuglink =='/' ) - debuglink++; + last_slash = filename + len; +while (last_slash != filename && *last_slash !='/' ) + last_slash--; - ret =-1 ; -if (!is_regular_file (filename)) +strncpy (dso_dir, filename, last_slash - filename); + dso_dir[last_slash-filename] ='\0' ; + +if (!is_regular_file (filename)) { + ret =-1 ; +break ; + } + + ret =filename__read_debuglink (filename, symfile,PATH_MAX ); +if (ret)break ; - ret =filename__read_debuglink (filename, debuglink, - size - (debuglink - filename)); +/* Check predefined locations where debug file might reside */ + ret =-1 ; +for (i =0 ; i <ARRAY_SIZE (debuglink_paths); i++) { +snprintf (filename, size, + debuglink_paths[i], dso_dir, symfile); +if (is_regular_file (filename)) { + ret =0 ; +break ; + } } +break ; + }case DSO_BINARY_TYPE__BUILD_ID_CACHE :if (dso__build_id_filename (dso, filename, size) ==NULL ) ret =-1 ;
tools/perf/util/unwind-libunwind-local.c +49 -5
70 lines not on this page · raw message
Signature · 1 line
2.9.3
Arnaldo Carvalho de Melo
maintainerPATCH 2/23 perf hists browser: Put hist_entry folding logic into single function
In reply to Arnaldo Carvalho de MeloFrom: Jiri Olsa <[email protected]>
It will be used in following patch to expand or collapse only the current browser entry.
--- tools/perf/ui/browsers/hists.c | 43 ++++++++++++++++++++++++------------------ 1 file changed, 25 insertions(+), 18 deletions(-)
tools/perf/ui/browsers/hists.c +25 -18
@@ -501,8 +501,8 @@ static int hierarchy_set_folding(struct hist_browser *hb, struct hist_entry *he,return n; } -static void hist_entry__set_folding (struct hist_entry *he, -struct hist_browser *hb,bool unfold) +static void __hist_entry__set_folding (struct hist_entry *he, +struct hist_browser *hb,bool unfold) {hist_entry__init_have_children (he); he->unfolded = unfold ? he->has_children : false;
@@ -520,12 +520,34 @@ static void hist_entry__set_folding(struct hist_entry *he, he->nr_rows =0 ; } +static void hist_entry__set_folding (struct hist_entry *he, +struct hist_browser *browser,bool unfold) +{ +double percent; + + percent =hist_entry__get_percent_limit (he); +if (he->filtered || percent < browser->min_pcnt) +return ; + +__hist_entry__set_folding (he, browser, unfold); + +if (!he->depth || unfold) + browser->nr_hierarchy_entries++; +if (he->leaf) + browser->nr_callchain_rows += he->nr_rows; +else if (unfold && !hist_entry__has_hierarchy_children (he, browser->min_pcnt)) { + browser->nr_hierarchy_entries++; + he->has_no_entry = true; + he->nr_rows =1 ; + }else + he->has_no_entry = false; +} +static void __hist_browser__set_folding (struct hist_browser *browser,bool unfold) {struct rb_node *nd;struct hist_entry *he; -double percent; nd =rb_first (&browser->hists->entries);while (nd) {
@@ -535,21 +557,6 @@ __hist_browser__set_folding(struct hist_browser *browser, bool unfold) nd =__rb_hierarchy_next (nd,HMD_FORCE_CHILD );hist_entry__set_folding (he, browser, unfold); - - percent =hist_entry__get_percent_limit (he); -if (he->filtered || percent < browser->min_pcnt) -continue ; - -if (!he->depth || unfold) - browser->nr_hierarchy_entries++; -if (he->leaf) - browser->nr_callchain_rows += he->nr_rows; -else if (unfold && !hist_entry__has_hierarchy_children (he, browser->min_pcnt)) { - browser->nr_hierarchy_entries++; - he->has_no_entry = true; - he->nr_rows =1 ; - }else - he->has_no_entry = false; } }
Signature · 1 line
2.9.3
Arnaldo Carvalho de Melo
maintainerPATCH 3/23 perf hists browser: Add e/c hotkeys to expand/collapse callchain for current entry
In reply to Arnaldo Carvalho de MeloFrom: Jiri Olsa <[email protected]>
Currently we allow only to expand or collapse all entries in the browser with 'E' or 'C' keys. Allow user to expand or collapse only current entry in the browser with e or c key.
--- tools/perf/ui/browsers/hists.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+)
tools/perf/ui/browsers/hists.c +17 -0
@@ -571,6 +571,15 @@ static void hist_browser__set_folding(struct hist_browser *browser, bool unfold)ui_browser__reset_index (&browser->b); } +static void hist_browser__set_folding_selected (struct hist_browser *browser,bool unfold) +{ +if (!browser->he_selection) +return ; + +hist_entry__set_folding (browser->he_selection, browser, unfold); + browser->b.nr_entries =hist_browser__nr_entries (browser); +} +static void ui_browser__warn_lost_events (struct ui_browser *browser) { ui_browser__warning(browser, 4,
@@ -644,10 +653,18 @@ int hist_browser__run(struct hist_browser *browser, const char *help)/* Collapse the whole world. */ hist_browser__set_folding (browser, false);break ; +case 'c' : +/* Collapse the selected entry. */ +hist_browser__set_folding_selected (browser, false); +break ;case 'E' :/* Expand the whole world. */ hist_browser__set_folding (browser, true);break ; +case 'e' : +/* Expand the selected entry. */ +hist_browser__set_folding_selected (browser, true); +break ;case 'H' : browser->show_headers = !browser->show_headers;hist_browser__update_rows (browser);
Signature · 1 line
2.9.3
Arnaldo Carvalho de Melo
maintainerPATCH 4/23 perf c2c report: Display Total records column in offset view
In reply to Arnaldo Carvalho de MeloFrom: Jiri Olsa <[email protected]>
Adding "Total records" column into cacheline pareto table, between cycles and cpu info.
$ perf c2c report ...
--- ---------- cycles ---------- Total cpu
rmt hitm lcl hitm load records cnt ... ........ ........ ........ ....... ........
0 112 71 34 4
0 0 0 18 1
0 0 0 2 1
0 132 0 3 3...
It's useful to see how many recorded samples represent each offset.
--- tools/perf/builtin-c2c.c | 1 + 1 file changed, 1 insertion(+)
tools/perf/builtin-c2c.c +1 -0
@@ -2476,6 +2476,7 @@ static int build_cl_output(char *cl_sort, bool no_source)"mean_rmt," "mean_lcl," "mean_load," +"tot_recs," "cpucnt," , add_sym ?"symbol," :"" , add_dso ? "dso," : "",
Signature · 1 line
2.9.3
Arnaldo Carvalho de Melo
maintainerPATCH 5/23 perf c2c report: Coalesce by default only by pid,iaddr
In reply to Arnaldo Carvalho de MeloFrom: Jiri Olsa <[email protected]>
It seems to be the most used argument for -c option so far. In the beginning when you want to have the overall process report, so it makes sense to make it the default one.
--- tools/perf/Documentation/perf-c2c.txt | 2 +- tools/perf/builtin-c2c.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-)
tools/perf/Documentation/perf-c2c.txt +1 -1
@@ -248,7 +248,7 @@ output fields set for caheline offsets output: Code address, Code symbol, Shared Object, Source line dso - coalesced by shared object -By default the coalescing is setup with 'pid,tid,iaddr'. +By default the coalescing is setup with 'pid,iaddr'. STDIO OUTPUT ------------
tools/perf/builtin-c2c.c +1 -1
@@ -58,7 +58,7 @@ struct c2c_hist_entry {struct hist_entry he; }; -static char const *coalesce_default ="pid,tid,iaddr" ; +static char const *coalesce_default ="pid,iaddr" ;struct perf_c2c {struct perf_tool tool;
Signature · 1 line
2.9.3
Arnaldo Carvalho de Melo
maintainerPATCH 6/23 perf tools: Add probing for the XED disassembler library
In reply to Arnaldo Carvalho de MeloFrom: Andi Kleen <[email protected]>
Can be downloaded from https://github.com/intelxed/xed
v2: Hide. Require XED=1 to enable. Add XED_DIR
v3: Remove -lxed from probe all. Don't touch FEATURE_DISPLAY.
v4: Move to FEATURE_FLAGS_BASIC
Committer Notes:
Quoted 1 line
---
The X86 Encoder Decoder (XED), is a software library (and associated headers) for encoding and decoding X86 (IA32 and Intel64) instructions. The decoder takes sequences of 1-15 bytes along with machine mode information and produces a data structure describing the opcode, operands, and flags. The encoder takes a similar data structure and produces a sequence of 1 to 15 bytes. Disassembly is essentially a printing pass on the data structure.
XED is the encoder/decoder used by Pin and the Intel® Software Development Emulator (SDE). XED is used by the ASIM performance model, ZSIM, Intel® VTune Amplifier, IACA, as well as in projects at McAfee, Wind River, and many other projects inside and outside Intel.
XED supports the notion of layers of instructions. As new instructions are made public corresponding to future processors, the associated layers are added to the tables of instructions in the "datafiles" subdirectory. (Intel announces and documents instructions in the ISE and SDM documents typically).
---
XED License: Apache, version 2.0.
Also remove it from test-all.c, since it is not normally available on distros at this time and not selected by default.
For the same reason, move it from FEATURE_TESTS_BASIC to FEATURE_TESTS_EXTRA, to avoid always trying to build tools/build/feature/test-xed.c.
One has to define XED=1 to build WITH the XED disassembler to be used in 'perf script'. It is also possible to set XED_DIR=/path to set the XED directory.
Added the XED_DIR to CFLAGS in addition to the feature detection specific CFLAGS, so that the following patches can work.
Testing it:
WITHOUT XED in the system, NOT explicitely selecting it:
$ make O=/tmp/build/perf -C tools/perf install-bin $ cat /tmp/build/perf/feature/test-xed.make.output cat: /tmp/build/perf/feature/test-xed.make.output: No such file or directory $
The feature test is NOT performed, ok.
WITHOUT XED in the system, EXPLICITELY selecting it:
$ make XED=1 O=/tmp/build/perf -C tools/perf install-bin
$ cat /tmp/build/perf/feature/test-xed.make.output
test-xed.c:1:31: fatal error: xed/xed-interface.h: No such file or directory
#include <xed/xed-interface.h>
^
compilation terminated.
$Ok, the test _IS_ performed, the required devel files are not found, the build is done without XED.
Now lets try building and installing xed in this system:
$ git clone https://github.com/intelxed/mbuild.git $ git clone https://github.com/intelxed/xed.git $ cd xed $ ./mfile.py $ ./mfile.py install
And lets try enabling XED, informing where 'mfile.py install' installed it:
$ make XED=1 XED_DIR=/home/acme/git/xed/kits/xed-install-base-2017-01-23-lin-x86-64/ O=/tmp/build/perf -C tools/perf install-bin $ ls -la /tmp/build/perf/feature/test-xed.make.output -rw-rw-r--. 1 acme acme 0 Jan 23 10:57 /tmp/build/perf/feature/test-xed.make.output $
But it still doesn't link with /home/acme/git/xed/kits/xed-install-base-2017-01-23-lin-x86-64/lib/libxed.a because the feature will only be used in the following csets.
--- tools/build/Makefile.feature | 4 +++- tools/build/feature/Makefile | 6 +++++- tools/build/feature/test-all.c | 14 ++++++++++++++ tools/build/feature/test-xed.c | 9 +++++++++ tools/perf/Makefile.config | 19 +++++++++++++++++++ tools/perf/Makefile.perf | 3 +++ 6 files changed, 53 insertions(+), 2 deletions(-) create mode 100644 tools/build/feature/test-xed.c
tools/build/Makefile.feature +3 -1
@@ -78,7 +78,8 @@ FEATURE_TESTS_EXTRA := \ liberty-z \ libunwind-debug-frame \ libunwind-debug-frame-arm \ - libunwind-debug-frame-aarch64 + libunwind-debug-frame-aarch64 \ + xed FEATURE_TESTS ?= $(FEATURE_TESTS_BASIC)
@@ -140,6 +141,7 @@ ifeq ($(feature-all), 1) $(call feature_check,compile-x32) $(call feature_check,bionic) $(call feature_check,libbabeltrace) + $(call feature_check,xed) else $(foreach feat,$(FEATURE_TESTS),$(call feature_check,$(feat))) endif
tools/build/feature/Makefile +5 -1
@@ -48,7 +48,8 @@ FILES= \ test-get_cpuid.bin \ test-sdt.bin \ test-cxx.bin \ - test-jvmti.bin + test-jvmti.bin \ + test-xed.bin FILES := $(addprefix $(OUTPUT),$(FILES))
@@ -123,6 +124,9 @@ $(OUTPUT)test-numa_num_possible_cpus.bin: $(OUTPUT)test-libunwind.bin: $(BUILD) -lelf +$(OUTPUT)test-xed.bin: + $(BUILD) -lxed + $(OUTPUT)test-libunwind-debug-frame.bin: $(BUILD) -lelf $(OUTPUT)test-libunwind-x86.bin:
tools/build/feature/test-all.c +14 -0
@@ -129,6 +129,19 @@#undef main#endif +#if 0 +/* +* Disable xed check for test-all, because it is not available +* in most distributions. Will reenable when it becomes generally +* available in major distros. +*/ +#define main main_test_xed +# include "test-xed.c" +#endif +#else +#define main_test_xed while(0) +#endif +#define main main_test_lzma# include "test-lzma.c" #undef main
@@ -183,6 +196,7 @@ int main(int argc, char *argv[])main_test_bpf ();main_test_libcrypto ();main_test_sdt (); +main_test_xed ();return 0 ; }
tools/build/feature/test-xed.c new file +9 -0
@@ -0,0 +1,9 @@ +#include <xed/xed-interface.h> +#include <xed/xed-decode.h> +#include <xed/xed-decoded-inst-api.h> + +int main (void ) +{ +xed_tables_init (); +return 0 ; +}
tools/perf/Makefile.config +19 -0
@@ -684,6 +684,25 @@ ifndef NO_ZLIB endif endif +ifdef XED + ifdef XED_DIR + XED_CFLAGS := -DHAVE_XED_SUPPORT -I$(XED_DIR)/include + XED_LDFLAGS := -L$(XED_DIR)/lib + endif + FEATURE_CHECK_CFLAGS-xed := $(XED_CFLAGS) + # override for lib64? + FEATURE_CHECK_LDFLAGS-xed := $(XED_LDFLAGS) -lxed + $(call feature_check,xed) + ifeq ($(feature-xed), 1) + CFLAGS += $(XED_CFLAGS) + LDFLAGS += $(XED_LDFLAGS) + EXTLIBS += -lxed + $(call detected,CONFIG_XED) + else + msg := $(warning No xed found, disables x86 disassembler support, please install xed); + endif +endif + ifndef NO_LZMA ifeq ($(feature-lzma), 1) CFLAGS += -DHAVE_LZMA_SUPPORT
tools/perf/Makefile.perf +3 -0
@@ -84,6 +84,9 @@ include ../scripts/utilities.mak # Define NO_SDT if you do not want to define SDT event in perf tools, # note that it doesn't disable SDT scanning support. # +# Define XED=1 to build WITH the XED disassembler for perf script +# Can also set XED_DIR=/path to set XED directory. +# # Define FEATURES_DUMP to provide features detection dump file # and bypass the feature detection #
Signature · 1 line
2.9.3
Arnaldo Carvalho de Melo
maintainerPATCH 7/23 perf tools: Add one liner warning for disabled features
In reply to Arnaldo Carvalho de MeloFrom: Andi Kleen <[email protected]>
Add a one liner warning for perf features that need to be enabled explicitly by the user, so that they know they are missing something.
Currently enabled for XED and BABELTRACE.
Committer notes:
Testing it:
$ make O=/tmp/build/perf -C tools/perf
make: Entering directory '/home/acme/git/linux/tools/perf'
Makefile.config:853: Disabled features, need explicit enabling by user: XED LIBBABELTRACE
make: Leaving directory '/home/acme/git/linux/tools/perf'
$
$ make O=/tmp/build/perf XED=1 -C tools/perf
make: Entering directory '/home/acme/git/linux/tools/perf'
Makefile.config:853: Disabled features, need explicit enabling by user: LIBBABELTRACE
make: Leaving directory '/home/acme/git/linux/tools/perf'
$
$ make O=/tmp/build/perf LIBBABELTRACE=1 -C tools/perf
make: Entering directory '/home/acme/git/linux/tools/perf'
Makefile.config:853: Disabled features, need explicit enabling by user: XED
CC /tmp/build/perf/arch/common.o
<SNIP>
$
$ make O=/tmp/build/perf XED=1 LIBBABELTRACE=1 -C tools/perf
make: Entering directory '/home/acme/git/linux/tools/perf'
BUILD: Doing 'make -j4' parallel build
make: Leaving directory '/home/acme/git/linux/tools/perf'
$--- tools/perf/Makefile.config | 10 ++++++++++ 1 file changed, 10 insertions(+)
tools/perf/Makefile.config +10 -0
@@ -65,6 +65,8 @@ ifneq ($(ARCH),$(filter $(ARCH),x86 arm)) NO_LIBDW_DWARF_UNWIND := 1 endif +DISABLED_FEATURES = + ifeq ($(LIBUNWIND_LIBS),) NO_LIBUNWIND := 1 endif
@@ -701,6 +703,8 @@ ifdef XED else msg := $(warning No xed found, disables x86 disassembler support, please install xed); endif +else + DISABLED_FEATURES += XED endif ifndef NO_LZMA
@@ -775,6 +779,8 @@ ifdef LIBBABELTRACE else msg := $(warning No libbabeltrace found, disables 'perf data' CTF format support, please install libbabeltrace-dev[el]/libbabeltrace-ctf-dev); endif +else + DISABLED_FEATURES += LIBBABELTRACE endif ifndef NO_AUXTRACE
@@ -846,6 +852,10 @@ ifdef LIBCLANGLLVM endif endif +ifneq ($(DISABLED_FEATURES),) + $(warning Disabled features, need explicit enabling by user: $(DISABLED_FEATURES)) +endif + # Among the variables below, these: # perfexecdir # template_dir
Signature · 1 line
2.9.3
Arnaldo Carvalho de Melo
maintainerPATCH 8/23 perf tools: Add disassembler for x86 using the XED library
In reply to Arnaldo Carvalho de MeloFrom: Andi Kleen <[email protected]>
Add a generic disassembler function for x86 using the XED library, and a fallback function for architectures that don't implement one. Other architectures can implement their own disassembler functions.
The previous version of this patch used udis86, but was rejected because udis86 was unmaintained and a runtime dependency. Using the recently released xed avoids both of these problems:
- XED is well maintained, uptodate, and used by many Intel tools
- XED is linked statically so there is no runtime dependency.
The XED library can be downloaded from http://github.com/intelxed/xed
v2: Clean up includes.
Committer notes:
- Aligned struct member definitions;
- Added missing includes to dis.h
- Went back to the feature detection patch to make sure the xed path is added to CFLAGS so that this patch can actually build.
Disable -Werror=old-style-declaration for tools/perf/arch/x86/util/dis.o due to xed header problems, for which we don't have control:
$ gcc --version gcc (GCC) 6.3.1 20161221 (Red Hat 6.3.1-1) $ make XED=1 XED_DIR=/home/acme/git/xed/kits/xed-install-base-2017-01-23-lin-x86-64 O=/tmp/build/perf -C tools/perf
CC /tmp/build/perf/tests/openat-syscall.o
In file included from /home/acme/git/xed/kits/xed-install-base-2017-01-23-lin-x86-64/include/xed/xed-inst.h:41:0,
from /home/acme/git/xed/kits/xed-install-base-2017-01-23-lin-x86-64/include/xed/xed-decoded-inst.h:28,
from /home/acme/git/xed/kits/xed-install-base-2017-01-23-lin-x86-64/include/xed/xed-decode.h:24,
from /home/acme/git/xed/kits/xed-install-base-2017-01-23-lin-x86-64/include/xed/xed-interface.h:40,
from arch/x86/util/dis.c:3:
/home/acme/git/xed/kits/xed-install-base-2017-01-23-lin-x86-64/include/xed/xed-iform-map.h:74:1: error: ‘inline’ is not at beginning of declaration [-Werror=old-style-declaration]
xed_iclass_enum_t XED_INLINE xed_iform_to_iclass(xed_iform_enum_t iform) {
^~~~~~~~~~~~~~~~~
In file included from /home/acme/git/xed/kits/xed-install-base-2017-01-23-lin-x86-64/include/xed/xed-interface.h:43:0,
from arch/x86/util/dis.c:3:Ditto for -Werror=switch-enum:
In file included from /home/acme/git/xed/kits/xed-install-base-2017-01-23-lin-x86-64/include/xed/xed-interface.h:43:0,
from arch/x86/util/dis.c:8:
/home/acme/git/xed/kits/xed-install-base-2017-01-23-lin-x86-64/include/xed/xed-state.h: In function ‘xed_state_get_address_width’:
/home/acme/git/xed/kits/xed-install-base-2017-01-23-lin-x86-64/include/xed/xed-state.h:144:5: error: enumeration value ‘XED_MACHINE_MODE_INVALID’ not handled in switch [-Werror=switch-enum]
switch(xed_state_get_machine_mode(p)) {
^~~~~~ /home/acme/git/xed/kits/xed-install-base-2017-01-23-lin-x86-64/include/xed/xed-state.h:144:5: error: enumeration value ‘XED_MACHINE_MODE_LAST’ not handled in switch [-Werror=switch-enum]
cc1: all warnings being treated as errors
mv: cannot stat '/tmp/build/perf/arch/x86/util/.dis.o.tmp': No such file or directory
/home/acme/git/linux/tools/build/Makefile.build:91: recipe for target '/tmp/build/perf/arch/x86/util/dis.o' failed
Now we have the static xed library linked with perf:
$ nm /tmp/build/perf/perf | grep "T xed" | head 0000000000682761 T xed3_decode_operands 0000000000682700 T xed3_dynamic_decode_part2 0000000000742002 T xed3_get_generic_operand 0000000000742ca4 T xed3_set_generic_operand 000000000068380e T xed3_static_decode 000000000064a6d0 T xed_attribute 000000000064a6ca T xed_attribute_max 00000000007409ab T xed_chip_enum_t2str 00000000007409d8 T xed_chip_enum_t_last 000000000074c8a7 T xed_dec_lu_ASZ_NONTERM_EASZ_MAP_MOD3_REXW_RM4_VEXVALID_VEX_PREFIX_VL $
--- tools/perf/arch/x86/util/Build | 3 ++ tools/perf/arch/x86/util/dis.c | 86 ++++++++++++++++++++++++++++++++++++++++++ tools/perf/util/Build | 1 + tools/perf/util/dis.c | 15 ++++++++ tools/perf/util/dis.h | 23 +++++++++++ 5 files changed, 128 insertions(+) create mode 100644 tools/perf/arch/x86/util/dis.c create mode 100644 tools/perf/util/dis.c create mode 100644 tools/perf/util/dis.h
tools/perf/arch/x86/util/Build +3 -0
@@ -14,3 +14,6 @@ libperf-$(CONFIG_LIBDW_DWARF_UNWIND) += unwind-libdw.o libperf-$(CONFIG_AUXTRACE) += auxtrace.o libperf-$(CONFIG_AUXTRACE) += intel-pt.o libperf-$(CONFIG_AUXTRACE) += intel-bts.o +libperf-$(CONFIG_XED) += dis.o + +CFLAGS_dis.o += -Wno-old-style-declaration -Wno-switch-enum
tools/perf/arch/x86/util/dis.c new file +86 -0
86 lines not on this page · raw message
tools/perf/util/Build +1 -0
@@ -88,6 +88,7 @@ libperf-y += mem-events.o libperf-y += vsprintf.o libperf-y += drv_configs.o libperf-y += time-utils.o +libperf-y += dis.o libperf-$(CONFIG_LIBBPF) += bpf-loader.o libperf-$(CONFIG_BPF_PROLOGUE) += bpf-prologue.o
tools/perf/util/dis.c new file +15 -0
@@ -0,0 +1,15 @@ +#include "perf.h" +#include "dis.h" +#include "util.h" + +/* Fallback for architectures with no disassembler */ + +__weak char *disas_inst (struct perf_dis *x,uint64_t ip__maybe_unused , +u8 *inbuf__maybe_unused ,int inlen__maybe_unused , +int *lenp) +{ +if (lenp) + *lenp =0 ; +strcpy (x->out,"?" ); +return x->out; +}
tools/perf/util/dis.h new file +23 -0
@@ -0,0 +1,23 @@ +#ifndef DIS_H +#define DIS_H 1 + +#include <stdbool.h> +#include <linux/types.h> + +struct thread ; + +#define MAXINSN 15 + +struct perf_dis { +/* Initialized by callers: */ +struct thread *thread; +u8 cpumode; +int cpu; +bool is64bit; +/* Temporary */ +char out[256 ]; +}; + +char *disas_inst (struct perf_dis *x,uint64_t ip,u8 *inbuf,int inlen,int *lenp); + +#endif
Signature · 1 line
2.9.3
Arnaldo Carvalho de Melo
maintainerPATCH 9/23 perf script: Add support for printing assembler
In reply to Arnaldo Carvalho de MeloFrom: Andi Kleen <[email protected]>
When dumping PT traces with perf script it is very useful to see the assembler for each sample, so that it is easily possible to follow the control flow.
As using objdump is difficult and inefficient from perf script this patch uses the Intel xed library to implement assembler output. The library can be downloaded from http://github.com/intelxed/xed
The previous version of this patch used udis86, but was rejected because udis86 was unmaintained and a runtime dependency. Using the recently released xed avoids both of these problems:
- XED is well maintained and used by many Intel tools
- XED is linked statically so there is no runtime dependency.
The library is probed as an external dependency in the usual way. Then perf script calls into it when needed, and handles callbacks to resolve symbols.
% perf record -e intel_pt//u true
% perf script -F sym,symoff,ip,asm --itrace=i0ns | head
7fc7188b4190 _start+0x0 mov %rsp, %rdi
7fc7188b4193 _start+0x3 call _dl_start
7fc7188b7710 _dl_start+0x0 push %rbp
7fc7188b7711 _dl_start+0x1 mov %rsp, %rbp
7fc7188b7714 _dl_start+0x4 push %r15
7fc7188b7716 _dl_start+0x6 push %r14
7fc7188b7718 _dl_start+0x8 push %r13
7fc7188b771a _dl_start+0xa push %r12
7fc7188b771c _dl_start+0xc mov %rdi, %r12
7fc7188b771f _dl_start+0xf push %rbxv2:
Converted to use XED instead of udis86.
Separate disassembler interface into separate arch specific file. Lots of cleanups and improvements.
Committer notes:
Testing it:
Disassembly of perf_evsel__enable() bits referenced in the samples collected for this test
'perf script' with this patch: DIFF objdump -d
4b8506 jz 0x4b84d0 <perf_evsel__enable+0x70> 74 c8 je 4b84d0 <perf_evsel__enable+0x70> 4b84d0 add $0x1, %r14 add $0x1,%r14 4b84d4 cmp %r14d, %ebx cmp %r14d,%ebx 4b84d7 jle 0x4b8530 <perf_evsel__enable+0xd0> jle 4b8530 <perf_evsel__enable+0xd0> 4b8530 add $0x1, %r12 add $0x1,%r12 4b8534 cmp %r12d, %r13d cmp %r12d,%r13d 4b8537 jnle 0x4b84c2 <perf_evsel__enable+0x62> 7f 89 jg 4b84c2 <perf_evsel__enable+0x62> 4b84c2 xor %r14d, %r14d xor %r14d,%r14d 4b84c5 test %ebx, %ebx test %ebx,%ebx 4b84c7 jnle 0x4b84d9 <perf_evsel__enable+0x79> 7f 10 jg 4b84d9 <perf_evsel__enable+0x79> 4b84d9 movq 0x90(%r15), %rax 49 8b 87 90 00 00 00 mov 0x90(%r15),%rax 4b84e0 mov %r12, %rdx mov %r12,%rdx 4b84e3 mov %r14, %rcx mov %r14,%rcx 4b84e6 mov $0x2400, %esi mov $0x2400,%esi 4b84eb imulq (%rax), %rdx 48 0f af 10 imul (%rax),%rdx 4b84ef imulq 0x8(%rax), %rcx 48 0f af 48 08 imul 0x8(%rax),%rcx 4b84f4 add %rdx, %rax add %rdx,%rax 4b84f7 xor %edx, %edx xor %edx,%edx 4b84f9 movl 0x18(%rcx,%rax,1), %edi 8b 7c 01 18 mov 0x18(%rcx,%rax,1),%edi 4b84fd xor %eax, %eax xor %eax,%eax 4b84ff callq 0x42d990 <ioctl@plt> callq 42d990 <ioctl@plt> 4b8504 test %eax, %eax test %eax,%eax 4b8506 jz 0x4b84d0 <perf_evsel__enable+0x70> 74 c8 je 4b84d0 <perf_evsel__enable+0x70>
--- tools/perf/Documentation/perf-script.txt | 4 +- tools/perf/builtin-script.c | 72 +++++++++++++++++++++++++++----- 2 files changed, 64 insertions(+), 12 deletions(-)
tools/perf/Documentation/perf-script.txt +3 -1
@@ -116,7 +116,7 @@ OPTIONS --fields:: Comma separated list of fields to print. Options are: comm, tid, pid, time, cpu, event, trace, ip, sym, dso, addr, symoff, - srcline, period, iregs, brstack, brstacksym, flags, bpf-output, + srcline, period, iregs, brstack, brstacksym, flags, bpf-output, asm. callindent, insn, insnlen. Field list can be prepended with the type, trace, sw or hw, to indicate to which event type the field list applies. e.g., -F sw:comm,tid,time,ip,sym and -F trace:time,cpu,trace
@@ -198,6 +198,8 @@ OPTIONS The brstacksym is identical to brstack, except that the FROM and TO addresses are printed in a symbolic form if possible. + When asm is specified the assembler instruction of each sample is printed in disassembled form. + -k:: --vmlinux=<file>:: vmlinux pathname
tools/perf/builtin-script.c +61 -11
154 lines not on this page · raw message
Signature · 1 line
2.9.3
Arnaldo Carvalho de Melo
maintainerPATCH 10/23 perf script: Add "brstackasm" output for branch stacks
In reply to Arnaldo Carvalho de MeloFrom: Andi Kleen <[email protected]>
Implement printing full disassembled sequences for branch stacks in perf script.
This allows to directly print hot paths for individual samples, together with branch misprediction and cycle count / IPC information if available (on Skylake systems).
This only works when no special branch filters are specified.
E.g.:
% perf record -b ...
% perf script -F brstackasm
...
000055b55d1147d0 pushq %rbp
000055b55d1147d1 pushq %r15
000055b55d1147d3 pushq %r14
000055b55d1147d5 pushq %r13
000055b55d1147d7 pushq %r12
000055b55d1147d9 pushq %rbx
000055b55d1147da sub $0x18, %rsp
000055b55d1147de mov %r8, %r13
000055b55d1147e1 mov %rcx, %rbp
000055b55d1147e4 mov %rdx, %r14
000055b55d1147e7 mov %rsi, %r15
000055b55d1147ea mov %rdi, %rbx
000055b55d1147ed movl $0x0, 0xc(%rsp)
000055b55d1147f5 movq (%rbp), %rax
000055b55d1147f9 test $0x1, %al
000055b55d1147fb jnz 0x55b55d114890 # PRED 4 cycles 3.75 IPC
000055b55d114890 mov %eax, %ecx
000055b55d114892 and $0x3, %ecx
000055b55d114895 cmp $0x1, %rcx
000055b55d114899 jnz 0x55b55d1148f8
000055b55d11489b movq -0x1(%rax), %rcx
000055b55d11489f cmpb $0x81, 0xb(%rcx)
000055b55d1148a3 jnz 0x55b55d1148fe # PRED 1 cycles 6.00 IPC...
Occasionally the path does not reach up to the sample IP, as the LBRs may be frozen before executing a final jump. In this case we print a special message.
v2:
Use low level abstracted disassembler interface.
Print symbols and source lines as labels.
Print first jump in LBR too.
Patch up blocks with filtered ring transfers.
Show IPC
Lots of cleanups and improvements.
v3:
Print special message for branches frozen early.
--- tools/perf/Documentation/perf-script.txt | 13 +- tools/perf/builtin-script.c | 268 +++++++++++++++++++++++++++++++ 2 files changed, 279 insertions(+), 2 deletions(-)
tools/perf/Documentation/perf-script.txt +11 -2
@@ -116,7 +116,7 @@ OPTIONS --fields:: Comma separated list of fields to print. Options are: comm, tid, pid, time, cpu, event, trace, ip, sym, dso, addr, symoff, - srcline, period, iregs, brstack, brstacksym, flags, bpf-output, asm. + srcline, period, iregs, brstack, brstacksym, flags, bpf-output, asm, brstackasm, callindent, insn, insnlen. Field list can be prepended with the type, trace, sw or hw, to indicate to which event type the field list applies. e.g., -F sw:comm,tid,time,ip,sym and -F trace:time,cpu,trace
@@ -189,17 +189,22 @@ OPTIONS i.e., -F "" is not allowed. The brstack output includes branch related information with raw addresses using the - /v/v/v/v/ syntax in the following order: + /v/v/v/v/cycles syntax in the following order: FROM: branch source instruction TO : branch target instruction M/P/-: M=branch target mispredicted or branch direction was mispredicted, P=target predicted or direction predicted, -=not supported X/- : X=branch inside a transactional region, -=not in transaction region or not supported A/- : A=TSX abort entry, -=not aborted region or not supported + cycles The brstacksym is identical to brstack, except that the FROM and TO addresses are printed in a symbolic form if possible. When asm is specified the assembler instruction of each sample is printed in disassembled form. + When brstackasm is specified the full assembler sequences of branch sequences for each sample + is printed. This is the full execution path leading to the sample. This is only supported when the + sample was recorded with perf record -b or -j any. + -k:: --vmlinux=<file>:: vmlinux pathname
@@ -301,6 +306,10 @@ include::itrace.txt[] stop time is not given (i.e, time string is 'x.y,') then analysis goes to end of file. +--max-blocks:: + Set the maximum number of program blocks to print with brstackasm for + each sample. + SEE ALSO -------- linkperf:perf-record[1], linkperf:perf-script-perl[1],
tools/perf/builtin-script.c +268 -0
310 lines not on this page · raw message
Signature · 1 line
2.9.3
Arnaldo Carvalho de Melo
maintainerPATCH 11/23 perf probe: Fix wrong register name for arm64
In reply to Arnaldo Carvalho de MeloFrom: He Kuang <[email protected]>
The register name of arm64 architecture is x0-x31 not r0-r31, this patch changes this typo.
Before this patch:
# perf probe --definition 'sys_write count' p:probe/sys_write _text+1502872 count=%r2:s64
# echo 'p:probe/sys_write _text+1502872 count=%r2:s64' > \
/sys/kernel/debug/tracing/kprobe_events
Parse error at argument[0]. (-22)After this patch:
# perf probe --definition 'sys_write count' p:probe/sys_write _text+1502872 count=%x2:s64
# echo 'p:probe/sys_write _text+1502872 count=%x2:s64' > \
/sys/kernel/debug/tracing/kprobe_events
# echo 1 >/sys/kernel/debug/tracing/events/probe/enable
# cat /sys/kernel/debug/tracing/trace
...
sh-422 [000] d... 650.495930: sys_write: (SyS_write+0x0/0xc8) count=22
sh-422 [000] d... 651.102389: sys_write: (SyS_write+0x0/0xc8) count=26
sh-422 [000] d... 651.358653: sys_write: (SyS_write+0x0/0xc8) count=86--- tools/perf/arch/arm64/include/dwarf-regs-table.h | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-)
tools/perf/arch/arm64/include/dwarf-regs-table.h +6 -6
@@ -2,12 +2,12 @@/* This is included in perf/util/dwarf-regs.c */ static const char *const aarch64_regstr_tbl[] = { -"%r0" ,"%r1" ,"%r2" ,"%r3" ,"%r4" , -"%r5" ,"%r6" ,"%r7" ,"%r8" ,"%r9" , -"%r10" ,"%r11" ,"%r12" ,"%r13" ,"%r14" , -"%r15" ,"%r16" ,"%r17" ,"%r18" ,"%r19" , -"%r20" ,"%r21" ,"%r22" ,"%r23" ,"%r24" , -"%r25" ,"%r26" ,"%r27" ,"%r28" ,"%r29" , +"%x0" ,"%x1" ,"%x2" ,"%x3" ,"%x4" , +"%x5" ,"%x6" ,"%x7" ,"%x8" ,"%x9" , +"%x10" ,"%x11" ,"%x12" ,"%x13" ,"%x14" , +"%x15" ,"%x16" ,"%x17" ,"%x18" ,"%x19" , +"%x20" ,"%x21" ,"%x22" ,"%x23" ,"%x24" , +"%x25" ,"%x26" ,"%x27" ,"%x28" ,"%x29" ,"%lr" ,"%sp" , };#endif
Signature · 1 line
2.9.3
Arnaldo Carvalho de Melo
maintainerPATCH 12/23 perf probe: Delete an unnecessary check in try_to_find_absolute_address()
In reply to Arnaldo Carvalho de MeloFrom: Markus Elfring <[email protected]>
Remove a condition check which is unnecessary at the end because this source code place should usually only be reached with a non-zero pointer.
--- tools/perf/util/probe-event.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-)
tools/perf/util/probe-event.c +2 -4
@@ -3004,10 +3004,8 @@ static int try_to_find_absolute_address(struct perf_probe_event *pev,return 1 ; errout: -if (*tevs) { -clear_probe_trace_events (*tevs,1 ); - *tevs =NULL ; - } +clear_probe_trace_events (*tevs,1 ); + *tevs =NULL ;return err; }
Signature · 1 line
2.9.3
Arnaldo Carvalho de Melo
maintainerPATCH 13/23 perf probe: Delete an unnecessary assignment in try_to_find_absolute_address()
In reply to Arnaldo Carvalho de MeloFrom: Markus Elfring <[email protected]>
Remove an error code assignment which is redundant in an if branch for the handling of a memory allocation failure because the same value was set for the local variable "err" before.
--- tools/perf/util/probe-event.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-)
tools/perf/util/probe-event.c +2 -3
@@ -2994,10 +2994,9 @@ static int try_to_find_absolute_address(struct perf_probe_event *pev, tev->nargs = pev->nargs; tev->args =zalloc (sizeof (struct probe_trace_arg ) * tev->nargs); -if (!tev->args) { - err = -ENOMEM ; +if (!tev->args) goto errout; - } +for (i =0 ; i < tev->nargs; i++)copy_to_probe_trace_arg (&tev->args[i], &pev->args[i]);
Signature · 1 line
2.9.3
Arnaldo Carvalho de Melo
maintainerPATCH 14/23 tools lib bpf: Fix map offsets in relocation
In reply to Arnaldo Carvalho de MeloFrom: Joe Stringer <[email protected]>
Commit 4708bbda5cb2 ("tools lib bpf: Fix maps resolution") attempted to fix map resolution by identifying the number of symbols that point to maps, and using this number to resolve each of the maps.
However, during relocation the original definition of the map size was still in use. For up to two maps, the calculation was correct if there was a small difference in size between the map definition in libbpf and the one that the client library uses. However if the difference was large, particularly if more than two maps were used in the BPF program, the relocation would fail.
For example, when using a map definition with size 28, with three maps, map relocation would count:
(sym_offset / sizeof(struct bpf_map_def) => map_idx)
(0 / 16 => 0), ie map_idx = 0
(28 / 16 => 1), ie map_idx = 1
(56 / 16 => 3), ie map_idx = 3So, libbpf reports:
libbpf: bpf relocation: map_idx 3 large than 2
Fix map relocation by checking the exact offset of maps when doing relocation.
--- tools/lib/bpf/libbpf.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-)
tools/lib/bpf/libbpf.c +12 -3
@@ -779,7 +779,7 @@ static int bpf_program__collect_reloc(struct bpf_program *prog, size_t nr_maps, GElf_Shdr *shdr, Elf_Data *data, Elf_Data *symbols, - int maps_shndx) + int maps_shndx, struct bpf_map *maps) { int i, nrels;
@@ -829,7 +829,15 @@ bpf_program__collect_reloc(struct bpf_program *prog,return -LIBBPF_ERRNO__RELOC ; } - map_idx = sym.st_value /sizeof (struct bpf_map_def ); +/* TODO: 'maps' is sorted. We can use bsearch to make it faster. */ +for (map_idx =0 ; map_idx < nr_maps; map_idx++) { +if (maps[map_idx].offset == sym.st_value) { +pr_debug ("relocation: find map %zd (%s) for insn %u\n" , + map_idx, maps[map_idx].name, insn_idx); +break ; + } + } +if (map_idx >= nr_maps) {pr_warning ("bpf relocation: map_idx %d large than %d\n" , (int )map_idx, (int )nr_maps -1 );
@@ -953,7 +961,8 @@ static int bpf_object__collect_reloc(struct bpf_object *obj) err =bpf_program__collect_reloc (prog, nr_maps, shdr, data, obj->efile.symbols, - obj->efile.maps_shndx); + obj->efile.maps_shndx, + obj->maps);if (err)return err; }
Signature · 1 line
2.9.3
Arnaldo Carvalho de Melo
maintainerPATCH 15/23 tools lib bpf: Define prog_type fns with macro
In reply to Arnaldo Carvalho de MeloFrom: Joe Stringer <[email protected]>
Turning this into a macro allows future prog types to be added with a single line per type.
--- tools/lib/bpf/libbpf.c | 41 ++++++++++++++++------------------------- 1 file changed, 16 insertions(+), 25 deletions(-)
tools/lib/bpf/libbpf.c +16 -25
@@ -1428,37 +1428,28 @@ static void bpf_program__set_type(struct bpf_program *prog, prog->type = type; } -int bpf_program__set_tracepoint (struct bpf_program *prog) -{ -if (!prog) -return -EINVAL ; -bpf_program__set_type (prog,BPF_PROG_TYPE_TRACEPOINT ); -return 0 ; -} - -int bpf_program__set_kprobe (struct bpf_program *prog) -{ -if (!prog) -return -EINVAL ; -bpf_program__set_type (prog,BPF_PROG_TYPE_KPROBE ); -return 0 ; -} -static bool bpf_program__is_type (struct bpf_program *prog,enum bpf_prog_type type) {return prog ? (prog->type == type) : false; } -bool bpf_program__is_tracepoint (struct bpf_program *prog) -{ -return bpf_program__is_type (prog,BPF_PROG_TYPE_TRACEPOINT ); -} - -bool bpf_program__is_kprobe (struct bpf_program *prog) -{ -return bpf_program__is_type (prog,BPF_PROG_TYPE_KPROBE ); -} +#define BPF_PROG_TYPE_FNS (NAME ,TYPE ) \ +int bpf_program__set_##NAME(struct bpf_program *prog) \ +{ \ + if (!prog) \ + return -EINVAL; \ + bpf_program__set_type(prog, TYPE); \ + return 0; \ +} \ + \ +bool bpf_program__is_##NAME(struct bpf_program *prog) \ +{ \ + return bpf_program__is_type(prog, TYPE); \ +} \ + +BPF_PROG_TYPE_FNS (kprobe,BPF_PROG_TYPE_KPROBE ); +BPF_PROG_TYPE_FNS (tracepoint,BPF_PROG_TYPE_TRACEPOINT );int bpf_map__fd (struct bpf_map *map) {
Signature · 1 line
2.9.3
Arnaldo Carvalho de Melo
maintainerPATCH 16/23 tools lib bpf: Add set/is helpers for all prog types
In reply to Arnaldo Carvalho de MeloFrom: Joe Stringer <[email protected]>
These bpf_prog_types were exposed in the uapi but there were no corresponding functions to set these types for programs in libbpf.
--- tools/lib/bpf/libbpf.c | 5 +++++ tools/lib/bpf/libbpf.h | 10 ++++++++++ 2 files changed, 15 insertions(+)
tools/lib/bpf/libbpf.c +5 -0
@@ -1448,8 +1448,13 @@ bool bpf_program__is_##NAME(struct bpf_program *prog) \return bpf_program__is_type (prog,TYPE ); \ } \ +BPF_PROG_TYPE_FNS (socket_filter,BPF_PROG_TYPE_SOCKET_FILTER );BPF_PROG_TYPE_FNS (kprobe,BPF_PROG_TYPE_KPROBE ); +BPF_PROG_TYPE_FNS (sched_cls,BPF_PROG_TYPE_SCHED_CLS ); +BPF_PROG_TYPE_FNS (sched_act,BPF_PROG_TYPE_SCHED_ACT );BPF_PROG_TYPE_FNS (tracepoint,BPF_PROG_TYPE_TRACEPOINT ); +BPF_PROG_TYPE_FNS (xdp,BPF_PROG_TYPE_XDP ); +BPF_PROG_TYPE_FNS (perf_event,BPF_PROG_TYPE_PERF_EVENT );int bpf_map__fd (struct bpf_map *map) {
tools/lib/bpf/libbpf.h +10 -0
@@ -174,11 +174,21 @@ int bpf_program__nth_fd(struct bpf_program *prog, int n);/* * Adjust type of bpf program. Default is kprobe. */ +int bpf_program__set_socket_filter (struct bpf_program *prog);int bpf_program__set_tracepoint (struct bpf_program *prog);int bpf_program__set_kprobe (struct bpf_program *prog); +int bpf_program__set_sched_cls (struct bpf_program *prog); +int bpf_program__set_sched_act (struct bpf_program *prog); +int bpf_program__set_xdp (struct bpf_program *prog); +int bpf_program__set_perf_event (struct bpf_program *prog); +bool bpf_program__is_socket_filter (struct bpf_program *prog);bool bpf_program__is_tracepoint (struct bpf_program *prog);bool bpf_program__is_kprobe (struct bpf_program *prog); +bool bpf_program__is_sched_cls (struct bpf_program *prog); +bool bpf_program__is_sched_act (struct bpf_program *prog); +bool bpf_program__is_xdp (struct bpf_program *prog); +bool bpf_program__is_perf_event (struct bpf_program *prog);/* * We don't need __attribute__((packed)) now since it is
Signature · 1 line
2.9.3
Arnaldo Carvalho de Melo
maintainerPATCH 17/23 tools lib bpf: Add libbpf_get_error()
In reply to Arnaldo Carvalho de MeloFrom: Joe Stringer <[email protected]>
This function will turn a libbpf pointer into a standard error code (or 0 if the pointer is valid).
This also allows removal of the dependency on linux/err.h in the public header file, which causes problems in userspace programs built against libbpf.
--- tools/lib/bpf/libbpf.c | 8 ++++++++ tools/lib/bpf/libbpf.h | 4 +++- tools/perf/tests/llvm.c | 2 +- 3 files changed, 12 insertions(+), 2 deletions(-)
tools/lib/bpf/libbpf.c +8 -0
@@ -28,6 +28,7 @@#include <fcntl.h> #include <errno.h> #include <asm/unistd.h> +#include <linux/err.h> #include <linux/kernel.h> #include <linux/bpf.h> #include <linux/list.h>
@@ -1542,3 +1543,10 @@ bpf_object__find_map_by_offset(struct bpf_object *obj, size_t offset) }return ERR_PTR (-ENOENT ); } + +long libbpf_get_error (const void *ptr) +{ +if (IS_ERR (ptr)) +return PTR_ERR (ptr); +return 0 ; +}
tools/lib/bpf/libbpf.h +3 -1
@@ -22,8 +22,8 @@#define __BPF_LIBBPF_H#include <stdio.h> +#include <stdint.h> #include <stdbool.h> -#include <linux/err.h> #include <sys/types.h> // for size_t enum libbpf_errno {
@@ -234,4 +234,6 @@ int bpf_map__set_priv(struct bpf_map *map, void *priv, bpf_map_clear_priv_t clear_priv);void *bpf_map__priv (struct bpf_map *map); +long libbpf_get_error (const void *ptr); +#endif
tools/perf/tests/llvm.c +1 -1
@@ -13,7 +13,7 @@ static int test__bpf_parsing(void *obj_buf, size_t obj_buf_sz)struct bpf_object *obj; obj =bpf_object__open_buffer (obj_buf, obj_buf_sz,NULL ); -if (IS_ERR (obj)) +if (libbpf_get_error (obj))return TEST_FAIL ;bpf_object__close (obj);return TEST_OK ;
Signature · 1 line
2.9.3
Arnaldo Carvalho de Melo
maintainerPATCH 18/23 perf scripting perl: Do not die() when not founding event for a type
In reply to Arnaldo Carvalho de MeloFrom: Arnaldo Carvalho de Melo <[email protected]>
Do just like handling other cases i.e. print some debug message and ignore the sample.
--- tools/perf/util/scripting-engines/trace-event-perl.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
tools/perf/util/scripting-engines/trace-event-perl.c +4 -2
@@ -350,8 +350,10 @@ static void perl_process_tracepoint(struct perf_sample *sample,if (evsel->attr.type !=PERF_TYPE_TRACEPOINT )return ; -if (!event) -die ("ug! no event found for type %" PRIu64, (u64 )evsel->attr.config); +if (!event) { +pr_debug ("ug! no event found for type %" PRIu64, (u64 )evsel->attr.config); +return ; + } pid =raw_field_value (event,"common_pid" , data);
Signature · 1 line
2.9.3
Arnaldo Carvalho de Melo
maintainerPATCH 19/23 perf tools: Propagate perf_config() errors
In reply to Arnaldo Carvalho de MeloFrom: Arnaldo Carvalho de Melo <[email protected]>
Previously these were being ignored, sometimes silently.
Stop doing that, emitting debug messages and handling the errors.
--- tools/perf/builtin-help.c | 6 ++++-- tools/perf/builtin-kmem.c | 8 ++++++-- tools/perf/builtin-record.c | 4 +++- tools/perf/builtin-report.c | 4 +++- tools/perf/builtin-top.c | 4 +++- tools/perf/perf.c | 15 ++++++++++----- tools/perf/util/callchain.c | 14 ++++++++++++-- tools/perf/util/config.c | 9 +++++---- tools/perf/util/data-convert-bt.c | 7 +++++-- tools/perf/util/hist.c | 4 +++- tools/perf/util/intel-pt.c | 4 +++- tools/perf/util/llvm-utils.c | 4 +++- 12 files changed, 60 insertions(+), 23 deletions(-)
tools/perf/builtin-help.c +4 -2
@@ -447,11 +447,13 @@ int cmd_help(int argc, const char **argv, const char *prefix __maybe_unused) NULL };const char *alias; -int rc =0 ; +int rc;load_command_list ("perf-" , &main_cmds, &other_cmds); -perf_config (perf_help_config, &help_format); + rc =perf_config (perf_help_config, &help_format); +if (rc) +return rc; argc =parse_options_subcommand (argc, argv, builtin_help_options, builtin_help_subcommands, builtin_help_usage,0 );
tools/perf/builtin-kmem.c +6 -2
@@ -1921,10 +1921,12 @@ int cmd_kmem(int argc, const char **argv, const char *prefix __maybe_unused) NULL };struct perf_session *session; -int ret =-1 ;const char errmsg[] ="No %s allocation events found. Have you run 'perf kmem record --%s'?\n" ; +int ret =perf_config (kmem_config,NULL ); + +if (ret) +return ret; -perf_config (kmem_config,NULL ); argc =parse_options_subcommand (argc, argv, kmem_options, kmem_subcommands, kmem_usage,0 );
@@ -1949,6 +1951,8 @@ int cmd_kmem(int argc, const char **argv, const char *prefix __maybe_unused)if (session ==NULL )return -1 ; + ret =-1 ; +if (kmem_slab) {if (!perf_evlist__find_tracepoint_by_name (session->evlist,"kmem:kmalloc" )) {
tools/perf/builtin-record.c +3 -1
@@ -1670,7 +1670,9 @@ int cmd_record(int argc, const char **argv, const char *prefix __maybe_unused)if (rec->evlist ==NULL )return -ENOMEM ; -perf_config (perf_record_config, rec); + err =perf_config (perf_record_config, rec); +if (err) +return err; argc =parse_options (argc, argv, record_options, record_usage,PARSE_OPT_STOP_AT_NON_OPTION );
tools/perf/builtin-report.c +3 -1
@@ -847,7 +847,9 @@ int cmd_report(int argc, const char **argv, const char *prefix __maybe_unused)if (ret <0 )return ret; -perf_config (report__config, &report); + ret =perf_config (report__config, &report); +if (ret) +return ret; argc =parse_options (argc, argv, options, report_usage,0 );if (argc) {
tools/perf/builtin-top.c +3 -1
@@ -1216,7 +1216,9 @@ int cmd_top(int argc, const char **argv, const char *prefix __maybe_unused)if (top.evlist ==NULL )return -ENOMEM ; -perf_config (perf_top_config, &top); + status =perf_config (perf_top_config, &top); +if (status) +return status; argc =parse_options (argc, argv, options, top_usage,0 );if (argc)
tools/perf/perf.c +10 -5
@@ -89,11 +89,12 @@ static int pager_command_config(const char *var, const char *value, void *data)/* returns 0 for "no pager", 1 for "use pager", and -1 for "not specified" */ int check_pager_config (const char *cmd) { +int err;struct pager_config c; c.cmd = cmd; c.val =-1 ; -perf_config (pager_command_config, &c); -return c.val; + err =perf_config (pager_command_config, &c); +return err ?: c.val; }static int browser_command_config (const char *var,const char *value,void *data)
@@ -112,11 +113,12 @@ static int browser_command_config(const char *var, const char *value, void *data*/ static int check_browser_config (const char *cmd) { +int err;struct pager_config c; c.cmd = cmd; c.val =-1 ; -perf_config (browser_command_config, &c); -return c.val; + err =perf_config (browser_command_config, &c); +return err ?: c.val; }static void commit_pager_choice (void )
@@ -508,6 +510,7 @@ static void cache_line_size(int *cacheline_sizep)int main (int argc,const char **argv) { +int err;const char *cmd;char sbuf[STRERR_BUFSIZE ];int value;
@@ -533,7 +536,9 @@ int main(int argc, const char **argv)srandom (time (NULL ));perf_config__init (); -perf_config (perf_default_config,NULL ); + err =perf_config (perf_default_config,NULL ); +if (err) +return err;set_buildid_dir (NULL );/* get debugfs/tracefs mount point from /proc/mounts */
tools/perf/util/callchain.c +12 -2
@@ -48,6 +48,8 @@ static int parse_callchain_mode(const char *value) callchain_param.mode =CHAIN_FOLDED ;return 0 ; } + +pr_debug ("Invalid callchain mode: %s\n" , value);return -1 ; }
@@ -63,6 +65,8 @@ static int parse_callchain_order(const char *value) callchain_param.order_set = true;return 0 ; } + +pr_debug ("Invalid callchain order: %s\n" , value);return -1 ; }
@@ -80,6 +84,8 @@ static int parse_callchain_sort_key(const char *value) callchain_param.branch_callstack =1 ;return 0 ; } + +pr_debug ("Invalid callchain sort key: %s\n" , value);return -1 ; }
@@ -210,13 +216,17 @@ int perf_callchain_config(const char *var, const char *value)return parse_callchain_sort_key (value);if (!strcmp (var,"threshold" )) { callchain_param.min_percent =strtod (value, &endptr); -if (value == endptr) +if (value == endptr) { +pr_debug ("Invalid callchain threshold: %s\n" , value);return -1 ; + } }if (!strcmp (var,"print-limit" )) { callchain_param.print_limit =strtod (value, &endptr); -if (value == endptr) +if (value == endptr) { +pr_debug ("Invalid callchain print limit: %s\n" , value);return -1 ; + } }return 0 ;
tools/perf/util/config.c +5 -4
@@ -386,8 +386,10 @@ static int perf_buildid_config(const char *var, const char *value)if (!strcmp (var,"buildid.dir" )) {const char *dir =perf_config_dirname (var, value); -if (!dir) +if (!dir) { +pr_debug ("Invalid buildid directory!\n" );return -1 ; + }strncpy (buildid_dir, dir,MAXPATHLEN -1 ); buildid_dir[MAXPATHLEN -1 ] ='\0' ; }
@@ -405,10 +407,9 @@ static int perf_default_core_config(const char *var __maybe_unused,static int perf_ui_config (const char *var,const char *value) {/* Add other config variables here. */ -if (!strcmp (var,"ui.show-headers" )) { +if (!strcmp (var,"ui.show-headers" )) symbol_conf.show_hist_headers =perf_config_bool (var, value); -return 0 ; - } +return 0 ; }
tools/perf/util/data-convert-bt.c +5 -2
@@ -1473,7 +1473,7 @@ int bt_convert__perf2ctf(const char *input, const char *path, }, };struct ctf_writer *cw = &c.writer; -int err =-1 ; +int err;if (opts->all) { c.tool.comm = process_comm_event;
@@ -1481,12 +1481,15 @@ int bt_convert__perf2ctf(const char *input, const char *path, c.tool.fork = process_fork_event; } -perf_config (convert__config, &c); + err =perf_config (convert__config, &c); +if (err) +return err;/* CTF writer */ if (ctf_writer__init (cw, path))return -1 ; + err =-1 ;/* perf.data session */ session =perf_session__new (&file,0 , &c.tool);if (!session)
tools/perf/util/hist.c +3 -1
@@ -2439,8 +2439,10 @@ int parse_filter_percentage(const struct option *opt __maybe_unused, symbol_conf.filter_relative = true; else if (!strcmp(arg, "absolute")) symbol_conf.filter_relative = false; - else + else { +pr_debug ("Invalud percentage: %s\n" , arg);return -1 ; + }return 0 ; }
tools/perf/util/intel-pt.c +3 -1
@@ -2159,7 +2159,9 @@ int intel_pt_process_auxtrace_info(union perf_event *event,addr_filters__init (&pt->filts); -perf_config (intel_pt_perf_config, pt); + err =perf_config (intel_pt_perf_config, pt); +if (err) + goto err_free; err =auxtrace_queues__init (&pt->queues);if (err)
tools/perf/util/llvm-utils.c +3 -1
@@ -48,8 +48,10 @@ int perf_llvm_config(const char *var, const char *value) llvm_param.kbuild_opts =strdup (value); else if (!strcmp(var, "dump-obj")) llvm_param.dump_obj = !!perf_config_bool (var, value); - else + else { +pr_debug ("Invalid LLVM config option: %s\n" , value);return -1 ; + } llvm_param.user_set_param = true;return 0 ; }
Signature · 1 line
2.9.3
Arnaldo Carvalho de Melo
maintainerPATCH 20/23 perf util: Save pid-cmdline mapping into tracing header
In reply to Arnaldo Carvalho de MeloFrom: Namhyung Kim <[email protected]>
Current trace info data lacks the saved cmdline mapping which is needed for pevent to find out the comm of a task. Add this and bump up the version number so that perf can determine its presence when reading.
This is mostly corresponding to trace.dat file version 6, but still lacks 4 byte of number of cpus, and 10 bytes of type string - and I think we don't need those anyway.
--- tools/perf/util/trace-event-info.c | 33 ++++++++++++++++++++++++++++++++- tools/perf/util/trace-event-parse.c | 17 +++++++++++++++++ tools/perf/util/trace-event-read.c | 36 ++++++++++++++++++++++++++++++++++-- tools/perf/util/trace-event.h | 1 + 4 files changed, 84 insertions(+), 3 deletions(-)
tools/perf/util/trace-event-info.c +32 -1
@@ -42,7 +42,7 @@#include "evsel.h" #include "debug.h" -#define VERSION "0.5" +#define VERSION "0.6"static int output_fd;
@@ -379,6 +379,34 @@ static int record_ftrace_printk(void)return err; } +static int record_saved_cmdline (void ) +{ +unsigned int size; +char *path; +struct stat st; +int ret, err =0 ; + + path =get_tracing_file ("saved_cmdlines" ); +if (!path) { +pr_debug ("can't get tracing/saved_cmdline" ); +return -ENOMEM ; + } + + ret =stat (path, &st); +if (ret <0 ) { +/* not found */ + size =0 ; +if (write (output_fd, &size,8 ) !=8 ) + err = -EIO ; + goto out; + } + err =record_file (path,8 ); + +out: +put_tracing_file (path); +return err; +} +static void put_tracepoints_path (struct tracepoint_path *tps) {
@@ -539,6 +567,9 @@ struct tracing_data *tracing_data_get(struct list_head *pattrs,if (err) goto out; err =record_ftrace_printk (); +if (err) + goto out; + err =record_saved_cmdline (); out:/*
tools/perf/util/trace-event-parse.c +17 -0
@@ -160,6 +160,23 @@ void parse_ftrace_printk(struct pevent *pevent, } } +void parse_saved_cmdline (struct pevent *pevent, +char *file,unsigned int size__maybe_unused ) +{ +char *comm; +char *line; +char *next =NULL ; +int pid; + + line =strtok_r (file,"\n" , &next); +while (line) { +sscanf (line,"%d %ms" , &pid, &comm); +pevent_register_comm (pevent, comm, pid); +free (comm); + line =strtok_r (NULL ,"\n" , &next); + } +} +int parse_ftrace_file (struct pevent *pevent,char *buf,unsigned long size) {return pevent_parse_event (pevent, buf, size,"ftrace" );
tools/perf/util/trace-event-read.c +34 -2
@@ -341,6 +341,31 @@ static int read_event_files(struct pevent *pevent)return 0 ; } +static int read_saved_cmdline (struct pevent *pevent) +{ +unsigned long long size; +char *buf; + +/* it can have 0 size */ + size =read8 (pevent); +if (!size) +return 0 ; + + buf =malloc (size +1 ); +if (buf ==NULL ) +return -1 ; + +if (do_read (buf, size) <0 ) { +free (buf); +return -1 ; + } + +parse_saved_cmdline (pevent, buf, size); + +free (buf); +return 0 ; +} +ssize_t trace_report (int fd,struct trace_event *tevent,bool __repipe) {char buf[BUFSIZ ];
@@ -379,10 +404,11 @@ ssize_t trace_report(int fd, struct trace_event *tevent, bool __repipe)return -1 ;if (show_version)printf ("version = %s\n" , version); -free (version); -if (do_read (buf,1 ) <0 ) +if (do_read (buf,1 ) <0 ) { +free (version);return -1 ; + } file_bigendian = buf[0 ]; host_bigendian =bigendian ();
@@ -423,6 +449,11 @@ ssize_t trace_report(int fd, struct trace_event *tevent, bool __repipe) err =read_ftrace_printk (pevent);if (err) goto out; +if (atof (version) >=0.6 ) { + err =read_saved_cmdline (pevent); +if (err) + goto out; + } size = trace_data_size; repipe = false;
@@ -438,5 +469,6 @@ ssize_t trace_report(int fd, struct trace_event *tevent, bool __repipe) out:if (pevent)trace_event__cleanup (tevent); +free (version);return size; }
tools/perf/util/trace-event.h +1 -0
@@ -42,6 +42,7 @@ raw_field_value(struct event_format *event, const char *name, void *data);void parse_proc_kallsyms (struct pevent *pevent,char *file,unsigned int size);void parse_ftrace_printk (struct pevent *pevent,char *file,unsigned int size); +void parse_saved_cmdline (struct pevent *pevent,char *file,unsigned int size);ssize_t trace_report (int fd,struct trace_event *tevent,bool repipe);
Signature · 1 line
2.9.3
Arnaldo Carvalho de Melo
maintainerPATCH 21/23 perf util: Add more debug message on failure path
In reply to Arnaldo Carvalho de MeloFrom: Namhyung Kim <[email protected]>
It's helpful for debugging on tracing features.
--- tools/perf/util/header.c | 4 ++- tools/perf/util/trace-event-read.c | 53 ++++++++++++++++++++++++++------------ 2 files changed, 39 insertions(+), 18 deletions(-)
tools/perf/util/header.c +3 -1
@@ -2803,8 +2803,10 @@ static int perf_evsel__prepare_tracepoint_event(struct perf_evsel *evsel, } event =pevent_find_event (pevent, evsel->attr.config); -if (event ==NULL ) +if (event ==NULL ) { +pr_debug ("cannot find event format for %d\n" , (int )evsel->attr.config);return -1 ; + }if (!evsel->name) {snprintf (bf,sizeof (bf),"%s:%s" , event->system, event->name);
tools/perf/util/trace-event-read.c +36 -17
99 lines not on this page · raw message
Signature · 1 line
2.9.3
Arnaldo Carvalho de Melo
maintainerPATCH 22/23 perf ftrace: Introduce new 'ftrace' tool
In reply to Arnaldo Carvalho de MeloFrom: Namhyung Kim <[email protected]>
The 'perf ftrace' command is a simple wrapper of kernel's ftrace functionality. It only supports single thread tracing currently and just reads trace_pipe in text and then write it to stdout.
Committer notes:
Testing it:
# perf ftrace -f function_graph usleep 123456
<SNIP>
2) | SyS_nanosleep() {
2) | _copy_from_user() {
<SNIP>
2) 0.900 us | }
2) 1.354 us | }
2) | hrtimer_nanosleep() {
2) 0.062 us | __hrtimer_init();
2) | do_nanosleep() {
2) | hrtimer_start_range_ns() {
<SNIP>
2) 5.025 us | }
2) | schedule() {
2) 0.125 us | rcu_note_context_switch();
2) 0.057 us | _raw_spin_lock();
2) | deactivate_task() {
2) 0.369 us | update_rq_clock.part.77();
2) | dequeue_task_fair() {
<SNIP>
2) + 22.453 us | }
2) + 23.736 us | }
2) | pick_next_task_fair() {
<SNIP>
2) + 47.167 us | }
2) | pick_next_task_idle() {
<SNIP>
2) 4.462 us | }
------------------------------------------
2) usleep-20387 => <idle>-0
------------------------------------------ 2) 0.806 us | switch_mm_irqs_off();
------------------------------------------
2) <idle>-0 => usleep-20387
------------------------------------------
2) 0.151 us | finish_task_switch();
2) @ 123597.2 us | }
2) 0.037 us | _cond_resched();
2) | hrtimer_try_to_cancel() {
2) 0.064 us | hrtimer_active();
2) 0.353 us | }
2) @ 123605.3 us | }
2) @ 123606.2 us | }
2) @ 123608.3 us | } /* SyS_nanosleep */
2) | __do_page_fault() {<SNIP>
--- tools/perf/Build | 1 + tools/perf/Documentation/perf-ftrace.txt | 36 +++++ tools/perf/builtin-ftrace.c | 242 +++++++++++++++++++++++++++++++ tools/perf/builtin.h | 1 + tools/perf/command-list.txt | 1 + tools/perf/perf.c | 1 + 6 files changed, 282 insertions(+) create mode 100644 tools/perf/Documentation/perf-ftrace.txt create mode 100644 tools/perf/builtin-ftrace.c
tools/perf/Build +1 -0
@@ -3,6 +3,7 @@ perf-y += builtin-annotate.o perf-y += builtin-config.o perf-y += builtin-diff.o perf-y += builtin-evlist.o +perf-y += builtin-ftrace.o perf-y += builtin-help.o perf-y += builtin-sched.o perf-y += builtin-buildid-list.o
tools/perf/Documentation/perf-ftrace.txt new file +36 -0
@@ -0,0 +1,36 @@ +perf-ftrace(1) +============= + +NAME +---- +perf-ftrace - simple wrapper for kernel's ftrace functionality + + +SYNOPSIS +-------- +[verse] +'perf ftrace' <command> + +DESCRIPTION +----------- +The 'perf ftrace' command is a simple wrapper of kernel's ftrace +functionality. It only supports single thread tracing currently and +just reads trace_pipe in text and then write it to stdout. + +The following options apply to perf ftrace. + +OPTIONS +------- + +-t:: +--tracer=:: + Tracer to use: function_graph or function. + +-v:: +--verbose=:: + Verbosity level. + + +SEE ALSO +-------- +linkperf:perf-record[1], linkperf:perf-trace[1]
tools/perf/builtin-ftrace.c new file +242 -0
242 lines not on this page · raw message
tools/perf/builtin.h +1 -0
@@ -41,6 +41,7 @@ int cmd_trace(int argc, const char **argv, const char *prefix);int cmd_inject (int argc,const char **argv,const char *prefix);int cmd_mem (int argc,const char **argv,const char *prefix);int cmd_data (int argc,const char **argv,const char *prefix); +int cmd_ftrace (int argc,const char **argv,const char *prefix);int find_scripts (char **scripts_array,char **scripts_path_array);#endif
tools/perf/command-list.txt +1 -0
@@ -11,6 +11,7 @@ perf-data mainporcelain common perf-diff mainporcelain common perf-config mainporcelain common perf-evlist mainporcelain common +perf-ftrace mainporcelain common perf-inject mainporcelain common perf-kallsyms mainporcelain common perf-kmem mainporcelain common
tools/perf/perf.c +1 -0
@@ -71,6 +71,7 @@ static struct cmd_struct commands[] = { { "inject", cmd_inject, 0 }, { "mem", cmd_mem, 0 }, { "data", cmd_data, 0 }, + { "ftrace", cmd_ftrace, 0 }, }; struct pager_config {
Signature · 1 line
2.9.3
Arnaldo Carvalho de Melo
maintainerPATCH 23/23 perf ftrace: Make 'function_graph' be the default tracer
In reply to Arnaldo Carvalho de MeloFrom: Arnaldo Carvalho de Melo <[email protected]>
So that we can suppress the '-t function_graph' and get a more compact command line:
# perf ftrace usleep 123456 | grep raw_spin_lock | sort -k2 -nr | head -5 2) 0.555 us | _raw_spin_lock(); 2) 0.516 us | _raw_spin_lock(); 2) 0.410 us | _raw_spin_lock_irq(); 2) 0.374 us | _raw_spin_lock_irqsave(); #
--- tools/perf/builtin-ftrace.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
tools/perf/builtin-ftrace.c +2 -1
@@ -202,6 +202,7 @@ int cmd_ftrace(int argc, const char **argv, const char *prefix __maybe_unused) {int ret;struct perf_ftrace ftrace = { + .tracer ="function_graph" , .target = { .uid =UINT_MAX , }, };const char *const ftrace_usage[] = {
@@ -211,7 +212,7 @@ int cmd_ftrace(int argc, const char **argv, const char *prefix __maybe_unused) };const struct option ftrace_options[] = {OPT_STRING ('t' ,"tracer" , &ftrace.tracer,"tracer" , -"tracer to use: function_graph or function" ), +"tracer to use: function_graph(default) or function" ),OPT_INCR ('v' ,"verbose" , &verbose,"be more verbose" ),OPT_END ()
Signature · 1 line
2.9.3