perf/core improvements and fixes
Subsystems (2)
Arnaldo Carvalho de Melo
maintainerHi Ingo,
Please consider pulling, more to come,
Regards,
- Arnaldo
Test results at the end of this message, as usual.
The following changes since commit b1a9d7b0190119dad5b9b7841751b5a7586bbc8b:
Merge tag 'perf-urgent-for-mingo-4.20-20181121' of git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux into perf/urgent (2018-11-21 15:57:21 +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-20181130
for you to fetch changes up to 09d3f015d1e1b4fee7e9bbdcf54201d239393391:
uprobes: Fix handle_swbp() vs. unregister() + register() race once more (2018-11-23 08:31:19 +0100)
----------------------------------------------------------------
perf/core improvements and fixes:
- Introduce 'perf record --aio' to use asynchronous IO trace writing in 'perf record' disabled by default, i.e. one needs to explicitly use 'perf record --aio' to use it, in which case the number of AIO aiocb structs will be one, specify 'perf record --aio=N' to ask for more, according to your needs, related to the number of processors in your machine. Reports about the effectiveness of this option are welcome so that we can decide on making it the default mode of operation. Read the respective patches commit logs for further information (Alexey Budankov)
- Add fallback routines to be used in places where we don't have the cpu mode (kernel/user space/hypervisor) and thus must first fallback lookups looking at all map trees when trying to resolve symbols (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)
- Fix CSV mode column output for non-cgroup events in 'perf stat' (Stephane Eranian)
- Fix 'perf stat' shadow stats for clock events. (Ravi Bangoria)
- Fix error with config term "pt=0", where we should just force "pt=1" and warn the user about the former being non-sensical (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)
- Remove needless rb_tree extra indirection from map__find() (Eric Saint-Etienne)
- Add sanity check to libtraceevent's is_timestamp_in_us() (Tzvetomir Stoyanov)
- Use ERR_CAST instead of ERR_PTR(PTR_ERR()) (Wen Yang)
----------------------------------------------------------------
Andrea Parri (1):
uprobes: Fix handle_swbp() vs. unregister() + register() race once more
Jiri Olsa (3):
perf/x86/intel: Move branch tracing setup to the Intel-specific source file perf/x86/intel: Add generic branch tracing check to intel_pmu_has_bts() perf/x86/intel: Disallow precise_ip on BTS events
arch/x86/events/core.c | 20 ---------------- arch/x86/events/intel/core.c | 56 ++++++++++++++++++++++++++++++++++---------- arch/x86/events/perf_event.h | 13 ++++++---- kernel/events/uprobes.c | 12 ++++++++-- 4 files changed, 63 insertions(+), 38 deletions(-)
Test results:
XXX: Investigation on the watchpoint and breakpoint 'perf test' failures is
underway, doesn't look like related to patches in this batch.
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 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-mips : Ok mips-linux-gnu-gcc (Debian 8.2.0-7) 8.2.0 21 debian:experimental-x-mips64 : Ok mips64-linux-gnuabi64-gcc (Debian 8.2.0-10) 8.2.0 22 debian:experimental-x-mipsel : Ok mipsel-linux-gnu-gcc (Debian 8.2.0-7) 8.2.0 23 fedora:20 : Ok gcc (GCC) 4.8.3 20140911 (Red Hat 4.8.3-7) 24 fedora:21 : Ok gcc (GCC) 4.9.2 20150212 (Red Hat 4.9.2-6) 25 fedora:22 : Ok gcc (GCC) 5.3.1 20160406 (Red Hat 5.3.1-6) 26 fedora:23 : Ok gcc (GCC) 5.3.1 20160406 (Red Hat 5.3.1-6) 27 fedora:24 : Ok gcc (GCC) 6.3.1 20161221 (Red Hat 6.3.1-1) 28 fedora:24-x-ARC-uClibc : Ok arc-linux-gcc (ARCompact ISA Linux uClibc toolchain 2017.09-rc2) 7.1.1 20170710 29 fedora:25 : Ok gcc (GCC) 6.4.1 20170727 (Red Hat 6.4.1-1) 30 fedora:26 : Ok gcc (GCC) 7.3.1 20180130 (Red Hat 7.3.1-2) 31 fedora:27 : Ok gcc (GCC) 7.3.1 20180712 (Red Hat 7.3.1-6) 32 fedora:28 : Ok gcc (GCC) 8.2.1 20181105 (Red Hat 8.2.1-5) 33 fedora:29 : Ok gcc (GCC) 8.2.1 20181011 (Red Hat 8.2.1-4) 34 fedora:rawhide : Ok gcc (GCC) 8.2.1 20181011 (Red Hat 8.2.1-4) 35 gentoo-stage3-amd64:latest : Ok gcc (Gentoo 7.3.0-r3 p1.4) 7.3.0 36 mageia:5 : Ok gcc (GCC) 4.9.2 37 mageia:6 : Ok gcc (Mageia 5.5.0-1.mga6) 5.5.0 38 opensuse:13.2 : Ok gcc (SUSE Linux) 4.8.3 20140627 [gcc-4_8-branch revision 212064] 39 opensuse:42.1 : Ok gcc (SUSE Linux) 4.8.5 40 opensuse:42.2 : Ok gcc (SUSE Linux) 4.8.5 41 opensuse:42.3 : Ok gcc (SUSE Linux) 4.8.5 42 opensuse:tumbleweed : Ok gcc (SUSE Linux) 7.3.1 20180323 [gcc-7-branch revision 258812] 43 oraclelinux:6 : Ok gcc (GCC) 4.4.7 20120313 (Red Hat 4.4.7-23.0.1) 44 oraclelinux:7 : Ok gcc (GCC) 4.8.5 20150623 (Red Hat 4.8.5-36.0.1) 45 ubuntu:12.04.5 : Ok gcc (Ubuntu/Linaro 4.6.3-1ubuntu5) 4.6.3 46 ubuntu:14.04.4 : Ok gcc (Ubuntu 4.8.4-2ubuntu1~14.04.3) 4.8.4 47 ubuntu:14.04.4-x-linaro-arm64 : Ok aarch64-linux-gnu-gcc (Linaro GCC 5.5-2017.10) 5.5.0 48 ubuntu:16.04 : Ok gcc (Ubuntu 5.4.0-6ubuntu1~16.04.10) 5.4.0 20160609 49 ubuntu:16.04-x-arm : Ok arm-linux-gnueabihf-gcc (Ubuntu/Linaro 5.4.0-6ubuntu1~16.04.9) 5.4.0 20160609 50 ubuntu:16.04-x-arm64 : Ok aarch64-linux-gnu-gcc (Ubuntu/Linaro 5.4.0-6ubuntu1~16.04.9) 5.4.0 20160609 51 ubuntu:16.04-x-powerpc : Ok powerpc-linux-gnu-gcc (Ubuntu 5.4.0-6ubuntu1~16.04.9) 5.4.0 20160609 52 ubuntu:16.04-x-powerpc64 : Ok powerpc64-linux-gnu-gcc (Ubuntu/IBM 5.4.0-6ubuntu1~16.04.9) 5.4.0 20160609 53 ubuntu:16.04-x-powerpc64el : Ok powerpc64le-linux-gnu-gcc (Ubuntu/IBM 5.4.0-6ubuntu1~16.04.9) 5.4.0 20160609 54 ubuntu:16.04-x-s390 : Ok s390x-linux-gnu-gcc (Ubuntu 5.4.0-6ubuntu1~16.04.9) 5.4.0 20160609 55 ubuntu:16.10 : Ok gcc (Ubuntu 6.2.0-5ubuntu12) 6.2.0 20161005 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-27ubuntu1~18.04) 7.3.0 58 ubuntu:18.04-x-arm : Ok arm-linux-gnueabihf-gcc (Ubuntu/Linaro 7.3.0-27ubuntu1~18.04) 7.3.0 59 ubuntu:18.04-x-arm64 : Ok aarch64-linux-gnu-gcc (Ubuntu/Linaro 7.3.0-27ubuntu1~18.04) 7.3.0 60 ubuntu:18.04-x-m68k : Ok m68k-linux-gnu-gcc (Ubuntu 7.3.0-27ubuntu1~18.04) 7.3.0 61 ubuntu:18.04-x-powerpc : Ok powerpc-linux-gnu-gcc (Ubuntu 7.3.0-27ubuntu1~18.04) 7.3.0 62 ubuntu:18.04-x-powerpc64 : Ok powerpc64-linux-gnu-gcc (Ubuntu 7.3.0-27ubuntu1~18.04) 7.3.0 63 ubuntu:18.04-x-powerpc64el : Ok powerpc64le-linux-gnu-gcc (Ubuntu 7.3.0-27ubuntu1~18.04) 7.3.0 64 ubuntu:18.04-x-riscv64 : Ok riscv64-linux-gnu-gcc (Ubuntu 7.3.0-27ubuntu1~18.04) 7.3.0 65 ubuntu:18.04-x-s390 : Ok s390x-linux-gnu-gcc (Ubuntu 7.3.0-27ubuntu1~18.04) 7.3.0 66 ubuntu:18.04-x-sh4 : Ok sh4-linux-gnu-gcc (Ubuntu 7.3.0-27ubuntu1~18.04) 7.3.0 67 ubuntu:18.04-x-sparc64 : Ok sparc64-linux-gnu-gcc (Ubuntu 7.3.0-27ubuntu1~18.04) 7.3.0 68 ubuntu:18.10 : Ok gcc (Ubuntu 8.2.0-7ubuntu1) 8.2.0 #
# uname -a
Linux seventh 4.18.19-100.fc27.x86_64 #1 SMP Wed Nov 14 22:04:34 UTC 2018 x86_64 x86_64 x86_64 GNU/Linux
# git log --oneline -1
ceed7c10bbb4 tools lib traceevent: Add sanity check to is_timestamp_in_us()
# perf version --build-options
perf version 4.20.rc3.gceed7c
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 : FAILED!
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 : FAILED!
64: probe libc's inet_pton & backtrace it with ping : Ok
65: Check open filename arg using perf trace + vfs_getname: Ok
66: Use vfs_getname probe to get syscall args filenames : 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_util_map_o_O: make util/map.o
make_util_pmu_bison_o_O: make util/pmu-bison.o
make_help_O: make help
make_with_clangllvm_O: make LIBCLANGLLVM=1
make_install_prefix_O: make install prefix=/tmp/krava
make_no_libbionic_O: make NO_LIBBIONIC=1
make_no_newt_O: make NO_NEWT=1
make_no_libdw_dwarf_unwind_O: make NO_LIBDW_DWARF_UNWIND=1
make_install_O: make install
make_no_auxtrace_O: make NO_AUXTRACE=1
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_debug_O: make DEBUG=1
make_doc_O: make doc
make_no_libbpf_O: make NO_LIBBPF=1
make_no_libelf_O: make NO_LIBELF=1
make_no_gtk2_O: make NO_GTK2=1
make_no_slang_O: make NO_SLANG=1
make_no_libaudit_O: make NO_LIBAUDIT=1
make_no_demangle_O: make NO_DEMANGLE=1
make_no_libunwind_O: make NO_LIBUNWIND=1
make_no_backtrace_O: make NO_BACKTRACE=1
make_no_libnuma_O: make NO_LIBNUMA=1
make_with_babeltrace_O: make LIBBABELTRACE=1
make_no_ui_O: make NO_NEWT=1 NO_SLANG=1 NO_GTK2=1
make_perf_o_O: make perf.o
make_no_scripts_O: make NO_LIBPYTHON=1 NO_LIBPERL=1
make_no_libpython_O: make NO_LIBPYTHON=1
make_install_bin_O: make install-bin
make_install_prefix_slash_O: make install prefix=/tmp/krava/
make_pure_O: make
make_no_libperl_O: make NO_LIBPERL=1
make_clean_all_O: make clean all
make_static_O: make LDFLAGS=-static
make_tags_O: make tags
OK
make: Leaving directory '/home/acme/git/perf/tools/perf'
$Arnaldo Carvalho de Melo
maintainerPATCH 1/22 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.1
Arnaldo Carvalho de Melo
maintainerPATCH 2/22 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.1
Arnaldo Carvalho de Melo
maintainerPATCH 3/22 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.1
Arnaldo Carvalho de Melo
maintainerPATCH 4/22 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.1
Arnaldo Carvalho de Melo
maintainerPATCH 5/22 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.1
Arnaldo Carvalho de Melo
maintainerPATCH 6/22 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.1
Arnaldo Carvalho de Melo
maintainerPATCH 7/22 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.1
Arnaldo Carvalho de Melo
maintainerPATCH 8/22 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.1
Arnaldo Carvalho de Melo
maintainerPATCH 9/22 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.1
Arnaldo Carvalho de Melo
maintainerPATCH 10/22 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.1
Arnaldo Carvalho de Melo
maintainerPATCH 11/22 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.1
Arnaldo Carvalho de Melo
maintainerPATCH 12/22 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.1
Arnaldo Carvalho de Melo
maintainerPATCH 13/22 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.1
Arnaldo Carvalho de Melo
maintainerPATCH 14/22 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.1
Arnaldo Carvalho de Melo
maintainerPATCH 15/22 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.1
Arnaldo Carvalho de Melo
maintainerPATCH 16/22 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.1
Arnaldo Carvalho de Melo
maintainerPATCH 17/22 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.1
Arnaldo Carvalho de Melo
maintainerPATCH 18/22 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.1
Arnaldo Carvalho de Melo
maintainerPATCH 19/22 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.1
Arnaldo Carvalho de Melo
maintainerPATCH 20/22 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.1
Arnaldo Carvalho de Melo
maintainerPATCH 21/22 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.1
Arnaldo Carvalho de Melo
maintainerPATCH 22/22 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.1