perf/core improvements and fixes
Subsystems (7)
Arnaldo Carvalho de Melo
maintainerHi Ingo,
Please consider pulling,
- Arnaldo
Test results at the end of this message, as usual.
The following changes since commit 84e5b549214f2160c12318aac549de85f600c79a:
Merge tag 'perf-core-for-mingo-4.11-20170306' of git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux into perf/core (2017-03-07 08:14:14 +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.12-20170314
for you to fetch changes up to 5f6bee34707973ea7879a7857fd63ddccc92fff3:
kprobes: Convert kprobe_exceptions_notify to use NOKPROBE_SYMBOL (2017-03-14 15:17:40 -0300)
----------------------------------------------------------------
perf/core improvements and fixes:
New features:
- Add PERF_RECORD_NAMESPACES so that the kernel can record information required to associate samples to namespaces, helping in container problem characterization.
Now the 'perf record has a --namespace' option to ask for such info, and when present, it can be used, initially, via a new sort order, 'cgroup_id', allowing histogram entry bucketization by a (device, inode) based cgroup identifier (Hari Bathini)
- Add --next option to 'perf sched timehist', showing what is the next thread to run (Brendan Gregg)
Fixes:
- Fix segfault with basic block 'cycles' sort dimension (Changbin Du)
- Add c2c to command-list.txt, making it appear in the 'perf help' output (Changbin Du)
- Fix zeroing of 'abs_path' variable in the perf hists browser switch file code (Changbin Du)
- Hide tips messages when -q/--quiet is given to 'perf report' (Namhyung Kim)
Infrastructure:
- Use ref_reloc_sym + offset to setup kretprobes (Naveen Rao)
- Ignore generated files pmu-events/{jevents,pmu-events.c} for git (Changbin Du)
Documentation:
- Document +field style argument support for --field option (Changbin Du)
- Clarify 'perf c2c --stats' help message (Namhyung Kim)
----------------------------------------------------------------
Brendan Gregg (1):
perf sched timehist: Add --next option
Changbin Du (5):
perf tools: Missing c2c command in command-list
perf tools: Ignore generated files pmu-events/{jevents,pmu-events.c} for git perf sort: Fix segfault with basic block 'cycles' sort dimension perf report: Document +field style argument support for --field option perf hists browser: Fix typo in function switch_data_file
Hari Bathini (5):
perf: Add PERF_RECORD_NAMESPACES to include namespaces related info perf tools: Add PERF_RECORD_NAMESPACES to include namespaces related info perf record: Synthesize namespace events for current processes perf script: Add script print support for namespace events perf tools: Add 'cgroup_id' sort order keyword
Namhyung Kim (3):
perf report: Hide tip message when -q option is given perf c2c: Clarify help message of --stats option perf c2c: Fix display bug when using pipe
Naveen N. Rao (5):
perf probe: Factor out the ftrace README scanning perf kretprobes: Offset from reloc_sym if kernel supports it perf powerpc: Choose local entry point with kretprobes
doc: trace/kprobes: add information about NOKPROBE_SYMBOL
kprobes: Convert kprobe_exceptions_notify to use NOKPROBE_SYMBOL
Documentation/trace/kprobetrace.txt | 5 +- include/linux/perf_event.h | 2 + include/uapi/linux/perf_event.h | 32 +++++- kernel/events/core.c | 139 ++++++++++++++++++++++++++ kernel/fork.c | 2 + kernel/kprobes.c | 5 +- kernel/nsproxy.c | 3 + tools/include/uapi/linux/perf_event.h | 32 +++++- tools/perf/.gitignore | 2 + tools/perf/Documentation/perf-record.txt | 3 + tools/perf/Documentation/perf-report.txt | 7 +- tools/perf/Documentation/perf-sched.txt | 4 + tools/perf/Documentation/perf-script.txt | 3 + tools/perf/arch/powerpc/util/sym-handling.c | 14 ++- tools/perf/builtin-annotate.c | 1 + tools/perf/builtin-c2c.c | 4 +- tools/perf/builtin-diff.c | 1 + tools/perf/builtin-inject.c | 13 +++ tools/perf/builtin-kmem.c | 1 + tools/perf/builtin-kvm.c | 2 + tools/perf/builtin-lock.c | 1 + tools/perf/builtin-mem.c | 1 + tools/perf/builtin-record.c | 35 ++++++- tools/perf/builtin-report.c | 4 +- tools/perf/builtin-sched.c | 26 ++++- tools/perf/builtin-script.c | 41 ++++++++ tools/perf/builtin-trace.c | 3 +- tools/perf/command-list.txt | 1 + tools/perf/perf.h | 1 + tools/perf/ui/browsers/hists.c | 2 +- tools/perf/util/Build | 1 + tools/perf/util/data-convert-bt.c | 1 + tools/perf/util/event.c | 150 ++++++++++++++++++++++++++-- tools/perf/util/event.h | 19 ++++ tools/perf/util/evsel.c | 3 + tools/perf/util/hist.c | 7 ++ tools/perf/util/hist.h | 1 + tools/perf/util/machine.c | 34 +++++++ tools/perf/util/machine.h | 3 + tools/perf/util/namespaces.c | 36 +++++++ tools/perf/util/namespaces.h | 26 +++++ tools/perf/util/probe-event.c | 12 +-- tools/perf/util/probe-file.c | 77 ++++++++------ tools/perf/util/probe-file.h | 1 + tools/perf/util/session.c | 7 ++ tools/perf/util/sort.c | 46 +++++++++ tools/perf/util/sort.h | 7 ++ tools/perf/util/thread.c | 44 +++++++- tools/perf/util/thread.h | 6 ++ tools/perf/util/tool.h | 2 + 50 files changed, 799 insertions(+), 74 deletions(-) create mode 100644 tools/perf/util/namespaces.c create mode 100644 tools/perf/util/namespaces.h
Test results:
The first ones are container (docker) based builds of tools/perf with and without libelf support, objtool where it is supported and samples/bpf/, ditto. Where clang is available, it is also used to build perf with/without libelf.
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 2 alpine:3.5: Ok 3 alpine:edge: Ok 4 android-ndk:r12b-arm: Ok 5 archlinux:latest: Ok 6 centos:5: Ok 7 centos:6: Ok 8 centos:7: Ok 9 debian:7: Ok 10 debian:8: Ok 11 debian:experimental: Ok 12 debian:experimental-x-arm64: Ok 13 debian:experimental-x-mips: Ok 14 debian:experimental-x-mips64: Ok 15 debian:experimental-x-mipsel: Ok 16 fedora:20: Ok 17 fedora:21: Ok 18 fedora:22: Ok 19 fedora:23: Ok 20 fedora:24: Ok 21 fedora:24-x-ARC-uClibc: Ok 22 fedora:25: Ok 23 fedora:rawhide: Ok 24 mageia:5: Ok 25 opensuse:13.2: Ok 26 opensuse:42.1: Ok 27 opensuse:tumbleweed: Ok 28 ubuntu:12.04.5: Ok 29 ubuntu:14.04.4: Ok 30 ubuntu:14.04.4-x-linaro-arm64: Ok 31 ubuntu:15.10: Ok 32 ubuntu:16.04: Ok 33 ubuntu:16.04-x-arm: Ok 34 ubuntu:16.04-x-arm64: Ok 35 ubuntu:16.04-x-powerpc: Ok 36 ubuntu:16.04-x-powerpc64: Ok 37 ubuntu:16.04-x-s390: Ok 38 ubuntu:16.10: Ok 39 ubuntu:17.04: Ok #
# uname -a Linux zoo 4.9.13-100.fc24.x86_64 #1 SMP Mon Feb 27 16:57:22 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux # perf test 1: vmlinux symtab matches kallsyms : Ok 2: Detect openat syscall event : Ok 3: Detect openat syscall event on all cpus : Ok 4: Read samples using the mmap interface : Ok 5: Parse event definition strings : Ok 6: PERF_RECORD_* events & perf_sample fields : Ok 7: Parse perf pmu format : Ok 8: DSO data read : Ok 9: DSO data cache : Ok 10: DSO data reopen : Ok 11: Roundtrip evsel->name : Ok 12: Parse sched tracepoints fields : Ok 13: syscalls:sys_enter_openat event fields : Ok 14: Setup struct perf_event_attr : Ok 15: Match and link multiple hists : Ok 16: 'import perf' in python : Ok 17: Breakpoint overflow signal handler : Ok 18: Breakpoint overflow sampling : Ok 19: Number of exit events of a simple workload : Ok 20: Software clock events period values : Ok 21: Object code reading : Ok 22: Sample parsing : Ok 23: Use a dummy software event to keep tracking: Ok 24: Parse with no sample_id_all bit set : Ok 25: Filter hist entries : Ok 26: Lookup mmap thread : Ok 27: Share thread mg : Ok 28: Sort output of hist entries : Ok 29: Cumulate child hist entries : Ok 30: Track with sched_switch : Ok 31: Filter fds with revents mask in a fdarray : Ok 32: Add fd to a fdarray, making it autogrow : Ok 33: kmod_path__parse : Ok 34: Thread map : Ok 35: LLVM search and compile : 35.1: Basic BPF llvm compile : Ok 35.2: kbuild searching : Ok 35.3: Compile source for BPF prologue generation: Ok 35.4: Compile source for BPF relocation : Ok 36: Session topology : Ok 37: BPF filter : 37.1: Basic BPF filtering : Ok 37.2: BPF pinning : Ok 37.3: BPF prologue generation : Ok 37.4: BPF relocation checker : Ok 38: Synthesize thread map : Ok 39: Remove thread map : Ok 40: Synthesize cpu map : Ok 41: Synthesize stat config : Ok 42: Synthesize stat : Ok 43: Synthesize stat round : Ok 44: Synthesize attr update : Ok 45: Event times : Ok 46: Read backward ring buffer : Ok 47: Print cpu map : Ok 48: Probe SDT events : Ok 49: is_printable_array : Ok 50: Print bitmap : Ok 51: perf hooks : Ok 52: builtin clang support : Skip (not compiled in) 53: unit_number__scnprintf : Ok 54: x86 rdpmc : Ok 55: Convert perf time to TSC : Ok 56: DWARF unwind : Ok 57: x86 instruction decoder - new instructions : Ok 58: Intel cqm nmi context read : Skip #
$ make -C tools/perf build-test
make: Entering directory '/home/acme/git/linux/tools/perf'
- tarpkg: ./tests/perf-targz-src-pkg .
make_no_ui_O: make NO_NEWT=1 NO_SLANG=1 NO_GTK2=1
make_debug_O: make DEBUG=1
make_no_libelf_O: make NO_LIBELF=1
make_no_libbionic_O: make NO_LIBBIONIC=1
make_no_libaudit_O: make NO_LIBAUDIT=1
make_pure_O: make
make_no_libbpf_O: make NO_LIBBPF=1
make_tags_O: make tags
make_with_babeltrace_O: make LIBBABELTRACE=1
make_with_clangllvm_O: make LIBCLANGLLVM=1
make_no_auxtrace_O: make NO_AUXTRACE=1
make_perf_o_O: make perf.o
make_no_demangle_O: make NO_DEMANGLE=1
make_clean_all_O: make clean all
make_no_slang_O: make NO_SLANG=1
make_doc_O: make doc
make_no_newt_O: make NO_NEWT=1
make_no_libpython_O: make NO_LIBPYTHON=1
make_util_pmu_bison_o_O: make util/pmu-bison.o
make_install_bin_O: make install-bin
make_no_gtk2_O: make NO_GTK2=1
make_no_backtrace_O: make NO_BACKTRACE=1
make_no_libnuma_O: make NO_LIBNUMA=1
make_no_libdw_dwarf_unwind_O: make NO_LIBDW_DWARF_UNWIND=1
make_util_map_o_O: make util/map.o
make_no_libperl_O: make NO_LIBPERL=1
make_static_O: make LDFLAGS=-static
make_no_libunwind_O: make NO_LIBUNWIND=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_help_O: make help
make_no_scripts_O: make NO_LIBPYTHON=1 NO_LIBPERL=1
OK
$Arnaldo Carvalho de Melo
maintainerPATCH 1/19 perf report: Hide tip message when -q option is given
From: Namhyung Kim <[email protected]>
The tip message at the end was printed regardless of the -q option.
Originally, the message suggested only '-s comm,dso' option for higher level view when no sort option and parent option were given.
Now it shows random help message regardless of the options so the condition can be simplified to honor the -q option.
Committer notes:
Before:
$ perf report --stdio -q
42.77% ls ls [.] _init
13.21% ls ld-2.24.so [.] match_symbol
12.55% ls libc-2.24.so [.] __strcoll_l
11.94% ls libc-2.24.so [.] _init #
# (Tip: Show current config key-value pairs: perf config --list) #
$
After:
$ perf report --stdio -q
42.77% ls ls [.] _init
13.21% ls ld-2.24.so [.] match_symbol
12.55% ls libc-2.24.so [.] __strcoll_l
11.94% ls libc-2.24.so [.] _init$
We still have those two extra lines tho (that git commit insists in turning into one, or git commit --amend doesn't make me add), food for another patch...
--- tools/perf/builtin-report.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
tools/perf/builtin-report.c +1 -2
@@ -394,8 +394,7 @@ static int perf_evlist__tty_browse_hists(struct perf_evlist *evlist,fprintf (stdout,"\n\n" ); } -if (sort_order ==NULL && - parent_pattern == default_parent_pattern) +if (!quiet)fprintf (stdout,"#\n# (%s)\n#\n" , help);if (rep->show_threads) {
Signature · 1 line
2.9.3
Arnaldo Carvalho de Melo
maintainerPATCH 2/19 perf c2c: Clarify help message of --stats option
In reply to Arnaldo Carvalho de MeloFrom: Namhyung Kim <[email protected]>
As it is not strictly asking for only stdio output, but will imply using it.
--- tools/perf/builtin-c2c.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
tools/perf/builtin-c2c.c +1 -1
@@ -2536,7 +2536,7 @@ static int perf_c2c__report(int argc, const char **argv)OPT_BOOLEAN (0 ,"stdio" , &c2c.use_stdio,"Use the stdio interface" ), #endifOPT_BOOLEAN (0 ,"stats" , &c2c.stats_only, -"Use the stdio interface" ), +"Display only statistic tables (implies --stdio)" ),OPT_BOOLEAN (0 ,"full-symbols" , &c2c.symbol_full,"Display full length of symbols" ), OPT_BOOLEAN(0, "no-source", &no_source,
Signature · 1 line
2.9.3
Arnaldo Carvalho de Melo
maintainerPATCH 3/19 perf c2c: Fix display bug when using pipe
In reply to Arnaldo Carvalho de MeloFrom: Namhyung Kim <[email protected]>
Currently 'perf c2c report' determines display mode using the --stdio option, but it could be a problem if stdout is not a tty since setup_browser falls back to stdio in this case.
But perf c2c didn't know this and tried to use TUI browser anyway. It should check "use_browser" variable instead.
For example, the following command showed nothing and broke terminal setting. Now it's fixed..
$ perf c2c report | head
=================================================
Trace Event Information
=================================================
Total records : 136
Locked Load/Store Operations : 6
Load Operations : 62
Loads - uncacheable : 0
Loads - IO : 1
Loads - Miss : 7
Loads - no mapping : 2Committer notes:
When trying it without a proper perf.data file it results in a stuck terminal, just as Namhyung reported above:
[acme@jouet ~]$ perf c2c report | head
WARNING: no sample cpu value[acme@jouet ~]$
One has to kill it from some other xterm. Confirm that this patch fixes it:
After:
$ perf c2c report | head
WARNING: no sample cpu value=================================================
Trace Event Information
=================================================
Total records : 14
Locked Load/Store Operations : 0
Load Operations : 0
Loads - uncacheable : 0
Loads - IO : 0
Loads - Miss : 0
Loads - no mapping : 0
$--- tools/perf/builtin-c2c.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
tools/perf/builtin-c2c.c +1 -1
@@ -2334,7 +2334,7 @@ static int perf_c2c__hists_browse(struct hists *hists)static void perf_c2c_display (struct perf_session *session) { -if (c2c.use_stdio) +if (use_browser ==0 )perf_c2c__hists_fprintf (stdout, session);else perf_c2c__hists_browse (&c2c.hists.hists);
Signature · 1 line
2.9.3
Arnaldo Carvalho de Melo
maintainerPATCH 4/19 perf tools: Missing c2c command in command-list
In reply to Arnaldo Carvalho de MeloFrom: Changbin Du <[email protected]>
Add the c2c command to command-list.txt so perf help can list this command.
Committer notes:
Before:
# perf help | grep c2c #
After:
# perf help | grep c2c
c2c Shared Data C2C/HITM Analyzer.
#--- tools/perf/command-list.txt | 1 + 1 file changed, 1 insertion(+)
tools/perf/command-list.txt +1 -0
@@ -9,6 +9,7 @@ perf-buildid-cache mainporcelain common perf-buildid-list mainporcelain common perf-data mainporcelain common perf-diff mainporcelain common +perf-c2c mainporcelain common perf-config mainporcelain common perf-evlist mainporcelain common perf-ftrace mainporcelain common
Signature · 1 line
2.9.3
Arnaldo Carvalho de Melo
maintainerPATCH 5/19 perf tools: Ignore generated files pmu-events/{jevents,pmu-events.c} for git
In reply to Arnaldo Carvalho de MeloFrom: Changbin Du <[email protected]>
Ignore two files: pmu-events/{jevents,pmu-events.c} which are generated during the build.
Committer notes:
Testing it:
$ make -C tools/perf/ $ git status On branch perf/core Untracked files: (use "git add <file>..." to include in what will be committed)
tools/perf/pmu-events/jevents
tools/perf/pmu-events/pmu-events.c
nothing added to commit but untracked files present (use "git add" to track) $
After the patch:
$ git status On branch perf/core nothing to commit, working tree clean $
--- tools/perf/.gitignore | 2 ++ 1 file changed, 2 insertions(+)
tools/perf/.gitignore +2 -0
@@ -31,3 +31,5 @@ config.mak.autogen .config-detected util/intel-pt-decoder/inat-tables.c arch/*/include/generated/ +pmu-events/pmu-events.c +pmu-events/jevents
Signature · 1 line
2.9.3
Arnaldo Carvalho de Melo
maintainerPATCH 6/19 perf sort: Fix segfault with basic block 'cycles' sort dimension
In reply to Arnaldo Carvalho de MeloFrom: Changbin Du <[email protected]>
Skip the sample which doesn't have branch_info to avoid segmentation fault:
The fault can be reproduced by:
perf record -a
perf report -F cycles
--- tools/perf/util/sort.c | 5 +++++ 1 file changed, 5 insertions(+)
tools/perf/util/sort.c +5 -0
@@ -846,6 +846,9 @@ static int hist_entry__mispredict_snprintf(struct hist_entry *he, char *bf,static int64_t sort__cycles_cmp (struct hist_entry *left,struct hist_entry *right) { +if (!left->branch_info || !right->branch_info) +return cmp_null (left->branch_info, right->branch_info); +return left->branch_info->flags.cycles - right->branch_info->flags.cycles; }
@@ -853,6 +856,8 @@ sort__cycles_cmp(struct hist_entry *left, struct hist_entry *right)static int hist_entry__cycles_snprintf (struct hist_entry *he,char *bf,size_t size,unsigned int width) { +if (!he->branch_info) +return scnprintf (bf, size,"%-.*s" , width,"N/A" );if (he->branch_info->flags.cycles ==0 )return repsep_snprintf (bf, size,"%-*s" , width,"-" ); return repsep_snprintf(bf, size, "%-*hd", width,
Signature · 1 line
2.9.3
Arnaldo Carvalho de Melo
maintainerPATCH 7/19 perf report: Document +field style argument support for --field option
In reply to Arnaldo Carvalho de MeloFrom: Changbin Du <[email protected]>
Commit 2f3f9bcf000b ("perf tools: Add +field argument support for --field option") by Jiri Olsa <[email protected]> introduced +field style argument support for --field option.
This is useful but not updated documentation. This add a little description there.
--- tools/perf/Documentation/perf-report.txt | 3 +++ 1 file changed, 3 insertions(+)
tools/perf/Documentation/perf-report.txt +3 -0
@@ -173,6 +173,9 @@ OPTIONS By default, every sort keys not specified in -F will be appended automatically. + If the keys starts with a prefix '+', then it will append the specified + field(s) to the default field order. For example: perf report -F +period,sample. + -p:: --parent=<regex>:: A regex filter to identify parent. The parent is a caller of this
Signature · 1 line
2.9.3
Arnaldo Carvalho de Melo
maintainerPATCH 8/19 perf hists browser: Fix typo in function switch_data_file
In reply to Arnaldo Carvalho de MeloFrom: Changbin Du <[email protected]>
Should clear buf 'abs_path', not 'options'.
--- tools/perf/ui/browsers/hists.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
tools/perf/ui/browsers/hists.c +1 -1
@@ -2308,7 +2308,7 @@ static int switch_data_file(void)return ret;memset (options,0 ,sizeof (options)); -memset (options,0 ,sizeof (abs_path)); +memset (abs_path,0 ,sizeof (abs_path));while ((dent =readdir (pwd_dir))) {char path[PATH_MAX ];
Signature · 1 line
2.9.3
Arnaldo Carvalho de Melo
maintainerPATCH 9/19 perf: Add PERF_RECORD_NAMESPACES to include namespaces related info
In reply to Arnaldo Carvalho de MeloFrom: Hari Bathini <[email protected]>
With the advert of container technologies like docker, that depend on namespaces for isolation, there is a need for tracing support for namespaces. This patch introduces new PERF_RECORD_NAMESPACES event for recording namespaces related info. By recording info for every namespace, it is left to userspace to take a call on the definition of a container and trace containers by updating perf tool accordingly.
Each namespace has a combination of device and inode numbers. Though every namespace has the same device number currently, that may change in future to avoid the need for a namespace of namespaces. Considering such possibility, record both device and inode numbers separately for each namespace.
--- include/linux/perf_event.h | 2 + include/uapi/linux/perf_event.h | 32 ++++++++- kernel/events/core.c | 139 ++++++++++++++++++++++++++++++++++++++++ kernel/fork.c | 2 + kernel/nsproxy.c | 3 + 5 files changed, 177 insertions(+), 1 deletion(-)
include/linux/perf_event.h +2 -0
@@ -1112,6 +1112,7 @@ extern int perf_unregister_guest_info_callbacks(struct perf_guest_info_callbacksextern void perf_event_exec (void );extern void perf_event_comm (struct task_struct *tsk,bool exec); +extern void perf_event_namespaces (struct task_struct *tsk);extern void perf_event_fork (struct task_struct *tsk);/* Callchains */
@@ -1315,6 +1316,7 @@ static inline int perf_unregister_guest_info_callbacksstatic inline void perf_event_mmap (struct vm_area_struct *vma) { }static inline void perf_event_exec (void ) { }static inline void perf_event_comm (struct task_struct *tsk,bool exec) { } +static inline void perf_event_namespaces (struct task_struct *tsk) { }static inline void perf_event_fork (struct task_struct *tsk) { }static inline void perf_event_init (void ) { }static inline int perf_swevent_get_recursion_context (void ) {return -1 ; }
include/uapi/linux/perf_event.h +31 -1
@@ -344,7 +344,8 @@ struct perf_event_attr { use_clockid : 1, /* use @clockid for time fields */ context_switch : 1, /* context switch data */ write_backward : 1, /* Write ring buffer from end to beginning */ - __reserved_1 : 36; + namespaces : 1, /* include namespaces data */ + __reserved_1 : 35;union {__u32 wakeup_events;/* wakeup every n events */
@@ -610,6 +611,23 @@ struct perf_event_header {__u16 size; }; +struct perf_ns_link_info { +__u64 dev; +__u64 ino; +}; + +enum { +NET_NS_INDEX =0 , +UTS_NS_INDEX =1 , +IPC_NS_INDEX =2 , +PID_NS_INDEX =3 , +USER_NS_INDEX =4 , +MNT_NS_INDEX =5 , +CGROUP_NS_INDEX =6 , + +NR_NAMESPACES ,/* number of available namespaces */ +}; +enum perf_event_type {/*
@@ -862,6 +880,18 @@ enum perf_event_type {*/ PERF_RECORD_SWITCH_CPU_WIDE =15 , +/* +* struct { +* struct perf_event_header header; +* u32 pid; +* u32 tid; +* u64 nr_namespaces; +* { u64 dev, inode; } [nr_namespaces]; +* struct sample_id sample_id; +* }; +*/ +PERF_RECORD_NAMESPACES =16 , + PERF_RECORD_MAX, /* non-ABI */ };
kernel/events/core.c +139 -0
181 lines not on this page · raw message
kernel/fork.c +2 -0
@@ -2352,6 +2352,8 @@ SYSCALL_DEFINE1(unshare, unsigned long, unshare_flags) } } +perf_event_namespaces (current); + bad_unshare_cleanup_cred:if (new_cred)put_cred (new_cred);
kernel/nsproxy.c +3 -0
@@ -26,6 +26,7 @@#include <linux/file.h> #include <linux/syscalls.h> #include <linux/cgroup.h> +#include <linux/perf_event.h> static struct kmem_cache *nsproxy_cachep;
@@ -262,6 +263,8 @@ SYSCALL_DEFINE2(setns, int, fd, int, nstype) goto out; }switch_task_namespaces (tsk, new_nsproxy); + +perf_event_namespaces (tsk); out:fput (file);return err;
Signature · 1 line
2.9.3
Arnaldo Carvalho de Melo
maintainerPATCH 10/19 perf tools: Add PERF_RECORD_NAMESPACES to include namespaces related info
In reply to Arnaldo Carvalho de MeloFrom: Hari Bathini <[email protected]>
Introduce a new option to record PERF_RECORD_NAMESPACES events emitted by the kernel when fork, clone, setns or unshare are invoked. And update perf-record documentation with the new option to record namespace events.
Committer notes:
Combined it with a later patch to allow printing it via 'perf report -D' and be able to test the feature introduced in this patch. Had to move here also perf_ns__name(), that was introduced in another later patch.
Also used PRIu64 and PRIx64 to fix the build in some enfironments wrt:
util/event.c:1129:39: error: format '%lx' expects argument of type 'long unsigned int', but argument 6 has type 'long long unsigned int' [-Werror=format=]
ret += fprintf(fp, "%u/%s: %lu/0x%lx%s", idx
^Testing it:
# perf record --namespaces -a
^C[ perf record: Woken up 1 times to write data ]
[ perf record: Captured and wrote 1.083 MB perf.data (423 samples) ]
#
# perf report -D
<SNIP>
3 2028902078892 0x115140 [0xa0]: PERF_RECORD_NAMESPACES 14783/14783 - nr_namespaces: 7
[0/net: 3/0xf0000081, 1/uts: 3/0xeffffffe, 2/ipc: 3/0xefffffff, 3/pid: 3/0xeffffffc,
4/user: 3/0xeffffffd, 5/mnt: 3/0xf0000000, 6/cgroup: 3/0xeffffffb] 0x1151e0 [0x30]: event: 9
.
. ... raw event: size 48 bytes
. 0000: 09 00 00 00 02 00 30 00 c4 71 82 68 0c 7f 00 00 ......0..q.h.... . 0010: a9 39 00 00 a9 39 00 00 94 28 fe 63 d8 01 00 00 .9...9...(.c.... . 0020: 03 00 00 00 00 00 00 00 ce c4 02 00 00 00 00 00 ................
<SNIP>
NAMESPACES events: 1
<SNIP>
#
--- tools/include/uapi/linux/perf_event.h | 32 +++++++++++++++++- tools/perf/Documentation/perf-record.txt | 3 ++ tools/perf/builtin-annotate.c | 1 + tools/perf/builtin-diff.c | 1 + tools/perf/builtin-inject.c | 13 ++++++++ tools/perf/builtin-kmem.c | 1 + tools/perf/builtin-kvm.c | 2 ++ tools/perf/builtin-lock.c | 1 + tools/perf/builtin-mem.c | 1 + tools/perf/builtin-record.c | 6 ++++ tools/perf/builtin-report.c | 1 + tools/perf/builtin-sched.c | 1 + tools/perf/builtin-script.c | 1 + tools/perf/builtin-trace.c | 3 +- tools/perf/perf.h | 1 + tools/perf/util/Build | 1 + tools/perf/util/data-convert-bt.c | 1 + tools/perf/util/event.c | 56 ++++++++++++++++++++++++++++++++ tools/perf/util/event.h | 13 ++++++++ tools/perf/util/evsel.c | 3 ++ tools/perf/util/machine.c | 34 +++++++++++++++++++ tools/perf/util/machine.h | 3 ++ tools/perf/util/namespaces.c | 36 ++++++++++++++++++++ tools/perf/util/namespaces.h | 26 +++++++++++++++ tools/perf/util/session.c | 7 ++++ tools/perf/util/thread.c | 44 +++++++++++++++++++++++-- tools/perf/util/thread.h | 6 ++++ tools/perf/util/tool.h | 2 ++ 28 files changed, 296 insertions(+), 4 deletions(-) create mode 100644 tools/perf/util/namespaces.c create mode 100644 tools/perf/util/namespaces.h
tools/include/uapi/linux/perf_event.h +31 -1
@@ -344,7 +344,8 @@ struct perf_event_attr { use_clockid : 1, /* use @clockid for time fields */ context_switch : 1, /* context switch data */ write_backward : 1, /* Write ring buffer from end to beginning */ - __reserved_1 : 36; + namespaces : 1, /* include namespaces data */ + __reserved_1 : 35;union {__u32 wakeup_events;/* wakeup every n events */
@@ -610,6 +611,23 @@ struct perf_event_header {__u16 size; }; +struct perf_ns_link_info { +__u64 dev; +__u64 ino; +}; + +enum { +NET_NS_INDEX =0 , +UTS_NS_INDEX =1 , +IPC_NS_INDEX =2 , +PID_NS_INDEX =3 , +USER_NS_INDEX =4 , +MNT_NS_INDEX =5 , +CGROUP_NS_INDEX =6 , + +NR_NAMESPACES ,/* number of available namespaces */ +}; +enum perf_event_type {/*
@@ -862,6 +880,18 @@ enum perf_event_type {*/ PERF_RECORD_SWITCH_CPU_WIDE =15 , +/* +* struct { +* struct perf_event_header header; +* u32 pid; +* u32 tid; +* u64 nr_namespaces; +* { u64 dev, inode; } [nr_namespaces]; +* struct sample_id sample_id; +* }; +*/ +PERF_RECORD_NAMESPACES =16 , + PERF_RECORD_MAX, /* non-ABI */ };
tools/perf/Documentation/perf-record.txt +3 -0
@@ -347,6 +347,9 @@ Enable weightened sampling. An additional weight is recorded per sample and can displayed with the weight and local_weight sort keys. This currently works for TSX abort events and some memory events in precise mode on modern Intel CPUs. +--namespaces:: +Record events of type PERF_RECORD_NAMESPACES. + --transaction:: Record transaction flags for transaction related events.
tools/perf/builtin-annotate.c +1 -0
@@ -393,6 +393,7 @@ int cmd_annotate(int argc, const char **argv, const char *prefix __maybe_unused) .comm = perf_event__process_comm, .exit = perf_event__process_exit, .fork = perf_event__process_fork, + .namespaces = perf_event__process_namespaces, .ordered_events = true, .ordering_requires_timestamps = true, },
tools/perf/builtin-diff.c +1 -0
@@ -364,6 +364,7 @@ static struct perf_tool tool = { .exit = perf_event__process_exit, .fork = perf_event__process_fork, .lost = perf_event__process_lost, + .namespaces = perf_event__process_namespaces, .ordered_events = true, .ordering_requires_timestamps = true, };
tools/perf/builtin-inject.c +13 -0
@@ -333,6 +333,18 @@ static int perf_event__repipe_comm(struct perf_tool *tool,return err; } +static int perf_event__repipe_namespaces (struct perf_tool *tool, +union perf_event *event, +struct perf_sample *sample, +struct machine *machine) +{ +int err =perf_event__process_namespaces (tool, event, sample, machine); + +perf_event__repipe (tool, event, sample, machine); + +return err; +} + static int perf_event__repipe_exit(struct perf_tool *tool, union perf_event *event, struct perf_sample *sample,
@@ -660,6 +672,7 @@ static int __cmd_inject(struct perf_inject *inject) session->itrace_synth_opts = &inject->itrace_synth_opts; inject->itrace_synth_opts.inject = true; inject->tool.comm = perf_event__repipe_comm; + inject->tool.namespaces = perf_event__repipe_namespaces; inject->tool.exit = perf_event__repipe_exit; inject->tool.id_index = perf_event__repipe_id_index; inject->tool.auxtrace_info = perf_event__process_auxtrace_info;
tools/perf/builtin-kmem.c +1 -0
@@ -964,6 +964,7 @@ static struct perf_tool perf_kmem = { .comm = perf_event__process_comm, .mmap = perf_event__process_mmap, .mmap2 = perf_event__process_mmap2, + .namespaces = perf_event__process_namespaces, .ordered_events = true, };
tools/perf/builtin-kvm.c +2 -0
@@ -1044,6 +1044,7 @@ static int read_events(struct perf_kvm_stat *kvm)struct perf_tool eops = { .sample = process_sample_event, .comm = perf_event__process_comm, + .namespaces = perf_event__process_namespaces, .ordered_events = true, };struct perf_data_file file = {
@@ -1348,6 +1349,7 @@ static int kvm_events_live(struct perf_kvm_stat *kvm, kvm->tool.exit = perf_event__process_exit; kvm->tool.fork = perf_event__process_fork; kvm->tool.lost = process_lost_event; + kvm->tool.namespaces = perf_event__process_namespaces; kvm->tool.ordered_events = true;perf_tool__fill_defaults (&kvm->tool);
tools/perf/builtin-lock.c +1 -0
@@ -858,6 +858,7 @@ static int __cmd_report(bool display_info)struct perf_tool eops = { .sample = process_sample_event, .comm = perf_event__process_comm, + .namespaces = perf_event__process_namespaces, .ordered_events = true, };struct perf_data_file file = {
tools/perf/builtin-mem.c +1 -0
@@ -342,6 +342,7 @@ int cmd_mem(int argc, const char **argv, const char *prefix __maybe_unused) .lost = perf_event__process_lost, .fork = perf_event__process_fork, .build_id = perf_event__process_build_id, + .namespaces = perf_event__process_namespaces, .ordered_events = true, }, .input_name = "perf.data",
tools/perf/builtin-record.c +6 -0
@@ -876,6 +876,9 @@ static int __cmd_record(struct record *rec, int argc, const char **argv)signal (SIGTERM , sig_handler);signal (SIGSEGV , sigsegv_handler); +if (rec->opts.record_namespaces) + tool->namespace_events = true; +if (rec->opts.auxtrace_snapshot_mode || rec->switch_output.enabled) {signal (SIGUSR2 , snapshot_sig_handler);if (rec->opts.auxtrace_snapshot_mode)
@@ -1497,6 +1500,7 @@ static struct record record = { .fork = perf_event__process_fork, .exit = perf_event__process_exit, .comm = perf_event__process_comm, + .namespaces = perf_event__process_namespaces, .mmap = perf_event__process_mmap, .mmap2 = perf_event__process_mmap2, .ordered_events = true,
@@ -1611,6 +1615,8 @@ static struct option __record_options[] = { "opts", "AUX area tracing Snapshot Mode", ""),OPT_UINTEGER (0 ,"proc-map-timeout" , &record.opts.proc_map_timeout,"per thread proc mmap processing timeout in ms" ), +OPT_BOOLEAN (0 ,"namespaces" , &record.opts.record_namespaces, +"Record namespaces events" ),OPT_BOOLEAN (0 ,"switch-events" , &record.opts.record_switch_events,"Record context switch events" ), OPT_BOOLEAN_FLAG(0, "all-kernel", &record.opts.all_kernel,
tools/perf/builtin-report.c +1 -0
@@ -700,6 +700,7 @@ int cmd_report(int argc, const char **argv, const char *prefix __maybe_unused) .mmap = perf_event__process_mmap, .mmap2 = perf_event__process_mmap2, .comm = perf_event__process_comm, + .namespaces = perf_event__process_namespaces, .exit = perf_event__process_exit, .fork = perf_event__process_fork, .lost = perf_event__process_lost,
tools/perf/builtin-sched.c +1 -0
@@ -3272,6 +3272,7 @@ int cmd_sched(int argc, const char **argv, const char *prefix __maybe_unused) .tool = { .sample = perf_sched__process_tracepoint_sample, .comm = perf_event__process_comm, + .namespaces = perf_event__process_namespaces, .lost = perf_event__process_lost, .fork = perf_sched__process_fork_event, .ordered_events = true,
tools/perf/builtin-script.c +1 -0
@@ -2097,6 +2097,7 @@ int cmd_script(int argc, const char **argv, const char *prefix __maybe_unused) .mmap = perf_event__process_mmap, .mmap2 = perf_event__process_mmap2, .comm = perf_event__process_comm, + .namespaces = perf_event__process_namespaces, .exit = perf_event__process_exit, .fork = perf_event__process_fork, .attr = process_attr,
tools/perf/builtin-trace.c +2 -1
@@ -2415,8 +2415,9 @@ static int trace__replay(struct trace *trace) trace->tool.exit = perf_event__process_exit; trace->tool.fork = perf_event__process_fork; trace->tool.attr = perf_event__process_attr; - trace->tool.tracing_data = perf_event__process_tracing_data; + trace->tool.tracing_data = perf_event__process_tracing_data; trace->tool.build_id = perf_event__process_build_id; + trace->tool.namespaces = perf_event__process_namespaces; trace->tool.ordered_events = true; trace->tool.ordering_requires_timestamps = true;
tools/perf/perf.h +1 -0
@@ -50,6 +50,7 @@ struct record_opts {bool running_time;bool full_auxtrace;bool auxtrace_snapshot_mode; +bool record_namespaces;bool record_switch_events;bool all_kernel;bool all_user;
tools/perf/util/Build +1 -0
@@ -42,6 +42,7 @@ libperf-y += pstack.o libperf-y += session.o libperf-$(CONFIG_AUDIT) += syscalltbl.o libperf-y += ordered-events.o +libperf-y += namespaces.o libperf-y += comm.o libperf-y += thread.o libperf-y += thread_map.o
tools/perf/util/data-convert-bt.c +1 -0
@@ -1468,6 +1468,7 @@ int bt_convert__perf2ctf(const char *input, const char *path, .lost = perf_event__process_lost, .tracing_data = perf_event__process_tracing_data, .build_id = perf_event__process_build_id, + .namespaces = perf_event__process_namespaces, .ordered_events = true, .ordering_requires_timestamps = true, },
tools/perf/util/event.c +56 -0
92 lines not on this page · raw message
tools/perf/util/event.h +13 -0
@@ -39,6 +39,13 @@ struct comm_event {char comm[16 ]; }; +struct namespaces_event { +struct perf_event_header header; +u32 pid, tid; +u64 nr_namespaces; +struct perf_ns_link_info link_info[]; +}; +struct fork_event {struct perf_event_header header;u32 pid, ppid;
@@ -485,6 +492,7 @@ union perf_event {struct mmap_event mmap;struct mmap2_event mmap2;struct comm_event comm; +struct namespaces_event namespaces;struct fork_event fork;struct lost_event lost;struct lost_samples_event lost_samples;
@@ -587,6 +595,10 @@ int perf_event__process_switch(struct perf_tool *tool,union perf_event *event, struct perf_sample *sample, struct machine *machine); +int perf_event__process_namespaces (struct perf_tool *tool, +union perf_event *event, +struct perf_sample *sample, +struct machine *machine); int perf_event__process_mmap(struct perf_tool *tool, union perf_event *event, struct perf_sample *sample,
@@ -653,6 +665,7 @@ size_t perf_event__fprintf_itrace_start(union perf_event *event, FILE *fp);size_t perf_event__fprintf_switch (union perf_event *event,FILE *fp);size_t perf_event__fprintf_thread_map (union perf_event *event,FILE *fp);size_t perf_event__fprintf_cpu_map (union perf_event *event,FILE *fp); +size_t perf_event__fprintf_namespaces (union perf_event *event,FILE *fp);size_t perf_event__fprintf (union perf_event *event,FILE *fp); u64 kallsyms__get_function_start(const char *kallsyms_filename,
tools/perf/util/evsel.c +3 -0
@@ -932,6 +932,9 @@ void perf_evsel__config(struct perf_evsel *evsel, struct record_opts *opts, attr->mmap2 = track && !perf_missing_features.mmap2; attr->comm = track; +if (opts->record_namespaces) + attr->namespaces = track; +if (opts->record_switch_events) attr->context_switch = track;
tools/perf/util/machine.c +34 -0
@@ -13,6 +13,7 @@#include <symbol/kallsyms.h> #include "unwind.h" #include "linux/hash.h" +#include "asm/bug.h" static void __machine__remove_thread (struct machine *machine,struct thread *th,bool lock);
@@ -501,6 +502,37 @@ int machine__process_comm_event(struct machine *machine, union perf_event *eventreturn err; } +int machine__process_namespaces_event (struct machine *machine__maybe_unused , +union perf_event *event, +struct perf_sample *sample__maybe_unused ) +{ +struct thread *thread =machine__findnew_thread (machine, + event->namespaces.pid, + event->namespaces.tid); +int err =0 ; + +WARN_ONCE (event->namespaces.nr_namespaces >NR_NAMESPACES , +"\nWARNING: kernel seems to support more namespaces than perf" +" tool.\nTry updating the perf tool..\n\n" ); + +WARN_ONCE (event->namespaces.nr_namespaces <NR_NAMESPACES , +"\nWARNING: perf tool seems to support more namespaces than" +" the kernel.\nTry updating the kernel..\n\n" ); + +if (dump_trace) +perf_event__fprintf_namespaces (event, stdout); + +if (thread ==NULL || +thread__set_namespaces (thread, sample->time, &event->namespaces)) { +dump_printf ("problem processing PERF_RECORD_NAMESPACES, skipping event.\n" ); + err =-1 ; + } + +thread__put (thread); + +return err; +} +int machine__process_lost_event (struct machine *machine__maybe_unused ,union perf_event *event,struct perf_sample *sample__maybe_unused ) {
@@ -1538,6 +1570,8 @@ int machine__process_event(struct machine *machine, union perf_event *event, ret =machine__process_comm_event (machine, event, sample);break ;case PERF_RECORD_MMAP : ret =machine__process_mmap_event (machine, event, sample);break ; +case PERF_RECORD_NAMESPACES : + ret =machine__process_namespaces_event (machine, event, sample);break ;case PERF_RECORD_MMAP2 : ret =machine__process_mmap2_event (machine, event, sample);break ;case PERF_RECORD_FORK :
tools/perf/util/machine.h +3 -0
@@ -97,6 +97,9 @@ int machine__process_itrace_start_event(struct machine *machine, union perf_event *event);int machine__process_switch_event (struct machine *machine,union perf_event *event); +int machine__process_namespaces_event (struct machine *machine, +union perf_event *event, +struct perf_sample *sample);int machine__process_mmap_event (struct machine *machine,union perf_event *event,struct perf_sample *sample); int machine__process_mmap2_event(struct machine *machine, union perf_event *event,
tools/perf/util/namespaces.c new file +36 -0
@@ -0,0 +1,36 @@ +/* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License, version 2, as +* published by the Free Software Foundation. +* +* Copyright (C) 2017 Hari Bathini, IBM Corporation +*/ + +#include "namespaces.h" +#include "util.h" +#include "event.h" +#include <stdlib.h> +#include <stdio.h> + +struct namespaces *namespaces__new (struct namespaces_event *event) +{ +struct namespaces *namespaces; +u64 link_info_size = ((event ? event->nr_namespaces :NR_NAMESPACES ) * +sizeof (struct perf_ns_link_info )); + + namespaces =zalloc (sizeof (struct namespaces ) + link_info_size); +if (!namespaces) +return NULL ; + + namespaces->end_time =-1 ; + +if (event) +memcpy (namespaces->link_info, event->link_info, link_info_size); + +return namespaces; +} + +void namespaces__free (struct namespaces *namespaces) +{ +free (namespaces); +}
tools/perf/util/namespaces.h new file +26 -0
@@ -0,0 +1,26 @@ +/* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License, version 2, as +* published by the Free Software Foundation. +* +* Copyright (C) 2017 Hari Bathini, IBM Corporation +*/ + +#ifndef __PERF_NAMESPACES_H +#define __PERF_NAMESPACES_H + +#include "../perf.h" +#include <linux/list.h> + +struct namespaces_event ; + +struct namespaces { +struct list_head list; +u64 end_time; +struct perf_ns_link_info link_info[]; +}; + +struct namespaces *namespaces__new (struct namespaces_event *event); +void namespaces__free (struct namespaces *namespaces); + +#endif /* __PERF_NAMESPACES_H */
tools/perf/util/session.c +7 -0
@@ -1239,6 +1239,8 @@ static int machines__deliver_event(struct machines *machines,return tool->mmap2 (tool, event, sample, machine);case PERF_RECORD_COMM :return tool->comm (tool, event, sample, machine); +case PERF_RECORD_NAMESPACES : +return tool->namespaces (tool, event, sample, machine);case PERF_RECORD_FORK :return tool->fork (tool, event, sample, machine);case PERF_RECORD_EXIT :
@@ -1494,6 +1496,11 @@ int perf_session__register_idle_thread(struct perf_session *session) err =-1 ; } +if (thread ==NULL ||thread__set_namespaces (thread,0 ,NULL )) { +pr_err ("problem inserting idle task.\n" ); + err =-1 ; + } +/* machine__findnew_thread() got the thread, so put it */ thread__put (thread);return err;
tools/perf/util/thread.c +42 -2
74 lines not on this page · raw message
tools/perf/util/thread.h +6 -0
@@ -28,6 +28,7 @@ struct thread {bool comm_set;int comm_len;bool dead;/* if set thread has exited */ +struct list_head namespaces_list;struct list_head comm_list;u64 db_id;
@@ -40,6 +41,7 @@ struct thread { };struct machine ; +struct namespaces ;struct comm ;struct thread *thread__new (pid_t pid,pid_t tid);
@@ -62,6 +64,10 @@ static inline void thread__exited(struct thread *thread) thread->dead = true; } +struct namespaces *thread__namespaces (const struct thread *thread); +int thread__set_namespaces (struct thread *thread,u64 timestamp, +struct namespaces_event *event); +int __thread__set_comm (struct thread *thread,const char *comm,u64 timestamp,bool exec); static inline int thread__set_comm(struct thread *thread, const char *comm,
tools/perf/util/tool.h +2 -0
@@ -40,6 +40,7 @@ struct perf_tool {event_op mmap, mmap2, comm, + namespaces, fork, exit, lost,
@@ -66,6 +67,7 @@ struct perf_tool {event_op3 auxtrace;bool ordered_events;bool ordering_requires_timestamps; + bool namespace_events; };#endif /* __PERF_TOOL_H */
Signature · 1 line
2.9.3
Arnaldo Carvalho de Melo
maintainerPATCH 11/19 perf record: Synthesize namespace events for current processes
In reply to Arnaldo Carvalho de MeloFrom: Hari Bathini <[email protected]>
Synthesize PERF_RECORD_NAMESPACES events for processes that were running prior to invocation of perf record. The data for this is taken from /proc/$PID/ns. These changes make way for analyzing events with regard to namespaces.
Committer notes:
Check if 'tool' is NULL in perf_event__synthesize_namespaces(), as in the test__mmap_thread_lookup case, i.e. 'perf test Lookup mmap thread".
Testing it:
# ps axH > /tmp/allthreads # perf record -a --namespaces usleep 1 [ perf record: Woken up 1 times to write data ] [ perf record: Captured and wrote 1.169 MB perf.data (8 samples) ] # perf report -D | grep PERF_RECORD_NAMESPACES | wc -l 602 # wc -l /tmp/allthreads 601 /tmp/allthreads # tail /tmp/allthreads 16951 pts/4 T 0:00 git rebase -i a033bf1bfacdaa25642e6bcc857a7d0f67cc3c92^ 16952 pts/4 T 0:00 /bin/sh /usr/libexec/git-core/git-rebase -i a033bf1bfacdaa25642e6bcc857a7d0f67cc3c92^ 17176 pts/4 T 0:00 git commit --amend --no-post-rewrite 17204 pts/4 T 0:00 vim /home/acme/git/linux/.git/COMMIT_EDITMSG 18939 ? S 0:00 [kworker/2:1] 18947 ? S 0:00 [kworker/3:0] 18974 ? S 0:00 [kworker/1:0] 19047 ? S 0:00 [kworker/0:1] 19152 pts/6 S+ 0:00 weechat 19153 pts/7 R+ 0:00 ps axH # perf report -D | grep PERF_RECORD_NAMESPACES | tail 0 0 0x125068 [0xa0]: PERF_RECORD_NAMESPACES 17176/17176 - nr_namespaces: 7 0 0 0x1255b8 [0xa0]: PERF_RECORD_NAMESPACES 17204/17204 - nr_namespaces: 7 0 0 0x125df0 [0xa0]: PERF_RECORD_NAMESPACES 18939/18939 - nr_namespaces: 7 0 0 0x125f00 [0xa0]: PERF_RECORD_NAMESPACES 18947/18947 - nr_namespaces: 7 0 0 0x126010 [0xa0]: PERF_RECORD_NAMESPACES 18974/18974 - nr_namespaces: 7 0 0 0x126120 [0xa0]: PERF_RECORD_NAMESPACES 19047/19047 - nr_namespaces: 7 0 0 0x126230 [0xa0]: PERF_RECORD_NAMESPACES 19152/19152 - nr_namespaces: 7 0 0 0x129330 [0xa0]: PERF_RECORD_NAMESPACES 19154/19154 - nr_namespaces: 7 0 0 0x12a1f8 [0xa0]: PERF_RECORD_NAMESPACES 19155/19155 - nr_namespaces: 7 0 0 0x12b0b8 [0xa0]: PERF_RECORD_NAMESPACES 19155/19155 - nr_namespaces: 7 #
Humm, investigate why we got two record for the 19155 pid/tid...
--- tools/perf/builtin-record.c | 29 ++++++++++++-- tools/perf/util/event.c | 94 ++++++++++++++++++++++++++++++++++++++++++--- tools/perf/util/event.h | 6 +++ 3 files changed, 119 insertions(+), 10 deletions(-)
tools/perf/builtin-record.c +25 -4
@@ -986,6 +986,7 @@ static int __cmd_record(struct record *rec, int argc, const char **argv)*/ if (forks) {union perf_event *event; +pid_t tgid; event =malloc (sizeof (event->comm) + machine->id_hdr_size);if (event ==NULL ) {
@@ -999,10 +1000,30 @@ static int __cmd_record(struct record *rec, int argc, const char **argv)* cannot see a correct process name for those events. * Synthesize COMM event to prevent it. */ -perf_event__synthesize_comm (tool, event, - rec->evlist->workload.pid, - process_synthesized_event, - machine); + tgid =perf_event__synthesize_comm (tool, event, + rec->evlist->workload.pid, + process_synthesized_event, + machine); +free (event); + +if (tgid ==-1 ) + goto out_child; + + event =malloc (sizeof (event->namespaces) + + (NR_NAMESPACES *sizeof (struct perf_ns_link_info )) + + machine->id_hdr_size); +if (event ==NULL ) { + err = -ENOMEM ; + goto out_child; + } + +/* +* Synthesize NAMESPACES event for the command specified. +*/ +perf_event__synthesize_namespaces (tool, event, + rec->evlist->workload.pid, + tgid, process_synthesized_event, + machine);free (event);perf_evlist__start_workload (rec->evlist);
tools/perf/util/event.c +88 -6
173 lines not on this page · raw message
tools/perf/util/event.h +6 -0
@@ -648,6 +648,12 @@ pid_t perf_event__synthesize_comm(struct perf_tool *tool,perf_event__handler_t process, struct machine *machine); +int perf_event__synthesize_namespaces (struct perf_tool *tool, +union perf_event *event, +pid_t pid,pid_t tgid, +perf_event__handler_t process, +struct machine *machine); + int perf_event__synthesize_mmap_events(struct perf_tool *tool, union perf_event *event, pid_t pid, pid_t tgid,
Signature · 1 line
2.9.3
Arnaldo Carvalho de Melo
maintainerPATCH 12/19 perf script: Add script print support for namespace events
In reply to Arnaldo Carvalho de MeloFrom: Hari Bathini <[email protected]>
Introduce a new option to display events of type PERF_RECORD_NAMESPACES and update perf-script documentation accordingly.
Shown below is output (trimmed) of perf script command with the newly introduced option, on perf.data generated with perf record command using --namespaces option.
$ perf script --show-namespace-events
swapper 0 [000] 0.000000: PERF_RECORD_NAMESPACES 1/1 - nr_namespaces: 7
[0/net: 3/0xf000001c, 1/uts: 3/0xeffffffe, 2/ipc: 3/0xefffffff, 3/pid: 3/0xeffffffc,
4/user: 3/0xeffffffd, 5/mnt: 3/0xf0000000, 6/cgroup: 3/0xeffffffb]
swapper 0 [000] 0.000000: PERF_RECORD_NAMESPACES 2/2 - nr_namespaces: 7
[0/net: 3/0xf000001c, 1/uts: 3/0xeffffffe, 2/ipc: 3/0xefffffff, 3/pid: 3/0xeffffffc,
4/user: 3/0xeffffffd, 5/mnt: 3/0xf0000000, 6/cgroup: 3/0xeffffffb]Commiter notes:
Testing it:
Investigating that double PERF_RECORD_NAMESPACES for the 19155 pid/tid... Its more than that, there are two PERF_RECORD_COMM as well, and with zeroed timestamps, so probably a synthesizing artifact...
# perf script --show-task --show-namespace
<SNIP>
perf 0 [000] 0.000000: PERF_RECORD_COMM: perf:19154/19154
perf 0 [000] 0.000000: PERF_RECORD_FORK(19155:19155):(19154:19154)
perf 0 [000] 0.000000: PERF_RECORD_NAMESPACES 19155/19155 - nr_namespaces: 7
[0/net: 3/0xf0000081, 1/uts: 3/0xeffffffe, 2/ipc: 3/0xefffffff, 3/pid: 3/0xeffffffc,
4/user: 3/0xeffffffd, 5/mnt: 3/0xf0000000, 6/cgroup: 3/0xeffffffb]
perf 0 [000] 0.000000: PERF_RECORD_COMM: perf:19155/19155
perf 0 [000] 0.000000: PERF_RECORD_COMM: perf:19155/19155
perf 0 [000] 0.000000: PERF_RECORD_NAMESPACES 19155/19155 - nr_namespaces: 7
[0/net: 3/0xf0000081, 1/uts: 3/0xeffffffe, 2/ipc: 3/0xefffffff, 3/pid: 3/0xeffffffc,
4/user: 3/0xeffffffd, 5/mnt: 3/0xf0000000, 6/cgroup: 3/0xeffffffb]
swapper 0 [000] 3110.881834: 1 cycles: ffffffffa7060bf6 native_write_msr (/lib/modules/4.11.0-rc1+/build/vmlinux)<SNIP>
--- tools/perf/Documentation/perf-script.txt | 3 +++ tools/perf/builtin-script.c | 40 ++++++++++++++++++++++++++++++++ 2 files changed, 43 insertions(+)
tools/perf/Documentation/perf-script.txt +3 -0
@@ -248,6 +248,9 @@ OPTIONS --show-mmap-events Display mmap related events (e.g. MMAP, MMAP2). +--show-namespace-events + Display namespace events i.e. events of type PERF_RECORD_NAMESPACES. + --show-switch-events Display context switch events i.e. events of type PERF_RECORD_SWITCH or PERF_RECORD_SWITCH_CPU_WIDE.
tools/perf/builtin-script.c +40 -0
@@ -830,6 +830,7 @@ struct perf_script {bool show_task_events;bool show_mmap_events;bool show_switch_events; +bool show_namespace_events;bool allocated;struct cpu_map *cpus;struct thread_map *threads;
@@ -1118,6 +1119,41 @@ static int process_comm_event(struct perf_tool *tool,return ret; } +static int process_namespaces_event (struct perf_tool *tool, +union perf_event *event, +struct perf_sample *sample, +struct machine *machine) +{ +struct thread *thread; + struct perf_script *script = container_of(tool, struct perf_script, tool); +struct perf_session *session = script->session; +struct perf_evsel *evsel =perf_evlist__id2evsel (session->evlist, sample->id); +int ret =-1 ; + + thread =machine__findnew_thread (machine, event->namespaces.pid, + event->namespaces.tid); +if (thread ==NULL ) { +pr_debug ("problem processing NAMESPACES event, skipping it.\n" ); +return -1 ; + } + +if (perf_event__process_namespaces (tool, event, sample, machine) <0 ) + goto out; + +if (!evsel->attr.sample_id_all) { + sample->cpu =0 ; + sample->time =0 ; + sample->tid = event->namespaces.tid; + sample->pid = event->namespaces.pid; + } +print_sample_start (sample, thread, evsel); +perf_event__fprintf (event, stdout); + ret =0 ; +out: +thread__put (thread); +return ret; +} + static int process_fork_event(struct perf_tool *tool, union perf_event *event, struct perf_sample *sample,
@@ -1293,6 +1329,8 @@ static int __cmd_script(struct perf_script *script) }if (script->show_switch_events) script->tool.context_switch = process_switch_event; +if (script->show_namespace_events) + script->tool.namespaces = process_namespaces_event; ret =perf_session__process_events (script->session);
@@ -2181,6 +2219,8 @@ int cmd_script(int argc, const char **argv, const char *prefix __maybe_unused) "Show the mmap events"),OPT_BOOLEAN ('\0' ,"show-switch-events" , &script.show_switch_events,"Show context switch events (if recorded)" ), +OPT_BOOLEAN ('\0' ,"show-namespace-events" , &script.show_namespace_events, +"Show namespace events (if recorded)" ),OPT_BOOLEAN ('f' ,"force" , &symbol_conf.force,"don't complain, do it" ),OPT_BOOLEAN (0 ,"ns" , &nanosecs, "Use 9 decimal places when displaying time"),
Signature · 1 line
2.9.3
Arnaldo Carvalho de Melo
maintainerPATCH 13/19 perf tools: Add 'cgroup_id' sort order keyword
In reply to Arnaldo Carvalho de MeloFrom: Hari Bathini <[email protected]>
This patch introduces a cgroup identifier entry field in perf report to identify or distinguish data of different cgroups. It uses the device number and inode number of cgroup namespace, included in perf data with the new PERF_RECORD_NAMESPACES event, as cgroup identifier.
With the assumption that each container is created with it's own cgroup namespace, this allows assessment/analysis of multiple containers at once.
A simple test for this would be to clone a few processes passing SIGCHILD & CLONE_NEWCROUP flags to each of them, execute shell and run different workloads on each of those contexts, while running perf record command with --namespaces option.
Shown below is the output of perf report, sorted with cgroup identifier, on perf.data generated with the above test scenario, clearly indicating one context's considerable use of kernel memory in comparison with others:
$ perf report -s cgroup_id,sample --stdio # # Total Lost Samples: 0 # # Samples: 5K of event 'kmem:kmalloc' # Event count (approx.): 5965 # # Overhead cgroup id (dev/inode) Samples # ........ ..................... ............ # 81.27% 3/0xeffffffb 4848 16.24% 3/0xf00000d0 969 1.16% 3/0xf00000ce 69 0.82% 3/0xf00000cf 49 0.50% 0/0x0 30
While this is a start, there is further scope of improving this. For example, instead of cgroup namespace's device and inode numbers, dev and inode numbers of some or all namespaces may be used to distinguish which processes are running in a given container context.
Also, scripts to map device and inode info to containers sounds plausible for better tracing of containers.
--- tools/perf/Documentation/perf-report.txt | 4 +++- tools/perf/util/hist.c | 7 ++++++ tools/perf/util/hist.h | 1 + tools/perf/util/sort.c | 41 ++++++++++++++++++++++++++++++++ tools/perf/util/sort.h | 7 ++++++ 5 files changed, 59 insertions(+), 1 deletion(-)
tools/perf/Documentation/perf-report.txt +3 -1
@@ -72,7 +72,8 @@ OPTIONS --sort=:: Sort histogram entries by given key(s) - multiple keys can be specified in CSV format. Following sort keys are available: - pid, comm, dso, symbol, parent, cpu, socket, srcline, weight, local_weight. + pid, comm, dso, symbol, parent, cpu, socket, srcline, weight, + local_weight, cgroup_id. Each key has following meaning:
@@ -92,6 +93,7 @@ OPTIONS - weight: Event specific weight, e.g. memory latency or transaction abort cost. This is the global weight. - local_weight: Local weight version of the weight above. + - cgroup_id: ID derived from cgroup namespace device and inode numbers. - transaction: Transaction abort flags. - overhead: Overhead percentage of sample - overhead_sys: Overhead percentage of sample running in system mode
tools/perf/util/hist.c +7 -0
@@ -3,6 +3,7 @@#include "hist.h" #include "map.h" #include "session.h" +#include "namespaces.h" #include "sort.h" #include "evlist.h" #include "evsel.h"
@@ -169,6 +170,7 @@ void hists__calc_col_len(struct hists *hists, struct hist_entry *h)hists__set_unres_dso_col_len (hists,HISTC_MEM_DADDR_DSO ); } +hists__new_col_len (hists,HISTC_CGROUP_ID ,20 );hists__new_col_len (hists,HISTC_CPU ,3 );hists__new_col_len (hists,HISTC_SOCKET ,6 );hists__new_col_len (hists,HISTC_MEM_LOCKED ,6 );
@@ -574,9 +576,14 @@ __hists__add_entry(struct hists *hists,bool sample_self, struct hist_entry_ops *ops) { + struct namespaces *ns = thread__namespaces(al->thread); struct hist_entry entry = { .thread = al->thread, .comm = thread__comm(al->thread), + .cgroup_id = { + .dev = ns ? ns->link_info[CGROUP_NS_INDEX].dev : 0, + .ino = ns ? ns->link_info[CGROUP_NS_INDEX].ino : 0, + }, .ms = { .map = al->map, .sym = al->sym,
tools/perf/util/hist.h +1 -0
@@ -30,6 +30,7 @@ enum hist_column {HISTC_DSO ,HISTC_THREAD ,HISTC_COMM , +HISTC_CGROUP_ID ,HISTC_PARENT ,HISTC_CPU , HISTC_SOCKET,
tools/perf/util/sort.c +41 -0
53 lines not on this page · raw message
tools/perf/util/sort.h +7 -0
@@ -54,6 +54,11 @@ struct he_stat {u32 nr_events; }; +struct namespace_id { +u64 dev; +u64 ino; +}; +struct hist_entry_diff {bool computed;union {
@@ -91,6 +96,7 @@ struct hist_entry {struct map_symbol ms;struct thread *thread;struct comm *comm; +struct namespace_id cgroup_id;u64 ip;u64 transaction;s32 socket;
@@ -212,6 +218,7 @@ enum sort_type {SORT_TRANSACTION ,SORT_TRACE ,SORT_SYM_SIZE , +SORT_CGROUP_ID ,/* branch stack specific sort keys */ __SORT_BRANCH_STACK,
Signature · 1 line
2.9.3
Arnaldo Carvalho de Melo
maintainerPATCH 14/19 perf sched timehist: Add --next option
In reply to Arnaldo Carvalho de MeloFrom: Brendan Gregg <[email protected]>
The --next option shows the next task for each context switch, providing more context for the sequence of scheduler events.
$ perf sched timehist --next | head
Samples do not have callchains.
time cpu task name waittime schdelay run time
[tid/pid] (msec) (msec) (msec)
---------- --- ---------- --------- ------ -----
374.793792 [0] <idle> 0.000 0.000 0.000 next: rngd[1524]
374.793801 [0] rngd[1524] 0.000 0.000 0.009 next: swapper/0[0]
374.794048 [7] <idle> 0.000 0.000 0.000 next: yes[30884]
374.794066 [7] yes[30884] 0.000 0.000 0.018 next: swapper/7[0]
374.794126 [2] <idle> 0.000 0.000 0.000 next: rngd[1524]
374.794140 [2] rngd[1524] 0.325 0.006 0.013 next: swapper/2[0]
374.794281 [3] <idle> 0.000 0.000 0.000 next: perf[31070]--- tools/perf/Documentation/perf-sched.txt | 4 ++++ tools/perf/builtin-sched.c | 25 ++++++++++++++++++++----- 2 files changed, 24 insertions(+), 5 deletions(-)
tools/perf/Documentation/perf-sched.txt +4 -0
@@ -132,6 +132,10 @@ OPTIONS for 'perf sched timehist' --migrations:: Show migration events. +-n:: +--next:: + Show next task. + -I:: --idle-hist:: Show idle-related events only.
tools/perf/builtin-sched.c +20 -5
@@ -221,6 +221,7 @@ struct perf_sched {unsigned int max_stack;bool show_cpu_visual;bool show_wakeups; +bool show_next;bool show_migrations;bool show_state;u64 skipped_samples;
@@ -1897,14 +1898,18 @@ static char task_state_char(struct thread *thread, int state) }static void timehist_print_sample (struct perf_sched *sched, +struct perf_evsel *evsel,struct perf_sample *sample,struct addr_location *al,struct thread *thread,u64 t,int state) {struct thread_runtime *tr =thread__priv (thread); +const char *next_comm =perf_evsel__strval (evsel, sample,"next_comm" ); +const u32 next_pid =perf_evsel__intval (evsel, sample,"next_pid" );u32 max_cpus = sched->max_cpu +1 ;char tstr[64 ]; +char nstr[30 ];u64 wait_time;timestamp__scnprintf_usec (t, tstr,sizeof (tstr));
@@ -1937,7 +1942,12 @@ static void timehist_print_sample(struct perf_sched *sched,if (sched->show_state)printf (" %5c " ,task_state_char (thread, state)); -if (sched->show_wakeups) +if (sched->show_next) { +snprintf (nstr,sizeof (nstr),"next: %s[%d]" , next_comm, next_pid); +printf (" %-*s" , comm_width, nstr); + } + +if (sched->show_wakeups && !sched->show_next)printf (" %-*s" , comm_width,"" );if (thread->tid ==0 )
@@ -2531,7 +2541,7 @@ static int timehist_sched_change_event(struct perf_tool *tool, }if (!sched->summary_only) -timehist_print_sample (sched, sample, &al, thread, t, state); +timehist_print_sample (sched, evsel, sample, &al, thread, t, state); out:if (sched->hist_time.start ==0 && t >= ptime->start)
@@ -3341,6 +3351,7 @@ int cmd_sched(int argc, const char **argv, const char *prefix __maybe_unused)OPT_BOOLEAN ('S' ,"with-summary" , &sched.summary,"Show all syscalls and summary with statistics" ),OPT_BOOLEAN ('w' ,"wakeups" , &sched.show_wakeups,"Show wakeup events" ), +OPT_BOOLEAN ('n' ,"next" , &sched.show_next,"Show next task" ),OPT_BOOLEAN ('M' ,"migrations" , &sched.show_migrations,"Show migration events" ),OPT_BOOLEAN ('V' ,"cpu-visual" , &sched.show_cpu_visual,"Add CPU visual" ), OPT_BOOLEAN('I', "idle-hist", &sched.idle_hist, "Show idle events only"),
@@ -3438,10 +3449,14 @@ int cmd_sched(int argc, const char **argv, const char *prefix __maybe_unused)if (argc)usage_with_options (timehist_usage, timehist_options); } -if (sched.show_wakeups && sched.summary_only) { -pr_err (" Error: -s and -w are mutually exclusive.\n" ); +if ((sched.show_wakeups || sched.show_next) && + sched.summary_only) { +pr_err (" Error: -s and -[n|w] are mutually exclusive.\n" );parse_options_usage (timehist_usage, timehist_options,"s" , true); -parse_options_usage (NULL , timehist_options,"w" , true); +if (sched.show_wakeups) +parse_options_usage (NULL , timehist_options,"w" , true); +if (sched.show_next) +parse_options_usage (NULL , timehist_options,"n" , true);return -EINVAL ; }
Signature · 1 line
2.9.3
Arnaldo Carvalho de Melo
maintainerPATCH 15/19 perf probe: Factor out the ftrace README scanning
In reply to Arnaldo Carvalho de MeloFrom: "Naveen N. Rao" <[email protected]>
Simplify and separate out the ftrace README scanning logic into a separate helper. This is used subsequently to scan for all patterns of interest and to cache the result.
Since we are only interested in availability of probe argument type x, we will only scan for that.
--- tools/perf/util/probe-file.c | 70 +++++++++++++++++++++++--------------------- 1 file changed, 37 insertions(+), 33 deletions(-)
tools/perf/util/probe-file.c +37 -33
@@ -877,35 +877,31 @@ int probe_cache__show_all_caches(struct strfilter *filter)return 0 ; } +enum ftrace_readme { +FTRACE_README_PROBE_TYPE_X =0 , +FTRACE_README_END , +}; +static struct {const char *pattern; -bool avail; -bool checked; -} probe_type_table[] = { -#define DEFINE_TYPE(idx, pat, def_avail) \ - [idx] = {.pattern = pat, .avail = (def_avail)} -DEFINE_TYPE (PROBE_TYPE_U ,"* u8/16/32/64,*" , true), -DEFINE_TYPE (PROBE_TYPE_S ,"* s8/16/32/64,*" , true), -DEFINE_TYPE (PROBE_TYPE_X ,"* x8/16/32/64,*" , false), -DEFINE_TYPE (PROBE_TYPE_STRING ,"* string,*" , true), -DEFINE_TYPE (PROBE_TYPE_BITFIELD , -"* b<bit-width>@<bit-offset>/<container-size>" , true), +bool avail; +} ftrace_readme_table[] = { +#define DEFINE_TYPE(idx, pat) \ + [idx] = {.pattern = pat, .avail = false} +DEFINE_TYPE (FTRACE_README_PROBE_TYPE_X ,"*type: * x8/16/32/64,*" ), }; -bool probe_type_is_available (enum probe_type type) +static bool scan_ftrace_readme (enum ftrace_readme type) { +int fd;FILE *fp;char *buf =NULL ;size_t len =0 ; -bool target_line = false; -bool ret = probe_type_table[type].avail; -int fd; +bool ret = false; +static bool scanned = false; -if (type >=PROBE_TYPE_END ) -return false; -/* We don't have to check the type which supported by default */ -if (ret || probe_type_table[type].checked) -return ret; +if (scanned) + goto result; fd =open_trace_file ("README" , false);if (fd <0 )
@@ -917,21 +913,29 @@ bool probe_type_is_available(enum probe_type type)return ret; } -while (getline (&buf, &len, fp) >0 && !ret) { -if (!target_line) { - target_line = !!strstr (buf," type: " ); -if (!target_line) -continue ; - }else if (strstr (buf,"\t " ) != buf) -break ; - ret =strglobmatch (buf, probe_type_table[type].pattern); - } -/* Cache the result */ - probe_type_table[type].checked = true; - probe_type_table[type].avail = ret; +while (getline (&buf, &len, fp) >0 ) +for (enum ftrace_readme i =0 ; i <FTRACE_README_END ; i++) +if (!ftrace_readme_table[i].avail) + ftrace_readme_table[i].avail = +strglobmatch (buf, ftrace_readme_table[i].pattern); + scanned = true;fclose (fp);free (buf); -return ret; +result: +if (type >=FTRACE_README_END ) +return false; + +return ftrace_readme_table[type].avail; +} + +bool probe_type_is_available (enum probe_type type) +{ +if (type >=PROBE_TYPE_END ) +return false; +else if (type ==PROBE_TYPE_X ) +return scan_ftrace_readme (FTRACE_README_PROBE_TYPE_X ); + +return true; }
Signature · 1 line
2.9.3
Arnaldo Carvalho de Melo
maintainerPATCH 16/19 perf kretprobes: Offset from reloc_sym if kernel supports it
In reply to Arnaldo Carvalho de MeloFrom: "Naveen N. Rao" <[email protected]>
We indicate support for accepting sym+offset with kretprobes through a line in ftrace README. Parse the same to identify support and choose the appropriate format for kprobe_events.
As an example, without this perf patch, but with the ftrace changes:
naveen@ubuntu:~/linux/tools/perf$ sudo cat /sys/kernel/debug/tracing/README | grep kretprobe
place (kretprobe): [<module>:]<symbol>[+<offset>]|<memaddr>
naveen@ubuntu:~/linux/tools/perf$
naveen@ubuntu:~/linux/tools/perf$ sudo ./perf probe -v do_open%return
probe-definition(0): do_open%return
symbol:do_open file:(null) line:0 offset:0 return:1 lazy:(null)
0 arguments
Looking at the vmlinux_path (8 entries long)
Using /boot/vmlinux for symbols
Open Debuginfo file: /boot/vmlinux
Try to find probe point from debuginfo.
Matched function: do_open [2d0c7d8]
Probe point found: do_open+0
Matched function: do_open [35d76b5]
found inline addr: 0xc0000000004ba984
Failed to find "do_open%return",
because do_open is an inlined function and has no return point.
An error occurred in debuginfo analysis (-22).
Trying to use symbols.
Opening /sys/kernel/debug/tracing//kprobe_events write=1
Writing event: r:probe/do_open do_open+0
Writing event: r:probe/do_open_1 do_open+0
Added new events:
probe:do_open (on do_open%return)
probe:do_open_1 (on do_open%return)You can now use it in all perf tools, such as:
perf record -e probe:do_open_1 -aR sleep 1
naveen@ubuntu:~/linux/tools/perf$ sudo cat /sys/kernel/debug/kprobes/list c000000000041370 k kretprobe_trampoline+0x0 [OPTIMIZED] c0000000004433d0 r do_open+0x0 [DISABLED] c0000000004433d0 r do_open+0x0 [DISABLED]
And after this patch (and the subsequent powerpc patch):
naveen@ubuntu:~/linux/tools/perf$ sudo ./perf probe -v do_open%return
probe-definition(0): do_open%return
symbol:do_open file:(null) line:0 offset:0 return:1 lazy:(null)
0 arguments
Looking at the vmlinux_path (8 entries long)
Using /boot/vmlinux for symbols
Open Debuginfo file: /boot/vmlinux
Try to find probe point from debuginfo.
Matched function: do_open [2d0c7d8]
Probe point found: do_open+0
Matched function: do_open [35d76b5]
found inline addr: 0xc0000000004ba984
Failed to find "do_open%return",
because do_open is an inlined function and has no return point.
An error occurred in debuginfo analysis (-22).
Trying to use symbols.
Opening /sys/kernel/debug/tracing//README write=0
Opening /sys/kernel/debug/tracing//kprobe_events write=1
Writing event: r:probe/do_open _text+4469712
Writing event: r:probe/do_open_1 _text+4956248
Added new events:
probe:do_open (on do_open%return)
probe:do_open_1 (on do_open%return)You can now use it in all perf tools, such as:
perf record -e probe:do_open_1 -aR sleep 1
naveen@ubuntu:~/linux/tools/perf$ sudo cat /sys/kernel/debug/kprobes/list c000000000041370 k kretprobe_trampoline+0x0 [OPTIMIZED] c0000000004433d0 r do_open+0x0 [DISABLED] c0000000004ba058 r do_open+0x8 [DISABLED]
--- tools/perf/util/probe-event.c | 12 +++++------- tools/perf/util/probe-file.c | 7 +++++++ tools/perf/util/probe-file.h | 1 + 3 files changed, 13 insertions(+), 7 deletions(-)
tools/perf/util/probe-event.c +5 -7
@@ -757,7 +757,9 @@ post_process_kernel_probe_trace_events(struct probe_trace_event *tevs, }for (i =0 ; i < ntevs; i++) { -if (!tevs[i].point.address || tevs[i].point.retprobe) +if (!tevs[i].point.address) +continue ; +if (tevs[i].point.retprobe && !kretprobe_offset_is_supported ())continue ;/* If we found a wrong one, mark it by NULL symbol */ if (kprobe_warn_out_range(tevs[i].point.symbol,
@@ -1528,11 +1530,6 @@ static int parse_perf_probe_point(char *arg, struct perf_probe_event *pev)return -EINVAL ; } -if (pp->retprobe && !pp->function) { -semantic_error ("Return probe requires an entry function.\n" ); -return -EINVAL ; - } -if ((pp->offset || pp->line || pp->lazy_line) && pp->retprobe) {semantic_error ("Offset/Line/Lazy pattern can't be used with " "return probe.\n" );
@@ -2841,7 +2838,8 @@ static int find_probe_trace_events_from_map(struct perf_probe_event *pev, }/* Note that the symbols in the kmodule are not relocated */ -if (!pev->uprobes && !pp->retprobe && !pev->target) { +if (!pev->uprobes && !pev->target && + (!pp->retprobe ||kretprobe_offset_is_supported ())) { reloc_sym =kernel_get_ref_reloc_sym ();if (!reloc_sym) {pr_warning ("Relocated base symbol is not found!\n" );
tools/perf/util/probe-file.c +7 -0
@@ -879,6 +879,7 @@ int probe_cache__show_all_caches(struct strfilter *filter)enum ftrace_readme {FTRACE_README_PROBE_TYPE_X =0 , +FTRACE_README_KRETPROBE_OFFSET ,FTRACE_README_END , };
@@ -889,6 +890,7 @@ static struct {#define DEFINE_TYPE (idx, pat) \ [idx] = {.pattern = pat, .avail = false}DEFINE_TYPE (FTRACE_README_PROBE_TYPE_X ,"*type: * x8/16/32/64,*" ), + DEFINE_TYPE(FTRACE_README_KRETPROBE_OFFSET, "*place (kretprobe): *"), };static bool scan_ftrace_readme (enum ftrace_readme type)
@@ -939,3 +941,8 @@ bool probe_type_is_available(enum probe_type type)return true; } + +bool kretprobe_offset_is_supported (void ) +{ +return scan_ftrace_readme (FTRACE_README_KRETPROBE_OFFSET ); +}
tools/perf/util/probe-file.h +1 -0
@@ -65,6 +65,7 @@ struct probe_cache_entry *probe_cache__find_by_name(struct probe_cache *pcache, const char *group, const char *event);int probe_cache__show_all_caches (struct strfilter *filter);bool probe_type_is_available (enum probe_type type); +bool kretprobe_offset_is_supported (void );#else /* ! HAVE_LIBELF_SUPPORT */ static inline struct probe_cache *probe_cache__new (const char *tgt__maybe_unused ) {
Signature · 1 line
2.9.3
Arnaldo Carvalho de Melo
maintainerPATCH 17/19 perf powerpc: Choose local entry point with kretprobes
In reply to Arnaldo Carvalho de MeloFrom: "Naveen N. Rao" <[email protected]>
perf now uses an offset from _text/_stext for kretprobes if the kernel supports it, rather than the actual function name. As such, let's choose the LEP for powerpc ABIv2 so as to ensure the probe gets hit. Do it only if the kernel supports specifying offsets with kretprobes.
--- tools/perf/arch/powerpc/util/sym-handling.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-)
tools/perf/arch/powerpc/util/sym-handling.c +10 -4
@@ -10,6 +10,7 @@#include "symbol.h" #include "map.h" #include "probe-event.h" +#include "probe-file.h" #ifdef HAVE_LIBELF_SUPPORT bool elf__needs_adjust_symbols (GElf_Ehdr ehdr)
@@ -79,13 +80,18 @@ void arch__fix_tev_from_maps(struct perf_probe_event *pev,* However, if the user specifies an offset, we fall back to using the * GEP since all userspace applications (objdump/readelf) show function * disassembly with offsets from the GEP. -* -* In addition, we shouldn't specify an offset for kretprobes. */ -if (pev->point.offset || (!pev->uprobes && pev->point.retprobe) || - !map || !sym) +if (pev->point.offset || !map || !sym)return ; +/* For kretprobes, add an offset only if the kernel supports it */ +if (!pev->uprobes && pev->point.retprobe) { +#ifdef HAVE_LIBELF_SUPPORT + if (!kretprobe_offset_is_supported()) +#endif +return ; + } + lep_offset =PPC64_LOCAL_ENTRY_OFFSET (sym->arch_sym);if (map->dso->symtab_type ==DSO_BINARY_TYPE__KALLSYMS )
Signature · 1 line
2.9.3
Arnaldo Carvalho de Melo
maintainerPATCH 18/19 doc: trace/kprobes: add information about NOKPROBE_SYMBOL
In reply to Arnaldo Carvalho de MeloFrom: "Naveen N. Rao" <[email protected]>
Update kprobe tracer documentation to also mention that NOKPROBE_SYMBOL() and nokprobe_inline add symbols to the kprobes blacklist.
--- Documentation/trace/kprobetrace.txt | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
Documentation/trace/kprobetrace.txt +3 -2
@@ -8,8 +8,9 @@ Overview -------- These events are similar to tracepoint based events. Instead of Tracepoint, this is based on kprobes (kprobe and kretprobe). So it can probe wherever -kprobes can probe (this means, all functions body except for __kprobes -functions). Unlike the Tracepoint based event, this can be added and removed +kprobes can probe (this means, all functions except those with +__kprobes/nokprobe_inline annotation and those marked NOKPROBE_SYMBOL). +Unlike the Tracepoint based event, this can be added and removed dynamically, on the fly. To enable this feature, build your kernel with CONFIG_KPROBE_EVENTS=y.
Signature · 1 line
2.9.3
Arnaldo Carvalho de Melo
maintainerPATCH 19/19 kprobes: Convert kprobe_exceptions_notify to use NOKPROBE_SYMBOL
In reply to Arnaldo Carvalho de MeloFrom: "Naveen N. Rao" <[email protected]>
commit fc62d0207ae0 ("kprobes: Introduce weak variant of kprobe_exceptions_notify()") used the __kprobes annotation to exclude kprobe_exceptions_notify from being probed. Since NOKPROBE_SYMBOL() is a better way to do this enabling the symbol to be discovered as being blacklisted, change over to using NOKPROBE_SYMBOL().
--- kernel/kprobes.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
kernel/kprobes.c +3 -2
@@ -1740,11 +1740,12 @@ void unregister_kprobes(struct kprobe **kps, int num) }EXPORT_SYMBOL_GPL (unregister_kprobes); -int __weak __kprobes kprobe_exceptions_notify (struct notifier_block *self, -unsigned long val,void *data) +int __weak kprobe_exceptions_notify (struct notifier_block *self, +unsigned long val,void *data) {return NOTIFY_DONE ; } +NOKPROBE_SYMBOL (kprobe_exceptions_notify);static struct notifier_block kprobe_exceptions_nb = { .notifier_call = kprobe_exceptions_notify,
Signature · 1 line
2.9.3
Quoted 138 lines · Arnaldo Carvalho de Melo
Hi Ingo,
Please consider pulling,
- Arnaldo
Test results at the end of this message, as usual.
The following changes since commit
84e5b549214f2160c12318aac549de85f600c79a:Merge tag 'perf-core-for-mingo-4.11-20170306' of
git://git.kernel.org/pub/scm/linux/kernel/git/acme/linuxinto perf/core (2017-03-07 08:14:14 +0100)are available in the git repository at:
git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux.gittags/perf-core-for-mingo-4.12-20170314for you to fetch changes up to
5f6bee34707973ea7879a7857fd63ddccc92fff3:kprobes: Convert
kprobe_exceptions_notifyto useNOKPROBE_SYMBOL(2017-03-14 15:17:40 -0300)----------------------------------------------------------------
perf/core improvements and fixes:New features:
- Add
PERF_RECORD_NAMESPACESso that the kernel can record information required to associate samples to namespaces, helping in container problem characterization.Now the 'perf record has a --namespace' option to ask for such info, and when present, it can be used, initially, via a new sort order, '
cgroup_id', allowing histogram entry bucketization by a (device, inode) based cgroup identifier (Hari Bathini)- Add --next option to 'perf sched timehist', showing what is the next thread to run (Brendan Gregg)
Fixes:
- Fix segfault with basic block 'cycles' sort dimension (Changbin Du)
- Add c2c to command-list.txt, making it appear in the 'perf help' output (Changbin Du)
- Fix zeroing of '
abs_path' variable in the perf hists browser switch file code (Changbin Du)- Hide tips messages when -q/--quiet is given to 'perf report' (Namhyung Kim)
Infrastructure:
- Use
ref_reloc_sym+ offset to setup kretprobes (Naveen Rao)- Ignore generated files pmu-events/{jevents,pmu-events.c} for git (Changbin Du)
Documentation:
- Document +field style argument support for --field option (Changbin Du)
- Clarify 'perf c2c --stats' help message (Namhyung Kim)
Signed-off-by Arnaldo Carvalho de Melo <[email protected]>----------------------------------------------------------------
Brendan Gregg (1):
perf sched timehist: Add --next optionChangbin Du (5):
perf tools: Missing c2c command in command-list
perf tools: Ignore generated files pmu-events/{jevents,pmu-events.c} for git perf sort: Fix segfault with basic block 'cycles' sort dimension perf report: Document +field style argument support for --field option perf hists browser: Fix typo in functionswitch_data_fileHari Bathini (5):
perf: AddPERF_RECORD_NAMESPACESto include namespaces related info perf tools: AddPERF_RECORD_NAMESPACESto include namespaces related info perf record: Synthesize namespace events for current processes perf script: Add script print support for namespace events perf tools: Add 'cgroup_id' sort order keywordNamhyung Kim (3):
perf report: Hide tip message when -q option is given perf c2c: Clarify help message of --stats option perf c2c: Fix display bug when using pipeNaveen N. Rao (5):
perf probe: Factor out the ftrace README scanning perf kretprobes: Offset fromreloc_symif kernel supports it perf powerpc: Choose local entry point with kretprobes
doc: trace/kprobes: add information aboutNOKPROBE_SYMBOL
kprobes: Convertkprobe_exceptions_notifyto useNOKPROBE_SYMBOLDocumentation/trace/kprobetrace.txt | 5 +- include/linux/perf_event.h | 2 + include/uapi/linux/perf_event.h | 32 +++++- kernel/events/core.c | 139 ++++++++++++++++++++++++++ kernel/fork.c | 2 + kernel/kprobes.c | 5 +- kernel/nsproxy.c | 3 + tools/include/uapi/linux/perf_event.h | 32 +++++- tools/perf/.gitignore | 2 + tools/perf/Documentation/perf-record.txt | 3 + tools/perf/Documentation/perf-report.txt | 7 +- tools/perf/Documentation/perf-sched.txt | 4 + tools/perf/Documentation/perf-script.txt | 3 + tools/perf/arch/powerpc/util/sym-handling.c | 14 ++- tools/perf/builtin-annotate.c | 1 + tools/perf/builtin-c2c.c | 4 +- tools/perf/builtin-diff.c | 1 + tools/perf/builtin-inject.c | 13 +++ tools/perf/builtin-kmem.c | 1 + tools/perf/builtin-kvm.c | 2 + tools/perf/builtin-lock.c | 1 + tools/perf/builtin-mem.c | 1 + tools/perf/builtin-record.c | 35 ++++++- tools/perf/builtin-report.c | 4 +- tools/perf/builtin-sched.c | 26 ++++- tools/perf/builtin-script.c | 41 ++++++++ tools/perf/builtin-trace.c | 3 +- tools/perf/command-list.txt | 1 + tools/perf/perf.h | 1 + tools/perf/ui/browsers/hists.c | 2 +- tools/perf/util/Build | 1 + tools/perf/util/data-convert-bt.c | 1 + tools/perf/util/event.c | 150 ++++++++++++++++++++++++++-- tools/perf/util/event.h | 19 ++++ tools/perf/util/evsel.c | 3 + tools/perf/util/hist.c | 7 ++ tools/perf/util/hist.h | 1 + tools/perf/util/machine.c | 34 +++++++ tools/perf/util/machine.h | 3 + tools/perf/util/namespaces.c | 36 +++++++ tools/perf/util/namespaces.h | 26 +++++ tools/perf/util/probe-event.c | 12 +-- tools/perf/util/probe-file.c | 77 ++++++++------ tools/perf/util/probe-file.h | 1 + tools/perf/util/session.c | 7 ++
Quoted 8 lines
tools/perf/util/sort.c | 46 +++++++++ tools/perf/util/sort.h | 7 ++ tools/perf/util/thread.c | 44 +++++++- tools/perf/util/thread.h | 6 ++ tools/perf/util/tool.h | 2 + 50 files changed, 799 insertions(+), 74 deletions(-) create mode 100644 tools/perf/util/namespaces.c create mode 100644 tools/perf/util/namespaces.h
Pulled, thanks a lot Arnaldo!
Ingo