perf/core improvements and fixes
Subsystems (3)
Arnaldo Carvalho de Melo
maintainerHi Ingo,
Please consider pulling, build tested on:
# perf stat -e cycles dm alldeps-ubuntu-12.04: Ok minimal-debian-experimental-x-mips64: Ok minimal-debian-experimental-x-mips64el: Ok minimal-debian-experimental-x-mipsel: Ok minimal-ubuntu-x-arm: Ok minimal-ubuntu-x-arm64: Ok minimal-ubuntu-x-ppc64: Ok minimal-ubuntu-x-ppc64el: Ok alldeps-debian: Ok alldeps-mageia: Ok alldeps-rhel7: Ok alldeps-centos: Ok alldeps-opensuse: Ok alldeps-ubuntu: Ok
Performance counter stats for 'dm':
3,095,685,547 cycles
454.805537820 seconds time elapsed#
'perf test' passes on fedora23 x86_64,
Thanks,
- Arnaldo
The following changes since commit dad38ca64a252144b4ccdfe9730a3fe2b7c61957:
Merge tag 'perf-core-for-mingo-20160401' of git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux into perf/core (2016-04-06 08:46:23 +0200)
are available in the git repository at:
git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux.git tags/perf-core-for-mingo-20160407
for you to fetch changes up to 98c3d844cd0bc56d33800114e6b6adcd0a5ec381:
perf symbols: Adjust symbol for shared objects (2016-04-07 17:17:01 -0300)
----------------------------------------------------------------
perf/core improvements and fixes:
User visible:
- Beautify more syscall arguments in 'perf trace', using the type column in tracepoint /format fields to attach, for instance, a pid_t resolver to the thread COMM, also attach a mode_t beautifier in the same fashion (Arnaldo Carvalho de Melo)
- Build the syscall table id <-> name resolver using the same .tbl file used in the kernel to generate headers, to avoid the delay in getting new syscalls supported in the audit-libs external dependency, done so far only for x86_64 (Arnaldo Carvalho de Melo)
- Improve the documentation of event specifications (Andi Kleen)
- Process update events in 'perf script', fixing up this use case:
# perf stat -a -I 1000 -e cycles record | perf script -s script.py
- Shared object symbol adjustment fixes, fixing symbol resolution in Android (Wang Nan)
Infrastructure:
- Add dedicated unwind addr_space member into thread struct, to allow tools to use thread->priv, noticed while working on having callchains in 'perf trace' (Jiri Olsa)
Build fixes:
- Fix the build in Ubuntu 12.04 (Arnaldo Carvalho de Melo, Vinson Lee)
----------------------------------------------------------------
Andi Kleen (1):
perf list: Document event specifications better
Arnaldo Carvalho de Melo (11):
perf probe: Check if dwarf_getlocations() is available
perf script perl: Do error checking on new backtrace routine perf trace: Beautify sched_setscheduler 'policy' argument
perf trace: Beautify wait4/waitid 'options' argument
perf trace: Infrastructure to show COMM strings for syscalls returning PIDs perf trace: Beautify set_tid_address, getpid, getppid return values perf trace: Beautify pid_t arguments
perf trace: Beautify mode_t arguments
perf trace: Move syscall table id <-> name routines to separate class perf tools: Allow generating per-arch syscall table arrays perf tools: Build syscall table .c header from kernel's syscall_64.tbl
Jiri Olsa (4):
perf tools: Remove superfluous ARCH Makefile includes perf tools: Introduce trim function
perf tools: Add dedicated unwind addr_space member into thread struct perf script: Process event update events
Vinson Lee (1):
perf config: Fix build with older toolchain.
Wang Nan (2):
perf symbols: Record text offset in dso to calculate objdump address perf symbols: Adjust symbol for shared objects
tools/build/Makefile.feature | 2 + tools/build/feature/Makefile | 4 + tools/build/feature/test-all.c | 5 + tools/build/feature/test-dwarf_getlocations.c | 12 + tools/perf/Documentation/perf-list.txt | 107 +++++- tools/perf/Makefile.perf | 13 +- tools/perf/arch/x86/Makefile | 23 ++ tools/perf/arch/x86/entry/syscalls/syscall_64.tbl | 374 +++++++++++++++++++++ tools/perf/arch/x86/entry/syscalls/syscalltbl.sh | 39 +++ tools/perf/builtin-script.c | 1 + tools/perf/builtin-trace.c | 156 +++++---- tools/perf/config/Makefile | 11 +- tools/perf/trace/beauty/mode_t.c | 68 ++++ tools/perf/trace/beauty/pid.c | 18 + tools/perf/trace/beauty/sched_policy.c | 44 +++ tools/perf/trace/beauty/waitid_options.c | 26 ++ tools/perf/ui/browsers/hists.c | 3 +- tools/perf/ui/stdio/hist.c | 3 +- tools/perf/util/Build | 5 + tools/perf/util/config.c | 6 +- tools/perf/util/dwarf-aux.c | 9 + tools/perf/util/map.c | 14 + .../perf/util/scripting-engines/trace-event-perl.c | 30 +- tools/perf/util/symbol-elf.c | 13 +- tools/perf/util/syscalltbl.c | 134 ++++++++ tools/perf/util/syscalltbl.h | 20 ++ tools/perf/util/thread.h | 6 + tools/perf/util/unwind-libunwind.c | 25 +- tools/perf/util/util.h | 5 + 29 files changed, 1060 insertions(+), 116 deletions(-) create mode 100644 tools/build/feature/test-dwarf_getlocations.c create mode 100644 tools/perf/arch/x86/entry/syscalls/syscall_64.tbl create mode 100755 tools/perf/arch/x86/entry/syscalls/syscalltbl.sh create mode 100644 tools/perf/trace/beauty/mode_t.c create mode 100644 tools/perf/trace/beauty/pid.c create mode 100644 tools/perf/trace/beauty/sched_policy.c create mode 100644 tools/perf/trace/beauty/waitid_options.c create mode 100644 tools/perf/util/syscalltbl.c create mode 100644 tools/perf/util/syscalltbl.h
Arnaldo Carvalho de Melo
maintainerPATCH 1/19 perf config: Fix build with older toolchain.
From: Vinson Lee <[email protected]>
Fix build error on Ubuntu 12.04.5 with GCC 4.6.3.
CC util/config.o
util/config.c: In function ‘perf_buildid_config’:
util/config.c:384:15: error: declaration of ‘dirname’ shadows a global declaration [-Werror=shadow]
--- tools/perf/util/config.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
tools/perf/util/config.c +3 -3
@@ -381,11 +381,11 @@ static int perf_buildid_config(const char *var, const char *value) {/* same dir for all commands */ if (!strcmp (var,"buildid.dir" )) { -const char *dirname =perf_config_dirname (var, value); +const char *dir =perf_config_dirname (var, value); -if (!dirname) +if (!dir)return -1 ; -strncpy (buildid_dir, dirname,MAXPATHLEN -1 ); +strncpy (buildid_dir, dir,MAXPATHLEN -1 ); buildid_dir[MAXPATHLEN -1 ] ='\0' ; }
Signature · 1 line
2.5.5
Arnaldo Carvalho de Melo
maintainerPATCH 2/19 perf probe: Check if dwarf_getlocations() is available
In reply to Arnaldo Carvalho de MeloFrom: Arnaldo Carvalho de Melo <[email protected]>
If not, tell the user that:
config/Makefile:273: Old libdw.h, finding variables at given 'perf probe' point will not work, install elfutils-devel/libdw-dev >= 0.157
And return -ENOTSUPP in die_get_var_range(), failing features that need it, like the one pointed out above.
This fixes the build on older systems, such as Ubuntu 12.04.5.
--- tools/build/Makefile.feature | 2 ++ tools/build/feature/Makefile | 4 ++++ tools/build/feature/test-all.c | 5 +++++ tools/build/feature/test-dwarf_getlocations.c | 12 ++++++++++++ tools/perf/config/Makefile | 6 ++++++ tools/perf/util/dwarf-aux.c | 9 +++++++++ 6 files changed, 38 insertions(+) create mode 100644 tools/build/feature/test-dwarf_getlocations.c
tools/build/Makefile.feature +2 -0
@@ -30,6 +30,7 @@ endef FEATURE_TESTS_BASIC := \ backtrace \ dwarf \ + dwarf_getlocations \ fortify-source \ sync-compare-and-swap \ glibc \
@@ -78,6 +79,7 @@ endif FEATURE_DISPLAY ?= \ dwarf \ + dwarf_getlocations \ glibc \ gtk2 \ libaudit \
tools/build/feature/Makefile +4 -0
@@ -3,6 +3,7 @@ FILES= \ test-backtrace.bin \ test-bionic.bin \ test-dwarf.bin \ + test-dwarf_getlocations.bin \ test-fortify-source.bin \ test-sync-compare-and-swap.bin \ test-glibc.bin \
@@ -82,6 +83,9 @@ endif $(OUTPUT)test-dwarf.bin: $(BUILD) $(DWARFLIBS) +$(OUTPUT)test-dwarf_getlocations.bin: + $(BUILD) $(DWARFLIBS) + $(OUTPUT)test-libelf-mmap.bin: $(BUILD) -lelf
tools/build/feature/test-all.c +5 -0
@@ -41,6 +41,10 @@# include "test-dwarf.c" #undef main +#define main main_test_dwarf_getlocations +# include "test-dwarf_getlocations.c" +#undef main +#define main main_test_libelf_getphdrnum# include "test-libelf-getphdrnum.c" #undef main
@@ -143,6 +147,7 @@ int main(int argc, char *argv[])main_test_libelf_mmap ();main_test_glibc ();main_test_dwarf (); +main_test_dwarf_getlocations ();main_test_libelf_getphdrnum ();main_test_libunwind ();main_test_libaudit ();
tools/build/feature/test-dwarf_getlocations.c new file +12 -0
@@ -0,0 +1,12 @@ +#include <stdlib.h> +#include <elfutils/libdw.h> + +int main (void ) +{ +Dwarf_Addr base, start, end; +Dwarf_Attribute attr; +Dwarf_Op *op; +size_t nops; +ptrdiff_t offset =0 ; +return (int )dwarf_getlocations (&attr, offset, &base, &start, &end, &op, &nops); +}
tools/perf/config/Makefile +6 -0
@@ -268,6 +268,12 @@ else ifneq ($(feature-dwarf), 1) msg := $(warning No libdw.h found or old libdw.h found or elfutils is older than 0.138, disables dwarf support. Please install new elfutils-devel/libdw-dev); NO_DWARF := 1 + else + ifneq ($(feature-dwarf_getlocations), 1) + msg := $(warning Old libdw.h, finding variables at given 'perf probe' point will not work, install elfutils-devel/libdw-dev >= 0.157); + else + CFLAGS += -DHAVE_DWARF_GETLOCATIONS + endif # dwarf_getlocations endif # Dwarf support endif # libelf support endif # NO_LIBELF
tools/perf/util/dwarf-aux.c +9 -0
@@ -959,6 +959,7 @@ int die_get_varname(Dwarf_Die *vr_die, struct strbuf *buf)return 0 ; } +#ifdef HAVE_DWARF_GETLOCATIONS /** * die_get_var_innermost_scope - Get innermost scope range of given variable DIE * @sp_die: a subprogram DIE
@@ -1080,3 +1081,11 @@ int die_get_var_range(Dwarf_Die *sp_die, Dwarf_Die *vr_die, struct strbuf *buf) return ret; } +#else +int die_get_var_range (Dwarf_Die *sp_die__maybe_unused , +Dwarf_Die *vr_die__maybe_unused , +struct strbuf *buf__maybe_unused ) +{ +return -ENOTSUP ; +} +#endif
Signature · 1 line
2.5.5
Arnaldo Carvalho de Melo
maintainerPATCH 3/19 perf script perl: Do error checking on new backtrace routine
In reply to Arnaldo Carvalho de MeloFrom: Arnaldo Carvalho de Melo <[email protected]>
This ended up triggering these warnings when building on Ubuntu 12.04.5:
util/scripting-engines/trace-event-perl.c: In function 'perl_process_callchain':
util/scripting-engines/trace-event-perl.c:293:4: error: value computed is not used [-Werror=unused-value] util/scripting-engines/trace-event-perl.c:294:4: error: value computed is not used [-Werror=unused-value] util/scripting-engines/trace-event-perl.c:295:4: error: value computed is not used [-Werror=unused-value] util/scripting-engines/trace-event-perl.c:297:4: error: value computed is not used [-Werror=unused-value] util/scripting-engines/trace-event-perl.c:309:4: error: value computed is not used [-Werror=unused-value]
cc1: all warnings being treated as errors
mv: cannot stat `/tmp/build/perf/util/scripting-engines/.trace-event-perl.o.tmp': No such file or directory make[4]: *** [/tmp/build/perf/util/scripting-engines/trace-event-perl.o] Error 1
Fix it by doing error checking when building the perl data structures related to callchains.
--- .../perf/util/scripting-engines/trace-event-perl.c | 30 +++++++++++++++------- 1 file changed, 21 insertions(+), 9 deletions(-)
tools/perf/util/scripting-engines/trace-event-perl.c +21 -9
@@ -283,18 +283,27 @@ static SV *perl_process_callchain(struct perf_sample *sample,if (!elem) goto exit; -hv_stores (elem,"ip" ,newSVuv (node->ip)); +if (!hv_stores (elem,"ip" ,newSVuv (node->ip))) { +hv_undef (elem); + goto exit; + }if (node->sym) {HV *sym =newHV (); -if (!sym) +if (!sym) { +hv_undef (elem); + goto exit; + } +if (!hv_stores (sym,"start" ,newSVuv (node->sym->start)) || + !hv_stores (sym,"end" ,newSVuv (node->sym->end)) || + !hv_stores (sym,"binding" ,newSVuv (node->sym->binding)) || + !hv_stores (sym,"name" ,newSVpvn (node->sym->name, + node->sym->namelen)) || + !hv_stores (elem,"sym" ,newRV_noinc ((SV *)sym))) { +hv_undef (sym); +hv_undef (elem); goto exit; -hv_stores (sym,"start" ,newSVuv (node->sym->start)); -hv_stores (sym,"end" ,newSVuv (node->sym->end)); -hv_stores (sym,"binding" ,newSVuv (node->sym->binding)); -hv_stores (sym,"name" ,newSVpvn (node->sym->name, - node->sym->namelen)); -hv_stores (elem,"sym" ,newRV_noinc ((SV *)sym)); + } }if (node->map) {
@@ -306,7 +315,10 @@ static SV *perl_process_callchain(struct perf_sample *sample,else if (map->dso->name) dsoname = map->dso->name; } -hv_stores (elem,"dso" ,newSVpv (dsoname,0 )); +if (!hv_stores (elem,"dso" ,newSVpv (dsoname,0 ))) { +hv_undef (elem); + goto exit; + } }callchain_cursor_advance (&callchain_cursor);
Signature · 1 line
2.5.5
Arnaldo Carvalho de Melo
maintainerPATCH 4/19 perf tools: Remove superfluous ARCH Makefile includes
In reply to Arnaldo Carvalho de MeloFrom: Jiri Olsa <[email protected]>
--- tools/perf/Makefile.perf | 2 -- tools/perf/config/Makefile | 3 --- 2 files changed, 5 deletions(-)
tools/perf/Makefile.perf +0 -2
@@ -297,8 +297,6 @@ endif # because maintaining the nesting to match is a pain. If # we had "elif" things would have been much nicer... --include arch/$(ARCH)/Makefile - ifneq ($(OUTPUT),) CFLAGS += -I$(OUTPUT) endif
tools/perf/config/Makefile +0 -3
@@ -295,9 +295,6 @@ ifndef NO_LIBELF CFLAGS += -DHAVE_ELF_GETPHDRNUM_SUPPORT endif - # include ARCH specific config - -include $(src-perf)/arch/$(ARCH)/Makefile - ifndef NO_DWARF ifeq ($(origin PERF_HAVE_DWARF_REGS), undefined) msg := $(warning DWARF register mappings have not been defined for architecture $(ARCH), DWARF support disabled);
Signature · 1 line
2.5.5
Arnaldo Carvalho de Melo
maintainerPATCH 5/19 perf list: Document event specifications better
In reply to Arnaldo Carvalho de MeloFrom: Andi Kleen <[email protected]>
Document some features for specifying events in the perf list manpage:
- Event groups
- Leader sampling
- How to specify raw PMU events in the new syntax
- Global versus per process PMUs.
- Access restrictions
- Fix Intel SDM URL
v2: Lots of new content. address review feedback.
--- tools/perf/Documentation/perf-list.txt | 107 ++++++++++++++++++++++++++++++++- 1 file changed, 106 insertions(+), 1 deletion(-)
tools/perf/Documentation/perf-list.txt +106 -1
@@ -93,6 +93,67 @@ raw encoding of 0x1A8 can be used: You should refer to the processor specific documentation for getting these details. Some of them are referenced in the SEE ALSO section below. +ARBITRARY PMUS +-------------- + +perf also supports an extended syntax for specifying raw parameters +to PMUs. Using this typically requires looking up the specific event +in the CPU vendor specific documentation. + +The available PMUs and their raw parameters can be listed with + + ls /sys/devices/*/format + +For example the raw event "LSD.UOPS" core pmu event above could +be specified as + + perf stat -e cpu/event=0xa8,umask=0x1,name=LSD.UOPS_CYCLES,cmask=1/ ... + +PER SOCKET PMUS +--------------- + +Some PMUs are not associated with a core, but with a whole CPU socket. +Events on these PMUs generally cannot be sampled, but only counted globally +with perf stat -a. They can be bound to one logical CPU, but will measure +all the CPUs in the same socket. + +This example measures memory bandwidth every second +on the first memory controller on socket 0 of a Intel Xeon system + + perf stat -C 0 -a uncore_imc_0/cas_count_read/,uncore_imc_0/cas_count_write/ -I 1000 ... + +Each memory controller has its own PMU. Measuring the complete system +bandwidth would require specifying all imc PMUs (see perf list output), +and adding the values together. + +This example measures the combined core power every second + + perf stat -I 1000 -e power/energy-cores/ -a + +ACCESS RESTRICTIONS +------------------- + +For non root users generally only context switched PMU events are available. +This is normally only the events in the cpu PMU, the predefined events +like cycles and instructions and some software events. + +Other PMUs and global measurements are normally root only. +Some event qualifiers, such as "any", are also root only. + +This can be overriden by setting the kernel.perf_event_paranoid +sysctl to -1, which allows non root to use these events. + +For accessing trace point events perf needs to have read access to +/sys/kernel/debug/tracing, even when perf_event_paranoid is in a relaxed +setting. + +TRACING +------- + +Some PMUs control advanced hardware tracing capabilities, such as Intel PT, +that allows low overhead execution tracing. These are described in a separate +intel-pt.txt document. + PARAMETERIZED EVENTS --------------------
@@ -106,6 +167,50 @@ also be supplied. For example: perf stat -C 0 -e 'hv_gpci/dtbp_ptitc,phys_processor_idx=0x2/' ... +EVENT GROUPS +------------ + +Perf supports time based multiplexing of events, when the number of events +active exceeds the number of hardware performance counters. Multiplexing +can cause measurement errors when the workload changes its execution +profile. + +When metrics are computed using formulas from event counts, it is useful to +ensure some events are always measured together as a group to minimize multiplexing +errors. Event groups can be specified using { }. + + perf stat -e '{instructions,cycles}' ... + +The number of available performance counters depend on the CPU. A group +cannot contain more events than available counters. +For example Intel Core CPUs typically have four generic performance counters +for the core, plus three fixed counters for instructions, cycles and +ref-cycles. Some special events have restrictions on which counter they +can schedule, and may not support multiple instances in a single group. +When too many events are specified in the group none of them will not +be measured. + +Globally pinned events can limit the number of counters available for +other groups. On x86 systems, the NMI watchdog pins a counter by default. +The nmi watchdog can be disabled as root with + + echo 0 > /proc/sys/kernel/nmi_watchdog + +Events from multiple different PMUs cannot be mixed in a group, with +some exceptions for software events. + +LEADER SAMPLING +--------------- + +perf also supports group leader sampling using the :S specifier. + + perf record -e '{cycles,instructions}:S' ... + perf report --group + +Normally all events in a event group sample, but with :S only +the first event (the leader) samples, and it only reads the values of the +other events in the group. + OPTIONS -------
@@ -143,5 +248,5 @@ SEE ALSO -------- linkperf:perf-stat[1], linkperf:perf-top[1], linkperf:perf-record[1], -http://www.intel.com/Assets/PDF/manual/253669.pdf[Intel® 64 and IA-32 Architectures Software Developer's Manual Volume 3B: System Programming Guide], +http://www.intel.com/sdm/[Intel® 64 and IA-32 Architectures Software Developer's Manual Volume 3B: System Programming Guide], http://support.amd.com/us/Processor_TechDocs/24593_APM_v2.pdf[AMD64 Architecture Programmer’s Manual Volume 2: System Programming]
Signature · 1 line
2.5.5
Arnaldo Carvalho de Melo
maintainerPATCH 6/19 perf trace: Beautify sched_setscheduler 'policy' argument
In reply to Arnaldo Carvalho de MeloFrom: Arnaldo Carvalho de Melo <[email protected]>
$ trace -e sched_setscheduler chrt -f 1 usleep 1
chrt: failed to set pid 0's policy: Operation not permitted
0.005 ( 0.005 ms): chrt/19189 sched_setscheduler(policy: FIFO, param: 0x7ffec5273d70) = -1 EPERM Operation not permitted
$--- tools/perf/builtin-trace.c | 4 ++++ tools/perf/trace/beauty/sched_policy.c | 44 ++++++++++++++++++++++++++++++++++ 2 files changed, 48 insertions(+) create mode 100644 tools/perf/trace/beauty/sched_policy.c
tools/perf/builtin-trace.c +4 -0
@@ -1073,6 +1073,8 @@ static size_t syscall_arg__scnprintf_getrandom_flags(char *bf, size_t size, .arg_scnprintf = { [arg] = SCA_STRARRAY, }, \ .arg_parm = { [arg] = &strarray__##array, } +#include "trace/beauty/sched_policy.c" + static struct syscall_fmt { const char *name; const char *alias;
@@ -1304,6 +1306,8 @@ static struct syscall_fmt { .arg_scnprintf = { [1] = SCA_SIGNUM, /* sig */ }, }, { .name = "rt_tgsigqueueinfo", .errmsg = true, .arg_scnprintf = { [2] = SCA_SIGNUM, /* sig */ }, }, + { .name = "sched_setscheduler", .errmsg = true, + .arg_scnprintf = { [1] = SCA_SCHED_POLICY, /* policy */ }, }, { .name = "seccomp", .errmsg = true, .arg_scnprintf = { [0] = SCA_SECCOMP_OP, /* op */ [1] = SCA_SECCOMP_FLAGS, /* flags */ }, },
tools/perf/trace/beauty/sched_policy.c new file +44 -0
44 lines not on this page · raw message
Signature · 1 line
2.5.5
Arnaldo Carvalho de Melo
maintainerPATCH 7/19 perf trace: Beautify wait4/waitid 'options' argument
In reply to Arnaldo Carvalho de MeloFrom: Arnaldo Carvalho de Melo <[email protected]>
# trace -e waitid,wait4
0.557 ( 0.557 ms): bash/27335 wait4(upid: -1, stat_addr: 0x7ffd02f449f0) = 27336
1.250 ( 0.685 ms): bash/27335 wait4(upid: -1, stat_addr: 0x7ffd02f449f0) = 27337
1.312 ( 0.002 ms): bash/27335 wait4(upid: -1, stat_addr: 0x7ffd02f44690, options: NOHANG) = -1 ECHILD No child processes
1.550 ( 0.015 ms): bash/3856 wait4(upid: -1, stat_addr: 0x7ffd02f44990, options: NOHANG|UNTRACED|CONTINUED) = 27335 1.552 ( 0.001 ms): bash/3856 wait4(upid: -1, stat_addr: 0x7ffd02f44990, options: NOHANG|UNTRACED|CONTINUED) = 0
#
--- tools/perf/builtin-trace.c | 5 +++++ tools/perf/trace/beauty/waitid_options.c | 26 ++++++++++++++++++++++++++ 2 files changed, 31 insertions(+) create mode 100644 tools/perf/trace/beauty/waitid_options.c
tools/perf/builtin-trace.c +5 -0
@@ -1074,6 +1074,7 @@ static size_t syscall_arg__scnprintf_getrandom_flags(char *bf, size_t size, .arg_parm = { [arg] = &strarray__##array, }#include "trace/beauty/sched_policy.c" +#include "trace/beauty/waitid_options.c" static struct syscall_fmt { const char *name;
@@ -1364,6 +1365,10 @@ static struct syscall_fmt { .arg_scnprintf = { [0] = SCA_FILENAME, /* filename */ }, }, { .name = "vmsplice", .errmsg = true, .arg_scnprintf = { [0] = SCA_FD, /* fd */ }, }, + { .name = "wait4", .errmsg = true, + .arg_scnprintf = { [2] = SCA_WAITID_OPTIONS, /* options */ }, }, + { .name = "waitid", .errmsg = true, + .arg_scnprintf = { [3] = SCA_WAITID_OPTIONS, /* options */ }, }, { .name = "write", .errmsg = true, .arg_scnprintf = { [0] = SCA_FD, /* fd */ }, }, { .name = "writev", .errmsg = true,
tools/perf/trace/beauty/waitid_options.c new file +26 -0
@@ -0,0 +1,26 @@ +#include <sys/types.h> +#include <sys/wait.h> + +static size_t syscall_arg__scnprintf_waitid_options (char *bf,size_t size, +struct syscall_arg *arg) +{ +int printed =0 , options = arg->val; + +#define P_OPTION (n) \ + if (options & W##n) { \ + printed += scnprintf(bf + printed, size - printed, "%s%s", printed ? "|" : "", #n); \ + options &= ~W##n; \ + } + +P_OPTION (NOHANG ); +P_OPTION (UNTRACED ); +P_OPTION (CONTINUED ); +#undef P_OPTION + +if (options) + printed +=scnprintf (bf + printed, size - printed,"%s%#x" , printed ?"|" :"" , options); + +return printed; +} + +#define SCA_WAITID_OPTIONS syscall_arg__scnprintf_waitid_options
Signature · 1 line
2.5.5
Arnaldo Carvalho de Melo
maintainerPATCH 8/19 perf trace: Infrastructure to show COMM strings for syscalls returning PIDs
In reply to Arnaldo Carvalho de MeloFrom: Arnaldo Carvalho de Melo <[email protected]>
Starting with clone, waitid and wait4:
# trace -e waitid,wait4
1.385 ( 1.385 ms): bash/12122 wait4(upid: -1, stat_addr: 0x7ffe0cee1720, options: UNTRACED|CONTINUED) = 1210 (ls)
1.426 ( 0.002 ms): bash/12122 wait4(upid: -1, stat_addr: 0x7ffe0cee1150, options: NOHANG|UNTRACED|CONTINUED) = 0
3.293 ( 0.604 ms): bash/1211 wait4(upid: -1, stat_addr: 0x7ffe0cee0560 ) = 1214 (sed)
3.342 ( 0.002 ms): bash/1211 wait4(upid: -1, stat_addr: 0x7ffe0cee01d0, options: NOHANG ) = -1 ECHILD No child processes
3.576 ( 0.016 ms): bash/12122 wait4(upid: -1, stat_addr: 0x7ffe0cee0550, options: NOHANG|UNTRACED|CONTINUED) = 1211 (bash)
^C# trace -e clone
0.027 ( 0.000 ms): systemd/1 ... [continued]: clone()) = 1227 (systemd)
0.050 ( 0.000 ms): systemd/1227 ... [continued]: clone()) = 0
^C[root@jouet ~]#--- tools/perf/builtin-trace.c | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-)
tools/perf/builtin-trace.c +15 -4
@@ -1082,6 +1082,7 @@ static struct syscall_fmt {size_t (*arg_scnprintf[6 ])(char *bf,size_t size,struct syscall_arg *arg);void *arg_parm[6 ];bool errmsg; +bool errpid;bool timeout;bool hexret; } syscall_fmts[] = {
@@ -1099,6 +1100,7 @@ static struct syscall_fmt { { .name = "chroot", .errmsg = true, .arg_scnprintf = { [0] = SCA_FILENAME, /* filename */ }, }, { .name = "clock_gettime", .errmsg = true, STRARRAY(0, clk_id, clockid), }, + { .name = "clone", .errpid = true, }, { .name = "close", .errmsg = true, .arg_scnprintf = { [0] = SCA_CLOSE_FD, /* fd */ }, }, { .name = "connect", .errmsg = true, },
@@ -1365,9 +1367,9 @@ static struct syscall_fmt { .arg_scnprintf = { [0] = SCA_FILENAME, /* filename */ }, }, { .name = "vmsplice", .errmsg = true, .arg_scnprintf = { [0] = SCA_FD, /* fd */ }, }, - { .name = "wait4", .errmsg = true, + { .name = "wait4", .errpid = true, .arg_scnprintf = { [2] = SCA_WAITID_OPTIONS, /* options */ }, }, - { .name = "waitid", .errmsg = true, + { .name = "waitid", .errpid = true, .arg_scnprintf = { [3] = SCA_WAITID_OPTIONS, /* options */ }, }, { .name = "write", .errmsg = true, .arg_scnprintf = { [0] = SCA_FD, /* fd */ }, },
@@ -2156,7 +2158,7 @@ static int trace__sys_exit(struct trace *trace, struct perf_evsel *evsel,if (sc->fmt ==NULL ) { signed_print:fprintf (trace->output,") = %ld" , ret); - }else if (ret <0 && sc->fmt->errmsg) { + }else if (ret <0 && (sc->fmt->errmsg || sc->fmt->errpid)) {char bf[STRERR_BUFSIZE ];const char *emsg =strerror_r (-ret, bf,sizeof (bf)), *e =audit_errno_to_name (-ret);
@@ -2166,7 +2168,16 @@ signed_print:fprintf (trace->output,") = 0 Timeout" ); else if (sc->fmt->hexret) fprintf(trace->output, ") = %#lx", ret); - else + else if (sc->fmt->errpid) { +struct thread *child =machine__find_thread (trace->host, ret, ret); + +if (child !=NULL ) { +fprintf (trace->output,") = %ld" , ret); +if (child->comm_set) +fprintf (trace->output," (%s)" ,thread__comm_str (child)); +thread__put (child); + } + } else goto signed_print;fputc ('\n' , trace->output);
Signature · 1 line
2.5.5
Arnaldo Carvalho de Melo
maintainerPATCH 9/19 perf trace: Beautify set_tid_address, getpid, getppid return values
In reply to Arnaldo Carvalho de MeloFrom: Arnaldo Carvalho de Melo <[email protected]>
Showing the COMM for that return, if available.
# trace -e getpid,getppid,set_tid_address
490.007 ( 0.005 ms): sh/8250 getpid(...) = 8250 (sh)
490.014 ( 0.001 ms): sh/8250 getppid(...) = 7886 (make)
491.156 ( 0.004 ms): install/8251 set_tid_address(tidptr: 0x7f204a9d4ad0) = 8251 (install)
^C--- tools/perf/builtin-trace.c | 3 +++ 1 file changed, 3 insertions(+)
tools/perf/builtin-trace.c +3 -0
@@ -1166,6 +1166,8 @@ static struct syscall_fmt { { .name = "getdents64", .errmsg = true, .arg_scnprintf = { [0] = SCA_FD, /* fd */ }, }, { .name = "getitimer", .errmsg = true, STRARRAY(0, which, itimers), }, + { .name = "getpid", .errpid = true, }, + { .name = "getppid", .errpid = true, }, { .name = "getrandom", .errmsg = true, .arg_scnprintf = { [2] = SCA_GETRANDOM_FLAGS, /* flags */ }, }, { .name = "getrlimit", .errmsg = true, STRARRAY(0, resource, rlimit_resources), },
@@ -1324,6 +1326,7 @@ static struct syscall_fmt { { .name = "sendto", .errmsg = true, .arg_scnprintf = { [0] = SCA_FD, /* fd */ [3] = SCA_MSG_FLAGS, /* flags */ }, }, + { .name = "set_tid_address", .errpid = true, }, { .name = "setitimer", .errmsg = true, STRARRAY(0, which, itimers), }, { .name = "setrlimit", .errmsg = true, STRARRAY(0, resource, rlimit_resources), }, { .name = "setxattr", .errmsg = true,
Signature · 1 line
2.5.5
Arnaldo Carvalho de Melo
maintainerPATCH 10/19 perf trace: Beautify pid_t arguments
In reply to Arnaldo Carvalho de MeloFrom: Arnaldo Carvalho de Melo <[email protected]>
When reading the syscall tracepoint /format file, look for arguments of type "pid_t" and attach the PID beautifier, that will do a lookup on the threads it knows, i.e. the ones that came from PERF_RECORD_COMM events and add the COMM after the pid in such args:
Excerpt of a system wide trace for syscalls with pid_t args:
55602.977 ( 0.006 ms): bash/12122 setpgid(pid: 24347 (bash), pgid: 24347 (bash)) = 0
55603.024 ( 0.004 ms): bash/24347 setpgid(pid: 24347 (bash), pgid: 24347 (bash)) = 0
55691.527 (88.397 ms): bash/12122 wait4(upid: -1, stat_addr: 0x7ffe0cee1720, options: UNTRACED|CONTINUED) ... 55692.479 ( 0.952 ms): git/24347 wait4(upid: 24368, stat_addr: 0x7ffe030d5724) ...
55694.549 ( 2.070 ms): pre-commit/24368 wait4(upid: -1, stat_addr: 0x7ffc94f4fc10) = 24369 (pre-commit) 55694.575 ( 0.002 ms): pre-commit/24368 wait4(upid: -1, stat_addr: 0x7ffc94f4f650, options: NOHANG) = -1 ECHILD No child processes 55695.934 ( 0.010 ms): pre-commit/24368 wait4(upid: -1, stat_addr: 0x7ffc94f4f2d0, options: NOHANG) = 24370 (git) 55695.937 ( 0.001 ms): pre-commit/24368 wait4(upid: -1, stat_addr: 0x7ffc94f4f2d0, options: NOHANG) = -1 ECHILD No child processes 55717.963 ( 0.000 ms): pre-commit/24371 ... [continued]: wait4()) = 24372
55717.978 (21.468 ms): :24371/24371 wait4(upid: -1, stat_addr: 0x7ffc94f4f230) ...
55718.087 ( 0.109 ms): pre-commit/24371 wait4(upid: -1, stat_addr: 0x7ffc94f4f230) = 24373 (tr)
55718.187 ( 0.096 ms): pre-commit/24371 wait4(upid: -1, stat_addr: 0x7ffc94f4f230) = 24374 (wc)
55718.218 ( 0.002 ms): pre-commit/24371 wait4(upid: -1, stat_addr: 0x7ffc94f4eed0, options: NOHANG) = -1 ECHILD No child processes 55718.367 ( 0.005 ms): pre-commit/24368 wait4(upid: -1, stat_addr: 0x7ffc94f4f1d0, options: NOHANG) = 24371 (pre-commit) 55718.369 ( 0.001 ms): pre-commit/24368 wait4(upid: -1, stat_addr: 0x7ffc94f4f1d0, options: NOHANG) = -1 ECHILD No child processes 55741.021 (49.494 ms): git/24347 ... [continued]: wait4()) = 24368 (pre-commit)
74146.427 (18319.601 ms): git/24347 wait4(upid: 24375 (git), stat_addr: 0x7ffe030d6824) ...
74149.036 ( 0.891 ms): bash/24391 wait4(upid: -1, stat_addr: 0x7ffe0cee0560) = 24393 (sed)
--- tools/perf/builtin-trace.c | 110 ++++++++++++++++++++++-------------------- tools/perf/trace/beauty/pid.c | 18 +++++++ 2 files changed, 75 insertions(+), 53 deletions(-) create mode 100644 tools/perf/trace/beauty/pid.c
tools/perf/builtin-trace.c +57 -53
@@ -112,6 +112,58 @@# define PERF_FLAG_FD_CLOEXEC (1UL << 3)/* O_CLOEXEC */ #endif +struct trace { +struct perf_tool tool; +struct { +int machine; +int open_id; + } audit; +struct { +int max; +struct syscall *table; +struct { +struct perf_evsel *sys_enter, + *sys_exit; + } events; + } syscalls; +struct record_opts opts; +struct perf_evlist *evlist; +struct machine *host; +struct thread *current; +u64 base_time; +FILE *output; +unsigned long nr_events; +struct strlist *ev_qualifier; +struct { +size_t nr; +int *entries; + } ev_qualifier_ids; +struct intlist *tid_list; +struct intlist *pid_list; +struct { +size_t nr; +pid_t *entries; + } filter_pids; +double duration_filter; +double runtime_ms; +struct { +u64 vfs_getname, + proc_getname; + } stats; +bool not_ev_qualifier; +bool live; +bool full_time; +bool sched; +bool multiple_threads; +bool summary; +bool summary_only; +bool show_comm; +bool show_tool_stats; +bool trace_syscalls; +bool force; +bool vfs_getname; +int trace_pgfaults; +};struct tp_field {int offset;
@@ -1073,6 +1125,7 @@ static size_t syscall_arg__scnprintf_getrandom_flags(char *bf, size_t size, .arg_scnprintf = { [arg] = SCA_STRARRAY, }, \ .arg_parm = { [arg] = &strarray__##array, } +#include "trace/beauty/pid.c" #include "trace/beauty/sched_policy.c" #include "trace/beauty/waitid_options.c"
@@ -1167,6 +1220,7 @@ static struct syscall_fmt { .arg_scnprintf = { [0] = SCA_FD, /* fd */ }, }, { .name = "getitimer", .errmsg = true, STRARRAY(0, which, itimers), }, { .name = "getpid", .errpid = true, }, + { .name = "getpgid", .errpid = true, }, { .name = "getppid", .errpid = true, }, { .name = "getrandom", .errmsg = true, .arg_scnprintf = { [2] = SCA_GETRANDOM_FLAGS, /* flags */ }, },
@@ -1328,6 +1382,7 @@ static struct syscall_fmt { [3] = SCA_MSG_FLAGS, /* flags */ }, }, { .name = "set_tid_address", .errpid = true, }, { .name = "setitimer", .errmsg = true, STRARRAY(0, which, itimers), }, + { .name = "setpgid", .errmsg = true, }, { .name = "setrlimit", .errmsg = true, STRARRAY(0, resource, rlimit_resources), }, { .name = "setxattr", .errmsg = true, .arg_scnprintf = { [0] = SCA_FILENAME, /* pathname */ }, },
@@ -1485,59 +1540,6 @@ fail:static const size_t trace__entry_str_size =2048 ; -struct trace { -struct perf_tool tool; -struct { -int machine; -int open_id; - } audit; -struct { -int max; -struct syscall *table; -struct { -struct perf_evsel *sys_enter, - *sys_exit; - } events; - } syscalls; -struct record_opts opts; -struct perf_evlist *evlist; -struct machine *host; -struct thread *current; -u64 base_time; -FILE *output; -unsigned long nr_events; -struct strlist *ev_qualifier; -struct { -size_t nr; -int *entries; - } ev_qualifier_ids; -struct intlist *tid_list; -struct intlist *pid_list; -struct { -size_t nr; -pid_t *entries; - } filter_pids; -double duration_filter; -double runtime_ms; -struct { -u64 vfs_getname, - proc_getname; - } stats; -bool not_ev_qualifier; -bool live; -bool full_time; -bool sched; -bool multiple_threads; -bool summary; -bool summary_only; -bool show_comm; -bool show_tool_stats; -bool trace_syscalls; -bool force; -bool vfs_getname; -int trace_pgfaults; -}; -static int trace__set_fd_pathname (struct thread *thread,int fd,const char *pathname) {struct thread_trace *ttrace =thread__priv (thread);
@@ -1763,6 +1765,8 @@ static int syscall__set_arg_fmts(struct syscall *sc) sc->arg_scnprintf[idx] = sc->fmt->arg_scnprintf[idx]; else if (field->flags & FIELD_IS_POINTER) sc->arg_scnprintf[idx] = syscall_arg__scnprintf_hex; + else if (strcmp(field->type, "pid_t") == 0) + sc->arg_scnprintf[idx] = SCA_PID; ++idx; }
tools/perf/trace/beauty/pid.c new file +18 -0
@@ -0,0 +1,18 @@ +static size_t syscall_arg__scnprintf_pid (char *bf,size_t size,struct syscall_arg *arg) +{ +int pid = arg->val; +struct trace *trace = arg->trace; +size_t printed =scnprintf (bf, size,"%d" , pid); +struct thread *thread =machine__find_thread (trace->host, pid, pid); + +if (thread !=NULL ) { +if (thread->comm_set) + printed +=scnprintf (bf + printed, size - printed, +" (%s)" ,thread__comm_str (thread)); +thread__put (thread); + } + +return printed; +} + +#define SCA_PID syscall_arg__scnprintf_pid
Signature · 1 line
2.5.5
Arnaldo Carvalho de Melo
maintainerPATCH 11/19 perf tools: Introduce trim function
In reply to Arnaldo Carvalho de MeloFrom: Jiri Olsa <[email protected]>
To be used in cases for both sides trim.
--- tools/perf/ui/browsers/hists.c | 3 +-- tools/perf/ui/stdio/hist.c | 3 +-- tools/perf/util/util.h | 5 +++++ 3 files changed, 7 insertions(+), 4 deletions(-)
tools/perf/ui/browsers/hists.c +1 -2
@@ -1607,9 +1607,8 @@ static int hists_browser__scnprintf_hierarchy_headers(struct hist_browser *brows ret = fmt->header (fmt, &dummy_hpp,hists_to_evsel (hists)); dummy_hpp.buf[ret] ='\0' ; -rtrim (dummy_hpp.buf); - start =ltrim (dummy_hpp.buf); + start =trim (dummy_hpp.buf); ret =strlen (start);if (start != dummy_hpp.buf)
tools/perf/ui/stdio/hist.c +1 -2
@@ -569,9 +569,8 @@ static int print_hierarchy_header(struct hists *hists, struct perf_hpp *hpp, first_col = false; fmt->header (fmt, hpp,hists_to_evsel (hists)); -rtrim (hpp->buf); - header_width +=fprintf (fp,"%s" ,ltrim (hpp->buf)); + header_width +=fprintf (fp,"%s" ,trim (hpp->buf)); } }
tools/perf/util/util.h +5 -0
@@ -254,6 +254,11 @@ int hex2u64(const char *ptr, u64 *val);char *ltrim (char *s);char *rtrim (char *s); +static inline char *trim (char *s) +{ +return ltrim (rtrim (s)); +} +void dump_stack (void );void sighandler_dump_stack (int sig);
Signature · 1 line
2.5.5
Arnaldo Carvalho de Melo
maintainerPATCH 12/19 perf tools: Add dedicated unwind addr_space member into thread struct
In reply to Arnaldo Carvalho de MeloFrom: Jiri Olsa <[email protected]>
Milian reported issue with thread::priv, which was double booked by perf trace and DWARF unwind code. So using those together is impossible at the moment.
Moving DWARF unwind private data into separate variable so perf trace can keep using thread::priv.
--- tools/perf/util/thread.h | 6 ++++++ tools/perf/util/unwind-libunwind.c | 25 +++++++++---------------- 2 files changed, 15 insertions(+), 16 deletions(-)
tools/perf/util/thread.h +6 -0
@@ -9,6 +9,9 @@#include "symbol.h" #include <strlist.h> #include <intlist.h> +#ifdef HAVE_LIBUNWIND_SUPPORT +#include <libunwind.h> +#endif struct thread_stack ;
@@ -32,6 +35,9 @@ struct thread {void *priv;struct thread_stack *ts; +#ifdef HAVE_LIBUNWIND_SUPPORT +unw_addr_space_t addr_space; +#endif };struct machine ;
tools/perf/util/unwind-libunwind.c +9 -16
@@ -32,6 +32,7 @@#include "symbol.h" #include "util.h" #include "debug.h" +#include "asm/bug.h" extern int UNW_OBJ(dwarf_search_unwind_table) (unw_addr_space_t as,
@@ -580,43 +581,33 @@ static unw_accessors_t accessors = {int unwind__prepare_access (struct thread *thread) { -unw_addr_space_t addr_space; -if (callchain_param.record_mode !=CALLCHAIN_DWARF )return 0 ; - addr_space =unw_create_addr_space (&accessors,0 ); -if (!addr_space) { + thread->addr_space =unw_create_addr_space (&accessors,0 ); +if (!thread->addr_space) {pr_err ("unwind: Can't create unwind address space.\n" );return -ENOMEM ; } -unw_set_caching_policy (addr_space,UNW_CACHE_GLOBAL ); -thread__set_priv (thread, addr_space); - +unw_set_caching_policy (thread->addr_space,UNW_CACHE_GLOBAL );return 0 ; }void unwind__flush_access (struct thread *thread) { -unw_addr_space_t addr_space; -if (callchain_param.record_mode !=CALLCHAIN_DWARF )return ; - addr_space =thread__priv (thread); -unw_flush_cache (addr_space,0 ,0 ); +unw_flush_cache (thread->addr_space,0 ,0 ); }void unwind__finish_access (struct thread *thread) { -unw_addr_space_t addr_space; -if (callchain_param.record_mode !=CALLCHAIN_DWARF )return ; - addr_space =thread__priv (thread); -unw_destroy_addr_space (addr_space); +unw_destroy_addr_space (thread->addr_space); } static int get_entries(struct unwind_info *ui, unwind_entry_cb_t cb,
@@ -639,7 +630,9 @@ static int get_entries(struct unwind_info *ui, unwind_entry_cb_t cb,* unwind itself. */ if (max_stack -1 >0 ) { - addr_space =thread__priv (ui->thread); +WARN_ONCE (!ui->thread,"WARNING: ui->thread is NULL" ); + addr_space = ui->thread->addr_space; +if (addr_space ==NULL )return -1 ;
Signature · 1 line
2.5.5
Arnaldo Carvalho de Melo
maintainerPATCH 13/19 perf script: Process event update events
In reply to Arnaldo Carvalho de MeloFrom: Jiri Olsa <[email protected]>
Andreas reported following command produces no output:
# cat test.py #!/usr/bin/env python
def stat__krava(cpu, thread, time, val, ena, run):
print "event %s cpu %d, thread %d, time %d, val %d, ena %d, run %d" % \
("krava", cpu, thread, time, val, ena, run)
# perf stat -a -I 1000 -e cycles,"cpu/config=0x6530160,name=krava/" record | perf script -s test.py ^C #
The reason is that 'perf script' does not process event update events and will never get the event name update thus the python callback is never called.
The fix is just to add already existing callback we use in 'perf stat report'.
Committer note:
After the patch:
# perf stat -a -I 1000 -e cycles,"cpu/config=0x6530160,name=krava/" record | perf script -s test.py event krava cpu -1, thread -1, time 1000239179, val 1789051, ena 4000690920, run 4000690920 event krava cpu -1, thread -1, time 2000479061, val 2391338, ena 4000879596, run 4000879596 event krava cpu -1, thread -1, time 3000740802, val 1939121, ena 4000977209, run 4000977209 event krava cpu -1, thread -1, time 4001006730, val 2356115, ena 4001000489, run 4001000489 ^C #
--- tools/perf/builtin-script.c | 1 + 1 file changed, 1 insertion(+)
tools/perf/builtin-script.c +1 -0
@@ -1961,6 +1961,7 @@ int cmd_script(int argc, const char **argv, const char *prefix __maybe_unused) .exit = perf_event__process_exit, .fork = perf_event__process_fork, .attr = process_attr, + .event_update = perf_event__process_event_update, .tracing_data = perf_event__process_tracing_data, .build_id = perf_event__process_build_id, .id_index = perf_event__process_id_index,
Signature · 1 line
2.5.5
Arnaldo Carvalho de Melo
maintainerPATCH 14/19 perf trace: Beautify mode_t arguments
In reply to Arnaldo Carvalho de MeloFrom: Arnaldo Carvalho de Melo <[email protected]>
When reading the syscall tracepoint /format file, look for arguments of type "mode_t" and attach a beautifier:
[root@jouet ~]# cat ~/bin/tp_with_fields_of_type
#!/bin/bash
grep -w $1 /sys/kernel/tracing/events/syscalls/*/format | sed -r 's%.*sys_enter_(.*)/format.*%\1%g' | paste -d, -s
# tp_with_fields_of_type umode_t chmod,creat,fchmodat,fchmod,mkdirat,mkdir,mknodat,mknod,mq_open,openat,open #
Testing it:
#define S_ISUID 0004000 #define S_ISGID 0002000 #define S_ISVTX 0001000 #define S_IRWXU 0000700 #define S_IRUSR 0000400 #define S_IWUSR 0000200 #define S_IXUSR 0000100 #define S_IRWXG 0000070 #define S_IRGRP 0000040 #define S_IWGRP 0000020 #define S_IXGRP 0000010 #define S_IRWXO 0000007 #define S_IROTH 0000004 #define S_IWOTH 0000002 #define S_IXOTH 0000001
# for mode in 4000 2000 1000 700 400 200 100 70 40 20 10 7 4 2 1 ; do \
echo -n $mode '->' ; trace --no-inherit -e chmod,fchmodat,fchmod chmod $mode x; \
done
4000 -> 0.338 ( 0.012 ms): fchmodat(dfd: CWD, filename: x, mode: ISUID) = 0
2000 -> 0.438 ( 0.015 ms): fchmodat(dfd: CWD, filename: x, mode: ISGID) = 0
1000 -> 0.677 ( 0.040 ms): fchmodat(dfd: CWD, filename: x, mode: ISVTX) = 0
700 -> 0.394 ( 0.013 ms): fchmodat(dfd: CWD, filename: x, mode: IRWXU) = 0
400 -> 0.337 ( 0.010 ms): fchmodat(dfd: CWD, filename: x, mode: IRUSR) = 0
200 -> 0.259 ( 0.008 ms): fchmodat(dfd: CWD, filename: x, mode: IWUSR) = 0
100 -> 0.249 ( 0.008 ms): fchmodat(dfd: CWD, filename: x, mode: IXUSR) = 0
70 -> 0.266 ( 0.008 ms): fchmodat(dfd: CWD, filename: x, mode: IRWXG) = 0
40 -> 0.329 ( 0.009 ms): fchmodat(dfd: CWD, filename: x, mode: IRGRP) = 0
20 -> 0.250 ( 0.009 ms): fchmodat(dfd: CWD, filename: x, mode: IWGRP) = 0
10 -> 0.259 ( 0.008 ms): fchmodat(dfd: CWD, filename: x, mode: IXGRP) = 0
7 -> 0.249 ( 0.009 ms): fchmodat(dfd: CWD, filename: x, mode: IRWXO) = 0
4 -> 0.278 ( 0.011 ms): fchmodat(dfd: CWD, filename: x, mode: IROTH) = 0
2 -> 0.276 ( 0.009 ms): fchmodat(dfd: CWD, filename: x, mode: IWOTH) = 0
1 -> 0.250 ( 0.008 ms): fchmodat(dfd: CWD, filename: x, mode: IXOTH) = 0
#
# trace --no-inherit -e chmod,fchmodat,fchmod chmod 7777 x
0.258 ( 0.011 ms): fchmodat(dfd: CWD, filename: x, mode: IALLUGO) = 0
# trace --no-inherit -e chmod,fchmodat,fchmod chmod 7770 x
0.258 ( 0.008 ms): fchmodat(dfd: CWD, filename: x, mode: ISUID|ISGID|ISVTX|IRWXU|IRWXG) = 0
# trace --no-inherit -e chmod,fchmodat,fchmod chmod 777 x
0.293 ( 0.012 ms): fchmodat(dfd: CWD, filename: x, mode: IRWXUGO
#Now lets see if check by using the tracepoint for that specific syscall, instead of raw_syscalls:sys_enter as 'trace' does for its strace fu:
# trace --no-inherit --ev syscalls:sys_enter_fchmodat -e fchmodat chmod 666 x
0.255 ( ): syscalls:sys_enter_fchmodat:dfd: 0xffffffffffffff9c, filename: 0x55db32a3f0f0, mode: 0x000001b6)
0.268 ( 0.012 ms): fchmodat(dfd: CWD, filename: x, mode: IRUGO|IWUGO ) = 0
#Perfect, 0x1bc == 0666.
--- tools/perf/builtin-trace.c | 3 ++ tools/perf/trace/beauty/mode_t.c | 68 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 71 insertions(+) create mode 100644 tools/perf/trace/beauty/mode_t.c
tools/perf/builtin-trace.c +3 -0
@@ -1126,6 +1126,7 @@ static size_t syscall_arg__scnprintf_getrandom_flags(char *bf, size_t size, .arg_parm = { [arg] = &strarray__##array, }#include "trace/beauty/pid.c" +#include "trace/beauty/mode_t.c" #include "trace/beauty/sched_policy.c" #include "trace/beauty/waitid_options.c"
@@ -1767,6 +1768,8 @@ static int syscall__set_arg_fmts(struct syscall *sc) sc->arg_scnprintf[idx] = syscall_arg__scnprintf_hex; else if (strcmp(field->type, "pid_t") == 0) sc->arg_scnprintf[idx] = SCA_PID; + else if (strcmp(field->type, "umode_t") == 0) + sc->arg_scnprintf[idx] = SCA_MODE_T; ++idx; }
tools/perf/trace/beauty/mode_t.c new file +68 -0
68 lines not on this page · raw message
Signature · 1 line
2.5.5
Arnaldo Carvalho de Melo
maintainerPATCH 15/19 perf trace: Move syscall table id <-> name routines to separate class
In reply to Arnaldo Carvalho de MeloFrom: Arnaldo Carvalho de Melo <[email protected]>
We're using libaudit for doing name to id and id to syscall name translations, but that makes 'perf trace' to have to wait for newer libaudit versions supporting recently added syscalls, such as "userfaultfd" at the time of this changeset.
We have all the information right there, in the kernel sources, so move this code to a separate place, wrapped behind functions that will progressively use the kernel source files to extract the syscall table for use in 'perf trace'.
--- tools/perf/builtin-trace.c | 24 +++++++++++------------- tools/perf/util/Build | 1 + tools/perf/util/syscalltbl.c | 43 +++++++++++++++++++++++++++++++++++++++++++ tools/perf/util/syscalltbl.h | 16 ++++++++++++++++ 4 files changed, 71 insertions(+), 13 deletions(-) create mode 100644 tools/perf/util/syscalltbl.c create mode 100644 tools/perf/util/syscalltbl.h
tools/perf/builtin-trace.c +11 -13
@@ -34,8 +34,9 @@#include "trace-event.h" #include "util/parse-events.h" #include "util/bpf-loader.h" +#include "syscalltbl.h" -#include <libaudit.h> +#include <libaudit.h> /* FIXME: Still needed for audit_errno_to_name */ #include <stdlib.h> #include <sys/mman.h> #include <linux/futex.h>
@@ -114,10 +115,7 @@struct trace {struct perf_tool tool; -struct { -int machine; -int open_id; - } audit; +struct syscalltbl *sctbl;struct {int max;struct syscall *table;
@@ -163,6 +161,7 @@ struct trace {bool force;bool vfs_getname;int trace_pgfaults; +int open_id; };struct tp_field {
@@ -1780,7 +1779,7 @@ static int trace__read_syscall_info(struct trace *trace, int id) {char tp_name[128 ];struct syscall *sc; -const char *name =audit_syscall_to_name (id, trace->audit.machine); +const char *name =syscalltbl__name (trace->sctbl, id);if (name ==NULL )return -1 ;
@@ -1855,7 +1854,7 @@ static int trace__validate_ev_qualifier(struct trace *trace)strlist__for_each (pos, trace->ev_qualifier) {const char *sc = pos->s; -int id =audit_name_to_syscall (sc, trace->audit.machine); +int id =syscalltbl__id (trace->sctbl, sc);if (id <0 ) {if (err ==0 ) {
@@ -2137,7 +2136,7 @@ static int trace__sys_exit(struct trace *trace, struct perf_evsel *evsel, ret =perf_evsel__sc_tp_uint (evsel, ret, sample); -if (id == trace->audit.open_id && ret >=0 && ttrace->filename.pending_open) { +if (id == trace->open_id && ret >=0 && ttrace->filename.pending_open) {trace__set_fd_pathname (thread, ret, ttrace->filename.name); ttrace->filename.pending_open = false; ++trace->stats.vfs_getname;
@@ -3189,10 +3188,6 @@ int cmd_trace(int argc, const char **argv, const char *prefix __maybe_unused)NULL };struct trace trace = { - .audit = { - .machine =audit_detect_machine (), - .open_id =audit_name_to_syscall ("open" , trace.audit.machine), - }, .syscalls = { . max =-1 , },
@@ -3267,8 +3262,9 @@ int cmd_trace(int argc, const char **argv, const char *prefix __maybe_unused)signal (SIGFPE , sighandler_dump_stack); trace.evlist =perf_evlist__new (); + trace.sctbl =syscalltbl__new (); -if (trace.evlist ==NULL ) { +if (trace.evlist ==NULL || trace.sctbl ==NULL ) {pr_err ("Not enough memory to run!\n" ); err = -ENOMEM ; goto out;
@@ -3306,6 +3302,8 @@ int cmd_trace(int argc, const char **argv, const char *prefix __maybe_unused) } } + trace.open_id =syscalltbl__id (trace.sctbl,"open" ); +if (ev_qualifier_str !=NULL ) {const char *s = ev_qualifier_str;struct strlist_config slist_config = {
tools/perf/util/Build +1 -0
@@ -38,6 +38,7 @@ libperf-y += machine.o libperf-y += map.o libperf-y += pstack.o libperf-y += session.o +libperf-$(CONFIG_AUDIT) += syscalltbl.o libperf-y += ordered-events.o libperf-y += comm.o libperf-y += thread.o
tools/perf/util/syscalltbl.c new file +43 -0
43 lines not on this page · raw message
tools/perf/util/syscalltbl.h new file +16 -0
@@ -0,0 +1,16 @@ +#ifndef __PERF_SYSCALLTBL_H +#define __PERF_SYSCALLTBL_H + +struct syscalltbl { +union { +int audit_machine; + }; +}; + +struct syscalltbl *syscalltbl__new (void ); +void syscalltbl__delete (struct syscalltbl *tbl); + +const char *syscalltbl__name (const struct syscalltbl *tbl,int id); +int syscalltbl__id (struct syscalltbl *tbl,const char *name); + +#endif /* __PERF_SYSCALLTBL_H */
Signature · 1 line
2.5.5
Arnaldo Carvalho de Melo
maintainerPATCH 16/19 perf tools: Allow generating per-arch syscall table arrays
In reply to Arnaldo Carvalho de MeloFrom: Arnaldo Carvalho de Melo <[email protected]>
Tools should use a mechanism similar to arch/x86/entry/syscalls/ to generate a header file with the definitions for two variables:
static const char *syscalltbl_x86_64[] = {
[0] = "read",
[1] = "write",
<SNIP>
[324] = "membarrier",
[325] = "mlock2",
[326] = "copy_file_range", };
static const int syscalltbl_x86_64_max_id = 326;
In a per arch file that should then be included in tools/perf/util/syscalltbl.c.
First one will be for x86_64.
--- tools/perf/util/syscalltbl.c | 89 +++++++++++++++++++++++++++++++++++++++++++- tools/perf/util/syscalltbl.h | 4 ++ 2 files changed, 91 insertions(+), 2 deletions(-)
tools/perf/util/syscalltbl.c +87 -2
@@ -14,21 +14,105 @@*/ #include "syscalltbl.h" +#include <stdlib.h> + +#ifdef HAVE_SYSCALL_TABLE +#include <linux/compiler.h> #include <string.h> -#include <libaudit.h> +#include "util.h" + +struct syscall { +int id; +const char *name; +}; +static int syscallcmpname (const void *vkey,const void *ventry) +{ +const char *key = vkey; +const struct syscall *entry = ventry; + +return strcmp (key, entry->name); +} + +static int syscallcmp (const void *va,const void *vb) +{ +const struct syscall *a = va, *b = vb; + +return strcmp (a->name, b->name); +} + +static int syscalltbl__init_native (struct syscalltbl *tbl) +{ +int nr_entries =0 , i, j; +struct syscall *entries; + +for (i =0 ; i <= syscalltbl_native_max_id; ++i) +if (syscalltbl_native[i]) + ++nr_entries; + + entries = tbl->syscalls.entries =malloc (sizeof (struct syscall ) * nr_entries); +if (tbl->syscalls.entries ==NULL ) +return -1 ; + +for (i =0 , j =0 ; i <= syscalltbl_native_max_id; ++i) { +if (syscalltbl_native[i]) { + entries[j].name = syscalltbl_native[i]; + entries[j].id = i; + ++j; + } + } + +qsort (tbl->syscalls.entries, nr_entries,sizeof (struct syscall ), syscallcmp); + tbl->syscalls.nr_entries = nr_entries; +return 0 ; +}struct syscalltbl *syscalltbl__new (void ) {struct syscalltbl *tbl =malloc (sizeof (*tbl));if (tbl) { - tbl->audit_machine =audit_detect_machine (); +if (syscalltbl__init_native (tbl)) { +free (tbl); +return NULL ; + } }return tbl; }void syscalltbl__delete (struct syscalltbl *tbl) { +zfree (&tbl->syscalls.entries); +free (tbl); +} + +const char *syscalltbl__name (const struct syscalltbl *tbl__maybe_unused ,int id) +{ +return id <= syscalltbl_native_max_id ? syscalltbl_native[id]:NULL ; +} + +int syscalltbl__id (struct syscalltbl *tbl,const char *name) +{ +struct syscall *sc =bsearch (name, tbl->syscalls.entries, + tbl->syscalls.nr_entries,sizeof (*sc), + syscallcmpname); + +return sc ? sc->id :-1 ; +} + +#else /* HAVE_SYSCALL_TABLE */ + +#include <libaudit.h> + +struct syscalltbl *syscalltbl__new (void ) +{ +struct syscalltbl *tbl =malloc (sizeof (*tbl)); +if (tbl) + tbl->audit_machine =audit_detect_machine (); +return tbl; +} + +void syscalltbl__delete (struct syscalltbl *tbl) +{free (tbl); }
@@ -41,3 +125,4 @@ int syscalltbl__id(struct syscalltbl *tbl, const char *name) {return audit_name_to_syscall (name, tbl->audit_machine); } +#endif /* HAVE_SYSCALL_TABLE */
tools/perf/util/syscalltbl.h +4 -0
@@ -4,6 +4,10 @@struct syscalltbl {union {int audit_machine; +struct { +int nr_entries; +void *entries; + } syscalls; }; };
Signature · 1 line
2.5.5
Arnaldo Carvalho de Melo
maintainerPATCH 17/19 perf tools: Build syscall table .c header from kernel's syscall_64.tbl
In reply to Arnaldo Carvalho de MeloFrom: Arnaldo Carvalho de Melo <[email protected]>
We used libaudit to map ids to syscall names and vice-versa, but that imposes a delay in supporting new syscalls, having to wait for libaudit to get those new syscalls on its tables.
To remove that delay, for x86_64 initially, grab a copy of arch/x86/entry/syscalls/syscall_64.tbl and use it to generate those tables.
Syscalls currently not available in audit-libs:
# trace -e copy_file_range,membarrier,mlock2,pread64,pwrite64,timerfd_create,userfaultfd Error: Invalid syscall copy_file_range, membarrier, mlock2, pread64, pwrite64, timerfd_create, userfaultfd Hint: try 'perf list syscalls:sys_enter_*' Hint: and: 'man syscalls' #
With this patch:
# trace -e copy_file_range,membarrier,mlock2,pread64,pwrite64,timerfd_create,userfaultfd
8505.733 ( 0.010 ms): gnome-shell/2519 timerfd_create(flags: 524288) = 36
8506.688 ( 0.005 ms): gnome-shell/2519 timerfd_create(flags: 524288) = 40
30023.097 ( 0.025 ms): qemu-system-x8/24629 pwrite64(fd: 18, buf: 0x7f63ae382000, count: 4096, pos: 529592320) = 4096
31268.712 ( 0.028 ms): qemu-system-x8/24629 pwrite64(fd: 18, buf: 0x7f63afd8b000, count: 4096, pos: 2314133504) = 4096
31268.854 ( 0.016 ms): qemu-system-x8/24629 pwrite64(fd: 18, buf: 0x7f63afda2000, count: 4096, pos: 2314137600) = 4096--- tools/perf/Makefile.perf | 11 +- tools/perf/arch/x86/Makefile | 23 ++ tools/perf/arch/x86/entry/syscalls/syscall_64.tbl | 374 ++++++++++++++++++++++ tools/perf/arch/x86/entry/syscalls/syscalltbl.sh | 39 +++ tools/perf/config/Makefile | 2 +- tools/perf/util/Build | 4 + tools/perf/util/syscalltbl.c | 6 + 7 files changed, 455 insertions(+), 4 deletions(-) create mode 100644 tools/perf/arch/x86/entry/syscalls/syscall_64.tbl create mode 100755 tools/perf/arch/x86/entry/syscalls/syscalltbl.sh
tools/perf/Makefile.perf +8 -3
@@ -183,6 +183,11 @@ endif include config/Makefile endif +ifeq ($(config),0) +include $(srctree)/tools/scripts/Makefile.arch +-include arch/$(ARCH)/Makefile +endif + # The FEATURE_DUMP_EXPORT holds location of the actual # FEATURE_DUMP file to be used to bypass feature detection # (for bpf or any other subproject)
@@ -388,7 +393,7 @@ endif __build-dir = $(subst $(OUTPUT),,$(dir $@)) build-dir = $(if $(__build-dir),$(__build-dir),.) -prepare: $(OUTPUT)PERF-VERSION-FILE $(OUTPUT)common-cmds.h fixdep +prepare: $(OUTPUT)PERF-VERSION-FILE $(OUTPUT)common-cmds.h fixdep archheaders $(OUTPUT)%.o: %.c prepare FORCE $(Q)$(MAKE) -f $(srctree)/tools/build/Makefile.build dir=$(build-dir) $@
@@ -623,7 +628,7 @@ config-clean: $(call QUIET_CLEAN, config) $(Q)$(MAKE) -C $(srctree)/tools/build/feature/ $(if $(OUTPUT),OUTPUT=$(OUTPUT)feature/,) clean >/dev/null -clean: $(LIBTRACEEVENT)-clean $(LIBAPI)-clean $(LIBBPF)-clean $(LIBSUBCMD)-clean config-clean +clean:: $(LIBTRACEEVENT)-clean $(LIBAPI)-clean $(LIBBPF)-clean $(LIBSUBCMD)-clean config-clean $(call QUIET_CLEAN, core-objs) $(RM) $(LIB_FILE) $(OUTPUT)perf-archive $(OUTPUT)perf-with-kcore $(LANG_BINDINGS) $(Q)find $(if $(OUTPUT),$(OUTPUT),.) -name '*.o' -delete -o -name '\.*.cmd' -delete -o -name '\.*.d' -delete $(Q)$(RM) $(OUTPUT).config-detected
@@ -660,5 +665,5 @@ FORCE: .PHONY: all install clean config-clean strip install-gtk .PHONY: shell_compatibility_test please_set_SHELL_PATH_to_a_more_modern_shell .PHONY: $(GIT-HEAD-PHONY) TAGS tags cscope FORCE prepare -.PHONY: libtraceevent_plugins +.PHONY: libtraceevent_plugins archheaders
tools/perf/arch/x86/Makefile +23 -0
@@ -4,3 +4,26 @@ endif HAVE_KVM_STAT_SUPPORT := 1 PERF_HAVE_ARCH_REGS_QUERY_REGISTER_OFFSET := 1 PERF_HAVE_JITDUMP := 1 + +### +# Syscall table generation +# + +out := $(OUTPUT)arch/x86/include/generated/asm +header := $(out)/syscalls_64.c +sys := $(srctree)/tools/perf/arch/x86/entry/syscalls +systbl := $(sys)/syscalltbl.sh + +# Create output directory if not already present +_dummy := $(shell [ -d '$(out)' ] || mkdir -p '$(out)') + +$(header): $(sys)/syscall_64.tbl $(systbl) + @(test -d ../../kernel -a -d ../../tools -a -d ../perf && ( \ + (diff -B arch/x86/entry/syscalls/syscall_64.tbl ../../arch/x86/entry/syscalls/syscall_64.tbl >/dev/null) \ + || echo "Warning: x86_64's syscall_64.tbl differs from kernel" >&2 )) || true + $(Q)$(SHELL) '$(systbl)' $(sys)/syscall_64.tbl 'x86_64' > $@ + +clean:: + rm -f $(header) + +archheaders: $(header)
tools/perf/arch/x86/entry/syscalls/syscall_64.tbl new file +374 -0
374 lines not on this page · raw message
tools/perf/arch/x86/entry/syscalls/syscalltbl.sh new file +39 -0
@@ -0,0 +1,39 @@ +#!/bin/sh + +in="$1" +arch="$2" + +syscall_macro() { + nr="$1" + name="$2" + + echo " [$nr] = \"$name\"," +} + +emit() { + nr="$1" + entry="$2" + + syscall_macro "$nr" "$entry" +} + +echo "static const char *syscalltbl_${arch}[] = {" + +sorted_table=$(mktemp /tmp/syscalltbl.XXXXXX) +grep '^[0-9]' "$in" | sort -n > $sorted_table + +max_nr=0 +while read nr abi name entry compat; do + if [ $nr -ge 512 ] ; then # discard compat sycalls + break + fi + + emit "$nr" "$name" + max_nr=$nr +done < $sorted_table + +rm -f $sorted_table + +echo "};" + +echo "#define SYSCALLTBL_${arch}_MAX_ID ${max_nr}"
tools/perf/config/Makefile +1 -1
@@ -27,7 +27,7 @@ NO_PERF_REGS := 1 ifeq ($(ARCH),x86) $(call detected,CONFIG_X86) ifeq (${IS_64_BIT}, 1) - CFLAGS += -DHAVE_ARCH_X86_64_SUPPORT + CFLAGS += -DHAVE_ARCH_X86_64_SUPPORT -DHAVE_SYSCALL_TABLE -I$(OUTPUT)arch/x86/include/generated ARCH_INCLUDE = ../../arch/x86/lib/memcpy_64.S ../../arch/x86/lib/memset_64.S LIBUNWIND_LIBS = -lunwind -lunwind-x86_64 $(call detected,CONFIG_X86_64)
tools/perf/util/Build +4 -0
@@ -148,6 +148,10 @@ CFLAGS_libstring.o += -Wno-unused-parameter -DETC_PERFCONFIG="BUILD_STR($(ET CFLAGS_hweight.o += -Wno-unused-parameter -DETC_PERFCONFIG="BUILD_STR($(ETC_PERFCONFIG_SQ))" CFLAGS_parse-events.o += -Wno-redundant-decls +$(OUTPUT)util/syscalltbl.o: util/syscalltbl.c arch/x86/entry/syscalls/syscall_64.tbl $(OUTPUT)arch/x86/include/generated/asm/syscalls_64.c FORCE + $(call rule_mkdir) + $(call if_changed_dep,cc_o_c) + $(OUTPUT)util/kallsyms.o: ../lib/symbol/kallsyms.c FORCE $(call rule_mkdir) $(call if_changed_dep,cc_o_c)
tools/perf/util/syscalltbl.c +6 -0
@@ -21,6 +21,12 @@#include <string.h> #include "util.h" +#if defined(__x86_64__) +#include <asm/syscalls_64.c> +const int syscalltbl_native_max_id = SYSCALLTBL_x86_64_MAX_ID; +static const char **syscalltbl_native = syscalltbl_x86_64; +#endif +struct syscall {int id;const char *name;
Signature · 1 line
2.5.5
Re: [PATCH 17/19] perf tools: Build syscall table .c header from kernel's syscall_64.tbl
Quoted 3 lines · Arnaldo Carvalho de Melo
We used libaudit to map ids to syscall names and vice-versa, but that imposes a delay in supporting new syscalls, having to wait for libaudit to get those new syscalls on its tables.
and for the distribution to get the new libaudit.
Quoted 4 lines
To remove that delay, for
x86_64initially, grab a copy ofarch/x86/entry/syscalls/syscall_64.tbland use it to generate those tables.
Now that's a benefit for perf in the kernel tree. What happens for out of tree perf builds? Are the requisite files included in the tarball? (apparently no, since the manifest file is not updated or perhaps I missed it)
Arnaldo Carvalho de Melo
maintainerRe: [PATCH 17/19] perf tools: Build syscall table .c header from kernel's syscall_64.tbl
Em Thu, Apr 07, 2016 at 03:39:21PM -0600, David Ahern escreveu:
Quoted 6 lines · Arnaldo Carvalho de Melo
Quoted 3 lines
We used libaudit to map ids to syscall names and vice-versa, but that imposes a delay in supporting new syscalls, having to wait for libaudit to get those new syscalls on its tables.
and for the distribution to get the new libaudit.
yeap
Quoted 8 lines
Quoted 3 lines
To remove that delay, for
x86_64initially, grab a copy ofarch/x86/entry/syscalls/syscall_64.tbland use it to generate those tables.Now that's a benefit for perf in the kernel tree. What happens for out of tree perf builds? Are the requisite files included in the tarball? (apparently no, since the manifest file is not updated or perhaps I missed it)
Well, we're removing references to files outside tools/, so what was done in this case was to copy the files:
[acme@jouet linux]$ ls -la tools/perf/arch/x86/entry/syscalls/ total 28
drwxrwxr-x. 2 acme acme 4096 Apr 7 16:59 . drwxrwxr-x. 3 acme acme 4096 Apr 7 16:59 .. -rw-rw-r--. 1 acme acme 12972 Apr 7 16:59 syscall_64.tbl -rwxrwxr-x. 1 acme acme 596 Apr 7 16:59 syscalltbl.sh
[acme@jouet linux]$
Then we have logic for when the kernel one gets out of sync, to be warned about, see:
tools/perf/arch/x86/Makefile
E.g.:
[acme@jouet linux]$ git diff
arch/x86/entry/syscalls/syscall_64.tbl +1 -0
@@ -333,6 +333,7 @@ 324 common membarrier sys_membarrier 325 common mlock2 sys_mlock2 326 common copy_file_range sys_copy_file_range +327 common leftpad sys_leftpad # # x32-specific system call numbers start at 512 to avoid cache impact
[acme@jouet linux]$
[acme@jouet linux]$ rm -rf /tmp/build/perf ; mkdir -p /tmp/build/perf ; m
make: Entering directory '/home/acme/git/linux/tools/perf'
[acme@jouet linux]$ make -C tools/perf build-test
make: Entering directory '/home/acme/git/linux/tools/perf'
- tarpkg: ./tests/perf-targz-src-pkg .
BUILD: Doing 'make -j4' parallel build
Auto-detecting system features:
... dwarf: [ on ]
<SNIP>
GEN /tmp/build/perf/common-cmds.h
Warning: x86_64's syscall_64.tbl differs from kernel
CC /tmp/build/perf/fixdep.o
LD /tmp/build/perf/fixdep-in.o
---------------------------------------
Looking at it now it needs some more polish, i.e. it should have a GEN ... line, but that can be done on top of this patchkit :-)
For completeness:
[acme@jouet linux]$ diff -u tools/perf/arch/x86/entry/syscalls/syscall_64.tbl arch/x86/entry/syscalls/syscall_64.tbl
x86/entry/syscalls/syscall_64.tbl renamed from perf/arch/x86/entry/syscalls/syscall_64.tbl +1 -0
@@ -333,6 +333,7 @@ 324 common membarrier sys_membarrier 325 common mlock2 sys_mlock2 326 common copy_file_range sys_copy_file_range +327 common leftpad sys_leftpad # # x32-specific system call numbers start at 512 to avoid cache impact
[acme@jouet linux]$
And 'make -C tools/perf build-test' does the tarball creation and out-of-tree build as its first step, to make sure it continues working, so all that is needed is there :-)
[acme@jouet linux]$ make -C tools/perf build-test
make: Entering directory '/home/acme/git/linux/tools/perf'
- tarpkg: ./tests/perf-targz-src-pkg .
- /home/acme/git/linux/tools/perf/BUILD_TEST_FEATURE_DUMP: cd . && make FEATURE_DUMP_COPY=/home/acme/git/linux/tools/perf/BUILD_TEST_FEATURE_DUMP feature-dump cd . && make FEATURE_DUMP_COPY=/home/acme/git/linux/tools/perf/BUILD_TEST_FEATURE_DUMP feature-dump
make_minimal_O: cd . && 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 FEATURES_DUMP=/home/acme/git/linux/tools/perf/BUILD_TEST_FEATURE_DUMP -j4 O=/tmp/tmp.6KCw8TRjm7 DESTDIR=/tmp/tmp.6yw98RESmd
<SNIP>
Best regards,
- Arnaldo
Re: [PATCH 17/19] perf tools: Build syscall table .c header from kernel's syscall_64.tbl
In reply to Arnaldo Carvalho de MeloUpon further review ...
Quoted 11 lines · Arnaldo Carvalho de Melo
From: Arnaldo Carvalho de Melo <[email protected]>
We used libaudit to map ids to syscall names and vice-versa, but that imposes a delay in supporting new syscalls, having to wait for libaudit to get those new syscalls on its tables.
To remove that delay, for
x86_64initially, grab a copy ofarch/x86/entry/syscalls/syscall_64.tbland use it to generate those tables.
Quoted 4 lines
tools/perf/Makefile.perf | 11 +- tools/perf/arch/x86/Makefile | 23 ++ tools/perf/arch/x86/entry/syscalls/syscall_64.tbl | 374 ++++++++++++++++++++++ tools/perf/arch/x86/entry/syscalls/syscalltbl.sh | 39 +++
Why make a copies of the files? Why can't perf reference the ones 2 levels up?
Re: [PATCH 17/19] perf tools: Build syscall table .c header from kernel's syscall_64.tbl
Em Thu, Apr 07, 2016 at 03:49:56PM -0600, David Ahern escreveu:
Quoted 14 lines
Upon further review ...
Quoted 9 lines · Arnaldo Carvalho de Melo
From: Arnaldo Carvalho de Melo <[email protected]>
We used libaudit to map ids to syscall names and vice-versa, but that imposes a delay in supporting new syscalls, having to wait for libaudit to get those new syscalls on its tables.
To remove that delay, for
x86_64initially, grab a copy ofarch/x86/entry/syscalls/syscall_64.tbland use it to generate those tables.
Quoted 7 lines
Quoted 4 lines
tools/perf/Makefile.perf | 11 +- tools/perf/arch/x86/Makefile | 23 ++ tools/perf/arch/x86/entry/syscalls/syscall_64.tbl | 374 ++++++++++++++++++++++ tools/perf/arch/x86/entry/syscalls/syscalltbl.sh | 39 +++Why make a copies of the files? Why can't perf reference the ones 2 levels up?
We did that in the past, but then, after the build broke in tools/ due to changes in the referenced files, we decided to use this "coherency protocol" where we benefit from using the kernel files but don't use it directly, being warned when changes happen so that we can do some analysis before updating our copy.
- Arnaldo
Re: [PATCH 17/19] perf tools: Build syscall table .c header from kernel's syscall_64.tbl
In reply to Arnaldo Carvalho de MeloQuoted 27 lines · Arnaldo Carvalho de Melo
From: Arnaldo Carvalho de Melo <[email protected]>
We used libaudit to map ids to syscall names and vice-versa, but that imposes a delay in supporting new syscalls, having to wait for libaudit to get those new syscalls on its tables.
To remove that delay, for
x86_64initially, grab a copy ofarch/x86/entry/syscalls/syscall_64.tbland use it to generate those tables.Syscalls currently not available in audit-libs:
# trace -e copy_file_range,membarrier,mlock2,pread64,pwrite64,timerfd_create,userfaultfd Error: Invalid syscall copy_file_range, membarrier, mlock2, pread64, pwrite64, timerfd_create, userfaultfd Hint: try 'perf list syscalls:sys_enter_*' Hint: and: 'man syscalls' #With this patch:
# trace -e copy_file_range,membarrier,mlock2,pread64,pwrite64,timerfd_create,userfaultfd 8505.733 ( 0.010 ms): gnome-shell/2519 timerfd_create(flags: 524288) = 36 8506.688 ( 0.005 ms): gnome-shell/2519 timerfd_create(flags: 524288) = 40 30023.097 ( 0.025 ms): qemu-system-x8/24629 pwrite64(fd: 18, buf: 0x7f63ae382000, count: 4096, pos: 529592320) = 4096 31268.712 ( 0.028 ms): qemu-system-x8/24629 pwrite64(fd: 18, buf: 0x7f63afd8b000, count: 4096, pos: 2314133504) = 4096 31268.854 ( 0.016 ms): qemu-system-x8/24629 pwrite64(fd: 18, buf: 0x7f63afda2000, count: 4096, pos: 2314137600) = 4096
Quoted 9 lines
Cc Adrian Hunter <[email protected]>Cc David Ahern <[email protected]>Cc Jiri Olsa <[email protected]>Cc Namhyung Kim <[email protected]>Cc Wang Nan <[email protected]>Signed-off-by Arnaldo Carvalho de Melo <[email protected]>---
There is racing in Makefile. I see following output:
...
CC /xx/xx/perf/1.0-r8/perf-1.0/util/callchain.o CC /xx/xx/perf/1.0-r8/perf-1.0/util/values.o CC /xx/xx/perf/1.0-r8/perf-1.0/util/debug.o
make[3]: *** No rule to make target `/xx/xx/perf/1.0-r8/perf-1.0/util/syscalltbl.o'. Stop. make[3]: *** Waiting for unfinished jobs....
CC /xx/xx/perf/1.0-r8/perf-1.0/util/machine.o
CC /xx/xx/perf/1.0-r8/perf-1.0/util/map.o
...
The error disappeareafter doing 'make archheaders' before 'make all'.
Thank you.
Arnaldo Carvalho de Melo
maintainerPATCH 18/19 perf symbols: Record text offset in dso to calculate objdump address
In reply to Arnaldo Carvalho de MeloFrom: Wang Nan <[email protected]>
In this patch, the offset of '.text' section is stored into dso and used here to re-calculate address to objdump.
In most of the cases, executable code is in '.text' section, so the adjustment made to a symbol in dso__load_sym (using sym.st_value -= shdr.sh_addr - shdr.sh_offset) should equal to 'sym.st_value -= dso->text_offset'. Therefore, adding text_offset back get objdump address from symbol address (rip). However, it is not true for kernel and kernel module since there could be multiple executable sections with different offset. Exclude kernel for this reason.
After this patch, even dso->adjust_symbols is set to true for shared objects, map__rip_2objdump() and map__objdump_2mem() would return correct result, so perf behavior of annotate won't be changed.
--- tools/perf/util/map.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+)
tools/perf/util/map.c +14 -0
@@ -431,6 +431,13 @@ u64 map__rip_2objdump(struct map *map, u64 rip)if (map->dso->rel)return rip - map->pgoff; +/* +* kernel modules also have DSO_TYPE_USER in dso->kernel, +* but all kernel modules are ET_REL, so won't get here. +*/ +if (map->dso->kernel ==DSO_TYPE_USER ) +return rip + map->dso->text_offset; +return map->unmap_ip (map, rip) - map->reloc; }
@@ -454,6 +461,13 @@ u64 map__objdump_2mem(struct map *map, u64 ip)if (map->dso->rel)return map->unmap_ip (map, ip + map->pgoff); +/* +* kernel modules also have DSO_TYPE_USER in dso->kernel, +* but all kernel modules are ET_REL, so won't get here. +*/ +if (map->dso->kernel ==DSO_TYPE_USER ) +return map->unmap_ip (map, ip - map->dso->text_offset); +return ip + map->reloc; }
Signature · 1 line
2.5.5
Arnaldo Carvalho de Melo
maintainerPATCH 19/19 perf symbols: Adjust symbol for shared objects
In reply to Arnaldo Carvalho de MeloFrom: Wang Nan <[email protected]>
He Kuang reported a problem that perf fails to get correct symbol on Android platform in [1]. The problem can be reproduced on normal x86_64 platform. I will describe the reproducing steps in detail at the end of commit message.
The reason of this problem is the missing of symbol adjustment for normal shared objects. In most of the cases skipping adjustment is okay. However, when '.text' section have different 'address' and 'offset' the result is wrong. I checked all shared objects in my working platform, only wine dll objects and debug objects (in .debug) have this problem. However, it is common on Android. For example:
$ readelf -S ./libsurfaceflinger.so | grep \.text [10] .text PROGBITS 0000000000029030 00012030
This patch enables symbol adjustment for dynamic objects so the symbol address got from elfutils would be adjusted correctly.
Now nearly all types of ELF files should adjust symbols. Makes ss->adjust_symbols default to true.
Steps to reproduce the problem:
$ cat ./Makefile PWD := $(shell pwd) LDFLAGS += "-Wl,-rpath=$(PWD)" CFLAGS += -g main: main.c libbuggy.so libbuggy.so: buggy.c gcc -g -shared -fPIC -Wl,-Ttext-segment=0x200000 $< -o $@ clean: rm -rf main libbuggy.so *.o
$ cat ./buggy.c
int fib(int x)
{
return (x == 0) ? 1 : (x == 1) ? 1 : fib(x - 1) + fib(x - 2);
}$ cat ./main.c #include <stdio.h>
extern int fib(int x);
int main()
{
int i; for (i = 0; i < 40; i++)
printf("%d\n", fib(i));
return 0;}
$ make
$ perf record ./main
...
$ perf report --stdio
# Overhead Command Shared Object Symbol
# ........ ....... ................. ...............................
#
14.97% main libbuggy.so [.] 0x000000000000066c
8.68% main libbuggy.so [.] 0x00000000000006aa
8.52% main libbuggy.so [.] fib@plt
7.95% main libbuggy.so [.] 0x0000000000000664
5.94% main libbuggy.so [.] 0x00000000000006a9
5.35% main libbuggy.so [.] 0x0000000000000678
...The correct result should be (after this patch):
# Overhead Command Shared Object Symbol
# ........ ....... ................. ...............................
#
91.47% main libbuggy.so [.] fib
8.52% main libbuggy.so [.] fib@plt
0.00% main [kernel.kallsyms] [k] kmem_cache_free[1] http://lkml.kernel.org/g/[email protected]
--- tools/perf/util/symbol-elf.c | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-)
tools/perf/util/symbol-elf.c +3 -10
@@ -709,17 +709,10 @@ int symsrc__init(struct symsrc *ss, struct dso *dso, const char *name,if (ss->opdshdr.sh_type !=SHT_PROGBITS ) ss->opdsec =NULL ; -if (dso->kernel ==DSO_TYPE_USER ) { -GElf_Shdr shdr; - ss->adjust_symbols = (ehdr.e_type ==ET_EXEC || - ehdr.e_type ==ET_REL || -dso__is_vdso (dso) || -elf_section_by_name (elf, &ehdr, &shdr, -".gnu.prelink_undo" , -NULL ) !=NULL ); - }else { +if (dso->kernel ==DSO_TYPE_USER ) + ss->adjust_symbols = true; +else ss->adjust_symbols =elf__needs_adjust_symbols (ehdr); - } ss->name =strdup (name);if (!ss->name) {
Signature · 1 line
2.5.5
Arnaldo Carvalho de Melo
maintainerEm Thu, Apr 07, 2016 at 05:58:21PM -0300, Arnaldo Carvalho de Melo escreveu:
Quoted 3 lines
Hi Ingo,
Please consider pulling, build tested on:
Ingo, if you haven't pulled this one, please pull instead perf-core-for-mingo-20160408, which has the same tag text and contents + a Tested-by tag from Milian for the unwind thread one and a bisection fix one liner for the syscall_tbl generation from Wang,
Thanks,
- Arnaldo
Quoted 147 lines
# perf stat -e cycles dm alldeps-ubuntu-12.04: Ok minimal-debian-experimental-x-mips64: Ok minimal-debian-experimental-x-mips64el: Ok minimal-debian-experimental-x-mipsel: Ok minimal-ubuntu-x-arm: Ok minimal-ubuntu-x-arm64: Ok minimal-ubuntu-x-ppc64: Ok minimal-ubuntu-x-ppc64el: Ok alldeps-debian: Ok alldeps-mageia: Ok alldeps-rhel7: Ok alldeps-centos: Ok alldeps-opensuse: Ok alldeps-ubuntu: OkPerformance counter stats for 'dm': 3,095,685,547 cycles 454.805537820 seconds time elapsed#
'perf test' passes on fedora23 x86_64,Thanks,
- Arnaldo
The following changes since commit
dad38ca64a252144b4ccdfe9730a3fe2b7c61957:Merge tag 'perf-core-for-mingo-20160401' of
git://git.kernel.org/pub/scm/linux/kernel/git/acme/linuxinto perf/core (2016-04-06 08:46:23 +0200)are available in the git repository at:
git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux.gittags/perf-core-for-mingo-20160407for you to fetch changes up to
98c3d844cd0bc56d33800114e6b6adcd0a5ec381:perf symbols: Adjust symbol for shared objects (2016-04-07 17:17:01 -0300)
----------------------------------------------------------------
perf/core improvements and fixes:User visible:
- Beautify more syscall arguments in 'perf trace', using the type column in tracepoint /format fields to attach, for instance, a
pid_tresolver to the thread COMM, also attach amode_tbeautifier in the same fashion (Arnaldo Carvalho de Melo)- Build the syscall table id <-> name resolver using the same .tbl file used in the kernel to generate headers, to avoid the delay in getting new syscalls supported in the audit-libs external dependency, done so far only for
x86_64(Arnaldo Carvalho de Melo)- Improve the documentation of event specifications (Andi Kleen)
- Process update events in 'perf script', fixing up this use case:
# perf stat -a -I 1000 -e cycles record | perf script -s script.py- Shared object symbol adjustment fixes, fixing symbol resolution in Android (Wang Nan)
Infrastructure:
- Add dedicated unwind
addr_spacemember into thread struct, to allow tools to usethread->priv, noticed while working on having callchains in 'perf trace' (Jiri Olsa)Build fixes:
- Fix the build in Ubuntu 12.04 (Arnaldo Carvalho de Melo, Vinson Lee)
Signed-off-by Arnaldo Carvalho de Melo <[email protected]>----------------------------------------------------------------
Andi Kleen (1):
perf list: Document event specifications betterArnaldo Carvalho de Melo (11):
perf probe: Check ifdwarf_getlocations()is available
perf script perl: Do error checking on new backtrace routine perf trace: Beautifysched_setscheduler'policy' argument
perf trace: Beautify wait4/waitid 'options' argument
perf trace: Infrastructure to show COMM strings for syscalls returning PIDs perf trace: Beautifyset_tid_address, getpid, getppid return values perf trace: Beautifypid_targuments
perf trace: Beautifymode_targuments
perf trace: Move syscall table id <-> name routines to separate class perf tools: Allow generating per-arch syscall table arrays perf tools: Build syscall table .c header from kernel's syscall_64.tblJiri Olsa (4):
perf tools: Remove superfluous ARCHMakefileincludes perf tools: Introduce trim function
perf tools: Add dedicated unwindaddr_spacemember into thread struct perf script: Process event update eventsVinson Lee (1):
perf config: Fix build with older toolchain.Wang Nan (2):
perf symbols: Record text offset in dso to calculate objdump address perf symbols: Adjust symbol for shared objectstools/build/Makefile.feature | 2 + tools/build/feature/Makefile | 4 + tools/build/feature/test-all.c | 5 + tools/build/feature/test-dwarf_getlocations.c | 12 + tools/perf/Documentation/perf-list.txt | 107 +++++- tools/perf/Makefile.perf | 13 +- tools/perf/arch/x86/Makefile | 23 ++ tools/perf/arch/x86/entry/syscalls/syscall_64.tbl | 374 +++++++++++++++++++++ tools/perf/arch/x86/entry/syscalls/syscalltbl.sh | 39 +++ tools/perf/builtin-script.c | 1 + tools/perf/builtin-trace.c | 156 +++++---- tools/perf/config/Makefile | 11 +- tools/perf/trace/beauty/mode_t.c | 68 ++++ tools/perf/trace/beauty/pid.c | 18 + tools/perf/trace/beauty/sched_policy.c | 44 +++ tools/perf/trace/beauty/waitid_options.c | 26 ++ tools/perf/ui/browsers/hists.c | 3 +- tools/perf/ui/stdio/hist.c | 3 +- tools/perf/util/Build | 5 + tools/perf/util/config.c | 6 +- tools/perf/util/dwarf-aux.c | 9 + tools/perf/util/map.c | 14 + .../perf/util/scripting-engines/trace-event-perl.c | 30 +- tools/perf/util/symbol-elf.c | 13 +- tools/perf/util/syscalltbl.c | 134 ++++++++ tools/perf/util/syscalltbl.h | 20 ++ tools/perf/util/thread.h | 6 + tools/perf/util/unwind-libunwind.c | 25 +- tools/perf/util/util.h | 5 + 29 files changed, 1060 insertions(+), 116 deletions(-) create mode 100644 tools/build/feature/test-dwarf_getlocations.c create mode 100644 tools/perf/arch/x86/entry/syscalls/syscall_64.tbl create mode 100755 tools/perf/arch/x86/entry/syscalls/syscalltbl.sh create mode 100644 tools/perf/trace/beauty/mode_t.c create mode 100644 tools/perf/trace/beauty/pid.c create mode 100644 tools/perf/trace/beauty/sched_policy.c create mode 100644 tools/perf/trace/beauty/waitid_options.c create mode 100644 tools/perf/util/syscalltbl.c create mode 100644 tools/perf/util/syscalltbl.h
Quoted 9 lines · Arnaldo Carvalho de Melo
Em Thu, Apr 07, 2016 at 05:58:21PM -0300, Arnaldo Carvalho de Melo escreveu:
Quoted 3 lines
Hi Ingo,
Please consider pulling, build tested on:
Ingo, if you haven't pulled this one, please pull instead perf-core-for-mingo-20160408, which has the same tag text and contents + a Tested-by tag from Milian for the unwind thread one and a bisection fix one liner for the
syscall_tblgeneration from Wang,
Pulled, thanks a lot Arnaldo!
Ingo