Skip to contentSkip to conversation

perf/pt -> Intel PT/BTS

GIT PULL New Arnaldo Carvalho de Melo 4 participants 23 messages Jun 26, 2015 – Jul 3, 2015 perf events

lore
Share & tools
lore

Arnaldo Carvalho de Melo

author maintainer
#0 lore raw

Hi Ingo,

Please consider pulling, there are several other patches after this,
but I think that this may be acceptable to showcase the capabilities already present, look at the output of 'perf script' and callchains for userspace without using any extra debugging info (no need for DWARF, CFI, nothing), really cool capabilities... :-)

Adrian wrote some docs and I tested it both on a Ivy Bridge machine
where there is only BTS and on a Broadwell machine with the whole shebang, adding the output of the commands to the csets, to further showcase what is there already.

This is on top of my last perf-core-for-mingo tag.

Up to you, please let us know what you think and we'll continue working
on having this in an acceptable form for merging,

Regards,

- Arnaldo

P.S. Kudos for Adrian for the patience with this process, way more is needed to polish this, but the promise is there, cool stuff indeed! :-)

The following changes since commit 36c8bb56a9f718a9a5f35d1834ca9dcec95deb4a:

perf symbols: Check access permission when reading symbol files (2015-06-26 12:11:53 -0300)

are available in the git repository at:

git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux.git tags/perf-pt-for-mingo

for you to fetch changes up to 04759f172270afb28c8004f5cad62ed55710a499:

perf tools: Add Intel BTS support (2015-06-26 18:36:11 -0300)

----------------------------------------------------------------
Put Intel PT and BTS into initial use (Adrian Hunter)

----------------------------------------------------------------
Adrian Hunter (8):
perf auxtrace: Add Intel PT as an AUX area tracing type perf tools: Add Intel PT packet decoder
perf tools: Add Intel PT instruction decoder perf tools: Add Intel PT log
perf tools: Add Intel PT decoder
perf tools: Add Intel PT support
perf tools: Take Intel PT into use
perf tools: Add Intel BTS support

 tools/build/Makefile.build                         |    2 +
 tools/perf/.gitignore                              |    2 +
 tools/perf/Documentation/intel-bts.txt             |   86 +
 tools/perf/Documentation/intel-pt.txt              |  588 ++++++
 tools/perf/MANIFEST                                |    7 +
 tools/perf/Makefile.perf                           |   12 +-
 tools/perf/arch/x86/util/Build                     |    5 +
 tools/perf/arch/x86/util/auxtrace.c                |   83 +
 tools/perf/arch/x86/util/intel-bts.c               |  458 +++++
 tools/perf/arch/x86/util/intel-pt.c                |  752 ++++++++
 tools/perf/arch/x86/util/pmu.c                     |   18 +
 tools/perf/util/Build                              |    3 +
 tools/perf/util/auxtrace.c                         |    9 +-
 tools/perf/util/auxtrace.h                         |    2 +
 tools/perf/util/intel-bts.c                        |  791 ++++++++
 tools/perf/util/intel-bts.h                        |   43 +
 tools/perf/util/intel-pt-decoder/Build             |   14 +
 .../perf/util/intel-pt-decoder/intel-pt-decoder.c  | 1759 ++++++++++++++++++
 .../perf/util/intel-pt-decoder/intel-pt-decoder.h  |  102 ++
 .../util/intel-pt-decoder/intel-pt-insn-decoder.c  |  246 +++
 .../util/intel-pt-decoder/intel-pt-insn-decoder.h  |   65 +
 tools/perf/util/intel-pt-decoder/intel-pt-log.c    |  155 ++
 tools/perf/util/intel-pt-decoder/intel-pt-log.h    |   52 +
 .../util/intel-pt-decoder/intel-pt-pkt-decoder.c   |  400 +++++
 .../util/intel-pt-decoder/intel-pt-pkt-decoder.h   |   64 +
 tools/perf/util/intel-pt.c                         | 1889 ++++++++++++++++++++
 tools/perf/util/intel-pt.h                         |   51 +
 tools/perf/util/pmu.c                              |    4 -
 28 files changed, 7655 insertions(+), 7 deletions(-)
 create mode 100644 tools/perf/Documentation/intel-bts.txt
 create mode 100644 tools/perf/Documentation/intel-pt.txt
 create mode 100644 tools/perf/arch/x86/util/auxtrace.c
 create mode 100644 tools/perf/arch/x86/util/intel-bts.c
 create mode 100644 tools/perf/arch/x86/util/intel-pt.c
 create mode 100644 tools/perf/arch/x86/util/pmu.c
 create mode 100644 tools/perf/util/intel-bts.c
 create mode 100644 tools/perf/util/intel-bts.h
 create mode 100644 tools/perf/util/intel-pt-decoder/Build
 create mode 100644 tools/perf/util/intel-pt-decoder/intel-pt-decoder.c
 create mode 100644 tools/perf/util/intel-pt-decoder/intel-pt-decoder.h
 create mode 100644 tools/perf/util/intel-pt-decoder/intel-pt-insn-decoder.c
 create mode 100644 tools/perf/util/intel-pt-decoder/intel-pt-insn-decoder.h
 create mode 100644 tools/perf/util/intel-pt-decoder/intel-pt-log.c
 create mode 100644 tools/perf/util/intel-pt-decoder/intel-pt-log.h
 create mode 100644 tools/perf/util/intel-pt-decoder/intel-pt-pkt-decoder.c
 create mode 100644 tools/perf/util/intel-pt-decoder/intel-pt-pkt-decoder.h
 create mode 100644 tools/perf/util/intel-pt.c
 create mode 100644 tools/perf/util/intel-pt.h
author maintainer
#1 lore raw

PATCH 1/8 perf auxtrace: Add Intel PT as an AUX area tracing type

From: Adrian Hunter <[email protected]>

Add the Intel Processor Trace type constant PERF_AUXTRACE_INTEL_PT.

---
 tools/perf/util/auxtrace.c | 1 +
 tools/perf/util/auxtrace.h | 1 +
 2 files changed, 2 insertions(+)
tools/perf/util/auxtrace.c +1 -0
index 7e7405c9b936..ea29022a4f52 100644
@@ -884,6 +884,7 @@ int perf_event__process_auxtrace_info(struct perf_tool *tool __maybe_unused,
 		fprintf(stdout, " type: %u\n", type);
 
 	switch (type) {
+	case PERF_AUXTRACE_INTEL_PT:
 	case PERF_AUXTRACE_UNKNOWN:
 	default:
 		return -EINVAL;
tools/perf/util/auxtrace.h +1 -0
index 471aecbc4d68..7d12f33a3a06 100644
@@ -39,6 +39,7 @@ struct events_stats;
 
 enum auxtrace_type {
 	PERF_AUXTRACE_UNKNOWN,
+	PERF_AUXTRACE_INTEL_PT,
 };
 
 enum itrace_period_type {
Signature · 1 line
2.1.0
author maintainer
#2 lore raw

PATCH 2/8 perf tools: Add Intel PT packet decoder

In reply to Arnaldo Carvalho de Melo

From: Adrian Hunter <[email protected]>

Add support for decoding Intel Processor Trace packets.

This essentially provides intel_pt_get_packet() which takes a buffer of binary data and returns the decoded packet.

---
 tools/perf/util/Build                              |   1 +
 tools/perf/util/intel-pt-decoder/Build             |   1 +
 .../util/intel-pt-decoder/intel-pt-pkt-decoder.c   | 400 +++++++++++++++++++++
 .../util/intel-pt-decoder/intel-pt-pkt-decoder.h   |  64 ++++
 4 files changed, 466 insertions(+)
 create mode 100644 tools/perf/util/intel-pt-decoder/Build
 create mode 100644 tools/perf/util/intel-pt-decoder/intel-pt-pkt-decoder.c
 create mode 100644 tools/perf/util/intel-pt-decoder/intel-pt-pkt-decoder.h
tools/perf/util/Build +1 -0
index 586a59d46022..e1b505a8055b 100644
@@ -76,6 +76,7 @@ libperf-$(CONFIG_X86) += tsc.o
 libperf-y += cloexec.o
 libperf-y += thread-stack.o
 libperf-$(CONFIG_AUXTRACE) += auxtrace.o
+libperf-$(CONFIG_AUXTRACE) += intel-pt-decoder/
 libperf-y += parse-branch-options.o
 
 libperf-$(CONFIG_LIBELF) += symbol-elf.o
tools/perf/util/intel-pt-decoder/Build new file +1 -0
new file mode 100644
index 000000000000..9d67381a9bd3
@@ -0,0 +1 @@
+libperf-$(CONFIG_AUXTRACE) += intel-pt-pkt-decoder.o
tools/perf/util/intel-pt-decoder/intel-pt-pkt-decoder.c new file +400 -0

400 lines not on this page · raw message

tools/perf/util/intel-pt-decoder/intel-pt-pkt-decoder.h new file +64 -0

64 lines not on this page · raw message

Signature · 1 line
2.1.0
author maintainer
#3 lore raw

PATCH 3/8 perf tools: Add Intel PT instruction decoder

In reply to Arnaldo Carvalho de Melo

From: Adrian Hunter <[email protected]>

Add support for decoding instructions for Intel Processor Trace. The kernel x86 instruction decoder is used for this.

This essentially provides intel_pt_get_insn() which takes a binary buffer, uses the kernel's x86 instruction decoder to get details of the instruction and then categorizes it for consumption by an Intel PT decoder.

Cc Jiri Olsa <[email protected]>
[ Fixed .gitignore conflict, added missing arch/x86/ used to tools/perf/MANIFEST ]
---
 tools/build/Makefile.build                         |   2 +
 tools/perf/.gitignore                              |   2 +
 tools/perf/MANIFEST                                |   7 +
 tools/perf/Makefile.perf                           |  12 +-
 tools/perf/util/intel-pt-decoder/Build             |  15 +-
 .../util/intel-pt-decoder/intel-pt-insn-decoder.c  | 246 +++++++++++++++++++++
 .../util/intel-pt-decoder/intel-pt-insn-decoder.h  |  65 ++++++
 7 files changed, 346 insertions(+), 3 deletions(-)
 create mode 100644 tools/perf/util/intel-pt-decoder/intel-pt-insn-decoder.c
 create mode 100644 tools/perf/util/intel-pt-decoder/intel-pt-insn-decoder.h
tools/build/Makefile.build +2 -0
index a51244a8022f..9f23562a99bb 100644
@@ -57,6 +57,8 @@ quiet_cmd_cc_i_c = CPP      $@
 quiet_cmd_cc_s_c = AS       $@
       cmd_cc_s_c = $(CC) $(c_flags) -S -o $@ $<
 
+quiet_cmd_gen = GEN      $@
+
 # Link agregate command
 # If there's nothing to link, create empty $@ object.
 quiet_cmd_ld_multi = LD       $@
tools/perf/.gitignore +2 -0
index 09db62ba5786..97f460a5f477 100644
@@ -29,3 +29,5 @@ config.mak.autogen
 *.pyc
 *.pyo
 .config-detected
+util/intel-pt-decoder/inat-tables.c
+util/intel-pt-decoder/inat.c
tools/perf/MANIFEST +7 -0
index fe50a1b34aa0..4e5662d8c274 100644
@@ -58,6 +58,13 @@ include/linux/stringify.h
 lib/hweight.c
 lib/rbtree.c
 include/linux/swab.h
+arch/x86/lib/insn.c
+arch/x86/lib/inat.c
+arch/x86/include/asm/insn.h
+arch/x86/include/asm/inat.h
+arch/x86/include/asm/inat_types.h
+arch/x86/tools/gen-insn-attr-x86.awk
+arch/x86/lib/x86-opcode-map.txt
 arch/*/include/asm/unistd*.h
 arch/*/include/uapi/asm/unistd*.h
 arch/*/include/uapi/asm/perf_regs.h
tools/perf/Makefile.perf +10 -2
index 1af0cfeb7a57..20e5d001f05b 100644
@@ -76,6 +76,12 @@ include config/utilities.mak
 #
 # Define NO_AUXTRACE if you do not want AUX area tracing support
 
+# As per kernel Makefile, avoid funny character set dependencies
+unexport LC_ALL
+LC_COLLATE=C
+LC_NUMERIC=C
+export LC_COLLATE LC_NUMERIC
+
 ifeq ($(srctree),)
 srctree := $(patsubst %/,%,$(dir $(shell pwd)))
 srctree := $(patsubst %/,%,$(dir $(srctree)))
@@ -122,6 +128,7 @@ INSTALL = install
 FLEX    = flex
 BISON   = bison
 STRIP   = strip
+AWK     = awk
 
 LIB_DIR          = $(srctree)/tools/lib/api/
 TRACE_EVENT_DIR = $(srctree)/tools/lib/traceevent/
@@ -276,7 +283,7 @@ strip: $(PROGRAMS) $(OUTPUT)perf
 
 PERF_IN := $(OUTPUT)perf-in.o
 
-export srctree OUTPUT RM CC LD AR CFLAGS V BISON FLEX
+export srctree OUTPUT RM CC LD AR CFLAGS V BISON FLEX AWK
 build := -f $(srctree)/tools/build/Makefile.build dir=. obj
 
 $(PERF_IN): $(OUTPUT)PERF-VERSION-FILE $(OUTPUT)common-cmds.h FORCE
@@ -547,7 +554,8 @@ clean: $(LIBTRACEEVENT)-clean $(LIBAPI)-clean config-clean
 	$(Q)find . -name '*.o' -delete -o -name '\.*.cmd' -delete -o -name '\.*.d' -delete
 	$(Q)$(RM) .config-detected
 	$(call QUIET_CLEAN, core-progs) $(RM) $(ALL_PROGRAMS) perf perf-read-vdso32 perf-read-vdsox32
-	$(call QUIET_CLEAN, core-gen)   $(RM)  *.spec *.pyc *.pyo */*.pyc */*.pyo $(OUTPUT)common-cmds.h TAGS tags cscope* $(OUTPUT)PERF-VERSION-FILE $(OUTPUT)FEATURE-DUMP $(OUTPUT)util/*-bison* $(OUTPUT)util/*-flex*
+	$(call QUIET_CLEAN, core-gen)   $(RM)  *.spec *.pyc *.pyo */*.pyc */*.pyo $(OUTPUT)common-cmds.h TAGS tags cscope* $(OUTPUT)PERF-VERSION-FILE $(OUTPUT)FEATURE-DUMP $(OUTPUT)util/*-bison* $(OUTPUT)util/*-flex* \
+		$(OUTPUT)util/intel-pt-decoder/inat.c $(OUTPUT)util/intel-pt-decoder/inat-tables.c
 	$(QUIET_SUBDIR0)Documentation $(QUIET_SUBDIR1) clean
 	$(python-clean)
 
tools/perf/util/intel-pt-decoder/Build +14 -1
index 9d67381a9bd3..f5f7f87eb718 100644
@@ -1 +1,14 @@
-libperf-$(CONFIG_AUXTRACE) += intel-pt-pkt-decoder.o
+libperf-$(CONFIG_AUXTRACE) += intel-pt-pkt-decoder.o intel-pt-insn-decoder.o
+
+inat_tables_script = ../../arch/x86/tools/gen-insn-attr-x86.awk
+inat_tables_maps = ../../arch/x86/lib/x86-opcode-map.txt
+
+$(OUTPUT)util/intel-pt-decoder/inat-tables.c: $(inat_tables_script) $(inat_tables_maps)
+	@$(call echo-cmd,gen)$(AWK) -f $(inat_tables_script) $(inat_tables_maps) > $@ || rm -f $@
+
+$(OUTPUT)util/intel-pt-decoder/inat.c:
+	@$(call echo-cmd,gen)cp ../../arch/x86/lib/inat.c $(OUTPUT)util/intel-pt-decoder/inat.c
+
+$(OUTPUT)util/intel-pt-decoder/intel-pt-insn-decoder.o: $(OUTPUT)util/intel-pt-decoder/inat.c $(OUTPUT)util/intel-pt-decoder/inat-tables.c
+
+CFLAGS_intel-pt-insn-decoder.o += -I../../arch/x86/include -I$(OUTPUT)util/intel-pt-decoder -I../../arch/x86/lib -Wno-override-init
tools/perf/util/intel-pt-decoder/intel-pt-insn-decoder.c new file +246 -0

246 lines not on this page · raw message

tools/perf/util/intel-pt-decoder/intel-pt-insn-decoder.h new file +65 -0

65 lines not on this page · raw message

Signature · 1 line
2.1.0
author maintainer
#4 lore raw

PATCH 4/8 perf tools: Add Intel PT log

In reply to Arnaldo Carvalho de Melo

From: Adrian Hunter <[email protected]>

Add a facility to log Intel Processor Trace decoding. The log is intended for debugging purposes only.

The log file name is "intel_pt.log" and is opened in the current directory. The log contains a record of all packets and instructions decoded and can get very large (10 MB would be a small one).

---
 tools/perf/util/intel-pt-decoder/Build          |   2 +-
 tools/perf/util/intel-pt-decoder/intel-pt-log.c | 155 ++++++++++++++++++++++++
 tools/perf/util/intel-pt-decoder/intel-pt-log.h |  52 ++++++++
 3 files changed, 208 insertions(+), 1 deletion(-)
 create mode 100644 tools/perf/util/intel-pt-decoder/intel-pt-log.c
 create mode 100644 tools/perf/util/intel-pt-decoder/intel-pt-log.h
tools/perf/util/intel-pt-decoder/Build +1 -1
index f5f7f87eb718..587321a67d95 100644
@@ -1,4 +1,4 @@
-libperf-$(CONFIG_AUXTRACE) += intel-pt-pkt-decoder.o intel-pt-insn-decoder.o
+libperf-$(CONFIG_AUXTRACE) += intel-pt-pkt-decoder.o intel-pt-insn-decoder.o intel-pt-log.o
 
 inat_tables_script = ../../arch/x86/tools/gen-insn-attr-x86.awk
 inat_tables_maps = ../../arch/x86/lib/x86-opcode-map.txt
tools/perf/util/intel-pt-decoder/intel-pt-log.c new file +155 -0

155 lines not on this page · raw message

tools/perf/util/intel-pt-decoder/intel-pt-log.h new file +52 -0

52 lines not on this page · raw message

Signature · 1 line
2.1.0
author maintainer
#5 lore raw

PATCH 5/8 perf tools: Add Intel PT decoder

In reply to Arnaldo Carvalho de Melo

From: Adrian Hunter <[email protected]>

Add support for decoding an Intel Processor Trace.

Intel PT trace data must be 'decoded' which involves walking the object code and matching the trace data packets.

The decoder requests a buffer of binary data via a get_trace() call-back, which it decodes using instruction information which it gets via another call-back walk_insn().

---
 tools/perf/util/intel-pt-decoder/Build             |    2 +-
 .../perf/util/intel-pt-decoder/intel-pt-decoder.c  | 1759 ++++++++++++++++++++
 .../perf/util/intel-pt-decoder/intel-pt-decoder.h  |  102 ++
 3 files changed, 1862 insertions(+), 1 deletion(-)
 create mode 100644 tools/perf/util/intel-pt-decoder/intel-pt-decoder.c
 create mode 100644 tools/perf/util/intel-pt-decoder/intel-pt-decoder.h
tools/perf/util/intel-pt-decoder/Build +1 -1
index 587321a67d95..fa12eac57a22 100644
@@ -1,4 +1,4 @@
-libperf-$(CONFIG_AUXTRACE) += intel-pt-pkt-decoder.o intel-pt-insn-decoder.o intel-pt-log.o
+libperf-$(CONFIG_AUXTRACE) += intel-pt-pkt-decoder.o intel-pt-insn-decoder.o intel-pt-log.o intel-pt-decoder.o
 
 inat_tables_script = ../../arch/x86/tools/gen-insn-attr-x86.awk
 inat_tables_maps = ../../arch/x86/lib/x86-opcode-map.txt
tools/perf/util/intel-pt-decoder/intel-pt-decoder.c new file +1759 -0

1,759 lines not on this page · raw message

tools/perf/util/intel-pt-decoder/intel-pt-decoder.h new file +102 -0

102 lines not on this page · raw message

Signature · 1 line
2.1.0
author maintainer
#6 lore raw

PATCH 6/8 perf tools: Add Intel PT support

In reply to Arnaldo Carvalho de Melo

From: Adrian Hunter <[email protected]>

Add support for Intel Processor Trace.

Intel PT support fits within the new auxtrace infrastructure. Recording is supporting by identifying the Intel PT PMU, parsing options and setting up events.

Decoding is supported by queuing up trace data by cpu or thread and then decoding synchronously delivering synthesized event samples into the session processing for tools to consume.

---
 tools/perf/arch/x86/util/Build      |    2 +
 tools/perf/arch/x86/util/intel-pt.c |  752 ++++++++++++++
 tools/perf/util/Build               |    1 +
 tools/perf/util/intel-pt.c          | 1889 +++++++++++++++++++++++++++++++++++
 tools/perf/util/intel-pt.h          |   51 +
 5 files changed, 2695 insertions(+)
 create mode 100644 tools/perf/arch/x86/util/intel-pt.c
 create mode 100644 tools/perf/util/intel-pt.c
 create mode 100644 tools/perf/util/intel-pt.h
tools/perf/arch/x86/util/Build +2 -0
index cfbccc4e3187..139608878888 100644
@@ -6,3 +6,5 @@ libperf-$(CONFIG_DWARF) += dwarf-regs.o
 
 libperf-$(CONFIG_LIBUNWIND)          += unwind-libunwind.o
 libperf-$(CONFIG_LIBDW_DWARF_UNWIND) += unwind-libdw.o
+
+libperf-$(CONFIG_AUXTRACE) += intel-pt.o
tools/perf/arch/x86/util/intel-pt.c new file +752 -0

752 lines not on this page · raw message

tools/perf/util/Build +1 -0
index e1b505a8055b..296de661933f 100644
@@ -77,6 +77,7 @@ libperf-y += cloexec.o
 libperf-y += thread-stack.o
 libperf-$(CONFIG_AUXTRACE) += auxtrace.o
 libperf-$(CONFIG_AUXTRACE) += intel-pt-decoder/
+libperf-$(CONFIG_AUXTRACE) += intel-pt.o
 libperf-y += parse-branch-options.o
 
 libperf-$(CONFIG_LIBELF) += symbol-elf.o
tools/perf/util/intel-pt.c new file +1889 -0

1,889 lines not on this page · raw message

tools/perf/util/intel-pt.h new file +51 -0

51 lines not on this page · raw message

Signature · 1 line
2.1.0
author maintainer
#7 lore raw

PATCH 7/8 perf tools: Take Intel PT into use

In reply to Arnaldo Carvalho de Melo

From: Adrian Hunter <[email protected]>

To record an AUX area, the weak function auxtrace_record__init() must be implemented.

Equally to decode an AUX area, the AUX area tracing type must be added to the perf_event__process_auxtrace_info() function.

This patch makes those two changes plus hooks up default config for the intel_pt PMU. Also some brief documentation is provided for using the tools with intel_pt.

E.g:

[root@perf4 ~]# dmesg
451 [0.405807] Performance Events: PEBS fmt2+, 16-deep LBR, Broadwell events, full-width counters, Intel PMU driver. [root@perf4 ~]# perf --version
perf version 4.1.g53874a
[root@perf4 ~]# perf record -e intel_pt//u -a sleep 10
[ perf record: Woken up 1 times to write data ]
[ perf record: Captured and wrote 0.383 MB perf.data ]
[root@perf4 ~]# perf evlist
intel_pt//u
sched:sched_switch
dummy:u
[root@perf4 ~]# perf report --stdio
# To display the perf.data header info, please use --header/--header-only options.
#
#
# Total Lost Samples: 0
#
# Samples: 0 of event 'intel_pt//u'
# Event count (approx.): 0
#

  # Overhead  Command  Shared Object  Symbol
  # ........  .......  .............  ......

#

# Samples: 393 of event 'sched:sched_switch'
# Event count (approx.): 393
#

  # Overhead  Command         Shared Object     Symbol
  # ........  ..............  ................  ..............
    49.62%  swapper         [kernel.vmlinux]  [k] __schedule
    10.69%  rcu_sched       [kernel.vmlinux]  [k] __schedule
     6.62%  rcuos/0         [kernel.vmlinux]  [k] __schedule
     5.60%  kworker/0:1     [kernel.vmlinux]  [k] __schedule
     3.56%  rcuos/3         [kernel.vmlinux]  [k] __schedule
     3.05%  kworker/u384:2  [kernel.vmlinux]  [k] __schedule
     2.54%  kworker/2:0     [kernel.vmlinux]  [k] __schedule
     2.54%  tuned           [kernel.vmlinux]  [k] __schedule
  <SNIP>
  # Samples: 0  of event 'dummy:u'
  # Event count (approx.): 0
  #
  # Overhead  Command  Shared Object  Symbol
  # ........  .......  .............  ......

# Samples: 28 of event 'instructions:u'
# Event count (approx.): 5030172
#

  # Overhead  Command     Shared Object        Symbol
  # ........  ..........  ...................  ................................
  #
    21.43%  tuned       libpython2.7.so.1.0  [.] PyEval_EvalFrameEx
                 |
                 ---PyEval_EvalFrameEx
                    |
                    |--83.33%-- PyEval_EvalCodeEx
                    |          PyEval_EvalFrameEx
                    |          |
                    |          |--60.00%-- PyEval_EvalCodeEx
                    |          |          PyEval_EvalFrameEx
                    |          |          PyEval_EvalFrameEx
                    |          |
                    |           --40.00%-- PyEval_EvalFrameEx
                    |
                     --16.67%-- PyEval_EvalFrameEx
                               PyEval_EvalCodeEx
                               PyEval_EvalFrameEx
                               PyEval_EvalCodeEx
                               PyEval_EvalFrameEx
                               PyEval_EvalFrameEx

    14.29%  tuned       libpython2.7.so.1.0  [.] _PyType_Lookup
                 |
                 ---_PyType_Lookup
                    _PyObject_GenericGetAttrWithDict
                    PyEval_EvalFrameEx
                    PyEval_EvalCodeEx
                    PyEval_EvalFrameEx
                    PyEval_EvalCodeEx
                    PyEval_EvalFrameEx
                    |
                    |--75.00%-- PyEval_EvalFrameEx
                    |
                     --25.00%-- PyEval_EvalCodeEx
                               PyEval_EvalFrameEx
                               PyEval_EvalFrameEx

     3.57%  irqbalance  irqbalance           [.] 0x0000000000004038
            |
            ---0x4038
               0x4761
               0x4761
               0x4761
               0x49f1
               0x2295

     3.57%  irqbalance  libc-2.17.so         [.] __GI_____strtoull_l_internal
            |
            ---__GI_____strtoull_l_internal
               0x6f49
               0x229a

     3.57%  irqbalance  libc-2.17.so         [.] __strchrnul
            |
            ---__strchrnul
               vfprintf
               __vsprintf_chk
               __sprintf_chk
               0x2724
               0x4038
               0x2331

     3.57%  irqbalance  libc-2.17.so         [.] __strstr_sse42
            |
            ---__strstr_sse42
               0x71e0
               0x229f

# And now to some userspace ftrace on uninstrumented binaries 8-) :
# Hand edited to make it a bit more compact, replacing /home/acme/bin/perf

  # with /bin/perf:

[root@perf4 ~]# perf script

     perf 8921 [3] 7.310889: 1 branches:u:            0 [unknown] ([unknown]) => 7fcecadbf257 __GI___ioctl (/usr/lib64/libc-2.17.so)
     perf 8921 [3] 7.310889: 1 branches:u: 7fcecadbf25f __GI___ioctl (/usr/lib64/libc-2.17.so) => 481689 perf_evlist__enable (/bin/perf)
     perf 8921 [3] 7.310889: 1 branches:u:       481694 perf_evlist__enable (/bin/perf) => 481614 perf_evlist__enable (/bin/perf)
     perf 8921 [3] 7.310889: 1 branches:u:       481630 perf_evlist__enable (/bin/perf) => 4816d8 perf_evlist__enable (/bin/perf)
     perf 8921 [3] 7.310889: 1 branches:u:       4816de perf_evlist__enable (/bin/perf) => 48164f perf_evlist__enable (/bin/perf)
     perf 8921 [3] 7.310889: 1 branches:u:       481652 perf_evlist__enable (/bin/perf) => 48165f perf_evlist__enable (/bin/perf)
     perf 8921 [3] 7.310889: 1 branches:u:       481684 perf_evlist__enable (/bin/perf) => 41d250 ioctl@plt (/bin/perf)
     perf 8921 [3] 7.310889: 1 branches:u:       41d250 ioctl@plt (/bin/perf) => 7fcecadbf250 __GI___ioctl (/usr/lib64/libc-2.17.so)
     perf 8921 [3] 7.310889: 1 branches:u: 7fcecadbf255 __GI___ioctl (/usr/lib64/libc-2.17.so) => 0 [unknown] ([unknown])
     perf 8921 [3] 7.310890: 1 branches:u:            0 [unknown] ([unknown]) => 7fcecadbf257 __GI___ioctl (/usr/lib64/libc-2.17.so)
     perf 8921 [3] 7.310890: 1 branches:u: 7fcecadbf25f __GI___ioctl (/usr/lib64/libc-2.17.so) => 481689 perf_evlist__enable (/bin/perf)
     perf 8921 [3] 7.310890: 1 branches:u:       481694 perf_evlist__enable (/bin/perf) => 481614 perf_evlist__enable (/bin/perf)
     perf 8921 [3] 7.310890: 1 branches:u:       481652 perf_evlist__enable (/bin/perf) => 48165f perf_evlist__enable (/bin/perf)
     perf 8921 [3] 7.310890: 1 branches:u:       481684 perf_evlist__enable (/bin/perf) => 41d250 ioctl@plt (/bin/perf)
     perf 8921 [3] 7.310890: 1 branches:u:       41d250 ioctl@plt (/bin/perf) => 7fcecadbf250 __GI___ioctl (/usr/lib64/libc-2.17.so)
     perf 8921 [3] 7.310890: 1 branches:u: 7fcecadbf255 __GI___ioctl (/usr/lib64/libc-2.17.so) => 0 [unknown] ([unknown])
     perf 8921 [3] 7.310893: 1 branches:u:            0 [unknown] ([unknown]) => 7fcecadbf257 __GI___ioctl (/usr/lib64/libc-2.17.so)
     perf 8921 [3] 7.310893: 1 branches:u: 7fcecadbf25f __GI___ioctl (/usr/lib64/libc-2.17.so) => 481689 perf_evlist__enable (/bin/perf)
     perf 8921 [3] 7.310893: 1 branches:u:       4816a8 perf_evlist__enable (/bin/perf) => 4815f8 perf_evlist__enable (/bin/perf)
     perf 8921 [3] 7.310893: 1 branches:u:       4815fe perf_evlist__enable (/bin/perf) => 481614 perf_evlist__enable (/bin/perf)
     perf 8921 [3] 7.310893: 1 branches:u:       481652 perf_evlist__enable (/bin/perf) => 48165f perf_evlist__enable (/bin/perf)
     perf 8921 [3] 7.310893: 1 branches:u:       481684 perf_evlist__enable (/bin/perf) => 41d250 ioctl@plt (/bin/perf)
     perf 8921 [3] 7.310893: 1 branches:u:       41d250 ioctl@plt (/bin/perf) => 7fcecadbf250 __GI___ioctl (/usr/lib64/libc-2.17.so)
     perf 8921 [3] 7.310893: 1 branches:u: 7fcecadbf255 __GI___ioctl (/usr/lib64/libc-2.17.so) => 0 [unknown] ([unknown])
     perf 8921 [3] 7.310956: 1 branches:u:            0 [unknown] ([unknown]) => 7fcecadbf257 __GI___ioctl (/usr/lib64/libc-2.17.so)
     perf 8921 [3] 7.310956: 1 branches:u: 7fcecadbf25f __GI___ioctl (/usr/lib64/libc-2.17.so) => 481689 perf_evlist__enable (/bin/perf)
     perf 8921 [3] 7.310956: 1 branches:u:       481694 perf_evlist__enable (/bin/perf) => 481614 perf_evlist__enable (/bin/perf)
     perf 8921 [3] 7.310956: 1 branches:u:       481630 perf_evlist__enable (/bin/perf) => 4816d8 perf_evlist__enable (/bin/perf)
     perf 8921 [3] 7.310956: 1 branches:u:       4816de perf_evlist__enable (/bin/perf) => 48164f perf_evlist__enable (/bin/perf)
     perf 8921 [3] 7.310956: 1 branches:u:       481652 perf_evlist__enable (/bin/perf) => 48165f perf_evlist__enable (/bin/perf)
     perf 8921 [3] 7.310956: 1 branches:u:       481684 perf_evlist__enable (/bin/perf) => 41d250 ioctl@plt (/bin/perf)
     perf 8921 [3] 7.310956: 1 branches:u:       41d250 ioctl@plt (/bin/perf) => 7fcecadbf250 __GI___ioctl (/usr/lib64/libc-2.17.so)
     perf 8921 [3] 7.310956: 1 branches:u: 7fcecadbf255 __GI___ioctl (/usr/lib64/libc-2.17.so) => 0 [unknown] ([unknown])
     perf 8921 [3] 7.310961: 1 branches:u:            0 [unknown] ([unknown]) => 7fcecadbf257 __GI___ioctl (/usr/lib64/libc-2.17.so)
     perf 8921 [3] 7.310961: 1 branches:u: 7fcecadbf25f __GI___ioctl (/usr/lib64/libc-2.17.so) => 481689 perf_evlist__enable (/bin/perf)
     perf 8921 [3] 7.310961: 1 branches:u:       481694 perf_evlist__enable (/bin/perf) => 481614 perf_evlist__enable (/bin/perf)
     perf 8921 [3] 7.310961: 1 branches:u:       481652 perf_evlist__enable (/bin/perf) => 48165f perf_evlist__enable (/bin/perf)
     perf 8921 [3] 7.310961: 1 branches:u:       481684 perf_evlist__enable (/bin/perf) => 41d250 ioctl@plt (/bin/perf)
     perf 8921 [3] 7.310961: 1 branches:u:       41d250 ioctl@plt (/bin/perf) => 7fcecadbf250 __GI___ioctl (/usr/lib64/libc-2.17.so)
     perf 8921 [3] 7.310961: 1 branches:u: 7fcecadbf255 __GI___ioctl (/usr/lib64/libc-2.17.so) => 0 [unknown] ([unknown])
     perf 8921 [3] 7.310968: 1 branches:u:            0 [unknown] ([unknown]) => 7fcecadbf257 __GI___ioctl (/usr/lib64/libc-2.17.so)
     perf 8921 [3] 7.310968: 1 branches:u: 7fcecadbf25f __GI___ioctl (/usr/lib64/libc-2.17.so) => 481689 perf_evlist__enable (/bin/perf)
     perf 8921 [3] 7.310968: 1 branches:u:       4816a8 perf_evlist__enable (/bin/perf) => 4815f8 perf_evlist__enable (/bin/perf)
     perf 8921 [3] 7.310968: 1 branches:u:       4815fe perf_evlist__enable (/bin/perf) => 481614 perf_evlist__enable (/bin/perf)
     perf 8921 [3] 7.310968: 1 branches:u:       481652 perf_evlist__enable (/bin/perf) => 48165f perf_evlist__enable (/bin/perf)
     perf 8921 [3] 7.310968: 1 branches:u:       481684 perf_evlist__enable (/bin/perf) => 41d250 ioctl@plt (/bin/perf)
     perf 8921 [3] 7.310968: 1 branches:u:       41d250 ioctl@plt (/bin/perf) => 7fcecadbf250 __GI___ioctl (/usr/lib64/libc-2.17.so)
     perf 8921 [3] 7.310968: 1 branches:u: 7fcecadbf255 __GI___ioctl (/usr/lib64/libc-2.17.so) => 0 [unknown] ([unknown])
     perf 8921 [3] 7.311040: 1 branches:u:            0 [unknown] ([unknown]) => 7fcecadbf257 __GI___ioctl (/usr/lib64/libc-2.17.so)
     perf 8921 [3] 7.311040: 1 branches:u: 7fcecadbf25f __GI___ioctl (/usr/lib64/libc-2.17.so) => 481689 perf_evlist__enable (/bin/perf)
     perf 8921 [3] 7.311040: 1 branches:u:       481694 perf_evlist__enable (/bin/perf) => 481614 perf_evlist__enable (/bin/perf)
     perf 8921 [3] 7.311040: 1 branches:u:       481630 perf_evlist__enable (/bin/perf) => 4816d8 perf_evlist__enable (/bin/perf)
     perf 8921 [3] 7.311040: 1 branches:u:       4816de perf_evlist__enable (/bin/perf) => 48164f perf_evlist__enable (/bin/perf)
     perf 8921 [3] 7.311040: 1 branches:u:       481652 perf_evlist__enable (/bin/perf) => 48165f perf_evlist__enable (/bin/perf)
     perf 8921 [3] 7.311040: 1 branches:u:       481684 perf_evlist__enable (/bin/perf) => 41d250 ioctl@plt (/bin/perf)
     perf 8921 [3] 7.311040: 1 branches:u:       41d250 ioctl@plt (/bin/perf) => 7fcecadbf250 __GI___ioctl (/usr/lib64/libc-2.17.so)
     perf 8921 [3] 7.311040: 1 branches:u: 7fcecadbf255 __GI___ioctl (/usr/lib64/libc-2.17.so) => 0 [unknown] ([unknown])
     perf 8921 [3] 7.311046: 1 branches:u:            0 [unknown] ([unknown]) => 7fcecadbf257 __GI___ioctl (/usr/lib64/libc-2.17.so)
     perf 8921 [3] 7.311046: 1 branches:u: 7fcecadbf25f __GI___ioctl (/usr/lib64/libc-2.17.so) => 481689 perf_evlist__enable (/bin/perf)
     perf 8921 [3] 7.311046: 1 branches:u:       481694 perf_evlist__enable (/bin/perf) => 481614 perf_evlist__enable (/bin/perf)
     perf 8921 [3] 7.311046: 1 branches:u:       481652 perf_evlist__enable (/bin/perf) => 48165f perf_evlist__enable (/bin/perf)
     perf 8921 [3] 7.311046: 1 branches:u:       481684 perf_evlist__enable (/bin/perf) => 41d250 ioctl@plt (/bin/perf)
     perf 8921 [3] 7.311046: 1 branches:u:       41d250 ioctl@plt (/bin/perf) => 7fcecadbf250 __GI___ioctl (/usr/lib64/libc-2.17.so)
     perf 8921 [3] 7.311046: 1 branches:u: 7fcecadbf255 __GI___ioctl (/usr/lib64/libc-2.17.so) => 0 [unknown] ([unknown])
     perf 8921 [3] 7.311050: 1 branches:u:            0 [unknown] ([unknown]) => 7fcecadbf257 __GI___ioctl (/usr/lib64/libc-2.17.so)
     perf 8921 [3] 7.311050: 1 branches:u: 7fcecadbf25f __GI___ioctl (/usr/lib64/libc-2.17.so) => 481689 perf_evlist__enable (/bin/perf)

:

---
 tools/perf/Documentation/intel-pt.txt | 588 ++++++++++++++++++++++++++++++++++
 tools/perf/arch/x86/util/Build        |   2 +
 tools/perf/arch/x86/util/auxtrace.c   |  38 +++
 tools/perf/arch/x86/util/pmu.c        |  15 +
 tools/perf/util/auxtrace.c            |   5 +-
 tools/perf/util/pmu.c                 |   4 +-
 6 files changed, 649 insertions(+), 3 deletions(-)
 create mode 100644 tools/perf/Documentation/intel-pt.txt
 create mode 100644 tools/perf/arch/x86/util/auxtrace.c
 create mode 100644 tools/perf/arch/x86/util/pmu.c
tools/perf/Documentation/intel-pt.txt new file +588 -0
new file mode 100644
index 000000000000..2866b62eb293
@@ -0,0 +1,588 @@
+Intel Processor Trace
+=====================
+
+Overview
+========
+
+Intel Processor Trace (Intel PT) is an extension of Intel Architecture that
+collects information about software execution such as control flow, execution
+modes and timings and formats it into highly compressed binary packets.
+Technical details are documented in the Intel 64 and IA-32 Architectures
+Software Developer Manuals, Chapter 36 Intel Processor Trace.
+
+Intel PT is first supported in Intel Core M and 5th generation Intel Core
+processors that are based on the Intel micro-architecture code name Broadwell.
+
+Trace data is collected by 'perf record' and stored within the perf.data file.
+See below for options to 'perf record'.
+
+Trace data must be 'decoded' which involves walking the object code and matching
+the trace data packets. For example a TNT packet only tells whether a
+conditional branch was taken or not taken, so to make use of that packet the
+decoder must know precisely which instruction was being executed.
+
+Decoding is done on-the-fly.  The decoder outputs samples in the same format as
+samples output by perf hardware events, for example as though the "instructions"
+or "branches" events had been recorded.  Presently 3 tools support this:
+'perf script', 'perf report' and 'perf inject'.  See below for more information
+on using those tools.
+
+The main distinguishing feature of Intel PT is that the decoder can determine
+the exact flow of software execution.  Intel PT can be used to understand why
+and how did software get to a certain point, or behave a certain way.  The
+software does not have to be recompiled, so Intel PT works with debug or release
+builds, however the executed images are needed - which makes use in JIT-compiled
+environments, or with self-modified code, a challenge.  Also symbols need to be
+provided to make sense of addresses.
+
+A limitation of Intel PT is that it produces huge amounts of trace data
+(hundreds of megabytes per second per core) which takes a long time to decode,
+for example two or three orders of magnitude longer than it took to collect.
+Another limitation is the performance impact of tracing, something that will
+vary depending on the use-case and architecture.
+
+
+Quickstart
+==========
+
+It is important to start small.  That is because it is easy to capture vastly
+more data than can possibly be processed.
+
+The simplest thing to do with Intel PT is userspace profiling of small programs.
+Data is captured with 'perf record' e.g. to trace 'ls' userspace-only:
+
+	perf record -e intel_pt//u ls
+
+And profiled with 'perf report' e.g.
+
+	perf report
+
+To also trace kernel space presents a problem, namely kernel self-modifying
+code.  A fairly good kernel image is available in /proc/kcore but to get an
+accurate image a copy of /proc/kcore needs to be made under the same conditions
+as the data capture.  A script perf-with-kcore can do that, but beware that the
+script makes use of 'sudo' to copy /proc/kcore.  If you have perf installed
+locally from the source tree you can do:
+
+	~/libexec/perf-core/perf-with-kcore record pt_ls -e intel_pt// -- ls
+
+which will create a directory named 'pt_ls' and put the perf.data file and
+copies of /proc/kcore, /proc/kallsyms and /proc/modules into it.  Then to use
+'perf report' becomes:
+
+	~/libexec/perf-core/perf-with-kcore report pt_ls
+
+Because samples are synthesized after-the-fact, the sampling period can be
+selected for reporting. e.g. sample every microsecond
+
+	~/libexec/perf-core/perf-with-kcore report pt_ls --itrace=i1usge
+
+See the sections below for more information about the --itrace option.
+
+Beware the smaller the period, the more samples that are produced, and the
+longer it takes to process them.
+
+Also note that the coarseness of Intel PT timing information will start to
+distort the statistical value of the sampling as the sampling period becomes
+smaller.
+
+To represent software control flow, "branches" samples are produced.  By default
+a branch sample is synthesized for every single branch.  To get an idea what
+data is available you can use the 'perf script' tool with no parameters, which
+will list all the samples.
+
+	perf record -e intel_pt//u ls
+	perf script
+
+An interesting field that is not printed by default is 'flags' which can be
+displayed as follows:
+
+	perf script -Fcomm,tid,pid,time,cpu,event,trace,ip,sym,dso,addr,symoff,flags
+
+The flags are "bcrosyiABEx" which stand for branch, call, return, conditional,
+system, asynchronous, interrupt, transaction abort, trace begin, trace end, and
+in transaction, respectively.
+
+While it is possible to create scripts to analyze the data, an alternative
+approach is available to export the data to a postgresql database.  Refer to
+script export-to-postgresql.py for more details, and to script
+call-graph-from-postgresql.py for an example of using the database.
+
+As mentioned above, it is easy to capture too much data.  One way to limit the
+data captured is to use 'snapshot' mode which is explained further below.
+Refer to 'new snapshot option' and 'Intel PT modes of operation' further below.
+
+Another problem that will be experienced is decoder errors.  They can be caused
+by inability to access the executed image, self-modified or JIT-ed code, or the
+inability to match side-band information (such as context switches and mmaps)
+which results in the decoder not knowing what code was executed.
+
+There is also the problem of perf not being able to copy the data fast enough,
+resulting in data lost because the buffer was full.  See 'Buffer handling' below
+for more details.
+
+
+perf record
+===========
+
+new event
+---------
+
+The Intel PT kernel driver creates a new PMU for Intel PT.  PMU events are
+selected by providing the PMU name followed by the "config" separated by slashes.
+An enhancement has been made to allow default "config" e.g. the option
+
+	-e intel_pt//
+
+will use a default config value.  Currently that is the same as
+
+	-e intel_pt/tsc,noretcomp=0/
+
+which is the same as
+
+	-e intel_pt/tsc=1,noretcomp=0/
+
+The config terms are listed in /sys/devices/intel_pt/format.  They are bit
+fields within the config member of the struct perf_event_attr which is
+passed to the kernel by the perf_event_open system call.  They correspond to bit
+fields in the IA32_RTIT_CTL MSR.  Here is a list of them and their definitions:
+
+	$ for f in `ls /sys/devices/intel_pt/format`;do
+	> echo $f
+	> cat /sys/devices/intel_pt/format/$f
+	> done
+	noretcomp
+	config:11
+	tsc
+	config:10
+
+Note that the default config must be overridden for each term i.e.
+
+	-e intel_pt/noretcomp=0/
+
+is the same as:
+
+	-e intel_pt/tsc=1,noretcomp=0/
+
+So, to disable TSC packets use:
+
+	-e intel_pt/tsc=0/
+
+It is also possible to specify the config value explicitly:
+
+	-e intel_pt/config=0x400/
+
+Note that, as with all events, the event is suffixed with event modifiers:
+
+	u	userspace
+	k	kernel
+	h	hypervisor
+	G	guest
+	H	host
+	p	precise ip
+
+'h', 'G' and 'H' are for virtualization which is not supported by Intel PT.
+'p' is also not relevant to Intel PT.  So only options 'u' and 'k' are
+meaningful for Intel PT.
+
+perf_event_attr is displayed if the -vv option is used e.g.
+
+	------------------------------------------------------------
+	perf_event_attr:
+	type                             6
+	size                             112
+	config                           0x400
+	{ sample_period, sample_freq }   1
+	sample_type                      IP|TID|TIME|CPU|IDENTIFIER
+	read_format                      ID
+	disabled                         1
+	inherit                          1
+	exclude_kernel                   1
+	exclude_hv                       1
+	enable_on_exec                   1
+	sample_id_all                    1
+	------------------------------------------------------------
+	sys_perf_event_open: pid 31104  cpu 0  group_fd -1  flags 0x8
+	sys_perf_event_open: pid 31104  cpu 1  group_fd -1  flags 0x8
+	sys_perf_event_open: pid 31104  cpu 2  group_fd -1  flags 0x8
+	sys_perf_event_open: pid 31104  cpu 3  group_fd -1  flags 0x8
+	------------------------------------------------------------
+
+
+new snapshot option
+-------------------
+
+To select snapshot mode a new option has been added:
+
+	-S
+
+Optionally it can be followed by the snapshot size e.g.
+
+	-S0x100000
+
+The default snapshot size is the auxtrace mmap size.  If neither auxtrace mmap size
+nor snapshot size is specified, then the default is 4MiB for privileged users
+(or if /proc/sys/kernel/perf_event_paranoid < 0), 128KiB for unprivileged users.
+If an unprivileged user does not specify mmap pages, the mmap pages will be
+reduced as described in the 'new auxtrace mmap size option' section below.
+
+The snapshot size is displayed if the option -vv is used e.g.
+
+	Intel PT snapshot size: %zu
+
+
+new auxtrace mmap size option
+---------------------------
+
+Intel PT buffer size is specified by an addition to the -m option e.g.
+
+	-m,16
+
+selects a buffer size of 16 pages i.e. 64KiB.
+
+Note that the existing functionality of -m is unchanged.  The auxtrace mmap size
+is specified by the optional addition of a comma and the value.
+
+The default auxtrace mmap size for Intel PT is 4MiB/page_size for privileged users
+(or if /proc/sys/kernel/perf_event_paranoid < 0), 128KiB for unprivileged users.
+If an unprivileged user does not specify mmap pages, the mmap pages will be
+reduced from the default 512KiB/page_size to 256KiB/page_size, otherwise the
+user is likely to get an error as they exceed their mlock limit (Max locked
+memory as shown in /proc/self/limits).  Note that perf does not count the first
+512KiB (actually /proc/sys/kernel/perf_event_mlock_kb minus 1 page) per cpu
+against the mlock limit so an unprivileged user is allowed 512KiB per cpu plus
+their mlock limit (which defaults to 64KiB but is not multiplied by the number
+of cpus).
+
+In full-trace mode, powers of two are allowed for buffer size, with a minimum
+size of 2 pages.  In snapshot mode, it is the same but the minimum size is
+1 page.
+
+The mmap size and auxtrace mmap size are displayed if the -vv option is used e.g.
+
+	mmap length 528384
+	auxtrace mmap length 4198400
+
+
+Intel PT modes of operation
+---------------------------
+
+Intel PT can be used in 2 modes:
+	full-trace mode
+	snapshot mode
+
+Full-trace mode traces continuously e.g.
+
+	perf record -e intel_pt//u uname
+
+Snapshot mode captures the available data when a signal is sent e.g.
+
+	perf record -v -e intel_pt//u -S ./loopy 1000000000 &
+	[1] 11435
+	kill -USR2 11435
+	Recording AUX area tracing snapshot
+
+Note that the signal sent is SIGUSR2.
+Note that "Recording AUX area tracing snapshot" is displayed because the -v
+option is used.
+
+The 2 modes cannot be used together.
+
+
+Buffer handling
+---------------
+
+There may be buffer limitations (i.e. single ToPa entry) which means that actual
+buffer sizes are limited to powers of 2 up to 4MiB (MAX_ORDER).  In order to
+provide other sizes, and in particular an arbitrarily large size, multiple
+buffers are logically concatenated.  However an interrupt must be used to switch
+between buffers.  That has two potential problems:
+	a) the interrupt may not be handled in time so that the current buffer
+	becomes full and some trace data is lost.
+	b) the interrupts may slow the system and affect the performance
+	results.
+
+If trace data is lost, the driver sets 'truncated' in the PERF_RECORD_AUX event
+which the tools report as an error.
+
+In full-trace mode, the driver waits for data to be copied out before allowing
+the (logical) buffer to wrap-around.  If data is not copied out quickly enough,
+again 'truncated' is set in the PERF_RECORD_AUX event.  If the driver has to
+wait, the intel_pt event gets disabled.  Because it is difficult to know when
+that happens, perf tools always re-enable the intel_pt event after copying out
+data.
+
+
+Intel PT and build ids
+----------------------
+
+By default "perf record" post-processes the event stream to find all build ids
+for executables for all addresses sampled.  Deliberately, Intel PT is not
+decoded for that purpose (it would take too long).  Instead the build ids for
+all executables encountered (due to mmap, comm or task events) are included
+in the perf.data file.
+
+To see buildids included in the perf.data file use the command:
+
+	perf buildid-list
+
+If the perf.data file contains Intel PT data, that is the same as:
+
+	perf buildid-list --with-hits
+
+
+Snapshot mode and event disabling
+---------------------------------
+
+In order to make a snapshot, the intel_pt event is disabled using an IOCTL,
+namely PERF_EVENT_IOC_DISABLE.  However doing that can also disable the
+collection of side-band information.  In order to prevent that,  a dummy
+software event has been introduced that permits tracking events (like mmaps) to
+continue to be recorded while intel_pt is disabled.  That is important to ensure
+there is complete side-band information to allow the decoding of subsequent
+snapshots.
+
+A test has been created for that.  To find the test:
+
+	perf test list
+	...
+	23: Test using a dummy software event to keep tracking
+
+To run the test:
+
+	perf test 23
+	23: Test using a dummy software event to keep tracking     : Ok
+
+
+perf record modes (nothing new here)
+------------------------------------
+
+perf record essentially operates in one of three modes:
+	per thread
+	per cpu
+	workload only
+
+"per thread" mode is selected by -t or by --per-thread (with -p or -u or just a
+workload).
+"per cpu" is selected by -C or -a.
+"workload only" mode is selected by not using the other options but providing a
+command to run (i.e. the workload).
+
+In per-thread mode an exact list of threads is traced.  There is no inheritance.
+Each thread has its own event buffer.
+
+In per-cpu mode all processes (or processes from the selected cgroup i.e. -G
+option, or processes selected with -p or -u) are traced.  Each cpu has its own
+buffer. Inheritance is allowed.
+
+In workload-only mode, the workload is traced but with per-cpu buffers.
+Inheritance is allowed.  Note that you can now trace a workload in per-thread
+mode by using the --per-thread option.
+
+
+Privileged vs non-privileged users
+----------------------------------
+
+Unless /proc/sys/kernel/perf_event_paranoid is set to -1, unprivileged users
+have memory limits imposed upon them.  That affects what buffer sizes they can
+have as outlined above.
+
+Unless /proc/sys/kernel/perf_event_paranoid is set to -1, unprivileged users are
+not permitted to use tracepoints which means there is insufficient side-band
+information to decode Intel PT in per-cpu mode, and potentially workload-only
+mode too if the workload creates new processes.
+
+Note also, that to use tracepoints, read-access to debugfs is required.  So if
+debugfs is not mounted or the user does not have read-access, it will again not
+be possible to decode Intel PT in per-cpu mode.
+
+
+sched_switch tracepoint
+-----------------------
+
+The sched_switch tracepoint is used to provide side-band data for Intel PT
+decoding.  sched_switch events are automatically added. e.g. the second event
+shown below
+
+	$ perf record -vv -e intel_pt//u uname
+	------------------------------------------------------------
+	perf_event_attr:
+	type                             6
+	size                             112
+	config                           0x400
+	{ sample_period, sample_freq }   1
+	sample_type                      IP|TID|TIME|CPU|IDENTIFIER
+	read_format                      ID
+	disabled                         1
+	inherit                          1
+	exclude_kernel                   1
+	exclude_hv                       1
+	enable_on_exec                   1
+	sample_id_all                    1
+	------------------------------------------------------------
+	sys_perf_event_open: pid 31104  cpu 0  group_fd -1  flags 0x8
+	sys_perf_event_open: pid 31104  cpu 1  group_fd -1  flags 0x8
+	sys_perf_event_open: pid 31104  cpu 2  group_fd -1  flags 0x8
+	sys_perf_event_open: pid 31104  cpu 3  group_fd -1  flags 0x8
+	------------------------------------------------------------
+	perf_event_attr:
+	type                             2
+	size                             112
+	config                           0x108
+	{ sample_period, sample_freq }   1
+	sample_type                      IP|TID|TIME|CPU|PERIOD|RAW|IDENTIFIER
+	read_format                      ID
+	inherit                          1
+	sample_id_all                    1
+	exclude_guest                    1
+	------------------------------------------------------------
+	sys_perf_event_open: pid -1  cpu 0  group_fd -1  flags 0x8
+	sys_perf_event_open: pid -1  cpu 1  group_fd -1  flags 0x8
+	sys_perf_event_open: pid -1  cpu 2  group_fd -1  flags 0x8
+	sys_perf_event_open: pid -1  cpu 3  group_fd -1  flags 0x8
+	------------------------------------------------------------
+	perf_event_attr:
+	type                             1
+	size                             112
+	config                           0x9
+	{ sample_period, sample_freq }   1
+	sample_type                      IP|TID|TIME|IDENTIFIER
+	read_format                      ID
+	disabled                         1
+	inherit                          1
+	exclude_kernel                   1
+	exclude_hv                       1
+	mmap                             1
+	comm                             1
+	enable_on_exec                   1
+	task                             1
+	sample_id_all                    1
+	mmap2                            1
+	comm_exec                        1
+	------------------------------------------------------------
+	sys_perf_event_open: pid 31104  cpu 0  group_fd -1  flags 0x8
+	sys_perf_event_open: pid 31104  cpu 1  group_fd -1  flags 0x8
+	sys_perf_event_open: pid 31104  cpu 2  group_fd -1  flags 0x8
+	sys_perf_event_open: pid 31104  cpu 3  group_fd -1  flags 0x8
+	mmap size 528384B
+	AUX area mmap length 4194304
+	perf event ring buffer mmapped per cpu
+	Synthesizing auxtrace information
+	Linux
+	[ perf record: Woken up 1 times to write data ]
+	[ perf record: Captured and wrote 0.042 MB perf.data ]
+
+Note, the sched_switch event is only added if the user is permitted to use it
+and only in per-cpu mode.
+
+Note also, the sched_switch event is only added if TSC packets are requested.
+That is because, in the absence of timing information, the sched_switch events
+cannot be matched against the Intel PT trace.
+
+
+perf script
+===========
+
+By default, perf script will decode trace data found in the perf.data file.
+This can be further controlled by new option --itrace.
+
+
+New --itrace option
+-------------------
+
+Having no option is the same as
+
+	--itrace
+
+which, in turn, is the same as
+
+	--itrace=ibxe
+
+The letters are:
+
+	i	synthesize "instructions" events
+	b	synthesize "branches" events
+	x	synthesize "transactions" events
+	c	synthesize branches events (calls only)
+	r	synthesize branches events (returns only)
+	e	synthesize tracing error events
+	d	create a debug log
+	g	synthesize a call chain (use with i or x)
+
+"Instructions" events look like they were recorded by "perf record -e
+instructions".
+
+"Branches" events look like they were recorded by "perf record -e branches". "c"
+and "r" can be combined to get calls and returns.
+
+"Transactions" events correspond to the start or end of transactions. The
+'flags' field can be used in perf script to determine whether the event is a
+tranasaction start, commit or abort.
+
+Error events are new.  They show where the decoder lost the trace.  Error events
+are quite important.  Users must know if what they are seeing is a complete
+picture or not.
+
+The "d" option will cause the creation of a file "intel_pt.log" containing all
+decoded packets and instructions.  Note that this option slows down the decoder
+and that the resulting file may be very large.
+
+In addition, the period of the "instructions" event can be specified. e.g.
+
+	--itrace=i10us
+
+sets the period to 10us i.e. one  instruction sample is synthesized for each 10
+microseconds of trace.  Alternatives to "us" are "ms" (milliseconds),
+"ns" (nanoseconds), "t" (TSC ticks) or "i" (instructions).
+
+"ms", "us" and "ns" are converted to TSC ticks.
+
+The timing information included with Intel PT does not give the time of every
+instruction.  Consequently, for the purpose of sampling, the decoder estimates
+the time since the last timing packet based on 1 tick per instruction.  The time
+on the sample is *not* adjusted and reflects the last known value of TSC.
+
+For Intel PT, the default period is 100us.
+
+Also the call chain size (default 16, max. 1024) for instructions or
+transactions events can be specified. e.g.
+
+	--itrace=ig32
+	--itrace=xg32
+
+To disable trace decoding entirely, use the option --no-itrace.
+
+
+dump option
+-----------
+
+perf script has an option (-D) to "dump" the events i.e. display the binary
+data.
+
+When -D is used, Intel PT packets are displayed.  The packet decoder does not
+pay attention to PSB packets, but just decodes the bytes - so the packets seen
+by the actual decoder may not be identical in places where the data is corrupt.
+One example of that would be when the buffer-switching interrupt has been too
+slow, and the buffer has been filled completely.  In that case, the last packet
+in the buffer might be truncated and immediately followed by a PSB as the trace
+continues in the next buffer.
+
+To disable the display of Intel PT packets, combine the -D option with
+--no-itrace.
+
+
+perf report
+===========
+
+By default, perf report will decode trace data found in the perf.data file.
+This can be further controlled by new option --itrace exactly the same as
+perf script, with the exception that the default is --itrace=igxe.
+
+
+perf inject
+===========
+
+perf inject also accepts the --itrace option in which case tracing data is
+removed and replaced with the synthesized events. e.g.
+
+	perf inject --itrace -i perf.data -o perf.data.new
tools/perf/arch/x86/util/Build +2 -0
index 139608878888..a8be9f9d0462 100644
@@ -1,5 +1,6 @@
 libperf-y += header.o
 libperf-y += tsc.o
+libperf-y += pmu.o
 libperf-y += kvm-stat.o
 
 libperf-$(CONFIG_DWARF) += dwarf-regs.o
@@ -7,4 +8,5 @@ libperf-$(CONFIG_DWARF) += dwarf-regs.o
 libperf-$(CONFIG_LIBUNWIND)          += unwind-libunwind.o
 libperf-$(CONFIG_LIBDW_DWARF_UNWIND) += unwind-libdw.o
 
+libperf-$(CONFIG_AUXTRACE) += auxtrace.o
 libperf-$(CONFIG_AUXTRACE) += intel-pt.o
tools/perf/arch/x86/util/auxtrace.c new file +38 -0
new file mode 100644
index 000000000000..e7654b506312
@@ -0,0 +1,38 @@
+/*
+ * auxtrace.c: AUX area tracing support
+ * Copyright (c) 2013-2014, Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ */
+
+#include "../../util/header.h"
+#include "../../util/auxtrace.h"
+#include "../../util/intel-pt.h"
+
+struct auxtrace_record *auxtrace_record__init(struct perf_evlist *evlist __maybe_unused,
+					      int *err)
+{
+	char buffer[64];
+	int ret;
+
+	*err = 0;
+
+	ret = get_cpuid(buffer, sizeof(buffer));
+	if (ret) {
+		*err = ret;
+		return NULL;
+	}
+
+	if (!strncmp(buffer, "GenuineIntel,", 13))
+		return intel_pt_recording_init(err);
+
+	return NULL;
+}
tools/perf/arch/x86/util/pmu.c new file +15 -0
new file mode 100644
index 000000000000..fd11cc3ce780
@@ -0,0 +1,15 @@
+#include <string.h>
+
+#include <linux/perf_event.h>
+
+#include "../../util/intel-pt.h"
+#include "../../util/pmu.h"
+
+struct perf_event_attr *perf_pmu__get_default_config(struct perf_pmu *pmu __maybe_unused)
+{
+#ifdef HAVE_AUXTRACE_SUPPORT
+	if (!strcmp(pmu->name, INTEL_PT_PMU_NAME))
+		return intel_pt_pmu_default_config(pmu);
+#endif
+	return NULL;
+}
tools/perf/util/auxtrace.c +4 -1
index ea29022a4f52..1b3cc297290d 100644
@@ -47,6 +47,8 @@
 #include "debug.h"
 #include "parse-options.h"
 
+#include "intel-pt.h"
+
 int auxtrace_mmap__mmap(struct auxtrace_mmap *mm,
 			struct auxtrace_mmap_params *mp,
 			void *userpg, int fd)
@@ -876,7 +878,7 @@ static bool auxtrace__dont_decode(struct perf_session *session)
 
 int perf_event__process_auxtrace_info(struct perf_tool *tool __maybe_unused,
 				      union perf_event *event,
-				      struct perf_session *session __maybe_unused)
+				      struct perf_session *session)
 {
 	enum auxtrace_type type = event->auxtrace_info.type;
 
@@ -885,6 +887,7 @@ int perf_event__process_auxtrace_info(struct perf_tool *tool __maybe_unused,
 
 	switch (type) {
 	case PERF_AUXTRACE_INTEL_PT:
+		return intel_pt_process_auxtrace_info(event, session);
 	case PERF_AUXTRACE_UNKNOWN:
 	default:
 		return -EINVAL;
tools/perf/util/pmu.c +2 -2
index 7bcb8c315615..b5ea26bc290d 100644
@@ -462,8 +462,8 @@ static struct perf_pmu *pmu_lookup(const char *name)
 	LIST_HEAD(aliases);
 	__u32 type;
 
-	/* No support for intel_bts or intel_pt so disallow them */
-	if (!strcmp(name, "intel_bts") || !strcmp(name, "intel_pt"))
+	/* No support for intel_bts so disallow it */
+	if (!strcmp(name, "intel_bts"))
 		return NULL;
 
 	/*
Signature · 1 line
2.1.0
author maintainer
#8 lore raw

PATCH 8/8 perf tools: Add Intel BTS support

In reply to Arnaldo Carvalho de Melo

From: Adrian Hunter <[email protected]>

Intel BTS support fits within the new auxtrace infrastructure. Recording is supporting by identifying the Intel BTS PMU, parsing options and setting up events.

Decoding is supported by queuing up trace data by thread and then decoding synchronously delivering synthesized event samples into the session processing for tools to consume.

E.g:

[root@zoo ~]# perf record --per-thread -e intel_bts// ls
anaconda-ks.cfg b bin lib64 libexec new old perf.data
perf.data.old stream_test tg.run
[ perf record: Woken up 2 times to write data ]
[ perf record: Captured and wrote 4.242 MB perf.data ]
[root@zoo ~]# perf evlist
intel_bts//
dummy:u
[root@zoo ~]# perf evlist -v
intel_bts//: type: 7, size: 112, { sample_period, sample_freq }: 1,
sample_type: IP|TID|IDENTIFIER, read_format: ID, disabled: 1,
enable_on_exec: 1, sample_id_all: 1, exclude_guest: 1 dummy:u:
type: 1, size: 112, config: 0x9, { sample_period, sample_freq }: 1,
sample_type: IP|TID|IDENTIFIER, read_format: ID, disabled: 1,
exclude_kernel: 1, exclude_hv: 1, mmap: 1, comm: 1, enable_on_exec: 1,
task: 1, sample_id_all: 1, mmap2: 1, comm_exec: 1
[root@zoo ~]# perf report --stdio
# To display the perf.data header info, please use --header/--header-only options. #
#
# Total Lost Samples: 0
#
# Samples: 0 of event 'intel_bts//'
# Event count (approx.): 0
#

  # Overhead  Command  Shared Object  Symbol
  # ........  .......  .............  ......

#

# Samples: 0 of event 'dummy:u'
# Event count (approx.): 0
#

  # Overhead  Command  Shared Object  Symbol
  # ........  .......  .............  ......

#

# Samples: 184K of event 'branches'
# Event count (approx.): 184522
#

  # Overhead  Command  Shared Object       Symbol
  # ........  .......  ..................  ..............................................
  #
     7.36%  ls       [kernel.kallsyms]   [.] unmap_single_vma
     4.69%  ls       ld-2.20.so          [.] strcmp
     4.66%  ls       libc-2.20.so        [.] _dl_addr
     3.43%  ls       [kernel.kallsyms]   [.] change_protection
     3.01%  ls       ld-2.20.so          [.] do_lookup_x
     2.18%  ls       [kernel.kallsyms]   [.] filemap_map_pages
     2.09%  ls       ld-2.20.so          [.] _dl_name_match_p
     1.93%  ls       ld-2.20.so          [.] _dl_lookup_symbol_x
     1.91%  ls       [kernel.kallsyms]   [.] page_remove_rmap
     1.72%  ls       [kernel.kallsyms]   [.] do_set_pte
     1.48%  ls       ld-2.20.so          [.] _dl_relocate_object
     1.34%  ls       [kernel.kallsyms]   [.] mem_cgroup_begin_page_stat
     1.11%  ls       [kernel.kallsyms]   [.] page_add_file_rmap
     1.00%  ls       [kernel.kallsyms]   [.] mark_page_accessed
     0.97%  ls       [kernel.kallsyms]   [.] perf_event_aux
     0.95%  ls       [kernel.kallsyms]   [.] handle_mm_fault
     0.94%  ls       [kernel.kallsyms]   [.] get_page_from_freelist
  <SNIP>
  [root@zoo ~]# perf record --per-thread -e intel_bts//u ls
  <SNIP>
  [ perf record: Woken up 1 times to write data ]
  [ perf record: Captured and wrote 1.278 MB perf.data ]
  [root@zoo ~]# perf report --stdio
  <SNIP>
  # Samples: 55K of event 'branches:u'
  # Event count (approx.): 55165
  #
  # Overhead  Command  Shared Object       Symbol
  # ........  .......  ..................  ......................................
  #
    15.69%  ls       ld-2.20.so          [.] strcmp
    15.58%  ls       libc-2.20.so        [.] _dl_addr
    10.05%  ls       ld-2.20.so          [.] do_lookup_x
     6.98%  ls       ld-2.20.so          [.] _dl_name_match_p
     6.46%  ls       ld-2.20.so          [.] _dl_lookup_symbol_x
     4.95%  ls       ld-2.20.so          [.] _dl_relocate_object
     2.96%  ls       ls                  [.] quotearg_buffer_restyled
     2.78%  ls       libc-2.20.so        [.] getenv
     1.91%  ls       ld-2.20.so          [.] _dl_cache_libcmp
     1.76%  ls       libc-2.20.so        [.] __memmove_sse2
     1.75%  ls       ld-2.20.so          [.] check_match.isra.0
     1.47%  ls       ld-2.20.so          [.] _dl_map_object_deps
     1.27%  ls       ld-2.20.so          [.] _dl_map_object_from_fd
     1.17%  ls       ls                  [.] quote_name
     1.16%  ls       ld-2.20.so          [.] _dl_check_map_versions
   <SNIP>
     0.19%  ls       [kernel.kallsyms]   [.] entry_SYSCALL_64_fastpath
     0.19%  ls       [kernel.kallsyms]   [.] native_irq_return_iret
     0.19%  ls       libc-2.20.so        [.] _IO_file_xsputn@@GLIBC_2.2.5

<SNIP>

[ Add a fix for an infinite loop in intel_bts_process_buffer
misplaced in a followup patch in the original patchkit ]

---
 tools/perf/Documentation/intel-bts.txt |  86 ++++
 tools/perf/arch/x86/util/Build         |   1 +
 tools/perf/arch/x86/util/auxtrace.c    |  49 +-
 tools/perf/arch/x86/util/intel-bts.c   | 458 +++++++++++++++++++
 tools/perf/arch/x86/util/pmu.c         |   3 +
 tools/perf/util/Build                  |   1 +
 tools/perf/util/auxtrace.c             |   3 +
 tools/perf/util/auxtrace.h             |   1 +
 tools/perf/util/intel-bts.c            | 791 +++++++++++++++++++++++++++++++++
 tools/perf/util/intel-bts.h            |  43 ++
 tools/perf/util/pmu.c                  |   4 -
 11 files changed, 1434 insertions(+), 6 deletions(-)
 create mode 100644 tools/perf/Documentation/intel-bts.txt
 create mode 100644 tools/perf/arch/x86/util/intel-bts.c
 create mode 100644 tools/perf/util/intel-bts.c
 create mode 100644 tools/perf/util/intel-bts.h
tools/perf/Documentation/intel-bts.txt new file +86 -0
new file mode 100644
index 000000000000..8bdc93bd7fdb
@@ -0,0 +1,86 @@
+Intel Branch Trace Store
+========================
+
+Overview
+========
+
+Intel BTS could be regarded as a predecessor to Intel PT and has some
+similarities because it can also identify every branch a program takes.  A
+notable difference is that Intel BTS has no timing information and as a
+consequence the present implementation is limited to per-thread recording.
+
+While decoding Intel BTS does not require walking the object code, the object
+code is still needed to pair up calls and returns correctly, consequently much
+of the Intel PT documentation applies also to Intel BTS.  Refer to the Intel PT
+documentation and consider that the PMU 'intel_bts' can usually be used in
+place of 'intel_pt' in the examples provided, with the proviso that per-thread
+recording must also be stipulated i.e. the --per-thread option for
+'perf record'.
+
+
+perf record
+===========
+
+new event
+---------
+
+The Intel BTS kernel driver creates a new PMU for Intel BTS.  The perf record
+option is:
+
+	-e intel_bts//
+
+Currently Intel BTS is limited to per-thread tracing so the --per-thread option
+is also needed.
+
+
+snapshot option
+---------------
+
+The snapshot option is the same as Intel PT (refer Intel PT documentation).
+
+
+auxtrace mmap size option
+-----------------------
+
+The mmap size option is the same as Intel PT (refer Intel PT documentation).
+
+
+perf script
+===========
+
+By default, perf script will decode trace data found in the perf.data file.
+This can be further controlled by option --itrace.  The --itrace option is
+the same as Intel PT (refer Intel PT documentation) except that neither
+"instructions" events nor "transactions" events (and consequently call
+chains) are supported.
+
+To disable trace decoding entirely, use the option --no-itrace.
+
+
+dump option
+-----------
+
+perf script has an option (-D) to "dump" the events i.e. display the binary
+data.
+
+When -D is used, Intel BTS packets are displayed.
+
+To disable the display of Intel BTS packets, combine the -D option with
+--no-itrace.
+
+
+perf report
+===========
+
+By default, perf report will decode trace data found in the perf.data file.
+This can be further controlled by new option --itrace exactly the same as
+perf script.
+
+
+perf inject
+===========
+
+perf inject also accepts the --itrace option in which case tracing data is
+removed and replaced with the synthesized events. e.g.
+
+	perf inject --itrace -i perf.data -o perf.data.new
tools/perf/arch/x86/util/Build +1 -0
index a8be9f9d0462..2c55e1b336c5 100644
@@ -10,3 +10,4 @@ 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
tools/perf/arch/x86/util/auxtrace.c +47 -2

65 lines not on this page · raw message

tools/perf/arch/x86/util/intel-bts.c new file +458 -0

458 lines not on this page · raw message

tools/perf/arch/x86/util/pmu.c +3 -0
index fd11cc3ce780..79fe07158d00 100644
@@ -3,6 +3,7 @@
 #include <linux/perf_event.h>
 
 #include "../../util/intel-pt.h"
+#include "../../util/intel-bts.h"
 #include "../../util/pmu.h"
 
 struct perf_event_attr *perf_pmu__get_default_config(struct perf_pmu *pmu __maybe_unused)
@@ -10,6 +11,8 @@ struct perf_event_attr *perf_pmu__get_default_config(struct perf_pmu *pmu __mayb
 #ifdef HAVE_AUXTRACE_SUPPORT
 	if (!strcmp(pmu->name, INTEL_PT_PMU_NAME))
 		return intel_pt_pmu_default_config(pmu);
+	if (!strcmp(pmu->name, INTEL_BTS_PMU_NAME))
+		pmu->selectable = true;
 #endif
 	return NULL;
 }
tools/perf/util/Build +1 -0
index 296de661933f..09340834fbd1 100644
@@ -78,6 +78,7 @@ libperf-y += thread-stack.o
 libperf-$(CONFIG_AUXTRACE) += auxtrace.o
 libperf-$(CONFIG_AUXTRACE) += intel-pt-decoder/
 libperf-$(CONFIG_AUXTRACE) += intel-pt.o
+libperf-$(CONFIG_AUXTRACE) += intel-bts.o
 libperf-y += parse-branch-options.o
 
 libperf-$(CONFIG_LIBELF) += symbol-elf.o
tools/perf/util/auxtrace.c +3 -0
index 1b3cc297290d..3f3b40fa87c8 100644
@@ -48,6 +48,7 @@
 #include "parse-options.h"
 
 #include "intel-pt.h"
+#include "intel-bts.h"
 
 int auxtrace_mmap__mmap(struct auxtrace_mmap *mm,
 			struct auxtrace_mmap_params *mp,
@@ -888,6 +889,8 @@ int perf_event__process_auxtrace_info(struct perf_tool *tool __maybe_unused,
 	switch (type) {
 	case PERF_AUXTRACE_INTEL_PT:
 		return intel_pt_process_auxtrace_info(event, session);
+	case PERF_AUXTRACE_INTEL_BTS:
+		return intel_bts_process_auxtrace_info(event, session);
 	case PERF_AUXTRACE_UNKNOWN:
 	default:
 		return -EINVAL;
tools/perf/util/auxtrace.h +1 -0
index 7d12f33a3a06..bf72b77a588a 100644
@@ -40,6 +40,7 @@ struct events_stats;
 enum auxtrace_type {
 	PERF_AUXTRACE_UNKNOWN,
 	PERF_AUXTRACE_INTEL_PT,
+	PERF_AUXTRACE_INTEL_BTS,
 };
 
 enum itrace_period_type {
tools/perf/util/intel-bts.c new file +791 -0

791 lines not on this page · raw message

tools/perf/util/intel-bts.h new file +43 -0

43 lines not on this page · raw message

tools/perf/util/pmu.c +0 -4
index b5ea26bc290d..52d569cda606 100644
@@ -462,10 +462,6 @@ static struct perf_pmu *pmu_lookup(const char *name)
 	LIST_HEAD(aliases);
 	__u32 type;
 
-	/* No support for intel_bts so disallow it */
-	if (!strcmp(name, "intel_bts"))
-		return NULL;
-
 	/*
 	 * The pmu data we store & need consists of the pmu
 	 * type value and format definitions. Load both right
Signature · 1 line
2.1.0
#9 lore raw
In reply to Arnaldo Carvalho de Melo
Quoted 93 lines · Arnaldo Carvalho de Melo

Hi Ingo,

Please consider pulling, there are several other patches after this,
but I think that this may be acceptable to showcase the capabilities already present, look at the output of 'perf script' and callchains for userspace without using any extra debugging info (no need for DWARF, CFI, nothing), really cool capabilities... :-)

Adrian wrote some docs and I tested it both on a Ivy Bridge machine
where there is only BTS and on a Broadwell machine with the whole shebang, adding the output of the commands to the csets, to further showcase what is there already.

This is on top of my last perf-core-for-mingo tag.

Up to you, please let us know what you think and we'll continue working
on having this in an acceptable form for merging,

Regards,

- Arnaldo

P.S. Kudos for Adrian for the patience with this process, way more is needed to polish this, but the promise is there, cool stuff indeed! :-)

The following changes since commit 36c8bb56a9f718a9a5f35d1834ca9dcec95deb4a:

perf symbols: Check access permission when reading symbol files (2015-06-26 12:11:53 -0300)

are available in the git repository at:

git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux.git tags/perf-pt-for-mingo

for you to fetch changes up to 04759f172270afb28c8004f5cad62ed55710a499:

perf tools: Add Intel BTS support (2015-06-26 18:36:11 -0300)

----------------------------------------------------------------
Put Intel PT and BTS into initial use (Adrian Hunter)

----------------------------------------------------------------
Adrian Hunter (8):
perf auxtrace: Add Intel PT as an AUX area tracing type perf tools: Add Intel PT packet decoder
perf tools: Add Intel PT instruction decoder perf tools: Add Intel PT log
perf tools: Add Intel PT decoder
perf tools: Add Intel PT support
perf tools: Take Intel PT into use
perf tools: Add Intel BTS support

 tools/build/Makefile.build                         |    2 +
 tools/perf/.gitignore                              |    2 +
 tools/perf/Documentation/intel-bts.txt             |   86 +
 tools/perf/Documentation/intel-pt.txt              |  588 ++++++
 tools/perf/MANIFEST                                |    7 +
 tools/perf/Makefile.perf                           |   12 +-
 tools/perf/arch/x86/util/Build                     |    5 +
 tools/perf/arch/x86/util/auxtrace.c                |   83 +
 tools/perf/arch/x86/util/intel-bts.c               |  458 +++++
 tools/perf/arch/x86/util/intel-pt.c                |  752 ++++++++
 tools/perf/arch/x86/util/pmu.c                     |   18 +
 tools/perf/util/Build                              |    3 +
 tools/perf/util/auxtrace.c                         |    9 +-
 tools/perf/util/auxtrace.h                         |    2 +
 tools/perf/util/intel-bts.c                        |  791 ++++++++
 tools/perf/util/intel-bts.h                        |   43 +
 tools/perf/util/intel-pt-decoder/Build             |   14 +
 .../perf/util/intel-pt-decoder/intel-pt-decoder.c  | 1759 ++++++++++++++++++
 .../perf/util/intel-pt-decoder/intel-pt-decoder.h  |  102 ++
 .../util/intel-pt-decoder/intel-pt-insn-decoder.c  |  246 +++
 .../util/intel-pt-decoder/intel-pt-insn-decoder.h  |   65 +
 tools/perf/util/intel-pt-decoder/intel-pt-log.c    |  155 ++
 tools/perf/util/intel-pt-decoder/intel-pt-log.h    |   52 +
 .../util/intel-pt-decoder/intel-pt-pkt-decoder.c   |  400 +++++
 .../util/intel-pt-decoder/intel-pt-pkt-decoder.h   |   64 +
 tools/perf/util/intel-pt.c                         | 1889 ++++++++++++++++++++
 tools/perf/util/intel-pt.h                         |   51 +
 tools/perf/util/pmu.c                              |    4 -
 28 files changed, 7655 insertions(+), 7 deletions(-)
 create mode 100644 tools/perf/Documentation/intel-bts.txt
 create mode 100644 tools/perf/Documentation/intel-pt.txt
 create mode 100644 tools/perf/arch/x86/util/auxtrace.c
 create mode 100644 tools/perf/arch/x86/util/intel-bts.c
 create mode 100644 tools/perf/arch/x86/util/intel-pt.c
 create mode 100644 tools/perf/arch/x86/util/pmu.c
 create mode 100644 tools/perf/util/intel-bts.c
 create mode 100644 tools/perf/util/intel-bts.h
 create mode 100644 tools/perf/util/intel-pt-decoder/Build
 create mode 100644 tools/perf/util/intel-pt-decoder/intel-pt-decoder.c
 create mode 100644 tools/perf/util/intel-pt-decoder/intel-pt-decoder.h
Quoted 8 lines
 create mode 100644 tools/perf/util/intel-pt-decoder/intel-pt-insn-decoder.c
 create mode 100644 tools/perf/util/intel-pt-decoder/intel-pt-insn-decoder.h
 create mode 100644 tools/perf/util/intel-pt-decoder/intel-pt-log.c
 create mode 100644 tools/perf/util/intel-pt-decoder/intel-pt-log.h
 create mode 100644 tools/perf/util/intel-pt-decoder/intel-pt-pkt-decoder.c
 create mode 100644 tools/perf/util/intel-pt-decoder/intel-pt-pkt-decoder.h
 create mode 100644 tools/perf/util/intel-pt.c
 create mode 100644 tools/perf/util/intel-pt.h

Yeah, so I did a 'newbie test':

I pulled the tree and saw that it has a tools/perf/Documentation/intel-bts.txt file and started reading it.

Based on its text:

The Intel BTS kernel driver creates a new PMU for Intel BTS. The perf record option is:

        -e intel_bts//

Currently Intel BTS is limited to per-thread tracing so the --per-thread option is also needed.

I tried the following command which failed:

triton:~/tip> perf record -e intel_bts// --per-thread sleep 1 invalid or unsupported event: 'intel_bts//'
Run 'perf list' for a list of valid events

usage: perf record [<options>] [<command>]
or: perf record [<options>] -- <command> [<options>]

-e, --event <event> event selector. use 'perf list' to list available events

That's a really ... unhelpful message. If I typoed something I want to know that. If the kernel does not support something, I want to know about that too. Tooling telling me: "maybe you typoed something, maybe it's not supported, I really don't care" is not very productive.

So this was with a distro kernel, and in the hope that I'm missing some magic new kernel feature, I tried it the latest -tip kernel, but it still gives me the same failure.

So the test newbie user got stuck after wasting some time.

Me as a kernel developer could probably figure it out, but that's not the point:
if newbies cannot discover and use our new features then it's as if they didn't exist, and I'm not pulling non-existent features! ;-)

Could we please improve all this?

Thanks,

Ingo

reviewer
#10 lore raw
Quoted 129 lines · Ingo Molnar
Quoted 93 lines · Arnaldo Carvalho de Melo

Hi Ingo,

Please consider pulling, there are several other patches after this,
but I think that this may be acceptable to showcase the capabilities already present, look at the output of 'perf script' and callchains for userspace without using any extra debugging info (no need for DWARF, CFI, nothing), really cool capabilities... :-)

Adrian wrote some docs and I tested it both on a Ivy Bridge machine
where there is only BTS and on a Broadwell machine with the whole shebang, adding the output of the commands to the csets, to further showcase what is there already.

This is on top of my last perf-core-for-mingo tag.

Up to you, please let us know what you think and we'll continue working
on having this in an acceptable form for merging,

Regards,

- Arnaldo

P.S. Kudos for Adrian for the patience with this process, way more is needed to polish this, but the promise is there, cool stuff indeed! :-)

The following changes since commit 36c8bb56a9f718a9a5f35d1834ca9dcec95deb4a:

perf symbols: Check access permission when reading symbol files (2015-06-26 12:11:53 -0300)

are available in the git repository at:

git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux.git tags/perf-pt-for-mingo

for you to fetch changes up to 04759f172270afb28c8004f5cad62ed55710a499:

perf tools: Add Intel BTS support (2015-06-26 18:36:11 -0300)

----------------------------------------------------------------
Put Intel PT and BTS into initial use (Adrian Hunter)

----------------------------------------------------------------
Adrian Hunter (8):
perf auxtrace: Add Intel PT as an AUX area tracing type perf tools: Add Intel PT packet decoder
perf tools: Add Intel PT instruction decoder perf tools: Add Intel PT log
perf tools: Add Intel PT decoder
perf tools: Add Intel PT support
perf tools: Take Intel PT into use
perf tools: Add Intel BTS support

 tools/build/Makefile.build                         |    2 +
 tools/perf/.gitignore                              |    2 +
 tools/perf/Documentation/intel-bts.txt             |   86 +
 tools/perf/Documentation/intel-pt.txt              |  588 ++++++
 tools/perf/MANIFEST                                |    7 +
 tools/perf/Makefile.perf                           |   12 +-
 tools/perf/arch/x86/util/Build                     |    5 +
 tools/perf/arch/x86/util/auxtrace.c                |   83 +
 tools/perf/arch/x86/util/intel-bts.c               |  458 +++++
 tools/perf/arch/x86/util/intel-pt.c                |  752 ++++++++
 tools/perf/arch/x86/util/pmu.c                     |   18 +
 tools/perf/util/Build                              |    3 +
 tools/perf/util/auxtrace.c                         |    9 +-
 tools/perf/util/auxtrace.h                         |    2 +
 tools/perf/util/intel-bts.c                        |  791 ++++++++
 tools/perf/util/intel-bts.h                        |   43 +
 tools/perf/util/intel-pt-decoder/Build             |   14 +
 .../perf/util/intel-pt-decoder/intel-pt-decoder.c  | 1759 ++++++++++++++++++
 .../perf/util/intel-pt-decoder/intel-pt-decoder.h  |  102 ++
 .../util/intel-pt-decoder/intel-pt-insn-decoder.c  |  246 +++
 .../util/intel-pt-decoder/intel-pt-insn-decoder.h  |   65 +
 tools/perf/util/intel-pt-decoder/intel-pt-log.c    |  155 ++
 tools/perf/util/intel-pt-decoder/intel-pt-log.h    |   52 +
 .../util/intel-pt-decoder/intel-pt-pkt-decoder.c   |  400 +++++
 .../util/intel-pt-decoder/intel-pt-pkt-decoder.h   |   64 +
 tools/perf/util/intel-pt.c                         | 1889 ++++++++++++++++++++
 tools/perf/util/intel-pt.h                         |   51 +
 tools/perf/util/pmu.c                              |    4 -
 28 files changed, 7655 insertions(+), 7 deletions(-)
 create mode 100644 tools/perf/Documentation/intel-bts.txt
 create mode 100644 tools/perf/Documentation/intel-pt.txt
 create mode 100644 tools/perf/arch/x86/util/auxtrace.c
 create mode 100644 tools/perf/arch/x86/util/intel-bts.c
 create mode 100644 tools/perf/arch/x86/util/intel-pt.c
 create mode 100644 tools/perf/arch/x86/util/pmu.c
 create mode 100644 tools/perf/util/intel-bts.c
 create mode 100644 tools/perf/util/intel-bts.h
 create mode 100644 tools/perf/util/intel-pt-decoder/Build
 create mode 100644 tools/perf/util/intel-pt-decoder/intel-pt-decoder.c
 create mode 100644 tools/perf/util/intel-pt-decoder/intel-pt-decoder.h
Quoted 8 lines
 create mode 100644 tools/perf/util/intel-pt-decoder/intel-pt-insn-decoder.c
 create mode 100644 tools/perf/util/intel-pt-decoder/intel-pt-insn-decoder.h
 create mode 100644 tools/perf/util/intel-pt-decoder/intel-pt-log.c
 create mode 100644 tools/perf/util/intel-pt-decoder/intel-pt-log.h
 create mode 100644 tools/perf/util/intel-pt-decoder/intel-pt-pkt-decoder.c
 create mode 100644 tools/perf/util/intel-pt-decoder/intel-pt-pkt-decoder.h
 create mode 100644 tools/perf/util/intel-pt.c
 create mode 100644 tools/perf/util/intel-pt.h

Yeah, so I did a 'newbie test':

I pulled the tree and saw that it has a tools/perf/Documentation/intel-bts.txt file and started reading it.

Based on its text:

The Intel BTS kernel driver creates a new PMU for Intel BTS. The perf record option is:

        -e intel_bts//

Currently Intel BTS is limited to per-thread tracing so the --per-thread option is also needed.

I tried the following command which failed:

triton:~/tip> perf record -e intel_bts// --per-thread sleep 1 invalid or unsupported event: 'intel_bts//'
Run 'perf list' for a list of valid events

usage: perf record [<options>] [<command>]
or: perf record [<options>] -- <command> [<options>]

Quoted 6 lines

-e, --event <event> event selector. use 'perf list' to list available events

That's a really ... unhelpful message. If I typoed something I want to know that. If the kernel does not support something, I want to know about that too. Tooling telling me: "maybe you typoed something, maybe it's not supported, I really don't care" is not very productive.

That is not entirely true. The message says "Run 'perf list' for a list of valid events" which will tell you if the event is valid. So you can tell the difference between a typo and unsupported event.

Quoted 5 lines

So this was with a distro kernel, and in the hope that I'm missing some magic new kernel feature, I tried it the latest -tip kernel, but it still gives me the same failure.

Quoted 7 lines

So the test newbie user got stuck after wasting some time.

Me as a kernel developer could probably figure it out, but that's not the point:
if newbies cannot discover and use our new features then it's as if they didn't exist, and I'm not pulling non-existent features! ;-)

Could we please improve all this?

'perf list' shows the event wasn't supported, so I am not sure what more the "newbie" could expect. Do you have any suggestions?

#11 lore raw
Quoted 26 lines · Adrian Hunter
Quoted 26 lines

Yeah, so I did a 'newbie test':

I pulled the tree and saw that it has a tools/perf/Documentation/intel-bts.txt file and started reading it.

Based on its text:

The Intel BTS kernel driver creates a new PMU for Intel BTS. The perf record option is:

        -e intel_bts//

Currently Intel BTS is limited to per-thread tracing so the --per-thread option is also needed.

I tried the following command which failed:

triton:~/tip> perf record -e intel_bts// --per-thread sleep 1 invalid or unsupported event: 'intel_bts//'
Run 'perf list' for a list of valid events

usage: perf record [<options>] [<command>]
or: perf record [<options>] -- <command> [<options>]

-e, --event <event> event selector. use 'perf list' to list available events

Quoted 8 lines
Quoted 4 lines

That's a really ... unhelpful message. If I typoed something I want to know that. If the kernel does not support something, I want to know about that too. Tooling telling me: "maybe you typoed something, maybe it's not supported, I really don't care" is not very productive.

That is not entirely true. The message says "Run 'perf list' for a list of valid events" which will tell you if the event is valid. So you can tell the difference between a typo and unsupported event.

Yeah, but my point is: why doesn't the tool do this disambiguation for me? Tools are hard enough to use as-is already, no need to put artificial roadblocks in the path of first time users.

Quoted 6 lines
Quoted 6 lines

So this was with a distro kernel, and in the hope that I'm missing some magic new kernel feature, I tried it the latest -tip kernel, but it still gives me the same failure.

So the test newbie user got stuck after wasting some time.

Quoted 8 lines
Quoted 5 lines

Me as a kernel developer could probably figure it out, but that's not the
point: if newbies cannot discover and use our new features then it's as if they didn't exist, and I'm not pulling non-existent features! ;-)

Could we please improve all this?

'perf list' shows the event wasn't supported, so I am not sure what more the "newbie" could expect. Do you have any suggestions?

So I think a first time user would expect a clear message from the computer: what was wrong with what he wrote and what should he do to fix it.

Btw., here's the 'perf list' output from a system running the latest -tip kernel:

vega:~> uname -a
Linux vega 4.1.0-02935-g390ad45394a3-dirty #567 SMP PREEMPT Mon Jun 29 11:44:48 CEST 2015 x86_64 x86_64 x86_64 GNU/Linux vega:~> perf list | grep -i bts
vega:~>

so is there any kernel feature dependency? It's unclear. If yes, it should be mentioned in the document, and in the tooling output as well. If not then we have a bug somewhere.

I.e. you need to smooth the first time user's rocky path to first use as much as technically possible. Every single such helping step will literally double the number of users who will be able to successfully make use of the new feature.

As a positive example take a look at the newbie's road to 'perf trace':

vega:~> trace
Error: No permissions to read /sys/kernel/debug/tracing/events/raw_syscalls/sys_(enter|exit)
Hint: Try 'sudo mount -o remount,mode=755 /sys/kernel/debug'

Aha, useful message, I need to run this as root:

  # trace

0.000 ( 0.000 ms): sleep/28926 ... [continued]: nanosleep()) = 0
0.051 ( 0.007 ms): sleep/28926 close(fd: 1 ) = 0
0.063 ( 0.005 ms): sleep/28926 close(fd: 2 ) = 0
0.072 ( 0.000 ms): sleep/28926 exit_group(

Ok?

Thanks,

Ingo

reviewer
#12 lore raw
Quoted 34 lines · Ingo Molnar
Quoted 31 lines · Adrian Hunter
Quoted 30 lines

Yeah, so I did a 'newbie test':

I pulled the tree and saw that it has a tools/perf/Documentation/intel-bts.txt file and started reading it.

Based on its text:

The Intel BTS kernel driver creates a new PMU for Intel BTS. The perf record option is:

        -e intel_bts//

Currently Intel BTS is limited to per-thread tracing so the --per-thread option is also needed.

I tried the following command which failed:

triton:~/tip> perf record -e intel_bts// --per-thread sleep 1 invalid or unsupported event: 'intel_bts//'
Run 'perf list' for a list of valid events

usage: perf record [<options>] [<command>]
or: perf record [<options>] -- <command> [<options>]

-e, --event <event> event selector. use 'perf list' to list available events

That's a really ... unhelpful message. If I typoed something I want to know that. If the kernel does not support something, I want to know about that too. Tooling telling me: "maybe you typoed something, maybe it's not supported, I really don't care" is not very productive.

Quoted 7 lines
Quoted 3 lines

That is not entirely true. The message says "Run 'perf list' for a list of valid events" which will tell you if the event is valid. So you can tell the difference between a typo and unsupported event.

Yeah, but my point is: why doesn't the tool do this disambiguation for me? Tools are hard enough to use as-is already, no need to put artificial roadblocks in the path of first time users.

That applies to all events e.g.

# perf record -e sched:sched_swotch sleep 1
invalid or unsupported event: 'sched:sched_swotch'                                                                                       
Run 'perf list' for a list of valid events                                                                                               

usage: perf record [<options>] [<command>]
or: perf record [<options>] -- <command> [<options>]

-e, --event <event> event selector. use 'perf list' to list available events

So it is a general problem.

Quoted 21 lines
Quoted 7 lines
Quoted 7 lines

So this was with a distro kernel, and in the hope that I'm missing some magic new kernel feature, I tried it the latest -tip kernel, but it still gives me the same failure.

So the test newbie user got stuck after wasting some time.

Quoted 8 lines
Quoted 5 lines

Me as a kernel developer could probably figure it out, but that's not the
point: if newbies cannot discover and use our new features then it's as if they didn't exist, and I'm not pulling non-existent features! ;-)

Could we please improve all this?

'perf list' shows the event wasn't supported, so I am not sure what more the "newbie" could expect. Do you have any suggestions?

So I think a first time user would expect a clear message from the computer: what was wrong with what he wrote and what should he do to fix it.

Btw., here's the 'perf list' output from a system running the latest -tip kernel:

Quoted 8 lines

vega:~> uname -a
Linux vega 4.1.0-02935-g390ad45394a3-dirty #567 SMP PREEMPT Mon Jun 29 11:44:48 CEST 2015 x86_64 x86_64 x86_64 GNU/Linux vega:~> perf list | grep -i bts
vega:~>

so is there any kernel feature dependency? It's unclear. If yes, it should be mentioned in the document, and in the tooling output as well. If not then we have a bug somewhere.

I am not aware of any dependencies, apart from perf events itself.

Are you sure you compiled perf tools with the new patches ;-) And it is an Intel CPU?

Quoted 13 lines

I.e. you need to smooth the first time user's rocky path to first use as much as technically possible. Every single such helping step will literally double the number of users who will be able to successfully make use of the new feature.

As a positive example take a look at the newbie's road to 'perf trace':

vega:~> trace
Error: No permissions to read /sys/kernel/debug/tracing/events/raw_syscalls/sys_(enter|exit)
Hint: Try 'sudo mount -o remount,mode=755 /sys/kernel/debug'

Aha, useful message, I need to run this as root:

Quoted 8 lines
  # trace

0.000 ( 0.000 ms): sleep/28926 ... [continued]: nanosleep()) = 0
0.051 ( 0.007 ms): sleep/28926 close(fd: 1 ) = 0
0.063 ( 0.005 ms): sleep/28926 close(fd: 2 ) = 0
0.072 ( 0.000 ms): sleep/28926 exit_group(

Ok?

Could do something like the following:

tools/perf/util/parse-events.c +6 -1
index 09f8d2357108..5ab8fee89361 100644
@@ -666,8 +666,13 @@ int parse_events_add_pmu(struct parse_events_evlist *data,
 	struct perf_evsel *evsel;
 
 	pmu = perf_pmu__find(name);
-	if (!pmu)
+	if (!pmu) {
+		if ((!strcmp(name, "intel_bts") || !strcmp(name, "intel_pt")) &&
+		    data->error)
+			if (asprintf(&data->error->str, "%s is not supported by the running kernel", name) < 0)
+				return -ENOMEM;
 		return -EINVAL;
+	}
 
 	if (pmu->default_config) {
 		memcpy(&attr, pmu->default_config,

Could then add checks for Intel hardware and bts CPU feature flag.

author maintainer
#13 lore raw

Em Tue, Jun 30, 2015 at 04:23:45PM +0300, Adrian Hunter escreveu:

Quoted 49 lines · Ingo Molnar
Quoted 34 lines · Adrian Hunter
Quoted 32 lines
Quoted 31 lines

Yeah, so I did a 'newbie test':

I pulled the tree and saw that it has a tools/perf/Documentation/intel-bts.txt file and started reading it.

Based on its text:

The Intel BTS kernel driver creates a new PMU for Intel BTS. The perf record option is:

        -e intel_bts//

Currently Intel BTS is limited to per-thread tracing so the --per-thread option is also needed.

I tried the following command which failed:

triton:~/tip> perf record -e intel_bts// --per-thread sleep 1 invalid or unsupported event: 'intel_bts//'
Run 'perf list' for a list of valid events

usage: perf record [<options>] [<command>]
or: perf record [<options>] -- <command> [<options>]

-e, --event <event> event selector. use 'perf list' to list available events

That's a really ... unhelpful message. If I typoed something I want to know that. If the kernel does not support something, I want to know about that too. Tooling telling me: "maybe you typoed something, maybe it's not supported, I really don't care" is not very productive.

Quoted 7 lines
Quoted 3 lines

That is not entirely true. The message says "Run 'perf list' for a list of valid events" which will tell you if the event is valid. So you can tell the difference between a typo and unsupported event.

Yeah, but my point is: why doesn't the tool do this disambiguation for me? Tools are hard enough to use as-is already, no need to put artificial roadblocks in the path of first time users.

That applies to all events e.g.

# perf record -e sched:sched_swotch sleep 1
invalid or unsupported event: 'sched:sched_swotch'                                                                                       
Run 'perf list' for a list of valid events                                                                                               
Quoted 6 lines

usage: perf record [<options>] [<command>]
or: perf record [<options>] -- <command> [<options>]

-e, --event <event> event selector. use 'perf list' to list available events

So it is a general problem.

Right, guess it is interesting to note at this point that Jiri improved this area:

[acme@zoo linux]$ perf record -e sched:sched_swotch sleep 1 event syntax error: 'sched:sched_swotch'
\___ unknown tracepoint
Run 'perf list' for a list of valid events

usage: perf record [<options>] [<command>]
or: perf record [<options>] -- <command> [<options>]

-e, --event <event> event selector. use 'perf list' to list available events
[acme@zoo linux]$

But:

[acme@zoo linux]$ perf record -e intel_pt// usleep 1 invalid or unsupported event: 'intel_pt//' Run 'perf list' for a list of valid events

usage: perf record [<options>] [<command>]
or: perf record [<options>] -- <command> [<options>]

-e, --event <event> event selector. use 'perf list' to list available events
[acme@zoo linux]$

I'll investigate how this can be improved...

- Arnaldo

reviewer
#14 lore raw
In reply to Adrian Hunter
Quoted 135 lines · Adrian Hunter
Quoted 34 lines · Ingo Molnar
Quoted 31 lines · Adrian Hunter
Quoted 30 lines

Yeah, so I did a 'newbie test':

I pulled the tree and saw that it has a tools/perf/Documentation/intel-bts.txt file and started reading it.

Based on its text:

The Intel BTS kernel driver creates a new PMU for Intel BTS. The perf record option is:

        -e intel_bts//

Currently Intel BTS is limited to per-thread tracing so the --per-thread option is also needed.

I tried the following command which failed:

triton:~/tip> perf record -e intel_bts// --per-thread sleep 1 invalid or unsupported event: 'intel_bts//'
Run 'perf list' for a list of valid events

usage: perf record [<options>] [<command>]
or: perf record [<options>] -- <command> [<options>]

-e, --event <event> event selector. use 'perf list' to list available events

That's a really ... unhelpful message. If I typoed something I want to know that. If the kernel does not support something, I want to know about that too. Tooling telling me: "maybe you typoed something, maybe it's not supported, I really don't care" is not very productive.

Quoted 7 lines
Quoted 3 lines

That is not entirely true. The message says "Run 'perf list' for a list of valid events" which will tell you if the event is valid. So you can tell the difference between a typo and unsupported event.

Yeah, but my point is: why doesn't the tool do this disambiguation for me? Tools are hard enough to use as-is already, no need to put artificial roadblocks in the path of first time users.

That applies to all events e.g.

# perf record -e sched:sched_swotch sleep 1
invalid or unsupported event: 'sched:sched_swotch'                                                                                       
Run 'perf list' for a list of valid events                                                                                               

usage: perf record [<options>] [<command>]
or: perf record [<options>] -- <command> [<options>]

-e, --event <event> event selector. use 'perf list' to list available events

So it is a general problem.

Quoted 21 lines
Quoted 7 lines
Quoted 7 lines

So this was with a distro kernel, and in the hope that I'm missing some magic new kernel feature, I tried it the latest -tip kernel, but it still gives me the same failure.

So the test newbie user got stuck after wasting some time.

Quoted 8 lines
Quoted 5 lines

Me as a kernel developer could probably figure it out, but that's not the
point: if newbies cannot discover and use our new features then it's as if they didn't exist, and I'm not pulling non-existent features! ;-)

Could we please improve all this?

'perf list' shows the event wasn't supported, so I am not sure what more the "newbie" could expect. Do you have any suggestions?

So I think a first time user would expect a clear message from the computer: what was wrong with what he wrote and what should he do to fix it.

Btw., here's the 'perf list' output from a system running the latest -tip kernel:

Quoted 8 lines

vega:~> uname -a
Linux vega 4.1.0-02935-g390ad45394a3-dirty #567 SMP PREEMPT Mon Jun 29 11:44:48 CEST 2015 x86_64 x86_64 x86_64 GNU/Linux vega:~> perf list | grep -i bts
vega:~>

so is there any kernel feature dependency? It's unclear. If yes, it should be mentioned in the document, and in the tooling output as well. If not then we have a bug somewhere.

I am not aware of any dependencies, apart from perf events itself.

Are you sure you compiled perf tools with the new patches ;-) And it is an Intel CPU?

Quoted 13 lines

I.e. you need to smooth the first time user's rocky path to first use as much as technically possible. Every single such helping step will literally double the number of users who will be able to successfully make use of the new feature.

As a positive example take a look at the newbie's road to 'perf trace':

vega:~> trace
Error: No permissions to read /sys/kernel/debug/tracing/events/raw_syscalls/sys_(enter|exit)
Hint: Try 'sudo mount -o remount,mode=755 /sys/kernel/debug'

Aha, useful message, I need to run this as root:

Quoted 8 lines
  # trace

0.000 ( 0.000 ms): sleep/28926 ... [continued]: nanosleep()) = 0
0.051 ( 0.007 ms): sleep/28926 close(fd: 1 ) = 0
0.063 ( 0.005 ms): sleep/28926 close(fd: 2 ) = 0
0.072 ( 0.000 ms): sleep/28926 exit_group(

Ok?

Could do something like the following:

tools/perf/util/parse-events.c +6 -1
index 09f8d2357108..5ab8fee89361 100644
@@ -666,8 +666,13 @@ int parse_events_add_pmu(struct parse_events_evlist *data,
 	struct perf_evsel *evsel;
 
 	pmu = perf_pmu__find(name);
-	if (!pmu)
+	if (!pmu) {
+		if ((!strcmp(name, "intel_bts") || !strcmp(name, "intel_pt")) &&
+		    data->error)
+			if (asprintf(&data->error->str, "%s is not supported by the running kernel", name) < 0)
+				return -ENOMEM;
 		return -EINVAL;
+	}
 
 	if (pmu->default_config) {
 		memcpy(&attr, pmu->default_config,
Quoted 1 line

Could then add checks for Intel hardware and bts CPU feature flag.

How is this?

From: Adrian Hunter <[email protected]>
Date: Wed, 1 Jul 2015 11:14:50 +0300
Subject: [PATCH] perf tools: Add error messages for missing intel_bts and
intel_pt support

Add error messages to assist users in determining why there is no intel_bts or intel_pt support.

---
 tools/perf/arch/x86/util/header.c | 15 ++++++++++++++
 tools/perf/util/header.h          |  3 ++-
 tools/perf/util/parse-events.c    | 41 ++++++++++++++++++++++++++++++++++++++-
 3 files changed, 57 insertions(+), 2 deletions(-)
tools/perf/arch/x86/util/header.c +15 -0
index 146d12a1cec0..afc5bdfd2d15 100644
@@ -57,3 +57,18 @@ get_cpuid(char *buffer, size_t sz)
 	}
 	return -1;
 }
+
+int have_intel_cpu(void)
+{
+	char buffer[64];
+	int ret;
+
+	ret = get_cpuid(buffer, sizeof(buffer));
+	if (ret)
+		return -1;
+
+	if (!strncmp(buffer, "GenuineIntel,", 13))
+		return 1;
+
+	return 0;
+}
tools/perf/util/header.h +2 -1
index d4d57962c591..f6eab49d13d1 100644
@@ -153,8 +153,9 @@ bool is_perf_magic(u64 magic);
 int write_padded(int fd, const void *bf, size_t count, size_t count_aligned);
 
 /*
- * arch specific callback
+ * arch specific callbacks
  */
 int get_cpuid(char *buffer, size_t sz);
+int have_intel_cpu(void);
 
 #endif /* __PERF_HEADER_H */
tools/perf/util/parse-events.c +40 -1

53 lines not on this page · raw message

Signature · 1 line
1.9.1
reviewer
#15 lore raw
Quoted 87 lines · Adrian Hunter
Quoted 86 lines · Adrian Hunter
Quoted 34 lines · Ingo Molnar
Quoted 31 lines · Adrian Hunter
Quoted 30 lines

Yeah, so I did a 'newbie test':

I pulled the tree and saw that it has a tools/perf/Documentation/intel-bts.txt file and started reading it.

Based on its text:

The Intel BTS kernel driver creates a new PMU for Intel BTS. The perf record option is:

        -e intel_bts//

Currently Intel BTS is limited to per-thread tracing so the --per-thread option is also needed.

I tried the following command which failed:

triton:~/tip> perf record -e intel_bts// --per-thread sleep 1 invalid or unsupported event: 'intel_bts//'
Run 'perf list' for a list of valid events

usage: perf record [<options>] [<command>]
or: perf record [<options>] -- <command> [<options>]

-e, --event <event> event selector. use 'perf list' to list available events

That's a really ... unhelpful message. If I typoed something I want to know that. If the kernel does not support something, I want to know about that too. Tooling telling me: "maybe you typoed something, maybe it's not supported, I really don't care" is not very productive.

Quoted 7 lines
Quoted 3 lines

That is not entirely true. The message says "Run 'perf list' for a list of valid events" which will tell you if the event is valid. So you can tell the difference between a typo and unsupported event.

Yeah, but my point is: why doesn't the tool do this disambiguation for me? Tools are hard enough to use as-is already, no need to put artificial roadblocks in the path of first time users.

That applies to all events e.g.

# perf record -e sched:sched_swotch sleep 1
invalid or unsupported event: 'sched:sched_swotch'                                                                                       
Run 'perf list' for a list of valid events                                                                                               

usage: perf record [<options>] [<command>]
or: perf record [<options>] -- <command> [<options>]

-e, --event <event> event selector. use 'perf list' to list available events

So it is a general problem.

Quoted 29 lines
Quoted 7 lines
Quoted 7 lines

So this was with a distro kernel, and in the hope that I'm missing some magic new kernel feature, I tried it the latest -tip kernel, but it still gives me the same failure.

So the test newbie user got stuck after wasting some time.

Quoted 8 lines
Quoted 5 lines

Me as a kernel developer could probably figure it out, but that's not the
point: if newbies cannot discover and use our new features then it's as if they didn't exist, and I'm not pulling non-existent features! ;-)

Could we please improve all this?

'perf list' shows the event wasn't supported, so I am not sure what more the "newbie" could expect. Do you have any suggestions?

So I think a first time user would expect a clear message from the computer: what was wrong with what he wrote and what should he do to fix it.

Btw., here's the 'perf list' output from a system running the latest -tip kernel:

vega:~> uname -a
Linux vega 4.1.0-02935-g390ad45394a3-dirty #567 SMP PREEMPT Mon Jun 29 11:44:48 CEST 2015 x86_64 x86_64 x86_64 GNU/Linux vega:~> perf list | grep -i bts
vega:~>

so is there any kernel feature dependency? It's unclear. If yes, it should be mentioned in the document, and in the tooling output as well. If not then we have a bug somewhere.

Quoted 5 lines
Quoted 5 lines

I am not aware of any dependencies, apart from perf events itself.

Are you sure you compiled perf tools with the new patches ;-) And it is an Intel CPU?

I am going to need to know what hardware it is and cpu feature flags i.e. /proc/cpuinfo

Also ls /sys/bus/event_source/devices

#16 lore raw
Quoted 4 lines · Adrian Hunter

I am going to need to know what hardware it is and cpu feature flags i.e. /proc/cpuinfo

Also ls /sys/bus/event_source/devices

Sorry about the delay, the merge window is busier than usual ...

So I tried it on:

1) Intel box, old kernel, new tools: threw an error
2) AMD box, new kernel, new tools: threw an error
3) AMD box, old kernel, new tools: threw an error

failure was expected in all 3 cases, but it threw the exact same error with no real indication about what the problem was, while the real problem was different for each case:

1) good CPU, bad kernel
2) bad CPU, good kernel
3) bad CPU, bad kernel

I'd expect the 'good CPU, good kernel' combination to work:

4) Intel box, new kernel, new tools

... but haven't tried it yet.

Thanks,

Ingo

#17 lore raw
In reply to Adrian Hunter
Quoted 106 lines · Adrian Hunter

How is this?

From: Adrian Hunter <[email protected]>
Date: Wed, 1 Jul 2015 11:14:50 +0300
Subject: [PATCH] perf tools: Add error messages for missing intel_bts and
intel_pt support

Add error messages to assist users in determining why there is no intel_bts or intel_pt support.

---
 tools/perf/arch/x86/util/header.c | 15 ++++++++++++++
 tools/perf/util/header.h          |  3 ++-
 tools/perf/util/parse-events.c    | 41 ++++++++++++++++++++++++++++++++++++++-
 3 files changed, 57 insertions(+), 2 deletions(-)
tools/perf/arch/x86/util/header.c +15 -0
index 146d12a1cec0..afc5bdfd2d15 100644
@@ -57,3 +57,18 @@ get_cpuid(char *buffer, size_t sz)
 	}
 	return -1;
 }
+
+int have_intel_cpu(void)
+{
+	char buffer[64];
+	int ret;
+
+	ret = get_cpuid(buffer, sizeof(buffer));
+	if (ret)
+		return -1;
+
+	if (!strncmp(buffer, "GenuineIntel,", 13))
+		return 1;
+
+	return 0;
+}
tools/perf/util/header.h +2 -1
index d4d57962c591..f6eab49d13d1 100644
@@ -153,8 +153,9 @@ bool is_perf_magic(u64 magic);
 int write_padded(int fd, const void *bf, size_t count, size_t count_aligned);
 
 /*
- * arch specific callback
+ * arch specific callbacks
  */
 int get_cpuid(char *buffer, size_t sz);
+int have_intel_cpu(void);
 
 #endif /* __PERF_HEADER_H */
tools/perf/util/parse-events.c +39 -0
index 09f8d2357108..23fb777b40fa 100644
@@ -656,6 +656,45 @@ static char *pmu_event_name(struct list_head *head_terms)
 	return NULL;
 }
 
+int __weak have_intel_cpu(void)
+{
+	return 0;
+}
+
+static int pmu_not_found_error(char *name, struct parse_events_error *err)
+{
+	int ret;
+
+	if (!err)
+		goto out;
+
+	if (!strcmp(name, "intel_bts")) {
+		ret = have_intel_cpu();
+		if (ret < 0)
+			goto out;
+		if (!ret) {
+			err->str = strdup("intel_bts requires an Intel CPU");
+			goto out;
+		}
+		err->str = strdup("kernel does not support intel_bts (requires 64-bit v4.1 kernel or later and BTS hardware support)");
+		goto out;
+	}
+
+	if (!strcmp(name, "intel_pt")) {
+		ret = have_intel_cpu();
+		if (ret < 0)
+			goto out;
+		if (!ret) {
+			err->str = strdup("intel_pt requires an Intel CPU (Core 5th generation or later)");
+			goto out;
+		}
+		err->str = strdup("kernel does not support intel_pt (requires v4.1 kernel or later and 5th generation Intel Core processor or later)");
+		goto out;
+	}
+out:
+	return -EINVAL;
+}
+
 int parse_events_add_pmu(struct parse_events_evlist *data,
 			 struct list_head *list, char *name,
 			 struct list_head *head_config)

tools/perf/util/parse-events.c int parse_events_add_pmu(struct parse_events_evlist *data, · line 712

Quoted 8 lines
tools/perf/util/parse-events.c +1 -1
@@ -667,7 +706,7 @@ int parse_events_add_pmu(struct parse_events_evlist *data,
 
 	pmu = perf_pmu__find(name);
 	if (!pmu)
-		return -EINVAL;
+		return pmu_not_found_error(name, data->error);
 
 	if (pmu->default_config) {
 		memcpy(&attr, pmu->default_config,

So I really think we need an extended error reporting feature on the perf kernel side, so that a 'natural' error (plus a string) is reported back to tooling, instead of the current -EINVAL.

No need to do it for everything, doing it for BTS and related functionality would be a good first step to start this.

If you are interested you could try this, or I can try to write something (after the merge window).

So the idea would be to convert such opaque error returns:

        if (attr->config == PERF_COUNT_HW_BRANCH_INSTRUCTIONS &&
            !attr->freq && hwc->sample_period == 1) {
                /* BTS is not supported by this architecture. */
                if (!x86_pmu.bts_active)
                        return -EOPNOTSUPP;

into:

			return perf_err(event, -EOPNOTSUPP, "The BTS hardware feature is not available on this CPU.");

Where perf_err() is a function that on one hand returns -EOPNOTSUPP - so 'legacy' error handling works as before: the syscall will return -EOPNOTSUPP.

But if a new 'extended error reporting' feature bit is set in the perf_attr, then perf_err() also does the following:

- it copies the error string either back to a user-space pointer which is in the perf_attr (plus a max length field)

- or an alternative implementation would be to puts the string into the event's ring buffer, with a special (new) event marker - where it can be recovered by tooling.

(I think the first approach is better, because it would work fine for events without ring-buffers as well.)

Old tooling won't have the feature flag set and won't have the string pointer in perf_attr, so nothing will happen on that case.

New tooling that supports 'extended error reporting' has the feature flag set and the kernel will copy the error string into the provided user-space string buffer, where tooling could use that string to generate more meaningful error messages:

perf syscall error: The BTS hardware feature is not available on this CPU.

Does this make sense to you?

Now an additional complication is the fact that BTS can now also be a separate PMU, listed under /sys/bus/event_source/devices/intel_bts/.

If it's not listed there, we don't know the exact reason: is it not available because it's an old kernel? Or is it the wrong CPU?

We could solve that by extending the sysfs interface and adding an "error" file to the PMU directory: which would contain the reason why the driver was not created.

I.e. if the BTS driver was not created, we'd still have /sys/bus/event_source/devices/intel_bts/error (and no other file), which gives tooling a good way to discover why a particular PMU is not available. This adds a tiny bit more RAM overhead, but it's for the better I think, because tooling could be a lot more certain about what the capabilities of the kernel are.

Thanks,

Ingo

reviewer
#18 lore raw
Quoted 122 lines · Ingo Molnar
Quoted 106 lines · Adrian Hunter

How is this?

From: Adrian Hunter <[email protected]>
Date: Wed, 1 Jul 2015 11:14:50 +0300
Subject: [PATCH] perf tools: Add error messages for missing intel_bts and
intel_pt support

Add error messages to assist users in determining why there is no intel_bts or intel_pt support.

---
 tools/perf/arch/x86/util/header.c | 15 ++++++++++++++
 tools/perf/util/header.h          |  3 ++-
 tools/perf/util/parse-events.c    | 41 ++++++++++++++++++++++++++++++++++++++-
 3 files changed, 57 insertions(+), 2 deletions(-)
tools/perf/arch/x86/util/header.c +15 -0
index 146d12a1cec0..afc5bdfd2d15 100644
@@ -57,3 +57,18 @@ get_cpuid(char *buffer, size_t sz)
 	}
 	return -1;
 }
+
+int have_intel_cpu(void)
+{
+	char buffer[64];
+	int ret;
+
+	ret = get_cpuid(buffer, sizeof(buffer));
+	if (ret)
+		return -1;
+
+	if (!strncmp(buffer, "GenuineIntel,", 13))
+		return 1;
+
+	return 0;
+}
tools/perf/util/header.h +2 -1
index d4d57962c591..f6eab49d13d1 100644
@@ -153,8 +153,9 @@ bool is_perf_magic(u64 magic);
 int write_padded(int fd, const void *bf, size_t count, size_t count_aligned);
 
 /*
- * arch specific callback
+ * arch specific callbacks
  */
 int get_cpuid(char *buffer, size_t sz);
+int have_intel_cpu(void);
 
 #endif /* __PERF_HEADER_H */
tools/perf/util/parse-events.c +39 -0
index 09f8d2357108..23fb777b40fa 100644
@@ -656,6 +656,45 @@ static char *pmu_event_name(struct list_head *head_terms)
 	return NULL;
 }
 
+int __weak have_intel_cpu(void)
+{
+	return 0;
+}
+
+static int pmu_not_found_error(char *name, struct parse_events_error *err)
+{
+	int ret;
+
+	if (!err)
+		goto out;
+
+	if (!strcmp(name, "intel_bts")) {
+		ret = have_intel_cpu();
+		if (ret < 0)
+			goto out;
+		if (!ret) {
+			err->str = strdup("intel_bts requires an Intel CPU");
+			goto out;
+		}
+		err->str = strdup("kernel does not support intel_bts (requires 64-bit v4.1 kernel or later and BTS hardware support)");
+		goto out;
+	}
+
+	if (!strcmp(name, "intel_pt")) {
+		ret = have_intel_cpu();
+		if (ret < 0)
+			goto out;
+		if (!ret) {
+			err->str = strdup("intel_pt requires an Intel CPU (Core 5th generation or later)");
+			goto out;
+		}
+		err->str = strdup("kernel does not support intel_pt (requires v4.1 kernel or later and 5th generation Intel Core processor or later)");
+		goto out;
+	}
+out:
+	return -EINVAL;
+}
+
 int parse_events_add_pmu(struct parse_events_evlist *data,
 			 struct list_head *list, char *name,
 			 struct list_head *head_config)

tools/perf/util/parse-events.c int parse_events_add_pmu(struct parse_events_evlist *data, · line 712

Quoted 8 lines
tools/perf/util/parse-events.c +1 -1
@@ -667,7 +706,7 @@ int parse_events_add_pmu(struct parse_events_evlist *data,
 
 	pmu = perf_pmu__find(name);
 	if (!pmu)
-		return -EINVAL;
+		return pmu_not_found_error(name, data->error);
 
 	if (pmu->default_config) {
 		memcpy(&attr, pmu->default_config,

So I really think we need an extended error reporting feature on the perf kernel side, so that a 'natural' error (plus a string) is reported back to tooling, instead of the current -EINVAL.

Quoted 5 lines

No need to do it for everything, doing it for BTS and related functionality would be a good first step to start this.

If you are interested you could try this, or I can try to write something (after the merge window).

Don't have time sorry.

Quoted 32 lines

So the idea would be to convert such opaque error returns:

        if (attr->config == PERF_COUNT_HW_BRANCH_INSTRUCTIONS &&
            !attr->freq && hwc->sample_period == 1) {
                /* BTS is not supported by this architecture. */
                if (!x86_pmu.bts_active)
                        return -EOPNOTSUPP;

into:

			return perf_err(event, -EOPNOTSUPP, "The BTS hardware feature is not available on this CPU.");

Where perf_err() is a function that on one hand returns -EOPNOTSUPP - so 'legacy' error handling works as before: the syscall will return -EOPNOTSUPP.

But if a new 'extended error reporting' feature bit is set in the perf_attr, then perf_err() also does the following:

- it copies the error string either back to a user-space pointer which is in the perf_attr (plus a max length field)

- or an alternative implementation would be to puts the string into the event's ring buffer, with a special (new) event marker - where it can be recovered by tooling.

(I think the first approach is better, because it would work fine for events without ring-buffers as well.)

Old tooling won't have the feature flag set and won't have the string pointer in perf_attr, so nothing will happen on that case.

Quoted 7 lines

New tooling that supports 'extended error reporting' has the feature flag set and the kernel will copy the error string into the provided user-space string buffer, where tooling could use that string to generate more meaningful error messages:

perf syscall error: The BTS hardware feature is not available on this CPU.

Does this make sense to you?

Normally the warts of syscalls are hidden by libraries. I am not sure a library couldn't do just as well with the advantage that it would work for old kernels too. A library could also have information about multiple architectures, not just the one that is actually running e.g. your BTS example won't work on ARM.

A library could provide a similar API to the one you described. Either it just does the syscall and returns, or if extended error information is requested, it probes the API with various options, checks perf_event_paranoid, and generally uses whatever information it can to best figure out what went wrong.

Quoted 7 lines

Now an additional complication is the fact that BTS can now also be a separate PMU, listed under /sys/bus/event_source/devices/intel_bts/.

If it's not listed there, we don't know the exact reason: is it not available because it's an old kernel? Or is it the wrong CPU?

Quoted 8 lines

We could solve that by extending the sysfs interface and adding an "error" file to the PMU directory: which would contain the reason why the driver was not created.

I.e. if the BTS driver was not created, we'd still have /sys/bus/event_source/devices/intel_bts/error (and no other file), which gives tooling a good way to discover why a particular PMU is not available. This adds a tiny bit more RAM overhead, but it's for the better I think, because tooling could be a lot more certain about what the capabilities of the kernel are.

That presumes the user understands what is or is not available on their architecture, because on a non-x86 architecture they still get nothing x86-specific.

It also runs a bit against the way config works e.g. even if the PMU driver is config'ed out it still has to provide a sysfs interface.

So, isn't the patch I proposed sufficient for now?

author maintainer
#19 lore raw

Em Thu, Jul 02, 2015 at 03:35:17PM +0300, Adrian Hunter escreveu:

Quoted 18 lines · Ingo Molnar
Quoted 10 lines

Old tooling won't have the feature flag set and won't have the string pointer in perf_attr, so nothing will happen on that case.

New tooling that supports 'extended error reporting' has the feature flag set and the kernel will copy the error string into the provided user-space string buffer, where tooling could use that string to generate more meaningful error messages:

perf syscall error: The BTS hardware feature is not available on this CPU.

Does this make sense to you?

Normally the warts of syscalls are hidden by libraries. I am not sure a library couldn't do just as well with the advantage that it would work for old kernels too. A library could also have information about multiple architectures, not just the one that is actually running e.g. your BTS example won't work on ARM.

Quoted 5 lines

A library could provide a similar API to the one you described. Either it just does the syscall and returns, or if extended error information is requested, it probes the API with various options, checks perf_event_paranoid, and generally uses whatever information it can to best figure out what went wrong.

Agreed, that is what tools/perf/util/evsel.c does, e.g.:

static struct {
        bool sample_id_all;
        bool exclude_guest;
        bool mmap2;
        bool cloexec;
        bool clockid;
        bool clockid_wrong;
} perf_missing_features;

And in __perf_evsel__open():

        /*
         * Must probe features in the order they were added to the
         * perf_event_attr interface.
         */
        if (!perf_missing_features.clockid_wrong && evsel->attr.use_clockid) {
                perf_missing_features.clockid_wrong = true;
                goto fallback_missing_features;
        } else if (!perf_missing_features.clockid && evsel->attr.use_clockid) {
                perf_missing_features.clockid = true;
                goto fallback_missing_features;
        } else if (!perf_missing_features.cloexec && (flags & PERF_FLAG_FD_CLOEXEC)) {
                perf_missing_features.cloexec = true;
                goto fallback_missing_features;
        } else if (!perf_missing_features.mmap2 && evsel->attr.mmap2) {
                perf_missing_features.mmap2 = true;
                goto fallback_missing_features;
        } else if (!perf_missing_features.exclude_guest &&
                   (evsel->attr.exclude_guest || evsel->attr.exclude_host)) {
                perf_missing_features.exclude_guest = true;
                goto fallback_missing_features;
        } else if (!perf_missing_features.sample_id_all) {
                perf_missing_features.sample_id_all = true;
                goto retry_sample_id;
        }

So it does already probe for features available in the kernel and reacts as best as imagined so far to kernels lacking those features.

The whole point here is: who writes the library? Those who need it to support some feature they want to have merged?

We can use the existing infrastructure to the fullest extent possible, but at some point we need to extend it, who does it?

Quoted 15 lines
Quoted 6 lines

Now an additional complication is the fact that BTS can now also be a separate PMU, listed under /sys/bus/event_source/devices/intel_bts/.

If it's not listed there, we don't know the exact reason: is it not available because it's an old kernel? Or is it the wrong CPU?

Quoted 8 lines

We could solve that by extending the sysfs interface and adding an "error" file to the PMU directory: which would contain the reason why the driver was not created.

I.e. if the BTS driver was not created, we'd still have /sys/bus/event_source/devices/intel_bts/error (and no other file), which gives tooling a good way to discover why a particular PMU is not available. This adds a tiny bit more RAM overhead, but it's for the better I think, because tooling could be a lot more certain about what the capabilities of the kernel are.

Quoted 8 lines

That presumes the user understands what is or is not available on their architecture, because on a non-x86 architecture they still get nothing x86-specific.

It also runs a bit against the way config works e.g. even if the PMU driver is config'ed out it still has to provide a sysfs interface.

So, isn't the patch I proposed sufficient for now?

I haven't tested it so far, but it seems to improve things, given the current infrastructure.

- Arnaldo

#20 lore raw
In reply to Adrian Hunter
Quoted 11 lines · Adrian Hunter
Quoted 9 lines

So I really think we need an extended error reporting feature on the perf kernel side, so that a 'natural' error (plus a string) is reported back to tooling, instead of the current -EINVAL.

No need to do it for everything, doing it for BTS and related functionality would be a good first step to start this.

If you are interested you could try this, or I can try to write something (after the merge window).

Don't have time sorry.

So who on the Intel side has time to finish Intel/PT support properly?

As a first step I think we need to disable the Intel/PT kernel side - it was merged with the express promise that proper tooling would come along promptly, but if that's not happening due to lack of resources, then the kernel side is obviously in limbo as well.

Quoted 6 lines
Quoted 1 line

Does this make sense to you?

Normally the warts of syscalls are hidden by libraries. I am not sure a library couldn't do just as well with the advantage that it would work for old kernels too. A library could also have information about multiple architectures, not just the one that is actually running e.g. your BTS example won't work on ARM.

The method I suggested works _both_ with old and new kernels, with the new kernel simply giving better error feedback.

And these are not warts really, it's simply a threshold issue: above a certain complexity of features it makes sense to introduce a qualitatively better error reporting interface. When I tested Intel PT support I happened to go past that threshold and it became obvious that we need it.

Quoted 4 lines

A library could provide a similar API to the one you described. Either it just does the syscall and returns, or if extended error information is requested, it probes the API with various options, checks perf_event_paranoid, and generally uses whatever information it can to best figure out what went wrong.

So I think eventually a proper libperf will crystalize out of perf's syscall wrappers (I suggested it for a long time), but this has very little impact on the end user who doesn't care whether it's done in perf, or in some intermediate library.

So it can be done in the current perf code just as much - when libperf gets introduced it will be factored out into tools/lib/perf/ without much problem and then other tools can use it too.

Quoted 7 lines
Quoted 6 lines

I.e. if the BTS driver was not created, we'd still have /sys/bus/event_source/devices/intel_bts/error (and no other file), which gives tooling a good way to discover why a particular PMU is not available. This adds a tiny bit more RAM overhead, but it's for the better I think, because tooling could be a lot more certain about what the capabilities of the kernel are.

Quoted 6 lines

That presumes the user understands what is or is not available on their architecture, because on a non-x86 architecture they still get nothing x86-specific.

It also runs a bit against the way config works e.g. even if the PMU driver is config'ed out it still has to provide a sysfs interface.

I partially agree - but it's really a problem that we currently only get two states:

- the PMU driver is there in sysfs
- the PMU driver is not there in sysfs

while we really want to a lot more about why it's not there - and it's the kernel that knows this best, not tooling.

So maybe instead of having a separate directory, we could have a sysfs file that listed all the PMU drivers that the kernel knows about, with a status line that tells us whether they are:

- not configured
- configured but runtime disabled due to reason X or Y or Z
- configured and enabled

OTOH having the directories with a single file in them is a close substitute, and better meets the sysfs 'one file, one value' principle.

Quoted 1 line

So, isn't the patch I proposed sufficient for now?

Well, no, because it really does the check in the wrong place and introduces possible friction between what tooling thinks is the supported environment and what the kernel thinks - and thus postpones the problem.

I could live with this current solution as the initial version if a subsequent effort fixes it up properly by adding much better error reporting infrastructure, but the 'no time' comment makes me doubt the whole Intel/PT feature set.

Thanks,

Ingo

reviewer
#21 lore raw
Quoted 13 lines · Ingo Molnar
Quoted 10 lines · Adrian Hunter
Quoted 9 lines

So I really think we need an extended error reporting feature on the perf kernel side, so that a 'natural' error (plus a string) is reported back to tooling, instead of the current -EINVAL.

No need to do it for everything, doing it for BTS and related functionality would be a good first step to start this.

If you are interested you could try this, or I can try to write something (after the merge window).

Quoted 8 lines
Quoted 1 line

Don't have time sorry.

So who on the Intel side has time to finish Intel/PT support properly?

As a first step I think we need to disable the Intel/PT kernel side - it was merged with the express promise that proper tooling would come along promptly, but if that's not happening due to lack of resources, then the kernel side is obviously in limbo as well.

I am afraid I took your "If you are interested you could try this" literally.

So you are saying you will apply the patches if I develop the extended error string feature for the perf_event_open syscall?

Quoted 57 lines
Quoted 7 lines
Quoted 2 lines

Does this make sense to you?

Normally the warts of syscalls are hidden by libraries. I am not sure a library couldn't do just as well with the advantage that it would work for old kernels too. A library could also have information about multiple architectures, not just the one that is actually running e.g. your BTS example won't work on ARM.

The method I suggested works _both_ with old and new kernels, with the new kernel simply giving better error feedback.

And these are not warts really, it's simply a threshold issue: above a certain complexity of features it makes sense to introduce a qualitatively better error reporting interface. When I tested Intel PT support I happened to go past that threshold and it became obvious that we need it.

Quoted 4 lines

A library could provide a similar API to the one you described. Either it just does the syscall and returns, or if extended error information is requested, it probes the API with various options, checks perf_event_paranoid, and generally uses whatever information it can to best figure out what went wrong.

So I think eventually a proper libperf will crystalize out of perf's syscall wrappers (I suggested it for a long time), but this has very little impact on the end user who doesn't care whether it's done in perf, or in some intermediate library.

So it can be done in the current perf code just as much - when libperf gets introduced it will be factored out into tools/lib/perf/ without much problem and then other tools can use it too.

Quoted 7 lines
Quoted 6 lines

I.e. if the BTS driver was not created, we'd still have /sys/bus/event_source/devices/intel_bts/error (and no other file), which gives tooling a good way to discover why a particular PMU is not available. This adds a tiny bit more RAM overhead, but it's for the better I think, because tooling could be a lot more certain about what the capabilities of the kernel are.

Quoted 6 lines

That presumes the user understands what is or is not available on their architecture, because on a non-x86 architecture they still get nothing x86-specific.

It also runs a bit against the way config works e.g. even if the PMU driver is config'ed out it still has to provide a sysfs interface.

I partially agree - but it's really a problem that we currently only get two states:

- the PMU driver is there in sysfs
- the PMU driver is not there in sysfs

while we really want to a lot more about why it's not there - and it's the kernel that knows this best, not tooling.

So maybe instead of having a separate directory, we could have a sysfs file that listed all the PMU drivers that the kernel knows about, with a status line that tells us whether they are:

Quoted 6 lines

- not configured
- configured but runtime disabled due to reason X or Y or Z
- configured and enabled

OTOH having the directories with a single file in them is a close substitute, and better meets the sysfs 'one file, one value' principle.

One file, one value can be done.

What about a directory:

/sys/bus/event_source/known_pmus/

that contains a subdirectory for each pmu e.g.

/sys/bus/event_source/known_pmus/intel_pt/

which contains at least 1 file:

/sys/bus/event_source/known_pmus/intel_pt/status

That makes it easy to add more information by adding new files.

So the core would create and manage the sysfs directories and files. The default status would be "Not supported on this architecture". Arch and PMU drivers would just need to tell the core what their status is.

Quoted 10 lines
Quoted 2 lines

So, isn't the patch I proposed sufficient for now?

Well, no, because it really does the check in the wrong place and introduces possible friction between what tooling thinks is the supported environment and what the kernel thinks - and thus postpones the problem.

I could live with this current solution as the initial version if a subsequent effort fixes it up properly by adding much better error reporting infrastructure, but the 'no time' comment makes me doubt the whole Intel/PT feature set.

#22 lore raw
In reply to Ingo Molnar
Quoted 18 lines · Ingo Molnar

So I really think we need an extended error reporting feature on the perf kernel side, so that a 'natural' error (plus a string) is reported back to tooling, instead of the current -EINVAL.

No need to do it for everything, doing it for BTS and related functionality would be a good first step to start this.

If you are interested you could try this, or I can try to write something (after the merge window).

So the idea would be to convert such opaque error returns:

        if (attr->config == PERF_COUNT_HW_BRANCH_INSTRUCTIONS &&
            !attr->freq && hwc->sample_period == 1) {
                /* BTS is not supported by this architecture. */
                if (!x86_pmu.bts_active)
                        return -EOPNOTSUPP;
Quoted 3 lines

into:

			return perf_err(event, -EOPNOTSUPP, "The BTS hardware feature is not available on this CPU.");

So I poked around this a bit and came up with the patch below to give this topic some more momentum.

Your average error will then be like this:

#define PERF_MODNAME "perf/x86"

...

               /* BTS is currently only allowed for user-mode. */
               if (!attr->exclude_kernel)
                       return perf_err(event, -EOPNOTSUPP,
                                       "BTS sampling not allowed for kernel space");

which in userspace will translate into:

---cut---

$ perf record -e branches:uk -c1 ls
kernel says: {
        "code": -95,
        "module": "perf/x86",
        "message": "BTS sampling not allowed for kernel space"
}

Error:
No hardware sampling interrupt available.
No APIC? If so then you can boot the kernel with the "lapic" boot parameter to force-enable it. ---cut---

The way I hacked it into tools/perf, it still prints out the old error message (which, to prove the point once again, is neither here nor there).

The patch below attaches the error to struct perf_event or copies it directly to user's buffer in case if we don't have an event at the point of error. Maybe a slightly easier way of doing it would be to strap it to task_struct instead, but let's not stir the pot too much this time around.

Also, to add an extra spin, the report is formatted as a JSON object so that we could include both human-readable and machine-readable bits.

Quoted 1 line

From a7de169ef2ca5425cd57286bfb61bfd5f8d15738 Mon Sep 17 00:00:00 2001

From: Alexander Shishkin <[email protected]>
Date: Fri, 3 Jul 2015 17:12:54 +0300
Subject: [PATCH] perf: Introduce extended syscall error reporting

It has been pointed several times out that perf syscall error reporting leaves a lot to be desired [1].

This patch introduces a fairly simple extension that allows call sites to annotate their error codes with arbitrary strings, which will then be copied to userspace (if they asked for it) along with the module name that produced the error message in JSON format. This way, we can provide both human-readable and machine-parsable information to user and leave room for extensions in the future.

[1] http://marc.info/?l=linux-kernel&m=141470811013082

---
 include/linux/perf_event.h      | 38 ++++++++++++++++++++++++
 include/uapi/linux/perf_event.h |  8 ++++-
 kernel/events/core.c            | 66 +++++++++++++++++++++++++++++++++++++++--
 3 files changed, 108 insertions(+), 4 deletions(-)
include/linux/perf_event.h +38 -0
index 1b82d44b0a..15bbef478f 100644
@@ -56,6 +56,37 @@ struct perf_guest_info_callbacks {
 #include <linux/cgroup.h>
 #include <asm/local.h>
 
+#ifndef PERF_MODNAME
+#define PERF_MODNAME KBUILD_MODNAME
+#endif
+
+/*
+ * Extended error reporting: annotate an error code with a string
+ * and a module name to help users diagnase problems with their
+ * attributes and whatnot.
+ */
+struct perf_err_site {
+	const char		*message;
+	const char		*owner;
+	const int		code;
+};
+
+#ifdef CONFIG_PERF_EVENTS
+
+#define __perf_err(__e, __c, __m) ({			\
+	static struct perf_err_site __err_site = {	\
+		.message	= (__m),		\
+		.owner		= PERF_MODNAME,		\
+		.code		= (__c),		\
+	};						\
+	(__e) = &__err_site;				\
+	(__c);						\
+})
+
+#define perf_err(__evt, __c, __m) ({ __perf_err((__evt)->error, (__c), (__m)); })
+
+#endif
+
 struct perf_callchain_entry {
 	__u64				nr;
 	__u64				ip[PERF_MAX_STACK_DEPTH];
@@ -447,6 +478,13 @@ struct perf_event {
 	struct list_head		owner_entry;
 	struct task_struct		*owner;
 
+	/*
+	 * Extended error reporting
+	 */
+	const struct perf_err_site	*error;
+	void __user			*error_buffer;
+	size_t				error_buffer_size;
+
 	/* mmap bits */
 	struct mutex			mmap_mutex;
 	atomic_t			mmap_count;
include/uapi/linux/perf_event.h +7 -1
index d97f84c080..d1ae1a079c 100644
@@ -264,6 +264,7 @@ enum perf_event_read_format {
 					/* add: sample_stack_user */
 #define PERF_ATTR_SIZE_VER4	104	/* add: sample_regs_intr */
 #define PERF_ATTR_SIZE_VER5	112	/* add: aux_watermark */
+#define PERF_ATTR_SIZE_VER6	120	/* add: perf_err */
 
 /*
  * Hardware event_id to monitor via a performance monitoring event:
@@ -374,7 +375,12 @@ struct perf_event_attr {
 	 * Wakeup watermark for AUX area
 	 */
 	__u32	aux_watermark;
-	__u32	__reserved_2;	/* align to __u64 */
+
+	/*
+	 * Extended error reporting buffer
+	 */
+	__u32	perf_err_size;
+	__u64	perf_err;
 };
 
 #define perf_flags(attr)	(*(&(attr)->read_format + 1))
kernel/events/core.c +63 -3

102 lines not on this page · raw message

Signature · 1 line
2.1.4