Skip to contentSkip to conversation

perf/core improvements and fixes

GIT PULL New Arnaldo Carvalho de Melo 1 participant 24 messages Jan 25, 2017

Subsystems (7)
lore
Share & tools
lore

Arnaldo Carvalho de Melo

author maintainer
#0 lore raw

Hi 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'
  $ 
author maintainer
#1 lore raw

PATCH 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
index d2c6cdd9d42b..28d41e709128 100644
@@ -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
author maintainer
#2 lore raw

PATCH 2/23 perf hists browser: Put hist_entry folding logic into single function

In reply to Arnaldo Carvalho de Melo

From: 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
index 641b40234a9d..8bf18afe2a1f 100644
@@ -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
author maintainer
#3 lore raw

PATCH 3/23 perf hists browser: Add e/c hotkeys to expand/collapse callchain for current entry

In reply to Arnaldo Carvalho de Melo

From: 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
index 8bf18afe2a1f..fc4fb669ceee 100644
@@ -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
author maintainer
#4 lore raw

PATCH 4/23 perf c2c report: Display Total records column in offset view

In reply to Arnaldo Carvalho de Melo

From: 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
index f8ca7a4ebabc..616cb1418c3f 100644
@@ -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
author maintainer
#5 lore raw

PATCH 5/23 perf c2c report: Coalesce by default only by pid,iaddr

In reply to Arnaldo Carvalho de Melo

From: 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
index 3f06730c7f47..2da07e51e119 100644
@@ -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
index 616cb1418c3f..e2b21723bbf8 100644
@@ -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
author maintainer
#6 lore raw

PATCH 6/23 perf tools: Add probing for the XED disassembler library

In reply to Arnaldo Carvalho de Melo

From: 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

From https://intelxed.github.io/:

---
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
index e3fb5ecbdcb6..a3fa78296cb5 100644
@@ -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
index b564a2eea039..4f1aa82b867a 100644
@@ -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
index 699e43627397..cffe9fcda7c4 100644
@@ -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
new file mode 100644
index 000000000000..ef9aebf1559d
@@ -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
index 03cf947755b9..fd798d118739 100644
@@ -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
index 4da19b6ba94a..f6760309edd3 100644
@@ -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
author maintainer
#7 lore raw

PATCH 7/23 perf tools: Add one liner warning for disabled features

In reply to Arnaldo Carvalho de Melo

From: 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
index fd798d118739..0caa11979279 100644
@@ -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
author maintainer
#8 lore raw

PATCH 8/23 perf tools: Add disassembler for x86 using the XED library

In reply to Arnaldo Carvalho de Melo

From: 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
index f95e6f46ef0d..fd1dfd7c6321 100644
@@ -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
index 5da376bc1afc..cdaeb4764fee 100644
@@ -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
new file mode 100644
index 000000000000..61cf96fbcd1b
@@ -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
new file mode 100644
index 000000000000..79ff8d915d3b
@@ -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
author maintainer
#9 lore raw

PATCH 9/23 perf script: Add support for printing assembler

In reply to Arnaldo Carvalho de Melo

From: 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 %rbx

v2:
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
index 4ed5f239ba7d..497989ea9768 100644
@@ -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
author maintainer
#10 lore raw

PATCH 10/23 perf script: Add "brstackasm" output for branch stacks

In reply to Arnaldo Carvalho de Melo

From: 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
index 497989ea9768..15a80815941e 100644
@@ -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
author maintainer
#11 lore raw

PATCH 11/23 perf probe: Fix wrong register name for arm64

In reply to Arnaldo Carvalho de Melo

From: 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
index 26759363f921..36e375f5a211 100644
@@ -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
author maintainer
#12 lore raw

PATCH 12/23 perf probe: Delete an unnecessary check in try_to_find_absolute_address()

In reply to Arnaldo Carvalho de Melo

From: 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
index 4a57c8a60bd9..cdfc468d4d5f 100644
@@ -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
author maintainer
#13 lore raw

PATCH 13/23 perf probe: Delete an unnecessary assignment in try_to_find_absolute_address()

In reply to Arnaldo Carvalho de Melo

From: 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
index cdfc468d4d5f..ded1e7d88874 100644
@@ -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
author maintainer
#14 lore raw

PATCH 14/23 tools lib bpf: Fix map offsets in relocation

In reply to Arnaldo Carvalho de Melo

From: 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 = 3

So, libbpf reports:

libbpf: bpf relocation: map_idx 3 large than 2

Fix map relocation by checking the exact offset of maps when doing relocation.

[Allow different map size in an object]
Cc Alexei Starovoitov <[email protected]>
Cc Daniel Borkmann <[email protected]>
Fixes 4708bbda5cb2 ("tools lib bpf: Fix maps resolution")
---
 tools/lib/bpf/libbpf.c | 15 ++++++++++++---
 1 file changed, 12 insertions(+), 3 deletions(-)
tools/lib/bpf/libbpf.c +12 -3
index 84e6b35da4bd..671d5ad07cf1 100644
@@ -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
author maintainer
#15 lore raw

PATCH 15/23 tools lib bpf: Define prog_type fns with macro

In reply to Arnaldo Carvalho de Melo

From: 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
index 671d5ad07cf1..371cb40a2304 100644
@@ -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
author maintainer
#16 lore raw

PATCH 16/23 tools lib bpf: Add set/is helpers for all prog types

In reply to Arnaldo Carvalho de Melo

From: 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
index 371cb40a2304..406838fa9c4f 100644
@@ -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
index a5a8b86a06fe..2188ccdc0e2d 100644
@@ -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
author maintainer
#17 lore raw

PATCH 17/23 tools lib bpf: Add libbpf_get_error()

In reply to Arnaldo Carvalho de Melo

From: 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
index 406838fa9c4f..e6cd62b1264b 100644
@@ -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
index 2188ccdc0e2d..4014d1ba5e3d 100644
@@ -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
index 02a33ebcd992..d357dab72e68 100644
@@ -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
author maintainer
#18 lore raw

PATCH 18/23 perf scripting perl: Do not die() when not founding event for a type

In reply to Arnaldo Carvalho de Melo

From: 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
index e55a132f69b7..014ecd6f67c4 100644
@@ -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
author maintainer
#19 lore raw

PATCH 19/23 perf tools: Propagate perf_config() errors

In reply to Arnaldo Carvalho de Melo

From: 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
index 93da24a638be..aed0d844e8c2 100644
@@ -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
index 35a02f8e5a4a..70ff88d8be7e 100644
@@ -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
index 33a9eaaf9db4..ffac8ca9fb01 100644
@@ -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
index 06cc759a4597..dbd7fa028861 100644
@@ -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
index 3df4178ba378..20aef9815cd8 100644
@@ -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
index 0324cd15e42a..c71000e022d7 100644
@@ -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
index 42922512c1c6..f19aff042925 100644
@@ -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
index 3d906dbbef74..b0b61af7c493 100644
@@ -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
index 7123f4de32cc..4e6cbc99f08e 100644
@@ -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
index 6770a9645609..cff2e9041b15 100644
@@ -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
index 85d5eeb66c75..da20cd5612e9 100644
@@ -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
index b23ff44cf214..824356488ce6 100644
@@ -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
author maintainer
#20 lore raw

PATCH 20/23 perf util: Save pid-cmdline mapping into tracing header

In reply to Arnaldo Carvalho de Melo

From: 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.

Cc Frederic Weisbecker <[email protected]>
Cc Jeremy Eder <[email protected]>
Cc Jiri Olsa <[email protected]>,
Cc Paul Mackerras <[email protected]>
Cc Peter Zijlstra <[email protected]>
Cc Stephane Eranian <[email protected]>
Cc Steven Rostedt <[email protected]>
[ Change version test from == to >= ]
---
 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
index d995743cb673..ceb0e2720223 100644
@@ -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
index 33b52eaa39db..de0078e21408 100644
@@ -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
index b67a0ccf5ab9..61c7162c31c7 100644
@@ -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
index b0af9c81bb0d..1fbc044f9eb0 100644
@@ -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
author maintainer
#21 lore raw

PATCH 21/23 perf util: Add more debug message on failure path

In reply to Arnaldo Carvalho de Melo

From: 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
index 00fd8a8850d3..c567d9f0aa92 100644
@@ -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
author maintainer
#22 lore raw

PATCH 22/23 perf ftrace: Introduce new 'ftrace' tool

In reply to Arnaldo Carvalho de Melo

From: 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>

Cc Frederic Weisbecker <[email protected]>
Cc Jeremy Eder <[email protected]>
Cc Jiri Olsa <[email protected]>,
Cc Paul Mackerras <[email protected]>
Cc Peter Zijlstra <[email protected]>
Cc Stephane Eranian <[email protected]>
Cc Steven Rostedt <[email protected]>
[ Various foward port fixes, add man page ]
---
 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
index 7039ecb89170..9b79f8d7db50 100644
@@ -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
new file mode 100644
index 000000000000..2d96de6132a9
@@ -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
index b55f5be486a1..036e1e35b1a8 100644
@@ -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
index fb45613dba9e..ac3efd396a72 100644
@@ -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
index c71000e022d7..6d5479e03e0d 100644
@@ -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
author maintainer
#23 lore raw

PATCH 23/23 perf ftrace: Make 'function_graph' be the default tracer

In reply to Arnaldo Carvalho de Melo

From: 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();
  #
Cc Adrian Hunter <[email protected]>
Cc David Ahern <[email protected]>
Cc Frederic Weisbecker <[email protected]>
Cc Jeremy Eder <[email protected]>
Cc Jiri Olsa <[email protected]>
Cc Namhyung Kim <[email protected]>
Cc Paul Mackerras <[email protected]>
Cc Peter Zijlstra <[email protected]>
Cc Stephane Eranian <[email protected]>
Cc Steven Rostedt <[email protected]>
Cc Wang Nan <[email protected]>
---
 tools/perf/builtin-ftrace.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)
tools/perf/builtin-ftrace.c +2 -1
index c320ae25c8e6..d05658d2b8f1 100644
@@ -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