perf/core improvements and fixes
Arnaldo Carvalho de Melo
maintainerHi Ingo,
Please consider pulling,
- Arnaldo
Test results at the end of this message, as usual.
The following changes since commit 1ccb8feda7471efb62ebf68d70055b4c51fa7d92:
Merge tag 'perf-core-for-mingo-4.16-20180110' of git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux into perf/core (2018-01-11 06:53:06 +0100)
are available in the Git repository at:
git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux.git tags/perf-core-for-mingo-4.16-20180117
for you to fetch changes up to 81fccd6ca507d3b2012eaf1edeb9b1dbf4bd22db:
perf record: Fix failed memory allocation for get_cpuid_str (2018-01-17 10:31:25 -0300)
----------------------------------------------------------------
perf/core improvements and fixes:
- Fix various per event 'max-stack' and 'call-graph=dwarf' issues, mostly in 'perf trace', allowing to use 'perf trace --call-graph' with 'dwarf' and 'fp' to setup the callgraph details for the syscall events and make that apply to other events, whilhe allowing to override that on a per-event basis, using '-e sched:*switch/call-graph=dwarf/' for instance (Arnaldo Carvalho de Melo)
- Improve the --time percent support in record/report/script (Jin Yao)
- Fix copyfile_offset update of output offset (Jiri Olsa)
- Add python script to profile and resolve physical mem type (Kan Liang)
- Add ARM Statistical Profiling Extensions (SPE) support (Kim Phillips)
- Remove trailing semicolon in the evlist code (Luis de Bethencourt)
- Fix incorrect handling of type _TERM_DRV_CFG (Mathieu Poirier)
- Use asprintf when possible in libtraceevent (Federico Vaga)
- Fix bad force_token escape sequence in libtraceevent (Michael Sartain)
- Add UL suffix to MISSING_EVENTS in libtraceevent (Michael Sartain)
- value of unknown symbolic fields in libtraceevent (Jan Kiszka)
- libtraceevent updates: (Steven Rostedt)
o Show value of flags that have not been parsed
o Simplify pointer print logic and fix %pF
o Handle new pointer processing of bprint strings
o Show contents (in hex) of data of unrecognized type records
o Fix get_field_str() for dynamic strings
- Add missing break in FALSE case of pevent_filter_clear_trivial() (Taeung Song)
- Fix failed memory allocation for get_cpuid_str (Thomas Richter)
----------------------------------------------------------------
Arnaldo Carvalho de Melo (8):
perf trace: No need to set PERF_SAMPLE_IDENTIFIER explicitely
perf evsel: Check if callchain is enabled before setting it up
perf trace: Fix setting of --call-graph/--max-stack for non-syscall events perf callchain: Fix attr.sample_max_stack setting
perf unwind: Do not look just at the global callchain_param.record_mode perf trace: Setup DWARF callchains for non-syscall events when --max-stack is used perf trace: Allow overriding global --max-stack per event
perf callchains: Ask for PERF_RECORD_MMAP for data mmaps for DWARF unwinding
Federico Vaga (1):
tools lib traceevent: Use asprintf when possible
Jan Kiszka (1):
tools lib traceevent: Print value of unknown symbolic fields
Jin Yao (8):
perf report: Improve error msg when no first/last sample time found perf script: Improve error msg when no first/last sample time found perf util: Improve error checking for time percent input perf util: Support no index time percent slice
perf report: Add an indication of what time slices are used perf util: Allocate time slices buffer according to number of comma perf report: Remove the time slices number limitation perf script: Remove the time slices number limitation
Jiri Olsa (1):
perf tools: Fix copyfile_offset update of output offset
Kan Liang (1):
perf script python: Add script to profile and resolve physical mem type
Kim Phillips (1):
perf tools: Add ARM Statistical Profiling Extensions (SPE) support
Luis de Bethencourt (1):
perf evlist: Remove trailing semicolon
Mathieu Poirier (1):
perf evsel: Fix incorrect handling of type _TERM_DRV_CFG
Michael Sartain (2):
tools lib traceevent: Fix bad force_token escape sequence tools lib traceevent: Add UL suffix to MISSING_EVENTS
Steven Rostedt (VMware) (5):
tools lib traceevent: Show value of flags that have not been parsed tools lib traceevent: Simplify pointer print logic and fix %pF tools lib traceevent: Handle new pointer processing of bprint strings tools lib traceevent: Show contents (in hex) of data of unrecognized type records tools lib traceevent: Fix get_field_str() for dynamic strings
Taeung Song (1):
tools lib traceevent: Fix missing break in FALSE case of pevent_filter_clear_trivial()
Thomas Richter (1):
perf record: Fix failed memory allocation for get_cpuid_str
tools/lib/traceevent/event-parse.c | 62 ++- tools/lib/traceevent/event-plugin.c | 24 +- tools/lib/traceevent/kbuffer-parse.c | 4 +- tools/lib/traceevent/parse-filter.c | 22 +- tools/perf/Documentation/perf-report.txt | 2 +- tools/perf/Documentation/perf-script.txt | 10 +- tools/perf/arch/arm/util/auxtrace.c | 77 +++- tools/perf/arch/arm/util/pmu.c | 6 + tools/perf/arch/arm64/util/Build | 3 +- tools/perf/arch/arm64/util/arm-spe.c | 225 ++++++++++ tools/perf/arch/x86/util/header.c | 2 +- tools/perf/builtin-c2c.c | 5 +- tools/perf/builtin-report.c | 34 +- tools/perf/builtin-script.c | 25 +- tools/perf/builtin-trace.c | 62 +-- tools/perf/scripts/python/bin/mem-phys-addr-record | 19 + tools/perf/scripts/python/bin/mem-phys-addr-report | 3 + tools/perf/scripts/python/mem-phys-addr.py | 95 +++++ tools/perf/tests/dwarf-unwind.c | 1 + tools/perf/util/Build | 2 + tools/perf/util/arm-spe-pkt-decoder.c | 462 +++++++++++++++++++++ tools/perf/util/arm-spe-pkt-decoder.h | 43 ++ tools/perf/util/arm-spe.c | 231 +++++++++++ tools/perf/util/arm-spe.h | 31 ++ tools/perf/util/auxtrace.c | 3 + tools/perf/util/auxtrace.h | 1 + tools/perf/util/callchain.c | 10 + tools/perf/util/callchain.h | 2 + tools/perf/util/evlist.c | 2 +- tools/perf/util/evsel.c | 40 +- .../util/scripting-engines/trace-event-python.c | 2 + tools/perf/util/time-utils.c | 72 +++- tools/perf/util/time-utils.h | 2 + tools/perf/util/unwind-libunwind-local.c | 9 +- tools/perf/util/util.c | 2 +- 35 files changed, 1465 insertions(+), 130 deletions(-) create mode 100644 tools/perf/arch/arm64/util/arm-spe.c create mode 100644 tools/perf/scripts/python/bin/mem-phys-addr-record create mode 100644 tools/perf/scripts/python/bin/mem-phys-addr-report create mode 100644 tools/perf/scripts/python/mem-phys-addr.py create mode 100644 tools/perf/util/arm-spe-pkt-decoder.c create mode 100644 tools/perf/util/arm-spe-pkt-decoder.h create mode 100644 tools/perf/util/arm-spe.c create mode 100644 tools/perf/util/arm-spe.h
Test results:
The first ones are container (docker) based builds of tools/perf with and without libelf support. Where clang is available, it is also used to build perf with/without libelf.
The objtool and samples/bpf/ builds are disabled now that I'm switching from using the sources in a local volume to fetching them from a http server to build it inside the container, to make it easier to build in a container cluster. Those will come back later.
Several are cross builds, the ones with -x-ARCH and the android ones, and those may not have all the features built, due to lack of multi-arch devel packages, available and being used so far on just a few, like debian:experimental-x-{arm64,mipsel}.
The 'perf test' one will perform a variety of tests exercising tools/perf/util/, tools/lib/{bpf,traceevent,etc}, as well as run perf commands with a variety of command line event specifications to then intercept the sys_perf_event syscall to check that the perf_event_attr fields are set up as expected, among a variety of other unit tests.
Then there is the 'make -C tools/perf build-test' ones, that build tools/perf/ with a variety of feature sets, exercising the build with an incomplete set of features as well as with a complete one. It is planned to have it run on each of the containers mentioned above, using some container orchestration infrastructure. Get in contact if interested in helping having this in place.
Intel(R) Core(TM) i5-7500 CPU @ 3.40GHz
# dm 1 36.63 alpine:3.4 : Ok gcc (Alpine 5.3.0) 5.3.0 2 44.29 alpine:3.5 : Ok gcc (Alpine 6.2.1) 6.2.1 20160822 3 41.00 alpine:3.6 : Ok gcc (Alpine 6.3.0) 6.3.0 4 43.95 alpine:edge : Ok gcc (Alpine 6.4.0) 6.4.0 5 35.44 amazonlinux:1 : Ok gcc (GCC) 4.8.5 20150623 (Red Hat 4.8.5-11) 6 40.90 amazonlinux:2 : Ok gcc (GCC) 7.2.1 20170915 (Red Hat 7.2.1-2) 7 26.89 android-ndk:r12b-arm : Ok arm-linux-androideabi-gcc (GCC) 4.9.x 20150123 (prerelease) 8 27.57 android-ndk:r15c-arm : Ok arm-linux-androideabi-gcc (GCC) 4.9.x 20150123 (prerelease) 9 22.78 centos:5 : Ok gcc (GCC) 4.1.2 20080704 (Red Hat 4.1.2-55) 10 35.27 centos:6 : Ok gcc (GCC) 4.4.7 20120313 (Red Hat 4.4.7-18) 11 40.16 centos:7 : Ok gcc (GCC) 4.8.5 20150623 (Red Hat 4.8.5-16) 12 34.36 debian:7 : Ok gcc (Debian 4.7.2-5) 4.7.2 13 37.23 debian:8 : Ok gcc (Debian 4.9.2-10) 4.9.2 14 62.09 debian:9 : Ok gcc (Debian 6.3.0-18) 6.3.0 20170516 15 64.09 debian:experimental : Ok gcc (Debian 7.2.0-18) 7.2.0 16 39.24 debian:experimental-x-arm64 : Ok aarch64-linux-gnu-gcc (Debian 7.2.0-11) 7.2.0 17 37.88 debian:experimental-x-mips : Ok mips-linux-gnu-gcc (Debian 7.2.0-11) 7.2.0 18 34.81 debian:experimental-x-mips64 : Ok mips64-linux-gnuabi64-gcc (Debian 7.2.0-11) 7.2.0 19 37.26 debian:experimental-x-mipsel : Ok mipsel-linux-gnu-gcc (Debian 7.2.0-11) 7.2.0 20 37.58 fedora:20 : Ok gcc (GCC) 4.8.3 20140911 (Red Hat 4.8.3-7) 21 40.34 fedora:21 : Ok gcc (GCC) 4.9.2 20150212 (Red Hat 4.9.2-6) 22 38.42 fedora:22 : Ok gcc (GCC) 5.3.1 20160406 (Red Hat 5.3.1-6) 23 40.07 fedora:23 : Ok gcc (GCC) 5.3.1 20160406 (Red Hat 5.3.1-6) 24 45.57 fedora:24 : Ok gcc (GCC) 6.3.1 20161221 (Red Hat 6.3.1-1) 25 35.50 fedora:24-x-ARC-uClibc : Ok arc-linux-gcc (ARCompact ISA Linux uClibc toolchain 2017.09-rc2) 7.1.1 20170710 26 80.48 fedora:25 : Ok gcc (GCC) 6.4.1 20170727 (Red Hat 6.4.1-1) 27 88.31 fedora:26 : Ok gcc (GCC) 7.2.1 20170915 (Red Hat 7.2.1-2) 28 86.02 fedora:27 : Ok gcc (GCC) 7.2.1 20170915 (Red Hat 7.2.1-2) 29 78.37 fedora:rawhide : Ok gcc (GCC) 7.2.1 20170915 (Red Hat 7.2.1-4) 30 39.71 gentoo-stage3-amd64:latest : Ok gcc (Gentoo 6.4.0-r1 p1.3) 6.4.0 31 40.65 mageia:5 : Ok gcc (GCC) 4.9.2 32 42.26 mageia:6 : Ok gcc (Mageia 5.4.0-5.mga6) 5.4.0 33 40.11 opensuse:42.1 : Ok gcc (SUSE Linux) 4.8.5 34 38.80 opensuse:42.2 : Ok gcc (SUSE Linux) 4.8.5 35 40.91 opensuse:42.3 : Ok gcc (SUSE Linux) 4.8.5 36 83.55 opensuse:tumbleweed : Ok gcc (SUSE Linux) 7.2.1 20171020 [gcc-7-branch revision 253932] 37 32.24 oraclelinux:6 : Ok gcc (GCC) 4.4.7 20120313 (Red Hat 4.4.7-18) 38 42.29 oraclelinux:7 : Ok gcc (GCC) 4.8.5 20150623 (Red Hat 4.8.5-16) 39 33.96 ubuntu:12.04.5 : Ok gcc (Ubuntu/Linaro 4.6.3-1ubuntu5) 4.6.3 40 38.79 ubuntu:14.04.4 : Ok gcc (Ubuntu 4.8.4-2ubuntu1~14.04.3) 4.8.4 41 32.93 ubuntu:14.04.4-x-linaro-arm64 : Ok aarch64-linux-gnu-gcc (Linaro GCC 5.5-2017.10) 5.5.0 42 61.08 ubuntu:16.04 : Ok gcc (Ubuntu 5.4.0-6ubuntu1~16.04.5) 5.4.0 20160609 43 32.29 ubuntu:16.04-x-arm : Ok arm-linux-gnueabihf-gcc (Ubuntu/Linaro 5.4.0-6ubuntu1~16.04.4) 5.4.0 20160609 44 32.09 ubuntu:16.04-x-arm64 : Ok aarch64-linux-gnu-gcc (Ubuntu/Linaro 5.4.0-6ubuntu1~16.04.4) 5.4.0 20160609 45 31.18 ubuntu:16.04-x-powerpc : Ok powerpc-linux-gnu-gcc (Ubuntu 5.4.0-6ubuntu1~16.04.4) 5.4.0 20160609 46 31.50 ubuntu:16.04-x-powerpc64 : Ok powerpc64-linux-gnu-gcc (Ubuntu/IBM 5.4.0-6ubuntu1~16.04.1) 5.4.0 20160609 47 32.23 ubuntu:16.04-x-powerpc64el : Ok powerpc64le-linux-gnu-gcc (Ubuntu/IBM 5.4.0-6ubuntu1~16.04.4) 5.4.0 20160609 48 30.79 ubuntu:16.04-x-s390 : Ok s390x-linux-gnu-gcc (Ubuntu 5.4.0-6ubuntu1~16.04.4) 5.4.0 20160609 49 63.98 ubuntu:16.10 : Ok gcc (Ubuntu 6.2.0-5ubuntu12) 6.2.0 20161005 50 64.41 ubuntu:17.04 : Ok gcc (Ubuntu 6.3.0-12ubuntu2) 6.3.0 20170406 51 64.98 ubuntu:17.10 : Ok gcc (Ubuntu 7.2.0-8ubuntu3) 7.2.0 52 68.13 ubuntu:18.04 : Ok gcc (Ubuntu 7.2.0-18ubuntu2) 7.2.0 #
# uname -a
Linux seventh 4.15.0-rc8+ #1 SMP Wed Jan 17 10:45:59 -03 2018 x86_64 x86_64 x86_64 GNU/Linux
# perf test
1: vmlinux symtab matches kallsyms : Ok
2: Detect openat syscall event : Ok
3: Detect openat syscall event on all cpus : Ok
4: Read samples using the mmap interface : Ok
5: Test data source output : Ok
6: Parse event definition strings : Ok
7: Simple expression parser : Ok
8: PERF_RECORD_* events & perf_sample fields : Ok
9: Parse perf pmu format : Ok
10: DSO data read : Ok
11: DSO data cache : Ok
12: DSO data reopen : Ok
13: Roundtrip evsel->name : Ok
14: Parse sched tracepoints fields : Ok
15: syscalls:sys_enter_openat event fields : Ok
16: Setup struct perf_event_attr : Ok
17: Match and link multiple hists : Ok
18: 'import perf' in python : Ok
19: Breakpoint overflow signal handler : Ok
20: Breakpoint overflow sampling : Ok
21: Number of exit events of a simple workload : Ok
22: Software clock events period values : Ok
23: Object code reading : Ok
24: Sample parsing : Ok
25: Use a dummy software event to keep tracking : Ok
26: Parse with no sample_id_all bit set : Ok
27: Filter hist entries : Ok
28: Lookup mmap thread : Ok
29: Share thread mg : Ok
30: Sort output of hist entries : Ok
31: Cumulate child hist entries : Ok
32: Track with sched_switch : Ok
33: Filter fds with revents mask in a fdarray : Ok
34: Add fd to a fdarray, making it autogrow : Ok
35: kmod_path__parse : Ok
36: Thread map : Ok
37: LLVM search and compile :
37.1: Basic BPF llvm compile : Ok
37.2: kbuild searching : Ok
37.3: Compile source for BPF prologue generation : Ok
37.4: Compile source for BPF relocation : Ok
38: Session topology : Ok
39: BPF filter :
39.1: Basic BPF filtering : Ok
39.2: BPF pinning : Ok
39.3: BPF prologue generation : Ok
39.4: BPF relocation checker : Ok
40: Synthesize thread map : Ok
41: Remove thread map : Ok
42: Synthesize cpu map : Ok
43: Synthesize stat config : Ok
44: Synthesize stat : Ok
45: Synthesize stat round : Ok
46: Synthesize attr update : Ok
47: Event times : Ok
48: Read backward ring buffer : Ok
49: Print cpu map : Ok
50: Probe SDT events : Ok
51: is_printable_array : Ok
52: Print bitmap : Ok
53: perf hooks : Ok
54: builtin clang support : Skip (not compiled in)
55: unit_number__scnprintf : Ok
56: x86 rdpmc : Ok
57: Convert perf time to TSC : Ok
58: DWARF unwind : Ok
59: x86 instruction decoder - new instructions : Ok
60: Use vfs_getname probe to get syscall args filenames : Ok
61: Check open filename arg using perf trace + vfs_getname: Ok
62: probe libc's inet_pton & backtrace it with ping : Ok
63: Add vfs_getname probe to get syscall args filenames : Ok
#
$ make -C tools/perf build-test
make: Entering directory '/home/acme/git/perf/tools/perf'
- tarpkg: ./tests/perf-targz-src-pkg .
make_minimal_O: make NO_LIBPERL=1 NO_LIBPYTHON=1 NO_NEWT=1 NO_GTK2=1 NO_DEMANGLE=1 NO_LIBELF=1 NO_LIBUNWIND=1 NO_BACKTRACE=1 NO_LIBNUMA=1 NO_LIBAUDIT=1 NO_LIBBIONIC=1 NO_LIBDW_DWARF_UNWIND=1 NO_AUXTRACE=1 NO_LIBBPF=1 NO_LIBCRYPTO=1 NO_SDT=1 NO_JVMTI=1
make_clean_all_O: make clean all
make_no_demangle_O: make NO_DEMANGLE=1
make_no_backtrace_O: make NO_BACKTRACE=1
make_no_libperl_O: make NO_LIBPERL=1
make_with_clangllvm_O: make LIBCLANGLLVM=1
make_install_prefix_slash_O: make install prefix=/tmp/krava/
make_no_libelf_O: make NO_LIBELF=1
make_doc_O: make doc
make_debug_O: make DEBUG=1
make_no_libdw_dwarf_unwind_O: make NO_LIBDW_DWARF_UNWIND=1
make_tags_O: make tags
make_help_O: make help
make_util_pmu_bison_o_O: make util/pmu-bison.o
make_util_map_o_O: make util/map.o
make_no_ui_O: make NO_NEWT=1 NO_SLANG=1 NO_GTK2=1
make_no_libbionic_O: make NO_LIBBIONIC=1
make_no_scripts_O: make NO_LIBPYTHON=1 NO_LIBPERL=1
make_with_babeltrace_O: make LIBBABELTRACE=1
make_no_auxtrace_O: make NO_AUXTRACE=1
make_install_prefix_O: make install prefix=/tmp/krava
make_no_libbpf_O: make NO_LIBBPF=1
make_perf_o_O: make perf.o
make_no_libpython_O: make NO_LIBPYTHON=1
make_install_O: make install
make_pure_O: make
make_static_O: make LDFLAGS=-static
make_no_slang_O: make NO_SLANG=1
make_no_libaudit_O: make NO_LIBAUDIT=1
make_no_libnuma_O: make NO_LIBNUMA=1
make_no_gtk2_O: make NO_GTK2=1
make_no_libunwind_O: make NO_LIBUNWIND=1
make_no_newt_O: make NO_NEWT=1
make_install_bin_O: make install-bin
OK
make: Leaving directory '/home/acme/git/perf/tools/perf'
$Arnaldo Carvalho de Melo
maintainerPATCH 1/32 perf evsel: Fix incorrect handling of type _TERM_DRV_CFG
From: Mathieu Poirier <[email protected]>
Commit ("d0565132605f perf evsel: Enable type checking for perf_evsel_config_term types") assumes PERF_EVSEL__CONFIG_TERM_DRV_CFG isn't used and as such adds a BUG_ON().
Since the enumeration type is used in macro ADD_CONFIG_TERM() the change break CoreSight trace acquisition.
This patch restores the original code.
--- tools/perf/util/evsel.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
tools/perf/util/evsel.c +1 -1
@@ -781,7 +781,7 @@ static void apply_config_terms(struct perf_evsel *evsel, attr->write_backward = term->val.overwrite ?1 :0 ;break ;case PERF_EVSEL__CONFIG_TERM_DRV_CFG : -BUG_ON (1 ); +break ;default :break ; }
Signature · 1 line
2.14.3
Arnaldo Carvalho de Melo
maintainerPATCH 2/32 perf evlist: Remove trailing semicolon
In reply to Arnaldo Carvalho de MeloFrom: Luis de Bethencourt <[email protected]>
The trailing semicolon is an empty statement that does no operation. Removing it since it doesn't do anything.
--- tools/perf/util/evlist.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
tools/perf/util/evlist.c +1 -1
@@ -1760,7 +1760,7 @@ void perf_evlist__toggle_bkw_mmap(struct perf_evlist *evlist,switch (old_state) {case BKW_MMAP_NOTREADY : {if (state !=BKW_MMAP_RUNNING ) - goto state_err;; + goto state_err;break ; }case BKW_MMAP_RUNNING : {
Signature · 1 line
2.14.3
Arnaldo Carvalho de Melo
maintainerPATCH 3/32 perf script python: Add script to profile and resolve physical mem type
In reply to Arnaldo Carvalho de MeloFrom: Kan Liang <[email protected]>
There could be different types of memory in the system. E.g normal System Memory, Persistent Memory. To understand how the workload maps to those memories, it's important to know the I/O statistics of them. Perf can collect physical addresses, but those are raw data. It still needs extra work to resolve the physical addresses. Provide a script to facilitate the physical addresses resolving and I/O statistics.
Profile with MEM_INST_RETIRED.ALL_LOADS or MEM_UOPS_RETIRED.ALL_LOADS event if any of them is available.
Look up the /proc/iomem and resolve the physical address. Provide memory type summary.
Here is an example output:
# perf script report mem-phys-addr Event: mem_inst_retired.all_loads:P Memory type count percentage ---------------------------------------- ----------- ----------- System RAM 74 53.2% Persistent Memory 55 39.6% N/A
---
Changes since V2:
- Apply the new license rules.
- Add comments for globals
Changes since V1:
- Do not mix DLA and Load Latency. Do not compare the loads and stores. Only profile the loads.
- Use event name to replace the RAW event
--- tools/perf/scripts/python/bin/mem-phys-addr-record | 19 +++++ tools/perf/scripts/python/bin/mem-phys-addr-report | 3 + tools/perf/scripts/python/mem-phys-addr.py | 95 ++++++++++++++++++++++ .../util/scripting-engines/trace-event-python.c | 2 + 4 files changed, 119 insertions(+) create mode 100644 tools/perf/scripts/python/bin/mem-phys-addr-record create mode 100644 tools/perf/scripts/python/bin/mem-phys-addr-report create mode 100644 tools/perf/scripts/python/mem-phys-addr.py
tools/perf/scripts/python/bin/mem-phys-addr-record new file +19 -0
@@ -0,0 +1,19 @@ +#!/bin/bash + +# +# Profiling physical memory by all retired load instructions/uops event +# MEM_INST_RETIRED.ALL_LOADS or MEM_UOPS_RETIRED.ALL_LOADS +# + +load=`perf list | grep mem_inst_retired.all_loads` +if [ -z "$load" ]; then + load=`perf list | grep mem_uops_retired.all_loads` +fi +if [ -z "$load" ]; then + echo "There is no event to count all retired load instructions/uops." + exit 1 +fi + +arg=$(echo $load | tr -d ' ') +arg="$arg:P" +perf record --phys-data -e $arg $@
tools/perf/scripts/python/bin/mem-phys-addr-report new file +3 -0
@@ -0,0 +1,3 @@ +#!/bin/bash +# description: resolve physical address samples +perf script $@ -s "$PERF_EXEC_PATH"/scripts/python/mem-phys-addr.py
tools/perf/scripts/python/mem-phys-addr.py new file +95 -0
95 lines not on this page · raw message
tools/perf/util/scripting-engines/trace-event-python.c +2 -0
@@ -499,6 +499,8 @@ static PyObject *get_perf_sample_dict(struct perf_sample *sample, PyLong_FromUnsignedLongLong(sample->time));pydict_set_item_string_decref (dict_sample,"period" ,PyLong_FromUnsignedLongLong (sample->period)); +pydict_set_item_string_decref (dict_sample,"phys_addr" , +PyLong_FromUnsignedLongLong (sample->phys_addr));set_sample_read_in_dict (dict_sample, sample, evsel);pydict_set_item_string_decref (dict,"sample" , dict_sample);
Signature · 1 line
2.14.3
Arnaldo Carvalho de Melo
maintainerPATCH 4/32 perf trace: No need to set PERF_SAMPLE_IDENTIFIER explicitely
In reply to Arnaldo Carvalho de MeloFrom: Arnaldo Carvalho de Melo <[email protected]>
Since 75562573bab3 ("perf tools: Add support for PERF_SAMPLE_IDENTIFIER") we don't need explicitely set PERF_SAMPLE_IDENTIFIER, as perf_evlist__config() will do this for us, i.e. when there are more than one evsel in an evlist, it will check if some evsel has a sample_type different than the one on the first evsel in the list, setting PERF_SAMPLE_IDENTIFIER in that case.
So, to simplify 'perf trace' codebase, ditch that check.
--- tools/perf/builtin-trace.c | 23 ----------------------- 1 file changed, 23 deletions(-)
tools/perf/builtin-trace.c +0 -23
@@ -2348,40 +2348,17 @@ static int trace__run(struct trace *trace, int argc, const char **argv)perf_evlist__config (evlist, &trace->opts,NULL );if (callchain_param.enabled) { -bool use_identifier = false; -if (trace->syscalls.events.sys_exit) {perf_evsel__config_callchain (trace->syscalls.events.sys_exit, &trace->opts, &callchain_param); - use_identifier = true; }if (pgfault_maj) {perf_evsel__config_callchain (pgfault_maj, &trace->opts, &callchain_param); - use_identifier = true; }if (pgfault_min) {perf_evsel__config_callchain (pgfault_min, &trace->opts, &callchain_param); - use_identifier = true; - } - -if (use_identifier) { -/* -* Now we have evsels with different sample_ids, use -* PERF_SAMPLE_IDENTIFIER to map from sample to evsel -* from a fixed position in each ring buffer record. -* -* As of this the changeset introducing this comment, this -* isn't strictly needed, as the fields that can come before -* PERF_SAMPLE_ID are all used, but we'll probably disable -* some of those for things like copying the payload of -* pointer syscall arguments, and for vfs_getname we don't -* need PERF_SAMPLE_ADDR and PERF_SAMPLE_IP, so do this -* here as a warning we need to use PERF_SAMPLE_IDENTIFIER. -*/ -perf_evlist__set_sample_bit (evlist,IDENTIFIER ); -perf_evlist__reset_sample_bit (evlist,ID ); } }
Signature · 1 line
2.14.3
Arnaldo Carvalho de Melo
maintainerPATCH 5/32 perf tools: Fix copyfile_offset update of output offset
In reply to Arnaldo Carvalho de MeloFrom: Jiri Olsa <[email protected]>
We need to increase output offset in each iteration, not decrease it as we currently do.
I guess we were lucky to finish in most cases in first iteration, so the bug never showed. However it shows a lot when working with big (~4GB) size data.
--- tools/perf/util/util.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
tools/perf/util/util.c +1 -1
@@ -210,7 +210,7 @@ static int copyfile_offset(int ifd, loff_t off_in, int ofd, loff_t off_out, u64 size -= ret; off_in += ret; - off_out -= ret; + off_out += ret; }munmap (ptr, off_in + size);
Signature · 1 line
2.14.3
Arnaldo Carvalho de Melo
maintainerPATCH 6/32 perf evsel: Check if callchain is enabled before setting it up
In reply to Arnaldo Carvalho de MeloFrom: Arnaldo Carvalho de Melo <[email protected]>
The construct:
if (callchain_param) perf_evsel__config_callchain(evsel, opts, &callchain_param);
happens in several places, so make perf_evsel__config_callchain() work just like free(NULL), do nothing if param->enabled is not set.
--- tools/perf/util/evsel.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-)
tools/perf/util/evsel.c +11 -3
@@ -651,9 +651,9 @@ int perf_evsel__group_desc(struct perf_evsel *evsel, char *buf, size_t size)return ret; } -void perf_evsel__config_callchain (struct perf_evsel *evsel, -struct record_opts *opts, -struct callchain_param *param) +static void __perf_evsel__config_callchain (struct perf_evsel *evsel, +struct record_opts *opts, +struct callchain_param *param) {bool function =perf_evsel__is_function_event (evsel);struct perf_event_attr *attr = &evsel->attr;
@@ -699,6 +699,14 @@ void perf_evsel__config_callchain(struct perf_evsel *evsel, } } +void perf_evsel__config_callchain (struct perf_evsel *evsel, +struct record_opts *opts, +struct callchain_param *param) +{ +if (param->enabled) +return __perf_evsel__config_callchain (evsel, opts, param); +} +static void perf_evsel__reset_callgraph (struct perf_evsel *evsel,struct callchain_param *param)
Signature · 1 line
2.14.3
Arnaldo Carvalho de Melo
maintainerPATCH 7/32 perf trace: Fix setting of --call-graph/--max-stack for non-syscall events
In reply to Arnaldo Carvalho de MeloFrom: Arnaldo Carvalho de Melo <[email protected]>
The raw_syscalls:sys_{enter,exit} were first supported in 'perf trace', together with minor and major page faults, then we supported --call-graph, then --max-stack, but when the other tracepoints got supported, and bpf, etc, I forgot to make those global call-graph settings apply to them.
Fix it by realizing that the global --max-stack and --call-graph settings are done via:
OPT_CALLBACK(0, "call-graph", &trace.opts,
"record_mode[,record_size]", record_callchain_help,
&record_parse_callchain_opt),And then, when we go to parse the events in -e via:
OPT_CALLBACK('e', "event", &trace, "event",
"event/syscall selector. use 'perf list' to list available events", trace__parse_events_option),
And trace__parse_sevents_option() calls:
struct option o = OPT_CALLBACK('e', "event", &trace->evlist, "event",
"event selector. use 'perf list' to list available events",
parse_events_option);
err = parse_events_option(&o, lists[0], 0);parse_events_option() will override the global --call-graph and --max-stack if the "call-graph" and/or "max-stack" terms are in the event definition, such as in the probe_libc:inet_pton event in one of the examples below (-e probe_libc:inet_pton/max-stack=2).
Before:
# perf trace --mmap 1024 --call-graph dwarf -e sendto,probe_libc:inet_pton ping -6 -c 1 ::1
1.525 ( ): probe_libc:inet_pton:(7f77f3ac9350))
PING ::1(::1) 56 data bytes
64 bytes from ::1: icmp_seq=1 ttl=64 time=0.071 ms --- ::1 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms rtt min/avg/max/mdev = 0.071/0.071/0.071/0.000 ms
1.677 ( 0.081 ms): ping/31296 sendto(fd: 3, buff: 0x55681b652720, len: 64, addr: 0x55681b650640, addr_len: 28) = 64
__libc_sendto (/usr/lib64/libc-2.26.so)
[0xffffaa97e4bc9cef] (/usr/bin/ping)
[0xffffaa97e4bc656d] (/usr/bin/ping)
[0xffffaa97e4bc7d0a] (/usr/bin/ping)
[0xffffaa97e4bca447] (/usr/bin/ping)
[0xffffaa97e4bc2f91] (/usr/bin/ping)
__libc_start_main (/usr/lib64/libc-2.26.so)
[0xffffaa97e4bc3379] (/usr/bin/ping)#
After:
# perf trace --mmap 1024 --call-graph dwarf -e sendto,probe_libc:inet_pton ping -6 -c 1 ::1 PING ::1(::1) 56 data bytes 64 bytes from ::1: icmp_seq=1 ttl=64 time=0.089 ms
--- ::1 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms rtt min/avg/max/mdev = 0.089/0.089/0.089/0.000 ms
1.955 ( ): probe_libc:inet_pton:(7f383a311350))
__inet_pton (inlined)
gaih_inet.constprop.7 (/usr/lib64/libc-2.26.so)
__GI_getaddrinfo (inlined)
[0xffffaa5d91444f3f] (/usr/bin/ping)
__libc_start_main (/usr/lib64/libc-2.26.so)
[0xffffaa5d91445379] (/usr/bin/ping)
2.140 ( 0.101 ms): ping/32047 sendto(fd: 3, buff: 0x55a26edd0720, len: 64, addr: 0x55a26edce640, addr_len: 28) = 64
__libc_sendto (/usr/lib64/libc-2.26.so)
[0xffffaa5d9144bcef] (/usr/bin/ping)
[0xffffaa5d9144856d] (/usr/bin/ping)
[0xffffaa5d91449d0a] (/usr/bin/ping)
[0xffffaa5d9144c447] (/usr/bin/ping)
[0xffffaa5d91444f91] (/usr/bin/ping)
__libc_start_main (/usr/lib64/libc-2.26.so)
[0xffffaa5d91445379] (/usr/bin/ping)#
Same thing for --max-stack, the global one:
# perf trace --max-stack 3 -e sendto,probe_libc:inet_pton ping -6 -c 1 ::1 PING ::1(::1) 56 data bytes 64 bytes from ::1: icmp_seq=1 ttl=64 time=0.097 ms
--- ::1 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms rtt min/avg/max/mdev = 0.097/0.097/0.097/0.000 ms
1.577 ( ): probe_libc:inet_pton:(7f32f3957350))
__inet_pton (inlined)
gaih_inet.constprop.7 (/usr/lib64/libc-2.26.so)
__GI_getaddrinfo (inlined)
1.738 ( 0.108 ms): ping/32103 sendto(fd: 3, buff: 0x55c3132d7720, len: 64, addr: 0x55c3132d5640, addr_len: 28) = 64
__libc_sendto (/usr/lib64/libc-2.26.so)
[0xffffaa3cecf44cef] (/usr/bin/ping)
[0xffffaa3cecf4156d] (/usr/bin/ping)#
And then setting up a global setting (dwarf, max-stack=4), that will affect the raw_syscall:sys_enter for the 'sendto' syscall and that will be overriden in the probe_libc:inet_pton call to just one entry.
# perf trace --max-stack=4 --call-graph dwarf -e sendto -e probe_libc:inet_pton/max-stack=1/ ping -6 -c 1 ::1 PING ::1(::1) 56 data bytes 64 bytes from ::1: icmp_seq=1 ttl=64 time=0.090 ms
--- ::1 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms rtt min/avg/max/mdev = 0.090/0.090/0.090/0.000 ms
2.140 ( ): probe_libc:inet_pton:(7f9fe9337350))
__GI___inet_pton (/usr/lib64/libc-2.26.so)
2.283 ( 0.103 ms): ping/31804 sendto(fd: 3, buff: 0x55c7f3e19720, len: 64, addr: 0x55c7f3e17640, addr_len: 28) = 64
__libc_sendto (/usr/lib64/libc-2.26.so)
[0xffffaa380c402cef] (/usr/bin/ping)
[0xffffaa380c3ff56d] (/usr/bin/ping)
[0xffffaa380c400d0a] (/usr/bin/ping)#
Install iputils-debuginfo to get those /usr/bin/ping addresses resolved, those routines are not on its .dymsym nor .symtab :-)
--- tools/perf/builtin-trace.c | 20 +++++--------------- 1 file changed, 5 insertions(+), 15 deletions(-)
tools/perf/builtin-trace.c +5 -15
@@ -2222,6 +2222,9 @@ static int trace__add_syscall_newtp(struct trace *trace)if (perf_evsel__init_sc_tp_uint_field (sys_exit, ret)) goto out_delete_sys_exit; +perf_evsel__config_callchain (sys_enter, &trace->opts, &callchain_param); +perf_evsel__config_callchain (sys_exit, &trace->opts, &callchain_param); +perf_evlist__add (evlist, sys_enter);perf_evlist__add (evlist, sys_exit);
@@ -2318,6 +2321,7 @@ static int trace__run(struct trace *trace, int argc, const char **argv) pgfault_maj =perf_evsel__new_pgfault (PERF_COUNT_SW_PAGE_FAULTS_MAJ );if (pgfault_maj ==NULL ) goto out_error_mem; +perf_evsel__config_callchain (pgfault_maj, &trace->opts, &callchain_param);perf_evlist__add (evlist, pgfault_maj); }
@@ -2325,6 +2329,7 @@ static int trace__run(struct trace *trace, int argc, const char **argv) pgfault_min =perf_evsel__new_pgfault (PERF_COUNT_SW_PAGE_FAULTS_MIN );if (pgfault_min ==NULL ) goto out_error_mem; +perf_evsel__config_callchain (pgfault_min, &trace->opts, &callchain_param);perf_evlist__add (evlist, pgfault_min); }
@@ -2347,21 +2352,6 @@ static int trace__run(struct trace *trace, int argc, const char **argv)perf_evlist__config (evlist, &trace->opts,NULL ); -if (callchain_param.enabled) { -if (trace->syscalls.events.sys_exit) { -perf_evsel__config_callchain (trace->syscalls.events.sys_exit, - &trace->opts, &callchain_param); - } - -if (pgfault_maj) { -perf_evsel__config_callchain (pgfault_maj, &trace->opts, &callchain_param); - } - -if (pgfault_min) { -perf_evsel__config_callchain (pgfault_min, &trace->opts, &callchain_param); - } - } -signal (SIGCHLD , sig_handler);signal (SIGINT , sig_handler);
Signature · 1 line
2.14.3
Arnaldo Carvalho de Melo
maintainerPATCH 8/32 tools lib traceevent: Fix bad force_token escape sequence
In reply to Arnaldo Carvalho de MeloFrom: Michael Sartain <[email protected]>
Older kernels have a bug that creates invalid symbols. event-parse.c handles them by replacing them with a "%s" token. But the fix included an extra backslash, and "\%s" was added incorrectly.
--- tools/lib/traceevent/event-parse.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
tools/lib/traceevent/event-parse.c +1 -1
@@ -1094,7 +1094,7 @@ static enum event_type __read_token(char **tok)if (strcmp (*tok,"LOCAL_PR_FMT" ) ==0 ) {free (*tok); *tok =NULL ; -return force_token ("\"\%s\" " , tok); +return force_token ("\"%s\" " , tok); }else if (strcmp (*tok,"STA_PR_FMT" ) ==0 ) {free (*tok); *tok =NULL ;
Signature · 1 line
2.14.3
Arnaldo Carvalho de Melo
maintainerPATCH 9/32 tools lib traceevent: Show value of flags that have not been parsed
In reply to Arnaldo Carvalho de MeloFrom: "Steven Rostedt (VMware)" <[email protected]>
If the value contains bits that are not defined by print_flags() helper, then show the remaining bits. This aligns with the functionality of the kernel.
--- tools/lib/traceevent/event-parse.c | 5 +++++ 1 file changed, 5 insertions(+)
tools/lib/traceevent/event-parse.c +5 -0
@@ -3970,6 +3970,11 @@ static void print_str_arg(struct trace_seq *s, void *data, int size, val &= ~fval; } } +if (val) { +if (print && arg->flags.delim) +trace_seq_puts (s, arg->flags.delim); +trace_seq_printf (s,"0x%llx" , val); + }break ;case PRINT_SYMBOL : val =eval_num_arg (data, size, event, arg->symbol.field);
Signature · 1 line
2.14.3
Arnaldo Carvalho de Melo
maintainerPATCH 10/32 tools lib traceevent: Print value of unknown symbolic fields
In reply to Arnaldo Carvalho de MeloFrom: Jan Kiszka <[email protected]>
Aligns trace-cmd with the behavior of the kernel.
--- tools/lib/traceevent/event-parse.c | 2 ++ 1 file changed, 2 insertions(+)
tools/lib/traceevent/event-parse.c +2 -0
@@ -3985,6 +3985,8 @@ static void print_str_arg(struct trace_seq *s, void *data, int size,break ; } } +if (!flag) +trace_seq_printf (s,"0x%llx" , val);break ;case PRINT_HEX :case PRINT_HEX_STR :
Signature · 1 line
2.14.3
Arnaldo Carvalho de Melo
maintainerPATCH 11/32 tools lib traceevent: Simplify pointer print logic and fix %pF
In reply to Arnaldo Carvalho de MeloFrom: "Steven Rostedt (VMware)" <[email protected]>
When processing %pX in pretty_print(), simplify the logic slightly by incrementing the ptr to the format string if isalnum(ptr[1]) is true. This follows the logic a bit more closely to what is in the kernel.
Also, this fixes a small bug where %pF was not giving the offset of the function.
--- tools/lib/traceevent/event-parse.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-)
tools/lib/traceevent/event-parse.c +9 -8
@@ -4956,21 +4956,22 @@ static void pretty_print(struct trace_seq *s, void *data, int size, struct eventelse ls =2 ; -if (*(ptr+1 ) =='F' || *(ptr+1 ) =='f' || - *(ptr+1 ) =='S' || *(ptr+1 ) =='s' ) { +if (isalnum (ptr[1 ])) ptr++; + +if (*ptr =='F' || *ptr =='f' || + *ptr =='S' || *ptr =='s' ) { show_func = *ptr; - }else if (*(ptr+1 ) =='M' || *(ptr+1 ) =='m' ) { -print_mac_arg (s, *(ptr+1 ), data, size, event, arg); - ptr++; + }else if (*ptr =='M' || *ptr =='m' ) { +print_mac_arg (s, *ptr, data, size, event, arg); arg = arg->next;break ; - }else if (*(ptr+1 ) =='I' || *(ptr+1 ) =='i' ) { + }else if (*ptr =='I' || *ptr =='i' ) {int n; - n =print_ip_arg (s, ptr+1 , data, size, event, arg); + n =print_ip_arg (s, ptr, data, size, event, arg);if (n >0 ) { - ptr += n; + ptr += n -1 ; arg = arg->next;break ; }
Signature · 1 line
2.14.3
Arnaldo Carvalho de Melo
maintainerPATCH 12/32 tools lib traceevent: Handle new pointer processing of bprint strings
In reply to Arnaldo Carvalho de MeloFrom: "Steven Rostedt (VMware)" <[email protected]>
The Linux kernel printf() has some extended use cases that dereference the pointer. This is dangerouse for tracing because the pointer that is dereferenced can change or even be unmapped. It also causes issues when the trace data is extracted, because user space does not have access to the contents of the pointer even if it still exists.
To handle this, the kernel was updated to process these dereferenced pointers at the time they are recorded, and not post processed. Now they exist in the tracing buffer, and no dereference is needed at the time of reading the trace.
The event parsing library needs to handle this new case.
--- tools/lib/traceevent/event-parse.c | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+)
tools/lib/traceevent/event-parse.c +26 -0
@@ -4300,6 +4300,26 @@ static struct print_arg *make_bprint_args(char *fmt, void *data, int size, struc goto process_again;case 'p' : ls =1 ; +if (isalnum (ptr[1 ])) { + ptr++; +/* Check for special pointers */ +switch (*ptr) { +case 's' : +case 'S' : +case 'f' : +case 'F' : +break ; +default : +/* +* Older kernels do not process +* dereferenced pointers. +* Only process if the pointer +* value is a printable. +*/ +if (isprint (*(char *)bptr)) + goto process_string; + } + }/* fall through */ case 'd' :case 'u' :
@@ -4352,6 +4372,7 @@ static struct print_arg *make_bprint_args(char *fmt, void *data, int size, strucbreak ;case 's' : + process_string: arg =alloc_arg ();if (!arg) { do_warning_event(event, "%s(%d): not enough memory!",
@@ -4959,6 +4980,11 @@ static void pretty_print(struct trace_seq *s, void *data, int size, struct eventif (isalnum (ptr[1 ])) ptr++; +if (arg->type ==PRINT_BSTRING ) { +trace_seq_puts (s, arg->string.string); +break ; + } +if (*ptr =='F' || *ptr =='f' || *ptr =='S' || *ptr =='s' ) { show_func = *ptr;
Signature · 1 line
2.14.3
Arnaldo Carvalho de Melo
maintainerPATCH 13/32 tools lib traceevent: Show contents (in hex) of data of unrecognized type records
In reply to Arnaldo Carvalho de MeloFrom: "Steven Rostedt (VMware)" <[email protected]>
When a record has an unrecognized type, an error message is reported, but it would also be helpful to see the contents of that record. At least show what it is in hex, instead of just showing a blank line.
--- tools/lib/traceevent/event-parse.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-)
tools/lib/traceevent/event-parse.c +8 -2
@@ -5566,8 +5566,14 @@ void pevent_print_event(struct pevent *pevent, struct trace_seq *s, event =pevent_find_event_by_record (pevent, record);if (!event) { -do_warning ("ug! no event found for type %d" , -trace_parse_common_type (pevent, record->data)); +int i; +int type =trace_parse_common_type (pevent, record->data); + +do_warning ("ug! no event found for type %d" , type); +trace_seq_printf (s,"[UNKNOWN TYPE %d]" , type); +for (i =0 ; i < record->size; i++) +trace_seq_printf (s," %02x" , + ((unsigned char *)record->data)[i]);return ; }
Signature · 1 line
2.14.3
Arnaldo Carvalho de Melo
maintainerPATCH 14/32 tools lib traceevent: Use asprintf when possible
In reply to Arnaldo Carvalho de MeloFrom: Federico Vaga <[email protected]>
It makes the code clearer and less error prone.
clearer:
- less code
- the code is now using the same format to create strings dynamically
less error prone:
- no magic number +2 +9 +5 to compute the size
- no copy&paste of the strings to compute the size and to concatenate
The function asprintf is not POSIX standard but the program was already using it. Later it can be decided to use only POSIX functions, then we can easly replace all the asprintf(3) with a local implementation of that function.
--- tools/lib/traceevent/event-plugin.c | 24 +++++++++--------------- tools/lib/traceevent/parse-filter.c | 11 ++++------- 2 files changed, 13 insertions(+), 22 deletions(-)
tools/lib/traceevent/event-plugin.c +9 -15
@@ -120,12 +120,12 @@ char **traceevent_plugin_list_options(void)for (op = reg->options; op->name; op++) {char *alias = op->plugin_alias ? op->plugin_alias : op->file;char **temp = list; +int ret; - name =malloc (strlen (op->name) +strlen (alias) +2 ); -if (!name) + ret =asprintf (&name,"%s:%s" , alias, op->name); +if (ret <0 ) goto err; -sprintf (name,"%s:%s" , alias, op->name); list =realloc (list, count +2 );if (!list) { list = temp;
@@ -290,17 +290,14 @@ load_plugin(struct pevent *pevent, const char *path,const char *alias;char *plugin;void *handle; +int ret; - plugin =malloc (strlen (path) +strlen (file) +2 ); -if (!plugin) { + ret =asprintf (&plugin,"%s/%s" , path, file); +if (ret <0 ) {warning ("could not allocate plugin memory\n" );return ; } -strcpy (plugin, path); -strcat (plugin,"/" ); -strcat (plugin, file); - handle =dlopen (plugin,RTLD_NOW |RTLD_GLOBAL );if (!handle) { warning("could not load plugin '%s'\n%s\n",
@@ -391,6 +388,7 @@ load_plugins(struct pevent *pevent, const char *suffix,char *home;char *path;char *envdir; +int ret;if (pevent->flags &PEVENT_DISABLE_PLUGINS )return ;
@@ -421,16 +419,12 @@ load_plugins(struct pevent *pevent, const char *suffix,if (!home)return ; - path =malloc (strlen (home) +strlen (LOCAL_PLUGIN_DIR ) +2 ); -if (!path) { + ret =asprintf (&path,"%s/%s" , home,LOCAL_PLUGIN_DIR ); +if (ret <0 ) {warning ("could not allocate plugin memory\n" );return ; } -strcpy (path, home); -strcat (path,"/" ); -strcat (path,LOCAL_PLUGIN_DIR ); -load_plugins_dir (pevent, suffix, path, load_plugin, data);free (path);
tools/lib/traceevent/parse-filter.c +4 -7
@@ -287,12 +287,10 @@ find_event(struct pevent *pevent, struct event_list **events, sys_name =NULL ; } - reg =malloc (strlen (event_name) +3 ); -if (reg ==NULL ) + ret =asprintf (®,"^%s$" , event_name); +if (ret <0 )return PEVENT_ERRNO__MEM_ALLOC_FAILED ; -sprintf (reg,"^%s$" , event_name); - ret =regcomp (&ereg, reg,REG_ICASE |REG_NOSUB );free (reg);
@@ -300,13 +298,12 @@ find_event(struct pevent *pevent, struct event_list **events,return PEVENT_ERRNO__INVALID_EVENT_NAME ;if (sys_name) { - reg =malloc (strlen (sys_name) +3 ); -if (reg ==NULL ) { + ret =asprintf (®,"^%s$" , sys_name); +if (ret <0 ) {regfree (&ereg);return PEVENT_ERRNO__MEM_ALLOC_FAILED ; } -sprintf (reg,"^%s$" , sys_name); ret =regcomp (&sreg, reg,REG_ICASE |REG_NOSUB );free (reg);if (ret) {
Signature · 1 line
2.14.3
Arnaldo Carvalho de Melo
maintainerPATCH 15/32 tools lib traceevent: Add UL suffix to MISSING_EVENTS
In reply to Arnaldo Carvalho de MeloFrom: Michael Sartain <[email protected]>
Add UL suffix to MISSING_EVENTS since ints shouldn't be left shifted by 31.
--- tools/lib/traceevent/kbuffer-parse.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
tools/lib/traceevent/kbuffer-parse.c +2 -2
@@ -24,8 +24,8 @@#include "kbuffer.h" -#define MISSING_EVENTS (1 << 31) -#define MISSING_STORED (1 << 30) +#define MISSING_EVENTS (1UL << 31) +#define MISSING_STORED (1UL << 30)#define COMMIT_MASK ((1 << 27) - 1)
Signature · 1 line
2.14.3
Arnaldo Carvalho de Melo
maintainerPATCH 16/32 tools lib traceevent: Fix missing break in FALSE case of pevent_filter_clear_trivial()
In reply to Arnaldo Carvalho de MeloFrom: Taeung Song <[email protected]>
Currently the FILTER_TRIVIAL_FALSE case has a missing break statement, if the trivial type is FALSE, it will also run into the TRUE case, and always be skipped as the TRUE statement will continue the loop on the inverse condition of the FALSE statement.
--- tools/lib/traceevent/parse-filter.c | 1 + 1 file changed, 1 insertion(+)
tools/lib/traceevent/parse-filter.c +1 -0
@@ -1631,6 +1631,7 @@ int pevent_filter_clear_trivial(struct event_filter *filter,case FILTER_TRIVIAL_FALSE :if (filter_type->filter->boolean.value)continue ; +break ;case FILTER_TRIVIAL_TRUE :if (!filter_type->filter->boolean.value)continue ;
Signature · 1 line
2.14.3
Arnaldo Carvalho de Melo
maintainerPATCH 17/32 tools lib traceevent: Fix get_field_str() for dynamic strings
In reply to Arnaldo Carvalho de MeloFrom: "Steven Rostedt (VMware)" <[email protected]>
If a field is a dynamic string, get_field_str() returned just the offset/size value and not the string. Have it parse the offset/size correctly to return the actual string. Otherwise filtering fails when trying to filter fields that are dynamic strings.
--- tools/lib/traceevent/parse-filter.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-)
tools/lib/traceevent/parse-filter.c +9 -1
@@ -1877,17 +1877,25 @@ static const char *get_field_str(struct filter_arg *arg, struct pevent_record *rstruct pevent *pevent;unsigned long long addr;const char *val =NULL ; +unsigned int size;char hex[64 ];/* If the field is not a string convert it */ if (arg->str.field->flags &FIELD_IS_STRING ) { val = record->data + arg->str.field->offset; + size = arg->str.field->size; + +if (arg->str.field->flags &FIELD_IS_DYNAMIC ) { + addr = *(unsigned int *)val; + val = record->data + (addr &0xffff ); + size = addr >>16 ; + }/* * We need to copy the data since we can't be sure the field * is null terminated. */ -if (*(val + arg->str.field->size -1 )) { +if (*(val + size -1 )) {/* copy it */ memcpy (arg->str.buffer, val, arg->str.field->size);/* the buffer is already NULL terminated */
Signature · 1 line
2.14.3
Arnaldo Carvalho de Melo
maintainerPATCH 18/32 perf tools: Add ARM Statistical Profiling Extensions (SPE) support
In reply to Arnaldo Carvalho de MeloFrom: Kim Phillips <[email protected]>
'perf record' and 'perf report --dump-raw-trace' supported in this release.
Example usage:
# perf record -e arm_spe/ts_enable=1,pa_enable=1/ dd if=/dev/zero of=/dev/null count=10000 # perf report --dump-raw-trace
Note that the perf.data file is portable, so the report can be run on another architecture host if necessary.
Output will contain raw SPE data and its textual representation, such as:
0x5c8 [0x30]: PERF_RECORD_AUXTRACE size: 0x200000 offset: 0 ref: 0x1891ad0e idx: 1 tid: 2227 cpu: 1 .
. ... ARM SPE data: size 2097152 bytes
. 00000000: 49 00 LD . 00000002: b2 c0 3b 29 0f 00 00 ff ff VA 0xffff00000f293bc0 . 0000000b: b3 c0 eb 24 fb 00 00 00 80 PA 0xfb24ebc0 ns=1 . 00000014: 9a 00 00 LAT 0 XLAT . 00000017: 42 16 EV RETIRED L1D-ACCESS TLB-ACCESS . 00000019: b0 00 c4 15 08 00 00 ff ff PC 0xff00000815c400 el3 ns=1 . 00000022: 98 00 00 LAT 0 TOT . 00000025: 71 36 6c 21 2c 09 00 00 00 TS 39395093558 . 0000002e: 49 00 LD . 00000030: b2 80 3c 29 0f 00 00 ff ff VA 0xffff00000f293c80 . 00000039: b3 80 ec 24 fb 00 00 00 80 PA 0xfb24ec80 ns=1 . 00000042: 9a 00 00 LAT 0 XLAT . 00000045: 42 16 EV RETIRED L1D-ACCESS TLB-ACCESS . 00000047: b0 f4 11 16 08 00 00 ff ff PC 0xff0000081611f4 el3 ns=1 . 00000050: 98 00 00 LAT 0 TOT . 00000053: 71 36 6c 21 2c 09 00 00 00 TS 39395093558 . 0000005c: 48 00 INSN-OTHER . 0000005e: 42 02 EV RETIRED . 00000060: b0 2c ef 7f 08 00 00 ff ff PC 0xff0000087fef2c el3 ns=1 . 00000069: 98 00 00 LAT 0 TOT . 0000006c: 71 d1 6f 21 2c 09 00 00 00 TS 39395094481
...
Other release notes:
- applies to acme's perf/{core,urgent} branches, likely elsewhere
- Report is self-contained within the tool. Record requires enabling the kernel SPE driver by setting CONFIG_ARM_SPE_PMU.
- The intel-bts implementation was used as a starting point; its min/default/max buffer sizes and power of 2 pages granularity need to be revisited for ARM SPE
- Recording across multiple SPE clusters/domains not supported
- Snapshot support (record -S), and conversion to native perf events (e.g., via 'perf inject --itrace'), are also not supported
- Technically both cs-etm and spe can be used simultaneously, however disabled for simplicity in this release
--- tools/perf/arch/arm/util/auxtrace.c | 77 +++++- tools/perf/arch/arm/util/pmu.c | 6 + tools/perf/arch/arm64/util/Build | 3 +- tools/perf/arch/arm64/util/arm-spe.c | 225 +++++++++++++++++ tools/perf/util/Build | 2 + tools/perf/util/arm-spe-pkt-decoder.c | 462 ++++++++++++++++++++++++++++++++++ tools/perf/util/arm-spe-pkt-decoder.h | 43 ++++ tools/perf/util/arm-spe.c | 231 +++++++++++++++++ tools/perf/util/arm-spe.h | 31 +++ tools/perf/util/auxtrace.c | 3 + tools/perf/util/auxtrace.h | 1 + 11 files changed, 1077 insertions(+), 7 deletions(-) create mode 100644 tools/perf/arch/arm64/util/arm-spe.c create mode 100644 tools/perf/util/arm-spe-pkt-decoder.c create mode 100644 tools/perf/util/arm-spe-pkt-decoder.h create mode 100644 tools/perf/util/arm-spe.c create mode 100644 tools/perf/util/arm-spe.h
tools/perf/arch/arm/util/auxtrace.c +71 -6
@@ -22,6 +22,42 @@#include "../../util/evlist.h" #include "../../util/pmu.h" #include "cs-etm.h" +#include "arm-spe.h" + +static struct perf_pmu **find_all_arm_spe_pmus (int *nr_spes,int *err) +{ +struct perf_pmu **arm_spe_pmus =NULL ; +int ret, i, nr_cpus =sysconf (_SC_NPROCESSORS_CONF); +/* arm_spe_xxxxxxxxx\0 */ +char arm_spe_pmu_name[sizeof (ARM_SPE_PMU_NAME ) +10 ]; + + arm_spe_pmus =zalloc (sizeof (struct perf_pmu *) * nr_cpus); +if (!arm_spe_pmus) { +pr_err ("spes alloc failed\n" ); + *err = -ENOMEM ; +return NULL ; + } + +for (i =0 ; i < nr_cpus; i++) { + ret =sprintf (arm_spe_pmu_name,"%s%d" ,ARM_SPE_PMU_NAME , i); +if (ret <0 ) { +pr_err ("sprintf failed\n" ); + *err = -ENOMEM ; +return NULL ; + } + + arm_spe_pmus[*nr_spes] =perf_pmu__find (arm_spe_pmu_name); +if (arm_spe_pmus[*nr_spes]) { +pr_debug2 ("%s %d: arm_spe_pmu %d type %d name %s\n" , + __func__, __LINE__, *nr_spes, + arm_spe_pmus[*nr_spes]->type, + arm_spe_pmus[*nr_spes]->name); + (*nr_spes)++; + } + } + +return arm_spe_pmus; +}struct auxtrace_record *auxtrace_record__init (struct perf_evlist *evlist,int *err)
@@ -29,22 +65,51 @@ struct auxtrace_recordstruct perf_pmu *cs_etm_pmu;struct perf_evsel *evsel;bool found_etm = false; +bool found_spe = false; +static struct perf_pmu **arm_spe_pmus =NULL ; +static int nr_spes =0 ; +int i; + +if (!evlist) +return NULL ; cs_etm_pmu =perf_pmu__find (CORESIGHT_ETM_PMU_NAME ); -if (evlist) { -evlist__for_each_entry (evlist, evsel) { -if (cs_etm_pmu && - evsel->attr.type == cs_etm_pmu->type) - found_etm = true; +if (!arm_spe_pmus) + arm_spe_pmus =find_all_arm_spe_pmus (&nr_spes, err); + +evlist__for_each_entry (evlist, evsel) { +if (cs_etm_pmu && + evsel->attr.type == cs_etm_pmu->type) + found_etm = true; + +if (!nr_spes) +continue ; + +for (i =0 ; i < nr_spes; i++) { +if (evsel->attr.type == arm_spe_pmus[i]->type) { + found_spe = true; +break ; + } } } +if (found_etm && found_spe) { +pr_err ("Concurrent ARM Coresight ETM and SPE operation not currently supported\n" ); + *err = -EOPNOTSUPP ; +return NULL ; + } +if (found_etm)return cs_etm_record_init (err); +#if defined(__aarch64__) +if (found_spe) +return arm_spe_recording_init (err, arm_spe_pmus[i]); +#endif +/* -* Clear 'err' even if we haven't found a cs_etm event - that way perf +* Clear 'err' even if we haven't found an event - that way perf * record can still be used even if tracers aren't present. The NULL * return value will take care of telling the infrastructure HW tracing * isn't available.
tools/perf/arch/arm/util/pmu.c +6 -0
@@ -20,6 +20,7 @@#include <linux/perf_event.h> #include "cs-etm.h" +#include "arm-spe.h" #include "../../util/pmu.h" struct perf_event_attr
@@ -30,7 +31,12 @@ struct perf_event_attr/* add ETM default config here */ pmu->selectable = true; pmu->set_drv_config = cs_etm_set_drv_config; +#if defined(__aarch64__) + } else if (strstarts(pmu->name, ARM_SPE_PMU_NAME)) { +return arm_spe_pmu_default_config (pmu); +#endif } +#endif return NULL; }
tools/perf/arch/arm64/util/Build +2 -1
@@ -5,4 +5,5 @@ libperf-$(CONFIG_LOCAL_LIBUNWIND) += unwind-libunwind.o libperf-$(CONFIG_AUXTRACE) += ../../arm/util/pmu.o \ ../../arm/util/auxtrace.o \ - ../../arm/util/cs-etm.o + ../../arm/util/cs-etm.o \ + arm-spe.o
tools/perf/arch/arm64/util/arm-spe.c new file +225 -0
225 lines not on this page · raw message
tools/perf/util/Build +2 -0
@@ -86,6 +86,8 @@ libperf-$(CONFIG_AUXTRACE) += auxtrace.o libperf-$(CONFIG_AUXTRACE) += intel-pt-decoder/ libperf-$(CONFIG_AUXTRACE) += intel-pt.o libperf-$(CONFIG_AUXTRACE) += intel-bts.o +libperf-$(CONFIG_AUXTRACE) += arm-spe.o +libperf-$(CONFIG_AUXTRACE) += arm-spe-pkt-decoder.o libperf-y += parse-branch-options.o libperf-y += dump-insn.o libperf-y += parse-regs-options.o
tools/perf/util/arm-spe-pkt-decoder.c new file +462 -0
462 lines not on this page · raw message
tools/perf/util/arm-spe-pkt-decoder.h new file +43 -0
43 lines not on this page · raw message
tools/perf/util/arm-spe.c new file +231 -0
231 lines not on this page · raw message
tools/perf/util/arm-spe.h new file +31 -0
@@ -0,0 +1,31 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* +* Arm Statistical Profiling Extensions (SPE) support +* Copyright (c) 2017-2018, Arm Ltd. +*/ + +#ifndef INCLUDE__PERF_ARM_SPE_H__ +#define INCLUDE__PERF_ARM_SPE_H__ + +#define ARM_SPE_PMU_NAME "arm_spe_" + +enum { +ARM_SPE_PMU_TYPE , +ARM_SPE_PER_CPU_MMAPS , +ARM_SPE_AUXTRACE_PRIV_MAX , +}; + +#define ARM_SPE_AUXTRACE_PRIV_SIZE (ARM_SPE_AUXTRACE_PRIV_MAX * sizeof(u64)) + +union perf_event ; +struct perf_session ; +struct perf_pmu ; + +struct auxtrace_record *arm_spe_recording_init (int *err, +struct perf_pmu *arm_spe_pmu); + +int arm_spe_process_auxtrace_info (union perf_event *event, +struct perf_session *session); + +struct perf_event_attr *arm_spe_pmu_default_config (struct perf_pmu *arm_spe_pmu); +#endif
tools/perf/util/auxtrace.c +3 -0
@@ -54,6 +54,7 @@#include "intel-pt.h" #include "intel-bts.h" +#include "arm-spe.h" #include "sane_ctype.h" #include "symbol/kallsyms.h"
@@ -910,6 +911,8 @@ int perf_event__process_auxtrace_info(struct perf_tool *tool __maybe_unused,return intel_pt_process_auxtrace_info (event, session);case PERF_AUXTRACE_INTEL_BTS :return intel_bts_process_auxtrace_info (event, session); +case PERF_AUXTRACE_ARM_SPE : +return arm_spe_process_auxtrace_info (event, session);case PERF_AUXTRACE_CS_ETM :case PERF_AUXTRACE_UNKNOWN :default :
tools/perf/util/auxtrace.h +1 -0
@@ -43,6 +43,7 @@ enum auxtrace_type {PERF_AUXTRACE_INTEL_PT ,PERF_AUXTRACE_INTEL_BTS ,PERF_AUXTRACE_CS_ETM , + PERF_AUXTRACE_ARM_SPE, }; enum itrace_period_type {
Signature · 1 line
2.14.3
Arnaldo Carvalho de Melo
maintainerPATCH 19/32 perf callchain: Fix attr.sample_max_stack setting
In reply to Arnaldo Carvalho de MeloFrom: Arnaldo Carvalho de Melo <[email protected]>
When setting the "dwarf" unwinder for a specific event and not specifying the max-stack, the attr.sample_max_stack ended up using an uninitialized callchain_param.max_stack, fix it by using designated initializers for that callchain_param variable, zeroing all non explicitely initialized struct members.
Here is what happened:
# perf trace -vv --no-syscalls --max-stack 4 -e probe_libc:inet_pton/call-graph=dwarf/ ping -6 -c 1 ::1
callchain: type DWARF
callchain: stack dump size 8192
perf_event_attr:
type 2
size 112
config 0x730
{ sample_period, sample_freq } 1
sample_type IP|TID|TIME|ADDR|CALLCHAIN|CPU|PERIOD|RAW|REGS_USER|STACK_USER|DATA_SRC
exclude_callchain_user 1
{ wakeup_events, wakeup_watermark } 1
sample_regs_user 0xff0fff
sample_stack_user 8192
sample_max_stack 50656
sys_perf_event_open failed, error -75
Value too large for defined data type
# perf trace -vv --no-syscalls --max-stack 4 -e probe_libc:inet_pton/call-graph=dwarf/ ping -6 -c 1 ::1
callchain: type DWARF
callchain: stack dump size 8192
perf_event_attr:
type 2
size 112
config 0x730
sample_type IP|TID|TIME|ADDR|CALLCHAIN|CPU|PERIOD|RAW|REGS_USER|STACK_USER|DATA_SRC
exclude_callchain_user 1
sample_regs_user 0xff0fff
sample_stack_user 8192
sample_max_stack 30448
sys_perf_event_open failed, error -75
Value too large for defined data type
#Now the attr.sample_max_stack is set to zero and the above works as expected:
# perf trace --no-syscalls --max-stack 4 -e probe_libc:inet_pton/call-graph=dwarf/ ping -6 -c 1 ::1 PING ::1(::1) 56 data bytes 64 bytes from ::1: icmp_seq=1 ttl=64 time=0.072 ms
--- ::1 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms rtt min/avg/max/mdev = 0.072/0.072/0.072/0.000 ms
0.000 probe_libc:inet_pton:(7feb7a998350))
__inet_pton (inlined)
gaih_inet.constprop.7 (/usr/lib64/libc-2.26.so)
__GI_getaddrinfo (inlined)
[0xffffaa39b6108f3f] (/usr/bin/ping)#
--- tools/perf/util/evsel.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
tools/perf/util/evsel.c +4 -4
@@ -731,14 +731,14 @@ static void apply_config_terms(struct perf_evsel *evsel,struct perf_evsel_config_term *term;struct list_head *config_terms = &evsel->config_terms;struct perf_event_attr *attr = &evsel->attr; -struct callchain_param param; +/* callgraph default */ +struct callchain_param param = { + .record_mode = callchain_param.record_mode, + };u32 dump_size =0 ;int max_stack =0 ;const char *callgraph_buf =NULL ; -/* callgraph default */ - param.record_mode = callchain_param.record_mode; -list_for_each_entry (term, config_terms, list) {switch (term->type) {case PERF_EVSEL__CONFIG_TERM_PERIOD :
Signature · 1 line
2.14.3
Arnaldo Carvalho de Melo
maintainerPATCH 20/32 perf unwind: Do not look just at the global callchain_param.record_mode
In reply to Arnaldo Carvalho de MeloFrom: Arnaldo Carvalho de Melo <[email protected]>
When setting up DWARF callchains on specific events, without using 'record' or 'trace' --call-graph, but instead doing it like:
perf trace -e cycles/call-graph=dwarf/
The unwind__prepare_access() call in thread__insert_map() when we process PERF_RECORD_MMAP(2) metadata events were not being performed, precluding us from using per-event DWARF callchains, handling them just when we asked for all events to be DWARF, using "--call-graph dwarf".
We do it in the PERF_RECORD_MMAP because we have to look at one of the executable maps to figure out the executable type (64-bit, 32-bit) of the DSO laid out in that mmap. Also to look at the architecture where the perf.data file was recorded.
All this probably should be deferred to when we process a sample for some thread that has callchains, so that we do this processing only for the threads with samples, not for all of them.
For now, fix using DWARF on specific events.
Before:
# perf trace --no-syscalls -e probe_libc:inet_pton/call-graph=dwarf/ ping -6 -c 1 ::1 PING ::1(::1) 56 data bytes 64 bytes from ::1: icmp_seq=1 ttl=64 time=0.048 ms
--- ::1 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms rtt min/avg/max/mdev = 0.048/0.048/0.048/0.000 ms
0.000 probe_libc:inet_pton:(7fe9597bb350))
Problem processing probe_libc:inet_pton callchain, skipping... #
After:
# perf trace --no-syscalls -e probe_libc:inet_pton/call-graph=dwarf/ ping -6 -c 1 ::1 PING ::1(::1) 56 data bytes 64 bytes from ::1: icmp_seq=1 ttl=64 time=0.060 ms
--- ::1 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms rtt min/avg/max/mdev = 0.060/0.060/0.060/0.000 ms
0.000 probe_libc:inet_pton:(7fd4aa930350))
__inet_pton (inlined)
gaih_inet.constprop.7 (/usr/lib64/libc-2.26.so)
__GI_getaddrinfo (inlined)
[0xffffaa804e51af3f] (/usr/bin/ping)
__libc_start_main (/usr/lib64/libc-2.26.so)
[0xffffaa804e51b379] (/usr/bin/ping)
#
# perf trace --call-graph=dwarf --no-syscalls -e probe_libc:inet_pton/call-graph=dwarf/ ping -6 -c 1 ::1
PING ::1(::1) 56 data bytes
64 bytes from ::1: icmp_seq=1 ttl=64 time=0.057 ms --- ::1 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms rtt min/avg/max/mdev = 0.057/0.057/0.057/0.000 ms
0.000 probe_libc:inet_pton:(7f9363b9e350))
__inet_pton (inlined)
gaih_inet.constprop.7 (/usr/lib64/libc-2.26.so)
__GI_getaddrinfo (inlined)
[0xffffa9e8a14e0f3f] (/usr/bin/ping)
__libc_start_main (/usr/lib64/libc-2.26.so)
[0xffffa9e8a14e1379] (/usr/bin/ping)
#
# perf trace --call-graph=fp --no-syscalls -e probe_libc:inet_pton/call-graph=dwarf/ ping -6 -c 1 ::1
PING ::1(::1) 56 data bytes
64 bytes from ::1: icmp_seq=1 ttl=64 time=0.077 ms --- ::1 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms rtt min/avg/max/mdev = 0.077/0.077/0.077/0.000 ms
0.000 probe_libc:inet_pton:(7f4947e1c350))
__inet_pton (inlined)
gaih_inet.constprop.7 (/usr/lib64/libc-2.26.so)
__GI_getaddrinfo (inlined)
[0xffffaa716d88ef3f] (/usr/bin/ping)
__libc_start_main (/usr/lib64/libc-2.26.so)
[0xffffaa716d88f379] (/usr/bin/ping)
#
# perf trace --no-syscalls -e probe_libc:inet_pton/call-graph=fp/ ping -6 -c 1 ::1
PING ::1(::1) 56 data bytes
64 bytes from ::1: icmp_seq=1 ttl=64 time=0.078 ms --- ::1 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms rtt min/avg/max/mdev = 0.078/0.078/0.078/0.000 ms
0.000 probe_libc:inet_pton:(7fa157696350))
__GI___inet_pton (/usr/lib64/libc-2.26.so)
getaddrinfo (/usr/lib64/libc-2.26.so)
[0xffffa9ba39c74f40] (/usr/bin/ping)#
--- tools/perf/builtin-c2c.c | 5 +++-- tools/perf/builtin-report.c | 5 +++-- tools/perf/builtin-script.c | 5 +++-- tools/perf/tests/dwarf-unwind.c | 1 + tools/perf/util/callchain.c | 10 ++++++++++ tools/perf/util/callchain.h | 2 ++ tools/perf/util/unwind-libunwind-local.c | 9 +++------ 7 files changed, 25 insertions(+), 12 deletions(-)
tools/perf/builtin-c2c.c +3 -2
@@ -2390,9 +2390,10 @@ static int setup_callchain(struct perf_evlist *evlist)enum perf_call_graph_mode mode =CALLCHAIN_NONE ;if ((sample_type &PERF_SAMPLE_REGS_USER ) && - (sample_type &PERF_SAMPLE_STACK_USER )) + (sample_type &PERF_SAMPLE_STACK_USER )) { mode =CALLCHAIN_DWARF ; -else if (sample_type &PERF_SAMPLE_BRANCH_STACK ) + dwarf_callchain_users = true; + }else if (sample_type &PERF_SAMPLE_BRANCH_STACK ) mode =CALLCHAIN_LBR ;else if (sample_type &PERF_SAMPLE_CALLCHAIN ) mode =CALLCHAIN_FP ;
tools/perf/builtin-report.c +3 -2
@@ -338,9 +338,10 @@ static int report__setup_sample_type(struct report *rep)if (symbol_conf.use_callchain || symbol_conf.cumulate_callchain) {if ((sample_type &PERF_SAMPLE_REGS_USER ) && - (sample_type &PERF_SAMPLE_STACK_USER )) + (sample_type &PERF_SAMPLE_STACK_USER )) { callchain_param.record_mode =CALLCHAIN_DWARF ; -else if (sample_type &PERF_SAMPLE_BRANCH_STACK ) + dwarf_callchain_users = true; + }else if (sample_type &PERF_SAMPLE_BRANCH_STACK ) callchain_param.record_mode =CALLCHAIN_LBR ;else callchain_param.record_mode =CALLCHAIN_FP ;
tools/perf/builtin-script.c +3 -2
@@ -2919,9 +2919,10 @@ static void script__setup_sample_type(struct perf_script *script)if (symbol_conf.use_callchain || symbol_conf.cumulate_callchain) {if ((sample_type &PERF_SAMPLE_REGS_USER ) && - (sample_type &PERF_SAMPLE_STACK_USER )) + (sample_type &PERF_SAMPLE_STACK_USER )) { callchain_param.record_mode =CALLCHAIN_DWARF ; -else if (sample_type &PERF_SAMPLE_BRANCH_STACK ) + dwarf_callchain_users = true; + }else if (sample_type &PERF_SAMPLE_BRANCH_STACK ) callchain_param.record_mode =CALLCHAIN_LBR ;else callchain_param.record_mode =CALLCHAIN_FP ;
tools/perf/tests/dwarf-unwind.c +1 -0
@@ -173,6 +173,7 @@ int test__dwarf_unwind(struct test *test __maybe_unused, int subtest __maybe_unu } callchain_param.record_mode =CALLCHAIN_DWARF ; + dwarf_callchain_users = true;if (init_live_machine (machine)) {pr_err ("Could not init machine\n" );
tools/perf/util/callchain.c +10 -0
@@ -37,6 +37,15 @@ struct callchain_param callchain_param = { CALLCHAIN_PARAM_DEFAULT }; +/* +* Are there any events usind DWARF callchains? +* +* I.e. +* +* -e cycles/call-graph=dwarf/ +*/ +bool dwarf_callchain_users; +struct callchain_param callchain_param_default = {CALLCHAIN_PARAM_DEFAULT };
@@ -265,6 +274,7 @@ int parse_callchain_record(const char *arg, struct callchain_param *param) ret =0 ; param->record_mode =CALLCHAIN_DWARF ; param->dump_size = default_stack_dump_size; + dwarf_callchain_users = true; tok =strtok_r (NULL ,"," , &saveptr);if (tok) {
tools/perf/util/callchain.h +2 -0
@@ -89,6 +89,8 @@ enum chain_value { CCVAL_COUNT, }; +extern bool dwarf_callchain_users; +struct callchain_param {bool enabled;enum perf_call_graph_mode record_mode;
tools/perf/util/unwind-libunwind-local.c +3 -6
@@ -631,9 +631,8 @@ static unw_accessors_t accessors = {static int _unwind__prepare_access (struct thread *thread) { -if (callchain_param.record_mode !=CALLCHAIN_DWARF ) +if (!dwarf_callchain_users)return 0 ; - thread->addr_space =unw_create_addr_space (&accessors,0 );if (!thread->addr_space) {pr_err ("unwind: Can't create unwind address space.\n" );
@@ -646,17 +645,15 @@ static int _unwind__prepare_access(struct thread *thread)static void _unwind__flush_access (struct thread *thread) { -if (callchain_param.record_mode !=CALLCHAIN_DWARF ) +if (!dwarf_callchain_users)return ; -unw_flush_cache (thread->addr_space,0 ,0 ); }static void _unwind__finish_access (struct thread *thread) { -if (callchain_param.record_mode !=CALLCHAIN_DWARF ) +if (!dwarf_callchain_users)return ; -unw_destroy_addr_space (thread->addr_space); }
Signature · 1 line
2.14.3
Arnaldo Carvalho de Melo
maintainerPATCH 21/32 perf trace: Setup DWARF callchains for non-syscall events when --max-stack is used
In reply to Arnaldo Carvalho de MeloFrom: Arnaldo Carvalho de Melo <[email protected]>
If we use:
perf trace --max-stack=4
then the syscall events will use DWARF callchains, when available (libunwind enabled in the build) and the printing will stop at 4 levels.
When we introduced support for tracepoint events this ended up not applying for them, fix it.
Before:
# perf trace --call-graph=dwarf --no-syscalls -e probe_libc:inet_pton ping -6 -c 1 ::1 PING ::1(::1) 56 data bytes 64 bytes from ::1: icmp_seq=1 ttl=64 time=0.058 ms
--- ::1 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms rtt min/avg/max/mdev = 0.058/0.058/0.058/0.000 ms
0.000 probe_libc:inet_pton:(7fc6c2a16350))
#
After:
# perf trace --call-graph=dwarf --no-syscalls -e probe_libc:inet_pton ping -6 -c 1 ::1 PING ::1(::1) 56 data bytes 64 bytes from ::1: icmp_seq=1 ttl=64 time=0.087 ms
--- ::1 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms rtt min/avg/max/mdev = 0.087/0.087/0.087/0.000 ms
0.000 probe_libc:inet_pton:(7fbf9a041350))
__inet_pton (inlined)
gaih_inet.constprop.7 (/usr/lib64/libc-2.26.so)
__GI_getaddrinfo (inlined)
[0xffffaa947cb67f3f] (/usr/bin/ping)
__libc_start_main (/usr/lib64/libc-2.26.so)
[0xffffaa947cb68379] (/usr/bin/ping)#
--- tools/perf/builtin-trace.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
tools/perf/builtin-trace.c +3 -2
@@ -2350,7 +2350,7 @@ static int trace__run(struct trace *trace, int argc, const char **argv) goto out_delete_evlist; } -perf_evlist__config (evlist, &trace->opts,NULL ); +perf_evlist__config (evlist, &trace->opts, &callchain_param);signal (SIGCHLD , sig_handler);signal (SIGINT , sig_handler);
@@ -3065,8 +3065,9 @@ int cmd_trace(int argc, const char **argv) }#ifdef HAVE_DWARF_UNWIND_SUPPORT -if ((trace.min_stack || max_stack_user_set) && !callchain_param.enabled && trace.trace_syscalls) +if ((trace.min_stack || max_stack_user_set) && !callchain_param.enabled) {record_opts__parse_callchain (&trace.opts, &callchain_param,"dwarf" , false); + }#endif if (callchain_param.enabled) {
Signature · 1 line
2.14.3
Arnaldo Carvalho de Melo
maintainerPATCH 22/32 perf trace: Allow overriding global --max-stack per event
In reply to Arnaldo Carvalho de MeloFrom: Arnaldo Carvalho de Melo <[email protected]>
The per-event max-stack setting wasn't overriding the global --max-stack setting:
# perf trace --no-syscalls --max-stack 4 -e probe_libc:inet_pton/call-graph=dwarf,max-stack=2/ ping -6 -c 1 ::1 PING ::1(::1) 56 data bytes 64 bytes from ::1: icmp_seq=1 ttl=64 time=0.072 ms
--- ::1 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms rtt min/avg/max/mdev = 0.072/0.072/0.072/0.000 ms
0.000 probe_libc:inet_pton:(7feb7a998350))
__inet_pton (inlined)
gaih_inet.constprop.7 (/usr/lib64/libc-2.26.so)
__GI_getaddrinfo (inlined)
[0xffffaa39b6108f3f] (/usr/bin/ping)#
Fix it:
# perf trace --no-syscalls --max-stack 4 -e probe_libc:inet_pton/call-graph=dwarf,max-stack=2/ ping -6 -c 1 ::1 PING ::1(::1) 56 data bytes 64 bytes from ::1: icmp_seq=1 ttl=64 time=0.073 ms
--- ::1 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms rtt min/avg/max/mdev = 0.073/0.073/0.073/0.000 ms
0.000 probe_libc:inet_pton:(7f1083221350))
__inet_pton (inlined)
gaih_inet.constprop.7 (/usr/lib64/libc-2.26.so)#
--- tools/perf/builtin-trace.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-)
tools/perf/builtin-trace.c +13 -1
@@ -1644,7 +1644,7 @@ static int trace__resolve_callchain(struct trace *trace, struct perf_evsel *evsestruct addr_location al;if (machine__resolve (trace->host, &al, sample) <0 || -thread__resolve_callchain (al.thread, cursor, evsel, sample,NULL ,NULL , trace->max_stack)) +thread__resolve_callchain (al.thread, cursor, evsel, sample,NULL ,NULL , evsel->attr.sample_max_stack))return -1 ;return 0 ;
@@ -2423,6 +2423,18 @@ static int trace__run(struct trace *trace, int argc, const char **argv) trace->multiple_threads =thread_map__pid (evlist->threads,0 ) ==-1 || evlist->threads->nr >1 ||perf_evlist__first (evlist)->attr.inherit; + +/* +* Now that we already used evsel->attr to ask the kernel to setup the +* events, lets reuse evsel->attr.sample_max_stack as the limit in +* trace__resolve_callchain(), allowing per-event max-stack settings +* to override an explicitely set --max-stack global setting. +*/ +evlist__for_each_entry (evlist, evsel) { +if ((evsel->attr.sample_type &PERF_SAMPLE_CALLCHAIN ) && + evsel->attr.sample_max_stack ==0 ) + evsel->attr.sample_max_stack = trace->max_stack; + } again: before = trace->nr_events;
Signature · 1 line
2.14.3
Arnaldo Carvalho de Melo
maintainerPATCH 23/32 perf callchains: Ask for PERF_RECORD_MMAP for data mmaps for DWARF unwinding
In reply to Arnaldo Carvalho de MeloFrom: Arnaldo Carvalho de Melo <[email protected]>
When we use a global DWARF setting as in:
perf record --call-graph dwarf
According to 5c0cf22477ea ("perf record: Store data mmaps for dwarf unwind") we need to set up some extra perf_event_attr bits.
But when we instead do a per event dwarf setting:
perf record -e cycles/call-graph=dwarf/
This was not being done, make them equivalent.
This didn't produce any output changes in my tests while fixing up loose ends in the per-event settings, I found it just by comparing the perf_event_attr fields trying to find an explanation for those problems.
--- tools/perf/util/evsel.c | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-)
tools/perf/util/evsel.c +13 -3
@@ -726,7 +726,7 @@ perf_evsel__reset_callgraph(struct perf_evsel *evsel, }static void apply_config_terms (struct perf_evsel *evsel, -struct record_opts *opts) +struct record_opts *opts,bool track) {struct perf_evsel_config_term *term;struct list_head *config_terms = &evsel->config_terms;
@@ -797,6 +797,8 @@ static void apply_config_terms(struct perf_evsel *evsel,/* User explicitly set per-event callgraph, clear the old setting and reset. */ if ((callgraph_buf !=NULL ) || (dump_size >0 ) || max_stack) { +bool sample_address = false; +if (max_stack) { param.max_stack = max_stack;if (callgraph_buf ==NULL )
@@ -816,6 +818,8 @@ static void apply_config_terms(struct perf_evsel *evsel, evsel->name);return ; } +if (param.record_mode ==CALLCHAIN_DWARF ) + sample_address = true; } }if (dump_size >0 ) {
@@ -828,8 +832,14 @@ static void apply_config_terms(struct perf_evsel *evsel,perf_evsel__reset_callgraph (evsel, &callchain_param);/* set perf-event callgraph */ -if (param.enabled) +if (param.enabled) { +if (sample_address) { +perf_evsel__set_sample_bit (evsel,ADDR ); +perf_evsel__set_sample_bit (evsel,DATA_SRC ); + evsel->attr.mmap_data = track; + }perf_evsel__config_callchain (evsel, opts, ¶m); + } } }
@@ -1060,7 +1070,7 @@ void perf_evsel__config(struct perf_evsel *evsel, struct record_opts *opts,* Apply event specific term settings, * it overloads any global configuration. */ -apply_config_terms (evsel, opts); +apply_config_terms (evsel, opts, track); evsel->ignore_missing_thread = opts->ignore_missing_thread; }
Signature · 1 line
2.14.3
Arnaldo Carvalho de Melo
maintainerPATCH 24/32 perf report: Improve error msg when no first/last sample time found
In reply to Arnaldo Carvalho de MeloFrom: Jin Yao <[email protected]>
The following message will be returned to user when executing 'perf report --time' if perf data file doesn't contain the first/last sample time.
"HINT: no first/last sample time found in perf data.
Please use latest perf binary to execute 'perf record'
(if '--buildid-all' is enabled, needs to set '--timestamp-boundary')."
--- tools/perf/builtin-report.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
tools/perf/builtin-report.c +3 -1
@@ -1300,7 +1300,9 @@ int cmd_report(int argc, const char **argv)if (perf_time__parse_str (report.ptime_range, report.time_str) !=0 ) {if (session->evlist->first_sample_time ==0 && session->evlist->last_sample_time ==0 ) { -pr_err ("No first/last sample time in perf data\n" ); +pr_err ("HINT: no first/last sample time found in perf data.\n" +"Please use latest perf binary to execute 'perf record'\n" +"(if '--buildid-all' is enabled, please set '--timestamp-boundary').\n" );return -EINVAL ; }
Signature · 1 line
2.14.3
Arnaldo Carvalho de Melo
maintainerPATCH 25/32 perf script: Improve error msg when no first/last sample time found
In reply to Arnaldo Carvalho de MeloFrom: Jin Yao <[email protected]>
The following message will be returned to user when executing 'perf script --time' if perf data file doesn't contain the first/last sample time.
"HINT: no first/last sample time found in perf data.
Please use latest perf binary to execute 'perf record'
(if '--buildid-all' is enabled, needs to set '--timestamp-boundary')."
--- tools/perf/builtin-script.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
tools/perf/builtin-script.c +3 -1
@@ -3449,7 +3449,9 @@ int cmd_script(int argc, const char **argv)if (perf_time__parse_str (script.ptime_range, script.time_str) !=0 ) {if (session->evlist->first_sample_time ==0 && session->evlist->last_sample_time ==0 ) { -pr_err ("No first/last sample time in perf data\n" ); +pr_err ("HINT: no first/last sample time found in perf data.\n" +"Please use latest perf binary to execute 'perf record'\n" +"(if '--buildid-all' is enabled, please set '--timestamp-boundary').\n" ); err = -EINVAL ; goto out_delete; }
Signature · 1 line
2.14.3
Arnaldo Carvalho de Melo
maintainerPATCH 26/32 perf util: Improve error checking for time percent input
In reply to Arnaldo Carvalho de MeloFrom: Jin Yao <[email protected]>
The command line like 'perf report --stdio --time 1abc%/1' could be accepted by perf. It looks not very good.
This patch uses strtod() to replace original atof() and check the entire string. Now for the same command line, it would return error message "Invalid time string".
root@skl:/tmp# perf report --stdio --time 1abc%/1 Invalid time string
--- tools/perf/util/time-utils.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-)
tools/perf/util/time-utils.c +6 -2
@@ -116,7 +116,8 @@ int perf_time__parse_str(struct perf_time_interval *ptime, const char *ostr)static int parse_percent (double *pcnt,char *str) { -char *c; +char *c, *endptr; +double d; c =strchr (str,'%' );if (c)
@@ -124,8 +125,11 @@ static int parse_percent(double *pcnt, char *str)else return -1 ; - *pcnt =atof (str) /100.0 ; + d =strtod (str, &endptr); +if (endptr != str +strlen (str)) +return -1 ; + *pcnt = d /100.0 ;return 0 ; }
Signature · 1 line
2.14.3
Arnaldo Carvalho de Melo
maintainerPATCH 27/32 perf util: Support no index time percent slice
In reply to Arnaldo Carvalho de MeloFrom: Jin Yao <[email protected]>
Previously, the time percent slice needs an index to specify which one the user wants.
It may be easier to use if the index can be omitted. So with this patch, for example,
perf report --stdio --time 10%/1 should be equivalent to perf report --stdio --time 10%
--- tools/perf/util/time-utils.c | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+)
tools/perf/util/time-utils.c +36 -0
@@ -261,6 +261,37 @@ static int percent_comma_split(struct perf_time_interval *ptime_buf, int num,return i; } +static int one_percent_convert (struct perf_time_interval *ptime_buf, +const char *ostr,u64 start,u64 end,char *c) +{ +char *str; +int len =strlen (ostr), ret; + +/* +* c points to '%'. +* '%' should be the last character +*/ +if (ostr + len -1 != c) +return -1 ; + +/* +* Construct a string like "xx%/1" +*/ + str =malloc (len +3 ); +if (str ==NULL ) +return -ENOMEM ; + +memcpy (str, ostr, len); +strcpy (str + len,"/1" ); + + ret =percent_slash_split (str, ptime_buf, start, end); +if (ret ==0 ) + ret =1 ; + +free (str); +return ret; +} +int perf_time__percent_parse_str (struct perf_time_interval *ptime_buf,int num,const char *ostr,u64 start,u64 end) {
@@ -270,6 +301,7 @@ int perf_time__percent_parse_str(struct perf_time_interval *ptime_buf, int num,* ostr example: * 10%/2,10%/3: select the second 10% slice and the third 10% slice * 0%-10%,30%-40%: multiple time range +* 50%: just one percent */ memset (ptime_buf,0 ,sizeof (*ptime_buf) * num);
@@ -286,6 +318,10 @@ int perf_time__percent_parse_str(struct perf_time_interval *ptime_buf, int num, end, percent_dash_split); } + c =strchr (ostr,'%' ); +if (c) +return one_percent_convert (ptime_buf, ostr, start, end, c); +return -1 ; }
Signature · 1 line
2.14.3
Arnaldo Carvalho de Melo
maintainerPATCH 28/32 perf report: Add an indication of what time slices are used
In reply to Arnaldo Carvalho de MeloFrom: Jin Yao <[email protected]>
Add a time slices indication to the perf report header.
For example,
# perf report --stdio --time 10%
# Total Lost Samples: 0
#
# Samples: 9K of event 'cycles:ppp' (time slices: 10%) # Event count (approx.): 8951288803
--- tools/perf/builtin-report.c | 3 +++ 1 file changed, 3 insertions(+)
tools/perf/builtin-report.c +3 -0
@@ -404,6 +404,9 @@ static size_t hists__fprintf_nr_sample_events(struct hists *hists, struct reportif (evname !=NULL ) ret +=fprintf (fp," of event '%s'" , evname); +if (rep->time_str) + ret +=fprintf (fp," (time slices: %s)" , rep->time_str); +if (symbol_conf.show_ref_callgraph &&strstr (evname,"call-graph=no" )) { ret +=fprintf (fp,", show reference callgraph" );
Signature · 1 line
2.14.3
Arnaldo Carvalho de Melo
maintainerPATCH 29/32 perf util: Allocate time slices buffer according to number of comma
In reply to Arnaldo Carvalho de MeloFrom: Jin Yao <[email protected]>
Previously we use a magic number 10 to limit the number of time slices. It's not very good.
This patch creates a new function perf_time__range_alloc() to allocate time slices buffer. The number of buffer entries is determined by the number of comma in string but at least it will allocate one entry even if no comma is found.
--- tools/perf/util/time-utils.c | 28 ++++++++++++++++++++++++++++ tools/perf/util/time-utils.h | 2 ++ 2 files changed, 30 insertions(+)
tools/perf/util/time-utils.c +28 -0
@@ -325,6 +325,34 @@ int perf_time__percent_parse_str(struct perf_time_interval *ptime_buf, int num,return -1 ; } +struct perf_time_interval *perf_time__range_alloc (const char *ostr,int *size) +{ +const char *p1, *p2; +int i =1 ; +struct perf_time_interval *ptime; + +/* +* At least allocate one time range. +*/ +if (!ostr) + goto alloc; + + p1 = ostr; +while (p1 < ostr +strlen (ostr)) { + p2 =strchr (p1,',' ); +if (!p2) +break ; + + p1 = p2 +1 ; + i++; + } + +alloc: + *size = i; + ptime =calloc (i,sizeof (*ptime)); +return ptime; +} +bool perf_time__skip_sample (struct perf_time_interval *ptime,u64 timestamp) {/* if time is not set don't drop sample */
tools/perf/util/time-utils.h +2 -0
@@ -16,6 +16,8 @@ int perf_time__parse_str(struct perf_time_interval *ptime, const char *ostr);int perf_time__percent_parse_str (struct perf_time_interval *ptime_buf,int num,const char *ostr,u64 start,u64 end); +struct perf_time_interval *perf_time__range_alloc (const char *ostr,int *size); +bool perf_time__skip_sample (struct perf_time_interval *ptime,u64 timestamp); bool perf_time__ranges_skip_sample(struct perf_time_interval *ptime_buf,
Signature · 1 line
2.14.3
Arnaldo Carvalho de Melo
maintainerPATCH 30/32 perf report: Remove the time slices number limitation
In reply to Arnaldo Carvalho de MeloFrom: Jin Yao <[email protected]>
Previously it was only allowed to use at most 10 time slices in 'perf report --time'.
This patch removes this limitation.
For example, following command line is OK (12 time slices)
perf report --stdio --time 1%/1,1%/2,1%/3,1%/4,1%/5,1%/6,1%/7,1%/8,1%/9,1%/10,1%/11,1%/12
--- tools/perf/Documentation/perf-report.txt | 2 +- tools/perf/builtin-report.c | 22 ++++++++++++++++------ 2 files changed, 17 insertions(+), 7 deletions(-)
tools/perf/Documentation/perf-report.txt +1 -1
@@ -403,7 +403,7 @@ OPTIONS to end of file. Also support time percent with multiple time range. Time string is - 'a%/n,b%/m,...' or 'a%-b%,c%-%d,...'. The maximum number of slices is 10. + 'a%/n,b%/m,...' or 'a%-b%,c%-%d,...'. For example: Select the second 10% time slice:
tools/perf/builtin-report.c +16 -6
@@ -54,8 +54,6 @@#include <unistd.h> #include <linux/mman.h> -#define PTIME_RANGE_MAX 10 -struct report {struct perf_tool tool;struct perf_session *session;
@@ -76,7 +74,8 @@ struct report {const char *cpu_list;const char *symbol_filter_str;const char *time_str; -struct perf_time_interval ptime_range[PTIME_RANGE_MAX ]; +struct perf_time_interval *ptime_range; +int range_size;int range_num;float min_percent;u64 nr_entries;
@@ -1300,24 +1299,33 @@ int cmd_report(int argc, const char **argv)if (symbol__init (&session->header.env) <0 ) goto error; + report.ptime_range =perf_time__range_alloc (report.time_str, + &report.range_size); +if (!report.ptime_range) { + ret = -ENOMEM ; + goto error; + } +if (perf_time__parse_str (report.ptime_range, report.time_str) !=0 ) {if (session->evlist->first_sample_time ==0 && session->evlist->last_sample_time ==0 ) {pr_err ("HINT: no first/last sample time found in perf data.\n" "Please use latest perf binary to execute 'perf record'\n" "(if '--buildid-all' is enabled, please set '--timestamp-boundary').\n" ); -return -EINVAL ; + ret = -EINVAL ; + goto error; } report.range_num =perf_time__percent_parse_str ( - report.ptime_range,PTIME_RANGE_MAX , + report.ptime_range, report.range_size, report.time_str, session->evlist->first_sample_time, session->evlist->last_sample_time);if (report.range_num <0 ) {pr_err ("Invalid time string\n" ); -return -EINVAL ; + ret = -EINVAL ; + goto error; } }else { report.range_num =1 ;
@@ -1333,6 +1341,8 @@ int cmd_report(int argc, const char **argv) ret =0 ; error: +zfree (&report.ptime_range); +perf_session__delete (session);return ret; }
Signature · 1 line
2.14.3
Arnaldo Carvalho de Melo
maintainerPATCH 31/32 perf script: Remove the time slices number limitation
In reply to Arnaldo Carvalho de MeloFrom: Jin Yao <[email protected]>
Previously it was only allowed to use at most 10 time slices in 'perf script --time'.
This patch removes this limitation.
For example, following command line is OK (12 time slices)
perf script --time 1%/1,1%/2,1%/3,1%/4,1%/5,1%/6,1%/7,1%/8,1%/9,1%/10,1%/11,1%/12
--- tools/perf/Documentation/perf-script.txt | 10 +++++----- tools/perf/builtin-script.c | 16 ++++++++++++---- 2 files changed, 17 insertions(+), 9 deletions(-)
tools/perf/Documentation/perf-script.txt +5 -5
@@ -351,19 +351,19 @@ include::itrace.txt[] to end of file. Also support time percent with multipe time range. Time string is - 'a%/n,b%/m,...' or 'a%-b%,c%-%d,...'. The maximum number of slices is 10. + 'a%/n,b%/m,...' or 'a%-b%,c%-%d,...'. For example: - Select the second 10% time slice + Select the second 10% time slice: perf script --time 10%/2 - Select from 0% to 10% time slice + Select from 0% to 10% time slice: perf script --time 0%-10% - Select the first and second 10% time slices + Select the first and second 10% time slices: perf script --time 10%/1,10%/2 - Select from 0% to 10% and 30% to 40% slices + Select from 0% to 10% and 30% to 40% slices: perf script --time 0%-10%,30%-40% --max-blocks::
tools/perf/builtin-script.c +12 -4
@@ -1480,8 +1480,6 @@ static int perf_sample__fprintf_synth(struct perf_sample *sample,return 0 ; } -#define PTIME_RANGE_MAX 10 -struct perf_script {struct perf_tool tool;struct perf_session *session;
@@ -1496,7 +1494,8 @@ struct perf_script {struct thread_map *threads;int name_width;const char *time_str; -struct perf_time_interval ptime_range[PTIME_RANGE_MAX ]; +struct perf_time_interval *ptime_range; +int range_size;int range_num; };
@@ -3445,6 +3444,13 @@ int cmd_script(int argc, const char **argv)if (err <0 ) goto out_delete; + script.ptime_range =perf_time__range_alloc (script.time_str, + &script.range_size); +if (!script.ptime_range) { + err = -ENOMEM ; + goto out_delete; + } +/* needs to be parsed after looking up reference time */ if (perf_time__parse_str (script.ptime_range, script.time_str) !=0 ) { if (session->evlist->first_sample_time == 0 &&
@@ -3457,7 +3463,7 @@ int cmd_script(int argc, const char **argv) } script.range_num =perf_time__percent_parse_str ( - script.ptime_range,PTIME_RANGE_MAX , + script.ptime_range, script.range_size, script.time_str, session->evlist->first_sample_time, session->evlist->last_sample_time);
@@ -3476,6 +3482,8 @@ int cmd_script(int argc, const char **argv)flush_scripting (); out_delete: +zfree (&script.ptime_range); +perf_evlist__free_stats (session->evlist);perf_session__delete (session);
Signature · 1 line
2.14.3
Arnaldo Carvalho de Melo
maintainerPATCH 32/32 perf record: Fix failed memory allocation for get_cpuid_str
In reply to Arnaldo Carvalho de MeloFrom: Thomas Richter <[email protected]>
In x86 architecture dependend part function get_cpuid_str() mallocs a 128 byte buffer, but does not check if the memory allocation succeeded or not.
When the memory allocation fails, function __get_cpuid() is called with first parameter being a NULL pointer. However this function references its first parameter and operates on a NULL pointer which might cause core dumps.
--- tools/perf/arch/x86/util/header.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
tools/perf/arch/x86/util/header.c +1 -1
@@ -70,7 +70,7 @@ get_cpuid_str(struct perf_pmu *pmu __maybe_unused) {char *buf =malloc (128 ); -if (__get_cpuid (buf,128 ,"%s-%u-%X$" ) <0 ) { +if (buf &&__get_cpuid (buf,128 ,"%s-%u-%X$" ) <0 ) {free (buf);return NULL ; }
Signature · 1 line
2.14.3
Quoted 159 lines · Arnaldo Carvalho de Melo
Hi Ingo,
Please consider pulling,
- Arnaldo
Test results at the end of this message, as usual.
The following changes since commit
1ccb8feda7471efb62ebf68d70055b4c51fa7d92:Merge tag 'perf-core-for-mingo-4.16-20180110' of
git://git.kernel.org/pub/scm/linux/kernel/git/acme/linuxinto perf/core (2018-01-11 06:53:06 +0100)are available in the Git repository at:
git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux.gittags/perf-core-for-mingo-4.16-20180117for you to fetch changes up to
81fccd6ca507d3b2012eaf1edeb9b1dbf4bd22db:perf record: Fix failed memory allocation for
get_cpuid_str(2018-01-17 10:31:25 -0300)----------------------------------------------------------------
perf/core improvements and fixes:- Fix various per event 'max-stack' and 'call-graph=dwarf' issues, mostly in 'perf trace', allowing to use 'perf trace --call-graph' with 'dwarf' and 'fp' to setup the callgraph details for the syscall events and make that apply to other events, whilhe allowing to override that on a per-event basis, using '-e sched:*switch/call-graph=dwarf/' for instance (Arnaldo Carvalho de Melo)
- Improve the --time percent support in record/report/script (Jin Yao)
- Fix
copyfile_offsetupdate of output offset (Jiri Olsa)- Add python script to profile and resolve physical mem type (Kan Liang)
- Add ARM Statistical Profiling Extensions (SPE) support (Kim Phillips)
- Remove trailing semicolon in the evlist code (Luis de Bethencourt)
- Fix incorrect handling of type
_TERM_DRV_CFG(Mathieu Poirier)- Use asprintf when possible in libtraceevent (Federico Vaga)
- Fix bad
force_tokenescape sequence in libtraceevent (Michael Sartain)- Add UL suffix to
MISSING_EVENTSin libtraceevent (Michael Sartain)- value of unknown symbolic fields in libtraceevent (Jan Kiszka)
- libtraceevent updates: (Steven Rostedt)
o Show value of flags that have not been parsed
o Simplify pointer print logic and fix %pF
o Handle new pointer processing of bprint strings
o Show contents (in hex) of data of unrecognized type records
o Fixget_field_str()for dynamic strings- Add missing break in FALSE case of
pevent_filter_clear_trivial()(Taeung Song)- Fix failed memory allocation for
get_cpuid_str(Thomas Richter)Signed-off-by Arnaldo Carvalho de Melo <[email protected]>----------------------------------------------------------------
Arnaldo Carvalho de Melo (8):
perf trace: No need to setPERF_SAMPLE_IDENTIFIERexplicitely
perf evsel: Check if callchain is enabled before setting it up
perf trace: Fix setting of --call-graph/--max-stack for non-syscall events perf callchain: Fix attr.sample_max_stack setting
perf unwind: Do not look just at the global callchain_param.record_mode perf trace: Setup DWARF callchains for non-syscall events when --max-stack is used perf trace: Allow overriding global --max-stack per event
perf callchains: Ask forPERF_RECORD_MMAPfor data mmaps for DWARF unwindingFederico Vaga (1):
tools lib traceevent: Use asprintf when possibleJan Kiszka (1):
tools lib traceevent: Print value of unknown symbolic fieldsJin Yao (8):
perf report: Improve error msg when no first/last sample time found perf script: Improve error msg when no first/last sample time found perf util: Improve error checking for time percent input perf util: Support no index time percent slice
perf report: Add an indication of what time slices are used perf util: Allocate time slices buffer according to number of comma perf report: Remove the time slices number limitation perf script: Remove the time slices number limitationJiri Olsa (1):
perf tools: Fixcopyfile_offsetupdate of output offsetKan Liang (1):
perf script python: Add script to profile and resolve physical mem typeKim Phillips (1):
perf tools: Add ARM Statistical Profiling Extensions (SPE) supportLuis de Bethencourt (1):
perf evlist: Remove trailing semicolonMathieu Poirier (1):
perf evsel: Fix incorrect handling of type_TERM_DRV_CFGMichael Sartain (2):
tools lib traceevent: Fix badforce_tokenescape sequence tools lib traceevent: Add UL suffix toMISSING_EVENTSSteven Rostedt (VMware) (5):
tools lib traceevent: Show value of flags that have not been parsed tools lib traceevent: Simplify pointer print logic and fix %pF tools lib traceevent: Handle new pointer processing of bprint strings tools lib traceevent: Show contents (in hex) of data of unrecognized type records tools lib traceevent: Fixget_field_str()for dynamic stringsTaeung Song (1):
tools lib traceevent: Fix missing break in FALSE case ofpevent_filter_clear_trivial()Thomas Richter (1):
perf record: Fix failed memory allocation forget_cpuid_strtools/lib/traceevent/event-parse.c | 62 ++- tools/lib/traceevent/event-plugin.c | 24 +- tools/lib/traceevent/kbuffer-parse.c | 4 +- tools/lib/traceevent/parse-filter.c | 22 +- tools/perf/Documentation/perf-report.txt | 2 +- tools/perf/Documentation/perf-script.txt | 10 +- tools/perf/arch/arm/util/auxtrace.c | 77 +++- tools/perf/arch/arm/util/pmu.c | 6 + tools/perf/arch/arm64/util/Build | 3 +- tools/perf/arch/arm64/util/arm-spe.c | 225 ++++++++++ tools/perf/arch/x86/util/header.c | 2 +- tools/perf/builtin-c2c.c | 5 +- tools/perf/builtin-report.c | 34 +- tools/perf/builtin-script.c | 25 +- tools/perf/builtin-trace.c | 62 +-- tools/perf/scripts/python/bin/mem-phys-addr-record | 19 + tools/perf/scripts/python/bin/mem-phys-addr-report | 3 + tools/perf/scripts/python/mem-phys-addr.py | 95 +++++ tools/perf/tests/dwarf-unwind.c | 1 + tools/perf/util/Build | 2 + tools/perf/util/arm-spe-pkt-decoder.c | 462 +++++++++++++++++++++ tools/perf/util/arm-spe-pkt-decoder.h | 43 ++ tools/perf/util/arm-spe.c | 231 +++++++++++ tools/perf/util/arm-spe.h | 31 ++ tools/perf/util/auxtrace.c | 3 + tools/perf/util/auxtrace.h | 1 + tools/perf/util/callchain.c | 10 + tools/perf/util/callchain.h | 2 + tools/perf/util/evlist.c | 2 +- tools/perf/util/evsel.c | 40 +- .../util/scripting-engines/trace-event-python.c | 2 + tools/perf/util/time-utils.c | 72 +++- tools/perf/util/time-utils.h | 2 + tools/perf/util/unwind-libunwind-local.c | 9 +- tools/perf/util/util.c | 2 +- 35 files changed, 1465 insertions(+), 130 deletions(-)
Quoted 8 lines
create mode 100644 tools/perf/arch/arm64/util/arm-spe.c create mode 100644 tools/perf/scripts/python/bin/mem-phys-addr-record create mode 100644 tools/perf/scripts/python/bin/mem-phys-addr-report create mode 100644 tools/perf/scripts/python/mem-phys-addr.py create mode 100644 tools/perf/util/arm-spe-pkt-decoder.c create mode 100644 tools/perf/util/arm-spe-pkt-decoder.h create mode 100644 tools/perf/util/arm-spe.c create mode 100644 tools/perf/util/arm-spe.h
Pulled, thanks a lot Arnaldo!
Ingo