perf/pt -> Intel PT/BTS
Arnaldo Carvalho de Melo
maintainerHi 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
Arnaldo Carvalho de Melo
maintainerPATCH 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
@@ -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
@@ -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
Arnaldo Carvalho de Melo
maintainerPATCH 2/8 perf tools: Add Intel PT packet decoder
In reply to Arnaldo Carvalho de MeloFrom: 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
@@ -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
@@ -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
Arnaldo Carvalho de Melo
maintainerPATCH 3/8 perf tools: Add Intel PT instruction decoder
In reply to Arnaldo Carvalho de MeloFrom: 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.
--- 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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
Arnaldo Carvalho de Melo
maintainerPATCH 4/8 perf tools: Add Intel PT log
In reply to Arnaldo Carvalho de MeloFrom: 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
@@ -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
Arnaldo Carvalho de Melo
maintainerPATCH 5/8 perf tools: Add Intel PT decoder
In reply to Arnaldo Carvalho de MeloFrom: 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
@@ -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
Arnaldo Carvalho de Melo
maintainerPATCH 6/8 perf tools: Add Intel PT support
In reply to Arnaldo Carvalho de MeloFrom: 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
@@ -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
@@ -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
Arnaldo Carvalho de Melo
maintainerPATCH 7/8 perf tools: Take Intel PT into use
In reply to Arnaldo Carvalho de MeloFrom: 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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
Arnaldo Carvalho de Melo
maintainerPATCH 8/8 perf tools: Add Intel BTS support
In reply to Arnaldo Carvalho de MeloFrom: 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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
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.gittags/perf-pt-for-mingofor 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)Signed-off-by Arnaldo Carvalho de Melo <[email protected]>----------------------------------------------------------------
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 supporttools/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
Adrian Hunter
reviewerQuoted 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.gittags/perf-pt-for-mingofor 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)Signed-off-by Arnaldo Carvalho de Melo <[email protected]>----------------------------------------------------------------
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 supporttools/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.hQuoted 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.hYeah, so I did a 'newbie test':
I pulled the tree and saw that it has a
tools/perf/Documentation/intel-bts.txtfile 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 eventsusage: 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?
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.txtfile 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 eventsusage: 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
Adrian Hunter
reviewerQuoted 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.txtfile 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 eventsusage: 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 2015x86_64x86_64x86_64GNU/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
# trace0.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
@@ -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.
Arnaldo Carvalho de Melo
maintainerEm 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.txtfile 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 eventsusage: 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
Adrian Hunter
reviewerQuoted 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.txtfile 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 eventsusage: 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 eventsusage: 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 2015x86_64x86_64x86_64GNU/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
# trace0.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@@ -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
@@ -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
@@ -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
Adrian Hunter
reviewerQuoted 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.txtfile 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 eventsusage: 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 eventsusage: 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 2015x86_64x86_64x86_64GNU/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
Quoted 4 lines · Adrian Hunter
I am going to need to know what hardware it is and cpu feature flags i.e.
/proc/cpuinfoAlso 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
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 missingintel_btsand
intel_ptsupportAdd error messages to assist users in determining why there is no
intel_btsorintel_ptsupport.Signed-off-by Adrian Hunter <[email protected]>--- 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@@ -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@@ -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@@ -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
Adrian Hunter
reviewerQuoted 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 missingintel_btsand
intel_ptsupportAdd error messages to assist users in determining why there is no
intel_btsorintel_ptsupport.Signed-off-by Adrian Hunter <[email protected]>--- 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@@ -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@@ -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@@ -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, thenperf_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?
Arnaldo Carvalho de Melo
maintainerEm 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
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
Adrian Hunter
reviewerQuoted 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 sysfswhile 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 enabledOTOH 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.
Alexander Shishkin
reviewerQuoted 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
a7de169ef2ca5425cd57286bfb61bfd5f8d15738Mon 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
@@ -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
@@ -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