perf/core improvements and fixes
Subsystems (5)
Arnaldo Carvalho de Melo
maintainerHi Ingo,
Please consider pulling, this includes what should have been in
my previous pull request, that ended up empty as I messed up when signing the tag, that was made with perf/urgent checked out :-\ Now it should be ok, sorry about that :-\
- Arnaldo
Test results at the end of this message, as usual.
The following changes since commit e8e94fce14658defc659021a50d4253a681d02e7:
Merge tag 'perf-core-for-mingo-4.21-20181122' of git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux into perf/core (2018-11-22 07:52:50 +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.21-20181206
for you to fetch changes up to 4085fed6373f15892959e3392efe5552504cfc94:
perf trace: Add ordered processing (2018-12-06 16:43:28 -0300)
----------------------------------------------------------------
perf/core improvements and fixes:
- Introduce 'perf record --aio' to use asynchronous IO trace writing, disabled by default (Alexey Budankov)
- Add fallback routines to be used in places where we don't have the CPU mode (kernel/userspace/hypervisor) and thus must first fallback lookups looking at all map trees when trying to resolve symbols (Adrian Hunter)
- Fix error with config term "pt=0", where we should just force "pt=1" and warn the user about the former being nonsensical (Adrian Hunter)
- Fix 'perf test' entry where we expect 'sleep' to come in a PERF_RECORD_COMM but instead we get 'coreutils' when sleep is provided by some versions of the 'coreutils' package (Adrian Hunter)
- Introduce 'perf top --kallsyms file' to match 'perf report --kallsyms', useful when dealing with BPF, where symbol resolution happens via kallsyms, not via the default vmlinux ELF symtabs (Arnaldo Carvalho de Melo)
- Support 'srccode' output field in 'perf script' (Andi Kleen)
- Introduce basic 'perf annotation' support for the ARC architecture (Eugeniy Paltsev)
- Compute and display average IPC and IPC coverage per symbol in 'perf annotate' and 'perf report' (Jin Yao)
- Make 'perf top' use ordered_events and process histograms in a separate thread (Jiri Olsa)
- Make 'perf trace' use ordered_events (Jiri Olsa)
- Add support for ETMv3 and PTMv1.1 decoding in cs-etm (Mathieu Poirier)
- Support for ARM A32/T32 instruction sets in CoreSight trace (cs-etm) (Robert Walker)
- Fix 'perf stat' shadow stats for clock events. (Ravi Bangoria)
- Remove needless rb_tree extra indirection from map__find() (Eric Saint-Etienne)
- Fix CSV mode column output for non-cgroup events in 'perf stat' (Stephane Eranian)
- Add sanity check to libtraceevent's is_timestamp_in_us() (Tzvetomir Stoyanov)
- Use ERR_CAST instead of ERR_PTR(PTR_ERR()) (Wen Yang)
- Fix Load_Miss_Real_Latency on SKL/SKX intel vendor event files (Andi Kleen)
- strncpy() fixes triggered by new warnings on gcc 8.2.0 (Arnaldo Carvalho de Melo)
- Handle tracefs syscall tracepoint older 'nr' field in 'perf trace', that got renamed to '__syscall_nr' to work in older kernels (Arnaldo Carvalho de Melo)
- Give better hint about devel package for libssl (Arnaldo Carvalho de Melo)
- Fix the 'perf trace' build in architectures lacking explicit mmap.h file (Arnaldo Carvalho de Melo)
- Remove extra rb_tree traversal indirection from map__find() (Eric Saint-Etienne)
- Disable breakpoint tests for 32-bit ARM (Florian Fainelli)
- Fix typos all over the place, mostly in comments, but also in some debug messages and JSON files (Ingo Molnar)
- Allow specifying proc-map-timeout in config file (Mark Drayton)
- Fix mmap_flags table generation script (Sihyeon Jang)
- Fix 'size' parameter to snprintf in the 'perf config' code (Sihyeon Jang)
- More libtraceevent renames to make it a proper library (Tzvetomir Stoyanov)
- Implement new API tep_get_ref() in libtraceevent (Tzvetomir Stoyanov)
- Added support for pkg-config in libtraceevent (Tzvetomir Stoyanov)
----------------------------------------------------------------
Adrian Hunter (8):
perf machine: Record if a arch has a single user/kernel address space perf thread: Add fallback functions for cases where cpumode is insufficient perf tools: Use fallback for sample_addr_correlates_sym() cases perf script: Use fallbacks for branch stacks
tools lib traceevent: Fix compile warnings in tools/lib/traceevent/event-parse.c perf tests record: Allow for 'sleep' being 'coreutils'
perf test: Fix perf_event_attr test failure
perf intel-pt: Fix error with config term "pt=0"
Alexey Budankov (5):
tools build feature: Check if libaio is available perf mmap: Map data buffer for preserving collected data perf record: Enable asynchronous trace writing perf record: Extend trace writing to multi AIO perf record: Fix memory leak on AIO objects deallocation
Andi Kleen (2):
perf tools: Support 'srccode' output
perf vendor events intel: Fix Load_Miss_Real_Latency on SKL/SKX
Arnaldo Carvalho de Melo (14):
perf build: Give better hint about devel package for libssl
perf env: Also consider env->arch == NULL as local operation
tools include: Adopt ERR_CAST() from the kernel err.h header
perf top: Allow passing a kallsyms file
perf beauty mmap_flags: Check if the arch has a mmap.h file
perf trace: We need to consider "nr" if "__syscall_nr" is not there perf dso: Fix unchecked usage of strncpy()
perf header: Fix unchecked usage of strncpy()
perf header: Fix unchecked usage of strncpy()
perf help: Remove needless use of strncpy()
perf svghelper: Fix unchecked usage of strncpy()
perf ui helpline: Use strlcpy() as a shorter form of strncpy() + explicit set nul perf probe: Fix unchecked usage of strncpy()
perf parse-events: Fix unchecked usage of strncpy()
Eric Saint-Etienne (1):
perf map: Remove extra indirection from map__find()
Eugeniy Paltsev (1):
perf annotate: Introduce basic support for ARC
Florian Fainelli (1):
perf tests ARM: Disable breakpoint tests 32-bit
Ingo Molnar (6):
perf vendor events intel: Fix diverse typos tools lib traceevent: Fix diverse typos in comments perf tools Documentation: Fix diverse typos perf bpf-loader: Fix debugging message typo perf tools: Fix diverse comment typos
tools lib subcmd: Fix a few source code comment typos
Jin Yao (4):
perf annotate: Compute average IPC and IPC coverage per symbol perf annotate: Create a annotate2 flag in struct symbol perf report: Display average IPC and IPC coverage per symbol perf report: Documentation average IPC and IPC coverage
Jiri Olsa (15):
perf ordered_events: Rework show_progress for __ordered_events__flush perf ordered_events: Add private data member
perf top: Save and display the lost count stats
perf top: Move lost events warning to helpline
perf top: Add processing thread
perf top: Use cond variable instead of a lock
perf top: Set the 'session_done' volatile variable when exiting perf top: Drop samples which are behind the refresh rate perf top: Save and display the drop count stats
perf top: Display slow reader warning when droping samples perf top: Move perf_top__reset_sample_counters() to after counts display perf ordered_events: Add ordered_events__flush_time interface perf trace: Move event delivery to a new deliver_event() function perf ordered_events: Add first_time() method
perf trace: Add ordered processing
Mark Drayton (1):
perf tools: Allow specifying proc-map-timeout in config file
Mathieu Poirier (3):
perf cs-etm: Add configuration for ETMv3 trace protocol perf cs-etm: Add support for ETMv3 trace decoding perf cs-etm: Add support for PTMv1.1 decoding
Ravi Bangoria (1):
perf stat: Fix shadow stats for clock events
Robert Walker (1):
perf cs-etm: Support for ARM A32/T32 instruction sets in CoreSight trace
Sihyeon Jang (2):
perf beauty mmap_flags: Fixed syntax error Fixed missing ']' error perf config: Modify size factor of snprintf
Stephane Eranian (1):
perf stat: Fix CSV mode column output for non-cgroup events
Tzvetomir Stoyanov (8):
tools lib traceevent: Add sanity check to is_timestamp_in_us()
tools lib traceevent: Implement new API tep_get_ref()
tools lib traceevent: Added support for pkg-config
tools lib traceevent: Install trace-seq.h API header file
tools lib traceevent, perf tools: Rename 'struct tep_event_format' to 'struct tep_event' tools lib traceevent: Rename tep_free_format() to tep_free_event()
perf tools: traceevent API cleanup, remove __tep_data2host*()
tools lib traceevent: traceevent API cleanup
Wen Yang (1):
perf bpf: Use ERR_CAST instead of ERR_PTR(PTR_ERR())
tools/build/Makefile.feature | 6 +- tools/build/feature/Makefile | 6 +- tools/build/feature/test-all.c | 5 + tools/build/feature/test-libaio.c | 16 ++ tools/build/feature/test-libopencsd.c | 8 + tools/include/linux/err.h | 13 + tools/lib/subcmd/parse-options.h | 4 +- tools/lib/traceevent/Makefile | 27 +- tools/lib/traceevent/event-parse-api.c | 8 +- tools/lib/traceevent/event-parse-local.h | 13 +- tools/lib/traceevent/event-parse.c | 234 +++++++++-------- tools/lib/traceevent/event-parse.h | 77 +++--- tools/lib/traceevent/libtraceevent.pc.template | 10 + tools/lib/traceevent/parse-filter.c | 42 +-- tools/lib/traceevent/plugin_function.c | 2 +- tools/lib/traceevent/plugin_hrtimer.c | 4 +- tools/lib/traceevent/plugin_kmem.c | 2 +- tools/lib/traceevent/plugin_kvm.c | 16 +- tools/lib/traceevent/plugin_mac80211.c | 4 +- tools/lib/traceevent/plugin_sched_switch.c | 4 +- tools/perf/Documentation/perf-config.txt | 6 + tools/perf/Documentation/perf-list.txt | 2 +- tools/perf/Documentation/perf-record.txt | 5 + tools/perf/Documentation/perf-report.txt | 10 +- tools/perf/Documentation/perf-script.txt | 2 +- tools/perf/Documentation/perf-stat.txt | 4 +- tools/perf/Documentation/perf-top.txt | 3 + tools/perf/Makefile.config | 8 +- tools/perf/Makefile.perf | 9 +- tools/perf/arch/arc/annotate/instructions.c | 9 + tools/perf/arch/common.c | 21 +- tools/perf/arch/common.h | 1 + tools/perf/arch/x86/tests/insn-x86.c | 2 +- tools/perf/arch/x86/util/intel-pt.c | 11 + tools/perf/builtin-help.c | 2 +- tools/perf/builtin-kvm.c | 6 +- tools/perf/builtin-record.c | 263 ++++++++++++++++++- tools/perf/builtin-report.c | 26 +- tools/perf/builtin-script.c | 59 ++++- tools/perf/builtin-top.c | 289 +++++++++++++++------ tools/perf/builtin-trace.c | 87 +++++-- tools/perf/perf.h | 2 +- .../perf/pmu-events/arch/x86/broadwell/cache.json | 4 +- .../pmu-events/arch/x86/broadwell/pipeline.json | 2 +- .../pmu-events/arch/x86/broadwellde/cache.json | 4 +- .../pmu-events/arch/x86/broadwellde/pipeline.json | 2 +- .../perf/pmu-events/arch/x86/broadwellx/cache.json | 4 +- .../pmu-events/arch/x86/broadwellx/pipeline.json | 2 +- tools/perf/pmu-events/arch/x86/jaketown/cache.json | 4 +- .../pmu-events/arch/x86/jaketown/pipeline.json | 2 +- .../pmu-events/arch/x86/knightslanding/cache.json | 30 +-- .../pmu-events/arch/x86/sandybridge/cache.json | 4 +- .../pmu-events/arch/x86/sandybridge/pipeline.json | 2 +- .../pmu-events/arch/x86/skylake/skl-metrics.json | 2 +- .../pmu-events/arch/x86/skylakex/skx-metrics.json | 2 +- .../pmu-events/arch/x86/skylakex/uncore-other.json | 12 +- tools/perf/tests/attr.c | 2 +- tools/perf/tests/attr.py | 2 +- tools/perf/tests/bp_signal.c | 20 +- tools/perf/tests/code-reading.c | 2 +- tools/perf/tests/dwarf-unwind.c | 2 +- tools/perf/tests/mmap-thread-lookup.c | 4 +- tools/perf/tests/perf-record.c | 7 +- tools/perf/trace/beauty/mmap_flags.sh | 4 +- tools/perf/ui/browsers/hists.c | 11 + tools/perf/ui/tui/helpline.c | 2 +- tools/perf/util/Build | 1 + tools/perf/util/annotate.c | 49 +++- tools/perf/util/annotate.h | 5 + tools/perf/util/bpf-loader.c | 4 +- tools/perf/util/config.c | 8 +- tools/perf/util/cs-etm-decoder/cs-etm-decoder.c | 60 +++++ tools/perf/util/cs-etm-decoder/cs-etm-decoder.h | 19 ++ tools/perf/util/cs-etm.c | 143 ++++++---- tools/perf/util/dso.c | 2 +- tools/perf/util/env.c | 2 +- tools/perf/util/event.c | 61 +++-- tools/perf/util/event.h | 8 +- tools/perf/util/evlist.c | 6 +- tools/perf/util/evlist.h | 2 +- tools/perf/util/evsel.h | 4 +- tools/perf/util/evsel_fprintf.c | 1 + tools/perf/util/header.c | 8 +- tools/perf/util/hist.c | 2 +- tools/perf/util/hist.h | 1 + tools/perf/util/jitdump.c | 2 +- tools/perf/util/machine.c | 33 ++- tools/perf/util/machine.h | 6 +- tools/perf/util/map.c | 62 ++++- tools/perf/util/map.h | 16 ++ tools/perf/util/mmap.c | 152 ++++++++++- tools/perf/util/mmap.h | 26 +- tools/perf/util/ordered-events.c | 44 +++- tools/perf/util/ordered-events.h | 8 +- tools/perf/util/parse-events.c | 2 +- tools/perf/util/probe-event.c | 4 +- tools/perf/util/probe-file.c | 2 +- tools/perf/util/python.c | 4 +- .../perf/util/scripting-engines/trace-event-perl.c | 6 +- .../util/scripting-engines/trace-event-python.c | 24 +- tools/perf/util/session.c | 7 +- tools/perf/util/sort.c | 63 ++++- tools/perf/util/sort.h | 2 + tools/perf/util/srccode.c | 186 +++++++++++++ tools/perf/util/srccode.h | 7 + tools/perf/util/srcline.c | 28 ++ tools/perf/util/srcline.h | 1 + tools/perf/util/stat-display.c | 16 +- tools/perf/util/stat-shadow.c | 3 +- tools/perf/util/svghelper.c | 2 +- tools/perf/util/symbol.h | 1 + tools/perf/util/thread.c | 2 + tools/perf/util/thread.h | 6 + tools/perf/util/top.c | 8 +- tools/perf/util/top.h | 10 +- tools/perf/util/trace-event-parse.c | 16 +- tools/perf/util/trace-event-read.c | 4 +- tools/perf/util/trace-event.c | 8 +- tools/perf/util/trace-event.h | 16 +- 119 files changed, 2051 insertions(+), 572 deletions(-) create mode 100644 tools/build/feature/test-libaio.c create mode 100644 tools/lib/traceevent/libtraceevent.pc.template create mode 100644 tools/perf/arch/arc/annotate/instructions.c create mode 100644 tools/perf/util/srccode.c create mode 100644 tools/perf/util/srccode.h
Test results:
The first ones are container based builds of tools/perf with and without libelf support. Where clang is available, it is also used to build perf with/without libelf, and building with LIBCLANGLLVM=1 (built-in clang) with gcc and clang when clang and its devel libraries are installed.
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 one, and those may not have all the features built, due to lack of multi-arch devel packages, available and being used so far on just a few, like debian:experimental-x-{arm64,mipsel}.
The 'perf test' one will perform a variety of tests exercising tools/perf/util/, tools/lib/{bpf,traceevent,etc}, as well as run perf commands with a variety of command line event specifications to then intercept the sys_perf_event syscall to check that the perf_event_attr fields are set up as expected, among a variety of other unit tests.
Then there is the 'make -C tools/perf build-test' ones, that build tools/perf/ with a variety of feature sets, exercising the build with an incomplete set of features as well as with a complete one. It is planned to have it run on each of the containers mentioned above, using some container orchestration infrastructure. Get in contact if interested in helping having this in place.
$ dm 1 alpine:3.4 : Ok gcc (Alpine 5.3.0) 5.3.0 2 alpine:3.5 : Ok gcc (Alpine 6.2.1) 6.2.1 20160822 3 alpine:3.6 : Ok gcc (Alpine 6.3.0) 6.3.0 4 alpine:3.7 : Ok gcc (Alpine 6.4.0) 6.4.0 5 alpine:3.8 : Ok gcc (Alpine 6.4.0) 6.4.0 6 alpine:edge : Ok gcc (Alpine 8.2.0) 8.2.0 7 amazonlinux:1 : Ok gcc (GCC) 4.8.5 20150623 (Red Hat 4.8.5-28) 8 amazonlinux:2 : Ok gcc (GCC) 7.3.1 20180303 (Red Hat 7.3.1-5) 9 android-ndk:r12b-arm : Ok arm-linux-androideabi-gcc (GCC) 4.9.x 20150123 (prerelease) 10 android-ndk:r15c-arm : Ok arm-linux-androideabi-gcc (GCC) 4.9.x 20150123 (prerelease) 11 centos:5 : Ok gcc (GCC) 4.1.2 20080704 (Red Hat 4.1.2-55) 12 centos:6 : Ok gcc (GCC) 4.4.7 20120313 (Red Hat 4.4.7-23) 13 centos:7 : Ok gcc (GCC) 4.8.5 20150623 (Red Hat 4.8.5-36) 14 clearlinux:latest : Ok gcc (Clear Linux OS for Intel Architecture) 8.2.1 20180502 15 debian:7 : Ok gcc (Debian 4.7.2-5) 4.7.2 16 debian:8 : Ok gcc (Debian 4.9.2-10+deb8u1) 4.9.2 17 debian:9 : Ok gcc (Debian 6.3.0-18+deb9u1) 6.3.0 20170516 18 debian:experimental : Ok gcc (Debian 8.2.0-10) 8.2.0 19 debian:experimental-x-arm64 : Ok aarch64-linux-gnu-gcc (Debian 8.2.0-10) 8.2.0 20 debian:experimental-x-mips64 : Ok mips64-linux-gnuabi64-gcc (Debian 8.2.0-10) 8.2.0 21 fedora:20 : Ok gcc (GCC) 4.8.3 20140911 (Red Hat 4.8.3-7) 22 fedora:22 : Ok gcc (GCC) 5.3.1 20160406 (Red Hat 5.3.1-6) 23 fedora:23 : Ok gcc (GCC) 5.3.1 20160406 (Red Hat 5.3.1-6) 24 fedora:24 : Ok gcc (GCC) 6.3.1 20161221 (Red Hat 6.3.1-1) 25 fedora:24-x-ARC-uClibc : Ok arc-linux-gcc (ARCompact ISA Linux uClibc toolchain 2017.09-rc2) 7.1.1 20170710 26 fedora:25 : Ok gcc (GCC) 6.4.1 20170727 (Red Hat 6.4.1-1) 27 fedora:26 : Ok gcc (GCC) 7.3.1 20180130 (Red Hat 7.3.1-2) 28 fedora:27 : Ok gcc (GCC) 7.3.1 20180712 (Red Hat 7.3.1-6) 29 fedora:28 : Ok gcc (GCC) 8.2.1 20181105 (Red Hat 8.2.1-5) 30 fedora:29 : Ok gcc (GCC) 8.2.1 20181105 (Red Hat 8.2.1-5) 31 fedora:rawhide : Ok gcc (GCC) 8.2.1 20181105 (Red Hat 8.2.1-5) 32 gentoo-stage3-amd64:latest : Ok gcc (Gentoo 7.3.0-r3 p1.4) 7.3.0 33 mageia:5 : Ok gcc (GCC) 4.9.2 34 mageia:6 : Ok gcc (Mageia 5.5.0-1.mga6) 5.5.0 35 opensuse:13.2 : Ok gcc (SUSE Linux) 4.8.3 20140627 [gcc-4_8-branch revision 212064] 36 opensuse:42.1 : Ok gcc (SUSE Linux) 4.8.5 37 opensuse:42.2 : Ok gcc (SUSE Linux) 4.8.5 38 opensuse:42.3 : Ok gcc (SUSE Linux) 4.8.5 39 oraclelinux:6 : Ok gcc (GCC) 4.4.7 20120313 (Red Hat 4.4.7-23.0.1) 40 oraclelinux:7 : Ok gcc (GCC) 4.8.5 20150623 (Red Hat 4.8.5-36.0.1) 41 ubuntu:12.04.5 : Ok gcc (Ubuntu/Linaro 4.6.3-1ubuntu5) 4.6.3 42 ubuntu:14.04.4 : Ok gcc (Ubuntu 4.8.4-2ubuntu1~14.04.4) 4.8.4 43 ubuntu:14.04.4-x-linaro-arm64 : Ok aarch64-linux-gnu-gcc (Linaro GCC 5.5-2017.10) 5.5.0 44 ubuntu:16.04 : Ok gcc (Ubuntu 5.4.0-6ubuntu1~16.04.10) 5.4.0 20160609 45 ubuntu:16.04-x-arm : Ok arm-linux-gnueabihf-gcc (Ubuntu/Linaro 5.4.0-6ubuntu1~16.04.9) 5.4.0 20160609 46 ubuntu:16.04-x-arm64 : Ok aarch64-linux-gnu-gcc (Ubuntu/Linaro 5.4.0-6ubuntu1~16.04.9) 5.4.0 20160609 47 ubuntu:16.04-x-powerpc : Ok powerpc-linux-gnu-gcc (Ubuntu 5.4.0-6ubuntu1~16.04.9) 5.4.0 20160609 48 ubuntu:16.04-x-powerpc64 : Ok powerpc64-linux-gnu-gcc (Ubuntu/IBM 5.4.0-6ubuntu1~16.04.9) 5.4.0 20160609 49 ubuntu:16.04-x-powerpc64el : Ok powerpc64le-linux-gnu-gcc (Ubuntu/IBM 5.4.0-6ubuntu1~16.04.9) 5.4.0 20160609 50 ubuntu:16.04-x-s390 : Ok s390x-linux-gnu-gcc (Ubuntu 5.4.0-6ubuntu1~16.04.9) 5.4.0 20160609 51 ubuntu:17.10 : Ok gcc (Ubuntu 7.2.0-8ubuntu3.2) 7.2.0 52 ubuntu:18.04 : Ok gcc (Ubuntu 7.3.0-27ubuntu1~18.04) 7.3.0 53 ubuntu:18.04-x-arm : Ok arm-linux-gnueabihf-gcc (Ubuntu/Linaro 7.3.0-27ubuntu1~18.04) 7.3.0 54 ubuntu:18.04-x-arm64 : Ok aarch64-linux-gnu-gcc (Ubuntu/Linaro 7.3.0-27ubuntu1~18.04) 7.3.0 55 ubuntu:18.04-x-m68k : Ok m68k-linux-gnu-gcc (Ubuntu 7.3.0-27ubuntu1~18.04) 7.3.0 56 ubuntu:18.04-x-powerpc : Ok powerpc-linux-gnu-gcc (Ubuntu 7.3.0-27ubuntu1~18.04) 7.3.0 57 ubuntu:18.04-x-powerpc64 : Ok powerpc64-linux-gnu-gcc (Ubuntu 7.3.0-27ubuntu1~18.04) 7.3.0 58 ubuntu:18.04-x-powerpc64el : Ok powerpc64le-linux-gnu-gcc (Ubuntu 7.3.0-27ubuntu1~18.04) 7.3.0 59 ubuntu:18.04-x-riscv64 : Ok riscv64-linux-gnu-gcc (Ubuntu 7.3.0-27ubuntu1~18.04) 7.3.0 60 ubuntu:18.04-x-s390 : Ok s390x-linux-gnu-gcc (Ubuntu 7.3.0-27ubuntu1~18.04) 7.3.0 61 ubuntu:18.04-x-sh4 : Ok sh4-linux-gnu-gcc (Ubuntu 7.3.0-27ubuntu1~18.04) 7.3.0 62 ubuntu:18.04-x-sparc64 : Ok sparc64-linux-gnu-gcc (Ubuntu 7.3.0-27ubuntu1~18.04) 7.3.0 63 ubuntu:18.10 : Ok gcc (Ubuntu 8.2.0-7ubuntu1) 8.2.0 $
# uname -a
Linux quaco 4.20.0-rc5 #1 SMP Mon Dec 3 12:20:42 -03 2018 x86_64 x86_64 x86_64 GNU/Linux
# git log --oneline -1
4085fed6373f perf trace: Add ordered processing
# perf version --build-options
perf version 4.20.rc3.g4085fe
dwarf: [ on ] # HAVE_DWARF_SUPPORT
dwarf_getlocations: [ on ] # HAVE_DWARF_GETLOCATIONS_SUPPORT
glibc: [ on ] # HAVE_GLIBC_SUPPORT
gtk2: [ on ] # HAVE_GTK2_SUPPORT
syscall_table: [ on ] # HAVE_SYSCALL_TABLE_SUPPORT
libbfd: [ on ] # HAVE_LIBBFD_SUPPORT
libelf: [ on ] # HAVE_LIBELF_SUPPORT
libnuma: [ on ] # HAVE_LIBNUMA_SUPPORT
numa_num_possible_cpus: [ on ] # HAVE_LIBNUMA_SUPPORT
libperl: [ on ] # HAVE_LIBPERL_SUPPORT
libpython: [ on ] # HAVE_LIBPYTHON_SUPPORT
libslang: [ on ] # HAVE_SLANG_SUPPORT
libcrypto: [ on ] # HAVE_LIBCRYPTO_SUPPORT
libunwind: [ on ] # HAVE_LIBUNWIND_SUPPORT
libdw-dwarf-unwind: [ on ] # HAVE_DWARF_SUPPORT
zlib: [ on ] # HAVE_ZLIB_SUPPORT
lzma: [ on ] # HAVE_LZMA_SUPPORT
get_cpuid: [ on ] # HAVE_AUXTRACE_SUPPORT
bpf: [ on ] # HAVE_LIBBPF_SUPPORT
# 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: Breakpoint accounting : Ok
22: Watchpoint :
22.1: Read Only Watchpoint : Skip
22.2: Write Only Watchpoint : Ok
22.3: Read / Write Watchpoint : Ok
22.4: Modify Watchpoint : Ok
23: Number of exit events of a simple workload : Ok
24: Software clock events period values : Ok
25: Object code reading : Ok
26: Sample parsing : Ok
27: Use a dummy software event to keep tracking : Ok
28: Parse with no sample_id_all bit set : Ok
29: Filter hist entries : Ok
30: Lookup mmap thread : Ok
31: Share thread mg : Ok
32: Sort output of hist entries : Ok
33: Cumulate child hist entries : Ok
34: Track with sched_switch : Ok
35: Filter fds with revents mask in a fdarray : Ok
36: Add fd to a fdarray, making it autogrow : Ok
37: kmod_path__parse : Ok
38: Thread map : Ok
39: LLVM search and compile :
39.1: Basic BPF llvm compile : Ok
39.2: kbuild searching : Ok
39.3: Compile source for BPF prologue generation : Ok
39.4: Compile source for BPF relocation : Ok
40: Session topology : Ok
41: BPF filter :
41.1: Basic BPF filtering : Ok
41.2: BPF pinning : Ok
41.3: BPF prologue generation : Ok
41.4: BPF relocation checker : Ok
42: Synthesize thread map : Ok
43: Remove thread map : Ok
44: Synthesize cpu map : Ok
45: Synthesize stat config : Ok
46: Synthesize stat : Ok
47: Synthesize stat round : Ok
48: Synthesize attr update : Ok
49: Event times : Ok
50: Read backward ring buffer : Ok
51: Print cpu map : Ok
52: Probe SDT events : Ok
53: is_printable_array : Ok
54: Print bitmap : Ok
55: perf hooks : Ok
56: builtin clang support : Skip (not compiled in)
57: unit_number__scnprintf : Ok
58: mem2node : Ok
59: x86 rdpmc : Ok
60: Convert perf time to TSC : Ok
61: DWARF unwind : Ok
62: x86 instruction decoder - new instructions : Ok
63: x86 bp modify : Ok
64: probe libc's inet_pton & backtrace it with ping : Ok
65: Use vfs_getname probe to get syscall args filenames : Ok
66: Add vfs_getname probe to get syscall args filenames : Ok
67: Check open filename arg using perf trace + vfs_getname: Ok $ make -C tools/perf build-test
make: Entering directory '/home/acme/git/perf/tools/perf'
- tarpkg: ./tests/perf-targz-src-pkg .
make_no_libperl_O: make NO_LIBPERL=1
make_clean_all_O: make clean all
make_doc_O: make doc
make_no_scripts_O: make NO_LIBPYTHON=1 NO_LIBPERL=1
make_no_libelf_O: make NO_LIBELF=1
make_help_O: make help
make_util_pmu_bison_o_O: make util/pmu-bison.o
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_perf_o_O: make perf.o
make_no_slang_O: make NO_SLANG=1
make_install_O: make install
make_install_prefix_O: make install prefix=/tmp/krava
make_install_prefix_slash_O: make install prefix=/tmp/krava/
make_no_auxtrace_O: make NO_AUXTRACE=1
make_no_demangle_O: make NO_DEMANGLE=1
make_no_libbionic_O: make NO_LIBBIONIC=1
make_no_newt_O: make NO_NEWT=1
make_no_libnuma_O: make NO_LIBNUMA=1
make_no_gtk2_O: make NO_GTK2=1
make_no_ui_O: make NO_NEWT=1 NO_SLANG=1 NO_GTK2=1
make_with_clangllvm_O: make LIBCLANGLLVM=1
make_no_libaudit_O: make NO_LIBAUDIT=1
make_static_O: make LDFLAGS=-static
make_tags_O: make tags
make_debug_O: make DEBUG=1
make_with_babeltrace_O: make LIBBABELTRACE=1
make_install_bin_O: make install-bin
make_no_libunwind_O: make NO_LIBUNWIND=1
make_no_libdw_dwarf_unwind_O: make NO_LIBDW_DWARF_UNWIND=1
make_util_map_o_O: make util/map.o
make_no_libbpf_O: make NO_LIBBPF=1
make_no_libpython_O: make NO_LIBPYTHON=1
make_pure_O: make
make_no_backtrace_O: make NO_BACKTRACE=1
OK
make: Leaving directory '/home/acme/git/perf/tools/perf'
$Arnaldo Carvalho de Melo
maintainerPATCH 1/75 perf build: Give better hint about devel package for libssl
From: Arnaldo Carvalho de Melo <[email protected]>
In debian/ubuntu its libssl-dev, but for fedora/RHEL/Centos/etc its openssl-devel, fix it.
--- tools/perf/Makefile.config | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
tools/perf/Makefile.config +1 -1
@@ -588,7 +588,7 @@ endif ifndef NO_LIBCRYPTO ifneq ($(feature-libcrypto), 1) - msg := $(warning No libcrypto.h found, disables jitted code injection, please install libssl-devel or libssl-dev); + msg := $(warning No libcrypto.h found, disables jitted code injection, please install openssl-devel or libssl-dev); NO_LIBCRYPTO := 1 else CFLAGS += -DHAVE_LIBCRYPTO_SUPPORT
Signature · 1 line
2.19.2
Arnaldo Carvalho de Melo
maintainerPATCH 2/75 perf stat: Fix shadow stats for clock events
In reply to Arnaldo Carvalho de MeloFrom: Ravi Bangoria <[email protected]>
Commit 0aa802a79469 ("perf stat: Get rid of extra clock display function") introduced scale and unit for clock events. Thus, perf_stat__update_shadow_stats() now saves scaled values of clock events in msecs, instead of original nsecs. But while calculating values of shadow stats we still consider clock event values in nsecs. This results in a wrong shadow stat values. Ex,
# ./perf stat -e task-clock,cycles ls
<SNIP>
2.60 msec task-clock:u # 0.877 CPUs utilized
2,430,564 cycles:u # 1215282.000 GHzFix this by saving original nsec values for clock events in perf_stat__update_shadow_stats(). After patch:
# ./perf stat -e task-clock,cycles ls
<SNIP>
3.14 msec task-clock:u # 0.839 CPUs utilized
3,094,528 cycles:u # 0.985 GHz--- tools/perf/util/stat-shadow.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
tools/perf/util/stat-shadow.c +2 -1
@@ -209,11 +209,12 @@ void perf_stat__update_shadow_stats(struct perf_evsel *counter, u64 count, int cpu, struct runtime_stat *st) { int ctx = evsel_context(counter); +u64 count_ns = count; count *= counter->scale;if (perf_evsel__is_clock (counter)) -update_runtime_stat (st,STAT_NSECS ,0 , cpu, count); +update_runtime_stat (st,STAT_NSECS ,0 , cpu, count_ns);else if (perf_evsel__match (counter,HARDWARE ,HW_CPU_CYCLES ))update_runtime_stat (st,STAT_CYCLES , ctx, cpu, count);else if (perf_stat_evsel__is (counter,CYCLES_IN_TX ))
Signature · 1 line
2.19.2
Arnaldo Carvalho de Melo
maintainerPATCH 3/75 perf stat: Fix CSV mode column output for non-cgroup events
In reply to Arnaldo Carvalho de MeloFrom: Stephane Eranian <[email protected]>
When using the -x option, perf stat prints CSV-style output with one event per line. For each event, it prints the count, the unit, the event name, the cgroup, and a bunch of other event specific fields (such as insn per cycles).
When you use CSV-style mode, you expect a normalized output where each event is printed with the same number of fields regardless of what it is so it can easily be imported into a spreadsheet or parsed.
For instance, if an event does not have a unit, then print an empty field for it.
Although this approach was implemented for the unit, it was not for the cgroup.
When mixing cgroup and non-cgroup events, then non-cgroup events would not show an empty field, instead the next field was printed, make columns not line up correctly.
This patch fixes the cgroup output issues by forcing an empty field for non-cgroup events as soon as one event has cgroup.
Before:
<not counted> @ @cycles @foo @ 0 @100.00@@
2531614 @ @cycles @[email protected]@ @
foo cgroup lines up with time_running!
After:
<not counted> @ @cycles @foo @0 @100.00@@
2594834 @ @cycles @ @5287372 @100.00@@
Fields line up.
--- tools/perf/util/stat-display.c | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-)
tools/perf/util/stat-display.c +11 -5
@@ -59,6 +59,15 @@ static void print_noise(struct perf_stat_config *config,print_noise_pct (config,stddev_stats (&ps->res_stats[0 ]), avg); } +static void print_cgroup (struct perf_stat_config *config,struct perf_evsel *evsel) +{ +if (nr_cgroups) { +const char *cgrp_name = evsel->cgrp ? evsel->cgrp->name :"" ; +fprintf (config->output,"%s%s" , config->csv_sep, cgrp_name); + } +} + +static void aggr_printout (struct perf_stat_config *config,struct perf_evsel *evsel,int id,int nr) {
@@ -336,8 +345,7 @@ static void abs_printout(struct perf_stat_config *config,fprintf (output,"%-*s" , config->csv_output ?0 :25 ,perf_evsel__name (evsel)); -if (evsel->cgrp) -fprintf (output,"%s%s" , config->csv_sep, evsel->cgrp->name); +print_cgroup (config, evsel); }static bool is_mixed_hw_group (struct perf_evsel *counter)
@@ -431,9 +439,7 @@ static void printout(struct perf_stat_config *config, int id, int nr, config->csv_output ?0 :-25 , perf_evsel__name(counter)); -if (counter->cgrp) -fprintf (config->output,"%s%s" , - config->csv_sep, counter->cgrp->name); +print_cgroup (config, counter);if (!config->csv_output)pm (config, &os,NULL ,NULL ,"" ,0 );
Signature · 1 line
2.19.2
Arnaldo Carvalho de Melo
maintainerPATCH 4/75 perf map: Remove extra indirection from map__find()
In reply to Arnaldo Carvalho de MeloFrom: Eric Saint-Etienne <[email protected]>
A double pointer is used in map__find() where a single pointer is enough because the function doesn't affect the rbtree and the rbtree is locked.
--- tools/perf/util/map.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-)
tools/perf/util/map.c +6 -7
@@ -873,19 +873,18 @@ void maps__remove(struct maps *maps, struct map *map)struct map *maps__find (struct maps *maps,u64 ip) { -struct rb_node **p, *parent =NULL ; +struct rb_node *p;struct map *m;down_read (&maps->lock); - p = &maps->entries.rb_node; -while (*p !=NULL ) { - parent = *p; - m = rb_entry(parent, struct map, rb_node); + p = maps->entries.rb_node; +while (p !=NULL ) { + m = rb_entry(p, struct map, rb_node);if (ip < m->start) - p = &(*p)->rb_left; + p = p->rb_left;else if (ip >= m->end) - p = &(*p)->rb_right; + p = p->rb_right;else goto out; }
Signature · 1 line
2.19.2
Arnaldo Carvalho de Melo
maintainerPATCH 5/75 perf env: Also consider env->arch == NULL as local operation
In reply to Arnaldo Carvalho de MeloFrom: Arnaldo Carvalho de Melo <[email protected]>
We'll set a new machine field based on env->arch, which for live mode, like with 'perf top' means we need to use uname() to figure the name of the arch, fix perf_env__arch() to consider both (env == NULL) and (env->arch == NULL) as local operation.
--- tools/perf/util/env.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
tools/perf/util/env.c +1 -1
@@ -166,7 +166,7 @@ const char *perf_env__arch(struct perf_env *env)struct utsname uts;char *arch_name; -if (!env) {/* Assume local operation */ +if (!env || !env->arch) {/* Assume local operation */ if (uname (&uts) <0 )return NULL ; arch_name = uts.machine;
Signature · 1 line
2.19.2
Arnaldo Carvalho de Melo
maintainerPATCH 6/75 perf machine: Record if a arch has a single user/kernel address space
In reply to Arnaldo Carvalho de MeloFrom: Adrian Hunter <[email protected]>
Some architectures have a single address space for kernel and user addresses, which makes it possible to determine if an address is in kernel space or user space. Some don't, e.g.: sparc.
Cache that info in perf_env so that, for instance, code needing to fallback failed symbol lookups at the kernel space in single address space arches can lookup at userspace.
--- tools/perf/arch/common.c | 10 ++++++++++ tools/perf/arch/common.h | 1 + tools/perf/util/machine.h | 1 + tools/perf/util/session.c | 4 ++++ 4 files changed, 16 insertions(+)
tools/perf/arch/common.c +10 -0
@@ -200,3 +200,13 @@ int perf_env__lookup_objdump(struct perf_env *env, const char **path)return perf_env__lookup_binutils_path (env,"objdump" , path); } + +/* +* Some architectures have a single address space for kernel and user addresses, +* which makes it possible to determine if an address is in kernel space or user +* space. +*/ +bool perf_env__single_address_space (struct perf_env *env) +{ +return strcmp (perf_env__arch (env),"sparc" ); +}
tools/perf/arch/common.h +1 -0
@@ -5,5 +5,6 @@#include "../util/env.h" int perf_env__lookup_objdump (struct perf_env *env,const char **path); +bool perf_env__single_address_space (struct perf_env *env);#endif /* ARCH_PERF_COMMON_H */
tools/perf/util/machine.h +1 -0
@@ -42,6 +42,7 @@ struct machine {u16 id_hdr_size;bool comm_exec;bool kptr_restrict_warned; +bool single_address_space;char *root_dir;char *mmap_name;struct threads threads[THREADS__TABLE_SIZE ];
tools/perf/util/session.c +4 -0
@@ -24,6 +24,7 @@#include "thread.h" #include "thread-stack.h" #include "stat.h" +#include "arch/common.h" static int perf_session__deliver_event(struct perf_session *session, union perf_event *event,
@@ -150,6 +151,9 @@ struct perf_session *perf_session__new(struct perf_data *data, session->machines.host.env = &perf_env; } + session->machines.host.single_address_space = +perf_env__single_address_space (session->machines.host.env); +if (!data ||perf_data__is_write (data)) {/* * In O_RDONLY mode this will be performed when reading the
Signature · 1 line
2.19.2
Arnaldo Carvalho de Melo
maintainerPATCH 7/75 perf thread: Add fallback functions for cases where cpumode is insufficient
In reply to Arnaldo Carvalho de MeloFrom: Adrian Hunter <[email protected]>
For branch stacks or branch samples, the sample cpumode might not be correct because it applies only to the sample 'ip' and not necessary to 'addr' or branch stack addresses. Add fallback functions that can be used to deal with those cases
--- tools/perf/util/event.c | 27 +++++++++++++++++++++++++++ tools/perf/util/machine.c | 27 +++++++++++++++++++++++++++ tools/perf/util/machine.h | 2 ++ tools/perf/util/thread.h | 4 ++++ 4 files changed, 60 insertions(+)
tools/perf/util/event.c +27 -0
@@ -1577,6 +1577,24 @@ struct map *thread__find_map(struct thread *thread, u8 cpumode, u64 addr,return al->map; } +/* +* For branch stacks or branch samples, the sample cpumode might not be correct +* because it applies only to the sample 'ip' and not necessary to 'addr' or +* branch stack addresses. If possible, use a fallback to deal with those cases. +*/ +struct map *thread__find_map_fb (struct thread *thread,u8 cpumode,u64 addr, +struct addr_location *al) +{ +struct map *map =thread__find_map (thread, cpumode, addr, al); +struct machine *machine = thread->mg->machine; +u8 addr_cpumode =machine__addr_cpumode (machine, cpumode, addr); + +if (map || addr_cpumode == cpumode) +return map; + +return thread__find_map (thread, addr_cpumode, addr, al); +} +struct symbol *thread__find_symbol (struct thread *thread,u8 cpumode,u64 addr,struct addr_location *al) {
@@ -1586,6 +1604,15 @@ struct symbol *thread__find_symbol(struct thread *thread, u8 cpumode,return al->sym; } +struct symbol *thread__find_symbol_fb (struct thread *thread,u8 cpumode, +u64 addr,struct addr_location *al) +{ + al->sym =NULL ; +if (thread__find_map_fb (thread, cpumode, addr, al)) + al->sym =map__find_symbol (al->map, al->addr); +return al->sym; +} +/* * Callers need to drop the reference to al->thread, obtained in * machine__findnew_thread()
tools/perf/util/machine.c +27 -0
@@ -2592,6 +2592,33 @@ int machine__get_kernel_start(struct machine *machine)return err; } +u8 machine__addr_cpumode (struct machine *machine,u8 cpumode,u64 addr) +{ +u8 addr_cpumode = cpumode; +bool kernel_ip; + +if (!machine->single_address_space) + goto out; + + kernel_ip =machine__kernel_ip (machine, addr); +switch (cpumode) { +case PERF_RECORD_MISC_KERNEL : +case PERF_RECORD_MISC_USER : + addr_cpumode = kernel_ip ?PERF_RECORD_MISC_KERNEL : +PERF_RECORD_MISC_USER ; +break ; +case PERF_RECORD_MISC_GUEST_KERNEL : +case PERF_RECORD_MISC_GUEST_USER : + addr_cpumode = kernel_ip ?PERF_RECORD_MISC_GUEST_KERNEL : +PERF_RECORD_MISC_GUEST_USER ; +break ; +default : +break ; + } +out: +return addr_cpumode; +} +struct dso *machine__findnew_dso (struct machine *machine,const char *filename) {return dsos__findnew (&machine->dsos, filename);
tools/perf/util/machine.h +2 -0
@@ -100,6 +100,8 @@ static inline bool machine__kernel_ip(struct machine *machine, u64 ip)return ip >= kernel_start; } +u8 machine__addr_cpumode (struct machine *machine,u8 cpumode,u64 addr); +struct thread *machine__find_thread (struct machine *machine,pid_t pid,pid_t tid); struct comm *machine__thread_exec_comm(struct machine *machine,
tools/perf/util/thread.h +4 -0
@@ -96,9 +96,13 @@ struct thread *thread__main_thread(struct machine *machine, struct thread *threastruct map *thread__find_map (struct thread *thread,u8 cpumode,u64 addr,struct addr_location *al); +struct map *thread__find_map_fb (struct thread *thread,u8 cpumode,u64 addr, +struct addr_location *al);struct symbol *thread__find_symbol (struct thread *thread,u8 cpumode,u64 addr,struct addr_location *al); +struct symbol *thread__find_symbol_fb (struct thread *thread,u8 cpumode, +u64 addr,struct addr_location *al);void thread__find_cpumode_addr_location (struct thread *thread,u64 addr,struct addr_location *al);
Signature · 1 line
2.19.2
Arnaldo Carvalho de Melo
maintainerPATCH 8/75 perf tools: Use fallback for sample_addr_correlates_sym() cases
In reply to Arnaldo Carvalho de MeloFrom: Adrian Hunter <[email protected]>
thread__resolve() is used in the sample_addr_correlates_sym() cases where 'addr' is a destination of a branch which does not necessarily have the same cpumode as the 'ip'. Use the fallback function in that case.
This patch depends on patch "perf tools: Add fallback functions for cases where cpumode is insufficient".
--- tools/perf/util/event.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
tools/perf/util/event.c +1 -1
@@ -1706,7 +1706,7 @@ bool sample_addr_correlates_sym(struct perf_event_attr *attr)void thread__resolve (struct thread *thread,struct addr_location *al,struct perf_sample *sample) { -thread__find_map (thread, sample->cpumode, sample->addr, al); +thread__find_map_fb (thread, sample->cpumode, sample->addr, al); al->cpu = sample->cpu; al->sym =NULL ;
Signature · 1 line
2.19.2
Arnaldo Carvalho de Melo
maintainerPATCH 9/75 perf script: Use fallbacks for branch stacks
In reply to Arnaldo Carvalho de MeloFrom: Adrian Hunter <[email protected]>
Branch stacks do not necessarily have the same cpumode as the 'ip'. Use the fallback functions in those cases.
This patch depends on patch "perf tools: Add fallback functions for cases where cpumode is insufficient".
--- tools/perf/builtin-script.c | 12 ++++++------ .../util/scripting-engines/trace-event-python.c | 16 ++++++++-------- 2 files changed, 14 insertions(+), 14 deletions(-)
tools/perf/builtin-script.c +6 -6
@@ -724,8 +724,8 @@ static int perf_sample__fprintf_brstack(struct perf_sample *sample,if (PRINT_FIELD (DSO )) {memset (&alf,0 ,sizeof (alf));memset (&alt,0 ,sizeof (alt)); -thread__find_map (thread, sample->cpumode, from, &alf); -thread__find_map (thread, sample->cpumode, to, &alt); +thread__find_map_fb (thread, sample->cpumode, from, &alf); +thread__find_map_fb (thread, sample->cpumode, to, &alt); } printed +=fprintf (fp," 0x%" PRIx64, from);
@@ -771,8 +771,8 @@ static int perf_sample__fprintf_brstacksym(struct perf_sample *sample, from = br->entries[i].from; to = br->entries[i].to; -thread__find_symbol (thread, sample->cpumode, from, &alf); -thread__find_symbol (thread, sample->cpumode, to, &alt); +thread__find_symbol_fb (thread, sample->cpumode, from, &alf); +thread__find_symbol_fb (thread, sample->cpumode, to, &alt); printed +=symbol__fprintf_symname_offs (alf.sym, &alf, fp);if (PRINT_FIELD (DSO )) {
@@ -816,11 +816,11 @@ static int perf_sample__fprintf_brstackoff(struct perf_sample *sample, from = br->entries[i].from; to = br->entries[i].to; -if (thread__find_map (thread, sample->cpumode, from, &alf) && +if (thread__find_map_fb (thread, sample->cpumode, from, &alf) && !alf.map->dso->adjust_symbols) from =map__map_ip (alf.map, from); -if (thread__find_map (thread, sample->cpumode, to, &alt) && +if (thread__find_map_fb (thread, sample->cpumode, to, &alt) && !alt.map->dso->adjust_symbols) to =map__map_ip (alt.map, to);
tools/perf/util/scripting-engines/trace-event-python.c +8 -8
@@ -494,14 +494,14 @@ static PyObject *python_process_brstack(struct perf_sample *sample,pydict_set_item_string_decref (pyelem,"cycles" ,PyLong_FromUnsignedLongLong (br->entries[i].flags.cycles)); -thread__find_map (thread, sample->cpumode, - br->entries[i].from, &al); +thread__find_map_fb (thread, sample->cpumode, + br->entries[i].from, &al); dsoname =get_dsoname (al.map);pydict_set_item_string_decref (pyelem,"from_dsoname" ,_PyUnicode_FromString (dsoname)); -thread__find_map (thread, sample->cpumode, - br->entries[i].to, &al); +thread__find_map_fb (thread, sample->cpumode, + br->entries[i].to, &al); dsoname =get_dsoname (al.map);pydict_set_item_string_decref (pyelem,"to_dsoname" ,_PyUnicode_FromString (dsoname));
@@ -576,14 +576,14 @@ static PyObject *python_process_brstacksym(struct perf_sample *sample,if (!pyelem)Py_FatalError ("couldn't create Python dictionary" ); -thread__find_symbol (thread, sample->cpumode, - br->entries[i].from, &al); +thread__find_symbol_fb (thread, sample->cpumode, + br->entries[i].from, &al);get_symoff (al.sym, &al, true, bf,sizeof (bf));pydict_set_item_string_decref (pyelem,"from" ,_PyUnicode_FromString (bf)); -thread__find_symbol (thread, sample->cpumode, - br->entries[i].to, &al); +thread__find_symbol_fb (thread, sample->cpumode, + br->entries[i].to, &al);get_symoff (al.sym, &al, true, bf,sizeof (bf));pydict_set_item_string_decref (pyelem,"to" ,_PyUnicode_FromString (bf));
Signature · 1 line
2.19.2
Arnaldo Carvalho de Melo
maintainerPATCH 10/75 tools lib traceevent: Fix compile warnings in tools/lib/traceevent/event-parse.c
In reply to Arnaldo Carvalho de MeloFrom: Adrian Hunter <[email protected]>
Fix following warnings:
event-parse.c: In function ‘tep_find_event_by_name’:
event-parse.c:3521:21: warning: ‘event’ may be used uninitialized in this function [-Wmaybe-uninitialized]
pevent->last_event = event;
~~~~~~~~~~~~~~~~~~~^~~~~~~
CC ui/gtk/hists.o
LINK plugin_mac80211.so
CC nlattr.o
event-parse.c: In function ‘tep_data_lat_fmt’:
event-parse.c:5200:4: warning: ‘migrate_disable’ may be used uninitialized in this function [-Wmaybe-uninitialized]
trace_seq_printf(s, "%d", migrate_disable);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
event-parse.c:5207:4: warning: ‘lock_depth’ may be used uninitialized in this function [-Wmaybe-uninitialized]
trace_seq_printf(s, "%d", lock_depth);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
LINK plugin_sched_switch.so
LINK plugin_function.so
LINK plugin_xen.so
event-parse.c: In function ‘tep_event_info’:
event-parse.c:5047:7: warning: ‘len_arg’ may be used uninitialized in this function [-Wmaybe-uninitialized]
trace_seq_printf(s, format, len_arg, (char)val);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
event-parse.c:4884:6: note: ‘len_arg’ was declared here
int len_arg;
^~~~~~~
event-parse.c:4338:11: warning: ‘vsize’ may be used uninitialized in this function [-Wmaybe-uninitialized]
val = tep_read_number(pevent, bptr, vsize);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
event-parse.c:4224:6: note: ‘vsize’ was declared here
int vsize;
^~~~~$ gcc --version gcc (Clear Linux OS for Intel Architecture) 8.2.1 20180502
--- tools/lib/traceevent/event-parse.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-)
tools/lib/traceevent/event-parse.c +5 -5
@@ -3498,7 +3498,7 @@ struct tep_event_format * tep_find_event_by_name(struct tep_handle *pevent, const char *sys, const char *name) { - struct tep_event_format *event; + struct tep_event_format *event = NULL;int i; if (pevent->last_event &&
@@ -4221,7 +4221,7 @@ static struct tep_print_arg *make_bprint_args(char *fmt, void *data, int size, sunsigned long long ip, val;char *ptr;void *bptr; -int vsize; +int vsize =0 ; field = pevent->bprint_buf_field; ip_field = pevent->bprint_ip_field;
@@ -4881,7 +4881,7 @@ static void pretty_print(struct trace_seq *s, void *data, int size, struct tep_echar format[32 ];int show_func;int len_as_arg; -int len_arg; +int len_arg =0 ;int len;int ls;
@@ -5146,8 +5146,8 @@ void tep_data_lat_fmt(struct tep_handle *pevent,static int migrate_disable_exists;unsigned int lat_flags;unsigned int pc; -int lock_depth; -int migrate_disable; +int lock_depth =0 ; +int migrate_disable =0 ;int hardirq;int softirq;void *data = record->data;
Signature · 1 line
2.19.2
Arnaldo Carvalho de Melo
maintainerPATCH 11/75 perf tests record: Allow for 'sleep' being 'coreutils'
In reply to Arnaldo Carvalho de MeloFrom: Adrian Hunter <[email protected]>
If the 'sleep' command is provided by coreutils, then the "PERF_RECORD_* events & perf_sample fields" test will fail because the MMAP name is 'coreutils' not 'sleep', and there is an extra COMM event. Fix the test to detect that case.
--- tools/perf/tests/perf-record.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-)
tools/perf/tests/perf-record.c +5 -2
@@ -58,6 +58,7 @@ int test__PERF_RECORD(struct test *test __maybe_unused, int subtest __maybe_unuschar *bname, *mmap_filename;u64 prev_time =0 ;bool found_cmd_mmap = false, + found_coreutils_mmap = false, found_libc_mmap = false, found_vdso_mmap = false, found_ld_mmap = false;
@@ -254,6 +255,8 @@ int test__PERF_RECORD(struct test *test __maybe_unused, int subtest __maybe_unusif (bname !=NULL ) {if (!found_cmd_mmap) found_cmd_mmap = !strcmp (bname +1 , cmd); +if (!found_coreutils_mmap) + found_coreutils_mmap = !strcmp (bname +1 ,"coreutils" );if (!found_libc_mmap) found_libc_mmap = !strncmp (bname +1 ,"libc" ,4 );if (!found_ld_mmap)
@@ -292,7 +295,7 @@ int test__PERF_RECORD(struct test *test __maybe_unused, int subtest __maybe_unus } found_exit: -if (nr_events[PERF_RECORD_COMM ] >1 ) { +if (nr_events[PERF_RECORD_COMM ] >1 + !!found_coreutils_mmap) {pr_debug ("Excessive number of PERF_RECORD_COMM events!\n" ); ++errs; }
@@ -302,7 +305,7 @@ int test__PERF_RECORD(struct test *test __maybe_unused, int subtest __maybe_unus ++errs; } -if (!found_cmd_mmap) { +if (!found_cmd_mmap && !found_coreutils_mmap) {pr_debug ("PERF_RECORD_MMAP for %s missing!\n" , cmd); ++errs; }
Signature · 1 line
2.19.2
Arnaldo Carvalho de Melo
maintainerPATCH 12/75 perf test: Fix perf_event_attr test failure
In reply to Arnaldo Carvalho de MeloFrom: Adrian Hunter <[email protected]>
Fix inconsistent use of tabs and spaces error:
# perf test 16 -v
16: Setup struct perf_event_attr :
--- start ---
test child forked, pid 20224
File "/usr/libexec/perf-core/tests/attr.py", line 119
log.warning("expected %s=%s, got %s" % (t, self[t], other[t]))
^
TabError: inconsistent use of tabs and spaces in indentation
test child finished with -1
---- end ----
Setup struct perf_event_attr: FAILED!--- tools/perf/tests/attr.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
tools/perf/tests/attr.py +1 -1
@@ -116,7 +116,7 @@ class Event(dict): if not self.has_key(t) or not other.has_key(t): continue if not data_equal(self[t], other[t]): - log.warning("expected %s=%s, got %s" % (t, self[t], other[t])) + log.warning("expected %s=%s, got %s" % (t, self[t], other[t])) # Test file description needs to have following sections: # [config]
Signature · 1 line
2.19.2
Arnaldo Carvalho de Melo
maintainerPATCH 13/75 tools include: Adopt ERR_CAST() from the kernel err.h header
In reply to Arnaldo Carvalho de MeloFrom: Arnaldo Carvalho de Melo <[email protected]>
Add ERR_CAST(), so that tools can use it, just like the kernel.
This addresses coccinelle checks that are being performed to tools/ in addition to kernel sources, so lets add this to cover that and to get tools code closer to kernel coding standards.
This originally was introduced in the kernel headers in this cset:
d1bc8e954452 ("Add an ERR_CAST() function to complement ERR_PTR and co.")
--- tools/include/linux/err.h | 13 +++++++++++++ 1 file changed, 13 insertions(+)
tools/include/linux/err.h +13 -0
@@ -59,4 +59,17 @@ static inline int __must_check PTR_ERR_OR_ZERO(__force const void *ptr) else return 0; } + +/** +* ERR_CAST - Explicitly cast an error-valued pointer to another pointer type +* @ptr: The pointer to cast. +* +* Explicitly cast an error-valued pointer to another pointer type in such a +* way as to make it clear that's what's going on. +*/ +static inline void *__must_check ERR_CAST (__force const void *ptr) +{ +/* cast away the const */ +return (void *) ptr; +}#endif /* _LINUX_ERR_H */
Signature · 1 line
2.19.2
Arnaldo Carvalho de Melo
maintainerPATCH 14/75 perf bpf: Use ERR_CAST instead of ERR_PTR(PTR_ERR())
In reply to Arnaldo Carvalho de MeloFrom: Wen Yang <[email protected]>
Use ERR_CAST inlined function instead of ERR_PTR(PTR_ERR(...)). This makes it more readable and also fix this warning detected by err_cast.cocci:
tools/perf/util/bpf-loader.c:1606:11-18: WARNING: ERR_CAST can be used with op
--- tools/perf/util/bpf-loader.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
tools/perf/util/bpf-loader.c +1 -1
@@ -1603,7 +1603,7 @@ struct perf_evsel *bpf__setup_output_event(struct perf_evlist *evlist, const cha op =bpf_map__add_newop (map,NULL );if (IS_ERR (op)) -return ERR_PTR (PTR_ERR (op)); +return ERR_CAST (op); op->op_type =BPF_MAP_OP_SET_EVSEL ; op->v.evsel = evsel; }
Signature · 1 line
2.19.2
Arnaldo Carvalho de Melo
maintainerPATCH 15/75 perf top: Allow passing a kallsyms file
In reply to Arnaldo Carvalho de MeloFrom: Arnaldo Carvalho de Melo <[email protected]>
This basically replicates what was done for 'perf report' in:
b226a5a72901 ("perf report: Allow user to specify path to kallsyms file")
This should help with resolving eBPF symbols, that are in kallsyms but, of course, not in vmlinux.
--- tools/perf/Documentation/perf-top.txt | 3 +++ tools/perf/builtin-top.c | 2 ++ 2 files changed, 5 insertions(+)
tools/perf/Documentation/perf-top.txt +3 -0
@@ -70,6 +70,9 @@ Default is to monitor all CPUS. --ignore-vmlinux:: Ignore vmlinux files. +--kallsyms=<file>:: + kallsyms pathname + -m <pages>:: --mmap-pages=<pages>:: Number of mmap data pages (must be a power of two) or size
tools/perf/builtin-top.c +2 -0
@@ -1289,6 +1289,8 @@ int cmd_top(int argc, const char **argv) "file", "vmlinux pathname"),OPT_BOOLEAN (0 ,"ignore-vmlinux" , &symbol_conf.ignore_vmlinux,"don't load vmlinux even if found" ), +OPT_STRING (0 ,"kallsyms" , &symbol_conf.kallsyms_name, +"file" ,"kallsyms pathname" ),OPT_BOOLEAN ('K' ,"hide_kernel_symbols" , &top.hide_kernel_symbols,"hide kernel symbols" ), OPT_CALLBACK('m', "mmap-pages", &opts->mmap_pages, "pages",
Signature · 1 line
2.19.2
Arnaldo Carvalho de Melo
maintainerPATCH 16/75 perf intel-pt: Fix error with config term "pt=0"
In reply to Arnaldo Carvalho de MeloFrom: Adrian Hunter <[email protected]>
Users should never use 'pt=0', but if they do it may give a meaningless error:
$ perf record -e intel_pt/pt=0/u uname Error: The sys_perf_event_open() syscall returned with 22 (Invalid argument) for event (intel_pt/pt=0/u).
Fix that by forcing 'pt=1'.
Committer testing:
# perf record -e intel_pt/pt=0/u uname Error: The sys_perf_event_open() syscall returned with 22 (Invalid argument) for event (intel_pt/pt=0/u). /bin/dmesg | grep -i perf may provide additional information.
# perf record -e intel_pt/pt=0/u uname pt=0 doesn't make sense, forcing pt=1 Linux [ perf record: Woken up 1 times to write data ] [ perf record: Captured and wrote 0.020 MB perf.data ] #
--- tools/perf/arch/x86/util/intel-pt.c | 11 +++++++++++ 1 file changed, 11 insertions(+)
tools/perf/arch/x86/util/intel-pt.c +11 -0
@@ -524,10 +524,21 @@ static int intel_pt_validate_config(struct perf_pmu *intel_pt_pmu, struct perf_evsel *evsel) {int err; +char c;if (!evsel)return 0 ; +/* +* If supported, force pass-through config term (pt=1) even if user +* sets pt=0, which avoids senseless kernel errors. +*/ +if (perf_pmu__scan_file (intel_pt_pmu,"format/pt" ,"%c" , &c) ==1 && + !(evsel->attr.config &1 )) { +pr_warning ("pt=0 doesn't make sense, forcing pt=1\n" ); + evsel->attr.config |=1 ; + } + err =intel_pt_val_config_term (intel_pt_pmu,"caps/cycle_thresholds" ,"cyc_thresh" ,"caps/psb_cyc" , evsel->attr.config);
Signature · 1 line
2.19.2
Arnaldo Carvalho de Melo
maintainerPATCH 17/75 tools build feature: Check if libaio is available
In reply to Arnaldo Carvalho de MeloFrom: Alexey Budankov <[email protected]>
This will be used by 'perf record' to speed up reading the perf ring buffer.
Committer testing:
$ make -C tools/perf O=/tmp/build/perf
make: Entering directory '/home/acme/git/perf/tools/perf'
BUILD: Doing 'make -j8' parallel buildAuto-detecting system features:
... dwarf: [ on ] ... dwarf_getlocations: [ on ] ... glibc: [ on ] ... gtk2: [ OFF ] ... libaudit: [ OFF ] ... libbfd: [ OFF ] ... libelf: [ on ] ... libnuma: [ OFF ] ... numa_num_possible_cpus: [ OFF ] ... libperl: [ OFF ] ... libpython: [ OFF ] ... libslang: [ on ] ... libcrypto: [ on ] ... libunwind: [ on ] ... libdw-dwarf-unwind: [ on ] ... zlib: [ on ] ... lzma: [ on ] ... get_cpuid: [ on ] ... bpf: [ on ] ... libaio: [ on ]
$ ls -la /tmp/build/perf/feature/test-libaio.* -rwxrwxr-x. 1 acme acme 18296 Nov 26 08:49 /tmp/build/perf/feature/test-libaio.bin -rw-rw-r--. 1 acme acme 1165 Nov 26 08:49 /tmp/build/perf/feature/test-libaio.d -rw-rw-r--. 1 acme acme 0 Nov 26 08:49 /tmp/build/perf/feature/test-libaio.make.output $ $ grep -i aio /tmp/build/perf/FEATURE-DUMP feature-libaio=1 $
--- tools/build/Makefile.feature | 6 ++++-- tools/build/feature/Makefile | 6 +++++- tools/build/feature/test-all.c | 5 +++++ tools/build/feature/test-libaio.c | 16 ++++++++++++++++ tools/perf/Makefile.config | 6 ++++++ tools/perf/Makefile.perf | 7 ++++++- 6 files changed, 42 insertions(+), 4 deletions(-) create mode 100644 tools/build/feature/test-libaio.c
tools/build/Makefile.feature +4 -2
@@ -70,7 +70,8 @@ FEATURE_TESTS_BASIC := \ sched_getcpu \ sdt \ setns \ - libopencsd + libopencsd \ + libaio # FEATURE_TESTS_BASIC + FEATURE_TESTS_EXTRA is the complete list # of all feature tests
@@ -116,7 +117,8 @@ FEATURE_DISPLAY ?= \ zlib \ lzma \ get_cpuid \ - bpf + bpf \ + libaio # Set FEATURE_CHECK_(C|LD)FLAGS-all for all FEATURE_TESTS features. # If in the future we need per-feature checks/flags for features not
tools/build/feature/Makefile +5 -1
@@ -61,7 +61,8 @@ FILES= \ test-libopencsd.bin \ test-clang.bin \ test-llvm.bin \ - test-llvm-version.bin + test-llvm-version.bin \ + test-libaio.bin FILES := $(addprefix $(OUTPUT),$(FILES))
@@ -297,6 +298,9 @@ $(OUTPUT)test-clang.bin: -include $(OUTPUT)*.d +$(OUTPUT)test-libaio.bin: + $(BUILD) -lrt + ############################### clean:
tools/build/feature/test-all.c +5 -0
@@ -174,6 +174,10 @@# include "test-libopencsd.c" #undef main +#define main main_test_libaio +# include "test-libaio.c" +#undef main +int main (int argc,char *argv[]) {main_test_libpython ();
@@ -214,6 +218,7 @@ int main(int argc, char *argv[])main_test_sdt ();main_test_setns ();main_test_libopencsd (); +main_test_libaio ();return 0 ; }
tools/build/feature/test-libaio.c new file +16 -0
@@ -0,0 +1,16 @@ +// SPDX-License-Identifier: GPL-2.0 +#include <aio.h> + +int main (void ) +{ +struct aiocb aiocb; + + aiocb.aio_fildes =0 ; + aiocb.aio_offset =0 ; + aiocb.aio_buf =0 ; + aiocb.aio_nbytes =0 ; + aiocb.aio_reqprio =0 ; + aiocb.aio_sigevent.sigev_notify =1 /*SIGEV_NONE*/ ; + +return (int )aio_return (&aiocb); +}
tools/perf/Makefile.config +6 -0
@@ -365,6 +365,12 @@ ifeq ($(feature-glibc), 1) CFLAGS += -DHAVE_GLIBC_SUPPORT endif +ifeq ($(feature-libaio), 1) + ifndef NO_AIO + CFLAGS += -DHAVE_AIO_SUPPORT + endif +endif + ifdef NO_DWARF NO_LIBDW_DWARF_UNWIND := 1 endif
tools/perf/Makefile.perf +6 -1
@@ -101,8 +101,13 @@ include ../scripts/utilities.mak # Define LIBCLANGLLVM if you DO want builtin clang and llvm support. # When selected, pass LLVM_CONFIG=/path/to/llvm-config to `make' if # llvm-config is not in $PATH. - +# # Define NO_CORESIGHT if you do not want support for CoreSight trace decoding. +# +# Define NO_AIO if you do not want support of Posix AIO based trace +# streaming for record mode. Currently Posix AIO trace streaming is +# supported only when linking with glibc. +# # As per kernel Makefile, avoid funny character set dependencies unexport LC_ALL
Signature · 1 line
2.19.2
Arnaldo Carvalho de Melo
maintainerPATCH 18/75 perf mmap: Map data buffer for preserving collected data
In reply to Arnaldo Carvalho de MeloFrom: Alexey Budankov <[email protected]>
The map->data buffer is used to preserve map->base profiling data for writing to disk. AIO map->cblock is used to queue corresponding map->data buffer for asynchronous writing.
--- tools/perf/util/evlist.c | 2 +- tools/perf/util/mmap.c | 49 +++++++++++++++++++++++++++++++++++++++- tools/perf/util/mmap.h | 11 ++++++++- 3 files changed, 59 insertions(+), 3 deletions(-)
tools/perf/util/evlist.c +1 -1
@@ -1028,7 +1028,7 @@ int perf_evlist__mmap_ex(struct perf_evlist *evlist, unsigned int pages,* Its value is decided by evsel's write_backward. * So &mp should not be passed through const pointer. */ -struct mmap_params mp; +struct mmap_params mp = { .nr_cblocks =0 };if (!evlist->mmap) evlist->mmap =perf_evlist__alloc_mmap (evlist, false);
tools/perf/util/mmap.c +48 -1
63 lines not on this page · raw message
tools/perf/util/mmap.h +10 -1
@@ -6,6 +6,9 @@#include <linux/types.h> #include <linux/ring_buffer.h> #include <stdbool.h> +#ifdef HAVE_AIO_SUPPORT +#include <aio.h> +#endif #include "auxtrace.h" #include "event.h"
@@ -26,6 +29,12 @@ struct perf_mmap {bool overwrite;struct auxtrace_mmap auxtrace_mmap;char event_copy[PERF_SAMPLE_MAX_SIZE ]__aligned(8) ; +#ifdef HAVE_AIO_SUPPORT +struct { +void *data; +struct aiocb cblock; + } aio; +#endif };/*
@@ -57,7 +66,7 @@ enum bkw_mmap_state { };struct mmap_params { -int prot, mask; +int prot, mask, nr_cblocks;struct auxtrace_mmap_params auxtrace_mp; };
Signature · 1 line
2.19.2
Arnaldo Carvalho de Melo
maintainerPATCH 19/75 perf record: Enable asynchronous trace writing
In reply to Arnaldo Carvalho de MeloFrom: Alexey Budankov <[email protected]>
The trace file offset is read once before mmaps iterating loop and written back after all performance data is enqueued for aio writing.
The trace file offset is incremented linearly after every successful aio write operation.
record__aio_sync() blocks till completion of the started AIO operation and then proceeds.
record__aio_mmap_read_sync() implements a barrier for all incomplete aio write requests.
--- tools/perf/Documentation/perf-record.txt | 5 + tools/perf/builtin-record.c | 218 ++++++++++++++++++++++- tools/perf/perf.h | 1 + tools/perf/util/evlist.c | 6 +- tools/perf/util/evlist.h | 2 +- tools/perf/util/mmap.c | 77 +++++++- tools/perf/util/mmap.h | 14 ++ 7 files changed, 314 insertions(+), 9 deletions(-)
tools/perf/Documentation/perf-record.txt +5 -0
@@ -435,6 +435,11 @@ Specify vmlinux path which has debuginfo. --buildid-all:: Record build-id of all DSOs regardless whether it's actually hit or not. +--aio:: +Enable asynchronous (Posix AIO) trace writing mode. +Asynchronous mode is supported only when linking Perf tool with libc library +providing implementation for Posix AIO API. + --all-kernel:: Configure all used events to run in kernel space.
tools/perf/builtin-record.c +214 -4
276 lines not on this page · raw message
tools/perf/perf.h +1 -0
@@ -83,6 +83,7 @@ struct record_opts {clockid_t clockid;u64 clockid_res_ns;unsigned int proc_map_timeout; +int nr_cblocks; };struct option ;
tools/perf/util/evlist.c +3 -3
@@ -1018,7 +1018,7 @@ int perf_evlist__parse_mmap_pages(const struct option *opt, const char *str,*/ int perf_evlist__mmap_ex (struct perf_evlist *evlist,unsigned int pages,unsigned int auxtrace_pages, -bool auxtrace_overwrite) +bool auxtrace_overwrite,int nr_cblocks) {struct perf_evsel *evsel;const struct cpu_map *cpus = evlist->cpus;
@@ -1028,7 +1028,7 @@ int perf_evlist__mmap_ex(struct perf_evlist *evlist, unsigned int pages,* Its value is decided by evsel's write_backward. * So &mp should not be passed through const pointer. */ -struct mmap_params mp = { .nr_cblocks =0 }; +struct mmap_params mp = { .nr_cblocks = nr_cblocks };if (!evlist->mmap) evlist->mmap =perf_evlist__alloc_mmap (evlist, false);
@@ -1060,7 +1060,7 @@ int perf_evlist__mmap_ex(struct perf_evlist *evlist, unsigned int pages,int perf_evlist__mmap (struct perf_evlist *evlist,unsigned int pages) { -return perf_evlist__mmap_ex (evlist, pages,0 , false); +return perf_evlist__mmap_ex (evlist, pages,0 , false,0 ); }int perf_evlist__create_maps (struct perf_evlist *evlist,struct target *target)
tools/perf/util/evlist.h +1 -1
@@ -162,7 +162,7 @@ unsigned long perf_event_mlock_kb_in_pages(void);int perf_evlist__mmap_ex (struct perf_evlist *evlist,unsigned int pages,unsigned int auxtrace_pages, -bool auxtrace_overwrite); +bool auxtrace_overwrite,int nr_cblocks);int perf_evlist__mmap (struct perf_evlist *evlist,unsigned int pages);void perf_evlist__munmap (struct perf_evlist *evlist);
tools/perf/util/mmap.c +76 -1
89 lines not on this page · raw message
tools/perf/util/mmap.h +14 -0
@@ -12,6 +12,7 @@#include "auxtrace.h" #include "event.h" +struct aiocb ;/** * struct perf_mmap - perf's ring buffer mmap details *
@@ -33,6 +34,7 @@ struct perf_mmap {struct {void *data;struct aiocb cblock; +int nr_cblocks; } aio;#endif };
@@ -94,6 +96,18 @@ union perf_event *perf_mmap__read_event(struct perf_mmap *map);int perf_mmap__push (struct perf_mmap *md,void *to,int push (struct perf_mmap *map,void *to,void *buf,size_t size)); +#ifdef HAVE_AIO_SUPPORT +int perf_mmap__aio_push (struct perf_mmap *md,void *to, +int push (void *to,struct aiocb *cblock,void *buf,size_t size,off_t off), +off_t *off); +#else +static inline int perf_mmap__aio_push (struct perf_mmap *md__maybe_unused ,void *to__maybe_unused , +int push (void *to,struct aiocb *cblock,void *buf,size_t size,off_t off)__maybe_unused , +off_t *off__maybe_unused ) +{ +return 0 ; +} +#endif size_t perf_mmap__mmap_len (struct perf_mmap *map);
Signature · 1 line
2.19.2
Arnaldo Carvalho de Melo
maintainerPATCH 20/75 perf record: Extend trace writing to multi AIO
In reply to Arnaldo Carvalho de MeloFrom: Alexey Budankov <[email protected]>
Multi AIO trace writing allows caching more kernel data into userspace memory postponing trace writing for the sake of overall profiling data thruput increase. It could be seen as kernel data buffer extension into userspace memory.
With an --aio option value different from 0 (default value is 1) the tool has capability to cache more and more data into user space along with delegating spill to AIO.
That allows avoiding to suspend at record__aio_sync() between calls of record__mmap_read_evlist() and increases profiling data thruput at the cost of userspace memory.
--- tools/perf/Documentation/perf-record.txt | 4 +- tools/perf/builtin-record.c | 67 ++++++++++++++++++------ tools/perf/util/mmap.c | 64 ++++++++++++++-------- tools/perf/util/mmap.h | 9 ++-- 4 files changed, 102 insertions(+), 42 deletions(-)
tools/perf/Documentation/perf-record.txt +2 -2
@@ -435,8 +435,8 @@ Specify vmlinux path which has debuginfo. --buildid-all:: Record build-id of all DSOs regardless whether it's actually hit or not. ---aio:: -Enable asynchronous (Posix AIO) trace writing mode. +--aio[=n]:: +Use <n> control blocks in asynchronous (Posix AIO) trace writing mode (default: 1, max: 4). Asynchronous mode is supported only when linking Perf tool with libc library providing implementation for Posix AIO API.
tools/perf/builtin-record.c +52 -15
128 lines not on this page · raw message
tools/perf/util/mmap.c +43 -21
112 lines not on this page · raw message
tools/perf/util/mmap.h +5 -4
@@ -32,8 +32,9 @@ struct perf_mmap {char event_copy[PERF_SAMPLE_MAX_SIZE ]__aligned(8) ;#ifdef HAVE_AIO_SUPPORT struct { -void *data; -struct aiocb cblock; +void **data; +struct aiocb *cblocks; +struct aiocb **aiocb;int nr_cblocks; } aio;#endif
@@ -97,11 +98,11 @@ union perf_event *perf_mmap__read_event(struct perf_mmap *map);int perf_mmap__push (struct perf_mmap *md,void *to,int push (struct perf_mmap *map,void *to,void *buf,size_t size));#ifdef HAVE_AIO_SUPPORT -int perf_mmap__aio_push (struct perf_mmap *md,void *to, +int perf_mmap__aio_push (struct perf_mmap *md,void *to,int idx,int push (void *to,struct aiocb *cblock,void *buf,size_t size,off_t off),off_t *off);#else -static inline int perf_mmap__aio_push (struct perf_mmap *md__maybe_unused ,void *to__maybe_unused , +static inline int perf_mmap__aio_push (struct perf_mmap *md__maybe_unused ,void *to__maybe_unused ,int idx__maybe_unused ,int push (void *to,struct aiocb *cblock,void *buf,size_t size,off_t off)__maybe_unused ,off_t *off__maybe_unused ) {
Signature · 1 line
2.19.2
Arnaldo Carvalho de Melo
maintainerPATCH 21/75 perf beauty mmap_flags: Check if the arch has a mmap.h file
In reply to Arnaldo Carvalho de MeloFrom: Arnaldo Carvalho de Melo <[email protected]>
If not, then just use what is in asm-generic. This fixes the build for my sh4, m68k and riscv64 perf test build containers that were failing due to 80ee5668b8a7 ("perf beauty: Add a generator for MAP_ mmap's flag constants"), that were not covered in the cset introducing those tools/arch/*/include/uapi/asm/mman.h files.
f3539c12d819 ("tools include: Add uapi mman.h for each architecture")
--- tools/perf/Makefile.perf | 2 +- tools/perf/trace/beauty/mmap_flags.sh | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-)
tools/perf/Makefile.perf +1 -1
@@ -474,7 +474,7 @@ $(madvise_behavior_array): $(madvise_hdr_dir)/mman-common.h $(madvise_behavior_t mmap_flags_array := $(beauty_outdir)/mmap_flags_array.c mmap_flags_tbl := $(srctree)/tools/perf/trace/beauty/mmap_flags.sh -$(mmap_flags_array): $(asm_generic_uapi_dir)/mman.h $(asm_generic_uapi_dir)/mman-common.h $(arch_asm_uapi_dir)/mman.h $(mmap_flags_tbl) +$(mmap_flags_array): $(asm_generic_uapi_dir)/mman.h $(asm_generic_uapi_dir)/mman-common.h $(mmap_flags_tbl) $(Q)$(SHELL) '$(mmap_flags_tbl)' $(asm_generic_uapi_dir) $(arch_asm_uapi_dir) > $@ mount_flags_array := $(beauty_outdir)/mount_flags_array.c
tools/perf/trace/beauty/mmap_flags.sh +2 -2
@@ -20,12 +20,12 @@ egrep -q $regex ${arch_mman} && \ (egrep $regex ${arch_mman} | \ sed -r "s/$regex/\2 \1/g" | \ xargs printf "\t[ilog2(%s) + 1] = \"%s\",\n") -egrep -q '#[[:space:]]*include[[:space:]]+<uapi/asm-generic/mman.*' ${arch_mman} && +[ ! -f ${arch_mman} || egrep -q '#[[:space:]]*include[[:space:]]+<uapi/asm-generic/mman.*' ${arch_mman} ] && (egrep $regex ${header_dir}/mman-common.h | \ egrep -vw 'MAP_(UNINITIALIZED|TYPE|SHARED_VALIDATE)' | \ sed -r "s/$regex/\2 \1/g" | \ xargs printf "\t[ilog2(%s) + 1] = \"%s\",\n") -egrep -q '#[[:space:]]*include[[:space:]]+<uapi/asm-generic/mman.h>.*' ${arch_mman} && +[ ! -f ${arch_mman} || egrep -q '#[[:space:]]*include[[:space:]]+<uapi/asm-generic/mman.h>.*' ${arch_mman} ] && (egrep $regex ${header_dir}/mman.h | \ sed -r "s/$regex/\2 \1/g" | \ xargs printf "\t[ilog2(%s) + 1] = \"%s\",\n")
Signature · 1 line
2.19.2
Arnaldo Carvalho de Melo
maintainerPATCH 22/75 tools lib traceevent: Add sanity check to is_timestamp_in_us()
In reply to Arnaldo Carvalho de MeloFrom: Tzvetomir Stoyanov <[email protected]>
This patch adds a sanity check to is_timestamp_in_us() input parameter trace_clock. It avoids a potential segfault in this function for the case trace_clock is NULL.
--- tools/lib/traceevent/event-parse.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
tools/lib/traceevent/event-parse.c +1 -1
@@ -5409,7 +5409,7 @@ void tep_event_info(struct trace_seq *s, struct tep_event_format *event,static bool is_timestamp_in_us (char *trace_clock,bool use_trace_clock) { -if (!use_trace_clock) +if (!trace_clock || !use_trace_clock)return true; if (!strcmp(trace_clock, "local") || !strcmp(trace_clock, "global")
Signature · 1 line
2.19.2
Arnaldo Carvalho de Melo
maintainerPATCH 23/75 perf annotate: Compute average IPC and IPC coverage per symbol
In reply to Arnaldo Carvalho de MeloFrom: Jin Yao <[email protected]>
Add support to 'perf report' annotate view or 'perf annotate --stdio2' to aggregate the IPC derived from timed LBRs per symbol. We compute the average IPC and the IPC coverage percentage.
For example:
$ perf annotate --stdio2
Percent IPC Cycle (Average IPC: 2.30, IPC Coverage: 54.8%)
Disassembly of section .text:
000000000003aac0 <random@@GLIBC_2.2.5>:
8.32 3.28 sub $0x18,%rsp
3.28 mov $0x1,%esi
3.28 xor %eax,%eax
3.28 cmpl $0x0,argp_program_version_hook@@GLIBC_2.2.5+0x1e0
11.57 3.28 1 ↓ je 20
lock cmpxchg %esi,__abort_msg@@GLIBC_PRIVATE+0x8a0
↓ jne 29
↓ jmp 43
11.57 1.10 20: cmpxchg %esi,__abort_msg@@GLIBC_PRIVATE+0x8a0
0.00 1.10 1 ↓ je 43
29: lea __abort_msg@@GLIBC_PRIVATE+0x8a0,%rdi
sub $0x80,%rsp
→ callq __lll_lock_wait_private
add $0x80,%rsp
0.00 3.00 43: lea __ctype_b@GLIBC_2.2.5+0x38,%rdi
3.00 lea 0xc(%rsp),%rsi
8.49 3.00 1 → callq __random_r
7.91 1.94 cmpl $0x0,argp_program_version_hook@@GLIBC_2.2.5+0x1e0
0.00 1.94 1 ↓ je 68
lock decl __abort_msg@@GLIBC_PRIVATE+0x8a0
↓ jne 70
↓ jmp 8a
0.00 2.00 68: decl __abort_msg@@GLIBC_PRIVATE+0x8a0
21.56 2.00 1 ↓ je 8a
70: lea __abort_msg@@GLIBC_PRIVATE+0x8a0,%rdi
sub $0x80,%rsp
→ callq __lll_unlock_wake_private
add $0x80,%rsp
21.56 2.90 8a: movslq 0xc(%rsp),%rax
2.90 add $0x18,%rsp
9.03 2.90 1 ← retqIt shows for this symbol the average IPC is 2.30 and the IPC coverage is 54.8%.
--- tools/perf/util/annotate.c | 41 +++++++++++++++++++++++++++++++++++--- tools/perf/util/annotate.h | 5 +++++ 2 files changed, 43 insertions(+), 3 deletions(-)
tools/perf/util/annotate.c +38 -3
@@ -1000,6 +1000,7 @@ static unsigned annotation__count_insn(struct annotation *notes, u64 start, u64static void annotation__count_and_fill (struct annotation *notes,u64 start,u64 end,struct cyc_hist *ch) {unsigned n_insn; +unsigned int cover_insn =0 ;u64 offset; n_insn =annotation__count_insn (notes, start, end);
@@ -1013,21 +1014,34 @@ static void annotation__count_and_fill(struct annotation *notes, u64 start, u64for (offset = start; offset <= end; offset++) {struct annotation_line *al = notes->offsets[offset]; -if (al) +if (al && al->ipc ==0.0 ) { al->ipc = ipc; + cover_insn++; + } + } + +if (cover_insn) { + notes->hit_cycles += ch->cycles; + notes->hit_insn += n_insn * ch->num; + notes->cover_insn += cover_insn; } } }void annotation__compute_ipc (struct annotation *notes,size_t size) { -u64 offset; +s64 offset;if (!notes->src || !notes->src->cycles_hist)return ; + notes->total_insn =annotation__count_insn (notes,0 , size -1 ); + notes->hit_cycles =0 ; + notes->hit_insn =0 ; + notes->cover_insn =0 ; +pthread_mutex_lock (¬es->lock); -for (offset =0 ; offset < size; ++offset) { +for (offset = size -1 ; offset >=0 ; --offset) {struct cyc_hist *ch; ch = ¬es->src->cycles_hist[offset];
@@ -2563,6 +2577,22 @@ static void disasm_line__write(struct disasm_line *dl, struct annotation *notes,disasm_line__scnprintf (dl, bf, size, !notes->options->use_offset); } +static void ipc_coverage_string (char *bf,int size,struct annotation *notes) +{ +double ipc =0.0 , coverage =0.0 ; + +if (notes->hit_cycles) + ipc = notes->hit_insn / ((double )notes->hit_cycles); + +if (notes->total_insn) { + coverage = notes->cover_insn *100.0 / + ((double )notes->total_insn); + } + +scnprintf (bf, size,"(Average IPC: %.2f, IPC Coverage: %.1f%%)" , + ipc, coverage); +} + static void __annotation_line__write(struct annotation_line *al, struct annotation *notes, bool first_line, bool current_entry, bool change_color, int width, void *obj, unsigned int percent_type,
@@ -2658,6 +2688,11 @@ static void __annotation_line__write(struct annotation_line *al, struct annotatiANNOTATION__MINMAX_CYCLES_WIDTH -1 , "Cycle(min/max)"); } + +if (show_title && !*al->line) { +ipc_coverage_string (bf,sizeof (bf), notes); +obj__printf (obj,"%*s" ,ANNOTATION__AVG_IPC_WIDTH , bf); + } }obj__printf (obj," " );
tools/perf/util/annotate.h +5 -0
@@ -64,6 +64,7 @@ bool ins__is_fused(struct arch *arch, const char *ins1, const char *ins2);#define ANNOTATION__IPC_WIDTH 6#define ANNOTATION__CYCLES_WIDTH 6#define ANNOTATION__MINMAX_CYCLES_WIDTH 19 +#define ANNOTATION__AVG_IPC_WIDTH 36struct annotation_options { bool hide_src_code,
@@ -262,6 +263,10 @@ struct annotation {pthread_mutex_t lock;u64 max_coverage;u64 start; +u64 hit_cycles; +u64 hit_insn; +unsigned int total_insn; +unsigned int cover_insn;struct annotation_options *options;struct annotation_line **offsets;int nr_events;
Signature · 1 line
2.19.2
Arnaldo Carvalho de Melo
maintainerPATCH 24/75 perf annotate: Create a annotate2 flag in struct symbol
In reply to Arnaldo Carvalho de MeloFrom: Jin Yao <[email protected]>
We often use the symbol__annotate2() to annotate a specified symbol. While annotating may take some time, so in order to avoid annotating the same symbol repeatedly, the patch creates a new flag to indicate the symbol has been annotated.
--- tools/perf/util/annotate.c | 1 + tools/perf/util/symbol.h | 1 + 2 files changed, 2 insertions(+)
tools/perf/util/annotate.c +1 -0
@@ -2798,6 +2798,7 @@ int symbol__annotate2(struct symbol *sym, struct map *map, struct perf_evsel *ev notes->nr_events = nr_pcnt;annotation__update_column_widths (notes); + sym->annotate2 = true;return 0 ;
tools/perf/util/symbol.h +1 -0
@@ -63,6 +63,7 @@ struct symbol { u8 ignore:1; u8 inlined:1;u8 arch_sym; +bool annotate2;char name[0 ]; };
Signature · 1 line
2.19.2
Arnaldo Carvalho de Melo
maintainerPATCH 25/75 perf report: Display average IPC and IPC coverage per symbol
In reply to Arnaldo Carvalho de MeloFrom: Jin Yao <[email protected]>
Support displaying the average IPC and IPC coverage per symbol in 'perf report' --tui and --stdio modes.
For example,
$ perf record -b ... $ perf report -s symbol
Overhead Symbol IPC [IPC Coverage]
39.60% [.] __random 2.30 [ 54.8%]
18.02% [.] main 0.43 [ 54.3%]
14.21% [.] compute_flag 2.29 [100.0%]
14.16% [.] rand 0.36 [100.0%]
7.06% [.] __random_r 2.57 [ 70.5%]
6.85% [.] rand@plt 0.00 [ 0.0%]Jiri Olsa <[email protected]> provided the patch to support the --stdio mode. I merged Jiri's code in this patch.
$ perf report -s symbol --stdio
# Overhead Symbol IPC [IPC Coverage]
# ........ ........................... ....................
#
39.60% [.] __random 2.30 [ 54.8%]
18.02% [.] main 0.43 [ 54.3%]
14.21% [.] compute_flag 2.29 [100.0%]
14.16% [.] rand 0.36 [100.0%]
7.06% [.] __random_r 2.57 [ 70.5%]
6.85% [.] rand@plt 0.00 [ 0.0%]
0.02% [k] run_timer_softirq 1.60 [ 57.2%]The columns "IPC" and "[IPC Coverage]" are automatically enabled when the sort-key "symbol" is specified. If the perf.data file doesn't contain timed LBR information, columns are filled with "-".
For example,
# Overhead Symbol IPC [IPC Coverage]
# ........ ........................... ....................
#
46.57% [.] main - -
17.60% [.] rand - -
15.84% [.] __random_r - -
11.90% [.] __random - -
6.50% [.] compute_flag - -
1.59% [.] rand@plt - -
0.00% [.] _dl_relocate_object - -
0.00% [k] tlb_flush_mmu - -
0.00% [k] perf_event_mmap - -
0.00% [k] native_sched_clock - -
0.00% [k] intel_pmu_handle_irq_v4 - -
0.00% [k] native_write_msr - - v3:
---
Removed the sortkey 'ipc' from command-line. The columns "IPC" and "[IPC Coverage]" are automatically enabled when "symbol" is specified.
v2:
---
Merge in Jiri's patch to support stdio mode
--- tools/perf/builtin-report.c | 26 ++++++++++++++-- tools/perf/util/hist.h | 1 + tools/perf/util/sort.c | 61 +++++++++++++++++++++++++++++++++++++ tools/perf/util/sort.h | 2 ++ 4 files changed, 87 insertions(+), 3 deletions(-)
tools/perf/builtin-report.c +23 -3
@@ -85,6 +85,7 @@ struct report {int socket_filter;DECLARE_BITMAP (cpu_bitmap,MAX_NR_CPUS );struct branch_type_stat brtype_stat; +bool symbol_ipc; };static int report__config (const char *var,const char *value,void *cb)
@@ -129,7 +130,7 @@ static int hist_iter__report_callback(struct hist_entry_iter *iter,struct mem_info *mi;struct branch_info *bi; -if (!ui__has_annotation ()) +if (!ui__has_annotation () && !rep->symbol_ipc)return 0 ; hist__account_cycles(sample->branch_stack, al, sample,
@@ -174,7 +175,7 @@ static int hist_iter__branch_callback(struct hist_entry_iter *iter,struct perf_evsel *evsel = iter->evsel;int err; -if (!ui__has_annotation ()) +if (!ui__has_annotation () && !rep->symbol_ipc)return 0 ; hist__account_cycles(sample->branch_stack, al, sample,
@@ -1133,6 +1134,7 @@ int cmd_report(int argc, const char **argv) .mode = PERF_DATA_MODE_READ, };int ret =hists__init (); +char sort_tmp[128 ];if (ret <0 )return ret;
@@ -1284,6 +1286,24 @@ int cmd_report(int argc, const char **argv)else use_browser =0 ; +if (sort_order &&strstr (sort_order,"ipc" )) { +parse_options_usage (report_usage, options,"s" ,1 ); + goto error; + } + +if (sort_order &&strstr (sort_order,"symbol" )) { +if (sort__mode ==SORT_MODE__BRANCH ) { +snprintf (sort_tmp,sizeof (sort_tmp),"%s,%s" , + sort_order,"ipc_lbr" ); + report.symbol_ipc = true; + }else { +snprintf (sort_tmp,sizeof (sort_tmp),"%s,%s" , + sort_order,"ipc_null" ); + } + + sort_order = sort_tmp; + } +if (setup_sorting (session->evlist) <0 ) {if (sort_order)parse_options_usage (report_usage, options,"s" ,1 );
@@ -1311,7 +1331,7 @@ int cmd_report(int argc, const char **argv)* so don't allocate extra space that won't be used in the stdio * implementation. */ -if (ui__has_annotation ()) { +if (ui__has_annotation () || report.symbol_ipc) { ret =symbol__annotation_init ();if (ret <0 ) goto error;
tools/perf/util/hist.h +1 -0
@@ -62,6 +62,7 @@ enum hist_column {HISTC_TRACE ,HISTC_SYM_SIZE ,HISTC_DSO_SIZE , +HISTC_SYMBOL_IPC , HISTC_NR_COLS, /* Last entry */ };
tools/perf/util/sort.c +61 -0
85 lines not on this page · raw message
tools/perf/util/sort.h +2 -0
@@ -229,6 +229,7 @@ enum sort_type {SORT_SYM_SIZE ,SORT_DSO_SIZE ,SORT_CGROUP_ID , +SORT_SYM_IPC_NULL ,/* branch stack specific sort keys */ __SORT_BRANCH_STACK,
@@ -242,6 +243,7 @@ enum sort_type {SORT_CYCLES ,SORT_SRCLINE_FROM ,SORT_SRCLINE_TO , +SORT_SYM_IPC ,/* memory mode specific sort keys */ __SORT_MEMORY_MODE,
Signature · 1 line
2.19.2
Arnaldo Carvalho de Melo
maintainerPATCH 26/75 perf report: Documentation average IPC and IPC coverage
In reply to Arnaldo Carvalho de MeloFrom: Jin Yao <[email protected]>
Add explanations for new columns "IPC" and "IPC coverage" in perf documentation.
v5:
---
Update the description according to Ingo's comments.
--- tools/perf/Documentation/perf-report.txt | 8 ++++++++ 1 file changed, 8 insertions(+)
tools/perf/Documentation/perf-report.txt +8 -0
@@ -126,6 +126,14 @@ OPTIONS And default sort keys are changed to comm, dso_from, symbol_from, dso_to and symbol_to, see '--branch-stack'. + When the sort key symbol is specified, columns "IPC" and "IPC Coverage" + are enabled automatically. Column "IPC" reports the average IPC per function + and column "IPC coverage" reports the percentage of instructions with + sampled IPC in this function. IPC means Instruction Per Cycle. If it's low, + it indicates there may be a performance bottleneck when the function is + executed, such as a memory access bottleneck. If a function has high overhead + and low IPC, it's worth further analyzing it to optimize its performance. + If the --mem-mode option is used, the following sort keys are also available (incompatible with --branch-stack): symbol_daddr, dso_daddr, locked, tlb, mem, snoop, dcacheline.
Signature · 1 line
2.19.2
Arnaldo Carvalho de Melo
maintainerPATCH 27/75 tools lib traceevent: Implement new API tep_get_ref()
In reply to Arnaldo Carvalho de MeloFrom: Tzvetomir Stoyanov <[email protected]>
This patch implements a new API of the tracevent library:
int tep_get_ref(struct tep_handle *tep);
The API returns the reference counter "ref_count" of the tep handler. As "struct tep_handle" is internal only, its members cannot be accessed by the library users, the API is used to get the reference counter.
--- tools/lib/traceevent/event-parse.c | 7 +++++++ tools/lib/traceevent/event-parse.h | 1 + 2 files changed, 8 insertions(+)
tools/lib/traceevent/event-parse.c +7 -0
@@ -6730,6 +6730,13 @@ void tep_ref(struct tep_handle *pevent) pevent->ref_count++; } +int tep_get_ref (struct tep_handle *tep) +{ +if (tep) +return tep->ref_count; +return 0 ; +} +void tep_free_format_field (struct tep_format_field *field) {free (field->type);
tools/lib/traceevent/event-parse.h +1 -0
@@ -581,6 +581,7 @@ struct tep_handle *tep_alloc(void);void tep_free (struct tep_handle *pevent);void tep_ref (struct tep_handle *pevent);void tep_unref (struct tep_handle *pevent); +int tep_get_ref (struct tep_handle *tep);/* access to the internal parser */ void tep_buffer_init (const char *buf,unsigned long long size);
Signature · 1 line
2.19.2
Arnaldo Carvalho de Melo
maintainerPATCH 28/75 tools lib traceevent: Added support for pkg-config
In reply to Arnaldo Carvalho de MeloFrom: Tzvetomir Stoyanov <[email protected]>
This patch implements integration with pkg-config framework. pkg-config can be used by the library users to determine required CFLAGS and LDFLAGS in order to use the library
--- tools/lib/traceevent/Makefile | 26 ++++++++++++++++--- .../lib/traceevent/libtraceevent.pc.template | 10 +++++++ 2 files changed, 33 insertions(+), 3 deletions(-) create mode 100644 tools/lib/traceevent/libtraceevent.pc.template
tools/lib/traceevent/Makefile +23 -3
@@ -25,6 +25,7 @@ endef $(call allow-override,CC,$(CROSS_COMPILE)gcc) $(call allow-override,AR,$(CROSS_COMPILE)ar) $(call allow-override,NM,$(CROSS_COMPILE)nm) +$(call allow-override,PKG_CONFIG,pkg-config) EXT = -std=gnu99 INSTALL = install
@@ -47,6 +48,8 @@ prefix ?= /usr/local libdir = $(prefix)/$(libdir_relative) man_dir = $(prefix)/share/man man_dir_SQ = '$(subst ','\'',$(man_dir))' +pkgconfig_dir ?= $(word 1,$(shell $(PKG_CONFIG) \ + --variable pc_path pkg-config | tr ":" " ")) export man_dir man_dir_SQ INSTALL export DESTDIR DESTDIR_SQ
@@ -270,7 +273,19 @@ define do_generate_dynamic_list_file fi endef -install_lib: all_cmd install_plugins +PKG_CONFIG_FILE = libtraceevent.pc +define do_install_pkgconfig_file + if [ -n "${pkgconfig_dir}" ]; then \ + cp -f ${PKG_CONFIG_FILE}.template ${PKG_CONFIG_FILE}; \ + sed -i "s|INSTALL_PREFIX|${1}|g" ${PKG_CONFIG_FILE}; \ + sed -i "s|LIB_VERSION|${EVENT_PARSE_VERSION}|g" ${PKG_CONFIG_FILE}; \ + $(call do_install,$(PKG_CONFIG_FILE),$(pkgconfig_dir),644); \ + else \ + (echo Failed to locate pkg-config directory) 1>&2; \ + fi +endef + +install_lib: all_cmd install_plugins install_pkgconfig $(call QUIET_INSTALL, $(LIB_TARGET)) \ $(call do_install_mkdir,$(libdir_SQ)); \ cp -fpR $(LIB_INSTALL) $(DESTDIR)$(libdir_SQ)
@@ -279,6 +294,10 @@ install_plugins: $(PLUGINS) $(call QUIET_INSTALL, trace_plugins) \ $(call do_install_plugins, $(PLUGINS)) +install_pkgconfig: + $(call QUIET_INSTALL, $(PKG_CONFIG_FILE)) \ + $(call do_install_pkgconfig_file,$(prefix)) + install_headers: $(call QUIET_INSTALL, headers) \ $(call do_install,event-parse.h,$(prefix)/include/traceevent,644); \
@@ -289,8 +308,9 @@ install: install_lib clean: $(call QUIET_CLEAN, libtraceevent) \ - $(RM) *.o *~ $(TARGETS) *.a *.so $(VERSION_FILES) .*.d .*.cmd \ - $(RM) TRACEEVENT-CFLAGS tags TAGS + $(RM) *.o *~ $(TARGETS) *.a *.so $(VERSION_FILES) .*.d .*.cmd; \ + $(RM) TRACEEVENT-CFLAGS tags TAGS; \ + $(RM) $(PKG_CONFIG_FILE) PHONY += force plugins force:
tools/lib/traceevent/libtraceevent.pc.template new file +10 -0
@@ -0,0 +1,10 @@ +prefix=INSTALL_PREFIX +libdir=${prefix}/lib64 +includedir=${prefix}/include/traceevent + +Name: libtraceevent +URL: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git +Description: Linux kernel trace event library +Version: LIB_VERSION +Cflags: -I${includedir} +Libs: -L${libdir} -ltraceevent
Signature · 1 line
2.19.2
Arnaldo Carvalho de Melo
maintainerPATCH 29/75 tools lib traceevent: Install trace-seq.h API header file
In reply to Arnaldo Carvalho de MeloFrom: Tzvetomir Stoyanov <[email protected]>
This patch installs trace-seq.h header file on "make install".
--- tools/lib/traceevent/Makefile | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
tools/lib/traceevent/Makefile +2 -1
@@ -285,7 +285,7 @@ define do_install_pkgconfig_file fi endef -install_lib: all_cmd install_plugins install_pkgconfig +install_lib: all_cmd install_plugins install_headers install_pkgconfig $(call QUIET_INSTALL, $(LIB_TARGET)) \ $(call do_install_mkdir,$(libdir_SQ)); \ cp -fpR $(LIB_INSTALL) $(DESTDIR)$(libdir_SQ)
@@ -302,6 +302,7 @@ install_headers: $(call QUIET_INSTALL, headers) \ $(call do_install,event-parse.h,$(prefix)/include/traceevent,644); \ $(call do_install,event-utils.h,$(prefix)/include/traceevent,644); \ + $(call do_install,trace-seq.h,$(prefix)/include/traceevent,644); \ $(call do_install,kbuffer.h,$(prefix)/include/traceevent,644) install: install_lib
Signature · 1 line
2.19.2
Arnaldo Carvalho de Melo
maintainerPATCH 30/75 tools lib traceevent, perf tools: Rename 'struct tep_event_format' to 'struct tep_event'
In reply to Arnaldo Carvalho de MeloFrom: Tzvetomir Stoyanov <[email protected]>
In order to make libtraceevent into a proper library, variables, data structures and functions require a unique prefix to prevent name space conflicts.
This renames 'struct tep_event_format' to 'struct tep_event', which describes more closely the purpose of the struct.
--- tools/lib/traceevent/event-parse-api.c | 2 +- tools/lib/traceevent/event-parse-local.h | 6 +- tools/lib/traceevent/event-parse.c | 188 +++++++++--------- tools/lib/traceevent/event-parse.h | 62 +++--- tools/lib/traceevent/parse-filter.c | 42 ++-- tools/lib/traceevent/plugin_function.c | 2 +- tools/lib/traceevent/plugin_hrtimer.c | 4 +- tools/lib/traceevent/plugin_kmem.c | 2 +- tools/lib/traceevent/plugin_kvm.c | 14 +- tools/lib/traceevent/plugin_mac80211.c | 4 +- tools/lib/traceevent/plugin_sched_switch.c | 4 +- tools/perf/builtin-trace.c | 2 +- tools/perf/util/evsel.h | 4 +- tools/perf/util/header.c | 2 +- tools/perf/util/python.c | 4 +- .../util/scripting-engines/trace-event-perl.c | 6 +- .../scripting-engines/trace-event-python.c | 8 +- tools/perf/util/trace-event-parse.c | 16 +- tools/perf/util/trace-event.c | 8 +- tools/perf/util/trace-event.h | 16 +- 20 files changed, 198 insertions(+), 198 deletions(-)
tools/lib/traceevent/event-parse-api.c +1 -1
@@ -15,7 +15,7 @@* This returns pointer to the first element of the events array * If @tep is NULL, NULL is returned. */ -struct tep_event_format *tep_get_first_event (struct tep_handle *tep) +struct tep_event *tep_get_first_event (struct tep_handle *tep) {if (tep && tep->events)return tep->events[0 ];
tools/lib/traceevent/event-parse-local.h +3 -3
@@ -50,9 +50,9 @@ struct tep_handle {unsigned int printk_count; -struct tep_event_format **events; +struct tep_event **events;int nr_events; -struct tep_event_format **sort_events; +struct tep_event **sort_events;enum tep_event_sort_type last_type;int type_offset;
@@ -84,7 +84,7 @@ struct tep_handle {struct tep_function_handler *func_handlers;/* cache */ -struct tep_event_format *last_event; +struct tep_event *last_event;char *trace_clock; };
tools/lib/traceevent/event-parse.c +94 -94
664 lines not on this page · raw message
tools/lib/traceevent/event-parse.h +31 -31
152 lines not on this page · raw message
tools/lib/traceevent/parse-filter.c +21 -21
162 lines not on this page · raw message
tools/lib/traceevent/plugin_function.c +1 -1
@@ -124,7 +124,7 @@ static int add_and_get_index(const char *parent, const char *child, int cpu) }static int function_handler (struct trace_seq *s,struct tep_record *record, -struct tep_event_format *event,void *context) +struct tep_event *event,void *context) {struct tep_handle *pevent = event->pevent;unsigned long long function;
tools/lib/traceevent/plugin_hrtimer.c +2 -2
@@ -27,7 +27,7 @@static int timer_expire_handler (struct trace_seq *s,struct tep_record *record, -struct tep_event_format *event,void *context) +struct tep_event *event,void *context) {trace_seq_printf (s,"hrtimer=" );
@@ -47,7 +47,7 @@ static int timer_expire_handler(struct trace_seq *s,static int timer_start_handler (struct trace_seq *s,struct tep_record *record, -struct tep_event_format *event,void *context) +struct tep_event *event,void *context) {trace_seq_printf (s,"hrtimer=" );
tools/lib/traceevent/plugin_kmem.c +1 -1
@@ -25,7 +25,7 @@#include "trace-seq.h" static int call_site_handler (struct trace_seq *s,struct tep_record *record, -struct tep_event_format *event,void *context) +struct tep_event *event,void *context) {struct tep_format_field *field;unsigned long long val, addr;
tools/lib/traceevent/plugin_kvm.c +7 -7
@@ -249,7 +249,7 @@ static const char *find_exit_reason(unsigned isa, int val) }static int print_exit_reason (struct trace_seq *s,struct tep_record *record, -struct tep_event_format *event,const char *field) +struct tep_event *event,const char *field) {unsigned long long isa;unsigned long long val;
@@ -270,7 +270,7 @@ static int print_exit_reason(struct trace_seq *s, struct tep_record *record, }static int kvm_exit_handler (struct trace_seq *s,struct tep_record *record, -struct tep_event_format *event,void *context) +struct tep_event *event,void *context) {unsigned long long info1 =0 , info2 =0 ;
@@ -293,7 +293,7 @@ static int kvm_exit_handler(struct trace_seq *s, struct tep_record *record,static int kvm_emulate_insn_handler (struct trace_seq *s,struct tep_record *record, -struct tep_event_format *event,void *context) +struct tep_event *event,void *context) {unsigned long long rip, csbase, len, flags, failed;int llen;
@@ -332,7 +332,7 @@ static int kvm_emulate_insn_handler(struct trace_seq *s,static int kvm_nested_vmexit_inject_handler (struct trace_seq *s,struct tep_record *record, -struct tep_event_format *event,void *context) +struct tep_event *event,void *context) {if (print_exit_reason (s, record, event,"exit_code" ) <0 )return -1 ;
@@ -346,7 +346,7 @@ static int kvm_nested_vmexit_inject_handler(struct trace_seq *s, struct tep_reco }static int kvm_nested_vmexit_handler (struct trace_seq *s,struct tep_record *record, -struct tep_event_format *event,void *context) +struct tep_event *event,void *context) {tep_print_num_field (s,"rip %llx " , event,"rip" , record,1 );
@@ -372,7 +372,7 @@ union kvm_mmu_page_role { };static int kvm_mmu_print_role (struct trace_seq *s,struct tep_record *record, -struct tep_event_format *event,void *context) +struct tep_event *event,void *context) {unsigned long long val;static const char *access_str[] = {
@@ -419,7 +419,7 @@ static int kvm_mmu_print_role(struct trace_seq *s, struct tep_record *record,static int kvm_mmu_get_page_handler (struct trace_seq *s,struct tep_record *record, -struct tep_event_format *event,void *context) +struct tep_event *event,void *context) {unsigned long long val;
tools/lib/traceevent/plugin_mac80211.c +2 -2
@@ -26,7 +26,7 @@#define INDENT 65 -static void print_string (struct trace_seq *s,struct tep_event_format *event, +static void print_string (struct trace_seq *s,struct tep_event *event,const char *name,const void *data) {struct tep_format_field *f =tep_find_field (event, name);
@@ -60,7 +60,7 @@ static void print_string(struct trace_seq *s, struct tep_event_format *event,static int drv_bss_info_changed (struct trace_seq *s,struct tep_record *record, -struct tep_event_format *event,void *context) +struct tep_event *event,void *context) {void *data = record->data;
tools/lib/traceevent/plugin_sched_switch.c +2 -2
@@ -67,7 +67,7 @@ static void write_and_save_comm(struct tep_format_field *field,static int sched_wakeup_handler (struct trace_seq *s,struct tep_record *record, -struct tep_event_format *event,void *context) +struct tep_event *event,void *context) {struct tep_format_field *field;unsigned long long val;
@@ -96,7 +96,7 @@ static int sched_wakeup_handler(struct trace_seq *s,static int sched_switch_handler (struct trace_seq *s,struct tep_record *record, -struct tep_event_format *event,void *context) +struct tep_event *event,void *context) {struct tep_format_field *field;unsigned long long val;
tools/perf/builtin-trace.c +1 -1
@@ -885,7 +885,7 @@ static struct syscall_fmt *syscall_fmt__find_by_alias(const char *alias)* args_size: sum of the sizes of the syscall arguments, anything after that is augmented stuff: pathname for openat, etc. */ struct syscall { -struct tep_event_format *tp_format; +struct tep_event *tp_format;int nr_args;int args_size;bool is_exit;
tools/perf/util/evsel.h +2 -2
@@ -106,7 +106,7 @@ struct perf_evsel {char *name;double scale;const char *unit; -struct tep_event_format *tp_format; +struct tep_event *tp_format;off_t id_offset;struct perf_stat_evsel *stats;void *priv;
@@ -216,7 +216,7 @@ static inline struct perf_evsel *perf_evsel__newtp(const char *sys, const char *struct perf_evsel *perf_evsel__new_cycles (bool precise); -struct tep_event_format *event_format__new (const char *sys,const char *name); +struct tep_event *event_format__new (const char *sys,const char *name);void perf_evsel__init (struct perf_evsel *evsel,struct perf_event_attr *attr,int idx);
tools/perf/util/header.c +1 -1
@@ -3268,7 +3268,7 @@ static int read_attr(int fd, struct perf_header *ph,static int perf_evsel__prepare_tracepoint_event (struct perf_evsel *evsel,struct tep_handle *pevent) { -struct tep_event_format *event; +struct tep_event *event;char bf[128 ];/* already prepared */
tools/perf/util/python.c +2 -2
@@ -386,7 +386,7 @@ get_tracepoint_field(struct pyrf_event *pevent, PyObject *attr_name)struct tep_format_field *field;if (!evsel->tp_format) { -struct tep_event_format *tp_format; +struct tep_event *tp_format; tp_format =trace_event__tp_format_id (evsel->attr.config);if (!tp_format)
@@ -1240,7 +1240,7 @@ static struct {static PyObject *pyrf__tracepoint (struct pyrf_evsel *pevsel,PyObject *args,PyObject *kwargs) { -struct tep_event_format *tp_format; +struct tep_event *tp_format;static char *kwlist[] = {"sys" ,"name" ,NULL };char *sys =NULL ;char *name =NULL ;
tools/perf/util/scripting-engines/trace-event-perl.c +3 -3
@@ -189,7 +189,7 @@ static void define_flag_field(const char *ev_name,LEAVE ; } -static void define_event_symbols (struct tep_event_format *event, +static void define_event_symbols (struct tep_event *event,const char *ev_name,struct tep_print_arg *args) {
@@ -338,7 +338,7 @@ static void perl_process_tracepoint(struct perf_sample *sample, struct addr_location *al) {struct thread *thread = al->thread; -struct tep_event_format *event = evsel->tp_format; +struct tep_event *event = evsel->tp_format;struct tep_format_field *field;static char handler[256 ];unsigned long long val;
@@ -537,7 +537,7 @@ static int perl_stop_script(void)static int perl_generate_script (struct tep_handle *pevent,const char *outfile) { -struct tep_event_format *event =NULL ; +struct tep_event *event =NULL ;struct tep_format_field *f;char fname[PATH_MAX ];int not_first, count;
tools/perf/util/scripting-engines/trace-event-python.c +4 -4
@@ -264,7 +264,7 @@ static void define_field(enum tep_print_arg_type field_type,Py_DECREF (t); } -static void define_event_symbols (struct tep_event_format *event, +static void define_event_symbols (struct tep_event *event,const char *ev_name,struct tep_print_arg *args) {
@@ -332,7 +332,7 @@ static void define_event_symbols(struct tep_event_format *event,define_event_symbols (event, ev_name, args->next); } -static PyObject *get_field_numeric_entry (struct tep_event_format *event, +static PyObject *get_field_numeric_entry (struct tep_event *event,struct tep_format_field *field,void *data) {bool is_array = field->flags &TEP_FIELD_IS_ARRAY ;
@@ -790,7 +790,7 @@ static void python_process_tracepoint(struct perf_sample *sample,struct perf_evsel *evsel, struct addr_location *al) { - struct tep_event_format *event = evsel->tp_format; + struct tep_event *event = evsel->tp_format;PyObject *handler, *context, *t, *obj =NULL , *callchain;PyObject *dict =NULL , *all_entries_dict =NULL ;static char handler_name[256 ];
@@ -1590,7 +1590,7 @@ static int python_stop_script(void)static int python_generate_script (struct tep_handle *pevent,const char *outfile) { -struct tep_event_format *event =NULL ; +struct tep_event *event =NULL ;struct tep_format_field *f;char fname[PATH_MAX ];int not_first, count;
tools/perf/util/trace-event-parse.c +8 -8
@@ -33,7 +33,7 @@ static int get_common_field(struct scripting_context *context, int *offset, int *size, const char *type) { struct tep_handle *pevent = context->pevent; -struct tep_event_format *event; +struct tep_event *event;struct tep_format_field *field;if (!*size) {
@@ -95,7 +95,7 @@ int common_pc(struct scripting_context *context) }unsigned long long -raw_field_value (struct tep_event_format *event,const char *name,void *data) +raw_field_value (struct tep_event *event,const char *name,void *data) {struct tep_format_field *field;unsigned long long val;
@@ -109,12 +109,12 @@ raw_field_value(struct tep_event_format *event, const char *name, void *data)return val; } -unsigned long long read_size (struct tep_event_format *event,void *ptr,int size) +unsigned long long read_size (struct tep_event *event,void *ptr,int size) {return tep_read_number (event->pevent, ptr, size); } -void event_format__fprintf (struct tep_event_format *event, +void event_format__fprintf (struct tep_event *event,int cpu,void *data,int size,FILE *fp) {struct tep_record record;
@@ -131,7 +131,7 @@ void event_format__fprintf(struct tep_event_format *event,trace_seq_destroy (&s); } -void event_format__print (struct tep_event_format *event, +void event_format__print (struct tep_event *event,int cpu,void *data,int size) {return event_format__fprintf (event, cpu, data, size, stdout);
@@ -190,12 +190,12 @@ int parse_event_file(struct tep_handle *pevent,return tep_parse_event (pevent, buf, size, sys); } -struct tep_event_format *trace_find_next_event (struct tep_handle *pevent, -struct tep_event_format *event) +struct tep_event *trace_find_next_event (struct tep_handle *pevent, +struct tep_event *event) {static int idx;int events_count; -struct tep_event_format *all_events; +struct tep_event *all_events; all_events =tep_get_first_event (pevent); events_count =tep_get_events_count (pevent);
tools/perf/util/trace-event.c +4 -4
@@ -72,12 +72,12 @@ void trace_event__cleanup(struct trace_event *t)/* * Returns pointer with encoded error via <linux/err.h> interface. */ -static struct tep_event_format * +static struct tep_event *tp_format (const char *sys,const char *name) {char *tp_dir =get_events_file (sys);struct tep_handle *pevent = tevent.pevent; -struct tep_event_format *event =NULL ; +struct tep_event *event =NULL ;char path[PATH_MAX ];size_t size;char *data;
@@ -102,7 +102,7 @@ tp_format(const char *sys, const char *name)/* * Returns pointer with encoded error via <linux/err.h> interface. */ -struct tep_event_format * +struct tep_event *trace_event__tp_format (const char *sys,const char *name) {if (!tevent_initialized &&trace_event__init2 ())
@@ -111,7 +111,7 @@ trace_event__tp_format(const char *sys, const char *name)return tp_format (sys, name); } -struct tep_event_format *trace_event__tp_format_id (int id) +struct tep_event *trace_event__tp_format_id (int id) {if (!tevent_initialized &&trace_event__init2 ())return ERR_PTR (-ENOMEM );
tools/perf/util/trace-event.h +8 -8
@@ -22,17 +22,17 @@ int trace_event__init(struct trace_event *t);void trace_event__cleanup (struct trace_event *t);int trace_event__register_resolver (struct machine *machine,tep_func_resolver_t *func); -struct tep_event_format * +struct tep_event *trace_event__tp_format (const char *sys,const char *name); -struct tep_event_format *trace_event__tp_format_id (int id); +struct tep_event *trace_event__tp_format_id (int id);int bigendian (void ); -void event_format__fprintf (struct tep_event_format *event, +void event_format__fprintf (struct tep_event *event,int cpu,void *data,int size,FILE *fp); -void event_format__print (struct tep_event_format *event, +void event_format__print (struct tep_event *event,int cpu,void *data,int size);int parse_ftrace_file (struct tep_handle *pevent,char *buf,unsigned long size);
@@ -40,7 +40,7 @@ int parse_event_file(struct tep_handle *pevent, char *buf, unsigned long size, char *sys);unsigned long long -raw_field_value (struct tep_event_format *event,const char *name,void *data); +raw_field_value (struct tep_event *event,const char *name,void *data);void parse_proc_kallsyms (struct tep_handle *pevent,char *file,unsigned int size);void parse_ftrace_printk (struct tep_handle *pevent,char *file,unsigned int size);
@@ -48,9 +48,9 @@ void parse_saved_cmdline(struct tep_handle *pevent, char *file, unsigned int sizssize_t trace_report (int fd,struct trace_event *tevent,bool repipe); -struct tep_event_format *trace_find_next_event (struct tep_handle *pevent, -struct tep_event_format *event); -unsigned long long read_size (struct tep_event_format *event,void *ptr,int size); +struct tep_event *trace_find_next_event (struct tep_handle *pevent, +struct tep_event *event); +unsigned long long read_size (struct tep_event *event,void *ptr,int size);unsigned long long eval_flag (const char *flag);int read_tracing_data (int fd,struct list_head *pattrs);
Signature · 1 line
2.19.2
Arnaldo Carvalho de Melo
maintainerPATCH 31/75 tools lib traceevent: Rename tep_free_format() to tep_free_event()
In reply to Arnaldo Carvalho de MeloFrom: Tzvetomir Stoyanov <[email protected]>
In order to make libtraceevent into a proper library, variables, data structures and functions require a unique prefix to prevent name space conflicts. This renames tep_free_format() to tep_free_event(), which describes more closely the purpose of the function.
--- tools/lib/traceevent/event-parse.c | 6 +++--- tools/lib/traceevent/event-parse.h | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-)
tools/lib/traceevent/event-parse.c +3 -3
@@ -6154,7 +6154,7 @@ __parse_event(struct tep_handle *pevent,return 0 ; event_add_failed: -tep_free_format (event); +tep_free_event (event);return ret; }
@@ -6763,7 +6763,7 @@ static void free_formats(struct tep_format *format)free_format_fields (format->fields); } -void tep_free_format (struct tep_event *event) +void tep_free_event (struct tep_event *event) {free (event->name);free (event->system);
@@ -6849,7 +6849,7 @@ void tep_free(struct tep_handle *pevent) }for (i =0 ; i < pevent->nr_events; i++) -tep_free_format (pevent->events[i]); +tep_free_event (pevent->events[i]);while (pevent->handlers) { handle = pevent->handlers;
tools/lib/traceevent/event-parse.h +1 -1
@@ -475,7 +475,7 @@ enum tep_errno tep_parse_format(struct tep_handle *pevent,struct tep_event **eventp, const char *buf, unsigned long size, const char *sys); -void tep_free_format (struct tep_event *event); +void tep_free_event (struct tep_event *event);void tep_free_format_field (struct tep_format_field *field); void *tep_get_field_raw(struct trace_seq *s, struct tep_event *event,
Signature · 1 line
2.19.2
Arnaldo Carvalho de Melo
maintainerPATCH 32/75 perf tools: traceevent API cleanup, remove __tep_data2host*()
In reply to Arnaldo Carvalho de MeloFrom: Tzvetomir Stoyanov <[email protected]>
In order to make libtraceevent into a proper library, its API should be straightforward. The __tep_data2host*() functions are going to no longer be available as a libtraceevent API, tep_read_number() should be used instead. This patch replaces __tep_data2host*() usage with tep_read_number() in perf.
--- tools/perf/util/trace-event-read.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
tools/perf/util/trace-event-read.c +2 -2
@@ -102,7 +102,7 @@ static unsigned int read4(struct tep_handle *pevent)if (do_read (&data,4 ) <0 )return 0 ; -return __tep_data2host4 (pevent, data); +return tep_read_number (pevent, &data,4 ); }static unsigned long long read8 (struct tep_handle *pevent)
@@ -111,7 +111,7 @@ static unsigned long long read8(struct tep_handle *pevent)if (do_read (&data,8 ) <0 )return 0 ; -return __tep_data2host8 (pevent, data); +return tep_read_number (pevent, &data,8 ); }static char *read_string (void )
Signature · 1 line
2.19.2
Arnaldo Carvalho de Melo
maintainerPATCH 33/75 tools lib traceevent: traceevent API cleanup
In reply to Arnaldo Carvalho de MeloFrom: Tzvetomir Stoyanov <[email protected]>
In order to make libtraceevent into a proper library, its API should be straightforward. This patch hides few API functions, intended for internal usage only:
tep_free_event(), tep_free_format_field(), __tep_data2host2(), __tep_data2host4() and __tep_data2host8().
The patch also alignes the libtraceevent summary man page with these API changes.
--- tools/lib/traceevent/event-parse-api.c | 6 +++--- tools/lib/traceevent/event-parse-local.h | 7 +++++++ tools/lib/traceevent/event-parse.c | 13 ++++++++----- tools/lib/traceevent/event-parse.h | 16 ---------------- 4 files changed, 18 insertions(+), 24 deletions(-)
tools/lib/traceevent/event-parse-api.c +3 -3
@@ -51,7 +51,7 @@ void tep_set_flag(struct tep_handle *tep, int flag) tep->flags |= flag; } -unsigned short __tep_data2host2 (struct tep_handle *pevent,unsigned short data) +unsigned short tep_data2host2 (struct tep_handle *pevent,unsigned short data) {unsigned short swap;
@@ -64,7 +64,7 @@ unsigned short __tep_data2host2(struct tep_handle *pevent, unsigned short data)return swap; } -unsigned int __tep_data2host4 (struct tep_handle *pevent,unsigned int data) +unsigned int tep_data2host4 (struct tep_handle *pevent,unsigned int data) {unsigned int swap;
@@ -80,7 +80,7 @@ unsigned int __tep_data2host4(struct tep_handle *pevent, unsigned int data) }unsigned long long -__tep_data2host8 (struct tep_handle *pevent,unsigned long long data) +tep_data2host8 (struct tep_handle *pevent,unsigned long long data) {unsigned long long swap;
tools/lib/traceevent/event-parse-local.h +7 -0
@@ -89,4 +89,11 @@ struct tep_handle { char *trace_clock; }; +void tep_free_event (struct tep_event *event); +void tep_free_format_field (struct tep_format_field *field); + +unsigned short tep_data2host2 (struct tep_handle *pevent,unsigned short data); +unsigned int tep_data2host4 (struct tep_handle *pevent,unsigned int data); +unsigned long long tep_data2host8 (struct tep_handle *pevent,unsigned long long data); +#endif /* _PARSE_EVENTS_INT_H */
tools/lib/traceevent/event-parse.c +8 -5
@@ -3328,15 +3328,18 @@ tep_find_any_field(struct tep_event *event, const char *name)unsigned long long tep_read_number (struct tep_handle *pevent,const void *ptr,int size) { +unsigned long long val; +switch (size) {case 1 :return *(unsigned char *)ptr;case 2 : -return tep_data2host2 (pevent, ptr); +return tep_data2host2 (pevent, *(unsigned short *)ptr);case 4 : -return tep_data2host4 (pevent, ptr); +return tep_data2host4 (pevent, *(unsigned int *)ptr);case 8 : -return tep_data2host8 (pevent, ptr); +memcpy (&val, (ptr),sizeof (unsigned long long )); +return tep_data2host8 (pevent, val);default :/* BUG! */ return 0 ;
@@ -4062,7 +4065,7 @@ static void print_str_arg(struct trace_seq *s, void *data, int size, f =tep_find_any_field (event, arg->string.string); arg->string.offset = f->offset; } - str_offset =tep_data2host4 (pevent, data + arg->string.offset); + str_offset =tep_data2host4 (pevent, *(unsigned int *)(data + arg->string.offset)); str_offset &=0xffff ;print_str_to_seq (s, format, len_arg, ((char *)data) + str_offset);break ;
@@ -4080,7 +4083,7 @@ static void print_str_arg(struct trace_seq *s, void *data, int size, f =tep_find_any_field (event, arg->bitmask.bitmask); arg->bitmask.offset = f->offset; } - bitmask_offset =tep_data2host4 (pevent, data + arg->bitmask.offset); + bitmask_offset =tep_data2host4 (pevent, *(unsigned int *)(data + arg->bitmask.offset)); bitmask_size = bitmask_offset >>16 ; bitmask_offset &=0xffff ; print_bitmask_to_seq(pevent, s, format, len_arg,
tools/lib/traceevent/event-parse.h +0 -16
@@ -409,20 +409,6 @@ void tep_print_plugins(struct trace_seq *s,typedef char *(tep_func_resolver_t )(void *priv,unsigned long long *addrp,char **modp);void tep_set_flag (struct tep_handle *tep,int flag); -unsigned short __tep_data2host2 (struct tep_handle *pevent,unsigned short data); -unsigned int __tep_data2host4 (struct tep_handle *pevent,unsigned int data); -unsigned long long -__tep_data2host8 (struct tep_handle *pevent,unsigned long long data); - -#define tep_data2host2 (pevent, ptr) __tep_data2host2(pevent, *(unsigned short *)(ptr)) -#define tep_data2host4 (pevent, ptr) __tep_data2host4(pevent, *(unsigned int *)(ptr)) -#define tep_data2host8 (pevent, ptr) \ -({ \ - unsigned long long __val; \ - \ - memcpy(&__val, (ptr), sizeof(unsigned long long)); \ - __tep_data2host8(pevent, __val); \ -})static inline int tep_host_bigendian (void ) {
@@ -475,8 +461,6 @@ enum tep_errno tep_parse_format(struct tep_handle *pevent,struct tep_event **eventp, const char *buf, unsigned long size, const char *sys); -void tep_free_event (struct tep_event *event); -void tep_free_format_field (struct tep_format_field *field); void *tep_get_field_raw(struct trace_seq *s, struct tep_event *event, const char *name, struct tep_record *record,
Signature · 1 line
2.19.2
Arnaldo Carvalho de Melo
maintainerPATCH 34/75 perf beauty mmap_flags: Fixed syntax error Fixed missing ']' error
In reply to Arnaldo Carvalho de MeloFrom: Sihyeon Jang <[email protected]>
Committer testing:
Before:
# tools/perf/trace/beauty/mmap_flags.sh
static const char *mmap_flags[] = {
[ilog2(0x40) + 1] = "32BIT",
tools/perf/trace/beauty/mmap_flags.sh: line 23: [: missing `]'
[ilog2(0x01) + 1] = "SHARED",
[ilog2(0x02) + 1] = "PRIVATE",
[ilog2(0x10) + 1] = "FIXED",
[ilog2(0x20) + 1] = "ANONYMOUS",
[ilog2(0x100000) + 1] = "FIXED_NOREPLACE",
tools/perf/trace/beauty/mmap_flags.sh: line 28: [: missing `]'
[ilog2(0x0100) + 1] = "GROWSDOWN",
[ilog2(0x0800) + 1] = "DENYWRITE",
[ilog2(0x1000) + 1] = "EXECUTABLE",
[ilog2(0x2000) + 1] = "LOCKED",
[ilog2(0x4000) + 1] = "NORESERVE",
[ilog2(0x8000) + 1] = "POPULATE",
[ilog2(0x10000) + 1] = "NONBLOCK",
[ilog2(0x20000) + 1] = "STACK",
[ilog2(0x40000) + 1] = "HUGETLB",
[ilog2(0x80000) + 1] = "SYNC",
};
#After:
$ tools/perf/trace/beauty/mmap_flags.sh
static const char *mmap_flags[] = {
[ilog2(0x40) + 1] = "32BIT",
[ilog2(0x01) + 1] = "SHARED",
[ilog2(0x02) + 1] = "PRIVATE",
[ilog2(0x10) + 1] = "FIXED",
[ilog2(0x20) + 1] = "ANONYMOUS",
[ilog2(0x100000) + 1] = "FIXED_NOREPLACE",
[ilog2(0x0100) + 1] = "GROWSDOWN",
[ilog2(0x0800) + 1] = "DENYWRITE",
[ilog2(0x1000) + 1] = "EXECUTABLE",
[ilog2(0x2000) + 1] = "LOCKED",
[ilog2(0x4000) + 1] = "NORESERVE",
[ilog2(0x8000) + 1] = "POPULATE",
[ilog2(0x10000) + 1] = "NONBLOCK",
[ilog2(0x20000) + 1] = "STACK",
[ilog2(0x40000) + 1] = "HUGETLB",
[ilog2(0x80000) + 1] = "SYNC",
};
$--- tools/perf/trace/beauty/mmap_flags.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
tools/perf/trace/beauty/mmap_flags.sh +2 -2
@@ -20,12 +20,12 @@ egrep -q $regex ${arch_mman} && \ (egrep $regex ${arch_mman} | \ sed -r "s/$regex/\2 \1/g" | \ xargs printf "\t[ilog2(%s) + 1] = \"%s\",\n") -[ ! -f ${arch_mman} || egrep -q '#[[:space:]]*include[[:space:]]+<uapi/asm-generic/mman.*' ${arch_mman} ] && +([ ! -f ${arch_mman} ] || egrep -q '#[[:space:]]*include[[:space:]]+<uapi/asm-generic/mman.*' ${arch_mman}) && (egrep $regex ${header_dir}/mman-common.h | \ egrep -vw 'MAP_(UNINITIALIZED|TYPE|SHARED_VALIDATE)' | \ sed -r "s/$regex/\2 \1/g" | \ xargs printf "\t[ilog2(%s) + 1] = \"%s\",\n") -[ ! -f ${arch_mman} || egrep -q '#[[:space:]]*include[[:space:]]+<uapi/asm-generic/mman.h>.*' ${arch_mman} ] && +([ ! -f ${arch_mman} ] || egrep -q '#[[:space:]]*include[[:space:]]+<uapi/asm-generic/mman.h>.*' ${arch_mman}) && (egrep $regex ${header_dir}/mman.h | \ sed -r "s/$regex/\2 \1/g" | \ xargs printf "\t[ilog2(%s) + 1] = \"%s\",\n")
Signature · 1 line
2.19.2
Arnaldo Carvalho de Melo
maintainerPATCH 35/75 perf cs-etm: Support for ARM A32/T32 instruction sets in CoreSight trace
In reply to Arnaldo Carvalho de MeloFrom: Robert Walker <[email protected]>
This patch adds support for generating instruction samples from trace of AArch32 programs using the A32 and T32 instruction sets.
T32 has variable 2 or 4 byte instruction size, so the conversion between addresses and instruction counts requires extra information from the trace decoder, requiring version 0.10.0 of OpenCSD. A check for the OpenCSD library version has been added to the feature check for OpenCSD.
--- tools/build/feature/test-libopencsd.c | 8 +++ .../perf/util/cs-etm-decoder/cs-etm-decoder.c | 29 ++++++++ .../perf/util/cs-etm-decoder/cs-etm-decoder.h | 10 +++ tools/perf/util/cs-etm.c | 70 ++++++++----------- 4 files changed, 78 insertions(+), 39 deletions(-)
tools/build/feature/test-libopencsd.c +8 -0
@@ -1,6 +1,14 @@// SPDX-License-Identifier: GPL-2.0 #include <opencsd/c_api/opencsd_c_api.h> +/* +* Check OpenCSD library version is sufficient to provide required features +*/ +#define OCSD_MIN_VER ((0 << 16) | (10 << 8) | (0)) +#if !defined(OCSD_VER_NUM ) || (OCSD_VER_NUM <OCSD_MIN_VER ) +#error "OpenCSD >= 0.10.0 is required" +#endif +int main (void ) { (void )ocsd_get_version ();
tools/perf/util/cs-etm-decoder/cs-etm-decoder.c +29 -0
@@ -263,9 +263,12 @@ static void cs_etm_decoder__clear_buffer(struct cs_etm_decoder *decoder) decoder->tail =0 ; decoder->packet_count =0 ;for (i =0 ; i <MAX_BUFFER ; i++) { + decoder->packet_buffer[i].isa =CS_ETM_ISA_UNKNOWN ; decoder->packet_buffer[i].start_addr =CS_ETM_INVAL_ADDR ; decoder->packet_buffer[i].end_addr =CS_ETM_INVAL_ADDR ; + decoder->packet_buffer[i].instr_count =0 ; decoder->packet_buffer[i].last_instr_taken_branch = false; + decoder->packet_buffer[i].last_instr_size =0 ; decoder->packet_buffer[i].exc = false; decoder->packet_buffer[i].exc_ret = false; decoder->packet_buffer[i].cpu =INT_MIN ;
@@ -294,11 +297,15 @@ cs_etm_decoder__buffer_packet(struct cs_etm_decoder *decoder, decoder->packet_count++; decoder->packet_buffer[et].sample_type = sample_type; + decoder->packet_buffer[et].isa =CS_ETM_ISA_UNKNOWN ; decoder->packet_buffer[et].exc = false; decoder->packet_buffer[et].exc_ret = false; decoder->packet_buffer[et].cpu = *((int *)inode->priv); decoder->packet_buffer[et].start_addr =CS_ETM_INVAL_ADDR ; decoder->packet_buffer[et].end_addr =CS_ETM_INVAL_ADDR ; + decoder->packet_buffer[et].instr_count =0 ; + decoder->packet_buffer[et].last_instr_taken_branch = false; + decoder->packet_buffer[et].last_instr_size =0 ;if (decoder->packet_count ==MAX_BUFFER -1 )return OCSD_RESP_WAIT ;
@@ -321,8 +328,28 @@ cs_etm_decoder__buffer_range(struct cs_etm_decoder *decoder, packet = &decoder->packet_buffer[decoder->tail]; +switch (elem->isa) { +case ocsd_isa_aarch64: + packet->isa =CS_ETM_ISA_A64 ; +break ; +case ocsd_isa_arm: + packet->isa =CS_ETM_ISA_A32 ; +break ; +case ocsd_isa_thumb2: + packet->isa =CS_ETM_ISA_T32 ; +break ; +case ocsd_isa_tee: +case ocsd_isa_jazelle: +case ocsd_isa_custom: +case ocsd_isa_unknown: +default : + packet->isa =CS_ETM_ISA_UNKNOWN ; + } + packet->start_addr = elem->st_addr; packet->end_addr = elem->en_addr; + packet->instr_count = elem->num_instr_range; +switch (elem->last_i_type) {case OCSD_INSTR_BR :case OCSD_INSTR_BR_INDIRECT :
@@ -336,6 +363,8 @@ cs_etm_decoder__buffer_range(struct cs_etm_decoder *decoder,break ; } + packet->last_instr_size = elem->last_instr_sz; +return ret; }
tools/perf/util/cs-etm-decoder/cs-etm-decoder.h +10 -0
@@ -28,11 +28,21 @@ enum cs_etm_sample_type { CS_ETM_TRACE_ON = 1 << 1, }; +enum cs_etm_isa { +CS_ETM_ISA_UNKNOWN , +CS_ETM_ISA_A64 , +CS_ETM_ISA_A32 , +CS_ETM_ISA_T32 , +}; +struct cs_etm_packet {enum cs_etm_sample_type sample_type; +enum cs_etm_isa isa;u64 start_addr;u64 end_addr; +u32 instr_count;u8 last_instr_taken_branch; +u8 last_instr_size;u8 exc;u8 exc_ret;int cpu;
tools/perf/util/cs-etm.c +31 -39
109 lines not on this page · raw message
Signature · 1 line
2.19.2
Arnaldo Carvalho de Melo
maintainerPATCH 36/75 perf tests ARM: Disable breakpoint tests 32-bit
In reply to Arnaldo Carvalho de MeloFrom: Florian Fainelli <[email protected]>
The breakpoint tests on the ARM 32-bit kernel are broken in several ways.
The breakpoint length requested does not necessarily match whether the function address has the Thumb bit (bit 0) set or not, and this does matter to the ARM kernel hw_breakpoint infrastructure. See [1] for background.
[1]: https://lkml.org/lkml/2018/11/15/205
As Will indicated, the overflow handling would require single-stepping which is not supported at the moment. Just disable those tests for the ARM 32-bit platforms and update the comment above to explain these limitations.
--- tools/perf/tests/bp_signal.c | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-)
tools/perf/tests/bp_signal.c +14 -6
@@ -291,12 +291,20 @@ int test__bp_signal(struct test *test __maybe_unused, int subtest __maybe_unusedbool test__bp_signal_is_supported (void ) { -/* -* The powerpc so far does not have support to even create -* instruction breakpoint using the perf event interface. -* Once it's there we can release this. -*/ -#if defined(__powerpc__) || defined(__s390x__) +/* +* PowerPC and S390 do not support creation of instruction +* breakpoints using the perf_event interface. +* +* ARM requires explicit rounding down of the instruction +* pointer in Thumb mode, and then requires the single-step +* to be handled explicitly in the overflow handler to avoid +* stepping into the SIGIO handler and getting stuck on the +* breakpointed instruction. +* +* Just disable the test for these architectures until these +* issues are resolved. +*/ +#if defined(__powerpc__) || defined(__s390x__) || defined(__arm__)return false;#else return true;
Signature · 1 line
2.19.2
Arnaldo Carvalho de Melo
maintainerPATCH 37/75 perf vendor events intel: Fix diverse typos
In reply to Arnaldo Carvalho de MeloFrom: Ingo Molnar <[email protected]>
Go over the tools/ files that are maintained in Arnaldo's tree and fix common typos: half of them were in comments, the other half in JSON files.
( Care should be taken not to re-import these typos in the future,
if the JSON files get updated by the vendor without fixing the typos. )
No change in functionality intended.
Committer notes:
This was split from a larger patch as there are code that is, additionally, maintained outside the kernel tree, so to ease cherry picking and/or backporting, split this into multiple patches.
--- .../pmu-events/arch/x86/broadwell/cache.json | 4 +-- .../arch/x86/broadwell/pipeline.json | 2 +- .../arch/x86/broadwellde/cache.json | 4 +-- .../arch/x86/broadwellde/pipeline.json | 2 +- .../pmu-events/arch/x86/broadwellx/cache.json | 4 +-- .../arch/x86/broadwellx/pipeline.json | 2 +- .../pmu-events/arch/x86/jaketown/cache.json | 4 +-- .../arch/x86/jaketown/pipeline.json | 2 +- .../arch/x86/knightslanding/cache.json | 30 +++++++++---------- .../arch/x86/sandybridge/cache.json | 4 +-- .../arch/x86/sandybridge/pipeline.json | 2 +- .../arch/x86/skylakex/uncore-other.json | 12 ++++---- 12 files changed, 36 insertions(+), 36 deletions(-)
tools/perf/pmu-events/arch/x86/broadwell/cache.json +2 -2
@@ -433,7 +433,7 @@ }, { "PEBS": "1", - "PublicDescription": "This is a precise version (that is, uses PEBS) of the event that counts line-splitted load uops retired to the architected path. A line split is across 64B cache-line which includes a page split (4K).", + "PublicDescription": "This is a precise version (that is, uses PEBS) of the event that counts line-split load uops retired to the architected path. A line split is across 64B cache-line which includes a page split (4K).", "EventCode": "0xD0", "Counter": "0,1,2,3", "UMask": "0x41",
@@ -445,7 +445,7 @@ }, { "PEBS": "1", - "PublicDescription": "This is a precise version (that is, uses PEBS) of the event that counts line-splitted store uops retired to the architected path. A line split is across 64B cache-line which includes a page split (4K).", + "PublicDescription": "This is a precise version (that is, uses PEBS) of the event that counts line-split store uops retired to the architected path. A line split is across 64B cache-line which includes a page split (4K).", "EventCode": "0xD0", "Counter": "0,1,2,3", "UMask": "0x42",
tools/perf/pmu-events/arch/x86/broadwell/pipeline.json +1 -1
@@ -317,7 +317,7 @@ "CounterHTOff": "0,1,2,3,4,5,6,7" }, { - "PublicDescription": "This event counts stalls occured due to changing prefix length (66, 67 or REX.W when they change the length of the decoded instruction). Occurrences counting is proportional to the number of prefixes in a 16B-line. This may result in the following penalties: three-cycle penalty for each LCP in a 16-byte chunk.", + "PublicDescription": "This event counts stalls occurred due to changing prefix length (66, 67 or REX.W when they change the length of the decoded instruction). Occurrences counting is proportional to the number of prefixes in a 16B-line. This may result in the following penalties: three-cycle penalty for each LCP in a 16-byte chunk.", "EventCode": "0x87", "Counter": "0,1,2,3", "UMask": "0x1",
tools/perf/pmu-events/arch/x86/broadwellde/cache.json +2 -2
@@ -439,7 +439,7 @@ "PEBS": "1", "Counter": "0,1,2,3", "EventName": "MEM_UOPS_RETIRED.SPLIT_LOADS", - "PublicDescription": "This is a precise version (that is, uses PEBS) of the event that counts line-splitted load uops retired to the architected path. A line split is across 64B cache-line which includes a page split (4K).", + "PublicDescription": "This is a precise version (that is, uses PEBS) of the event that counts line-split load uops retired to the architected path. A line split is across 64B cache-line which includes a page split (4K).", "SampleAfterValue": "100003", "CounterHTOff": "0,1,2,3" },
@@ -451,7 +451,7 @@ "PEBS": "1", "Counter": "0,1,2,3", "EventName": "MEM_UOPS_RETIRED.SPLIT_STORES", - "PublicDescription": "This is a precise version (that is, uses PEBS) of the event that counts line-splitted store uops retired to the architected path. A line split is across 64B cache-line which includes a page split (4K).", + "PublicDescription": "This is a precise version (that is, uses PEBS) of the event that counts line-split store uops retired to the architected path. A line split is across 64B cache-line which includes a page split (4K).", "SampleAfterValue": "100003", "L1_Hit_Indication": "1", "CounterHTOff": "0,1,2,3"
tools/perf/pmu-events/arch/x86/broadwellde/pipeline.json +1 -1
@@ -322,7 +322,7 @@ "BriefDescription": "Stalls caused by changing prefix length of the instruction.", "Counter": "0,1,2,3", "EventName": "ILD_STALL.LCP", - "PublicDescription": "This event counts stalls occured due to changing prefix length (66, 67 or REX.W when they change the length of the decoded instruction). Occurrences counting is proportional to the number of prefixes in a 16B-line. This may result in the following penalties: three-cycle penalty for each LCP in a 16-byte chunk.", + "PublicDescription": "This event counts stalls occurred due to changing prefix length (66, 67 or REX.W when they change the length of the decoded instruction). Occurrences counting is proportional to the number of prefixes in a 16B-line. This may result in the following penalties: three-cycle penalty for each LCP in a 16-byte chunk.", "SampleAfterValue": "2000003", "CounterHTOff": "0,1,2,3,4,5,6,7" },
tools/perf/pmu-events/arch/x86/broadwellx/cache.json +2 -2
@@ -439,7 +439,7 @@ "PEBS": "1", "Counter": "0,1,2,3", "EventName": "MEM_UOPS_RETIRED.SPLIT_LOADS", - "PublicDescription": "This is a precise version (that is, uses PEBS) of the event that counts line-splitted load uops retired to the architected path. A line split is across 64B cache-line which includes a page split (4K).", + "PublicDescription": "This is a precise version (that is, uses PEBS) of the event that counts line-split load uops retired to the architected path. A line split is across 64B cache-line which includes a page split (4K).", "SampleAfterValue": "100003", "CounterHTOff": "0,1,2,3" },
@@ -451,7 +451,7 @@ "PEBS": "1", "Counter": "0,1,2,3", "EventName": "MEM_UOPS_RETIRED.SPLIT_STORES", - "PublicDescription": "This is a precise version (that is, uses PEBS) of the event that counts line-splitted store uops retired to the architected path. A line split is across 64B cache-line which includes a page split (4K).", + "PublicDescription": "This is a precise version (that is, uses PEBS) of the event that counts line-split store uops retired to the architected path. A line split is across 64B cache-line which includes a page split (4K).", "SampleAfterValue": "100003", "L1_Hit_Indication": "1", "CounterHTOff": "0,1,2,3"
tools/perf/pmu-events/arch/x86/broadwellx/pipeline.json +1 -1
@@ -322,7 +322,7 @@ "BriefDescription": "Stalls caused by changing prefix length of the instruction.", "Counter": "0,1,2,3", "EventName": "ILD_STALL.LCP", - "PublicDescription": "This event counts stalls occured due to changing prefix length (66, 67 or REX.W when they change the length of the decoded instruction). Occurrences counting is proportional to the number of prefixes in a 16B-line. This may result in the following penalties: three-cycle penalty for each LCP in a 16-byte chunk.", + "PublicDescription": "This event counts stalls occurred due to changing prefix length (66, 67 or REX.W when they change the length of the decoded instruction). Occurrences counting is proportional to the number of prefixes in a 16B-line. This may result in the following penalties: three-cycle penalty for each LCP in a 16-byte chunk.", "SampleAfterValue": "2000003", "CounterHTOff": "0,1,2,3,4,5,6,7" },
tools/perf/pmu-events/arch/x86/jaketown/cache.json +2 -2
@@ -31,7 +31,7 @@ }, { "PEBS": "1", - "PublicDescription": "This event counts line-splitted load uops retired to the architected path. A line split is across 64B cache-line which includes a page split (4K).", + "PublicDescription": "This event counts line-split load uops retired to the architected path. A line split is across 64B cache-line which includes a page split (4K).", "EventCode": "0xD0", "Counter": "0,1,2,3", "UMask": "0x41",
@@ -42,7 +42,7 @@ }, { "PEBS": "1", - "PublicDescription": "This event counts line-splitted store uops retired to the architected path. A line split is across 64B cache-line which includes a page split (4K).", + "PublicDescription": "This event counts line-split store uops retired to the architected path. A line split is across 64B cache-line which includes a page split (4K).", "EventCode": "0xD0", "Counter": "0,1,2,3", "UMask": "0x42",
tools/perf/pmu-events/arch/x86/jaketown/pipeline.json +1 -1
@@ -778,7 +778,7 @@ "CounterHTOff": "0,1,2,3,4,5,6,7" }, { - "PublicDescription": "This event counts loads that followed a store to the same address, where the data could not be forwarded inside the pipeline from the store to the load. The most common reason why store forwarding would be blocked is when a load's address range overlaps with a preceeding smaller uncompleted store. See the table of not supported store forwards in the Intel? 64 and IA-32 Architectures Optimization Reference Manual. The penalty for blocked store forwarding is that the load must wait for the store to complete before it can be issued.", + "PublicDescription": "This event counts loads that followed a store to the same address, where the data could not be forwarded inside the pipeline from the store to the load. The most common reason why store forwarding would be blocked is when a load's address range overlaps with a preceding smaller uncompleted store. See the table of not supported store forwards in the Intel? 64 and IA-32 Architectures Optimization Reference Manual. The penalty for blocked store forwarding is that the load must wait for the store to complete before it can be issued.", "EventCode": "0x03", "Counter": "0,1,2,3", "UMask": "0x2",
tools/perf/pmu-events/arch/x86/knightslanding/cache.json +15 -15
@@ -121,7 +121,7 @@ "EventName": "OFFCORE_RESPONSE.ANY_PF_L2.OUTSTANDING", "MSRIndex": "0x1a6", "SampleAfterValue": "100007", - "BriefDescription": "Counts any Prefetch requests that are outstanding, per weighted cycle, from the time of the request to when any response is received. The oustanding response should be programmed only on PMC0. ", + "BriefDescription": "Counts any Prefetch requests that are outstanding, per weighted cycle, from the time of the request to when any response is received. The outstanding response should be programmed only on PMC0. ", "Offcore": "1" }, {
@@ -187,7 +187,7 @@ "EventName": "OFFCORE_RESPONSE.ANY_READ.OUTSTANDING", "MSRIndex": "0x1a6", "SampleAfterValue": "100007", - "BriefDescription": "Counts any Read request that are outstanding, per weighted cycle, from the time of the request to when any response is received. The oustanding response should be programmed only on PMC0. ", + "BriefDescription": "Counts any Read request that are outstanding, per weighted cycle, from the time of the request to when any response is received. The outstanding response should be programmed only on PMC0. ", "Offcore": "1" }, {
@@ -253,7 +253,7 @@ "EventName": "OFFCORE_RESPONSE.ANY_CODE_RD.OUTSTANDING", "MSRIndex": "0x1a6", "SampleAfterValue": "100007", - "BriefDescription": "Counts Demand code reads and prefetch code read requests that are outstanding, per weighted cycle, from the time of the request to when any response is received. The oustanding response should be programmed only on PMC0. ", + "BriefDescription": "Counts Demand code reads and prefetch code read requests that are outstanding, per weighted cycle, from the time of the request to when any response is received. The outstanding response should be programmed only on PMC0. ", "Offcore": "1" }, {
@@ -319,7 +319,7 @@ "EventName": "OFFCORE_RESPONSE.ANY_RFO.OUTSTANDING", "MSRIndex": "0x1a6", "SampleAfterValue": "100007", - "BriefDescription": "Counts Demand cacheable data write requests that are outstanding, per weighted cycle, from the time of the request to when any response is received. The oustanding response should be programmed only on PMC0. ", + "BriefDescription": "Counts Demand cacheable data write requests that are outstanding, per weighted cycle, from the time of the request to when any response is received. The outstanding response should be programmed only on PMC0. ", "Offcore": "1" }, {
@@ -385,7 +385,7 @@ "EventName": "OFFCORE_RESPONSE.ANY_DATA_RD.OUTSTANDING", "MSRIndex": "0x1a6", "SampleAfterValue": "100007", - "BriefDescription": "Counts Demand cacheable data and L1 prefetch data read requests that are outstanding, per weighted cycle, from the time of the request to when any response is received. The oustanding response should be programmed only on PMC0. ", + "BriefDescription": "Counts Demand cacheable data and L1 prefetch data read requests that are outstanding, per weighted cycle, from the time of the request to when any response is received. The outstanding response should be programmed only on PMC0. ", "Offcore": "1" }, {
@@ -451,7 +451,7 @@ "EventName": "OFFCORE_RESPONSE.ANY_REQUEST.OUTSTANDING", "MSRIndex": "0x1a6", "SampleAfterValue": "100007", - "BriefDescription": "Counts any request that are outstanding, per weighted cycle, from the time of the request to when any response is received. The oustanding response should be programmed only on PMC0. ", + "BriefDescription": "Counts any request that are outstanding, per weighted cycle, from the time of the request to when any response is received. The outstanding response should be programmed only on PMC0. ", "Offcore": "1" }, {
@@ -539,7 +539,7 @@ "EventName": "OFFCORE_RESPONSE.PF_L1_DATA_RD.OUTSTANDING", "MSRIndex": "0x1a6", "SampleAfterValue": "100007", - "BriefDescription": "Counts L1 data HW prefetches that are outstanding, per weighted cycle, from the time of the request to when any response is received. The oustanding response should be programmed only on PMC0. ", + "BriefDescription": "Counts L1 data HW prefetches that are outstanding, per weighted cycle, from the time of the request to when any response is received. The outstanding response should be programmed only on PMC0. ", "Offcore": "1" }, {
@@ -605,7 +605,7 @@ "EventName": "OFFCORE_RESPONSE.PF_SOFTWARE.OUTSTANDING", "MSRIndex": "0x1a6", "SampleAfterValue": "100007", - "BriefDescription": "Counts Software Prefetches that are outstanding, per weighted cycle, from the time of the request to when any response is received. The oustanding response should be programmed only on PMC0. ", + "BriefDescription": "Counts Software Prefetches that are outstanding, per weighted cycle, from the time of the request to when any response is received. The outstanding response should be programmed only on PMC0. ", "Offcore": "1" }, {
@@ -682,7 +682,7 @@ "EventName": "OFFCORE_RESPONSE.BUS_LOCKS.OUTSTANDING", "MSRIndex": "0x1a6", "SampleAfterValue": "100007", - "BriefDescription": "Counts Bus locks and split lock requests that are outstanding, per weighted cycle, from the time of the request to when any response is received. The oustanding response should be programmed only on PMC0. ", + "BriefDescription": "Counts Bus locks and split lock requests that are outstanding, per weighted cycle, from the time of the request to when any response is received. The outstanding response should be programmed only on PMC0. ", "Offcore": "1" }, {
@@ -748,7 +748,7 @@ "EventName": "OFFCORE_RESPONSE.UC_CODE_READS.OUTSTANDING", "MSRIndex": "0x1a6", "SampleAfterValue": "100007", - "BriefDescription": "Counts UC code reads (valid only for Outstanding response type) that are outstanding, per weighted cycle, from the time of the request to when any response is received. The oustanding response should be programmed only on PMC0. ", + "BriefDescription": "Counts UC code reads (valid only for Outstanding response type) that are outstanding, per weighted cycle, from the time of the request to when any response is received. The outstanding response should be programmed only on PMC0. ", "Offcore": "1" }, {
@@ -869,7 +869,7 @@ "EventName": "OFFCORE_RESPONSE.PARTIAL_READS.OUTSTANDING", "MSRIndex": "0x1a6", "SampleAfterValue": "100007", - "BriefDescription": "Counts Partial reads (UC or WC and is valid only for Outstanding response type). that are outstanding, per weighted cycle, from the time of the request to when any response is received. The oustanding response should be programmed only on PMC0. ", + "BriefDescription": "Counts Partial reads (UC or WC and is valid only for Outstanding response type). that are outstanding, per weighted cycle, from the time of the request to when any response is received. The outstanding response should be programmed only on PMC0. ", "Offcore": "1" }, {
@@ -935,7 +935,7 @@ "EventName": "OFFCORE_RESPONSE.PF_L2_CODE_RD.OUTSTANDING", "MSRIndex": "0x1a6", "SampleAfterValue": "100007", - "BriefDescription": "Counts L2 code HW prefetches that are outstanding, per weighted cycle, from the time of the request to when any response is received. The oustanding response should be programmed only on PMC0. ", + "BriefDescription": "Counts L2 code HW prefetches that are outstanding, per weighted cycle, from the time of the request to when any response is received. The outstanding response should be programmed only on PMC0. ", "Offcore": "1" }, {
@@ -1067,7 +1067,7 @@ "EventName": "OFFCORE_RESPONSE.DEMAND_CODE_RD.OUTSTANDING", "MSRIndex": "0x1a6", "SampleAfterValue": "100007", - "BriefDescription": "Counts demand code reads and prefetch code reads that are outstanding, per weighted cycle, from the time of the request to when any response is received. The oustanding response should be programmed only on PMC0. ", + "BriefDescription": "Counts demand code reads and prefetch code reads that are outstanding, per weighted cycle, from the time of the request to when any response is received. The outstanding response should be programmed only on PMC0. ", "Offcore": "1" }, {
@@ -1133,7 +1133,7 @@ "EventName": "OFFCORE_RESPONSE.DEMAND_RFO.OUTSTANDING", "MSRIndex": "0x1a6", "SampleAfterValue": "100007", - "BriefDescription": "Counts Demand cacheable data writes that are outstanding, per weighted cycle, from the time of the request to when any response is received. The oustanding response should be programmed only on PMC0. ", + "BriefDescription": "Counts Demand cacheable data writes that are outstanding, per weighted cycle, from the time of the request to when any response is received. The outstanding response should be programmed only on PMC0. ", "Offcore": "1" }, {
@@ -1199,7 +1199,7 @@ "EventName": "OFFCORE_RESPONSE.DEMAND_DATA_RD.OUTSTANDING", "MSRIndex": "0x1a6", "SampleAfterValue": "100007", - "BriefDescription": "Counts demand cacheable data and L1 prefetch data reads that are outstanding, per weighted cycle, from the time of the request to when any response is received. The oustanding response should be programmed only on PMC0. ", + "BriefDescription": "Counts demand cacheable data and L1 prefetch data reads that are outstanding, per weighted cycle, from the time of the request to when any response is received. The outstanding response should be programmed only on PMC0. ", "Offcore": "1" }, {
tools/perf/pmu-events/arch/x86/sandybridge/cache.json +2 -2
@@ -31,7 +31,7 @@ }, { "PEBS": "1", - "PublicDescription": "This event counts line-splitted load uops retired to the architected path. A line split is across 64B cache-line which includes a page split (4K).", + "PublicDescription": "This event counts line-split load uops retired to the architected path. A line split is across 64B cache-line which includes a page split (4K).", "EventCode": "0xD0", "Counter": "0,1,2,3", "UMask": "0x41",
@@ -42,7 +42,7 @@ }, { "PEBS": "1", - "PublicDescription": "This event counts line-splitted store uops retired to the architected path. A line split is across 64B cache-line which includes a page split (4K).", + "PublicDescription": "This event counts line-split store uops retired to the architected path. A line split is across 64B cache-line which includes a page split (4K).", "EventCode": "0xD0", "Counter": "0,1,2,3", "UMask": "0x42",
tools/perf/pmu-events/arch/x86/sandybridge/pipeline.json +1 -1
@@ -778,7 +778,7 @@ "CounterHTOff": "0,1,2,3,4,5,6,7" }, { - "PublicDescription": "This event counts loads that followed a store to the same address, where the data could not be forwarded inside the pipeline from the store to the load. The most common reason why store forwarding would be blocked is when a load's address range overlaps with a preceeding smaller uncompleted store. See the table of not supported store forwards in the Intel? 64 and IA-32 Architectures Optimization Reference Manual. The penalty for blocked store forwarding is that the load must wait for the store to complete before it can be issued.", + "PublicDescription": "This event counts loads that followed a store to the same address, where the data could not be forwarded inside the pipeline from the store to the load. The most common reason why store forwarding would be blocked is when a load's address range overlaps with a preceding smaller uncompleted store. See the table of not supported store forwards in the Intel? 64 and IA-32 Architectures Optimization Reference Manual. The penalty for blocked store forwarding is that the load must wait for the store to complete before it can be issued.", "EventCode": "0x03", "Counter": "0,1,2,3", "UMask": "0x2",
tools/perf/pmu-events/arch/x86/skylakex/uncore-other.json +6 -6
@@ -428,7 +428,7 @@ "EventCode": "0x5C", "EventName": "UNC_CHA_SNOOP_RESP.RSP_WBWB", "PerPkg": "1", - "PublicDescription": "Counts when a transaction with the opcode type Rsp*WB Snoop Response was received which indicates which indicates the data was written back to it's home. This is returned when a non-RFO request hits a cacheline in the Modified state. The Cache can either downgrade the cacheline to a S (Shared) or I (Invalid) state depending on how the system has been configured. This reponse will also be sent when a cache requests E (Exclusive) ownership of a cache line without receiving data, because the cache must acquire ownership.", + "PublicDescription": "Counts when a transaction with the opcode type Rsp*WB Snoop Response was received which indicates which indicates the data was written back to it's home. This is returned when a non-RFO request hits a cacheline in the Modified state. The Cache can either downgrade the cacheline to a S (Shared) or I (Invalid) state depending on how the system has been configured. This response will also be sent when a cache requests E (Exclusive) ownership of a cache line without receiving data, because the cache must acquire ownership.", "UMask": "0x10", "Unit": "CHA" },
@@ -967,7 +967,7 @@ "EventCode": "0x57", "EventName": "UNC_M2M_PREFCAM_INSERTS", "PerPkg": "1", - "PublicDescription": "Counts when the M2M (Mesh to Memory) recieves a prefetch request and inserts it into its outstanding prefetch queue. Explanatory Side Note: the prefect queue is made from CAM: Content Addressable Memory", + "PublicDescription": "Counts when the M2M (Mesh to Memory) receives a prefetch request and inserts it into its outstanding prefetch queue. Explanatory Side Note: the prefect queue is made from CAM: Content Addressable Memory", "Unit": "M2M" }, {
@@ -1041,7 +1041,7 @@ "EventCode": "0x31", "EventName": "UNC_UPI_RxL_BYPASSED.SLOT0", "PerPkg": "1", - "PublicDescription": "Counts incoming FLITs (FLow control unITs) which bypassed the slot0 RxQ buffer (Receive Queue) and passed directly to the Egress. This is a latency optimization, and should generally be the common case. If this value is less than the number of FLITs transfered, it implies that there was queueing getting onto the ring, and thus the transactions saw higher latency.", + "PublicDescription": "Counts incoming FLITs (FLow control unITs) which bypassed the slot0 RxQ buffer (Receive Queue) and passed directly to the Egress. This is a latency optimization, and should generally be the common case. If this value is less than the number of FLITs transferred, it implies that there was queueing getting onto the ring, and thus the transactions saw higher latency.", "UMask": "0x1", "Unit": "UPI LL" },
@@ -1051,17 +1051,17 @@ "EventCode": "0x31", "EventName": "UNC_UPI_RxL_BYPASSED.SLOT1", "PerPkg": "1", - "PublicDescription": "Counts incoming FLITs (FLow control unITs) which bypassed the slot1 RxQ buffer (Receive Queue) and passed directly across the BGF and into the Egress. This is a latency optimization, and should generally be the common case. If this value is less than the number of FLITs transfered, it implies that there was queueing getting onto the ring, and thus the transactions saw higher latency.", + "PublicDescription": "Counts incoming FLITs (FLow control unITs) which bypassed the slot1 RxQ buffer (Receive Queue) and passed directly across the BGF and into the Egress. This is a latency optimization, and should generally be the common case. If this value is less than the number of FLITs transferred, it implies that there was queueing getting onto the ring, and thus the transactions saw higher latency.", "UMask": "0x2", "Unit": "UPI LL" }, { - "BriefDescription": "FLITs received which bypassed the Slot0 Recieve Buffer", + "BriefDescription": "FLITs received which bypassed the Slot0 Receive Buffer", "Counter": "0,1,2,3", "EventCode": "0x31", "EventName": "UNC_UPI_RxL_BYPASSED.SLOT2", "PerPkg": "1", - "PublicDescription": "Counts incoming FLITs (FLow control unITs) whcih bypassed the slot2 RxQ buffer (Receive Queue) and passed directly to the Egress. This is a latency optimization, and should generally be the common case. If this value is less than the number of FLITs transfered, it implies that there was queueing getting onto the ring, and thus the transactions saw higher latency.", + "PublicDescription": "Counts incoming FLITs (FLow control unITs) which bypassed the slot2 RxQ buffer (Receive Queue) and passed directly to the Egress. This is a latency optimization, and should generally be the common case. If this value is less than the number of FLITs transferred, it implies that there was queueing getting onto the ring, and thus the transactions saw higher latency.", "UMask": "0x4", "Unit": "UPI LL" },
Signature · 1 line
2.19.2
Arnaldo Carvalho de Melo
maintainerPATCH 38/75 tools lib traceevent: Fix diverse typos in comments
In reply to Arnaldo Carvalho de MeloFrom: Ingo Molnar <[email protected]>
Go over the tools/ files that are maintained in Arnaldo's tree and fix common typos: half of them were in comments, the other half in JSON files.
No change in functionality intended.
Committer notes:
This was split from a larger patch as there are code that is, additionally, maintained outside the kernel tree, so to ease cherry picking and/or backporting, split this into multiple patches.
--- tools/lib/traceevent/event-parse.c | 12 ++++++------ tools/lib/traceevent/plugin_kvm.c | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-)
tools/lib/traceevent/event-parse.c +6 -6
@@ -1145,7 +1145,7 @@ static enum tep_event_type read_token(char **tok) }/** -* tep_read_token - access to utilites to use the pevent parser +* tep_read_token - access to utilities to use the pevent parser * @tok: The token to return * * This will parse tokens from the string given by
@@ -3258,7 +3258,7 @@ static int event_read_print(struct tep_event *event)* @name: the name of the common field to return * * Returns a common field from the event by the given @name. -* This only searchs the common fields and not all field. +* This only searches the common fields and not all field. */ struct tep_format_field *tep_find_common_field (struct tep_event *event,const char *name)
@@ -3302,7 +3302,7 @@ tep_find_field(struct tep_event *event, const char *name)* @name: the name of the field * * Returns a field by the given @name. -* This searchs the common field names first, then +* This searches the common field names first, then * the non-common ones if a common one was not found. */ struct tep_format_field *
@@ -3841,7 +3841,7 @@ static void print_bitmask_to_seq(struct tep_handle *pevent,/* * data points to a bit mask of size bytes. * In the kernel, this is an array of long words, thus -* endianess is very important. +* endianness is very important. */ if (pevent->file_bigendian) index = size - (len +1 );
@@ -5316,9 +5316,9 @@ pid_from_cmdlist(struct tep_handle *pevent, const char *comm, struct cmdline *ne* This returns the cmdline structure that holds a pid for a given * comm, or NULL if none found. As there may be more than one pid for * a given comm, the result of this call can be passed back into -* a recurring call in the @next paramater, and then it will find the +* a recurring call in the @next parameter, and then it will find the * next pid. -* Also, it does a linear seach, so it may be slow. +* Also, it does a linear search, so it may be slow. */ struct cmdline *tep_data_pid_from_comm (struct tep_handle *pevent,const char *comm,struct cmdline *next)
tools/lib/traceevent/plugin_kvm.c +1 -1
@@ -387,7 +387,7 @@ static int kvm_mmu_print_role(struct trace_seq *s, struct tep_record *record,/* * We can only use the structure if file is of the same -* endianess. +* endianness. */ if (tep_is_file_bigendian (event->pevent) ==tep_is_host_bigendian (event->pevent)) {
Signature · 1 line
2.19.2
Arnaldo Carvalho de Melo
maintainerPATCH 39/75 perf tools Documentation: Fix diverse typos
In reply to Arnaldo Carvalho de MeloFrom: Ingo Molnar <[email protected]>
Go over the tools/ files that are maintained in Arnaldo's tree and fix common typos: half of them were in comments, the other half in JSON files.
No change in functionality intended.
Committer notes:
This was split from a larger patch as there are code that is, additionally, maintained outside the kernel tree, so to ease cherry picking and/or backporting, split this into multiple patches.
In this particular case, it affects documentation, so may be interesting to cherry pick as it is information that is presented to the user.
--- tools/perf/Documentation/perf-list.txt | 2 +- tools/perf/Documentation/perf-report.txt | 2 +- tools/perf/Documentation/perf-stat.txt | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-)
tools/perf/Documentation/perf-list.txt +1 -1
@@ -172,7 +172,7 @@ like cycles and instructions and some software events. Other PMUs and global measurements are normally root only. Some event qualifiers, such as "any", are also root only. -This can be overriden by setting the kernel.perf_event_paranoid +This can be overridden by setting the kernel.perf_event_paranoid sysctl to -1, which allows non root to use these events. For accessing trace point events perf needs to have read access to
tools/perf/Documentation/perf-report.txt +1 -1
@@ -252,7 +252,7 @@ OPTIONS Usually more convenient to use --branch-history for this. value can be: - - percent: diplay overhead percent (default) + - percent: display overhead percent (default) - period: display event period - count: display event count
tools/perf/Documentation/perf-stat.txt +2 -2
@@ -50,7 +50,7 @@ report:: /sys/bus/event_source/devices/<pmu>/format/* Note that the last two syntaxes support prefix and glob matching in - the PMU name to simplify creation of events accross multiple instances + the PMU name to simplify creation of events across multiple instances of the same type of PMU in large systems (e.g. memory controller PMUs). Multiple PMU instances are typical for uncore PMUs, so the prefix 'uncore_' is also ignored when performing this match.
@@ -277,7 +277,7 @@ echo 0 > /proc/sys/kernel/nmi_watchdog for best results. Otherwise the bottlenecks may be inconsistent on workload with changing phases. -This enables --metric-only, unless overriden with --no-metric-only. +This enables --metric-only, unless overridden with --no-metric-only. To interpret the results it is usually needed to know on which CPUs the workload runs on. If needed the CPUs can be forced using
Signature · 1 line
2.19.2
Arnaldo Carvalho de Melo
maintainerPATCH 40/75 perf bpf-loader: Fix debugging message typo
In reply to Arnaldo Carvalho de MeloFrom: Ingo Molnar <[email protected]>
Go over the tools/ files that are maintained in Arnaldo's tree and fix common typos: half of them were in comments, the other half in JSON files.
No change in functionality intended.
Committer notes:
This was split from a larger patch as there are code that is, additionally, maintained outside the kernel tree, so to ease cherry picking and/or backporting, split this into multiple patches.
This one has information that is presented to the user, albeit in debug mode.
--- tools/perf/util/bpf-loader.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
tools/perf/util/bpf-loader.c +1 -1
@@ -99,7 +99,7 @@ struct bpf_object *bpf__prepare_load(const char *filename, bool source)if (err)return ERR_PTR (-BPF_LOADER_ERRNO__COMPILE ); }else -pr_debug ("bpf: successfull builtin compilation\n" ); +pr_debug ("bpf: successful builtin compilation\n" ); obj =bpf_object__open_buffer (obj_buf, obj_buf_sz, filename);if (!IS_ERR_OR_NULL (obj) && llvm_param.dump_obj)
Signature · 1 line
2.19.2
Arnaldo Carvalho de Melo
maintainerPATCH 41/75 perf tools: Fix diverse comment typos
In reply to Arnaldo Carvalho de MeloFrom: Ingo Molnar <[email protected]>
Go over the tools/ files that are maintained in Arnaldo's tree and fix common typos: half of them were in comments, the other half in JSON files.
No change in functionality intended.
Committer notes:
This was split from a larger patch as there are code that is, additionally, maintained outside the kernel tree, so to ease cherry-picking and/or backporting, split this into multiple patches.
Just typos in comments, no need to backport, reducing the possibility of possible backporting artifacts.
--- tools/perf/arch/x86/tests/insn-x86.c | 2 +- tools/perf/builtin-top.c | 2 +- tools/perf/builtin-trace.c | 2 +- tools/perf/tests/attr.c | 2 +- tools/perf/util/annotate.c | 2 +- tools/perf/util/header.c | 2 +- tools/perf/util/hist.c | 2 +- tools/perf/util/jitdump.c | 2 +- tools/perf/util/machine.c | 2 +- tools/perf/util/probe-event.c | 4 ++-- tools/perf/util/sort.c | 2 +- 11 files changed, 12 insertions(+), 12 deletions(-)
tools/perf/arch/x86/tests/insn-x86.c +1 -1
@@ -170,7 +170,7 @@ static int test_data_set(struct test_data *dat_set, int x86_64)* * If the test passes %0 is returned, otherwise %-1 is returned. Use the * verbose (-v) option to see all the instructions and whether or not they -* decoded successfuly. +* decoded successfully. */ int test__insn_x86 (struct test *test__maybe_unused ,int subtest__maybe_unused ) {
tools/perf/builtin-top.c +1 -1
@@ -595,7 +595,7 @@ static void *display_thread_tui(void *arg)/* * Initialize the uid_filter_str, in the future the TUI will allow -* Zooming in/out UIDs. For now juse use whatever the user passed +* Zooming in/out UIDs. For now just use whatever the user passed * via --uid. */ evlist__for_each_entry (top->evlist, pos) {
tools/perf/builtin-trace.c +1 -1
@@ -2782,7 +2782,7 @@ static int trace__run(struct trace *trace, int argc, const char **argv)* 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. +* to override an explicitly set --max-stack global setting. */ evlist__for_each_entry (evlist, evsel) { if (evsel__has_callchain(evsel) &&
tools/perf/tests/attr.c +1 -1
@@ -182,7 +182,7 @@ int test__attr(struct test *test __maybe_unused, int subtest __maybe_unused)char path_perf[PATH_MAX ];char path_dir[PATH_MAX ]; -/* First try developement tree tests. */ +/* First try development tree tests. */ if (!lstat ("./tests" , &st))return run_dir ("./tests" ,"./perf" );
tools/perf/util/annotate.c +1 -1
@@ -1772,7 +1772,7 @@ static int symbol__disassemble(struct symbol *sym, struct annotate_args *args)while (!feof (file)) {/* * The source code line number (lineno) needs to be kept in -* accross calls to symbol__parse_objdump_line(), so that it +* across calls to symbol__parse_objdump_line(), so that it * can associate it with the instructions till the next one. * See disasm_line__new() and struct disasm_line::line_nr. */
tools/perf/util/header.c +1 -1
@@ -2798,7 +2798,7 @@ static int perf_header__adds_write(struct perf_header *header,lseek (fd, sec_start,SEEK_SET );/* * may write more than needed due to dropped feature, but -* this is okay, reader will skip the mising entries +* this is okay, reader will skip the missing entries */ err =do_write (&ff, feat_sec, sec_size);if (err <0 )
tools/perf/util/hist.c +1 -1
@@ -1160,7 +1160,7 @@ void hist_entry__delete(struct hist_entry *he)/* * If this is not the last column, then we need to pad it according to the -* pre-calculated max lenght for this column, otherwise don't bother adding +* pre-calculated max length for this column, otherwise don't bother adding * spaces because that would break viewing this with, for instance, 'less', * that would show tons of trailing spaces when a long C++ demangled method * names is sampled.
tools/perf/util/jitdump.c +1 -1
@@ -38,7 +38,7 @@ struct jit_buf_desc {uint64_t sample_type;size_t bufsize;FILE *in; -bool needs_bswap;/* handles cross-endianess */ +bool needs_bswap;/* handles cross-endianness */ bool use_arch_timestamp;void *debug_data;void *unwinding_data;
tools/perf/util/machine.c +1 -1
@@ -137,7 +137,7 @@ struct machine *machine__new_kallsyms(void)struct machine *machine =machine__new_host ();/* * FIXME: -* 1) We should switch to machine__load_kallsyms(), i.e. not explicitely +* 1) We should switch to machine__load_kallsyms(), i.e. not explicitly * ask for not using the kcore parsing code, once this one is fixed * to create a map per module. */
tools/perf/util/probe-event.c +2 -2
@@ -692,7 +692,7 @@ static int add_exec_to_probe_trace_events(struct probe_trace_event *tevs,return ret;for (i =0 ; i < ntevs && ret >=0 ; i++) { -/* point.address is the addres of point.symbol + point.offset */ +/* point.address is the address of point.symbol + point.offset */ tevs[i].point.address -= stext; tevs[i].point.module =strdup (exec);if (!tevs[i].point.module) {
@@ -3062,7 +3062,7 @@ static int try_to_find_absolute_address(struct perf_probe_event *pev,/* * Give it a '0x' leading symbol name. * In __add_probe_trace_events, a NULL symbol is interpreted as -* invalud. +* invalid. */ if (asprintf (&tp->symbol,"0x%lx" , tp->address) <0 ) goto errout;
tools/perf/util/sort.c +1 -1
@@ -37,7 +37,7 @@ enum sort_mode sort__mode = SORT_MODE__NORMAL;* -t, --field-separator * * option, that uses a special separator character and don't pad with spaces, -* replacing all occurances of this separator in symbol names (and other +* replacing all occurrences of this separator in symbol names (and other * output) with a '.' character, that thus it's the only non valid separator. */ static int repsep_snprintf (char *bf,size_t size,const char *fmt, ...)
Signature · 1 line
2.19.2
Arnaldo Carvalho de Melo
maintainerPATCH 42/75 tools lib subcmd: Fix a few source code comment typos
In reply to Arnaldo Carvalho de MeloFrom: Ingo Molnar <[email protected]>
Go over the tools/ files that are maintained in Arnaldo's tree and fix common typos: half of them were in comments, the other half in JSON files.
No change in functionality intended.
Committer notes:
This was split from a larger patch as there are code that is, additionally, maintained outside the kernel tree, so to ease cherry-picking and/or backporting, split this into multiple patches.
--- tools/lib/subcmd/parse-options.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
tools/lib/subcmd/parse-options.h +2 -2
@@ -71,7 +71,7 @@ typedef int parse_opt_cb(const struct option *, const char *arg, int unset);* * `argh`:: * token to explain the kind of argument this option wants. Keep it -* homogenous across the repository. +* homogeneous across the repository. * * `help`:: * the short help associated to what the option does.
@@ -80,7 +80,7 @@ typedef int parse_opt_cb(const struct option *, const char *arg, int unset);* * `flags`:: * mask of parse_opt_option_flags. -* PARSE_OPT_OPTARG: says that the argument is optionnal (not for BOOLEANs) +* PARSE_OPT_OPTARG: says that the argument is optional (not for BOOLEANs) * PARSE_OPT_NOARG: says that this option takes no argument, for CALLBACKs * PARSE_OPT_NONEG: says that this option cannot be negated * PARSE_OPT_HIDDEN this option is skipped in the default usage, showed in
Signature · 1 line
2.19.2
Arnaldo Carvalho de Melo
maintainerPATCH 43/75 perf tools: Allow specifying proc-map-timeout in config file
In reply to Arnaldo Carvalho de MeloFrom: Mark Drayton <[email protected]>
The default timeout of 500ms for parsing /proc/<pid>/maps files is too short for profiling many of our services.
This can be overridden by passing --proc-map-timeout to the relevant command but it'd be nice to globally increase our default value.
This patch permits setting a different default with the core.proc-map-timeout config file parameter.
--- tools/perf/Documentation/perf-config.txt | 6 +++++ tools/perf/builtin-kvm.c | 6 ++--- tools/perf/builtin-record.c | 8 +++--- tools/perf/builtin-top.c | 4 +-- tools/perf/builtin-trace.c | 5 ++-- tools/perf/perf.h | 1 - tools/perf/tests/code-reading.c | 2 +- tools/perf/tests/dwarf-unwind.c | 2 +- tools/perf/tests/mmap-thread-lookup.c | 4 +-- tools/perf/util/config.c | 4 +++ tools/perf/util/event.c | 32 ++++++++++-------------- tools/perf/util/event.h | 8 +++--- tools/perf/util/machine.c | 4 +-- tools/perf/util/machine.h | 3 --- 14 files changed, 39 insertions(+), 50 deletions(-)
tools/perf/Documentation/perf-config.txt +6 -0
@@ -199,6 +199,12 @@ colors.*:: Colors for headers in the output of a sub-commands (top, report). Default values are 'white', 'blue'. +core.*:: + core.proc-map-timeout:: + Sets a timeout (in milliseconds) for parsing /proc/<pid>/maps files. + Can be overridden by the --proc-map-timeout option on supported + subcommands. The default timeout is 500ms. + tui.*, gtk.*:: Subcommands that can be configured here are 'top', 'report' and 'annotate'. These values are booleans, for example:
tools/perf/builtin-kvm.c +2 -4
@@ -1364,7 +1364,7 @@ static int kvm_events_live(struct perf_kvm_stat *kvm,"show events other than" " HLT (x86 only) or Wait state (s390 only)" " that take longer than duration usecs"), -OPT_UINTEGER (0 ,"proc-map-timeout" , &kvm->opts.proc_map_timeout, +OPT_UINTEGER (0 ,"proc-map-timeout" , &proc_map_timeout,"per thread proc mmap processing timeout in ms" ), OPT_END() };
@@ -1394,7 +1394,6 @@ static int kvm_events_live(struct perf_kvm_stat *kvm, kvm->opts.target.uses_mmap = false; kvm->opts.target.uid_str =NULL ; kvm->opts.target.uid =UINT_MAX ; - kvm->opts.proc_map_timeout =500 ;symbol__init (NULL );disable_buildid_cache ();
@@ -1453,8 +1452,7 @@ static int kvm_events_live(struct perf_kvm_stat *kvm,perf_session__set_id_hdr_size (kvm->session);ordered_events__set_copy_on_queue (&kvm->session->ordered_events, true);machine__synthesize_threads (&kvm->session->machines.host, &kvm->opts.target, - kvm->evlist->threads, false, - kvm->opts.proc_map_timeout,1 ); + kvm->evlist->threads, false,1 ); err =kvm_live_open_events (kvm);if (err) goto out;
tools/perf/builtin-record.c +3 -5
@@ -867,8 +867,7 @@ static int record__synthesize_workload(struct record *rec, bool tail) err =perf_event__synthesize_thread_map (&rec->tool, thread_map, process_synthesized_event, &rec->session->machines.host, - rec->opts.sample_address, - rec->opts.proc_map_timeout); + rec->opts.sample_address);thread_map__put (thread_map);return err; }
@@ -1085,7 +1084,7 @@ static int record__synthesize(struct record *rec, bool tail) err =__machine__synthesize_threads (machine, tool, &opts->target, rec->evlist->threads, process_synthesized_event, opts->sample_address, - opts->proc_map_timeout,1 ); +1 ); out:return err; }
@@ -1783,7 +1782,6 @@ static struct record record = { .uses_mmap = true, .default_per_cpu = true, }, - .proc_map_timeout = 500, }, .tool = { .sample = process_sample_event,
@@ -1913,7 +1911,7 @@ static struct option __record_options[] = { parse_clockid),OPT_STRING_OPTARG ('S' ,"snapshot" , &record.opts.auxtrace_snapshot_opts,"opts" ,"AUX area tracing Snapshot Mode" ,"" ), -OPT_UINTEGER (0 ,"proc-map-timeout" , &record.opts.proc_map_timeout, +OPT_UINTEGER (0 ,"proc-map-timeout" , &proc_map_timeout,"per thread proc mmap processing timeout in ms" ),OPT_BOOLEAN (0 ,"namespaces" , &record.opts.record_namespaces, "Record namespaces events"),
tools/perf/builtin-top.c +1 -3
@@ -1096,7 +1096,6 @@ static int __cmd_top(struct perf_top *top)machine__synthesize_threads (&top->session->machines.host, &opts->target, top->evlist->threads, false, - opts->proc_map_timeout, top->nr_threads_synthesize);if (top->nr_threads_synthesize >1 )
@@ -1256,7 +1255,6 @@ int cmd_top(int argc, const char **argv) .target = { .uses_mmap = true, }, - .proc_map_timeout = 500,/* * FIXME: This will lose PERF_RECORD_MMAP and other metadata * when we pause, fix that and reenable. Probably using a
@@ -1369,7 +1367,7 @@ int cmd_top(int argc, const char **argv)OPT_STRING ('w' ,"column-widths" , &symbol_conf.col_width_list_str,"width[,width...]" ,"don't try to adjust column width, use these fixed values" ), -OPT_UINTEGER (0 ,"proc-map-timeout" , &opts->proc_map_timeout, +OPT_UINTEGER (0 ,"proc-map-timeout" , &proc_map_timeout,"per thread proc mmap processing timeout in ms" ), OPT_CALLBACK_NOOPT('b', "branch-any", &opts->branch_stack, "branch any", "sample any taken branches",
tools/perf/builtin-trace.c +2 -3
@@ -1264,7 +1264,7 @@ static int trace__symbols_init(struct trace *trace, struct perf_evlist *evlist) err =__machine__synthesize_threads (trace->host, &trace->tool, &trace->opts.target, evlist->threads, trace__tool_process, false, - trace->opts.proc_map_timeout,1 ); +1 ); out:if (err)symbol__exit ();
@@ -3393,7 +3393,6 @@ int cmd_trace(int argc, const char **argv) .user_interval = ULLONG_MAX, .no_buffering = true, .mmap_pages = UINT_MAX, - .proc_map_timeout = 500, }, .output = stderr, .show_comm = true,
@@ -3464,7 +3463,7 @@ int cmd_trace(int argc, const char **argv) "Default: kernel.perf_event_max_stack or " __stringify(PERF_MAX_STACK_DEPTH)),OPT_BOOLEAN (0 ,"print-sample" , &trace.print_sample,"print the PERF_RECORD_SAMPLE PERF_SAMPLE_ info, for debugging" ), -OPT_UINTEGER (0 ,"proc-map-timeout" , &trace.opts.proc_map_timeout, +OPT_UINTEGER (0 ,"proc-map-timeout" , &proc_map_timeout,"per thread proc mmap processing timeout in ms" ),OPT_CALLBACK ('G' ,"cgroup" , &trace,"name" ,"monitor event in cgroup name only" , trace__parse_cgroups),
tools/perf/perf.h +0 -1
@@ -82,7 +82,6 @@ struct record_opts {bool use_clockid;clockid_t clockid;u64 clockid_res_ns; -unsigned int proc_map_timeout;int nr_cblocks; };
tools/perf/tests/code-reading.c +1 -1
@@ -599,7 +599,7 @@ static int do_test_code_reading(bool try_kcore) } ret =perf_event__synthesize_thread_map (NULL , threads, - perf_event__process, machine, false,500 ); + perf_event__process, machine, false);if (ret <0 ) {pr_debug ("perf_event__synthesize_thread_map failed\n" ); goto out_err;
tools/perf/tests/dwarf-unwind.c +1 -1
@@ -34,7 +34,7 @@ static int init_live_machine(struct machine *machine)pid_t pid =getpid ();return perf_event__synthesize_mmap_events (NULL , &event, pid, pid, - mmap_handler, machine, true,500 ); + mmap_handler, machine, true); }/*
tools/perf/tests/mmap-thread-lookup.c +2 -2
@@ -132,7 +132,7 @@ static int synth_all(struct machine *machine) {return perf_event__synthesize_threads (NULL , perf_event__process, - machine,0 ,500 ,1 ); + machine,0 ,1 ); }static int synth_process (struct machine *machine)
@@ -144,7 +144,7 @@ static int synth_process(struct machine *machine) err =perf_event__synthesize_thread_map (NULL , map, perf_event__process, - machine,0 ,500 ); + machine,0 );thread_map__put (map);return err;
tools/perf/util/config.c +4 -0
@@ -14,6 +14,7 @@#include "util.h" #include "cache.h" #include <subcmd/exec-cmd.h> +#include "util/event.h" /* proc_map_timeout */ #include "util/hist.h" /* perf_hist_config */ #include "util/llvm-utils.h" /* perf_llvm_config */ #include "config.h"
@@ -419,6 +420,9 @@ static int perf_buildid_config(const char *var, const char *value)static int perf_default_core_config (const char *var__maybe_unused ,const char *value__maybe_unused ) { +if (!strcmp (var,"core.proc-map-timeout" )) + proc_map_timeout =strtoul (value,NULL ,10 ); +/* Add other config variables here. */ return 0 ; }
tools/perf/util/event.c +13 -19
@@ -25,6 +25,8 @@#include "asm/bug.h" #include "stat.h" +#define DEFAULT_PROC_MAP_PARSE_TIMEOUT 500 +static const char *perf_event__names[] = { [0 ] ="TOTAL" , [PERF_RECORD_MMAP ] ="MMAP" ,
@@ -72,6 +74,8 @@ static const char *perf_ns__names[] = { [CGROUP_NS_INDEX] = "cgroup", }; +unsigned int proc_map_timeout =DEFAULT_PROC_MAP_PARSE_TIMEOUT ; +const char *perf_event__name (unsigned int id) {if (id >=ARRAY_SIZE (perf_event__names))
@@ -323,8 +327,7 @@ int perf_event__synthesize_mmap_events(struct perf_tool *tool, pid_t pid, pid_t tgid, perf_event__handler_t process, struct machine *machine, - bool mmap_data, - unsigned int proc_map_timeout) + bool mmap_data) { char filename[PATH_MAX];FILE *fp;
@@ -521,8 +524,7 @@ static int __event__synthesize_thread(union perf_event *comm_event,perf_event__handler_t process, struct perf_tool *tool, struct machine *machine, - bool mmap_data, - unsigned int proc_map_timeout) + bool mmap_data) { char filename[PATH_MAX];DIR *tasks;
@@ -548,8 +550,7 @@ static int __event__synthesize_thread(union perf_event *comm_event,*/ if (pid == tgid &&perf_event__synthesize_mmap_events (tool, mmap_event, pid, tgid, - process, machine, mmap_data, - proc_map_timeout)) + process, machine, mmap_data))return -1 ;return 0 ;
@@ -598,7 +599,7 @@ static int __event__synthesize_thread(union perf_event *comm_event,if (_pid == pid) {/* process the parent's maps too */ rc =perf_event__synthesize_mmap_events (tool, mmap_event, pid, tgid, - process, machine, mmap_data, proc_map_timeout); + process, machine, mmap_data);if (rc)break ; }
@@ -612,8 +613,7 @@ int perf_event__synthesize_thread_map(struct perf_tool *tool,struct thread_map *threads, perf_event__handler_t process, struct machine *machine, - bool mmap_data, - unsigned int proc_map_timeout) + bool mmap_data) { union perf_event *comm_event, *mmap_event, *fork_event;union perf_event *namespaces_event;
@@ -643,7 +643,7 @@ int perf_event__synthesize_thread_map(struct perf_tool *tool, fork_event, namespaces_event, thread_map__pid(threads, thread), 0, process, tool, machine, - mmap_data, proc_map_timeout)) { + mmap_data)) { err =-1 ;break ; }
@@ -669,7 +669,7 @@ int perf_event__synthesize_thread_map(struct perf_tool *tool, fork_event, namespaces_event, comm_event->comm.pid, 0, process, tool, machine, - mmap_data, proc_map_timeout)) { + mmap_data)) { err =-1 ;break ; }
@@ -690,7 +690,6 @@ static int __perf_event__synthesize_threads(struct perf_tool *tool,perf_event__handler_t process, struct machine *machine, bool mmap_data, - unsigned int proc_map_timeout, struct dirent **dirent, int start, int num)
@@ -734,8 +733,7 @@ static int __perf_event__synthesize_threads(struct perf_tool *tool,*/ __event__synthesize_thread (comm_event, mmap_event, fork_event, namespaces_event, pid,1 , process, - tool, machine, mmap_data, - proc_map_timeout); + tool, machine, mmap_data); } err =0 ;
@@ -755,7 +753,6 @@ struct synthesize_threads_arg {perf_event__handler_t process;struct machine *machine;bool mmap_data; -unsigned int proc_map_timeout;struct dirent **dirent;int num;int start;
@@ -767,7 +764,7 @@ static void *synthesize_threads_worker(void *arg)__perf_event__synthesize_threads (args->tool, args->process, args->machine, args->mmap_data, - args->proc_map_timeout, args->dirent, + args->dirent, args->start, args->num);return NULL ; }
@@ -776,7 +773,6 @@ int perf_event__synthesize_threads(struct perf_tool *tool,perf_event__handler_t process, struct machine *machine, bool mmap_data, - unsigned int proc_map_timeout, unsigned int nr_threads_synthesize) { struct synthesize_threads_arg *args = NULL;
@@ -806,7 +802,6 @@ int perf_event__synthesize_threads(struct perf_tool *tool,if (thread_nr <=1 ) { err =__perf_event__synthesize_threads (tool, process, machine, mmap_data, - proc_map_timeout, dirent, base, n); goto free_dirent; }
@@ -828,7 +823,6 @@ int perf_event__synthesize_threads(struct perf_tool *tool, args[i].process = process; args[i].machine = machine; args[i].mmap_data = mmap_data; - args[i].proc_map_timeout = proc_map_timeout; args[i].dirent = dirent; }for (i =0 ; i < m; i++) {
tools/perf/util/event.h +3 -5
@@ -669,8 +669,7 @@ typedef int (*perf_event__handler_t)(struct perf_tool *tool,int perf_event__synthesize_thread_map (struct perf_tool *tool,struct thread_map *threads,perf_event__handler_t process, -struct machine *machine,bool mmap_data, -unsigned int proc_map_timeout); +struct machine *machine,bool mmap_data); int perf_event__synthesize_thread_map2(struct perf_tool *tool, struct thread_map *threads, perf_event__handler_t process,
@@ -682,7 +681,6 @@ int perf_event__synthesize_cpu_map(struct perf_tool *tool,int perf_event__synthesize_threads (struct perf_tool *tool,perf_event__handler_t process,struct machine *machine,bool mmap_data, -unsigned int proc_map_timeout,unsigned int nr_threads_synthesize); int perf_event__synthesize_kernel_mmap(struct perf_tool *tool, perf_event__handler_t process,
@@ -797,8 +795,7 @@ int perf_event__synthesize_mmap_events(struct perf_tool *tool, pid_t pid, pid_t tgid, perf_event__handler_t process, struct machine *machine, - bool mmap_data, - unsigned int proc_map_timeout); + bool mmap_data); int perf_event__synthesize_extra_kmaps(struct perf_tool *tool, perf_event__handler_t process,
@@ -829,5 +826,6 @@ int perf_event_paranoid(void);extern int sysctl_perf_event_max_stack;extern int sysctl_perf_event_max_contexts_per_stack; +extern unsigned int proc_map_timeout;#endif /* __PERF_RECORD_H */
tools/perf/util/machine.c +1 -3
@@ -2493,15 +2493,13 @@ int machines__for_each_thread(struct machines *machines,int __machine__synthesize_threads (struct machine *machine,struct perf_tool *tool,struct target *target,struct thread_map *threads,perf_event__handler_t process,bool data_mmap, -unsigned int proc_map_timeout,unsigned int nr_threads_synthesize) {if (target__has_task (target)) -return perf_event__synthesize_thread_map (tool, threads, process, machine, data_mmap, proc_map_timeout); +return perf_event__synthesize_thread_map (tool, threads, process, machine, data_mmap);else if (target__has_cpu (target))return perf_event__synthesize_threads (tool, process, machine, data_mmap, - proc_map_timeout, nr_threads_synthesize);/* command specified */ return 0 ;
tools/perf/util/machine.h +0 -3
@@ -250,17 +250,14 @@ int machines__for_each_thread(struct machines *machines,int __machine__synthesize_threads (struct machine *machine,struct perf_tool *tool,struct target *target,struct thread_map *threads,perf_event__handler_t process,bool data_mmap, -unsigned int proc_map_timeout,unsigned int nr_threads_synthesize);static inline int machine__synthesize_threads (struct machine *machine,struct target *target,struct thread_map *threads,bool data_mmap, -unsigned int proc_map_timeout,unsigned int nr_threads_synthesize) {return __machine__synthesize_threads (machine,NULL , target, threads, perf_event__process, data_mmap, - proc_map_timeout, nr_threads_synthesize); }
Signature · 1 line
2.19.2
Arnaldo Carvalho de Melo
maintainerPATCH 44/75 perf trace: We need to consider "nr" if "__syscall_nr" is not there
In reply to Arnaldo Carvalho de MeloFrom: Arnaldo Carvalho de Melo <[email protected]>
To cope with older kernels that don't have this patch backported:
026842d148b9 ("tracing/syscalls: Rename "/format" tracepoint field name "nr" to "__syscall_nr:")
This makes 'perf trace' work again in RHEL7 kernels.
--- tools/perf/builtin-trace.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
tools/perf/builtin-trace.c +2 -1
@@ -258,7 +258,8 @@ static int perf_evsel__init_syscall_tp(struct perf_evsel *evsel)struct syscall_tp *sc = evsel->priv =malloc (sizeof (struct syscall_tp ));if (evsel->priv !=NULL ) { -if (perf_evsel__init_tp_uint_field (evsel, &sc->id,"__syscall_nr" )) +if (perf_evsel__init_tp_uint_field (evsel, &sc->id,"__syscall_nr" ) && +perf_evsel__init_tp_uint_field (evsel, &sc->id,"nr" )) goto out_delete;return 0 ; }
Signature · 1 line
2.19.2
Arnaldo Carvalho de Melo
maintainerPATCH 45/75 perf tools: Support 'srccode' output
In reply to Arnaldo Carvalho de MeloFrom: Andi Kleen <[email protected]>
When looking at PT or brstackinsn traces with 'perf script' it can be very useful to see the source code. This adds a simple facility to print them with 'perf script', if the information is available through dwarf
% perf record ...
% perf script -F insn,ip,sym,srccode
...
4004c6 main
5 for (i = 0; i < 10000000; i++)
4004cd main
5 for (i = 0; i < 10000000; i++)
4004c6 main
5 for (i = 0; i < 10000000; i++)
4004cd main
5 for (i = 0; i < 10000000; i++)
4004cd main
5 for (i = 0; i < 10000000; i++)
4004cd main
5 for (i = 0; i < 10000000; i++)
4004cd main
5 for (i = 0; i < 10000000; i++)
4004cd main
5 for (i = 0; i < 10000000; i++)
4004b3 main6 v++;
% perf record -b ...
% perf script -F insn,ip,sym,srccode,brstackinsn
...
main+22:
0000000000400543 insn: e8 ca ff ff ff # PRED
|18 f1();
f1:
0000000000400512 insn: 55
|10 {
0000000000400513 insn: 48 89 e5
0000000000400516 insn: b8 00 00 00 00
|11 f2();
000000000040051b insn: e8 d6 ff ff ff # PRED
f2:
00000000004004f6 insn: 55
|5 {
00000000004004f7 insn: 48 89 e5
00000000004004fa insn: 8b 05 2c 0b 20 00
|6 c = a / b;
0000000000400500 insn: 8b 0d 2a 0b 20 00
0000000000400506 insn: 99
0000000000400507 insn: f7 f9
0000000000400509 insn: 89 05 29 0b 20 00
000000000040050f insn: 90
|7 }
0000000000400510 insn: 5d
0000000000400511 insn: c3 # PRED
f1+14:
0000000000400520 insn: b8 00 00 00 00
|12 f2();
0000000000400525 insn: e8 cc ff ff ff # PRED
f2:
00000000004004f6 insn: 55
|5 {
00000000004004f7 insn: 48 89 e5
00000000004004fa insn: 8b 05 2c 0b 20 00
|6 c = a / b;Not supported for callchains currently, would need some layout changes there.
Committer notes:
Fixed the build on Alpine Linux (3.4 .. 3.8) by addressing this warning:
In file included from util/srccode.c:19:0:
/usr/include/sys/fcntl.h:1:2: error: #warning redirecting incorrect #include <sys/fcntl.h> to <fcntl.h> [-Werror=cpp]
#warning redirecting incorrect #include <sys/fcntl.h> to <fcntl.h>
^~~~~~~
cc1: all warnings being treated as errors
--- tools/perf/Documentation/perf-script.txt | 2 +- tools/perf/builtin-script.c | 47 +++++- tools/perf/util/Build | 1 + tools/perf/util/evsel_fprintf.c | 1 + tools/perf/util/map.c | 49 ++++++ tools/perf/util/map.h | 16 ++ tools/perf/util/srccode.c | 186 +++++++++++++++++++++++ tools/perf/util/srccode.h | 7 + tools/perf/util/srcline.c | 28 ++++ tools/perf/util/srcline.h | 1 + tools/perf/util/thread.c | 2 + tools/perf/util/thread.h | 2 + 12 files changed, 339 insertions(+), 3 deletions(-) create mode 100644 tools/perf/util/srccode.c create mode 100644 tools/perf/util/srccode.h
tools/perf/Documentation/perf-script.txt +1 -1
@@ -117,7 +117,7 @@ OPTIONS Comma separated list of fields to print. Options are: comm, tid, pid, time, cpu, event, trace, ip, sym, dso, addr, symoff, srcline, period, iregs, uregs, brstack, brstacksym, flags, bpf-output, brstackinsn, - brstackoff, callindent, insn, insnlen, synth, phys_addr, metric, misc. + brstackoff, callindent, insn, insnlen, synth, phys_addr, metric, misc, srccode. Field list can be prepended with the type, trace, sw or hw, to indicate to which event type the field list applies. e.g., -F sw:comm,tid,time,ip,sym and -F trace:time,cpu,trace
tools/perf/builtin-script.c +45 -2
113 lines not on this page · raw message
tools/perf/util/Build +1 -0
@@ -77,6 +77,7 @@ libperf-y += stat-shadow.o libperf-y += stat-display.o libperf-y += record.o libperf-y += srcline.o +libperf-y += srccode.o libperf-y += data.o libperf-y += tsc.o libperf-y += cloexec.o
tools/perf/util/evsel_fprintf.c +1 -0
@@ -173,6 +173,7 @@ int sample__fprintf_callchain(struct perf_sample *sample, int left_alignment,if (!print_oneline) printed +=fprintf (fp,"\n" ); +/* Add srccode here too? */ if (symbol_conf.bt_stop_list && node->sym && strlist__has_entry(symbol_conf.bt_stop_list,
tools/perf/util/map.c +49 -0
61 lines not on this page · raw message
tools/perf/util/map.h +16 -0
@@ -174,6 +174,22 @@ char *map__srcline(struct map *map, u64 addr, struct symbol *sym);int map__fprintf_srcline (struct map *map,u64 addr,const char *prefix,FILE *fp); +struct srccode_state { +char *srcfile; +unsigned line; +}; + +static inline void srccode_state_init (struct srccode_state *state) +{ + state->srcfile =NULL ; + state->line =0 ; +} + +void srccode_state_free (struct srccode_state *state); + +int map__fprintf_srccode (struct map *map,u64 addr, +FILE *fp,struct srccode_state *state); +int map__load (struct map *map);struct symbol *map__find_symbol (struct map *map,u64 addr);struct symbol *map__find_symbol_by_name (struct map *map,const char *name);
tools/perf/util/srccode.c new file +186 -0
186 lines not on this page · raw message
tools/perf/util/srccode.h new file +7 -0
@@ -0,0 +1,7 @@ +#ifndef SRCCODE_H +#define SRCCODE_H 1 + +/* Result is not 0 terminated */ +char *find_sourceline (char *fn,unsigned line,int *lenp); + +#endif
tools/perf/util/srcline.c +28 -0
@@ -548,6 +548,34 @@ char *__get_srcline(struct dso *dso, u64 addr, struct symbol *sym,return srcline; } +/* Returns filename and fills in line number in line */ +char *get_srcline_split (struct dso *dso,u64 addr,unsigned *line) +{ +char *file =NULL ; +const char *dso_name; + +if (!dso->has_srcline) + goto out; + + dso_name =dso__name (dso); +if (dso_name ==NULL ) + goto out; + +if (!addr2line (dso_name, addr, &file, line, dso, true,NULL ,NULL )) + goto out; + + dso->a2l_fails =0 ; +return file; + +out: +if (dso->a2l_fails && ++dso->a2l_fails >A2L_FAIL_LIMIT ) { + dso->has_srcline =0 ; +dso__free_a2l (dso); + } + +return NULL ; +} +void free_srcline (char *srcline) {if (srcline &&strcmp (srcline,SRCLINE_UNKNOWN ) !=0 )
tools/perf/util/srcline.h +1 -0
@@ -16,6 +16,7 @@ char *__get_srcline(struct dso *dso, u64 addr, struct symbol *sym, bool show_sym, bool show_addr, bool unwind_inlines, u64 ip);void free_srcline (char *srcline); +char *get_srcline_split (struct dso *dso,u64 addr,unsigned *line);/* insert the srcline into the DSO, which will take ownership */ void srcline__tree_insert (struct rb_root *tree,u64 addr,char *srcline);
tools/perf/util/thread.c +2 -0
@@ -64,6 +64,7 @@ struct thread *thread__new(pid_t pid, pid_t tid)RB_CLEAR_NODE (&thread->rb_node);/* Thread holds first ref to nsdata. */ thread->nsinfo =nsinfo__new (pid); +srccode_state_init (&thread->srccode_state); }return thread;
@@ -103,6 +104,7 @@ void thread__delete(struct thread *thread)unwind__finish_access (thread);nsinfo__zput (thread->nsinfo); +srccode_state_free (&thread->srccode_state);exit_rwsem (&thread->namespaces_lock);exit_rwsem (&thread->comm_lock);
tools/perf/util/thread.h +2 -0
@@ -8,6 +8,7 @@#include <unistd.h> #include <sys/types.h> #include "symbol.h" +#include "map.h" #include <strlist.h> #include <intlist.h> #include "rwsem.h"
@@ -38,6 +39,7 @@ struct thread {void *priv;struct thread_stack *ts;struct nsinfo *nsinfo; +struct srccode_state srccode_state;#ifdef HAVE_LIBUNWIND_SUPPORT void *addr_space;struct unwind_libunwind_ops *unwind_libunwind_ops;
Signature · 1 line
2.19.2
Arnaldo Carvalho de Melo
maintainerPATCH 46/75 perf ordered_events: Rework show_progress for __ordered_events__flush
In reply to Arnaldo Carvalho de MeloFrom: Jiri Olsa <[email protected]>
Decide to use the progress bar one level higher, we will need this in following patch.
--- tools/perf/util/ordered-events.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-)
tools/perf/util/ordered-events.c +5 -3
@@ -219,13 +219,13 @@ int ordered_events__queue(struct ordered_events *oe, union perf_event *event,return 0 ; } -static int __ordered_events__flush (struct ordered_events *oe) +static int __ordered_events__flush (struct ordered_events *oe, +bool show_progress) {struct list_head *head = &oe->events;struct ordered_event *tmp, *iter;u64 limit = oe->next_flush;u64 last_ts = oe->last ? oe->last->timestamp :0ULL ; -bool show_progress = limit ==ULLONG_MAX ;struct ui_progress prog;int ret;
@@ -272,6 +272,7 @@ int ordered_events__flush(struct ordered_events *oe, enum oe_flush how) "HALF ", };int err; +bool show_progress = false;if (oe->nr_events ==0 )return 0 ;
@@ -279,6 +280,7 @@ int ordered_events__flush(struct ordered_events *oe, enum oe_flush how)switch (how) {case OE_FLUSH__FINAL : oe->next_flush =ULLONG_MAX ; + show_progress = true;break ;case OE_FLUSH__HALF :
@@ -308,7 +310,7 @@ int ordered_events__flush(struct ordered_events *oe, enum oe_flush how) str[how], oe->nr_events);pr_oe_time (oe->max_timestamp,"max_timestamp\n" ); - err =__ordered_events__flush (oe); + err =__ordered_events__flush (oe, show_progress);if (!err) {if (how ==OE_FLUSH__ROUND )
Signature · 1 line
2.19.2
Arnaldo Carvalho de Melo
maintainerPATCH 47/75 perf ordered_events: Add private data member
In reply to Arnaldo Carvalho de MeloFrom: Jiri Olsa <[email protected]>
We will need it in following patch, where we can't use the container_of() trick to get the higher level object.
--- tools/perf/util/ordered-events.c | 6 ++++-- tools/perf/util/ordered-events.h | 4 +++- tools/perf/util/session.c | 3 ++- 3 files changed, 9 insertions(+), 4 deletions(-)
tools/perf/util/ordered-events.c +4 -2
@@ -326,7 +326,8 @@ int ordered_events__flush(struct ordered_events *oe, enum oe_flush how)return err; } -void ordered_events__init (struct ordered_events *oe,ordered_events__deliver_t deliver) +void ordered_events__init (struct ordered_events *oe,ordered_events__deliver_t deliver, +void *data) {INIT_LIST_HEAD (&oe->events);INIT_LIST_HEAD (&oe->cache);
@@ -334,6 +335,7 @@ void ordered_events__init(struct ordered_events *oe, ordered_events__deliver_t d oe->max_alloc_size = (u64) -1 ; oe->cur_alloc_size =0 ; oe->deliver = deliver; + oe->data = data; } static void
@@ -377,5 +379,5 @@ void ordered_events__reinit(struct ordered_events *oe)ordered_events__free (oe);memset (oe,'\0' ,sizeof (*oe)); -ordered_events__init (oe, old_deliver); +ordered_events__init (oe, old_deliver, oe->data); }
tools/perf/util/ordered-events.h +3 -1
@@ -47,13 +47,15 @@ struct ordered_events {enum oe_flush last_flush_type;u32 nr_unordered_events;bool copy_on_queue; +void *data; };int ordered_events__queue (struct ordered_events *oe,union perf_event *event,u64 timestamp,u64 file_offset);void ordered_events__delete (struct ordered_events *oe,struct ordered_event *event);int ordered_events__flush (struct ordered_events *oe,enum oe_flush how); -void ordered_events__init (struct ordered_events *oe,ordered_events__deliver_t deliver); +void ordered_events__init (struct ordered_events *oe,ordered_events__deliver_t deliver, +void *data);void ordered_events__free (struct ordered_events *oe);void ordered_events__reinit (struct ordered_events *oe);
tools/perf/util/session.c +2 -1
@@ -126,7 +126,8 @@ struct perf_session *perf_session__new(struct perf_data *data, session->tool = tool;INIT_LIST_HEAD (&session->auxtrace_index);machines__init (&session->machines); -ordered_events__init (&session->ordered_events, ordered_events__deliver_event); +ordered_events__init (&session->ordered_events, + ordered_events__deliver_event,NULL );if (data) {if (perf_data__open (data))
Signature · 1 line
2.19.2
Arnaldo Carvalho de Melo
maintainerPATCH 48/75 perf top: Save and display the lost count stats
In reply to Arnaldo Carvalho de MeloFrom: Jiri Olsa <[email protected]>
Add a 'lost count' to 'perf top' headers:
# perf top --stdio PerfTop: 3850 irqs/sec kernel:49.0% exact: 100.0% lost: 0/0 [4000Hz cycles:ppp], (all, 8 CPUs)
# perf top Samples: 0 of event 'cycles:ppp', 4000 Hz, Event count (approx.): 0 lost: 0/0
The format is: <current period lost>/<total lost>
--- tools/perf/builtin-top.c | 27 +++++++++++++++++++++++++++ tools/perf/ui/browsers/hists.c | 4 ++++ tools/perf/util/top.c | 6 +++--- tools/perf/util/top.h | 2 +- 4 files changed, 35 insertions(+), 4 deletions(-)
tools/perf/builtin-top.c +27 -0
@@ -800,6 +800,29 @@ static void perf_event__process_sample(struct perf_tool *tool,addr_location__put (&al); } +static void +perf_top__process_lost (struct perf_top *top,union perf_event *event, +struct perf_evsel *evsel) +{ +struct hists *hists =evsel__hists (evsel); + + top->lost += event->lost.lost; + top->lost_total += event->lost.lost; + hists->stats.total_lost += event->lost.lost; +} + +static void +perf_top__process_lost_samples (struct perf_top *top, +union perf_event *event, +struct perf_evsel *evsel) +{ +struct hists *hists =evsel__hists (evsel); + + top->lost += event->lost_samples.lost; + top->lost_total += event->lost_samples.lost; + hists->stats.total_lost_samples += event->lost_samples.lost; +} +static void perf_top__mmap_read_idx (struct perf_top *top,int idx) {struct record_opts *opts = &top->record_opts;
@@ -865,6 +888,10 @@ static void perf_top__mmap_read_idx(struct perf_top *top, int idx)if (event->header.type ==PERF_RECORD_SAMPLE ) {perf_event__process_sample (&top->tool, event, evsel, &sample, machine); + }else if (event->header.type ==PERF_RECORD_LOST ) { +perf_top__process_lost (top, event, evsel); + }else if (event->header.type ==PERF_RECORD_LOST_SAMPLES ) { +perf_top__process_lost_samples (top, event, evsel); }else if (event->header.type <PERF_RECORD_MAX ) {hists__inc_nr_events (evsel__hists (evsel), event->header.type);machine__process_event (machine, event, &sample);
tools/perf/ui/browsers/hists.c +4 -0
@@ -2219,6 +2219,10 @@ static int hists_browser__scnprintf_title(struct hist_browser *browser, char *bfif (!is_report_browser (hbt)) {struct perf_top *top = hbt->arg; + printed +=scnprintf (bf + printed, size - printed, +" lost: %" PRIu64"/%" PRIu64, + top->lost, top->lost_total); +if (top->zero) printed +=scnprintf (bf + printed, size - printed," [z]" ); }
tools/perf/util/top.c +3 -3
@@ -46,8 +46,8 @@ size_t perf_top__header_snprintf(struct perf_top *top, char *bf, size_t size) samples_per_sec; ret =SNPRINTF (bf, size," PerfTop:%8.0f irqs/sec kernel:%4.1f%%" -" exact: %4.1f%% [" , samples_per_sec, - ksamples_percent, esamples_percent); +" exact: %4.1f%% lost: %" PRIu64"/%" PRIu64" [" , samples_per_sec, + ksamples_percent, esamples_percent, top->lost, top->lost_total); }else {float us_samples_per_sec = top->us_samples / top->delay_secs;float guest_kernel_samples_per_sec = top->guest_kernel_samples / top->delay_secs;
@@ -113,5 +113,5 @@ void perf_top__reset_sample_counters(struct perf_top *top) { top->samples = top->us_samples = top->kernel_samples = top->exact_samples = top->guest_kernel_samples = - top->guest_us_samples =0 ; + top->guest_us_samples = top->lost =0 ; }
tools/perf/util/top.h +1 -1
@@ -22,7 +22,7 @@ struct perf_top {* Symbols will be added here in perf_event__process_sample and will * get out after decayed. */ -u64 samples; +u64 samples, lost, lost_total;u64 kernel_samples, us_samples;u64 exact_samples;u64 guest_us_samples, guest_kernel_samples;
Signature · 1 line
2.19.2
Arnaldo Carvalho de Melo
maintainerPATCH 49/75 perf top: Move lost events warning to helpline
In reply to Arnaldo Carvalho de MeloFrom: Jiri Olsa <[email protected]>
We can't display the UI box saying that we are slow in the reader thread. That will make 'perf top' even slower and the user even more angry ;-)
Move the UI box message from the reader thread to the UI thread and change it to a helpline, so there's no need to 'press any key'.
--- tools/perf/builtin-top.c | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-)
tools/perf/builtin-top.c +5 -11
@@ -553,8 +553,6 @@ static void perf_top__sort_new_samples(void *arg)struct perf_evsel *evsel = t->sym_evsel;struct hists *hists; -perf_top__reset_sample_counters (t); -if (t->evlist->selected !=NULL ) t->sym_evsel = t->evlist->selected;
@@ -571,6 +569,11 @@ static void perf_top__sort_new_samples(void *arg)hists__collapse_resort (hists,NULL );perf_evsel__output_resort (evsel,NULL ); + +if (t->lost) +pr_warning ("Too slow to read ring buffer (change period (-c/-F) or limit CPUs (-C)\n" ); + +perf_top__reset_sample_counters (t); }static void *display_thread_tui (void *arg)
@@ -908,10 +911,8 @@ static void perf_top__mmap_read(struct perf_top *top) {bool overwrite = top->record_opts.overwrite;struct perf_evlist *evlist = top->evlist; -unsigned long long start, end;int i; - start =rdclock ();if (overwrite)perf_evlist__toggle_bkw_mmap (evlist,BKW_MMAP_DATA_PENDING );
@@ -922,13 +923,6 @@ static void perf_top__mmap_read(struct perf_top *top)perf_evlist__toggle_bkw_mmap (evlist,BKW_MMAP_EMPTY );perf_evlist__toggle_bkw_mmap (evlist,BKW_MMAP_RUNNING ); } - end =rdclock (); - -if ((end - start) > (unsigned long long )top->delay_secs *NSEC_PER_SEC ) -ui__warning ("Too slow to read ring buffer.\n" -"Please try increasing the period (-c) or\n" -"decreasing the freq (-F) or\n" -"limiting the number of CPUs (-C)\n" ); }/*
Signature · 1 line
2.19.2
Arnaldo Carvalho de Melo
maintainerPATCH 50/75 perf top: Add processing thread
In reply to Arnaldo Carvalho de MeloFrom: Jiri Olsa <[email protected]>
Add a new thread that takes care of the hist creating to alleviate the main reader thread so it can keep perf mmaps served in time so that we reduce the possibility of losing events.
The 'perf top' command now spawns 2 extra threads, the data processing is the following:
1) The main thread reads the data from mmaps and queues them to
ordered events object;
2) The processing threads takes the data from the ordered events
object and create initial histogram;
3) The GUI thread periodically sorts the initial histogram and presents it.
Passing the data between threads 1 and 2 is done by having 2 ordered events queues. One is always being stored by thread 1 while the other is flushed out in thread 2.
Passing the data between threads 2 and 3 stays the same as was initially for threads 1 and 3.
--- tools/perf/builtin-top.c | 202 +++++++++++++++++++++---------- tools/perf/util/ordered-events.c | 4 +- tools/perf/util/ordered-events.h | 1 + tools/perf/util/top.h | 6 + 4 files changed, 151 insertions(+), 62 deletions(-)
tools/perf/builtin-top.c +141 -61
@@ -46,6 +46,7 @@#include "arch/common.h" #include "util/debug.h" +#include "util/ordered-events.h" #include <assert.h> #include <elf.h>
@@ -830,78 +831,28 @@ static void perf_top__mmap_read_idx(struct perf_top *top, int idx) {struct record_opts *opts = &top->record_opts;struct perf_evlist *evlist = top->evlist; -struct perf_sample sample; -struct perf_evsel *evsel;struct perf_mmap *md; -struct perf_session *session = top->session;union perf_event *event; -struct machine *machine; -int ret; md = opts->overwrite ? &evlist->overwrite_mmap[idx] : &evlist->mmap[idx];if (perf_mmap__read_init (md) <0 )return ;while ((event =perf_mmap__read_event (md)) !=NULL ) { - ret =perf_evlist__parse_sample (evlist, event, &sample); -if (ret) { -pr_err ("Can't parse sample, err = %d\n" , ret); - goto next_event; - } - - evsel =perf_evlist__id2evsel (session->evlist, sample.id); -assert (evsel !=NULL ); +u64 timestamp =-1ULL ; +int ret; -if (event->header.type ==PERF_RECORD_SAMPLE ) - ++top->samples; - -switch (sample.cpumode) { -case PERF_RECORD_MISC_USER : - ++top->us_samples; -if (top->hide_user_symbols) - goto next_event; - machine = &session->machines.host; -break ; -case PERF_RECORD_MISC_KERNEL : - ++top->kernel_samples; -if (top->hide_kernel_symbols) - goto next_event; - machine = &session->machines.host; + ret =perf_evlist__parse_sample_timestamp (evlist, event, ×tamp); +if (ret && ret !=-1 )break ; -case PERF_RECORD_MISC_GUEST_KERNEL : - ++top->guest_kernel_samples; - machine =perf_session__find_machine (session, - sample.pid); -break ; -case PERF_RECORD_MISC_GUEST_USER : - ++top->guest_us_samples; -/* -* TODO: we don't process guest user from host side -* except simple counting. -*/ - goto next_event; -default : -if (event->header.type ==PERF_RECORD_SAMPLE ) - goto next_event; - machine = &session->machines.host; -break ; - } +pthread_mutex_lock (&top->qe.lock); + ret =ordered_events__queue (top->qe.in, event, timestamp,0 ); +pthread_mutex_unlock (&top->qe.lock); -if (event->header.type ==PERF_RECORD_SAMPLE ) { -perf_event__process_sample (&top->tool, event, evsel, - &sample, machine); - }else if (event->header.type ==PERF_RECORD_LOST ) { -perf_top__process_lost (top, event, evsel); - }else if (event->header.type ==PERF_RECORD_LOST_SAMPLES ) { -perf_top__process_lost_samples (top, event, evsel); - }else if (event->header.type <PERF_RECORD_MAX ) { -hists__inc_nr_events (evsel__hists (evsel), event->header.type); -machine__process_event (machine, event, &sample); - }else - ++session->evlist->stats.nr_unknown_events; -next_event:perf_mmap__consume (md); +if (ret) +break ; }perf_mmap__read_done (md);
@@ -1084,6 +1035,125 @@ static int callchain_param__setup_sample_type(struct callchain_param *callchain)return 0 ; } +static struct ordered_events *rotate_queues (struct perf_top *top) +{ +struct ordered_events *in = top->qe.in; + +if (top->qe.in == &top->qe.data[1 ]) + top->qe.in = &top->qe.data[0 ]; +else + top->qe.in = &top->qe.data[1 ]; + +return in; +} + +static void *process_thread (void *arg) +{ +struct perf_top *top = arg; + +while (!done) { +struct ordered_events *out, *in = top->qe.in; + +if (!in->nr_events) { +usleep (100 ); +continue ; + } + +pthread_mutex_lock (&top->qe.lock); + out =rotate_queues (top); +pthread_mutex_unlock (&top->qe.lock); + +if (ordered_events__flush (out,OE_FLUSH__TOP )) +pr_err ("failed to process events\n" ); + } + +return NULL ; +} + +static int deliver_event (struct ordered_events *qe, +struct ordered_event *qevent) +{ +struct perf_top *top = qe->data; +struct perf_evlist *evlist = top->evlist; +struct perf_session *session = top->session; +union perf_event *event = qevent->event; +struct perf_sample sample; +struct perf_evsel *evsel; +struct machine *machine; +int ret =-1 ; + + ret =perf_evlist__parse_sample (evlist, event, &sample); +if (ret) { +pr_err ("Can't parse sample, err = %d\n" , ret); + goto next_event; + } + + evsel =perf_evlist__id2evsel (session->evlist, sample.id); +assert (evsel !=NULL ); + +if (event->header.type ==PERF_RECORD_SAMPLE ) + ++top->samples; + +switch (sample.cpumode) { +case PERF_RECORD_MISC_USER : + ++top->us_samples; +if (top->hide_user_symbols) + goto next_event; + machine = &session->machines.host; +break ; +case PERF_RECORD_MISC_KERNEL : + ++top->kernel_samples; +if (top->hide_kernel_symbols) + goto next_event; + machine = &session->machines.host; +break ; +case PERF_RECORD_MISC_GUEST_KERNEL : + ++top->guest_kernel_samples; + machine =perf_session__find_machine (session, + sample.pid); +break ; +case PERF_RECORD_MISC_GUEST_USER : + ++top->guest_us_samples; +/* +* TODO: we don't process guest user from host side +* except simple counting. +*/ + goto next_event; +default : +if (event->header.type ==PERF_RECORD_SAMPLE ) + goto next_event; + machine = &session->machines.host; +break ; + } + +if (event->header.type ==PERF_RECORD_SAMPLE ) { +perf_event__process_sample (&top->tool, event, evsel, + &sample, machine); + }else if (event->header.type ==PERF_RECORD_LOST ) { +perf_top__process_lost (top, event, evsel); + }else if (event->header.type ==PERF_RECORD_LOST_SAMPLES ) { +perf_top__process_lost_samples (top, event, evsel); + }else if (event->header.type <PERF_RECORD_MAX ) { +hists__inc_nr_events (evsel__hists (evsel), event->header.type); +machine__process_event (machine, event, &sample); + }else + ++session->evlist->stats.nr_unknown_events; + + ret =0 ; +next_event: +return ret; +} + +static void init_process_thread (struct perf_top *top) +{ +ordered_events__init (&top->qe.data[0 ], deliver_event, top); +ordered_events__init (&top->qe.data[1 ], deliver_event, top); +ordered_events__set_copy_on_queue (&top->qe.data[0 ], true); +ordered_events__set_copy_on_queue (&top->qe.data[1 ], true); + top->qe.in = &top->qe.data[0 ]; +pthread_mutex_init (&top->qe.lock,NULL ); +} +static int __cmd_top (struct perf_top *top) {char msg[512 ];
@@ -1091,7 +1161,7 @@ static int __cmd_top(struct perf_top *top)struct perf_evsel_config_term *err_term;struct perf_evlist *evlist = top->evlist;struct record_opts *opts = &top->record_opts; -pthread_t thread; +pthread_t thread, thread_process;int ret; top->session =perf_session__new (NULL , false,NULL );
@@ -1115,6 +1185,8 @@ static int __cmd_top(struct perf_top *top)if (top->nr_threads_synthesize >1 )perf_set_multithreaded (); +init_process_thread (top); +machine__synthesize_threads (&top->session->machines.host, &opts->target, top->evlist->threads, false, top->nr_threads_synthesize);
@@ -1155,10 +1227,15 @@ static int __cmd_top(struct perf_top *top)perf_evlist__enable (top->evlist); ret =-1 ; +if (pthread_create (&thread_process,NULL , process_thread, top)) { +ui__error ("Could not create process thread.\n" ); + goto out_delete; + } +if (pthread_create (&thread,NULL , (use_browser >0 ? display_thread_tui : display_thread), top)) {ui__error ("Could not create display thread.\n" ); - goto out_delete; + goto out_join_thread; }if (top->realtime_prio) {
@@ -1193,6 +1270,8 @@ static int __cmd_top(struct perf_top *top) ret =0 ; out_join:pthread_join (thread,NULL ); +out_join_thread: +pthread_join (thread_process,NULL ); out_delete:perf_session__delete (top->session); top->session =NULL ;
@@ -1284,6 +1363,7 @@ int cmd_top(int argc, const char **argv)* stays in overwrite mode. -acme * */ .overwrite = 0, + .sample_time = true, }, .max_stack = sysctl__max_stack(), .annotation_opts = annotation__default_options,
tools/perf/util/ordered-events.c +3 -1
@@ -279,8 +279,10 @@ int ordered_events__flush(struct ordered_events *oe, enum oe_flush how)switch (how) {case OE_FLUSH__FINAL : - oe->next_flush =ULLONG_MAX ; show_progress = true; + __fallthrough; +case OE_FLUSH__TOP : + oe->next_flush =ULLONG_MAX ;break ;case OE_FLUSH__HALF :
tools/perf/util/ordered-events.h +1 -0
@@ -18,6 +18,7 @@ enum oe_flush {OE_FLUSH__FINAL ,OE_FLUSH__ROUND ,OE_FLUSH__HALF , + OE_FLUSH__TOP, };struct ordered_events ;
tools/perf/util/top.h +6 -0
@@ -40,6 +40,12 @@ struct perf_top {const char *sym_filter;float min_percent;unsigned int nr_threads_synthesize; + +struct { +struct ordered_events *in; +struct ordered_events data[2 ]; +pthread_mutex_t lock; + } qe; };#define CONSOLE_CLEAR "[H[2J"
Signature · 1 line
2.19.2
Arnaldo Carvalho de Melo
maintainerPATCH 51/75 perf top: Use cond variable instead of a lock
In reply to Arnaldo Carvalho de MeloFrom: Jiri Olsa <[email protected]>
Use conditional variable logic to synchronize between the reading and processing threads. Currently it's done by having mutex around rotation code.
Using a POSIX cond variable to sync both threads after queues rotation:
Process thread:
- Detects data
- Switches queues
- Sets rotate variable
- Waits in pthread_cond_wait()
Read thread:
- Detects rotate is set
- Kicks the process thread with a pthread_cond_signal()
After this rotation is safely completed and both threads can continue with the new queue.
--- tools/perf/builtin-top.c | 24 +++++++++++++++++------- tools/perf/util/top.h | 4 +++- 2 files changed, 20 insertions(+), 8 deletions(-)
tools/perf/builtin-top.c +17 -7
@@ -846,13 +846,18 @@ static void perf_top__mmap_read_idx(struct perf_top *top, int idx)if (ret && ret !=-1 )break ; -pthread_mutex_lock (&top->qe.lock); ret =ordered_events__queue (top->qe.in, event, timestamp,0 ); -pthread_mutex_unlock (&top->qe.lock); - -perf_mmap__consume (md);if (ret)break ; + +perf_mmap__consume (md); + +if (top->qe.rotate) { +pthread_mutex_lock (&top->qe.mutex); + top->qe.rotate = false; +pthread_cond_signal (&top->qe.cond); +pthread_mutex_unlock (&top->qe.mutex); + } }perf_mmap__read_done (md);
@@ -1059,9 +1064,12 @@ static void *process_thread(void *arg)continue ; } -pthread_mutex_lock (&top->qe.lock); out =rotate_queues (top); -pthread_mutex_unlock (&top->qe.lock); + +pthread_mutex_lock (&top->qe.mutex); + top->qe.rotate = true; +pthread_cond_wait (&top->qe.cond, &top->qe.mutex); +pthread_mutex_unlock (&top->qe.mutex);if (ordered_events__flush (out,OE_FLUSH__TOP ))pr_err ("failed to process events\n" );
@@ -1151,7 +1159,8 @@ static void init_process_thread(struct perf_top *top)ordered_events__set_copy_on_queue (&top->qe.data[0 ], true);ordered_events__set_copy_on_queue (&top->qe.data[1 ], true); top->qe.in = &top->qe.data[0 ]; -pthread_mutex_init (&top->qe.lock,NULL ); +pthread_mutex_init (&top->qe.mutex,NULL ); +pthread_cond_init (&top->qe.cond,NULL ); }static int __cmd_top (struct perf_top *top)
@@ -1271,6 +1280,7 @@ static int __cmd_top(struct perf_top *top) out_join:pthread_join (thread,NULL ); out_join_thread: +pthread_cond_signal (&top->qe.cond);pthread_join (thread_process,NULL ); out_delete:perf_session__delete (top->session);
tools/perf/util/top.h +3 -1
@@ -44,7 +44,9 @@ struct perf_top {struct {struct ordered_events *in;struct ordered_events data[2 ]; -pthread_mutex_t lock; +bool rotate; +pthread_mutex_t mutex; +pthread_cond_t cond; } qe; };
Signature · 1 line
2.19.2
Arnaldo Carvalho de Melo
maintainerPATCH 52/75 perf top: Set the 'session_done' volatile variable when exiting
In reply to Arnaldo Carvalho de MeloFrom: Jiri Olsa <[email protected]>
So we can get out of hist processing ASAP on user request.
--- tools/perf/builtin-top.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-)
tools/perf/builtin-top.c +9 -3
@@ -577,6 +577,12 @@ static void perf_top__sort_new_samples(void *arg)perf_top__reset_sample_counters (t); } +static void stop_top (void ) +{ + session_done =1 ; + done =1 ; +} +static void *display_thread_tui (void *arg) {struct perf_evsel *pos;
@@ -613,13 +619,13 @@ static void *display_thread_tui(void *arg) !top->record_opts.overwrite, &top->annotation_opts); - done =1 ; +stop_top ();return NULL ; }static void display_sig (int sig__maybe_unused ) { - done =1 ; +stop_top (); }static void display_setup_sig (void )
@@ -672,7 +678,7 @@ static void *display_thread(void *arg)if (perf_top__handle_keypress (top, c)) goto repeat; - done =1 ; +stop_top (); } }
Signature · 1 line
2.19.2
Arnaldo Carvalho de Melo
maintainerPATCH 53/75 perf top: Drop samples which are behind the refresh rate
In reply to Arnaldo Carvalho de MeloFrom: Jiri Olsa <[email protected]>
Drop samples from processing thread if they get behind the latest event read from the kernel maps. If it gets behind more than the refresh rate (-d option), drop the sample.
--- tools/perf/builtin-top.c | 25 ++++++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-)
tools/perf/builtin-top.c +22 -3
@@ -833,6 +833,8 @@ perf_top__process_lost_samples(struct perf_top *top, hists->stats.total_lost_samples += event->lost_samples.lost; } +static u64 last_timestamp; +static void perf_top__mmap_read_idx (struct perf_top *top,int idx) {struct record_opts *opts = &top->record_opts;
@@ -845,14 +847,13 @@ static void perf_top__mmap_read_idx(struct perf_top *top, int idx)return ;while ((event =perf_mmap__read_event (md)) !=NULL ) { -u64 timestamp =-1ULL ;int ret; - ret =perf_evlist__parse_sample_timestamp (evlist, event, ×tamp); + ret =perf_evlist__parse_sample_timestamp (evlist, event, &last_timestamp);if (ret && ret !=-1 )break ; - ret =ordered_events__queue (top->qe.in, event, timestamp,0 ); + ret =ordered_events__queue (top->qe.in, event, last_timestamp,0 );if (ret)break ;
@@ -1084,6 +1085,21 @@ static void *process_thread(void *arg)return NULL ; } +/* +* Allow only 'top->delay_secs' seconds behind samples. +*/ +static int should_drop (struct ordered_event *qevent,struct perf_top *top) +{ +union perf_event *event = qevent->event; +u64 delay_timestamp; + +if (event->header.type !=PERF_RECORD_SAMPLE ) +return false; + + delay_timestamp = qevent->timestamp + top->delay_secs *NSEC_PER_SEC ; +return delay_timestamp < last_timestamp; +} +static int deliver_event (struct ordered_events *qe,struct ordered_event *qevent) {
@@ -1096,6 +1112,9 @@ static int deliver_event(struct ordered_events *qe,struct machine *machine;int ret =-1 ; +if (should_drop (qevent, top)) +return 0 ; + ret =perf_evlist__parse_sample (evlist, event, &sample);if (ret) {pr_err ("Can't parse sample, err = %d\n" , ret);
Signature · 1 line
2.19.2
Arnaldo Carvalho de Melo
maintainerPATCH 54/75 perf top: Save and display the drop count stats
In reply to Arnaldo Carvalho de MeloFrom: Jiri Olsa <[email protected]>
Add drop count to 'perf top' headers:
# perf top --stdio PerfTop: 3549 irqs/sec kernel:51.8% exact: 100.0% lost: 0/0 drop: 0/0 [4000Hz cycles:ppp], (all, 8 CPUs)
# perf top Samples: 0 of event 'cycles:ppp', 4000 Hz, Event count (approx.): 0 lost: 0/0 drop: 0/0
The format is: <current period drop>/<total drop>
--- tools/perf/builtin-top.c | 5 ++++- tools/perf/ui/browsers/hists.c | 4 ++++ tools/perf/util/top.c | 7 ++++--- tools/perf/util/top.h | 2 +- 4 files changed, 13 insertions(+), 5 deletions(-)
tools/perf/builtin-top.c +4 -1
@@ -1112,8 +1112,11 @@ static int deliver_event(struct ordered_events *qe,struct machine *machine;int ret =-1 ; -if (should_drop (qevent, top)) +if (should_drop (qevent, top)) { + top->drop++; + top->drop_total++;return 0 ; + } ret =perf_evlist__parse_sample (evlist, event, &sample);if (ret) {
tools/perf/ui/browsers/hists.c +4 -0
@@ -2223,6 +2223,10 @@ static int hists_browser__scnprintf_title(struct hist_browser *browser, char *bf" lost: %" PRIu64"/%" PRIu64, top->lost, top->lost_total); + printed +=scnprintf (bf + printed, size - printed, +" drop: %" PRIu64"/%" PRIu64, + top->drop, top->drop_total); +if (top->zero) printed +=scnprintf (bf + printed, size - printed," [z]" ); }
tools/perf/util/top.c +4 -3
@@ -46,8 +46,9 @@ size_t perf_top__header_snprintf(struct perf_top *top, char *bf, size_t size) samples_per_sec; ret =SNPRINTF (bf, size," PerfTop:%8.0f irqs/sec kernel:%4.1f%%" -" exact: %4.1f%% lost: %" PRIu64"/%" PRIu64" [" , samples_per_sec, - ksamples_percent, esamples_percent, top->lost, top->lost_total); +" exact: %4.1f%% lost: %" PRIu64"/%" PRIu64" drop: %" PRIu64"/%" PRIu64" [" , + samples_per_sec, ksamples_percent, esamples_percent, + top->lost, top->lost_total, top->drop, top->drop_total); }else {float us_samples_per_sec = top->us_samples / top->delay_secs;float guest_kernel_samples_per_sec = top->guest_kernel_samples / top->delay_secs;
@@ -113,5 +114,5 @@ void perf_top__reset_sample_counters(struct perf_top *top) { top->samples = top->us_samples = top->kernel_samples = top->exact_samples = top->guest_kernel_samples = - top->guest_us_samples = top->lost =0 ; + top->guest_us_samples = top->lost = top->drop =0 ; }
tools/perf/util/top.h +1 -1
@@ -22,7 +22,7 @@ struct perf_top {* Symbols will be added here in perf_event__process_sample and will * get out after decayed. */ -u64 samples, lost, lost_total; +u64 samples, lost, lost_total, drop, drop_total;u64 kernel_samples, us_samples;u64 exact_samples;u64 guest_us_samples, guest_kernel_samples;
Signature · 1 line
2.19.2
Arnaldo Carvalho de Melo
maintainerPATCH 55/75 perf top: Display slow reader warning when droping samples
In reply to Arnaldo Carvalho de MeloFrom: Jiri Olsa <[email protected]>
Currently we display the "Too slow to read ring buffer.." helpline only in the slow reader thread. This patch triggers it also when the processing thread drops samples, because it has the same reason, which is too many data on input.
--- tools/perf/builtin-top.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
tools/perf/builtin-top.c +1 -1
@@ -571,7 +571,7 @@ static void perf_top__sort_new_samples(void *arg)hists__collapse_resort (hists,NULL );perf_evsel__output_resort (evsel,NULL ); -if (t->lost) +if (t->lost || t->drop)pr_warning ("Too slow to read ring buffer (change period (-c/-F) or limit CPUs (-C)\n" );perf_top__reset_sample_counters (t);
Signature · 1 line
2.19.2
Arnaldo Carvalho de Melo
maintainerPATCH 56/75 perf top: Move perf_top__reset_sample_counters() to after counts display
In reply to Arnaldo Carvalho de MeloFrom: Jiri Olsa <[email protected]>
Move the perf_top__reset_sample_counters() call to right after we display the counters so we can see the updated numbers for longer.
--- tools/perf/builtin-top.c | 4 ---- tools/perf/ui/browsers/hists.c | 3 +++ tools/perf/util/top.c | 1 + 3 files changed, 4 insertions(+), 4 deletions(-)
tools/perf/builtin-top.c +0 -4
@@ -273,8 +273,6 @@ static void perf_top__print_sym_table(struct perf_top *top)perf_top__header_snprintf (top, bf,sizeof (bf));printf ("%s\n" , bf); -perf_top__reset_sample_counters (top); -printf ("%-*.*s\n" , win_width, win_width, graph_dotted_line); if (!top->record_opts.overwrite &&
@@ -573,8 +571,6 @@ static void perf_top__sort_new_samples(void *arg)if (t->lost || t->drop)pr_warning ("Too slow to read ring buffer (change period (-c/-F) or limit CPUs (-C)\n" ); - -perf_top__reset_sample_counters (t); }static void stop_top (void )
tools/perf/ui/browsers/hists.c +3 -0
@@ -2229,8 +2229,11 @@ static int hists_browser__scnprintf_title(struct hist_browser *browser, char *bfif (top->zero) printed +=scnprintf (bf + printed, size - printed," [z]" ); + +perf_top__reset_sample_counters (top); } +return printed; }
tools/perf/util/top.c +1 -0
@@ -107,6 +107,7 @@ size_t perf_top__header_snprintf(struct perf_top *top, char *bf, size_t size) top->evlist->cpus->nr > 1 ? "s" : ""); } +perf_top__reset_sample_counters (top);return ret; }
Signature · 1 line
2.19.2
Arnaldo Carvalho de Melo
maintainerPATCH 57/75 perf cs-etm: Add configuration for ETMv3 trace protocol
In reply to Arnaldo Carvalho de MeloFrom: Mathieu Poirier <[email protected]>
This patch deals with the proper initialisation of configuration parameters for the ETMv3 trace protocol in order to properly handle packets generated by tracers following this specification.
--- .../perf/util/cs-etm-decoder/cs-etm-decoder.h | 8 +++ tools/perf/util/cs-etm.c | 54 ++++++++++++++----- 2 files changed, 48 insertions(+), 14 deletions(-)
tools/perf/util/cs-etm-decoder/cs-etm-decoder.h +8 -0
@@ -53,6 +53,13 @@ struct cs_etm_queue;typedef u32 (*cs_etm_mem_cb_type )(struct cs_etm_queue *,u64 ,size_t ,u8 *); +struct cs_etmv3_trace_params { +u32 reg_ctrl; +u32 reg_trc_id; +u32 reg_ccer; +u32 reg_idr; +}; +struct cs_etmv4_trace_params {u32 reg_idr0;u32 reg_idr1;
@@ -65,6 +72,7 @@ struct cs_etmv4_trace_params {struct cs_etm_trace_params {int protocol;union { +struct cs_etmv3_trace_params etmv3;struct cs_etmv4_trace_params etmv4; }; };
tools/perf/util/cs-etm.c +40 -14
70 lines not on this page · raw message
Signature · 1 line
2.19.2
Arnaldo Carvalho de Melo
maintainerPATCH 58/75 perf cs-etm: Add support for ETMv3 trace decoding
In reply to Arnaldo Carvalho de MeloFrom: Mathieu Poirier <[email protected]>
Add support for the creation of packet printer and decoder for the ETMv3 trace architecture. That way traces generated by tracers adhering to that trace protocol can be handled properly by the perf infrastructure.
--- .../perf/util/cs-etm-decoder/cs-etm-decoder.c | 25 +++++++++++++++++++ 1 file changed, 25 insertions(+)
tools/perf/util/cs-etm-decoder/cs-etm-decoder.c +25 -0
@@ -116,6 +116,19 @@ int cs_etm_decoder__get_packet(struct cs_etm_decoder *decoder,return 1 ; } +static int cs_etm_decoder__gen_etmv3_config (struct cs_etm_trace_params *params, +ocsd_etmv3_cfg *config) +{ + config->reg_idr = params->etmv3.reg_idr; + config->reg_ctrl = params->etmv3.reg_ctrl; + config->reg_ccer = params->etmv3.reg_ccer; + config->reg_trc_id = params->etmv3.reg_trc_id; + config->arch_ver =ARCH_V7 ; + config->core_prof = profile_CortexA; + +return 0 ; +} +static void cs_etm_decoder__gen_etmv4_config (struct cs_etm_trace_params *params,ocsd_etmv4_cfg *config) {
@@ -237,10 +250,16 @@ cs_etm_decoder__create_etm_packet_printer(struct cs_etm_trace_params *t_params, struct cs_etm_decoder *decoder) {const char *decoder_name; +ocsd_etmv3_cfg config_etmv3;ocsd_etmv4_cfg trace_config_etmv4;void *trace_config;switch (t_params->protocol) { +case CS_ETM_PROTO_ETMV3 : +cs_etm_decoder__gen_etmv3_config (t_params, &config_etmv3); + decoder_name =OCSD_BUILTIN_DCD_ETMV3 ; + trace_config = &config_etmv3; +break ;case CS_ETM_PROTO_ETMV4i:cs_etm_decoder__gen_etmv4_config (t_params, &trace_config_etmv4); decoder_name =OCSD_BUILTIN_DCD_ETMV4I ;
@@ -427,11 +446,17 @@ static int cs_etm_decoder__create_etm_packet_decoder( struct cs_etm_decoder *decoder) {const char *decoder_name; +ocsd_etmv3_cfg config_etmv3;ocsd_etmv4_cfg trace_config_etmv4;void *trace_config;u8 csid;switch (t_params->protocol) { +case CS_ETM_PROTO_ETMV3 : +cs_etm_decoder__gen_etmv3_config (t_params, &config_etmv3); + decoder_name =OCSD_BUILTIN_DCD_ETMV3 ; + trace_config = &config_etmv3; +break ;case CS_ETM_PROTO_ETMV4i:cs_etm_decoder__gen_etmv4_config (t_params, &trace_config_etmv4); decoder_name =OCSD_BUILTIN_DCD_ETMV4I ;
Signature · 1 line
2.19.2
Arnaldo Carvalho de Melo
maintainerPATCH 59/75 perf cs-etm: Add support for PTMv1.1 decoding
In reply to Arnaldo Carvalho de MeloFrom: Mathieu Poirier <[email protected]>
This patch is re-using the mechanic set forth by ETMv3 to add support for PTM decoding. Configuration for both encoding protocol is similar but the generated stream itself is very different, hence requiring special handling.
--- .../perf/util/cs-etm-decoder/cs-etm-decoder.c | 10 ++++++-- .../perf/util/cs-etm-decoder/cs-etm-decoder.h | 1 + tools/perf/util/cs-etm.c | 23 +++++++++++++++++-- 3 files changed, 30 insertions(+), 4 deletions(-)
tools/perf/util/cs-etm-decoder/cs-etm-decoder.c +8 -2
@@ -256,8 +256,11 @@ cs_etm_decoder__create_etm_packet_printer(struct cs_etm_trace_params *t_params,switch (t_params->protocol) {case CS_ETM_PROTO_ETMV3 : +case CS_ETM_PROTO_PTM :cs_etm_decoder__gen_etmv3_config (t_params, &config_etmv3); - decoder_name =OCSD_BUILTIN_DCD_ETMV3 ; + decoder_name = (t_params->protocol ==CS_ETM_PROTO_ETMV3 ) ? +OCSD_BUILTIN_DCD_ETMV3 : +OCSD_BUILTIN_DCD_PTM ; trace_config = &config_etmv3;break ;case CS_ETM_PROTO_ETMV4i:
@@ -453,8 +456,11 @@ static int cs_etm_decoder__create_etm_packet_decoder(switch (t_params->protocol) {case CS_ETM_PROTO_ETMV3 : +case CS_ETM_PROTO_PTM :cs_etm_decoder__gen_etmv3_config (t_params, &config_etmv3); - decoder_name =OCSD_BUILTIN_DCD_ETMV3 ; + decoder_name = (t_params->protocol ==CS_ETM_PROTO_ETMV3 ) ? +OCSD_BUILTIN_DCD_ETMV3 : +OCSD_BUILTIN_DCD_PTM ; trace_config = &config_etmv3;break ;case CS_ETM_PROTO_ETMV4i:
tools/perf/util/cs-etm-decoder/cs-etm-decoder.h +1 -0
@@ -96,6 +96,7 @@ enum {CS_ETM_PROTO_ETMV3 =1 , CS_ETM_PROTO_ETMV4i, CS_ETM_PROTO_ETMV4d, + CS_ETM_PROTO_PTM, }; enum {
tools/perf/util/cs-etm.c +21 -2
@@ -83,6 +83,19 @@ static int cs_etm__update_queues(struct cs_etm_auxtrace *etm);static int cs_etm__process_timeless_queues (struct cs_etm_auxtrace *etm,pid_t tid,u64 time_); +/* PTMs ETMIDR [11:8] set to b0011 */ +#define ETMIDR_PTM_VERSION 0x00000300 + +static u32 cs_etm__get_v7_protocol_version (u32 etmidr) +{ + etmidr &=ETMIDR_PTM_VERSION ; + +if (etmidr ==ETMIDR_PTM_VERSION ) +return CS_ETM_PROTO_PTM ; + +return CS_ETM_PROTO_ETMV3 ; +} +static void cs_etm__packet_dump (const char *pkt_string) {const char *color =PERF_COLOR_BLUE ;
@@ -115,7 +128,10 @@ static void cs_etm__dump_event(struct cs_etm_auxtrace *etm, t_params =zalloc (sizeof (*t_params) * etm->num_cpu);for (i =0 ; i < etm->num_cpu; i++) {if (etm->metadata[i][CS_ETM_MAGIC ] == __perf_cs_etmv3_magic) { - t_params[i].protocol =CS_ETM_PROTO_ETMV3 ; +u32 etmidr = etm->metadata[i][CS_ETM_ETMIDR ]; + + t_params[i].protocol = +cs_etm__get_v7_protocol_version (etmidr); t_params[i].etmv3.reg_ctrl = etm->metadata[i][CS_ETM_ETMCR ]; t_params[i].etmv3.reg_trc_id =
@@ -366,7 +382,10 @@ static struct cs_etm_queue *cs_etm__alloc_queue(struct cs_etm_auxtrace *etm,for (i =0 ; i < etm->num_cpu; i++) {if (etm->metadata[i][CS_ETM_MAGIC ] == __perf_cs_etmv3_magic) { - t_params[i].protocol =CS_ETM_PROTO_ETMV3 ; +u32 etmidr = etm->metadata[i][CS_ETM_ETMIDR ]; + + t_params[i].protocol = +cs_etm__get_v7_protocol_version (etmidr); t_params[i].etmv3.reg_ctrl = etm->metadata[i][CS_ETM_ETMCR ]; t_params[i].etmv3.reg_trc_id =
Signature · 1 line
2.19.2
Arnaldo Carvalho de Melo
maintainerPATCH 60/75 perf dso: Fix unchecked usage of strncpy()
In reply to Arnaldo Carvalho de MeloFrom: Arnaldo Carvalho de Melo <[email protected]>
The strncpy() function may leave the destination string buffer unterminated, better use strlcpy() that we have a __weak fallback implementation for systems without it.
This fixes this warning on an Alpine Linux Edge system with gcc 8.2:
In function 'decompress_kmodule',
inlined from 'dso__decompress_kmodule_fd' at util/dso.c:305:9:
util/dso.c:298:3: error: 'strncpy' destination unchanged after copying no bytes [-Werror=stringop-truncation]
strncpy(pathname, tmpbuf, len);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
CC /tmp/build/perf/util/values.o
CC /tmp/build/perf/util/debug.occ1: all warnings being treated as errors
--- tools/perf/util/dso.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
tools/perf/util/dso.c +1 -1
@@ -295,7 +295,7 @@ static int decompress_kmodule(struct dso *dso, const char *name,unlink (tmpbuf);if (pathname && (fd >=0 )) -strncpy (pathname, tmpbuf, len); +strlcpy (pathname, tmpbuf, len);return fd; }
Signature · 1 line
2.19.2
Arnaldo Carvalho de Melo
maintainerPATCH 61/75 perf header: Fix unchecked usage of strncpy()
In reply to Arnaldo Carvalho de MeloFrom: Arnaldo Carvalho de Melo <[email protected]>
The strncpy() function may leave the destination string buffer unterminated, better use strlcpy() that we have a __weak fallback implementation for systems without it.
This fixes this warning on an Alpine Linux Edge system with gcc 8.2:
util/header.c: In function 'perf_event__synthesize_event_update_unit':
util/header.c:3586:2: error: 'strncpy' output truncated before terminating nul copying as many bytes from a string as its length [-Werror=stringop-truncation]
strncpy(ev->data, evsel->unit, size);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
util/header.c:3579:16: note: length computed here
size_t size = strlen(evsel->unit);
^~~~~~~~~~~~~~~~~~~--- tools/perf/util/header.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
tools/perf/util/header.c +1 -1
@@ -3583,7 +3583,7 @@ perf_event__synthesize_event_update_unit(struct perf_tool *tool,if (ev ==NULL )return -ENOMEM ; -strncpy (ev->data, evsel->unit, size); +strlcpy (ev->data, evsel->unit, size +1 ); err =process (tool, (union perf_event *)ev,NULL ,NULL );free (ev);return err;
Signature · 1 line
2.19.2
Arnaldo Carvalho de Melo
maintainerPATCH 62/75 perf header: Fix unchecked usage of strncpy()
In reply to Arnaldo Carvalho de MeloFrom: Arnaldo Carvalho de Melo <[email protected]>
The strncpy() function may leave the destination string buffer unterminated, better use strlcpy() that we have a __weak fallback implementation for systems without it.
This fixes this warning on an Alpine Linux Edge system with gcc 8.2:
util/header.c: In function 'perf_event__synthesize_event_update_name':
util/header.c:3625:2: error: 'strncpy' output truncated before terminating nul copying as many bytes from a string as its length [-Werror=stringop-truncation]
strncpy(ev->data, evsel->name, len);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
util/header.c:3618:15: note: length computed here
size_t len = strlen(evsel->name);
^~~~~~~~~~~~~~~~~~~--- tools/perf/util/header.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
tools/perf/util/header.c +1 -1
@@ -3622,7 +3622,7 @@ perf_event__synthesize_event_update_name(struct perf_tool *tool,if (ev ==NULL )return -ENOMEM ; -strncpy (ev->data, evsel->name, len); +strlcpy (ev->data, evsel->name, len +1 ); err =process (tool, (union perf_event *) ev,NULL ,NULL );free (ev);return err;
Signature · 1 line
2.19.2
Arnaldo Carvalho de Melo
maintainerPATCH 63/75 perf help: Remove needless use of strncpy()
In reply to Arnaldo Carvalho de MeloFrom: Arnaldo Carvalho de Melo <[email protected]>
Since we make sure the destination buffer has at least strlen(orig) + 1, no need to do a strncpy(dest, orig, strlen(orig)), just use strcpy(dest, orig).
This silences this gcc 8.2 warning on Alpine Linux:
In function 'add_man_viewer',
inlined from 'perf_help_config' at builtin-help.c:284:3:
builtin-help.c:192:2: error: 'strncpy' output truncated before terminating nul copying as many bytes from a string as its length [-Werror=stringop-truncation]
strncpy((*p)->name, name, len);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
builtin-help.c: In function 'perf_help_config':
builtin-help.c:187:15: note: length computed here
size_t len = strlen(name);
^~~~~~~~~~~~--- tools/perf/builtin-help.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
tools/perf/builtin-help.c +1 -1
@@ -189,7 +189,7 @@ static void add_man_viewer(const char *name)while (*p) p = &((*p)->next); *p =zalloc (sizeof (**p) + len +1 ); -strncpy ((*p)->name, name, len); +strcpy ((*p)->name, name); }static int supported_man_viewer (const char *name,size_t len)
Signature · 1 line
2.19.2
Arnaldo Carvalho de Melo
maintainerPATCH 64/75 perf svghelper: Fix unchecked usage of strncpy()
In reply to Arnaldo Carvalho de MeloFrom: Arnaldo Carvalho de Melo <[email protected]>
The strncpy() function may leave the destination string buffer unterminated, better use strlcpy() that we have a __weak fallback implementation for systems without it.
In this specific case this would only happen if fgets() was buggy, as its man page states that it should read one less byte than the size of the destination buffer, so that it can put the nul byte at the end of it, so it would never copy 255 non-nul chars, as fgets reads into the orig buffer at most 254 non-nul chars and terminates it. But lets just switch to strlcpy to keep the original intent and silence the gcc 8.2 warning.
This fixes this warning on an Alpine Linux Edge system with gcc 8.2:
In function 'cpu_model',
inlined from 'svg_cpu_box' at util/svghelper.c:378:2:
util/svghelper.c:337:5: error: 'strncpy' output may be truncated copying 255 bytes from a string of length 255 [-Werror=stringop-truncation]
strncpy(cpu_m, &buf[13], 255);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~--- tools/perf/util/svghelper.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
tools/perf/util/svghelper.c +1 -1
@@ -334,7 +334,7 @@ static char *cpu_model(void)if (file) {while (fgets (buf,255 , file)) {if (strstr (buf,"model name" )) { -strncpy (cpu_m, &buf[13 ],255 ); +strlcpy (cpu_m, &buf[13 ],255 );break ; } }
Signature · 1 line
2.19.2
Arnaldo Carvalho de Melo
maintainerPATCH 65/75 perf ui helpline: Use strlcpy() as a shorter form of strncpy() + explicit set nul
In reply to Arnaldo Carvalho de MeloFrom: Arnaldo Carvalho de Melo <[email protected]>
The strncpy() function may leave the destination string buffer unterminated, better use strlcpy() that we have a __weak fallback implementation for systems without it.
In this case we are actually setting the null byte at the right place, but since we pass the buffer size as the limit to strncpy() and not it minus one, gcc ends up warning us about that, see below. So, lets just switch to the shorter form provided by strlcpy().
This fixes this warning on an Alpine Linux Edge system with gcc 8.2:
ui/tui/helpline.c: In function 'tui_helpline__push':
ui/tui/helpline.c:27:2: error: 'strncpy' specified bound 512 equals destination size [-Werror=stringop-truncation]
strncpy(ui_helpline__current, msg, sz)[sz - 1] = '\0';
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~cc1: all warnings being treated as errors
--- tools/perf/ui/tui/helpline.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
tools/perf/ui/tui/helpline.c +1 -1
@@ -24,7 +24,7 @@ static void tui_helpline__push(const char *msg)SLsmg_set_color (0 );SLsmg_write_nstring ((char *)msg, SLtt_Screen_Cols);SLsmg_refresh (); -strncpy (ui_helpline__current, msg, sz)[sz -1 ] ='\0' ; +strlcpy (ui_helpline__current, msg, sz); }static int tui_helpline__show (const char *format,va_list ap)
Signature · 1 line
2.19.2
Arnaldo Carvalho de Melo
maintainerPATCH 66/75 perf probe: Fix unchecked usage of strncpy()
In reply to Arnaldo Carvalho de MeloFrom: Arnaldo Carvalho de Melo <[email protected]>
The strncpy() function may leave the destination string buffer unterminated, better use strlcpy() that we have a __weak fallback implementation for systems without it.
In this case the 'target' buffer is coming from a list of build-ids that are expected to have a len of at most (SBUILD_ID_SIZE - 1) chars, so probably we're safe, but since we're using strncpy() here, use strlcpy() instead to provide the intended safety checking without the using the problematic strncpy() function.
This fixes this warning on an Alpine Linux Edge system with gcc 8.2:
util/probe-file.c: In function 'probe_cache__open.isra.5':
util/probe-file.c:427:3: error: 'strncpy' specified bound 41 equals destination size [-Werror=stringop-truncation]
strncpy(sbuildid, target, SBUILD_ID_SIZE);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~cc1: all warnings being treated as errors
--- tools/perf/util/probe-file.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
tools/perf/util/probe-file.c +1 -1
@@ -424,7 +424,7 @@ static int probe_cache__open(struct probe_cache *pcache, const char *target,if (target &&build_id_cache__cached (target)) {/* This is a cached buildid */ -strncpy (sbuildid, target,SBUILD_ID_SIZE ); +strlcpy (sbuildid, target,SBUILD_ID_SIZE ); dir_name =build_id_cache__linkname (sbuildid,NULL ,0 ); goto found; }
Signature · 1 line
2.19.2
Arnaldo Carvalho de Melo
maintainerPATCH 67/75 perf parse-events: Fix unchecked usage of strncpy()
In reply to Arnaldo Carvalho de MeloFrom: Arnaldo Carvalho de Melo <[email protected]>
The strncpy() function may leave the destination string buffer unterminated, better use strlcpy() that we have a __weak fallback implementation for systems without it.
This fixes this warning on an Alpine Linux Edge system with gcc 8.2:
util/parse-events.c: In function 'print_symbol_events':
util/parse-events.c:2465:4: error: 'strncpy' specified bound 100 equals destination size [-Werror=stringop-truncation]
strncpy(name, syms->symbol, MAX_NAME_LEN);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In function 'print_symbol_events.constprop',
inlined from 'print_events' at util/parse-events.c:2508:2:
util/parse-events.c:2465:4: error: 'strncpy' specified bound 100 equals destination size [-Werror=stringop-truncation]
strncpy(name, syms->symbol, MAX_NAME_LEN);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In function 'print_symbol_events.constprop',
inlined from 'print_events' at util/parse-events.c:2511:2:
util/parse-events.c:2465:4: error: 'strncpy' specified bound 100 equals destination size [-Werror=stringop-truncation]
strncpy(name, syms->symbol, MAX_NAME_LEN);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~cc1: all warnings being treated as errors
--- tools/perf/util/parse-events.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
tools/perf/util/parse-events.c +1 -1
@@ -2462,7 +2462,7 @@ void print_symbol_events(const char *event_glob, unsigned type,if (!name_only &&strlen (syms->alias))snprintf (name,MAX_NAME_LEN ,"%s OR %s" , syms->symbol, syms->alias);else -strncpy (name, syms->symbol,MAX_NAME_LEN ); +strlcpy (name, syms->symbol,MAX_NAME_LEN ); evt_list[evt_i] =strdup (name);if (evt_list[evt_i] ==NULL )
Signature · 1 line
2.19.2
Arnaldo Carvalho de Melo
maintainerPATCH 68/75 perf vendor events intel: Fix Load_Miss_Real_Latency on SKL/SKX
In reply to Arnaldo Carvalho de MeloFrom: Andi Kleen <[email protected]>
Fix incorrect event names for the Load_Miss_Real_Latency metric for Skylake and Skylake Server.
Fixes https://github.com/andikleen/pmu-tools/issues/158
Before:
% perf stat -M Load_Miss_Real_Latency true
event syntax error: '..ss.pending,mem_load_retired.l1_miss_ps,mem_load_retired.fb_hit_ps}:W'
\___ parser error
Usage: perf stat [<options>] [<command>]
-M, --metrics <metric/metric group list>
monitor specified metrics or metric groups (separated by ,)
After:
% perf stat -M Load_Miss_Real_Latency true
Performance counter stats for 'true':
279,204 l1d_pend_miss.pending # 14.0 Load_Miss_Real_Latency
4,784 mem_load_uops_retired.l1_miss
15,188 mem_load_uops_retired.hit_lfb0.000899640 seconds time elapsed
--- tools/perf/pmu-events/arch/x86/skylake/skl-metrics.json | 2 +- tools/perf/pmu-events/arch/x86/skylakex/skx-metrics.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-)
tools/perf/pmu-events/arch/x86/skylake/skl-metrics.json +1 -1
@@ -73,7 +73,7 @@ }, { "BriefDescription": "Actual Average Latency for L1 data-cache miss demand loads", - "MetricExpr": "L1D_PEND_MISS.PENDING / ( MEM_LOAD_RETIRED.L1_MISS_PS + MEM_LOAD_RETIRED.FB_HIT_PS )", + "MetricExpr": "L1D_PEND_MISS.PENDING / ( MEM_LOAD_RETIRED.L1_MISS + MEM_LOAD_RETIRED.FB_HIT )", "MetricGroup": "Memory_Bound;Memory_Lat", "MetricName": "Load_Miss_Real_Latency" },
tools/perf/pmu-events/arch/x86/skylakex/skx-metrics.json +1 -1
@@ -73,7 +73,7 @@ }, { "BriefDescription": "Actual Average Latency for L1 data-cache miss demand loads", - "MetricExpr": "L1D_PEND_MISS.PENDING / ( MEM_LOAD_RETIRED.L1_MISS_PS + MEM_LOAD_RETIRED.FB_HIT_PS )", + "MetricExpr": "L1D_PEND_MISS.PENDING / ( MEM_LOAD_RETIRED.L1_MISS + MEM_LOAD_RETIRED.FB_HIT )", "MetricGroup": "Memory_Bound;Memory_Lat", "MetricName": "Load_Miss_Real_Latency" },
Signature · 1 line
2.19.2
Arnaldo Carvalho de Melo
maintainerPATCH 69/75 perf record: Fix memory leak on AIO objects deallocation
In reply to Arnaldo Carvalho de MeloFrom: Alexey Budankov <[email protected]>
Sending a part which was missed between v12 and v13 of the patch set introducing AIO trace streaming for perf record mode.
The part is essential to avoid memory leakage during deallocation of AIO related trace data buffers.
--- tools/perf/util/mmap.c | 6 ++++++ 1 file changed, 6 insertions(+)
tools/perf/util/mmap.c +6 -0
@@ -207,8 +207,14 @@ static int perf_mmap__aio_mmap(struct perf_mmap *map, struct mmap_params *mp)static void perf_mmap__aio_munmap (struct perf_mmap *map) { +int i; + +for (i =0 ; i < map->aio.nr_cblocks; ++i) +zfree (&map->aio.data[i]);if (map->aio.data)zfree (&map->aio.data); +zfree (&map->aio.cblocks); +zfree (&map->aio.aiocb); } int perf_mmap__aio_push(struct perf_mmap *md, void *to, int idx,
Signature · 1 line
2.19.2
Arnaldo Carvalho de Melo
maintainerPATCH 70/75 perf config: Modify size factor of snprintf
In reply to Arnaldo Carvalho de MeloFrom: Sihyeon Jang <[email protected]>
According to definition of snprintf, it gets size factor including null('\0') byte. So '-1' is not neccessary. Also it will be helpful unfied style with other cases. (eg. builtin-script.c)
--- tools/perf/util/config.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
tools/perf/util/config.c +2 -2
@@ -815,14 +815,14 @@ int config_error_nonbool(const char *var)void set_buildid_dir (const char *dir) {if (dir) -scnprintf (buildid_dir,MAXPATHLEN -1 ,"%s" , dir); +scnprintf (buildid_dir,MAXPATHLEN ,"%s" , dir);/* default to $HOME/.debug */ if (buildid_dir[0 ] =='\0' ) {char *home =getenv ("HOME" );if (home) { -snprintf (buildid_dir,MAXPATHLEN -1 ,"%s/%s" , +snprintf (buildid_dir,MAXPATHLEN ,"%s/%s" , home,DEBUG_CACHE_DIR ); }else {strncpy (buildid_dir,DEBUG_CACHE_DIR ,MAXPATHLEN -1 );
Signature · 1 line
2.19.2
Arnaldo Carvalho de Melo
maintainerPATCH 71/75 perf annotate: Introduce basic support for ARC
In reply to Arnaldo Carvalho de MeloFrom: Eugeniy Paltsev <[email protected]>
Introduce basic 'perf annotate' support for ARC to be able to use anotation via stdio interface.
--- tools/perf/arch/arc/annotate/instructions.c | 9 +++++++++ tools/perf/arch/common.c | 11 ++++++++++- tools/perf/util/annotate.c | 5 +++++ 3 files changed, 24 insertions(+), 1 deletion(-) create mode 100644 tools/perf/arch/arc/annotate/instructions.c
tools/perf/arch/arc/annotate/instructions.c new file +9 -0
@@ -0,0 +1,9 @@ +// SPDX-License-Identifier: GPL-2.0 +#include <linux/compiler.h> + +static int arc__annotate_init (struct arch *arch,char *cpuid__maybe_unused ) +{ + arch->initialized = true; + arch->objdump.comment_char =';' ; +return 0 ; +}
tools/perf/arch/common.c +10 -1
@@ -5,6 +5,13 @@#include "../util/util.h" #include "../util/debug.h" +const char *const arc_triplets[] = { +"arc-linux-" , +"arc-snps-linux-uclibc-" , +"arc-snps-linux-gnu-" , +NULL +}; +const char *const arm_triplets[] = {"arm-eabi-" ,"arm-linux-androideabi-" ,
@@ -147,7 +154,9 @@ static int perf_env__lookup_binutils_path(struct perf_env *env,zfree (&buf); } -if (!strcmp (arch,"arm" )) +if (!strcmp (arch,"arc" )) + path_list = arc_triplets; +else if (!strcmp (arch,"arm" )) path_list = arm_triplets;else if (!strcmp (arch,"arm64" )) path_list = arm64_triplets;
tools/perf/util/annotate.c +5 -0
@@ -134,6 +134,7 @@ static int arch__associate_ins_ops(struct arch* arch, const char *name, struct ireturn 0 ; } +#include "arch/arc/annotate/instructions.c" #include "arch/arm/annotate/instructions.c" #include "arch/arm64/annotate/instructions.c" #include "arch/x86/annotate/instructions.c"
@@ -142,6 +143,10 @@ static int arch__associate_ins_ops(struct arch* arch, const char *name, struct i#include "arch/sparc/annotate/instructions.c" static struct arch architectures[] = { + { + .name ="arc" , + .init = arc__annotate_init, + }, { .name ="arm" , .init = arm__annotate_init,
Signature · 1 line
2.19.2
Arnaldo Carvalho de Melo
maintainerPATCH 72/75 perf ordered_events: Add ordered_events__flush_time interface
In reply to Arnaldo Carvalho de MeloFrom: Jiri Olsa <[email protected]>
Add OE_FLUSH__TIME flush type, to be able to flush only certain amount of the queue based on the provided timestamp. It will be used in the following patches.
--- tools/perf/util/ordered-events.c | 23 +++++++++++++++++++---- tools/perf/util/ordered-events.h | 2 ++ 2 files changed, 21 insertions(+), 4 deletions(-)
tools/perf/util/ordered-events.c +19 -4
@@ -219,8 +219,7 @@ int ordered_events__queue(struct ordered_events *oe, union perf_event *event,return 0 ; } -static int __ordered_events__flush (struct ordered_events *oe, -bool show_progress) +static int do_flush (struct ordered_events *oe,bool show_progress) {struct list_head *head = &oe->events;struct ordered_event *tmp, *iter;
@@ -263,7 +262,8 @@ static int __ordered_events__flush(struct ordered_events *oe,return 0 ; } -int ordered_events__flush (struct ordered_events *oe,enum oe_flush how) +static int __ordered_events__flush (struct ordered_events *oe,enum oe_flush how, +u64 timestamp) {static const char *const str[] = {"NONE" ,
@@ -302,6 +302,11 @@ int ordered_events__flush(struct ordered_events *oe, enum oe_flush how)break ; } +case OE_FLUSH__TIME : + oe->next_flush = timestamp; + show_progress = false; +break ; +case OE_FLUSH__ROUND :case OE_FLUSH__NONE :default :
@@ -312,7 +317,7 @@ int ordered_events__flush(struct ordered_events *oe, enum oe_flush how) str[how], oe->nr_events);pr_oe_time (oe->max_timestamp,"max_timestamp\n" ); - err =__ordered_events__flush (oe, show_progress); + err =do_flush (oe, show_progress);if (!err) {if (how ==OE_FLUSH__ROUND )
@@ -328,6 +333,16 @@ int ordered_events__flush(struct ordered_events *oe, enum oe_flush how)return err; } +int ordered_events__flush (struct ordered_events *oe,enum oe_flush how) +{ +return __ordered_events__flush (oe, how,0 ); +} + +int ordered_events__flush_time (struct ordered_events *oe,u64 timestamp) +{ +return __ordered_events__flush (oe,OE_FLUSH__TIME , timestamp); +} +void ordered_events__init (struct ordered_events *oe,ordered_events__deliver_t deliver,void *data) {
tools/perf/util/ordered-events.h +2 -0
@@ -19,6 +19,7 @@ enum oe_flush {OE_FLUSH__ROUND ,OE_FLUSH__HALF ,OE_FLUSH__TOP , + OE_FLUSH__TIME, };struct ordered_events ;
@@ -55,6 +56,7 @@ int ordered_events__queue(struct ordered_events *oe, union perf_event *event, u64 timestamp, u64 file_offset);void ordered_events__delete (struct ordered_events *oe,struct ordered_event *event);int ordered_events__flush (struct ordered_events *oe,enum oe_flush how); +int ordered_events__flush_time (struct ordered_events *oe,u64 timestamp);void ordered_events__init (struct ordered_events *oe,ordered_events__deliver_t deliver,void *data);void ordered_events__free (struct ordered_events *oe);
Signature · 1 line
2.19.2
Arnaldo Carvalho de Melo
maintainerPATCH 73/75 perf trace: Move event delivery to a new deliver_event() function
In reply to Arnaldo Carvalho de MeloFrom: Jiri Olsa <[email protected]>
Mov event delivery code to a new trace__deliver_event() function, so it's easier to add ordered delivery coming in the following patches.
--- tools/perf/builtin-trace.c | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-)
tools/perf/builtin-trace.c +16 -9
@@ -2637,6 +2637,21 @@ static int trace__set_filter_pids(struct trace *trace)return err; } +static int trace__deliver_event (struct trace *trace,union perf_event *event) +{ +struct perf_evlist *evlist = trace->evlist; +struct perf_sample sample; +int err; + + err =perf_evlist__parse_sample (evlist, event, &sample); +if (err) +fprintf (trace->output,"Can't parse sample, err = %d, skipping...\n" , err); +else +trace__handle_event (trace, event, &sample); + +return 0 ; +} +static int trace__run (struct trace *trace,int argc,const char **argv) {struct perf_evlist *evlist = trace->evlist;
@@ -2802,18 +2817,10 @@ static int trace__run(struct trace *trace, int argc, const char **argv)continue ;while ((event =perf_mmap__read_event (md)) !=NULL ) { -struct perf_sample sample; - ++trace->nr_events; - err =perf_evlist__parse_sample (evlist, event, &sample); -if (err) { -fprintf (trace->output,"Can't parse sample, err = %d, skipping...\n" , err); - goto next_event; - } +trace__deliver_event (trace, event); -trace__handle_event (trace, event, &sample); -next_event:perf_mmap__consume (md);if (interrupted)
Signature · 1 line
2.19.2
Arnaldo Carvalho de Melo
maintainerPATCH 74/75 perf ordered_events: Add first_time() method
In reply to Arnaldo Carvalho de MeloFrom: Jiri Olsa <[email protected]>
To get the timestamp in the first event in the queue.
--- tools/perf/util/ordered-events.c | 11 +++++++++++ tools/perf/util/ordered-events.h | 1 + 2 files changed, 12 insertions(+)
tools/perf/util/ordered-events.c +11 -0
@@ -343,6 +343,17 @@ int ordered_events__flush_time(struct ordered_events *oe, u64 timestamp)return __ordered_events__flush (oe,OE_FLUSH__TIME , timestamp); } +u64 ordered_events__first_time (struct ordered_events *oe) +{ +struct ordered_event *event; + +if (list_empty (&oe->events)) +return 0 ; + + event = list_first_entry(&oe->events, struct ordered_event, list); +return event->timestamp; +} +void ordered_events__init (struct ordered_events *oe,ordered_events__deliver_t deliver,void *data) {
tools/perf/util/ordered-events.h +1 -0
@@ -61,6 +61,7 @@ void ordered_events__init(struct ordered_events *oe, ordered_events__deliver_t d void *data);void ordered_events__free (struct ordered_events *oe);void ordered_events__reinit (struct ordered_events *oe); +u64 ordered_events__first_time (struct ordered_events *oe);static inline void ordered_events__set_alloc_size (struct ordered_events *oe,u64 size)
Signature · 1 line
2.19.2
Arnaldo Carvalho de Melo
maintainerPATCH 75/75 perf trace: Add ordered processing
In reply to Arnaldo Carvalho de MeloFrom: Jiri Olsa <[email protected]>
Sort events to provide the precise outcome of ordered events, just like is done with 'perf report' and 'perf top'.
--- tools/perf/builtin-trace.c | 52 +++++++++++++++++++++++++++++++++++++- 1 file changed, 51 insertions(+), 1 deletion(-)
tools/perf/builtin-trace.c +51 -1
@@ -127,6 +127,10 @@ struct trace {bool force;bool vfs_getname;int trace_pgfaults; +struct { +struct ordered_events data; +u64 last; + } oe; };struct tp_field {
@@ -2652,6 +2656,42 @@ static int trace__deliver_event(struct trace *trace, union perf_event *event)return 0 ; } +static int trace__flush_ordered_events (struct trace *trace) +{ +u64 first =ordered_events__first_time (&trace->oe.data); +u64 flush = trace->oe.last -NSEC_PER_SEC ; + +/* Is there some thing to flush.. */ +if (first && first < flush) +return ordered_events__flush_time (&trace->oe.data, flush); + +return 0 ; +} + +static int trace__deliver_ordered_event (struct trace *trace,union perf_event *event) +{ +struct perf_evlist *evlist = trace->evlist; +int err; + + err =perf_evlist__parse_sample_timestamp (evlist, event, &trace->oe.last); +if (err && err !=-1 ) +return err; + + err =ordered_events__queue (&trace->oe.data, event, trace->oe.last,0 ); +if (err) +return err; + +return trace__flush_ordered_events (trace); +} + +static int ordered_events__deliver_event (struct ordered_events *oe, +struct ordered_event *event) +{ + struct trace *trace = container_of(oe, struct trace, oe.data); + +return trace__deliver_event (trace, event->event); +} +static int trace__run (struct trace *trace,int argc,const char **argv) {struct perf_evlist *evlist = trace->evlist;
@@ -2819,7 +2859,9 @@ static int trace__run(struct trace *trace, int argc, const char **argv)while ((event =perf_mmap__read_event (md)) !=NULL ) { ++trace->nr_events; -trace__deliver_event (trace, event); + err =trace__deliver_ordered_event (trace, event); +if (err) + goto out_disable;perf_mmap__consume (md);
@@ -2842,6 +2884,9 @@ static int trace__run(struct trace *trace, int argc, const char **argv) draining = true; goto again; + }else { +if (trace__flush_ordered_events (trace)) + goto out_disable; } }else { goto again;
@@ -2852,6 +2897,8 @@ static int trace__run(struct trace *trace, int argc, const char **argv)perf_evlist__disable (evlist); +ordered_events__flush (&trace->oe.data,OE_FLUSH__FINAL ); +if (!err) {if (trace->summary)trace__fprintf_thread_summary (trace, trace->output);
@@ -3562,6 +3609,9 @@ int cmd_trace(int argc, const char **argv) } } +ordered_events__init (&trace.oe.data, ordered_events__deliver_event, &trace); +ordered_events__set_copy_on_queue (&trace.oe.data, true); +/* * If we are augmenting syscalls, then combine what we put in the * __augmented_syscalls__ BPF map with what is in the
Signature · 1 line
2.19.2