perf/urgent improvements and fixes
Subsystems (2)
Arnaldo Carvalho de Melo
maintainerHi Ingo,
Please consider pulling, mostly fixes, some late coming
improvements in non-core areas,
- Arnaldo
Test results at the end of this message, as usual.
The following changes since commit 29995d296e3e9ce4f9767963ecbef143ade26c36:
Merge tag 'perf-urgent-for-mingo-4.20-20181031' of git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux into perf/urgent (2018-10-31 22:53:40 +0100)
are available in the Git repository at:
git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux.git tags/perf-urgent-for-mingo-4.20-20181106
for you to fetch changes up to 8e88c29b351ed4e09dd63f825f1c8260b0cb0ab3:
perf tools: Do not zero sample_id_all for group members (2018-11-06 08:29:56 -0300)
----------------------------------------------------------------
perf/urgent improvements and fixes:
Intel PT sql viewer: (Adrian Hunter)
- Fall back to /usr/local/lib/libxed.so
- Add Selected branches report
- Add help window
- Fix table find when table re-ordered
Intel PT debug log (Adrian Hunter)
- Add more event information
- Add MTC and CYC timestamps
perf record: (Andi Kleen)
- Support weak groups, just like with 'perf stat'
perf trace: (Arnaldo Carvalho de Melo)
- Start augmenting raw_syscalls:{sys_enter,sys_exit}: goal is to have a generic, arch independent eBPF kernel component that is programmed with syscall table details, what to copy, how many bytes, pid, arg filters from the userspace via eBPF maps by the 'perf trace' tool that continues to use all its argument beautifiers, just taking advantage of the extra pointer contents.
JVMTI: (Gustavo Romero)
- Fix undefined symbol scnprintf in libperf-jvmti.so
perf top: (Jin Yao)
- Display the LBR stats in callchain entries
perf stat: (Thomas Richter)
- Handle different PMU names with common prefix
arm64: Will (Deacon)
- Fix arm64 tools build failure wrt smp_load_{acquire,release}.
----------------------------------------------------------------
Adrian Hunter (6):
perf scripts python: exported-sql-viewer.py: Fall back to /usr/local/lib/libxed.so perf scripts python: exported-sql-viewer.py: Add Selected branches report perf scripts python: exported-sql-viewer.py: Add help window
perf scripts python: exported-sql-viewer.py: Fix table find when table re-ordered perf intel-pt: Add more event information to debug log
perf intel-pt: Add MTC and CYC timestamps to debug log
Andi Kleen (2):
perf evlist: Move perf_evsel__reset_weak_group into evlist perf record: Support weak groups
Arnaldo Carvalho de Melo (5):
perf examples bpf: Start augmenting raw_syscalls:sys_{start,exit} perf trace: When augmenting raw_syscalls plug raw_syscalls:sys_exit too perf trace: Fix setting of augmented payload when using eBPF + raw_syscalls perf augmented_syscalls: Start collecting pathnames in the BPF program perf beauty: Use SRCARCH, ARCH=x86_64 must map to "x86" to find the headers
Gustavo Romero (1):
perf tools: Fix undefined symbol scnprintf in libperf-jvmti.so
Jin Yao (1):
perf top: Display the LBR stats in callchain entry
Jiri Olsa (1):
perf tools: Do not zero sample_id_all for group members
Thomas Richter (1):
perf stat: Handle different PMU names with common prefix
Will Deacon (1):
tools headers barrier: Fix arm64 tools build failure wrt smp_load_{acquire,release}tools/arch/arm64/include/asm/barrier.h | 133 +++--- tools/perf/Documentation/perf-list.txt | 1 - tools/perf/Makefile.perf | 2 +- tools/perf/builtin-record.c | 7 +- tools/perf/builtin-stat.c | 28 +- tools/perf/builtin-top.c | 3 + tools/perf/builtin-trace.c | 34 +- tools/perf/examples/bpf/augmented_raw_syscalls.c | 131 ++++++ tools/perf/jvmti/jvmti_agent.c | 49 +- tools/perf/scripts/python/exported-sql-viewer.py | 493 ++++++++++++++++++++- tools/perf/tests/attr/test-record-group-sampling | 1 - tools/perf/util/evlist.c | 27 ++ tools/perf/util/evlist.h | 3 + tools/perf/util/evsel.c | 1 - .../perf/util/intel-pt-decoder/intel-pt-decoder.c | 4 + tools/perf/util/intel-pt-decoder/intel-pt-log.c | 5 + tools/perf/util/intel-pt-decoder/intel-pt-log.h | 1 + tools/perf/util/intel-pt.c | 16 +- tools/perf/util/pmu.c | 2 +- 19 files changed, 820 insertions(+), 121 deletions(-) create mode 100644 tools/perf/examples/bpf/augmented_raw_syscalls.c
Test results:
The first ones are container (docker) based builds of tools/perf with and without libelf support. Where clang is available, it is also used to build perf with/without libelf, 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 6.4.0) 6.4.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-28) 14 debian:7 : Ok gcc (Debian 4.7.2-5) 4.7.2 15 debian:8 : Ok gcc (Debian 4.9.2-10+deb8u1) 4.9.2 16 debian:9 : Ok gcc (Debian 6.3.0-18+deb9u1) 6.3.0 20170516 17 debian:experimental : Ok gcc (Debian 8.2.0-4) 8.2.0 18 debian:experimental-x-arm64 : Ok aarch64-linux-gnu-gcc (Debian 8.2.0-4) 8.2.0 19 debian:experimental-x-mips : Ok mips-linux-gnu-gcc (Debian 8.2.0-4) 8.2.0 20 debian:experimental-x-mips64 : Ok mips64-linux-gnuabi64-gcc (Debian 8.1.0-12) 8.1.0 21 debian:experimental-x-mipsel : Ok mipsel-linux-gnu-gcc (Debian 8.2.0-4) 8.2.0 22 fedora:20 : Ok gcc (GCC) 4.8.3 20140911 (Red Hat 4.8.3-7) 23 fedora:21 : Ok gcc (GCC) 4.9.2 20150212 (Red Hat 4.9.2-6) 24 fedora:22 : Ok gcc (GCC) 5.3.1 20160406 (Red Hat 5.3.1-6) 25 fedora:23 : Ok gcc (GCC) 5.3.1 20160406 (Red Hat 5.3.1-6) 26 fedora:24 : Ok gcc (GCC) 6.3.1 20161221 (Red Hat 6.3.1-1) 27 fedora:24-x-ARC-uClibc : Ok arc-linux-gcc (ARCompact ISA Linux uClibc toolchain 2017.09-rc2) 7.1.1 20170710 28 fedora:25 : Ok gcc (GCC) 6.4.1 20170727 (Red Hat 6.4.1-1) 29 fedora:26 : Ok gcc (GCC) 7.3.1 20180130 (Red Hat 7.3.1-2) 30 fedora:27 : Ok gcc (GCC) 7.3.1 20180712 (Red Hat 7.3.1-6) 31 fedora:28 : Ok gcc (GCC) 8.1.1 20180712 (Red Hat 8.1.1-5) 32 fedora:rawhide : Ok gcc (GCC) 8.2.1 20180905 (Red Hat 8.2.1-3) 33 gentoo-stage3-amd64:latest : Ok gcc (Gentoo 7.3.0-r3 p1.4) 7.3.0 34 mageia:5 : Ok gcc (GCC) 4.9.2 35 mageia:6 : Ok gcc (Mageia 5.5.0-1.mga6) 5.5.0 36 opensuse:13.2 : Ok gcc (SUSE Linux) 4.8.3 20140627 [gcc-4_8-branch revision 212064] 37 opensuse:42.1 : Ok gcc (SUSE Linux) 4.8.5 38 opensuse:42.2 : Ok gcc (SUSE Linux) 4.8.5 39 opensuse:42.3 : Ok gcc (SUSE Linux) 4.8.5 40 opensuse:tumbleweed : Ok gcc (SUSE Linux) 7.3.1 20180323 [gcc-7-branch revision 258812] 41 oraclelinux:6 : Ok gcc (GCC) 4.4.7 20120313 (Red Hat 4.4.7-23.0.1) 42 oraclelinux:7 : Ok gcc (GCC) 4.8.5 20150623 (Red Hat 4.8.5-28.0.1) 43 ubuntu:12.04.5 : Ok gcc (Ubuntu/Linaro 4.6.3-1ubuntu5) 4.6.3 44 ubuntu:14.04.4 : Ok gcc (Ubuntu 4.8.4-2ubuntu1~14.04.3) 4.8.4 45 ubuntu:14.04.4-x-linaro-arm64 : Ok aarch64-linux-gnu-gcc (Linaro GCC 5.5-2017.10) 5.5.0 46 ubuntu:15.04 : Ok gcc (Ubuntu 4.9.2-10ubuntu13) 4.9.2 47 ubuntu:16.04 : Ok gcc (Ubuntu 5.4.0-6ubuntu1~16.04.9) 5.4.0 20160609 48 ubuntu:16.04-x-arm : Ok arm-linux-gnueabihf-gcc (Ubuntu/Linaro 5.4.0-6ubuntu1~16.04.9) 5.4.0 20160609 49 ubuntu:16.04-x-arm64 : Ok aarch64-linux-gnu-gcc (Ubuntu/Linaro 5.4.0-6ubuntu1~16.04.9) 5.4.0 20160609 50 ubuntu:16.04-x-powerpc : Ok powerpc-linux-gnu-gcc (Ubuntu 5.4.0-6ubuntu1~16.04.9) 5.4.0 20160609 51 ubuntu:16.04-x-powerpc64 : Ok powerpc64-linux-gnu-gcc (Ubuntu/IBM 5.4.0-6ubuntu1~16.04.9) 5.4.0 20160609 52 ubuntu:16.04-x-powerpc64el : Ok powerpc64le-linux-gnu-gcc (Ubuntu/IBM 5.4.0-6ubuntu1~16.04.9) 5.4.0 20160609 53 ubuntu:16.04-x-s390 : Ok s390x-linux-gnu-gcc (Ubuntu 5.4.0-6ubuntu1~16.04.9) 5.4.0 20160609 54 ubuntu:16.10 : Ok gcc (Ubuntu 6.2.0-5ubuntu12) 6.2.0 20161005 55 ubuntu:17.04 : Ok gcc (Ubuntu 6.3.0-12ubuntu2) 6.3.0 20170406 56 ubuntu:17.10 : Ok gcc (Ubuntu 7.2.0-8ubuntu3.2) 7.2.0 57 ubuntu:18.04 : Ok gcc (Ubuntu 7.3.0-16ubuntu3) 7.3.0 58 ubuntu:18.04-x-arm : Ok arm-linux-gnueabihf-gcc (Ubuntu/Linaro 7.3.0-16ubuntu3) 7.3.0 59 ubuntu:18.04-x-arm64 : Ok aarch64-linux-gnu-gcc (Ubuntu/Linaro 7.3.0-16ubuntu3) 7.3.0 60 ubuntu:18.04-x-powerpc : Ok powerpc-linux-gnu-gcc (Ubuntu 7.3.0-16ubuntu3) 7.3.0 61 ubuntu:18.04-x-powerpc64 : Ok powerpc64-linux-gnu-gcc (Ubuntu 7.3.0-16ubuntu3) 7.3.0 62 ubuntu:18.04-x-powerpc64el : Ok powerpc64le-linux-gnu-gcc (Ubuntu 7.3.0-16ubuntu3) 7.3.0 64 ubuntu:18.04-x-s390 : Ok s390x-linux-gnu-gcc (Ubuntu 7.3.0-16ubuntu3) 7.3.0 65 ubuntu:18.04-x-sparc64 : Ok sparc64-linux-gnu-gcc (Ubuntu 7.3.0-16ubuntu3) 7.3.0 66 ubuntu:18.10 : Ok gcc (Ubuntu 8.2.0-1ubuntu2) 8.2.0
# uname -a
Linux jouet 4.19.0-rc4-00022-gad3273d5f1b9 #1 SMP Mon Sep 17 17:18:22 -03 2018 x86_64 x86_64 x86_64 GNU/Linux
# git log --oneline -1
8e88c29b351e perf tools: Do not zero sample_id_all for group members
# perf version --build-options
perf version 4.19.g8e88c2
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: Use vfs_getname probe to get syscall args filenames : Ok
65: Check open filename arg using perf trace + vfs_getname: Ok
66: probe libc's inet_pton & backtrace it with ping : Ok
67: Add vfs_getname probe to get syscall args filenames : Ok $ make -C tools/perf build-test
make: Entering directory '/home/acme/git/perf/tools/perf'
- tarpkg: ./tests/perf-targz-src-pkg .
make_no_demangle_O: make NO_DEMANGLE=1
make_with_clangllvm_O: make LIBCLANGLLVM=1
make_no_scripts_O: make NO_LIBPYTHON=1 NO_LIBPERL=1
make_no_libbpf_O: make NO_LIBBPF=1
make_with_babeltrace_O: make LIBBABELTRACE=1
make_install_prefix_O: make install prefix=/tmp/krava
make_util_pmu_bison_o_O: make util/pmu-bison.o
make_clean_all_O: make clean all
make_no_gtk2_O: make NO_GTK2=1
make_doc_O: make doc
make_no_libdw_dwarf_unwind_O: make NO_LIBDW_DWARF_UNWIND=1
make_no_backtrace_O: make NO_BACKTRACE=1
make_no_slang_O: make NO_SLANG=1
make_no_libperl_O: make NO_LIBPERL=1
make_no_libnuma_O: make NO_LIBNUMA=1
make_install_bin_O: make install-bin
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_install_prefix_slash_O: make install prefix=/tmp/krava/
make_install_O: make install
make_no_libpython_O: make NO_LIBPYTHON=1
make_no_libunwind_O: make NO_LIBUNWIND=1
make_util_map_o_O: make util/map.o
make_no_libelf_O: make NO_LIBELF=1
make_debug_O: make DEBUG=1
make_tags_O: make tags
make_perf_o_O: make perf.o
make_help_O: make help
make_no_libbionic_O: make NO_LIBBIONIC=1
make_pure_O: make
make_no_libaudit_O: make NO_LIBAUDIT=1
make_no_ui_O: make NO_NEWT=1 NO_SLANG=1 NO_GTK2=1
make_no_newt_O: make NO_NEWT=1
make_no_auxtrace_O: make NO_AUXTRACE=1
make_static_O: make LDFLAGS=-static
OK
make: Leaving directory '/home/acme/git/perf/tools/perf'
$Arnaldo Carvalho de Melo
maintainerPATCH 1/18 tools headers barrier: Fix arm64 tools build failure wrt smp_load_{acquire,release}
From: Will Deacon <[email protected]>
Cheers for reporting this. I managed to reproduce the build failure with gcc version 6.3.0 20170516 (Debian 6.3.0-18+deb9u1).
The code in question is the arm64 versions of smp_load_acquire() and smp_store_release(). Unlike other architectures, these are not built around READ_ONCE() and WRITE_ONCE() since we have instructions we can use instead of fences. Bringing our macros up-to-date with those (i.e. tweaking the union initialisation and using the special "uXX_alias_t" types) appears to fix the issue for me.
Committer notes:
Testing it in the systems previously failing:
# time dm android-ndk:r12b-arm \
android-ndk:r15c-arm \
debian:experimental-x-arm64 \
ubuntu:14.04.4-x-linaro-arm64 \
ubuntu:16.04-x-arm \
ubuntu:16.04-x-arm64 \
ubuntu:18.04-x-arm \
ubuntu:18.04-x-arm64
1 android-ndk:r12b-arm : Ok arm-linux-androideabi-gcc (GCC) 4.9.x 20150123 (prerelease)
2 android-ndk:r15c-arm : Ok arm-linux-androideabi-gcc (GCC) 4.9.x 20150123 (prerelease)
3 debian:experimental-x-arm64 : Ok aarch64-linux-gnu-gcc (Debian 8.2.0-7) 8.2.0
4 ubuntu:14.04.4-x-linaro-arm64 : Ok aarch64-linux-gnu-gcc (Linaro GCC 5.5-2017.10) 5.5.0
5 ubuntu:16.04-x-arm : Ok arm-linux-gnueabihf-gcc (Ubuntu/Linaro 5.4.0-6ubuntu1~16.04.9) 5.4.0 20160609
6 ubuntu:16.04-x-arm64 : Ok aarch64-linux-gnu-gcc (Ubuntu/Linaro 5.4.0-6ubuntu1~16.04.9) 5.4.0 20160609
7 ubuntu:18.04-x-arm : Ok arm-linux-gnueabihf-gcc (Ubuntu/Linaro 7.3.0-27ubuntu1~18.04) 7.3.0
8 ubuntu:18.04-x-arm64 : Ok aarch64-linux-gnu-gcc (Ubuntu/Linaro 7.3.0-27ubuntu1~18.04) 7.3.0--- tools/arch/arm64/include/asm/barrier.h | 133 +++++++++++++++++---------------- 1 file changed, 67 insertions(+), 66 deletions(-)
tools/arch/arm64/include/asm/barrier.h +67 -66
@@ -14,74 +14,75 @@#define wmb () asm volatile("dmb ishst" ::: "memory")#define rmb () asm volatile("dmb ishld" ::: "memory") -#define smp_store_release (p, v) \ -do { \ - union { typeof(*p) __val; char __c[1]; } __u = \ - { .__val = (__force typeof(*p)) (v) }; \ - \ - switch (sizeof(*p)) { \ - case 1: \ - asm volatile ("stlrb %w1, %0" \ - : "=Q" (*p) \ - : "r" (*(__u8 *)__u.__c) \ - : "memory"); \ - break; \ - case 2: \ - asm volatile ("stlrh %w1, %0" \ - : "=Q" (*p) \ - : "r" (*(__u16 *)__u.__c) \ - : "memory"); \ - break; \ - case 4: \ - asm volatile ("stlr %w1, %0" \ - : "=Q" (*p) \ - : "r" (*(__u32 *)__u.__c) \ - : "memory"); \ - break; \ - case 8: \ - asm volatile ("stlr %1, %0" \ - : "=Q" (*p) \ - : "r" (*(__u64 *)__u.__c) \ - : "memory"); \ - break; \ - default: \ -/* Only to shut up gcc ... */ \ -mb (); \ -break ; \ - } \ +#define smp_store_release (p, v) \ +do { \ + union { typeof(*p) __val; char __c[1]; } __u = \ + { .__val = (v) }; \ + \ + switch (sizeof(*p)) { \ + case 1: \ + asm volatile ("stlrb %w1, %0" \ + : "=Q" (*p) \ + : "r" (*(__u8_alias_t *)__u.__c) \ + : "memory"); \ + break; \ + case 2: \ + asm volatile ("stlrh %w1, %0" \ + : "=Q" (*p) \ + : "r" (*(__u16_alias_t *)__u.__c) \ + : "memory"); \ + break; \ + case 4: \ + asm volatile ("stlr %w1, %0" \ + : "=Q" (*p) \ + : "r" (*(__u32_alias_t *)__u.__c) \ + : "memory"); \ + break; \ + case 8: \ + asm volatile ("stlr %1, %0" \ + : "=Q" (*p) \ + : "r" (*(__u64_alias_t *)__u.__c) \ + : "memory"); \ + break; \ + default: \ +/* Only to shut up gcc ... */ \ +mb (); \ +break ; \ + } \ } while (0) -#define smp_load_acquire (p) \ -({ \ - union { typeof(*p) __val; char __c[1]; } __u; \ - \ - switch (sizeof(*p)) { \ - case 1: \ - asm volatile ("ldarb %w0, %1" \ - : "=r" (*(__u8 *)__u.__c) \ - : "Q" (*p) : "memory"); \ - break; \ - case 2: \ - asm volatile ("ldarh %w0, %1" \ - : "=r" (*(__u16 *)__u.__c) \ - : "Q" (*p) : "memory"); \ - break; \ - case 4: \ - asm volatile ("ldar %w0, %1" \ - : "=r" (*(__u32 *)__u.__c) \ - : "Q" (*p) : "memory"); \ - break; \ - case 8: \ - asm volatile ("ldar %0, %1" \ - : "=r" (*(__u64 *)__u.__c) \ - : "Q" (*p) : "memory"); \ - break; \ - default: \ -/* Only to shut up gcc ... */ \ -mb (); \ -break ; \ - } \ - __u.__val; \ +#define smp_load_acquire (p) \ +({ \ + union { typeof(*p) __val; char __c[1]; } __u = \ + { .__c = { 0 } }; \ + \ + switch (sizeof(*p)) { \ + case 1: \ + asm volatile ("ldarb %w0, %1" \ + : "=r" (*(__u8_alias_t *)__u.__c) \ + : "Q" (*p) : "memory"); \ + break; \ + case 2: \ + asm volatile ("ldarh %w0, %1" \ + : "=r" (*(__u16_alias_t *)__u.__c) \ + : "Q" (*p) : "memory"); \ + break; \ + case 4: \ + asm volatile ("ldar %w0, %1" \ + : "=r" (*(__u32_alias_t *)__u.__c) \ + : "Q" (*p) : "memory"); \ + break; \ + case 8: \ + asm volatile ("ldar %0, %1" \ + : "=r" (*(__u64_alias_t *)__u.__c) \ + : "Q" (*p) : "memory"); \ + break; \ + default: \ +/* Only to shut up gcc ... */ \ +mb (); \ +break ; \ + } \ + __u.__val; \ })#endif /* _TOOLS_LINUX_ASM_AARCH64_BARRIER_H */
Signature · 1 line
2.14.4
Arnaldo Carvalho de Melo
maintainerPATCH 2/18 perf examples bpf: Start augmenting raw_syscalls:sys_{start,exit}
In reply to Arnaldo Carvalho de MeloFrom: Arnaldo Carvalho de Melo <[email protected]>
The previous approach of attaching to each syscall showed how it is possible to augment tracepoints and use that augmentation, pointer payloads, in the existing beautifiers in 'perf trace', but for a more general solution we now will try to augment the main raw_syscalls:sys_{enter,exit} syscalls, and then pass instructions in maps so that it knows which syscalls and which pointer contents, and how many bytes for each of the arguments should be copied.
Start with just the bare minimum to collect what is provided by those two tracepoints via the __augmented_syscalls__ map + bpf-output perf event, which results in perf trace showing them without connecting enter+exit:
# perf trace -e tools/perf/examples/bpf/augmented_raw_syscalls.c sleep 1
0.000 sleep/11563 raw_syscalls:sys_exit:NR 59 = 0
0.019 ( ): sleep/11563 brk() ...
0.021 sleep/11563 raw_syscalls:sys_exit:NR 12 = 94682642325504
0.033 ( ): sleep/11563 access(filename:, mode: R) ...
0.037 sleep/11563 raw_syscalls:sys_exit:NR 21 = -2
0.041 ( ): sleep/11563 openat(dfd: CWD, filename: , flags: CLOEXEC) ...
0.044 sleep/11563 raw_syscalls:sys_exit:NR 257 = 3
0.045 ( ): sleep/11563 fstat(fd: 3, statbuf: 0x7ffdbf7119b0) ...
0.046 sleep/11563 raw_syscalls:sys_exit:NR 5 = 0
0.047 ( ): sleep/11563 mmap(len: 103334, prot: READ, flags: PRIVATE, fd: 3) ...
0.049 sleep/11563 raw_syscalls:sys_exit:NR 9 = 140196285493248
0.050 ( ): sleep/11563 close(fd: 3) ...
0.051 sleep/11563 raw_syscalls:sys_exit:NR 3 = 0
0.059 ( ): sleep/11563 openat(dfd: CWD, filename: , flags: CLOEXEC) ...
0.062 sleep/11563 raw_syscalls:sys_exit:NR 257 = 3
0.063 ( ): sleep/11563 read(fd: 3, buf: 0x7ffdbf711b78, count: 832) ...
0.065 sleep/11563 raw_syscalls:sys_exit:NR 0 = 832
0.066 ( ): sleep/11563 fstat(fd: 3, statbuf: 0x7ffdbf711a10) ...
0.067 sleep/11563 raw_syscalls:sys_exit:NR 5 = 0
0.068 ( ): sleep/11563 mmap(len: 8192, prot: READ|WRITE, flags: PRIVATE|ANONYMOUS) ...
0.070 sleep/11563 raw_syscalls:sys_exit:NR 9 = 140196285485056
0.073 ( ): sleep/11563 mmap(len: 3889792, prot: EXEC|READ, flags: PRIVATE|DENYWRITE, fd: 3) ...
0.076 sleep/11563 raw_syscalls:sys_exit:NR 9 = 140196279463936
0.077 ( ): sleep/11563 mprotect(start: 0x7f81fd8a8000, len: 2093056) ...
0.083 sleep/11563 raw_syscalls:sys_exit:NR 10 = 0
0.084 ( ): sleep/11563 mmap(addr: 0x7f81fdaa7000, len: 24576, prot: READ|WRITE, flags: PRIVATE|FIXED|DENYWRITE, fd: 3, off: 1753088) ...
0.088 sleep/11563 raw_syscalls:sys_exit:NR 9 = 140196283314176
0.091 ( ): sleep/11563 mmap(addr: 0x7f81fdaad000, len: 14976, prot: READ|WRITE, flags: PRIVATE|FIXED|ANONYMOUS) ...
0.093 sleep/11563 raw_syscalls:sys_exit:NR 9 = 140196283338752
0.097 ( ): sleep/11563 close(fd: 3) ...
0.098 sleep/11563 raw_syscalls:sys_exit:NR 3 = 0
0.107 ( ): sleep/11563 arch_prctl(option: 4098, arg2: 140196285490432) ...
0.108 sleep/11563 raw_syscalls:sys_exit:NR 158 = 0
0.143 ( ): sleep/11563 mprotect(start: 0x7f81fdaa7000, len: 16384, prot: READ) ...
0.146 sleep/11563 raw_syscalls:sys_exit:NR 10 = 0
0.157 ( ): sleep/11563 mprotect(start: 0x561d037e7000, len: 4096, prot: READ) ...
0.160 sleep/11563 raw_syscalls:sys_exit:NR 10 = 0
0.163 ( ): sleep/11563 mprotect(start: 0x7f81fdcd5000, len: 4096, prot: READ) ...
0.165 sleep/11563 raw_syscalls:sys_exit:NR 10 = 0
0.166 ( ): sleep/11563 munmap(addr: 0x7f81fdcbb000, len: 103334) ...
0.174 sleep/11563 raw_syscalls:sys_exit:NR 11 = 0
0.216 ( ): sleep/11563 brk() ...
0.217 sleep/11563 raw_syscalls:sys_exit:NR 12 = 94682642325504
0.217 ( ): sleep/11563 brk(brk: 0x561d05453000) ...
0.219 sleep/11563 raw_syscalls:sys_exit:NR 12 = 94682642460672
0.220 ( ): sleep/11563 brk() ...
0.221 sleep/11563 raw_syscalls:sys_exit:NR 12 = 94682642460672
0.224 ( ): sleep/11563 open(filename: , flags: CLOEXEC) ...
0.228 sleep/11563 raw_syscalls:sys_exit:NR 2 = 3
0.229 ( ): sleep/11563 fstat(fd: 3, statbuf: 0x7f81fdaacaa0) ...
0.230 sleep/11563 raw_syscalls:sys_exit:NR 5 = 0
0.231 ( ): sleep/11563 mmap(len: 113045344, prot: READ, flags: PRIVATE, fd: 3) ...
0.234 sleep/11563 raw_syscalls:sys_exit:NR 9 = 140196166418432
0.237 ( ): sleep/11563 close(fd: 3) ...
0.238 sleep/11563 raw_syscalls:sys_exit:NR 3 = 0
0.262 ( ): sleep/11563 nanosleep(rqtp: 0x7ffdbf7126f0) ...
1000.399 sleep/11563 raw_syscalls:sys_exit:NR 35 = 0
1000.440 ( ): sleep/11563 close(fd: 1) ...
1000.447 sleep/11563 raw_syscalls:sys_exit:NR 3 = 0
1000.454 ( ): sleep/11563 close(fd: 2) ...
1000.468 ( ): sleep/11563 exit_group( )
#In the next csets we'll connect those events to the existing enter/exit raw_syscalls handlers in 'perf trace', just like we did with the syscalls:sys_{enter,exit}_* tracepoints.
--- tools/perf/examples/bpf/augmented_raw_syscalls.c | 59 ++++++++++++++++++++++++ 1 file changed, 59 insertions(+) create mode 100644 tools/perf/examples/bpf/augmented_raw_syscalls.c
tools/perf/examples/bpf/augmented_raw_syscalls.c new file +59 -0
@@ -0,0 +1,59 @@ +// SPDX-License-Identifier: GPL-2.0 +/* +* Augment the raw_syscalls tracepoints with the contents of the pointer arguments. +* +* Test it with: +* +* perf trace -e tools/perf/examples/bpf/augmented_raw_syscalls.c cat /etc/passwd > /dev/null +* +* This exactly matches what is marshalled into the raw_syscall:sys_enter +* payload expected by the 'perf trace' beautifiers. +* +* For now it just uses the existing tracepoint augmentation code in 'perf +* trace', in the next csets we'll hook up these with the sys_enter/sys_exit +* code that will combine entry/exit in a strace like way. +*/ + +#include <stdio.h> +#include <linux/socket.h> + +/* bpf-output associated map */ +struct bpf_map SEC("maps") __augmented_syscalls__ = { + .type = BPF_MAP_TYPE_PERF_EVENT_ARRAY, + .key_size = sizeof(int), + .value_size = sizeof(u32), + .max_entries = __NR_CPUS__, +}; + +struct syscall_enter_args { +unsigned long long common_tp_fields; +long syscall_nr; +unsigned long args[6 ]; +}; + +struct syscall_exit_args { +unsigned long long common_tp_fields; +long syscall_nr; +long ret; +}; + +SEC("raw_syscalls:sys_enter") +int sys_enter (struct syscall_enter_args *args) +{ +struct { +struct syscall_enter_args args; + } augmented_args; +unsigned int len =sizeof (augmented_args); + +probe_read (&augmented_args.args,sizeof (augmented_args.args), args); +perf_event_output (args, &__augmented_syscalls__,BPF_F_CURRENT_CPU , &augmented_args, len); +return 0 ; +} + +SEC("raw_syscalls:sys_exit") +int sys_exit (struct syscall_exit_args *args) +{ +return 1 ;/* 0 as soon as we start copying data returned by the kernel, e.g. 'read' */ +} + +license (GPL );
Signature · 1 line
2.14.4
Arnaldo Carvalho de Melo
maintainerPATCH 3/18 perf trace: When augmenting raw_syscalls plug raw_syscalls:sys_exit too
In reply to Arnaldo Carvalho de MeloFrom: Arnaldo Carvalho de Melo <[email protected]>
With just this commit we get to support all syscalls via hooking raw_syscalls:sys_{enter,exit} to the trace__sys_{enter,exit} routines to combine, strace-like, those tracepoints.
# trace -e tools/perf/examples/bpf/augmented_raw_syscalls.c sleep 1
? ( ): sleep/31680 ... [continued]: execve()) = 0
0.043 ( 0.004 ms): sleep/31680 brk() = 0x55652a851000
0.070 ( 0.009 ms): sleep/31680 access(filename:, mode: R) = -1 ENOENT No such file or directory
0.087 ( 0.006 ms): sleep/31680 openat(dfd: CWD, filename: , flags: CLOEXEC) = 3
0.096 ( 0.003 ms): sleep/31680 fstat(fd: 3, statbuf: 0x7ffc5269e190) = 0
0.101 ( 0.005 ms): sleep/31680 mmap(len: 103334, prot: READ, flags: PRIVATE, fd: 3) = 0x7f709c239000
0.109 ( 0.002 ms): sleep/31680 close(fd: 3) = 0
0.126 ( 0.006 ms): sleep/31680 openat(dfd: CWD, filename: , flags: CLOEXEC) = 3
0.135 ( 0.003 ms): sleep/31680 read(fd: 3, buf: 0x7ffc5269e358, count: 832) = 832
0.141 ( 0.002 ms): sleep/31680 fstat(fd: 3, statbuf: 0x7ffc5269e1f0) = 0
0.146 ( 0.005 ms): sleep/31680 mmap(len: 8192, prot: READ|WRITE, flags: PRIVATE|ANONYMOUS) = 0x7f709c237000
0.159 ( 0.007 ms): sleep/31680 mmap(len: 3889792, prot: EXEC|READ, flags: PRIVATE|DENYWRITE, fd: 3) = 0x7f709bc79000
0.168 ( 0.009 ms): sleep/31680 mprotect(start: 0x7f709be26000, len: 2093056) = 0
0.179 ( 0.010 ms): sleep/31680 mmap(addr: 0x7f709c025000, len: 24576, prot: READ|WRITE, flags: PRIVATE|FIXED|DENYWRITE, fd: 3, off: 1753088) = 0x7f709c025000
0.196 ( 0.005 ms): sleep/31680 mmap(addr: 0x7f709c02b000, len: 14976, prot: READ|WRITE, flags: PRIVATE|FIXED|ANONYMOUS) = 0x7f709c02b000
0.210 ( 0.002 ms): sleep/31680 close(fd: 3) = 0
0.230 ( 0.002 ms): sleep/31680 arch_prctl(option: 4098, arg2: 140121632638208) = 0
0.306 ( 0.009 ms): sleep/31680 mprotect(start: 0x7f709c025000, len: 16384, prot: READ) = 0
0.338 ( 0.005 ms): sleep/31680 mprotect(start: 0x556529607000, len: 4096, prot: READ) = 0
0.348 ( 0.005 ms): sleep/31680 mprotect(start: 0x7f709c253000, len: 4096, prot: READ) = 0
0.356 ( 0.019 ms): sleep/31680 munmap(addr: 0x7f709c239000, len: 103334) = 0
0.463 ( 0.002 ms): sleep/31680 brk() = 0x55652a851000
0.468 ( 0.004 ms): sleep/31680 brk(brk: 0x55652a872000) = 0x55652a872000
0.474 ( 0.002 ms): sleep/31680 brk() = 0x55652a872000
0.484 ( 0.008 ms): sleep/31680 open(filename: , flags: CLOEXEC) = 3
0.497 ( 0.002 ms): sleep/31680 fstat(fd: 3, statbuf: 0x7f709c02aaa0) = 0
0.501 ( 0.006 ms): sleep/31680 mmap(len: 113045344, prot: READ, flags: PRIVATE, fd: 3) = 0x7f70950aa000
0.514 ( 0.002 ms): sleep/31680 close(fd: 3) = 0
0.554 (1000.140 ms): sleep/31680 nanosleep(rqtp: 0x7ffc5269eed0) = 0
1000.734 ( 0.007 ms): sleep/31680 close(fd: 1) = 0
1000.748 ( 0.004 ms): sleep/31680 close(fd: 2) = 0
1000.769 ( ): sleep/31680 exit_group()
#Now to allow selecting which syscalls should be traced, using a map.
--- tools/perf/builtin-trace.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
tools/perf/builtin-trace.c +2 -1
@@ -3501,7 +3501,8 @@ int cmd_trace(int argc, const char **argv) evsel->handler = trace__sys_enter;evlist__for_each_entry (trace.evlist, evsel) { -if (strstarts (perf_evsel__name (evsel),"syscalls:sys_exit_" )) { +if (strstarts (perf_evsel__name (evsel),"syscalls:sys_exit_" ) || +strcmp (perf_evsel__name (evsel),"raw_syscalls:sys_exit" ) ==0 ) {perf_evsel__init_augmented_syscall_tp (evsel);perf_evsel__init_augmented_syscall_tp_ret (evsel); evsel->handler = trace__sys_exit;
Signature · 1 line
2.14.4
Arnaldo Carvalho de Melo
maintainerPATCH 4/18 perf trace: Fix setting of augmented payload when using eBPF + raw_syscalls
In reply to Arnaldo Carvalho de MeloFrom: Arnaldo Carvalho de Melo <[email protected]>
For now with BPF raw_augmented we hook into raw_syscalls:sys_enter and there we get all 6 syscall args plus the tracepoint common fields (sizeof(long)) and the syscall_nr (another long). So we check if that is the case and if so don't look after the sc->args_size, but always after the full raw_syscalls:sys_enter payload, which is fixed.
We'll revisit this later to pass s->args_size to the BPF augmenter (now tools/perf/examples/bpf/augmented_raw_syscalls.c, so that it copies only what we need for each syscall, like what happens when we use syscalls:sys_enter_NAME, so that we reduce the kernel/userspace traffic to just what is needed for each syscall.
--- tools/perf/builtin-trace.c | 37 ++++++++++++++++++++++++++++++------- 1 file changed, 30 insertions(+), 7 deletions(-)
tools/perf/builtin-trace.c +30 -7
@@ -108,6 +108,7 @@ struct trace { } stats;unsigned int max_stack;unsigned int min_stack; +bool raw_augmented_syscalls;bool not_ev_qualifier;bool live;bool full_time;
@@ -1724,13 +1725,28 @@ static int trace__fprintf_sample(struct trace *trace, struct perf_evsel *evsel,return printed; } -static void *syscall__augmented_args (struct syscall *sc,struct perf_sample *sample,int *augmented_args_size) +static void *syscall__augmented_args (struct syscall *sc,struct perf_sample *sample,int *augmented_args_size,bool raw_augmented) {void *augmented_args =NULL ; +/* +* For now with BPF raw_augmented we hook into raw_syscalls:sys_enter +* and there we get all 6 syscall args plus the tracepoint common +* fields (sizeof(long)) and the syscall_nr (another long). So we check +* if that is the case and if so don't look after the sc->args_size, +* but always after the full raw_syscalls:sys_enter payload, which is +* fixed. +* +* We'll revisit this later to pass s->args_size to the BPF augmenter +* (now tools/perf/examples/bpf/augmented_raw_syscalls.c, so that it +* copies only what we need for each syscall, like what happens when we +* use syscalls:sys_enter_NAME, so that we reduce the kernel/userspace +* traffic to just what is needed for each syscall. +*/ +int args_size = raw_augmented ? (8 * (int )sizeof (long )) : sc->args_size; - *augmented_args_size = sample->raw_size - sc->args_size; + *augmented_args_size = sample->raw_size - args_size;if (*augmented_args_size >0 ) - augmented_args = sample->raw_data + sc->args_size; + augmented_args = sample->raw_data + args_size;return augmented_args; }
@@ -1780,7 +1796,7 @@ static int trace__sys_enter(struct trace *trace, struct perf_evsel *evsel,* here and avoid using augmented syscalls when the evsel is the raw_syscalls one. */ if (evsel != trace->syscalls.events.sys_enter) - augmented_args =syscall__augmented_args (sc, sample, &augmented_args_size); + augmented_args =syscall__augmented_args (sc, sample, &augmented_args_size, trace->raw_augmented_syscalls); ttrace->entry_time = sample->time; msg = ttrace->entry_str; printed +=scnprintf (msg + printed, trace__entry_str_size - printed,"%s(" , sc->name);
@@ -1833,7 +1849,7 @@ static int trace__fprintf_sys_enter(struct trace *trace, struct perf_evsel *evse goto out_put; args =perf_evsel__sc_tp_ptr (evsel, args, sample); - augmented_args =syscall__augmented_args (sc, sample, &augmented_args_size); + augmented_args =syscall__augmented_args (sc, sample, &augmented_args_size, trace->raw_augmented_syscalls);syscall__scnprintf_args (sc, msg,sizeof (msg), args, augmented_args, augmented_args_size, trace, thread);fprintf (trace->output,"%s" , msg); err =0 ;
@@ -3501,8 +3517,15 @@ int cmd_trace(int argc, const char **argv) evsel->handler = trace__sys_enter;evlist__for_each_entry (trace.evlist, evsel) { -if (strstarts (perf_evsel__name (evsel),"syscalls:sys_exit_" ) || -strcmp (perf_evsel__name (evsel),"raw_syscalls:sys_exit" ) ==0 ) { +bool raw_syscalls_sys_exit =strcmp (perf_evsel__name (evsel),"raw_syscalls:sys_exit" ) ==0 ; + +if (raw_syscalls_sys_exit) { + trace.raw_augmented_syscalls = true; + goto init_augmented_syscall_tp; + } + +if (strstarts (perf_evsel__name (evsel),"syscalls:sys_exit_" )) { +init_augmented_syscall_tp:perf_evsel__init_augmented_syscall_tp (evsel);perf_evsel__init_augmented_syscall_tp_ret (evsel); evsel->handler = trace__sys_exit;
Signature · 1 line
2.14.4
Arnaldo Carvalho de Melo
maintainerPATCH 5/18 perf augmented_syscalls: Start collecting pathnames in the BPF program
In reply to Arnaldo Carvalho de MeloFrom: Arnaldo Carvalho de Melo <[email protected]>
This is the start of having the raw_syscalls:sys_enter BPF handler collecting pointer arguments, namely pathnames, and with two syscalls that have that pointer in different arguments, "open" as it as its first argument, "openat" as the second.
With this in place the existing beautifiers in 'perf trace' works, those args are shown instead of just the pointer that comes with the syscalls tracepoints.
This also serves to show and document pitfalls in the process of using just that place in the kernel (raw_syscalls:sys_enter) plus tables provided by userspace to collect syscall pointer arguments.
One is the need to use a barrier, as suggested by Edward, to avoid clang optimizations that make the kernel BPF verifier to refuse loading our pointer contents collector.
The end result should be a generic eBPF program that works in all architectures, with the differences amongst archs resolved by the userspace component, 'perf trace', that should get all its tables created automatically from the kernel components where they are defined, via string table constructors for things not expressed in BTF/DWARF (enums, structs, etc), and otherwise using those observability files (BTF).
--- tools/perf/examples/bpf/augmented_raw_syscalls.c | 72 ++++++++++++++++++++++++ 1 file changed, 72 insertions(+)
tools/perf/examples/bpf/augmented_raw_syscalls.c +72 -0
@@ -37,15 +37,87 @@ struct syscall_exit_args {long ret; }; +struct augmented_filename { +unsigned int size; +int reserved; +char value[256 ]; +}; + +#define SYS_OPEN 2 +#define SYS_OPENAT 257 + SEC("raw_syscalls:sys_enter")int sys_enter (struct syscall_enter_args *args) {struct {struct syscall_enter_args args; +struct augmented_filename filename; } augmented_args;unsigned int len =sizeof (augmented_args); +const void *filename_arg =NULL ;probe_read (&augmented_args.args,sizeof (augmented_args.args), args); +/* +* Yonghong and Edward Cree sayz: +* +* https://www.spinics.net/lists/netdev/msg531645.html +* +* >> R0=inv(id=0) R1=inv2 R6=ctx(id=0,off=0,imm=0) R7=inv64 R10=fp0,call_-1 +* >> 10: (bf) r1 = r6 +* >> 11: (07) r1 += 16 +* >> 12: (05) goto pc+2 +* >> 15: (79) r3 = *(u64 *)(r1 +0) +* >> dereference of modified ctx ptr R1 off=16 disallowed +* > Aha, we at least got a different error message this time. +* > And indeed llvm has done that optimisation, rather than the more obvious +* > 11: r3 = *(u64 *)(r1 +16) +* > because it wants to have lots of reads share a single insn. You may be able +* > to defeat that optimisation by adding compiler barriers, idk. Maybe someone +* > with llvm knowledge can figure out how to stop it (ideally, llvm would know +* > when it's generating for bpf backend and not do that). -O0? ¯\_(ツ)_/¯ +* +* The optimization mostly likes below: +* +* br1: +* ... +* r1 += 16 +* goto merge +* br2: +* ... +* r1 += 20 +* goto merge +* merge: +* *(u64 *)(r1 + 0) +* +* The compiler tries to merge common loads. There is no easy way to +* stop this compiler optimization without turning off a lot of other +* optimizations. The easiest way is to add barriers: +* +* __asm__ __volatile__("": : :"memory") +* +* after the ctx memory access to prevent their down stream merging. +*/ +switch (augmented_args.args.syscall_nr) { +case SYS_OPEN : filename_arg = (const void *)args->args[0 ]; + __asm__ __volatile__("" : : :"memory" ); +break ; +case SYS_OPENAT : filename_arg = (const void *)args->args[1 ]; +break ; + } + +if (filename_arg !=NULL ) { + augmented_args.filename.reserved =0 ; + augmented_args.filename.size =probe_read_str (&augmented_args.filename.value, +sizeof (augmented_args.filename.value), + filename_arg); +if (augmented_args.filename.size <sizeof (augmented_args.filename.value)) { + len -=sizeof (augmented_args.filename.value) - augmented_args.filename.size; + len &=sizeof (augmented_args.filename.value) -1 ; + } + }else { + len =sizeof (augmented_args.args); + } +perf_event_output (args, &__augmented_syscalls__,BPF_F_CURRENT_CPU , &augmented_args, len);return 0 ; }
Signature · 1 line
2.14.4
Arnaldo Carvalho de Melo
maintainerPATCH 6/18 perf evlist: Move perf_evsel__reset_weak_group into evlist
In reply to Arnaldo Carvalho de MeloFrom: Andi Kleen <[email protected]>
- Move the function from builtin-stat to evlist for reuse
- Rename to evlist to match purpose better
- Pass the evlist as first argument.
- No functional changes
--- tools/perf/builtin-stat.c | 28 +--------------------------- tools/perf/util/evlist.c | 27 +++++++++++++++++++++++++++ tools/perf/util/evlist.h | 3 +++ 3 files changed, 31 insertions(+), 27 deletions(-)
tools/perf/builtin-stat.c +1 -27
@@ -383,32 +383,6 @@ static bool perf_evsel__should_store_id(struct perf_evsel *counter)return STAT_RECORD || counter->attr.read_format &PERF_FORMAT_ID ; } -static struct perf_evsel *perf_evsel__reset_weak_group (struct perf_evsel *evsel) -{ -struct perf_evsel *c2, *leader; -bool is_open = true; - - leader = evsel->leader; -pr_debug ("Weak group for %s/%d failed\n" , - leader->name, leader->nr_members); - -/* -* for_each_group_member doesn't work here because it doesn't -* include the first entry. -*/ -evlist__for_each_entry (evsel_list, c2) { -if (c2 == evsel) - is_open = false; -if (c2->leader == leader) { -if (is_open) -perf_evsel__close (c2); - c2->leader = c2; - c2->nr_members =0 ; - } - } -return leader; -} -static bool is_target_alive (struct target *_target,struct thread_map *threads) {
@@ -477,7 +451,7 @@ static int __run_perf_stat(int argc, const char **argv, int run_idx)if ((errno ==EINVAL || errno ==EBADF ) && counter->leader != counter && counter->weak_group) { - counter =perf_evsel__reset_weak_group (counter); + counter =perf_evlist__reset_weak_group (evsel_list, counter); goto try_again; }
tools/perf/util/evlist.c +27 -0
@@ -1810,3 +1810,30 @@ void perf_evlist__force_leader(struct perf_evlist *evlist) leader->forced_leader = true; } } + +struct perf_evsel *perf_evlist__reset_weak_group (struct perf_evlist *evsel_list, +struct perf_evsel *evsel) +{ +struct perf_evsel *c2, *leader; +bool is_open = true; + + leader = evsel->leader; +pr_debug ("Weak group for %s/%d failed\n" , + leader->name, leader->nr_members); + +/* +* for_each_group_member doesn't work here because it doesn't +* include the first entry. +*/ +evlist__for_each_entry (evsel_list, c2) { +if (c2 == evsel) + is_open = false; +if (c2->leader == leader) { +if (is_open) +perf_evsel__close (c2); + c2->leader = c2; + c2->nr_members =0 ; + } + } +return leader; +}
tools/perf/util/evlist.h +3 -0
@@ -312,4 +312,7 @@ bool perf_evlist__exclude_kernel(struct perf_evlist *evlist);void perf_evlist__force_leader (struct perf_evlist *evlist); +struct perf_evsel *perf_evlist__reset_weak_group (struct perf_evlist *evlist, +struct perf_evsel *evsel); +#endif /* __PERF_EVLIST_H */
Signature · 1 line
2.14.4
Arnaldo Carvalho de Melo
maintainerPATCH 7/18 perf record: Support weak groups
In reply to Arnaldo Carvalho de MeloFrom: Andi Kleen <[email protected]>
Implement a weak group fallback for 'perf record', similar to the existing 'perf stat' support. This allows to use groups that might be longer than the available counters without failing.
Before:
$ perf record -e '{cycles,cache-misses,cache-references,cpu_clk_unhalted.thread,cycles,cycles,cycles}' -a sleep 1
Error:
The sys_perf_event_open() syscall returned with 22 (Invalid argument) for event (cycles).
/bin/dmesg | grep -i perf may provide additional information.After:
$ ./perf record -e '{cycles,cache-misses,cache-references,cpu_clk_unhalted.thread,cycles,cycles,cycles}:W' -a sleep 1
WARNING: No sample_id_all support, falling back to unordered processing
[ perf record: Woken up 3 times to write data ]
[ perf record: Captured and wrote 8.136 MB perf.data (134069 samples) ]--- tools/perf/Documentation/perf-list.txt | 1 - tools/perf/builtin-record.c | 7 ++++++- 2 files changed, 6 insertions(+), 2 deletions(-)
tools/perf/Documentation/perf-list.txt +0 -1
@@ -55,7 +55,6 @@ counted. The following modifiers exist: S - read sample value (PERF_SAMPLE_READ) D - pin the event to the PMU W - group is weak and will fallback to non-group if not schedulable, - only supported in 'perf stat' for now. The 'p' modifier can be used for specifying how precise the instruction address should be. The 'p' modifier can be specified multiple times:
tools/perf/builtin-record.c +6 -1
@@ -391,7 +391,12 @@ static int record__open(struct record *rec)ui__warning ("%s\n" , msg); goto try_again; } - +if ((errno ==EINVAL || errno ==EBADF ) && + pos->leader != pos && + pos->weak_group) { + pos =perf_evlist__reset_weak_group (evlist, pos); + goto try_again; + } rc = -errno;perf_evsel__open_strerror (pos, &opts->target, errno, msg,sizeof (msg));
Signature · 1 line
2.14.4
Arnaldo Carvalho de Melo
maintainerPATCH 8/18 perf stat: Handle different PMU names with common prefix
In reply to Arnaldo Carvalho de MeloFrom: Thomas Richter <[email protected]>
On s390 the CPU Measurement Facility for counters now supports 2 PMUs named cpum_cf (CPU Measurement Facility for counters) and cpum_cf_diag (CPU Measurement Facility for diagnostic counters) for one and the same CPU.
Running command
[root@s35lp76 perf]# ./perf stat -e tx_c_tend \ -- ~/mytests/cf-tx-events 1
Measuring transactions
TX_C_TABORT_NO_SPECIAL: 0 expected:0
TX_C_TABORT_SPECIAL: 0 expected:0
TX_C_TEND: 1 expected:1
TX_NC_TABORT: 11 expected:11
TX_NC_TEND: 1 expected:1
Performance counter stats for '/root/mytests/cf-tx-events 1':
2 tx_c_tend
0.002120091 seconds time elapsed
0.000121000 seconds user
0.002127000 seconds sys[root@s35lp76 perf]#
displays output which is unexpected (and wrong):
2 tx_c_tend
The test program definitely triggers only one transaction, as shown in line 'TX_C_TEND: 1 expected:1'.
This is caused by the following call sequence:
pmu_lookup() scans and installs a PMU. +--> pmu_aliases() parses all aliases in directory
.../<pmu-name>/events/* which are file names.
+--> pmu_aliases_parse() Read each file in directory and create
an new alias entry. This is done with
+--> perf_pmu__new_alias() and
+--> __perf_pmu__new_alias() which also check for
identical alias names.After pmu_aliases() returns, a complete list of event names for this pmu has been created. Now function
pmu_add_cpu_aliases() is called to add the events listed in the json
| files to the alias list of the cpu.
+--> perf_pmu__find_map() Returns a pointer to the json events.
Now function pmu_add_cpu_aliases() scans through all events listed in the JSON files for this CPU.
Each json event pmu name is compared with the current PMU being built up and if they mismatch, the json event is added to the current PMUs alias list.
To avoid duplicate entries the following comparison is done:
if (!is_arm_pmu_core(name)) {
pname = pe->pmu ? pe->pmu : "cpu";
if (strncmp(pname, name, strlen(pname)))
continue;
}The culprit is the strncmp() function.
Using current s390 PMU naming, the first PMU is 'cpum_cf' and a long list of events is added, among them 'tx_c_tend'
When the second PMU named 'cpum_cf_diag' is added, only one event named 'CF_DIAG' is added by the pmu_aliases() function.
Now function pmu_add_cpu_aliases() is invoked for PMU 'cpum_cf_diag'. Since the CPUID string is the same for both PMUs, json file events for PMU named 'cpum_cf' are added to the PMU 'cpm_cf_diag'
This happens because the strncmp() actually compares:
strncmp("cpum_cf", "cpum_cf_diag", 6);The first parameter is the pmu name taken from the event in the json file. The second parameter is the pmu name of the PMU currently being built.
They are different, but the length of the compare only tests the common prefix and this returns 0(true) when it should return false.
Now all events for PMU cpum_cf are added to the alias list for pmu cpum_cf_diag.
Later on in function parse_events_add_pmu() the event 'tx_c_end' is searched in all available PMUs and found twice, adding it two times to the evsel_list global variable which is the root of all events. This results in a counter value of 2 instead of 1.
Output with this patch:
[root@s35lp76 perf]# ./perf stat -e tx_c_tend \ -- ~/mytests/cf-tx-events 1
Measuring transactions
TX_C_TABORT_NO_SPECIAL: 0 expected:0
TX_C_TABORT_SPECIAL: 0 expected:0
TX_C_TEND: 1 expected:1
TX_NC_TABORT: 11 expected:11
TX_NC_TEND: 1 expected:1
Performance counter stats for '/root/mytests/cf-tx-events 1':
1 tx_c_tend
0.001815365 seconds time elapsed
0.000123000 seconds user
0.001756000 seconds sys[root@s35lp76 perf]#
--- tools/perf/util/pmu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
tools/perf/util/pmu.c +1 -1
@@ -773,7 +773,7 @@ static void pmu_add_cpu_aliases(struct list_head *head, struct perf_pmu *pmu)if (!is_arm_pmu_core (name)) { pname = pe->pmu ? pe->pmu :"cpu" ; -if (strncmp (pname, name,strlen (pname))) +if (strcmp (pname, name))continue ; }
Signature · 1 line
2.14.4
Arnaldo Carvalho de Melo
maintainerPATCH 9/18 perf top: Display the LBR stats in callchain entry
In reply to Arnaldo Carvalho de MeloFrom: Jin Yao <[email protected]>
'perf report' has supported the displaying of LBR stats (such as cycles, predicted%) in callchain entry.
For example:
$ perf report --branch-history --stdio
--1.01%--intel_idle mwait.h:29
intel_idle cpufeature.h:164 (cycles:5)
intel_idle cpufeature.h:164 (predicted:76.4%)
intel_idle mwait.h:102 (cycles:41)
intel_idle current.h:15While 'perf top' doesn't support that.
For example:
$ perf top -a -b --call-graph branch
- 13.86% 0.23% [kernel] [k] __x86_indirect_thunk_rax
- 13.65% __x86_indirect_thunk_rax
+ 1.69% do_syscall_64
+ 1.68% do_select
+ 1.41% ktime_get
+ 0.70% __schedule
+ 0.62% do_sys_poll
0.58% __x86_indirect_thunk_rax
Actually it's very easy to enable this feature in 'perf top'.
With this patch, the result is:
$ perf top -a -b --call-graph branch
$ - 13.58% 0.00% [kernel] [k] __x86_indirect_thunk_rax
$ - 13.57% __x86_indirect_thunk_rax (predicted:93.9%)
$ + 1.78% do_select (cycles:2)
$ + 1.68% perf_pmu_disable.part.99 (cycles:1)
$ + 1.45% ___sys_recvmsg (cycles:25)
$ + 0.81% unix_stream_sendmsg (cycles:18)
$ + 0.80% ktime_get (cycles:400)
$ 0.58% pick_next_task_fair (cycles:47)
$ + 0.56% i915_request_retire (cycles:2)
$ + 0.52% do_sys_poll (cycles:4)--- tools/perf/builtin-top.c | 3 +++ 1 file changed, 3 insertions(+)
tools/perf/builtin-top.c +3 -0
@@ -1429,6 +1429,9 @@ int cmd_top(int argc, const char **argv) } } +if (opts->branch_stack && callchain_param.enabled) + symbol_conf.show_branchflag_count = true; + sort__mode =SORT_MODE__TOP ;/* display thread wants entries to be collapsed in a different tree */ perf_hpp_list.need_collapse =1 ;
Signature · 1 line
2.14.4
Arnaldo Carvalho de Melo
maintainerPATCH 10/18 perf scripts python: exported-sql-viewer.py: Fall back to /usr/local/lib/libxed.so
In reply to Arnaldo Carvalho de MeloFrom: Adrian Hunter <[email protected]>
Fall back to /usr/local/lib/libxed.so to cater for distributions that do not have /usr/local/lib in the library path by default.
--- tools/perf/scripts/python/exported-sql-viewer.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-)
tools/perf/scripts/python/exported-sql-viewer.py +6 -1
@@ -1929,7 +1929,12 @@ class XEDInstruction(): class LibXED(): def __init__(self): - self.libxed = CDLL("libxed.so") + try: + self.libxed = CDLL("libxed.so") + except: + self.libxed = None + if not self.libxed: + self.libxed = CDLL("/usr/local/lib/libxed.so") self.xed_tables_init = self.libxed.xed_tables_init self.xed_tables_init.restype = None
Signature · 1 line
2.14.4
Arnaldo Carvalho de Melo
maintainerPATCH 11/18 perf scripts python: exported-sql-viewer.py: Add Selected branches report
In reply to Arnaldo Carvalho de MeloFrom: Adrian Hunter <[email protected]>
Fetching data from the database can be slow. Add a report that provides the ability to select a subset of branches.
--- tools/perf/scripts/python/exported-sql-viewer.py | 327 +++++++++++++++++++++++ 1 file changed, 327 insertions(+)
tools/perf/scripts/python/exported-sql-viewer.py +327 -0
@@ -119,6 +119,14 @@ def dsoname(name): return "[kernel]" return name +def findnth(s, sub, n, offs=0): + pos = s.find(sub) + if pos < 0: + return pos + if n <= 1: + return offs + pos + return findnth(s[pos + 1:], sub, n - 1, offs + pos + 1) + # Percent to one decimal place def PercentToOneDP(n, d):
@@ -1464,6 +1472,317 @@ class BranchWindow(QMdiSubWindow): else: self.find_bar.NotFound() +# Dialog data item converted and validated using a SQL table + +class SQLTableDialogDataItem(): + + def __init__(self, glb, label, placeholder_text, table_name, match_column, column_name1, column_name2, parent): + self.glb = glb + self.label = label + self.placeholder_text = placeholder_text + self.table_name = table_name + self.match_column = match_column + self.column_name1 = column_name1 + self.column_name2 = column_name2 + self.parent = parent + + self.value = "" + + self.widget = QLineEdit() + self.widget.editingFinished.connect(self.Validate) + self.widget.textChanged.connect(self.Invalidate) + self.red = False + self.error = "" + self.validated = True + + self.last_id = 0 + self.first_time = 0 + self.last_time = 2 ** 64 + if self.table_name == "<timeranges>": + query = QSqlQuery(self.glb.db) + QueryExec(query, "SELECT id, time FROM samples ORDER BY id DESC LIMIT 1") + if query.next(): + self.last_id = int(query.value(0)) + self.last_time = int(query.value(1)) + QueryExec(query, "SELECT time FROM samples WHERE time != 0 ORDER BY id LIMIT 1") + if query.next(): + self.first_time = int(query.value(0)) + if placeholder_text: + placeholder_text += ", between " + str(self.first_time) + " and " + str(self.last_time) + + if placeholder_text: + self.widget.setPlaceholderText(placeholder_text) + + def ValueToIds(self, value): + ids = [] + query = QSqlQuery(self.glb.db) + stmt = "SELECT id FROM " + self.table_name + " WHERE " + self.match_column + " = '" + value + "'" + ret = query.exec_(stmt) + if ret: + while query.next(): + ids.append(str(query.value(0))) + return ids + + def IdBetween(self, query, lower_id, higher_id, order): + QueryExec(query, "SELECT id FROM samples WHERE id > " + str(lower_id) + " AND id < " + str(higher_id) + " ORDER BY id " + order + " LIMIT 1") + if query.next(): + return True, int(query.value(0)) + else: + return False, 0 + + def BinarySearchTime(self, lower_id, higher_id, target_time, get_floor): + query = QSqlQuery(self.glb.db) + while True: + next_id = int((lower_id + higher_id) / 2) + QueryExec(query, "SELECT time FROM samples WHERE id = " + str(next_id)) + if not query.next(): + ok, dbid = self.IdBetween(query, lower_id, next_id, "DESC") + if not ok: + ok, dbid = self.IdBetween(query, next_id, higher_id, "") + if not ok: + return str(higher_id) + next_id = dbid + QueryExec(query, "SELECT time FROM samples WHERE id = " + str(next_id)) + next_time = int(query.value(0)) + if get_floor: + if target_time > next_time: + lower_id = next_id + else: + higher_id = next_id + if higher_id <= lower_id + 1: + return str(higher_id) + else: + if target_time >= next_time: + lower_id = next_id + else: + higher_id = next_id + if higher_id <= lower_id + 1: + return str(lower_id) + + def ConvertRelativeTime(self, val): + print "val ", val + mult = 1 + suffix = val[-2:] + if suffix == "ms": + mult = 1000000 + elif suffix == "us": + mult = 1000 + elif suffix == "ns": + mult = 1 + else: + return val + val = val[:-2].strip() + if not self.IsNumber(val): + return val + val = int(val) * mult + if val >= 0: + val += self.first_time + else: + val += self.last_time + return str(val) + + def ConvertTimeRange(self, vrange): + print "vrange ", vrange + if vrange[0] == "": + vrange[0] = str(self.first_time) + if vrange[1] == "": + vrange[1] = str(self.last_time) + vrange[0] = self.ConvertRelativeTime(vrange[0]) + vrange[1] = self.ConvertRelativeTime(vrange[1]) + print "vrange2 ", vrange + if not self.IsNumber(vrange[0]) or not self.IsNumber(vrange[1]): + return False + print "ok1" + beg_range = max(int(vrange[0]), self.first_time) + end_range = min(int(vrange[1]), self.last_time) + if beg_range > self.last_time or end_range < self.first_time: + return False + print "ok2" + vrange[0] = self.BinarySearchTime(0, self.last_id, beg_range, True) + vrange[1] = self.BinarySearchTime(1, self.last_id + 1, end_range, False) + print "vrange3 ", vrange + return True + + def AddTimeRange(self, value, ranges): + print "value ", value + n = value.count("-") + if n == 1: + pass + elif n == 2: + if value.split("-")[1].strip() == "": + n = 1 + elif n == 3: + n = 2 + else: + return False + pos = findnth(value, "-", n) + vrange = [value[:pos].strip() ,value[pos+1:].strip()] + if self.ConvertTimeRange(vrange): + ranges.append(vrange) + return True + return False + + def InvalidValue(self, value): + self.value = "" + palette = QPalette() + palette.setColor(QPalette.Text,Qt.red) + self.widget.setPalette(palette) + self.red = True + self.error = self.label + " invalid value '" + value + "'" + self.parent.ShowMessage(self.error) + + def IsNumber(self, value): + try: + x = int(value) + except: + x = 0 + return str(x) == value + + def Invalidate(self): + self.validated = False + + def Validate(self): + input_string = self.widget.text() + self.validated = True + if self.red: + palette = QPalette() + self.widget.setPalette(palette) + self.red = False + if not len(input_string.strip()): + self.error = "" + self.value = "" + return + if self.table_name == "<timeranges>": + ranges = [] + for value in [x.strip() for x in input_string.split(",")]: + if not self.AddTimeRange(value, ranges): + return self.InvalidValue(value) + ranges = [("(" + self.column_name1 + " >= " + r[0] + " AND " + self.column_name1 + " <= " + r[1] + ")") for r in ranges] + self.value = " OR ".join(ranges) + elif self.table_name == "<ranges>": + singles = [] + ranges = [] + for value in [x.strip() for x in input_string.split(",")]: + if "-" in value: + vrange = value.split("-") + if len(vrange) != 2 or not self.IsNumber(vrange[0]) or not self.IsNumber(vrange[1]): + return self.InvalidValue(value) + ranges.append(vrange) + else: + if not self.IsNumber(value): + return self.InvalidValue(value) + singles.append(value) + ranges = [("(" + self.column_name1 + " >= " + r[0] + " AND " + self.column_name1 + " <= " + r[1] + ")") for r in ranges] + if len(singles): + ranges.append(self.column_name1 + " IN (" + ",".join(singles) + ")") + self.value = " OR ".join(ranges) + elif self.table_name: + all_ids = [] + for value in [x.strip() for x in input_string.split(",")]: + ids = self.ValueToIds(value) + if len(ids): + all_ids.extend(ids) + else: + return self.InvalidValue(value) + self.value = self.column_name1 + " IN (" + ",".join(all_ids) + ")" + if self.column_name2: + self.value = "( " + self.value + " OR " + self.column_name2 + " IN (" + ",".join(all_ids) + ") )" + else: + self.value = input_string.strip() + self.error = "" + self.parent.ClearMessage() + + def IsValid(self): + if not self.validated: + self.Validate() + if len(self.error): + self.parent.ShowMessage(self.error) + return False + return True + +# Selected branch report creation dialog + +class SelectedBranchDialog(QDialog): + + def __init__(self, glb, parent=None): + super(SelectedBranchDialog, self).__init__(parent) + + self.glb = glb + + self.name = "" + self.where_clause = "" + + self.setWindowTitle("Selected Branches") + self.setMinimumWidth(600) + + items = ( + ("Report name:", "Enter a name to appear in the window title bar", "", "", "", ""), + ("Time ranges:", "Enter time ranges", "<timeranges>", "", "samples.id", ""), + ("CPUs:", "Enter CPUs or ranges e.g. 0,5-6", "<ranges>", "", "cpu", ""), + ("Commands:", "Only branches with these commands will be included", "comms", "comm", "comm_id", ""), + ("PIDs:", "Only branches with these process IDs will be included", "threads", "pid", "thread_id", ""), + ("TIDs:", "Only branches with these thread IDs will be included", "threads", "tid", "thread_id", ""), + ("DSOs:", "Only branches with these DSOs will be included", "dsos", "short_name", "samples.dso_id", "to_dso_id"), + ("Symbols:", "Only branches with these symbols will be included", "symbols", "name", "symbol_id", "to_symbol_id"), + ("Raw SQL clause: ", "Enter a raw SQL WHERE clause", "", "", "", ""), + ) + self.data_items = [SQLTableDialogDataItem(glb, *x, parent=self) for x in items] + + self.grid = QGridLayout() + + for row in xrange(len(self.data_items)): + self.grid.addWidget(QLabel(self.data_items[row].label), row, 0) + self.grid.addWidget(self.data_items[row].widget, row, 1) + + self.status = QLabel() + + self.ok_button = QPushButton("Ok", self) + self.ok_button.setDefault(True) + self.ok_button.released.connect(self.Ok) + self.ok_button.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) + + self.cancel_button = QPushButton("Cancel", self) + self.cancel_button.released.connect(self.reject) + self.cancel_button.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) + + self.hbox = QHBoxLayout() + #self.hbox.addStretch() + self.hbox.addWidget(self.status) + self.hbox.addWidget(self.ok_button) + self.hbox.addWidget(self.cancel_button) + + self.vbox = QVBoxLayout() + self.vbox.addLayout(self.grid) + self.vbox.addLayout(self.hbox) + + self.setLayout(self.vbox); + + def Ok(self): + self.name = self.data_items[0].value + if not self.name: + self.ShowMessage("Report name is required") + return + for d in self.data_items: + if not d.IsValid(): + return + for d in self.data_items[1:]: + if len(d.value): + if len(self.where_clause): + self.where_clause += " AND " + self.where_clause += d.value + if len(self.where_clause): + self.where_clause = " AND ( " + self.where_clause + " ) " + else: + self.ShowMessage("No selection") + return + self.accept() + + def ShowMessage(self, msg): + self.status.setText("<font color=#FF0000>" + msg) + + def ClearMessage(self): + self.status.setText("") + # Event list def GetEventList(db):
@@ -1888,6 +2207,8 @@ class MainWindow(QMainWindow): if event == "branches": label = "All branches" if branches_events == 1 else "All branches " + "(id=" + dbid + ")" reports_menu.addAction(CreateAction(label, "Create a new window displaying branch events", lambda x=dbid: self.NewBranchView(x), self)) + label = "Selected branches" if branches_events == 1 else "Selected branches " + "(id=" + dbid + ")" + reports_menu.addAction(CreateAction(label, "Create a new window displaying branch events", lambda x=dbid: self.NewSelectedBranchView(x), self)) def TableMenu(self, tables, menu): table_menu = menu.addMenu("&Tables")
@@ -1900,6 +2221,12 @@ class MainWindow(QMainWindow): def NewBranchView(self, event_id): BranchWindow(self.glb, event_id, "", "", self) + def NewSelectedBranchView(self, event_id): + dialog = SelectedBranchDialog(self.glb, self) + ret = dialog.exec_() + if ret: + BranchWindow(self.glb, event_id, dialog.name, dialog.where_clause, self) + def NewTableView(self, table_name): TableWindow(self.glb, table_name, self)
Signature · 1 line
2.14.4
Arnaldo Carvalho de Melo
maintainerPATCH 12/18 perf scripts python: exported-sql-viewer.py: Add help window
In reply to Arnaldo Carvalho de MeloFrom: Adrian Hunter <[email protected]>
Add a window to display help. It is also possible to display the help only, by using the option "--help-only" instead of a database name.
--- tools/perf/scripts/python/exported-sql-viewer.py | 155 ++++++++++++++++++++++- 1 file changed, 154 insertions(+), 1 deletion(-)
tools/perf/scripts/python/exported-sql-viewer.py +154 -1
@@ -2084,6 +2084,147 @@ class WindowMenu(): def setActiveSubWindow(self, nr): self.mdi_area.setActiveSubWindow(self.mdi_area.subWindowList()[nr - 1]) +# Help text + +glb_help_text = """ +<h1>Contents</h1> +<style> +p.c1 { + text-indent: 40px; +} +p.c2 { + text-indent: 80px; +} +} +</style> +<p class=c1><a href=#reports>1. Reports</a></p> +<p class=c2><a href=#callgraph>1.1 Context-Sensitive Call Graph</a></p> +<p class=c2><a href=#allbranches>1.2 All branches</a></p> +<p class=c2><a href=#selectedbranches>1.3 Selected branches</a></p> +<p class=c1><a href=#tables>2. Tables</a></p> +<h1 id=reports>1. Reports</h1> +<h2 id=callgraph>1.1 Context-Sensitive Call Graph</h2> +The result is a GUI window with a tree representing a context-sensitive +call-graph. Expanding a couple of levels of the tree and adjusting column +widths to suit will display something like: +<pre> + Call Graph: pt_example +Call Path Object Count Time(ns) Time(%) Branch Count Branch Count(%) +v- ls + v- 2638:2638 + v- _start ld-2.19.so 1 10074071 100.0 211135 100.0 + |- unknown unknown 1 13198 0.1 1 0.0 + >- _dl_start ld-2.19.so 1 1400980 13.9 19637 9.3 + >- _d_linit_internal ld-2.19.so 1 448152 4.4 11094 5.3 + v-__libc_start_main@plt ls 1 8211741 81.5 180397 85.4 + >- _dl_fixup ld-2.19.so 1 7607 0.1 108 0.1 + >- __cxa_atexit libc-2.19.so 1 11737 0.1 10 0.0 + >- __libc_csu_init ls 1 10354 0.1 10 0.0 + |- _setjmp libc-2.19.so 1 0 0.0 4 0.0 + v- main ls 1 8182043 99.6 180254 99.9 +</pre> +<h3>Points to note:</h3> +<ul> +<li>The top level is a command name (comm)</li> +<li>The next level is a thread (pid:tid)</li> +<li>Subsequent levels are functions</li> +<li>'Count' is the number of calls</li> +<li>'Time' is the elapsed time until the function returns</li> +<li>Percentages are relative to the level above</li> +<li>'Branch Count' is the total number of branches for that function and all functions that it calls +</ul> +<h3>Find</h3> +Ctrl-F displays a Find bar which finds function names by either an exact match or a pattern match. +The pattern matching symbols are ? for any character and * for zero or more characters. +<h2 id=allbranches>1.2 All branches</h2> +The All branches report displays all branches in chronological order. +Not all data is fetched immediately. More records can be fetched using the Fetch bar provided. +<h3>Disassembly</h3> +Open a branch to display disassembly. This only works if: +<ol> +<li>The disassembler is available. Currently, only Intel XED is supported - see <a href=#xed>Intel XED Setup</a></li> +<li>The object code is available. Currently, only the perf build ID cache is searched for object code. +The default directory ~/.debug can be overridden by setting environment variable PERF_BUILDID_DIR. +One exception is kcore where the DSO long name is used (refer dsos_view on the Tables menu), +or alternatively, set environment variable PERF_KCORE to the kcore file name.</li> +</ol> +<h4 id=xed>Intel XED Setup</h4> +To use Intel XED, libxed.so must be present. To build and install libxed.so: +<pre> +git clone https://github.com/intelxed/mbuild.git mbuild +git clone https://github.com/intelxed/xed +cd xed +./mfile.py --share +sudo ./mfile.py --prefix=/usr/local install +sudo ldconfig +</pre> +<h3>Find</h3> +Ctrl-F displays a Find bar which finds substrings by either an exact match or a regular expression match. +Refer to Python documentation for the regular expression syntax. +All columns are searched, but only currently fetched rows are searched. +<h2 id=selectedbranches>1.3 Selected branches</h2> +This is the same as the <a href=#allbranches>All branches</a> report but with the data reduced +by various selection criteria. A dialog box displays available criteria which are AND'ed together. +<h3>1.3.1 Time ranges</h3> +The time ranges hint text shows the total time range. Relative time ranges can also be entered in +ms, us or ns. Also, negative values are relative to the end of trace. Examples: +<pre> + 81073085947329-81073085958238 From 81073085947329 to 81073085958238 + 100us-200us From 100us to 200us + 10ms- From 10ms to the end + -100ns The first 100ns + -10ms- The last 10ms +</pre> +N.B. Due to the granularity of timestamps, there could be no branches in any given time range. +<h1 id=tables>2. Tables</h1> +The Tables menu shows all tables and views in the database. Most tables have an associated view +which displays the information in a more friendly way. Not all data for large tables is fetched +immediately. More records can be fetched using the Fetch bar provided. Columns can be sorted, +but that can be slow for large tables. +<p>There are also tables of database meta-information. +For SQLite3 databases, the sqlite_master table is included. +For PostgreSQL databases, information_schema.tables/views/columns are included. +<h3>Find</h3> +Ctrl-F displays a Find bar which finds substrings by either an exact match or a regular expression match. +Refer to Python documentation for the regular expression syntax. +All columns are searched, but only currently fetched rows are searched. +""" + +# Help window + +class HelpWindow(QMdiSubWindow): + + def __init__(self, glb, parent=None): + super(HelpWindow, self).__init__(parent) + + self.text = QTextBrowser() + self.text.setHtml(glb_help_text) + self.text.setReadOnly(True) + self.text.setOpenExternalLinks(True) + + self.setWidget(self.text) + + AddSubWindow(glb.mainwindow.mdi_area, self, "Exported SQL Viewer Help") + +# Main window that only displays the help text + +class HelpOnlyWindow(QMainWindow): + + def __init__(self, parent=None): + super(HelpOnlyWindow, self).__init__(parent) + + self.setMinimumSize(200, 100) + self.resize(800, 600) + self.setWindowTitle("Exported SQL Viewer Help") + self.setWindowIcon(self.style().standardIcon(QStyle.SP_MessageBoxInformation)) + + self.text = QTextBrowser() + self.text.setHtml(glb_help_text) + self.text.setReadOnly(True) + self.text.setOpenExternalLinks(True) + + self.setCentralWidget(self.text) + # Font resize def ResizeFont(widget, diff):
@@ -2170,6 +2311,9 @@ class MainWindow(QMainWindow): self.window_menu = WindowMenu(self.mdi_area, menu) + help_menu = menu.addMenu("&Help") + help_menu.addAction(CreateAction("&Exported SQL Viewer Help", "Helpful information", self.Help, self, QKeySequence.HelpContents)) + def Find(self): win = self.mdi_area.activeSubWindow() if win:
@@ -2230,6 +2374,9 @@ class MainWindow(QMainWindow): def NewTableView(self, table_name): TableWindow(self.glb, table_name, self) + def Help(self): + HelpWindow(self.glb, self) + # XED Disassembler class xed_state_t(Structure):
@@ -2429,10 +2576,16 @@ class DBRef(): def Main(): if (len(sys.argv) < 2): - print >> sys.stderr, "Usage is: exported-sql-viewer.py <database name>" + print >> sys.stderr, "Usage is: exported-sql-viewer.py {<database name> | --help-only}" raise Exception("Too few arguments") dbname = sys.argv[1] + if dbname == "--help-only": + app = QApplication(sys.argv) + mainwindow = HelpOnlyWindow() + mainwindow.show() + err = app.exec_() + sys.exit(err) is_sqlite3 = False try:
Signature · 1 line
2.14.4
Arnaldo Carvalho de Melo
maintainerPATCH 13/18 perf scripts python: exported-sql-viewer.py: Fix table find when table re-ordered
In reply to Arnaldo Carvalho de MeloFrom: Adrian Hunter <[email protected]>
Table rows can be re-ordered by selecting a column to sort by. After re-ordering, the "find" operation was highlighting the wrong row, fix it.
--- tools/perf/scripts/python/exported-sql-viewer.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
tools/perf/scripts/python/exported-sql-viewer.py +3 -1
@@ -1975,7 +1975,7 @@ class TableWindow(QMdiSubWindow, ResizeColumnsToContentsBase): def FindDone(self, row): self.find_bar.Idle() if row >= 0: - self.view.setCurrentIndex(self.model.index(row, 0, QModelIndex())) + self.view.setCurrentIndex(self.model.mapFromSource(self.data_model.index(row, 0, QModelIndex()))) else: self.find_bar.NotFound()
@@ -2188,6 +2188,8 @@ For PostgreSQL databases, information_schema.tables/views/columns are included. Ctrl-F displays a Find bar which finds substrings by either an exact match or a regular expression match. Refer to Python documentation for the regular expression syntax. All columns are searched, but only currently fetched rows are searched. +<p>N.B. Results are found in id order, so if the table is re-ordered, find-next and find-previous +will go to the next/previous result in id order, instead of display order. """ # Help window
Signature · 1 line
2.14.4
Arnaldo Carvalho de Melo
maintainerPATCH 14/18 perf intel-pt: Add more event information to debug log
In reply to Arnaldo Carvalho de MeloFrom: Adrian Hunter <[email protected]>
More event information is useful for debugging, especially MMAP events.
--- tools/perf/util/intel-pt-decoder/intel-pt-log.c | 5 +++++ tools/perf/util/intel-pt-decoder/intel-pt-log.h | 1 + tools/perf/util/intel-pt.c | 16 +++++++++++++--- 3 files changed, 19 insertions(+), 3 deletions(-)
tools/perf/util/intel-pt-decoder/intel-pt-log.c +5 -0
@@ -31,6 +31,11 @@ static FILE *f;static char log_name[MAX_LOG_NAME ];bool intel_pt_enable_logging; +void *intel_pt_log_fp (void ) +{ +return f; +} +void intel_pt_log_enable (void ) { intel_pt_enable_logging = true;
tools/perf/util/intel-pt-decoder/intel-pt-log.h +1 -0
@@ -22,6 +22,7 @@struct intel_pt_pkt ; +void *intel_pt_log_fp (void );void intel_pt_log_enable (void );void intel_pt_log_disable (void );void intel_pt_log_set_name (const char *name);
tools/perf/util/intel-pt.c +13 -3
@@ -206,6 +206,16 @@ static void intel_pt_dump_event(struct intel_pt *pt, unsigned char *buf,intel_pt_dump (pt, buf, len); } +static void intel_pt_log_event (union perf_event *event) +{ +FILE *f =intel_pt_log_fp (); + +if (!intel_pt_enable_logging || !f) +return ; + +perf_event__fprintf (event, f); +} +static int intel_pt_do_fix_overlap (struct intel_pt *pt,struct auxtrace_buffer *a,struct auxtrace_buffer *b) {
@@ -2010,9 +2020,9 @@ static int intel_pt_process_event(struct perf_session *session, event->header.type == PERF_RECORD_SWITCH_CPU_WIDE) err =intel_pt_context_switch (pt, event, sample); -intel_pt_log ("event %s (%u): cpu %d time %" PRIu64" tsc %#" PRIx64"\n" , -perf_event__name (event->header.type), event->header.type, - sample->cpu, sample->time, timestamp); +intel_pt_log ("event %u: cpu %d time %" PRIu64" tsc %#" PRIx64" " , + event->header.type, sample->cpu, sample->time, timestamp); +intel_pt_log_event (event);return err; }
Signature · 1 line
2.14.4
Arnaldo Carvalho de Melo
maintainerPATCH 15/18 perf intel-pt: Add MTC and CYC timestamps to debug log
In reply to Arnaldo Carvalho de MeloFrom: Adrian Hunter <[email protected]>
One cause of decoding errors is un-synchronized side-band data. Timestamps are needed to debug such cases. TSC packet timestamps are logged. Log also MTC and CYC timestamps.
--- tools/perf/util/intel-pt-decoder/intel-pt-decoder.c | 4 ++++ 1 file changed, 4 insertions(+)
tools/perf/util/intel-pt-decoder/intel-pt-decoder.c +4 -0
@@ -1474,6 +1474,8 @@ static void intel_pt_calc_mtc_timestamp(struct intel_pt_decoder *decoder) decoder->have_calc_cyc_to_tsc = false;intel_pt_calc_cyc_to_tsc (decoder, true); } + +intel_pt_log_to ("Setting timestamp" , decoder->timestamp); }static void intel_pt_calc_cbr (struct intel_pt_decoder *decoder)
@@ -1514,6 +1516,8 @@ static void intel_pt_calc_cyc_timestamp(struct intel_pt_decoder *decoder) decoder->timestamp = timestamp; decoder->timestamp_insn_cnt =0 ; + +intel_pt_log_to ("Setting timestamp" , decoder->timestamp); }/* Walk PSB+ packets when already in sync. */
Signature · 1 line
2.14.4
Arnaldo Carvalho de Melo
maintainerPATCH 16/18 perf beauty: Use SRCARCH, ARCH=x86_64 must map to "x86" to find the headers
In reply to Arnaldo Carvalho de MeloFrom: Arnaldo Carvalho de Melo <[email protected]>
Guenter reported that using ARCH=x86_64 to build perf has regressed:
$ make -C tools/perf O=/tmp/build/perf ARCH=x86_64
make: Entering directory '/home/acme/git/perf/tools/perf'
BUILD: Doing 'make -j4' parallel build
HOSTCC /tmp/build/perf/fixdep.o
HOSTLD /tmp/build/perf/fixdep-in.o
LINK /tmp/build/perf/fixdep Auto-detecting system features:
... dwarf: [ on ]
<SNIP>
... bpf: [ on ]
GEN /tmp/build/perf/common-cmds.h
make[2]: *** No rule to make target '/home/acme/git/perf/tools/arch/x86_64/include/uapi/asm//mman.h', needed by '/tmp/build/perf/trace/beauty/generated/mmap_flags_array.c'. Stop. make[2]: *** Waiting for unfinished jobs....
PERF_VERSION = 4.19.gf6c23e3
make[1]: *** [Makefile.perf:207: sub-make] Error 2
make: *** [Makefile:70: all] Error 2
make: Leaving directory '/home/acme/git/perf/tools/perf' $
This is because we must use $(SRCARCH) where we were using $(ARCH), so that, just like the top level Makefile, we get this done:
# Additional ARCH settings for x86
ifeq ($(ARCH),i386)
SRCARCH := x86
endif
ifeq ($(ARCH),x86_64)
SRCARCH := x86
endifWhich is done in tools/scripts/Makefile.arch, so switch to use $(SRCARCH).
--- tools/perf/Makefile.perf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
tools/perf/Makefile.perf +1 -1
@@ -387,7 +387,7 @@ SHELL = $(SHELL_PATH) linux_uapi_dir := $(srctree)/tools/include/uapi/linux asm_generic_uapi_dir := $(srctree)/tools/include/uapi/asm-generic -arch_asm_uapi_dir := $(srctree)/tools/arch/$(ARCH)/include/uapi/asm/ +arch_asm_uapi_dir := $(srctree)/tools/arch/$(SRCARCH)/include/uapi/asm/ beauty_outdir := $(OUTPUT)trace/beauty/generated beauty_ioctl_outdir := $(beauty_outdir)/ioctl
Signature · 1 line
2.14.4
Arnaldo Carvalho de Melo
maintainerPATCH 17/18 perf tools: Fix undefined symbol scnprintf in libperf-jvmti.so
In reply to Arnaldo Carvalho de MeloFrom: Gustavo Romero <[email protected]>
Currently jvmti agent can not be used because function scnprintf is not present in the agent libperf-jvmti.so. As a result the JVM when using such agent to record JITed code profiling information will fail on looking up scnprintf:
java: symbol lookup error: lib/libperf-jvmti.so: undefined symbol: scnprintf
This commit fixes that by reverting to the use of snprintf, that can be looked up, instead of scnprintf, adding a proper check for the returned value in order to print a better error message when the jitdump file pathname is too long. Checking the returned value also helps to comply with some recent gcc versions, like gcc8, which will fail due to truncated writing checks related to the -Werror=format-truncation= flag.
LPU-Reference: [email protected]
--- tools/perf/jvmti/jvmti_agent.c | 49 ++++++++++++++++++++++++++++++++---------- 1 file changed, 38 insertions(+), 11 deletions(-)
tools/perf/jvmti/jvmti_agent.c +38 -11
@@ -125,7 +125,7 @@ perf_get_timestamp(void) }static int -debug_cache_init (void ) +create_jit_cache_dir (void ) {char str[32 ];char *base, *p;
@@ -144,8 +144,13 @@ debug_cache_init(void)strftime (str,sizeof (str),JIT_LANG "-jit-%Y%m%d" , &tm); -snprintf (jit_path,PATH_MAX -1 ,"%s/.debug/" , base); - + ret =snprintf (jit_path,PATH_MAX ,"%s/.debug/" , base); +if (ret >=PATH_MAX ) { +warnx ("jvmti: cannot generate jit cache dir because %s/.debug/" +" is too long, please check the cwd, JITDUMPDIR, and" +" HOME variables" , base); +return -1 ; + } ret =mkdir (jit_path,0755 );if (ret ==-1 ) {if (errno !=EEXIST ) {
@@ -154,20 +159,32 @@ debug_cache_init(void) } } -snprintf (jit_path,PATH_MAX -1 ,"%s/.debug/jit" , base); + ret =snprintf (jit_path,PATH_MAX ,"%s/.debug/jit" , base); +if (ret >=PATH_MAX ) { +warnx ("jvmti: cannot generate jit cache dir because" +" %s/.debug/jit is too long, please check the cwd," +" JITDUMPDIR, and HOME variables" , base); +return -1 ; + } ret =mkdir (jit_path,0755 );if (ret ==-1 ) {if (errno !=EEXIST ) { -warn ("cannot create jit cache dir %s" , jit_path); +warn ("jvmti: cannot create jit cache dir %s" , jit_path);return -1 ; } } -snprintf (jit_path,PATH_MAX -1 ,"%s/.debug/jit/%s.XXXXXXXX" , base, str); - + ret =snprintf (jit_path,PATH_MAX ,"%s/.debug/jit/%s.XXXXXXXX" , base, str); +if (ret >=PATH_MAX ) { +warnx ("jvmti: cannot generate jit cache dir because" +" %s/.debug/jit/%s.XXXXXXXX is too long, please check" +" the cwd, JITDUMPDIR, and HOME variables" , + base, str); +return -1 ; + } p =mkdtemp (jit_path);if (p != jit_path) { -warn ("cannot create jit cache dir %s" , jit_path); +warn ("jvmti: cannot create jit cache dir %s" , jit_path);return -1 ; }
@@ -228,7 +245,7 @@ void *jvmti_open(void) {char dump_path[PATH_MAX ];struct jitheader header; -int fd; +int fd, ret;FILE *fp;init_arch_timestamp ();
@@ -245,12 +262,22 @@ void *jvmti_open(void)memset (&header,0 ,sizeof (header)); -debug_cache_init (); +/* +* jitdump file dir +*/ +if (create_jit_cache_dir () <0 ) +return NULL ;/* * jitdump file name */ -scnprintf (dump_path,PATH_MAX ,"%s/jit-%i.dump" , jit_path,getpid ()); + ret =snprintf (dump_path,PATH_MAX ,"%s/jit-%i.dump" , jit_path,getpid ()); +if (ret >=PATH_MAX ) { +warnx ("jvmti: cannot generate jitdump file full path because" +" %s/jit-%i.dump is too long, please check the cwd," +" JITDUMPDIR, and HOME variables" , jit_path,getpid ()); +return NULL ; + } fd =open (dump_path,O_CREAT |O_TRUNC |O_RDWR ,0666 );if (fd ==-1 )
Signature · 1 line
2.14.4
Arnaldo Carvalho de Melo
maintainerPATCH 18/18 perf tools: Do not zero sample_id_all for group members
In reply to Arnaldo Carvalho de MeloFrom: Jiri Olsa <[email protected]>
Andi reported following malfunction:
# perf record -e '{ref-cycles,cycles}:S' -a sleep 1
# perf script
non matching sample_id_allThat's because we disable sample_id_all bit for non-sampling group members. We can't do that, because it needs to be the same over the whole event list. This patch keeps it untouched again.
--- tools/perf/tests/attr/test-record-group-sampling | 1 - tools/perf/util/evsel.c | 1 - 2 files changed, 2 deletions(-)
tools/perf/tests/attr/test-record-group-sampling +0 -1
@@ -37,4 +37,3 @@ sample_freq=0 sample_period=0 freq=0 write_backward=0 -sample_id_all=0
tools/perf/util/evsel.c +0 -1
@@ -956,7 +956,6 @@ void perf_evsel__config(struct perf_evsel *evsel, struct record_opts *opts, attr->sample_freq =0 ; attr->sample_period =0 ; attr->write_backward =0 ; - attr->sample_id_all =0 ; }if (opts->no_samples)
Signature · 1 line
2.14.4
Quoted 114 lines · Arnaldo Carvalho de Melo
Hi Ingo,
Please consider pulling, mostly fixes, some late coming
improvements in non-core areas,- Arnaldo
Test results at the end of this message, as usual.
The following changes since commit
29995d296e3e9ce4f9767963ecbef143ade26c36:Merge tag 'perf-urgent-for-mingo-4.20-20181031' of
git://git.kernel.org/pub/scm/linux/kernel/git/acme/linuxinto perf/urgent (2018-10-31 22:53:40 +0100)are available in the Git repository at:
git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux.gittags/perf-urgent-for-mingo-4.20-20181106for you to fetch changes up to
8e88c29b351ed4e09dd63f825f1c8260b0cb0ab3:perf tools: Do not zero
sample_id_allfor group members (2018-11-06 08:29:56 -0300)----------------------------------------------------------------
perf/urgent improvements and fixes:Intel PT sql viewer: (Adrian Hunter)
- Fall back to
/usr/local/lib/libxed.so
- Add Selected branches report
- Add help window
- Fix table find when table re-orderedIntel PT debug log (Adrian Hunter)
- Add more event information
- Add MTC and CYC timestampsperf record: (Andi Kleen)
- Support weak groups, just like with 'perf stat'
perf trace: (Arnaldo Carvalho de Melo)
- Start augmenting raw_syscalls:{sys_enter,sys_exit}: goal is to have a generic, arch independent eBPF kernel component that is programmed with syscall table details, what to copy, how many bytes, pid, arg filters from the userspace via eBPF maps by the 'perf trace' tool that continues to use all its argument beautifiers, just taking advantage of the extra pointer contents.
JVMTI: (Gustavo Romero)
- Fix undefined symbol scnprintf in libperf-jvmti.so
perf top: (Jin Yao)
- Display the LBR stats in callchain entries
perf stat: (Thomas Richter)
- Handle different PMU names with common prefix
arm64: Will (Deacon)
- Fix arm64 tools build failure wrt smp_load_{acquire,release}.
Signed-off-by Arnaldo Carvalho de Melo <[email protected]>----------------------------------------------------------------
Adrian Hunter (6):
perf scripts python:exported-sql-viewer.py: Fall back to/usr/local/lib/libxed.soperf scripts python:exported-sql-viewer.py: Add Selected branches report perf scripts python:exported-sql-viewer.py: Add help window
perf scripts python:exported-sql-viewer.py: Fix table find when table re-ordered perf intel-pt: Add more event information to debug log
perf intel-pt: Add MTC and CYC timestamps to debug logAndi Kleen (2):
perf evlist: Moveperf_evsel__reset_weak_groupinto evlist perf record: Support weak groupsArnaldo Carvalho de Melo (5):
perf examples bpf: Start augmenting raw_syscalls:sys_{start,exit} perf trace: When augmentingraw_syscallsplug raw_syscalls:sys_exit too perf trace: Fix setting of augmented payload when using eBPF +raw_syscallsperfaugmented_syscalls: Start collecting pathnames in the BPF program perf beauty: Use SRCARCH, ARCH=x86_64 must map to "x86" to find the headersGustavo Romero (1):
perf tools: Fix undefined symbol scnprintf in libperf-jvmti.soJin Yao (1):
perf top: Display the LBR stats in callchain entryJiri Olsa (1):
perf tools: Do not zerosample_id_allfor group membersThomas Richter (1):
perf stat: Handle different PMU names with common prefixWill Deacon (1):
tools headers barrier: Fix arm64 tools build failure wrt smp_load_{acquire,release}tools/arch/arm64/include/asm/barrier.h | 133 +++--- tools/perf/Documentation/perf-list.txt | 1 - tools/perf/Makefile.perf | 2 +- tools/perf/builtin-record.c | 7 +- tools/perf/builtin-stat.c | 28 +- tools/perf/builtin-top.c | 3 + tools/perf/builtin-trace.c | 34 +- tools/perf/examples/bpf/augmented_raw_syscalls.c | 131 ++++++ tools/perf/jvmti/jvmti_agent.c | 49 +- tools/perf/scripts/python/exported-sql-viewer.py | 493 ++++++++++++++++++++- tools/perf/tests/attr/test-record-group-sampling | 1 - tools/perf/util/evlist.c | 27 ++ tools/perf/util/evlist.h | 3 +
Quoted 8 lines
tools/perf/util/evsel.c | 1 - .../perf/util/intel-pt-decoder/intel-pt-decoder.c | 4 + tools/perf/util/intel-pt-decoder/intel-pt-log.c | 5 + tools/perf/util/intel-pt-decoder/intel-pt-log.h | 1 + tools/perf/util/intel-pt.c | 16 +- tools/perf/util/pmu.c | 2 +- 19 files changed, 820 insertions(+), 121 deletions(-) create mode 100644 tools/perf/examples/bpf/augmented_raw_syscalls.c
Pulled, thanks a lot Arnaldo!
Ingo