License cleanup: add SPDX GPL-2.0 license identifier to files with no license
Many source files in the tree are missing licensing information, which
makes it harder for compliance tools to determine the correct license.
By default all files without license information are under the default
license of the kernel, which is GPL version 2.
Update the files which contain no license information with the 'GPL-2.0'
SPDX license identifier. The SPDX identifier is a legally binding
shorthand, which can be used instead of the full boiler plate text.
This patch is based on work done by Thomas Gleixner and Kate Stewart and
Philippe Ombredanne.
How this work was done:
Patches were generated and checked against linux-4.14-rc6 for a subset of
the use cases:
- file had no licensing information it it.
- file was a */uapi/* one with no licensing information in it,
- file was a */uapi/* one with existing licensing information,
Further patches will be generated in subsequent months to fix up cases
where non-standard license headers were used, and references to license
had to be inferred by heuristics based on keywords.
The analysis to determine which SPDX License Identifier to be applied to
a file was done in a spreadsheet of side by side results from of the
output of two independent scanners (ScanCode & Windriver) producing SPDX
tag:value files created by Philippe Ombredanne. Philippe prepared the
base worksheet, and did an initial spot review of a few 1000 files.
The 4.13 kernel was the starting point of the analysis with 60,537 files
assessed. Kate Stewart did a file by file comparison of the scanner
results in the spreadsheet to determine which SPDX license identifier(s)
to be applied to the file. She confirmed any determination that was not
immediately clear with lawyers working with the Linux Foundation.
Criteria used to select files for SPDX license identifier tagging was:
- Files considered eligible had to be source code files.
- Make and config files were included as candidates if they contained >5
lines of source
- File already had some variant of a license header in it (even if <5
lines).
All documentation files were explicitly excluded.
The following heuristics were used to determine which SPDX license
identifiers to apply.
- when both scanners couldn't find any license traces, file was
considered to have no license information in it, and the top level
COPYING file license applied.
For non */uapi/* files that summary was:
SPDX license identifier # files
---------------------------------------------------|-------
GPL-2.0 11139
and resulted in the first patch in this series.
If that file was a */uapi/* path one, it was "GPL-2.0 WITH
Linux-syscall-note" otherwise it was "GPL-2.0". Results of that was:
SPDX license identifier # files
---------------------------------------------------|-------
GPL-2.0 WITH Linux-syscall-note 930
and resulted in the second patch in this series.
- if a file had some form of licensing information in it, and was one
of the */uapi/* ones, it was denoted with the Linux-syscall-note if
any GPL family license was found in the file or had no licensing in
it (per prior point). Results summary:
SPDX license identifier # files
---------------------------------------------------|------
GPL-2.0 WITH Linux-syscall-note 270
GPL-2.0+ WITH Linux-syscall-note 169
((GPL-2.0 WITH Linux-syscall-note) OR BSD-2-Clause) 21
((GPL-2.0 WITH Linux-syscall-note) OR BSD-3-Clause) 17
LGPL-2.1+ WITH Linux-syscall-note 15
GPL-1.0+ WITH Linux-syscall-note 14
((GPL-2.0+ WITH Linux-syscall-note) OR BSD-3-Clause) 5
LGPL-2.0+ WITH Linux-syscall-note 4
LGPL-2.1 WITH Linux-syscall-note 3
((GPL-2.0 WITH Linux-syscall-note) OR MIT) 3
((GPL-2.0 WITH Linux-syscall-note) AND MIT) 1
and that resulted in the third patch in this series.
- when the two scanners agreed on the detected license(s), that became
the concluded license(s).
- when there was disagreement between the two scanners (one detected a
license but the other didn't, or they both detected different
licenses) a manual inspection of the file occurred.
- In most cases a manual inspection of the information in the file
resulted in a clear resolution of the license that should apply (and
which scanner probably needed to revisit its heuristics).
- When it was not immediately clear, the license identifier was
confirmed with lawyers working with the Linux Foundation.
- If there was any question as to the appropriate license identifier,
the file was flagged for further research and to be revisited later
in time.
In total, over 70 hours of logged manual review was done on the
spreadsheet to determine the SPDX license identifiers to apply to the
source files by Kate, Philippe, Thomas and, in some cases, confirmation
by lawyers working with the Linux Foundation.
Kate also obtained a third independent scan of the 4.13 code base from
FOSSology, and compared selected files where the other two scanners
disagreed against that SPDX file, to see if there was new insights. The
Windriver scanner is based on an older version of FOSSology in part, so
they are related.
Thomas did random spot checks in about 500 files from the spreadsheets
for the uapi headers and agreed with SPDX license identifier in the
files he inspected. For the non-uapi files Thomas did random spot checks
in about 15000 files.
In initial set of patches against 4.14-rc6, 3 files were found to have
copy/paste license identifier errors, and have been fixed to reflect the
correct identifier.
Additionally Philippe spent 10 hours this week doing a detailed manual
inspection and review of the 12,461 patched files from the initial patch
version early this week with:
- a full scancode scan run, collecting the matched texts, detected
license ids and scores
- reviewing anything where there was a license detected (about 500+
files) to ensure that the applied SPDX license was correct
- reviewing anything where there was no detection but the patch license
was not GPL-2.0 WITH Linux-syscall-note to ensure that the applied
SPDX license was correct
This produced a worksheet with 20 files needing minor correction. This
worksheet was then exported into 3 different .csv files for the
different types of files to be modified.
These .csv files were then reviewed by Greg. Thomas wrote a script to
parse the csv files and add the proper SPDX tag to the file, in the
format that the file expected. This script was further refined by Greg
based on the output to detect more types of files automatically and to
distinguish between header and source .c files (which need different
comment types.) Finally Greg ran the script using the .csv files to
generate the patches.
Reviewed-by: Kate Stewart <kstewart@linuxfoundation.org>
Reviewed-by: Philippe Ombredanne <pombredanne@nexb.com>
Reviewed-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2017-11-01 22:07:57 +08:00
|
|
|
// SPDX-License-Identifier: GPL-2.0
|
2009-06-03 04:59:57 +08:00
|
|
|
/*
|
2009-06-03 05:37:05 +08:00
|
|
|
* builtin-record.c
|
|
|
|
*
|
|
|
|
* Builtin record command: Record the profile of a workload
|
|
|
|
* (or a CPU, or a PID) into the perf.data output file - for
|
|
|
|
* later analysis via perf report.
|
2009-06-03 04:59:57 +08:00
|
|
|
*/
|
2009-05-27 15:10:38 +08:00
|
|
|
#include "builtin.h"
|
2009-06-03 05:37:05 +08:00
|
|
|
|
|
|
|
#include "perf.h"
|
|
|
|
|
2010-02-04 02:52:05 +08:00
|
|
|
#include "util/build-id.h"
|
2009-05-02 00:29:57 +08:00
|
|
|
#include "util/util.h"
|
2015-12-15 23:39:39 +08:00
|
|
|
#include <subcmd/parse-options.h>
|
2009-05-26 17:10:09 +08:00
|
|
|
#include "util/parse-events.h"
|
2016-06-23 16:55:17 +08:00
|
|
|
#include "util/config.h"
|
2009-05-02 00:29:57 +08:00
|
|
|
|
2014-10-10 03:12:24 +08:00
|
|
|
#include "util/callchain.h"
|
2014-10-17 23:17:40 +08:00
|
|
|
#include "util/cgroup.h"
|
2009-06-25 23:05:54 +08:00
|
|
|
#include "util/header.h"
|
2009-08-12 17:07:25 +08:00
|
|
|
#include "util/event.h"
|
2011-01-12 06:56:53 +08:00
|
|
|
#include "util/evlist.h"
|
2011-01-04 02:39:04 +08:00
|
|
|
#include "util/evsel.h"
|
2009-08-17 04:05:48 +08:00
|
|
|
#include "util/debug.h"
|
2009-12-12 07:24:02 +08:00
|
|
|
#include "util/session.h"
|
2011-11-28 18:30:20 +08:00
|
|
|
#include "util/tool.h"
|
perf symbols: Use the buildids if present
With this change 'perf record' will intercept PERF_RECORD_MMAP
calls, creating a linked list of DSOs, then when the session
finishes, it will traverse this list and read the buildids,
stashing them at the end of the file and will set up a new
feature bit in the header bitmask.
'perf report' will then notice this feature and populate the
'dsos' list and set the build ids.
When reading the symtabs it will refuse to load from a file that
doesn't have the same build id. This improves the
reliability of the profiler output, as symbols and profiling
data is more guaranteed to match.
Example:
[root@doppio ~]# perf report | head
/home/acme/bin/perf with build id b1ea544ac3746e7538972548a09aadecc5753868 not found, continuing without symbols
# Samples: 2621434559
#
# Overhead Command Shared Object Symbol
# ........ ............... ............................. ......
#
7.91% init [kernel] [k] read_hpet
7.64% init [kernel] [k] mwait_idle_with_hints
7.60% swapper [kernel] [k] read_hpet
7.60% swapper [kernel] [k] mwait_idle_with_hints
3.65% init [kernel] [k] 0xffffffffa02339d9
[root@doppio ~]#
In this case the 'perf' binary was an older one, vanished,
so its symbols probably wouldn't match or would cause subtly
different (and misleading) output.
Next patches will support the kernel as well, reading the build
id notes for it and the modules from /sys.
Another patch should also introduce a new plumbing command:
'perf list-buildids'
that will then be used in porcelain that is distro specific to
fetch -debuginfo packages where such buildids are present. This
will in turn allow for one to run 'perf record' in one machine
and 'perf report' in another.
Future work on having the buildid sent directly from the kernel
in the PERF_RECORD_MMAP event is needed to close races, as the
DSO can be changed during a 'perf record' session, but this
patch at least helps with non-corner cases and current/older
kernels.
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Ananth N Mavinakayanahalli <ananth@in.ibm.com>
Cc: Christoph Hellwig <hch@infradead.org>
Cc: Frank Ch. Eigler <fche@redhat.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Jason Baron <jbaron@redhat.com>
Cc: Jim Keniston <jkenisto@us.ibm.com>
Cc: K. Prasad <prasad@linux.vnet.ibm.com>
Cc: Masami Hiramatsu <mhiramat@redhat.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Roland McGrath <roland@redhat.com>
Cc: Srikar Dronamraju <srikar@linux.vnet.ibm.com>
Cc: Steven Rostedt <rostedt@goodmis.org>
LKML-Reference: <1257367843-26224-1-git-send-email-acme@infradead.org>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
2009-11-05 04:50:43 +08:00
|
|
|
#include "util/symbol.h"
|
perf tools: Fix sparse CPU numbering related bugs
At present, the perf subcommands that do system-wide monitoring
(perf stat, perf record and perf top) don't work properly unless
the online cpus are numbered 0, 1, ..., N-1. These tools ask
for the number of online cpus with sysconf(_SC_NPROCESSORS_ONLN)
and then try to create events for cpus 0, 1, ..., N-1.
This creates problems for systems where the online cpus are
numbered sparsely. For example, a POWER6 system in
single-threaded mode (i.e. only running 1 hardware thread per
core) will have only even-numbered cpus online.
This fixes the problem by reading the /sys/devices/system/cpu/online
file to find out which cpus are online. The code that does that is in
tools/perf/util/cpumap.[ch], and consists of a read_cpu_map()
function that sets up a cpumap[] array and returns the number of
online cpus. If /sys/devices/system/cpu/online can't be read or
can't be parsed successfully, it falls back to using sysconf to
ask how many cpus are online and sets up an identity map in cpumap[].
The perf record, perf stat and perf top code then calls
read_cpu_map() in the system-wide monitoring case (instead of
sysconf) and uses cpumap[] to get the cpu numbers to pass to
perf_event_open.
Signed-off-by: Paul Mackerras <paulus@samba.org>
Cc: Anton Blanchard <anton@samba.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Arnaldo Carvalho de Melo <acme@infradead.org>
LKML-Reference: <20100310093609.GA3959@brick.ozlabs.ibm.com>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
2010-03-10 17:36:09 +08:00
|
|
|
#include "util/cpumap.h"
|
2011-01-19 01:15:24 +08:00
|
|
|
#include "util/thread_map.h"
|
2013-10-15 22:27:32 +08:00
|
|
|
#include "util/data.h"
|
perf record: Add ability to name registers to record
This patch modifies the -I/--int-regs option to enablepassing the name
of the registers to sample on interrupt. Registers can be specified by
their symbolic names. For instance on x86, --intr-regs=ax,si.
The motivation is to reduce the size of the perf.data file and the
overhead of sampling by only collecting the registers useful to a
specific analysis. For instance, for value profiling, sampling only the
registers used to passed arguements to functions.
With no parameter, the --intr-regs still records all possible registers
based on the architecture.
To name registers, it is necessary to use the long form of the option,
i.e., --intr-regs:
$ perf record --intr-regs=si,di,r8,r9 .....
To record any possible registers:
$ perf record -I .....
$ perf report --intr-regs ...
To display the register, one can use perf report -D
To list the available registers:
$ perf record --intr-regs=\?
available registers: AX BX CX DX SI DI BP SP IP FLAGS CS SS R8 R9 R10 R11 R12 R13 R14 R15
Signed-off-by: Stephane Eranian <eranian@google.com>
Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Andi Kleen <ak@linux.intel.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Kan Liang <kan.liang@intel.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Link: http://lkml.kernel.org/r/1441039273-16260-4-git-send-email-eranian@google.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2015-09-01 00:41:12 +08:00
|
|
|
#include "util/perf_regs.h"
|
2015-04-09 23:53:45 +08:00
|
|
|
#include "util/auxtrace.h"
|
2016-03-08 16:38:44 +08:00
|
|
|
#include "util/tsc.h"
|
2015-05-28 01:51:51 +08:00
|
|
|
#include "util/parse-branch-options.h"
|
perf record: Add ability to name registers to record
This patch modifies the -I/--int-regs option to enablepassing the name
of the registers to sample on interrupt. Registers can be specified by
their symbolic names. For instance on x86, --intr-regs=ax,si.
The motivation is to reduce the size of the perf.data file and the
overhead of sampling by only collecting the registers useful to a
specific analysis. For instance, for value profiling, sampling only the
registers used to passed arguements to functions.
With no parameter, the --intr-regs still records all possible registers
based on the architecture.
To name registers, it is necessary to use the long form of the option,
i.e., --intr-regs:
$ perf record --intr-regs=si,di,r8,r9 .....
To record any possible registers:
$ perf record -I .....
$ perf report --intr-regs ...
To display the register, one can use perf report -D
To list the available registers:
$ perf record --intr-regs=\?
available registers: AX BX CX DX SI DI BP SP IP FLAGS CS SS R8 R9 R10 R11 R12 R13 R14 R15
Signed-off-by: Stephane Eranian <eranian@google.com>
Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Andi Kleen <ak@linux.intel.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Kan Liang <kan.liang@intel.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Link: http://lkml.kernel.org/r/1441039273-16260-4-git-send-email-eranian@google.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2015-09-01 00:41:12 +08:00
|
|
|
#include "util/parse-regs-options.h"
|
2015-10-14 20:41:19 +08:00
|
|
|
#include "util/llvm-utils.h"
|
perf record: Apply config to BPF objects before recording
bpf__apply_obj_config() is introduced as the core API to apply object
config options to all BPF objects. This patch also does the real work
for setting values for BPF_MAP_TYPE_PERF_ARRAY maps by inserting value
stored in map's private field into the BPF map.
This patch is required because we are not always able to set all BPF
config during parsing. Further patch will set events created by perf to
BPF_MAP_TYPE_PERF_EVENT_ARRAY maps, which is not exist until
perf_evsel__open().
bpf_map_foreach_key() is introduced to iterate over each key needs to be
configured. This function would be extended to support more map types
and different key settings.
In perf record, before start recording, call bpf__apply_config() to turn
on all BPF config options.
Test result:
# cat ./test_bpf_map_1.c
/************************ BEGIN **************************/
#include <uapi/linux/bpf.h>
#define SEC(NAME) __attribute__((section(NAME), used))
struct bpf_map_def {
unsigned int type;
unsigned int key_size;
unsigned int value_size;
unsigned int max_entries;
};
static void *(*map_lookup_elem)(struct bpf_map_def *, void *) =
(void *)BPF_FUNC_map_lookup_elem;
static int (*trace_printk)(const char *fmt, int fmt_size, ...) =
(void *)BPF_FUNC_trace_printk;
struct bpf_map_def SEC("maps") channel = {
.type = BPF_MAP_TYPE_ARRAY,
.key_size = sizeof(int),
.value_size = sizeof(int),
.max_entries = 1,
};
SEC("func=sys_nanosleep")
int func(void *ctx)
{
int key = 0;
char fmt[] = "%d\n";
int *pval = map_lookup_elem(&channel, &key);
if (!pval)
return 0;
trace_printk(fmt, sizeof(fmt), *pval);
return 0;
}
char _license[] SEC("license") = "GPL";
int _version SEC("version") = LINUX_VERSION_CODE;
/************************* END ***************************/
# echo "" > /sys/kernel/debug/tracing/trace
# ./perf record -e './test_bpf_map_1.c/map:channel.value=11/' usleep 10
[ perf record: Woken up 1 times to write data ]
[ perf record: Captured and wrote 0.012 MB perf.data ]
# cat /sys/kernel/debug/tracing/trace
# tracer: nop
#
# entries-in-buffer/entries-written: 1/1 #P:8
[SNIP]
# TASK-PID CPU# |||| TIMESTAMP FUNCTION
# | | | |||| | |
usleep-18593 [007] d... 2394714.395539: : 11
# ./perf record -e './test_bpf_map_1.c/map:channel.value=101/' usleep 10
[ perf record: Woken up 1 times to write data ]
[ perf record: Captured and wrote 0.012 MB perf.data ]
# cat /sys/kernel/debug/tracing/trace
# tracer: nop
#
# entries-in-buffer/entries-written: 1/1 #P:8
[SNIP]
# TASK-PID CPU# |||| TIMESTAMP FUNCTION
# | | | |||| | |
usleep-18593 [007] d... 2394714.395539: : 11
usleep-19000 [006] d... 2394831.057840: : 101
Signed-off-by: Wang Nan <wangnan0@huawei.com>
Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Alexei Starovoitov <ast@kernel.org>
Cc: Brendan Gregg <brendan.d.gregg@gmail.com>
Cc: Cody P Schafer <dev@codyps.com>
Cc: He Kuang <hekuang@huawei.com>
Cc: Jeremie Galarneau <jeremie.galarneau@efficios.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Kirill Smelkov <kirr@nexedi.com>
Cc: Li Zefan <lizefan@huawei.com>
Cc: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Zefan Li <lizefan@huawei.com>
Cc: pi3orama@163.com
Link: http://lkml.kernel.org/r/1456132275-98875-6-git-send-email-wangnan0@huawei.com
Signed-off-by: He Kuang <hekuang@huawei.com>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2016-02-22 17:10:32 +08:00
|
|
|
#include "util/bpf-loader.h"
|
2016-04-21 02:59:49 +08:00
|
|
|
#include "util/trigger.h"
|
2016-11-26 15:03:28 +08:00
|
|
|
#include "util/perf-hooks.h"
|
2019-01-23 01:50:57 +08:00
|
|
|
#include "util/cpu-set-sched.h"
|
2017-04-20 03:12:39 +08:00
|
|
|
#include "util/time-utils.h"
|
2017-04-20 03:05:56 +08:00
|
|
|
#include "util/units.h"
|
perf tools: Synthesize PERF_RECORD_* for loaded BPF programs
This patch synthesize PERF_RECORD_KSYMBOL and PERF_RECORD_BPF_EVENT for
BPF programs loaded before perf-record. This is achieved by gathering
information about all BPF programs via sys_bpf.
Committer notes:
Fix the build on some older systems such as amazonlinux:1 where it was
breaking with:
util/bpf-event.c: In function 'perf_event__synthesize_one_bpf_prog':
util/bpf-event.c:52:9: error: missing initializer for field 'type' of 'struct bpf_prog_info' [-Werror=missing-field-initializers]
struct bpf_prog_info info = {};
^
In file included from /git/linux/tools/lib/bpf/bpf.h:26:0,
from util/bpf-event.c:3:
/git/linux/tools/include/uapi/linux/bpf.h:2699:8: note: 'type' declared here
__u32 type;
^
cc1: all warnings being treated as errors
Further fix on a centos:6 system:
cc1: warnings being treated as errors
util/bpf-event.c: In function 'perf_event__synthesize_one_bpf_prog':
util/bpf-event.c:50: error: 'func_info_rec_size' may be used uninitialized in this function
The compiler is wrong, but to silence it, initialize that variable to
zero.
One more fix, this time for debian:experimental-x-mips, x-mips64 and
x-mipsel:
util/bpf-event.c: In function 'perf_event__synthesize_one_bpf_prog':
util/bpf-event.c:93:16: error: implicit declaration of function 'calloc' [-Werror=implicit-function-declaration]
func_infos = calloc(sub_prog_cnt, func_info_rec_size);
^~~~~~
util/bpf-event.c:93:16: error: incompatible implicit declaration of built-in function 'calloc' [-Werror]
util/bpf-event.c:93:16: note: include '<stdlib.h>' or provide a declaration of 'calloc'
Add the missing header.
Committer testing:
# perf record --bpf-event sleep 1
[ perf record: Woken up 1 times to write data ]
[ perf record: Captured and wrote 0.021 MB perf.data (7 samples) ]
# perf report -D | grep PERF_RECORD_BPF_EVENT | nl
1 0 0x4b10 [0x18]: PERF_RECORD_BPF_EVENT bpf event with type 1, flags 0, id 13
2 0 0x4c60 [0x18]: PERF_RECORD_BPF_EVENT bpf event with type 1, flags 0, id 14
3 0 0x4db0 [0x18]: PERF_RECORD_BPF_EVENT bpf event with type 1, flags 0, id 15
4 0 0x4f00 [0x18]: PERF_RECORD_BPF_EVENT bpf event with type 1, flags 0, id 16
5 0 0x5050 [0x18]: PERF_RECORD_BPF_EVENT bpf event with type 1, flags 0, id 17
6 0 0x51a0 [0x18]: PERF_RECORD_BPF_EVENT bpf event with type 1, flags 0, id 18
7 0 0x52f0 [0x18]: PERF_RECORD_BPF_EVENT bpf event with type 1, flags 0, id 21
8 0 0x5440 [0x18]: PERF_RECORD_BPF_EVENT bpf event with type 1, flags 0, id 22
# bpftool prog
13: cgroup_skb tag 7be49e3934a125ba gpl
loaded_at 2019-01-19T09:09:43-0300 uid 0
xlated 296B jited 229B memlock 4096B map_ids 13,14
14: cgroup_skb tag 2a142ef67aaad174 gpl
loaded_at 2019-01-19T09:09:43-0300 uid 0
xlated 296B jited 229B memlock 4096B map_ids 13,14
15: cgroup_skb tag 7be49e3934a125ba gpl
loaded_at 2019-01-19T09:09:43-0300 uid 0
xlated 296B jited 229B memlock 4096B map_ids 15,16
16: cgroup_skb tag 2a142ef67aaad174 gpl
loaded_at 2019-01-19T09:09:43-0300 uid 0
xlated 296B jited 229B memlock 4096B map_ids 15,16
17: cgroup_skb tag 7be49e3934a125ba gpl
loaded_at 2019-01-19T09:09:44-0300 uid 0
xlated 296B jited 229B memlock 4096B map_ids 17,18
18: cgroup_skb tag 2a142ef67aaad174 gpl
loaded_at 2019-01-19T09:09:44-0300 uid 0
xlated 296B jited 229B memlock 4096B map_ids 17,18
21: cgroup_skb tag 7be49e3934a125ba gpl
loaded_at 2019-01-19T09:09:45-0300 uid 0
xlated 296B jited 229B memlock 4096B map_ids 21,22
22: cgroup_skb tag 2a142ef67aaad174 gpl
loaded_at 2019-01-19T09:09:45-0300 uid 0
xlated 296B jited 229B memlock 4096B map_ids 21,22
#
# perf report -D | grep -B22 PERF_RECORD_KSYMBOL
. ... raw event: size 312 bytes
. 0000: 11 00 00 00 00 00 38 01 ff 44 06 c0 ff ff ff ff ......8..D......
. 0010: e5 00 00 00 01 00 00 00 62 70 66 5f 70 72 6f 67 ........bpf_prog
. 0020: 5f 37 62 65 34 39 65 33 39 33 34 61 31 32 35 62 _7be49e3934a125b
. 0030: 61 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 a...............
<SNIP zeroes>
. 0110: 00 00 00 00 00 00 00 00 21 00 00 00 00 00 00 00 ........!.......
. 0120: 7b e4 9e 39 34 a1 25 ba 00 00 00 00 00 00 00 00 {..94.%.........
. 0130: 00 00 00 00 00 00 00 00 ........
0 0x49d8 [0x138]: PERF_RECORD_KSYMBOL ksymbol event with addr ffffffffc00644ff len 229 type 1 flags 0x0 name bpf_prog_7be49e3934a125ba
--
. ... raw event: size 312 bytes
. 0000: 11 00 00 00 00 00 38 01 48 6d 06 c0 ff ff ff ff ......8.Hm......
. 0010: e5 00 00 00 01 00 00 00 62 70 66 5f 70 72 6f 67 ........bpf_prog
. 0020: 5f 32 61 31 34 32 65 66 36 37 61 61 61 64 31 37 _2a142ef67aaad17
. 0030: 34 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 4...............
<SNIP zeroes>
. 0110: 00 00 00 00 00 00 00 00 21 00 00 00 00 00 00 00 ........!.......
. 0120: 2a 14 2e f6 7a aa d1 74 00 00 00 00 00 00 00 00 *...z..t........
. 0130: 00 00 00 00 00 00 00 00 ........
0 0x4b28 [0x138]: PERF_RECORD_KSYMBOL ksymbol event with addr ffffffffc0066d48 len 229 type 1 flags 0x0 name bpf_prog_2a142ef67aaad174
--
. ... raw event: size 312 bytes
. 0000: 11 00 00 00 00 00 38 01 04 cf 03 c0 ff ff ff ff ......8.........
. 0010: e5 00 00 00 01 00 00 00 62 70 66 5f 70 72 6f 67 ........bpf_prog
. 0020: 5f 37 62 65 34 39 65 33 39 33 34 61 31 32 35 62 _7be49e3934a125b
. 0030: 61 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 a...............
<SNIP zeroes>
. 0110: 00 00 00 00 00 00 00 00 21 00 00 00 00 00 00 00 ........!.......
. 0120: 7b e4 9e 39 34 a1 25 ba 00 00 00 00 00 00 00 00 {..94.%.........
. 0130: 00 00 00 00 00 00 00 00 ........
0 0x4c78 [0x138]: PERF_RECORD_KSYMBOL ksymbol event with addr ffffffffc003cf04 len 229 type 1 flags 0x0 name bpf_prog_7be49e3934a125ba
--
. ... raw event: size 312 bytes
. 0000: 11 00 00 00 00 00 38 01 96 28 04 c0 ff ff ff ff ......8..(......
. 0010: e5 00 00 00 01 00 00 00 62 70 66 5f 70 72 6f 67 ........bpf_prog
. 0020: 5f 32 61 31 34 32 65 66 36 37 61 61 61 64 31 37 _2a142ef67aaad17
. 0030: 34 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 4...............
<SNIP zeroes>
. 0110: 00 00 00 00 00 00 00 00 21 00 00 00 00 00 00 00 ........!.......
. 0120: 2a 14 2e f6 7a aa d1 74 00 00 00 00 00 00 00 00 *...z..t........
. 0130: 00 00 00 00 00 00 00 00 ........
0 0x4dc8 [0x138]: PERF_RECORD_KSYMBOL ksymbol event with addr ffffffffc0042896 len 229 type 1 flags 0x0 name bpf_prog_2a142ef67aaad174
--
. ... raw event: size 312 bytes
. 0000: 11 00 00 00 00 00 38 01 05 13 17 c0 ff ff ff ff ......8.........
. 0010: e5 00 00 00 01 00 00 00 62 70 66 5f 70 72 6f 67 ........bpf_prog
. 0020: 5f 37 62 65 34 39 65 33 39 33 34 61 31 32 35 62 _7be49e3934a125b
. 0030: 61 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 a...............
<SNIP zeroes>
. 0110: 00 00 00 00 00 00 00 00 21 00 00 00 00 00 00 00 ........!.......
. 0120: 7b e4 9e 39 34 a1 25 ba 00 00 00 00 00 00 00 00 {..94.%.........
. 0130: 00 00 00 00 00 00 00 00 ........
0 0x4f18 [0x138]: PERF_RECORD_KSYMBOL ksymbol event with addr ffffffffc0171305 len 229 type 1 flags 0x0 name bpf_prog_7be49e3934a125ba
--
. ... raw event: size 312 bytes
. 0000: 11 00 00 00 00 00 38 01 0a 8c 23 c0 ff ff ff ff ......8...#.....
. 0010: e5 00 00 00 01 00 00 00 62 70 66 5f 70 72 6f 67 ........bpf_prog
. 0020: 5f 32 61 31 34 32 65 66 36 37 61 61 61 64 31 37 _2a142ef67aaad17
. 0030: 34 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 4...............
<SNIP zeroes>
. 0110: 00 00 00 00 00 00 00 00 21 00 00 00 00 00 00 00 ........!.......
. 0120: 2a 14 2e f6 7a aa d1 74 00 00 00 00 00 00 00 00 *...z..t........
. 0130: 00 00 00 00 00 00 00 00 ........
0 0x5068 [0x138]: PERF_RECORD_KSYMBOL ksymbol event with addr ffffffffc0238c0a len 229 type 1 flags 0x0 name bpf_prog_2a142ef67aaad174
--
. ... raw event: size 312 bytes
. 0000: 11 00 00 00 00 00 38 01 2a a5 a4 c0 ff ff ff ff ......8.*.......
. 0010: e5 00 00 00 01 00 00 00 62 70 66 5f 70 72 6f 67 ........bpf_prog
. 0020: 5f 37 62 65 34 39 65 33 39 33 34 61 31 32 35 62 _7be49e3934a125b
. 0030: 61 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 a...............
<SNIP zeroes>
. 0110: 00 00 00 00 00 00 00 00 21 00 00 00 00 00 00 00 ........!.......
. 0120: 7b e4 9e 39 34 a1 25 ba 00 00 00 00 00 00 00 00 {..94.%.........
. 0130: 00 00 00 00 00 00 00 00 ........
0 0x51b8 [0x138]: PERF_RECORD_KSYMBOL ksymbol event with addr ffffffffc0a4a52a len 229 type 1 flags 0x0 name bpf_prog_7be49e3934a125ba
--
. ... raw event: size 312 bytes
. 0000: 11 00 00 00 00 00 38 01 9b c9 a4 c0 ff ff ff ff ......8.........
. 0010: e5 00 00 00 01 00 00 00 62 70 66 5f 70 72 6f 67 ........bpf_prog
. 0020: 5f 32 61 31 34 32 65 66 36 37 61 61 61 64 31 37 _2a142ef67aaad17
. 0030: 34 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 4...............
<SNIP zeroes>
. 0110: 00 00 00 00 00 00 00 00 21 00 00 00 00 00 00 00 ........!.......
. 0120: 2a 14 2e f6 7a aa d1 74 00 00 00 00 00 00 00 00 *...z..t........
. 0130: 00 00 00 00 00 00 00 00 ........
0 0x5308 [0x138]: PERF_RECORD_KSYMBOL ksymbol event with addr ffffffffc0a4c99b len 229 type 1 flags 0x0 name bpf_prog_2a142ef67aaad174
Signed-off-by: Song Liu <songliubraving@fb.com>
Reviewed-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Alexei Starovoitov <ast@kernel.org>
Cc: Daniel Borkmann <daniel@iogearbox.net>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: kernel-team@fb.com
Cc: netdev@vger.kernel.org
Link: http://lkml.kernel.org/r/20190117161521.1341602-8-songliubraving@fb.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2019-01-18 00:15:19 +08:00
|
|
|
#include "util/bpf-event.h"
|
2016-02-26 17:32:06 +08:00
|
|
|
#include "asm/bug.h"
|
2009-06-25 23:05:54 +08:00
|
|
|
|
2017-04-18 21:46:11 +08:00
|
|
|
#include <errno.h>
|
2017-04-18 02:23:08 +08:00
|
|
|
#include <inttypes.h>
|
perf record: Allow asking for the maximum allowed sample rate
Add the handy '-F max' shortcut to reading and using the
kernel.perf_event_max_sample_rate value as the user supplied
sampling frequency:
# perf record -F max sleep 1
info: Using a maximum frequency rate of 15,000 Hz
[ perf record: Woken up 1 times to write data ]
[ perf record: Captured and wrote 0.019 MB perf.data (14 samples) ]
# sysctl kernel.perf_event_max_sample_rate
kernel.perf_event_max_sample_rate = 15000
# perf evlist -v
cycles:ppp: size: 112, { sample_period, sample_freq }: 15000, sample_type: IP|TID|TIME|PERIOD, disabled: 1, inherit: 1, mmap: 1, comm: 1, freq: 1, enable_on_exec: 1, task: 1, precise_ip: 3, sample_id_all: 1, exclude_guest: 1, mmap2: 1, comm_exec: 1
# perf record -F 10 sleep 1
[ perf record: Woken up 1 times to write data ]
[ perf record: Captured and wrote 0.019 MB perf.data (4 samples) ]
# perf evlist -v
cycles:ppp: size: 112, { sample_period, sample_freq }: 10, sample_type: IP|TID|TIME|PERIOD, disabled: 1, inherit: 1, mmap: 1, comm: 1, freq: 1, enable_on_exec: 1, task: 1, precise_ip: 3, sample_id_all: 1, exclude_guest: 1, mmap2: 1, comm_exec: 1
#
Suggested-by: Ingo Molnar <mingo@kernel.org>
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Wang Nan <wangnan0@huawei.com>
Link: https://lkml.kernel.org/n/tip-4y0tiuws62c64gp4cf0hme0m@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2018-03-02 00:46:23 +08:00
|
|
|
#include <locale.h>
|
2017-04-20 06:06:30 +08:00
|
|
|
#include <poll.h>
|
2009-06-02 21:52:24 +08:00
|
|
|
#include <unistd.h>
|
2009-04-08 21:01:31 +08:00
|
|
|
#include <sched.h>
|
2017-04-20 02:49:18 +08:00
|
|
|
#include <signal.h>
|
2010-05-19 05:29:23 +08:00
|
|
|
#include <sys/mman.h>
|
2017-04-20 06:06:30 +08:00
|
|
|
#include <sys/wait.h>
|
2016-08-09 02:05:46 +08:00
|
|
|
#include <linux/time64.h>
|
2012-10-08 14:43:26 +08:00
|
|
|
|
2017-01-09 17:51:56 +08:00
|
|
|
struct switch_output {
|
2017-01-09 17:51:58 +08:00
|
|
|
bool enabled;
|
2017-01-09 17:51:56 +08:00
|
|
|
bool signal;
|
2017-01-09 17:51:58 +08:00
|
|
|
unsigned long size;
|
2017-01-09 17:52:00 +08:00
|
|
|
unsigned long time;
|
2017-01-09 17:51:57 +08:00
|
|
|
const char *str;
|
|
|
|
bool set;
|
2019-03-15 06:49:55 +08:00
|
|
|
char **filenames;
|
|
|
|
int num_files;
|
|
|
|
int cur_file;
|
2017-01-09 17:51:56 +08:00
|
|
|
};
|
|
|
|
|
2013-12-20 01:38:03 +08:00
|
|
|
struct record {
|
2011-11-28 18:30:20 +08:00
|
|
|
struct perf_tool tool;
|
2013-12-20 01:43:45 +08:00
|
|
|
struct record_opts opts;
|
2011-11-25 18:19:45 +08:00
|
|
|
u64 bytes_written;
|
2017-01-24 05:07:59 +08:00
|
|
|
struct perf_data data;
|
2015-04-09 23:53:45 +08:00
|
|
|
struct auxtrace_record *itr;
|
2011-11-25 18:19:45 +08:00
|
|
|
struct perf_evlist *evlist;
|
|
|
|
struct perf_session *session;
|
|
|
|
int realtime_prio;
|
|
|
|
bool no_buildid;
|
2016-01-25 17:56:19 +08:00
|
|
|
bool no_buildid_set;
|
2011-11-25 18:19:45 +08:00
|
|
|
bool no_buildid_cache;
|
2016-01-25 17:56:19 +08:00
|
|
|
bool no_buildid_cache_set;
|
2016-01-11 21:37:09 +08:00
|
|
|
bool buildid_all;
|
2016-04-13 16:21:07 +08:00
|
|
|
bool timestamp_filename;
|
perf record: Record the first and last sample time in the header
In the default 'perf record' configuration, all samples are processed,
to create the HEADER_BUILD_ID table. So it's very easy to get the
first/last samples and save the time to perf file header via the
function write_sample_time().
Later, at post processing time, perf report/script will fetch the time
from perf file header.
Committer testing:
# perf record -a sleep 1
[ perf record: Woken up 1 times to write data ]
[ perf record: Captured and wrote 2.099 MB perf.data (1101 samples) ]
[root@jouet home]# perf report --header | grep "time of "
# time of first sample : 22947.909226
# time of last sample : 22948.910704
#
# perf report -D | grep PERF_RECORD_SAMPLE\(
0 22947909226101 0x20bb68 [0x30]: PERF_RECORD_SAMPLE(IP, 0x4001): 0/0: 0xffffffffa21b1af3 period: 1 addr: 0
0 22947909229928 0x20bb98 [0x30]: PERF_RECORD_SAMPLE(IP, 0x4001): 0/0: 0xffffffffa200d204 period: 1 addr: 0
<SNIP>
3 22948910397351 0x219360 [0x30]: PERF_RECORD_SAMPLE(IP, 0x4001): 28251/28251: 0xffffffffa22071d8 period: 169518 addr: 0
0 22948910652380 0x20f120 [0x30]: PERF_RECORD_SAMPLE(IP, 0x4001): 0/0: 0xffffffffa2856816 period: 198807 addr: 0
2 22948910704034 0x2172d0 [0x30]: PERF_RECORD_SAMPLE(IP, 0x4001): 0/0: 0xffffffffa2856816 period: 88111 addr: 0
#
Changelog:
v7: Just update the patch description according to Arnaldo's suggestion.
v6: Currently '--buildid-all' is not enabled at default. So the walking
on all samples is the default operation. There is no big overhead
to calculate the timestamp boundary in process_sample_event handler
once we already go through all samples. So the timestamp boundary
calculation is enabled by default when '--buildid-all' is not enabled.
While if '--buildid-all' is enabled, we creates a new option
"--timestamp-boundary" for user to decide if it enables the
timestamp boundary calculation.
v5: There is an issue that the sample walking can only work when
'--buildid-all' is not enabled. So we need to let the walking
be able to work even if '--buildid-all' is enabled and let the
processing skips the dso hit marking for this case.
At first, I want to provide a new option "--record-time-boundaries".
While after consideration, I think a new option is not very
necessary.
v3: Remove the definitions of first_sample_time and last_sample_time
from struct record and directly save them in perf_evlist.
Signed-off-by: Jin Yao <yao.jin@linux.intel.com>
Acked-by: Jiri Olsa <jolsa@kernel.org>
Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Andi Kleen <ak@linux.intel.com>
Cc: Kan Liang <kan.liang@intel.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Link: http://lkml.kernel.org/r/1512738826-2628-3-git-send-email-yao.jin@linux.intel.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2017-12-08 21:13:42 +08:00
|
|
|
bool timestamp_boundary;
|
2017-01-09 17:51:56 +08:00
|
|
|
struct switch_output switch_output;
|
perf record: Change 'record.samples' type to unsigned long long
When run "perf record -e", the number of samples showed up is wrong on some
32 bit systems, i.e. powerpc and arm.
For example, run the below commands on 32 bit powerpc:
perf probe -x /lib/libc.so.6 malloc
perf record -e probe_libc:malloc -a ls perf.data
[ perf record: Woken up 1 times to write data ]
[ perf record: Captured and wrote 0.036 MB perf.data (13829241621624967218 samples) ]
Actually, "perf script" just shows 21 samples. The number of samples is also
absurd since samples is long type, but it is printed as PRIu64.
Build test ran on x86-64, x86, aarch64, arm, mips, ppc and ppc64.
Signed-off-by: Yang Shi <yang.shi@linaro.org>
Cc: linaro-kernel@lists.linaro.org
Link: http://lkml.kernel.org/r/1443563383-4064-1-git-send-email-yang.shi@linaro.org
[ Bumped the 'hits' var used together with record.samples to 'unsigned long long' too ]
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2015-09-30 05:49:43 +08:00
|
|
|
unsigned long long samples;
|
2019-01-23 01:47:43 +08:00
|
|
|
cpu_set_t affinity_mask;
|
2011-11-09 00:41:57 +08:00
|
|
|
};
|
2009-06-06 15:58:57 +08:00
|
|
|
|
2017-01-09 17:51:58 +08:00
|
|
|
static volatile int auxtrace_record__snapshot_started;
|
|
|
|
static DEFINE_TRIGGER(auxtrace_snapshot_trigger);
|
|
|
|
static DEFINE_TRIGGER(switch_output_trigger);
|
|
|
|
|
2019-01-23 01:47:43 +08:00
|
|
|
static const char *affinity_tags[PERF_AFFINITY_MAX] = {
|
|
|
|
"SYS", "NODE", "CPU"
|
|
|
|
};
|
|
|
|
|
2017-01-09 17:51:58 +08:00
|
|
|
static bool switch_output_signal(struct record *rec)
|
|
|
|
{
|
|
|
|
return rec->switch_output.signal &&
|
|
|
|
trigger_is_ready(&switch_output_trigger);
|
|
|
|
}
|
|
|
|
|
|
|
|
static bool switch_output_size(struct record *rec)
|
|
|
|
{
|
|
|
|
return rec->switch_output.size &&
|
|
|
|
trigger_is_ready(&switch_output_trigger) &&
|
|
|
|
(rec->bytes_written >= rec->switch_output.size);
|
|
|
|
}
|
|
|
|
|
2017-01-09 17:52:00 +08:00
|
|
|
static bool switch_output_time(struct record *rec)
|
|
|
|
{
|
|
|
|
return rec->switch_output.time &&
|
|
|
|
trigger_is_ready(&switch_output_trigger);
|
|
|
|
}
|
|
|
|
|
2018-09-13 20:54:06 +08:00
|
|
|
static int record__write(struct record *rec, struct perf_mmap *map __maybe_unused,
|
|
|
|
void *bf, size_t size)
|
2009-06-19 05:22:55 +08:00
|
|
|
{
|
2018-09-13 20:54:06 +08:00
|
|
|
struct perf_data_file *file = &rec->session->data->file;
|
|
|
|
|
|
|
|
if (perf_data_file__write(file, bf, size) < 0) {
|
2013-11-22 20:11:24 +08:00
|
|
|
pr_err("failed to write perf data, error: %m\n");
|
|
|
|
return -1;
|
2009-06-19 05:22:55 +08:00
|
|
|
}
|
2012-08-27 02:24:47 +08:00
|
|
|
|
2013-12-20 01:26:26 +08:00
|
|
|
rec->bytes_written += size;
|
2017-01-09 17:51:58 +08:00
|
|
|
|
|
|
|
if (switch_output_size(rec))
|
|
|
|
trigger_hit(&switch_output_trigger);
|
|
|
|
|
2012-08-27 02:24:47 +08:00
|
|
|
return 0;
|
2009-06-19 05:22:55 +08:00
|
|
|
}
|
|
|
|
|
2018-11-06 17:04:58 +08:00
|
|
|
#ifdef HAVE_AIO_SUPPORT
|
|
|
|
static int record__aio_write(struct aiocb *cblock, int trace_fd,
|
|
|
|
void *buf, size_t size, off_t off)
|
|
|
|
{
|
|
|
|
int rc;
|
|
|
|
|
|
|
|
cblock->aio_fildes = trace_fd;
|
|
|
|
cblock->aio_buf = buf;
|
|
|
|
cblock->aio_nbytes = size;
|
|
|
|
cblock->aio_offset = off;
|
|
|
|
cblock->aio_sigevent.sigev_notify = SIGEV_NONE;
|
|
|
|
|
|
|
|
do {
|
|
|
|
rc = aio_write(cblock);
|
|
|
|
if (rc == 0) {
|
|
|
|
break;
|
|
|
|
} else if (errno != EAGAIN) {
|
|
|
|
cblock->aio_fildes = -1;
|
|
|
|
pr_err("failed to queue perf data, error: %m\n");
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
} while (1);
|
|
|
|
|
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int record__aio_complete(struct perf_mmap *md, struct aiocb *cblock)
|
|
|
|
{
|
|
|
|
void *rem_buf;
|
|
|
|
off_t rem_off;
|
|
|
|
size_t rem_size;
|
|
|
|
int rc, aio_errno;
|
|
|
|
ssize_t aio_ret, written;
|
|
|
|
|
|
|
|
aio_errno = aio_error(cblock);
|
|
|
|
if (aio_errno == EINPROGRESS)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
written = aio_ret = aio_return(cblock);
|
|
|
|
if (aio_ret < 0) {
|
|
|
|
if (aio_errno != EINTR)
|
|
|
|
pr_err("failed to write perf data, error: %m\n");
|
|
|
|
written = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
rem_size = cblock->aio_nbytes - written;
|
|
|
|
|
|
|
|
if (rem_size == 0) {
|
|
|
|
cblock->aio_fildes = -1;
|
|
|
|
/*
|
|
|
|
* md->refcount is incremented in perf_mmap__push() for
|
|
|
|
* every enqueued aio write request so decrement it because
|
|
|
|
* the request is now complete.
|
|
|
|
*/
|
|
|
|
perf_mmap__put(md);
|
|
|
|
rc = 1;
|
|
|
|
} else {
|
|
|
|
/*
|
|
|
|
* aio write request may require restart with the
|
|
|
|
* reminder if the kernel didn't write whole
|
|
|
|
* chunk at once.
|
|
|
|
*/
|
|
|
|
rem_off = cblock->aio_offset + written;
|
|
|
|
rem_buf = (void *)(cblock->aio_buf + written);
|
|
|
|
record__aio_write(cblock, cblock->aio_fildes,
|
|
|
|
rem_buf, rem_size, rem_off);
|
|
|
|
rc = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
|
2018-11-06 17:07:19 +08:00
|
|
|
static int record__aio_sync(struct perf_mmap *md, bool sync_all)
|
2018-11-06 17:04:58 +08:00
|
|
|
{
|
2018-11-06 17:07:19 +08:00
|
|
|
struct aiocb **aiocb = md->aio.aiocb;
|
|
|
|
struct aiocb *cblocks = md->aio.cblocks;
|
2018-11-06 17:04:58 +08:00
|
|
|
struct timespec timeout = { 0, 1000 * 1000 * 1 }; /* 1ms */
|
2018-11-06 17:07:19 +08:00
|
|
|
int i, do_suspend;
|
2018-11-06 17:04:58 +08:00
|
|
|
|
|
|
|
do {
|
2018-11-06 17:07:19 +08:00
|
|
|
do_suspend = 0;
|
|
|
|
for (i = 0; i < md->aio.nr_cblocks; ++i) {
|
|
|
|
if (cblocks[i].aio_fildes == -1 || record__aio_complete(md, &cblocks[i])) {
|
|
|
|
if (sync_all)
|
|
|
|
aiocb[i] = NULL;
|
|
|
|
else
|
|
|
|
return i;
|
|
|
|
} else {
|
|
|
|
/*
|
|
|
|
* Started aio write is not complete yet
|
|
|
|
* so it has to be waited before the
|
|
|
|
* next allocation.
|
|
|
|
*/
|
|
|
|
aiocb[i] = &cblocks[i];
|
|
|
|
do_suspend = 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (!do_suspend)
|
|
|
|
return -1;
|
2018-11-06 17:04:58 +08:00
|
|
|
|
2018-11-06 17:07:19 +08:00
|
|
|
while (aio_suspend((const struct aiocb **)aiocb, md->aio.nr_cblocks, &timeout)) {
|
2018-11-06 17:04:58 +08:00
|
|
|
if (!(errno == EAGAIN || errno == EINTR))
|
|
|
|
pr_err("failed to sync perf data, error: %m\n");
|
|
|
|
}
|
|
|
|
} while (1);
|
|
|
|
}
|
|
|
|
|
|
|
|
static int record__aio_pushfn(void *to, struct aiocb *cblock, void *bf, size_t size, off_t off)
|
|
|
|
{
|
|
|
|
struct record *rec = to;
|
|
|
|
int ret, trace_fd = rec->session->data->file.fd;
|
|
|
|
|
|
|
|
rec->samples++;
|
|
|
|
|
|
|
|
ret = record__aio_write(cblock, trace_fd, bf, size, off);
|
|
|
|
if (!ret) {
|
|
|
|
rec->bytes_written += size;
|
|
|
|
if (switch_output_size(rec))
|
|
|
|
trigger_hit(&switch_output_trigger);
|
|
|
|
}
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
static off_t record__aio_get_pos(int trace_fd)
|
|
|
|
{
|
|
|
|
return lseek(trace_fd, 0, SEEK_CUR);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void record__aio_set_pos(int trace_fd, off_t pos)
|
|
|
|
{
|
|
|
|
lseek(trace_fd, pos, SEEK_SET);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void record__aio_mmap_read_sync(struct record *rec)
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
struct perf_evlist *evlist = rec->evlist;
|
|
|
|
struct perf_mmap *maps = evlist->mmap;
|
|
|
|
|
|
|
|
if (!rec->opts.nr_cblocks)
|
|
|
|
return;
|
|
|
|
|
|
|
|
for (i = 0; i < evlist->nr_mmaps; i++) {
|
|
|
|
struct perf_mmap *map = &maps[i];
|
|
|
|
|
|
|
|
if (map->base)
|
2018-11-06 17:07:19 +08:00
|
|
|
record__aio_sync(map, true);
|
2018-11-06 17:04:58 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static int nr_cblocks_default = 1;
|
2018-11-06 17:07:19 +08:00
|
|
|
static int nr_cblocks_max = 4;
|
2018-11-06 17:04:58 +08:00
|
|
|
|
|
|
|
static int record__aio_parse(const struct option *opt,
|
2018-11-06 17:07:19 +08:00
|
|
|
const char *str,
|
2018-11-06 17:04:58 +08:00
|
|
|
int unset)
|
|
|
|
{
|
|
|
|
struct record_opts *opts = (struct record_opts *)opt->value;
|
|
|
|
|
2018-11-06 17:07:19 +08:00
|
|
|
if (unset) {
|
2018-11-06 17:04:58 +08:00
|
|
|
opts->nr_cblocks = 0;
|
2018-11-06 17:07:19 +08:00
|
|
|
} else {
|
|
|
|
if (str)
|
|
|
|
opts->nr_cblocks = strtol(str, NULL, 0);
|
|
|
|
if (!opts->nr_cblocks)
|
|
|
|
opts->nr_cblocks = nr_cblocks_default;
|
|
|
|
}
|
2018-11-06 17:04:58 +08:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
#else /* HAVE_AIO_SUPPORT */
|
2018-11-06 17:07:19 +08:00
|
|
|
static int nr_cblocks_max = 0;
|
|
|
|
|
|
|
|
static int record__aio_sync(struct perf_mmap *md __maybe_unused, bool sync_all __maybe_unused)
|
2018-11-06 17:04:58 +08:00
|
|
|
{
|
2018-11-06 17:07:19 +08:00
|
|
|
return -1;
|
2018-11-06 17:04:58 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
static int record__aio_pushfn(void *to __maybe_unused, struct aiocb *cblock __maybe_unused,
|
|
|
|
void *bf __maybe_unused, size_t size __maybe_unused, off_t off __maybe_unused)
|
|
|
|
{
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
static off_t record__aio_get_pos(int trace_fd __maybe_unused)
|
|
|
|
{
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void record__aio_set_pos(int trace_fd __maybe_unused, off_t pos __maybe_unused)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
static void record__aio_mmap_read_sync(struct record *rec __maybe_unused)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
static int record__aio_enabled(struct record *rec)
|
|
|
|
{
|
|
|
|
return rec->opts.nr_cblocks > 0;
|
|
|
|
}
|
|
|
|
|
2011-11-28 18:30:20 +08:00
|
|
|
static int process_synthesized_event(struct perf_tool *tool,
|
2011-11-25 18:19:45 +08:00
|
|
|
union perf_event *event,
|
2012-09-11 06:15:03 +08:00
|
|
|
struct perf_sample *sample __maybe_unused,
|
|
|
|
struct machine *machine __maybe_unused)
|
2009-10-27 05:23:18 +08:00
|
|
|
{
|
2013-12-20 01:38:03 +08:00
|
|
|
struct record *rec = container_of(tool, struct record, tool);
|
2018-09-13 20:54:06 +08:00
|
|
|
return record__write(rec, NULL, event, event->header.size);
|
2009-10-27 05:23:18 +08:00
|
|
|
}
|
|
|
|
|
2018-09-13 20:54:06 +08:00
|
|
|
static int record__pushfn(struct perf_mmap *map, void *to, void *bf, size_t size)
|
2017-10-06 03:39:55 +08:00
|
|
|
{
|
|
|
|
struct record *rec = to;
|
|
|
|
|
|
|
|
rec->samples++;
|
2018-09-13 20:54:06 +08:00
|
|
|
return record__write(rec, map, bf, size);
|
2017-10-06 03:39:55 +08:00
|
|
|
}
|
|
|
|
|
2015-04-30 22:37:32 +08:00
|
|
|
static volatile int done;
|
|
|
|
static volatile int signr = -1;
|
|
|
|
static volatile int child_finished;
|
2016-04-13 16:21:06 +08:00
|
|
|
|
2015-04-30 22:37:32 +08:00
|
|
|
static void sig_handler(int sig)
|
|
|
|
{
|
|
|
|
if (sig == SIGCHLD)
|
|
|
|
child_finished = 1;
|
|
|
|
else
|
|
|
|
signr = sig;
|
|
|
|
|
|
|
|
done = 1;
|
|
|
|
}
|
|
|
|
|
2016-11-26 15:03:28 +08:00
|
|
|
static void sigsegv_handler(int sig)
|
|
|
|
{
|
|
|
|
perf_hooks__recover();
|
|
|
|
sighandler_dump_stack(sig);
|
|
|
|
}
|
|
|
|
|
2015-04-30 22:37:32 +08:00
|
|
|
static void record__sig_exit(void)
|
|
|
|
{
|
|
|
|
if (signr == -1)
|
|
|
|
return;
|
|
|
|
|
|
|
|
signal(signr, SIG_DFL);
|
|
|
|
raise(signr);
|
|
|
|
}
|
|
|
|
|
2015-04-30 22:37:27 +08:00
|
|
|
#ifdef HAVE_AUXTRACE_SUPPORT
|
|
|
|
|
2015-04-09 23:53:45 +08:00
|
|
|
static int record__process_auxtrace(struct perf_tool *tool,
|
2018-09-13 20:54:06 +08:00
|
|
|
struct perf_mmap *map,
|
2015-04-09 23:53:45 +08:00
|
|
|
union perf_event *event, void *data1,
|
|
|
|
size_t len1, void *data2, size_t len2)
|
|
|
|
{
|
|
|
|
struct record *rec = container_of(tool, struct record, tool);
|
2017-01-24 05:07:59 +08:00
|
|
|
struct perf_data *data = &rec->data;
|
2015-04-09 23:53:45 +08:00
|
|
|
size_t padding;
|
|
|
|
u8 pad[8] = {0};
|
|
|
|
|
2019-03-08 21:47:36 +08:00
|
|
|
if (!perf_data__is_pipe(data) && !perf_data__is_dir(data)) {
|
2015-04-30 22:37:25 +08:00
|
|
|
off_t file_offset;
|
2017-01-24 05:07:59 +08:00
|
|
|
int fd = perf_data__fd(data);
|
2015-04-30 22:37:25 +08:00
|
|
|
int err;
|
|
|
|
|
|
|
|
file_offset = lseek(fd, 0, SEEK_CUR);
|
|
|
|
if (file_offset == -1)
|
|
|
|
return -1;
|
|
|
|
err = auxtrace_index__auxtrace_event(&rec->session->auxtrace_index,
|
|
|
|
event, file_offset);
|
|
|
|
if (err)
|
|
|
|
return err;
|
|
|
|
}
|
|
|
|
|
2015-04-09 23:53:45 +08:00
|
|
|
/* event.auxtrace.size includes padding, see __auxtrace_mmap__read() */
|
|
|
|
padding = (len1 + len2) & 7;
|
|
|
|
if (padding)
|
|
|
|
padding = 8 - padding;
|
|
|
|
|
2018-09-13 20:54:06 +08:00
|
|
|
record__write(rec, map, event, event->header.size);
|
|
|
|
record__write(rec, map, data1, len1);
|
2015-04-09 23:53:45 +08:00
|
|
|
if (len2)
|
2018-09-13 20:54:06 +08:00
|
|
|
record__write(rec, map, data2, len2);
|
|
|
|
record__write(rec, map, &pad, padding);
|
2015-04-09 23:53:45 +08:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int record__auxtrace_mmap_read(struct record *rec,
|
2018-09-13 20:54:05 +08:00
|
|
|
struct perf_mmap *map)
|
2015-04-09 23:53:45 +08:00
|
|
|
{
|
|
|
|
int ret;
|
|
|
|
|
2018-09-13 20:54:05 +08:00
|
|
|
ret = auxtrace_mmap__read(map, rec->itr, &rec->tool,
|
2015-04-09 23:53:45 +08:00
|
|
|
record__process_auxtrace);
|
|
|
|
if (ret < 0)
|
|
|
|
return ret;
|
|
|
|
|
|
|
|
if (ret)
|
|
|
|
rec->samples++;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2015-04-30 22:37:32 +08:00
|
|
|
static int record__auxtrace_mmap_read_snapshot(struct record *rec,
|
2018-09-13 20:54:05 +08:00
|
|
|
struct perf_mmap *map)
|
2015-04-30 22:37:32 +08:00
|
|
|
{
|
|
|
|
int ret;
|
|
|
|
|
2018-09-13 20:54:05 +08:00
|
|
|
ret = auxtrace_mmap__read_snapshot(map, rec->itr, &rec->tool,
|
2015-04-30 22:37:32 +08:00
|
|
|
record__process_auxtrace,
|
|
|
|
rec->opts.auxtrace_snapshot_size);
|
|
|
|
if (ret < 0)
|
|
|
|
return ret;
|
|
|
|
|
|
|
|
if (ret)
|
|
|
|
rec->samples++;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int record__auxtrace_read_snapshot_all(struct record *rec)
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
int rc = 0;
|
|
|
|
|
|
|
|
for (i = 0; i < rec->evlist->nr_mmaps; i++) {
|
2018-09-13 20:54:05 +08:00
|
|
|
struct perf_mmap *map = &rec->evlist->mmap[i];
|
2015-04-30 22:37:32 +08:00
|
|
|
|
2018-09-13 20:54:05 +08:00
|
|
|
if (!map->auxtrace_mmap.base)
|
2015-04-30 22:37:32 +08:00
|
|
|
continue;
|
|
|
|
|
2018-09-13 20:54:05 +08:00
|
|
|
if (record__auxtrace_mmap_read_snapshot(rec, map) != 0) {
|
2015-04-30 22:37:32 +08:00
|
|
|
rc = -1;
|
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
out:
|
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void record__read_auxtrace_snapshot(struct record *rec)
|
|
|
|
{
|
|
|
|
pr_debug("Recording AUX area tracing snapshot\n");
|
|
|
|
if (record__auxtrace_read_snapshot_all(rec) < 0) {
|
2016-04-21 02:59:49 +08:00
|
|
|
trigger_error(&auxtrace_snapshot_trigger);
|
2015-04-30 22:37:32 +08:00
|
|
|
} else {
|
2016-04-21 02:59:49 +08:00
|
|
|
if (auxtrace_record__snapshot_finish(rec->itr))
|
|
|
|
trigger_error(&auxtrace_snapshot_trigger);
|
|
|
|
else
|
|
|
|
trigger_ready(&auxtrace_snapshot_trigger);
|
2015-04-30 22:37:32 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-03-06 17:13:12 +08:00
|
|
|
static int record__auxtrace_init(struct record *rec)
|
|
|
|
{
|
|
|
|
int err;
|
|
|
|
|
|
|
|
if (!rec->itr) {
|
|
|
|
rec->itr = auxtrace_record__init(rec->evlist, &err);
|
|
|
|
if (err)
|
|
|
|
return err;
|
|
|
|
}
|
|
|
|
|
|
|
|
err = auxtrace_parse_snapshot_options(rec->itr, &rec->opts,
|
|
|
|
rec->opts.auxtrace_snapshot_opts);
|
|
|
|
if (err)
|
|
|
|
return err;
|
|
|
|
|
|
|
|
return auxtrace_parse_filters(rec->evlist);
|
|
|
|
}
|
|
|
|
|
2015-04-30 22:37:27 +08:00
|
|
|
#else
|
|
|
|
|
|
|
|
static inline
|
|
|
|
int record__auxtrace_mmap_read(struct record *rec __maybe_unused,
|
2018-09-13 20:54:05 +08:00
|
|
|
struct perf_mmap *map __maybe_unused)
|
2015-04-30 22:37:27 +08:00
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2015-04-30 22:37:32 +08:00
|
|
|
static inline
|
|
|
|
void record__read_auxtrace_snapshot(struct record *rec __maybe_unused)
|
2009-04-08 21:01:31 +08:00
|
|
|
{
|
2009-06-10 21:55:59 +08:00
|
|
|
}
|
|
|
|
|
2015-04-30 22:37:32 +08:00
|
|
|
static inline
|
|
|
|
int auxtrace_record__snapshot_start(struct auxtrace_record *itr __maybe_unused)
|
2009-06-10 21:55:59 +08:00
|
|
|
{
|
2015-04-30 22:37:32 +08:00
|
|
|
return 0;
|
2009-04-08 21:01:31 +08:00
|
|
|
}
|
|
|
|
|
2018-03-06 17:13:12 +08:00
|
|
|
static int record__auxtrace_init(struct record *rec __maybe_unused)
|
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2015-04-30 22:37:32 +08:00
|
|
|
#endif
|
|
|
|
|
2016-06-27 18:24:03 +08:00
|
|
|
static int record__mmap_evlist(struct record *rec,
|
|
|
|
struct perf_evlist *evlist)
|
|
|
|
{
|
|
|
|
struct record_opts *opts = &rec->opts;
|
|
|
|
char msg[512];
|
|
|
|
|
2019-01-23 01:50:57 +08:00
|
|
|
if (opts->affinity != PERF_AFFINITY_SYS)
|
|
|
|
cpu__setup_cpunode_map();
|
|
|
|
|
2017-12-03 10:00:38 +08:00
|
|
|
if (perf_evlist__mmap_ex(evlist, opts->mmap_pages,
|
2016-06-27 18:24:03 +08:00
|
|
|
opts->auxtrace_mmap_pages,
|
2019-01-23 01:47:43 +08:00
|
|
|
opts->auxtrace_snapshot_mode,
|
|
|
|
opts->nr_cblocks, opts->affinity) < 0) {
|
2016-06-27 18:24:03 +08:00
|
|
|
if (errno == EPERM) {
|
|
|
|
pr_err("Permission error mapping pages.\n"
|
|
|
|
"Consider increasing "
|
|
|
|
"/proc/sys/kernel/perf_event_mlock_kb,\n"
|
|
|
|
"or try again with a smaller value of -m/--mmap_pages.\n"
|
|
|
|
"(current value: %u,%u)\n",
|
|
|
|
opts->mmap_pages, opts->auxtrace_mmap_pages);
|
|
|
|
return -errno;
|
|
|
|
} else {
|
|
|
|
pr_err("failed to mmap with %d (%s)\n", errno,
|
tools: Introduce str_error_r()
The tools so far have been using the strerror_r() GNU variant, that
returns a string, be it the buffer passed or something else.
But that, besides being tricky in cases where we expect that the
function using strerror_r() returns the error formatted in a provided
buffer (we have to check if it returned something else and copy that
instead), breaks the build on systems not using glibc, like Alpine
Linux, where musl libc is used.
So, introduce yet another wrapper, str_error_r(), that has the GNU
interface, but uses the portable XSI variant of strerror_r(), so that
users rest asured that the provided buffer is used and it is what is
returned.
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Wang Nan <wangnan0@huawei.com>
Link: http://lkml.kernel.org/n/tip-d4t42fnf48ytlk8rjxs822tf@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2016-07-06 22:56:20 +08:00
|
|
|
str_error_r(errno, msg, sizeof(msg)));
|
2016-06-27 18:24:03 +08:00
|
|
|
if (errno)
|
|
|
|
return -errno;
|
|
|
|
else
|
|
|
|
return -EINVAL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int record__mmap(struct record *rec)
|
|
|
|
{
|
|
|
|
return record__mmap_evlist(rec, rec->evlist);
|
|
|
|
}
|
|
|
|
|
2013-12-20 01:38:03 +08:00
|
|
|
static int record__open(struct record *rec)
|
2011-01-13 00:28:51 +08:00
|
|
|
{
|
2017-02-14 03:45:24 +08:00
|
|
|
char msg[BUFSIZ];
|
perf tools: Enable grouping logic for parsed events
This patch adds a functionality that allows to create event groups
based on the way they are specified on the command line. Adding
functionality to the '{}' group syntax introduced in earlier patch.
The current '--group/-g' option behaviour remains intact. If you
specify it for record/stat/top command, all the specified events
become members of a single group with the first event as a group
leader.
With the new '{}' group syntax you can create group like:
# perf record -e '{cycles,faults}' ls
resulting in single event group containing 'cycles' and 'faults'
events, with cycles event as group leader.
All groups are created with regards to threads and cpus. Thus
recording an event group within a 2 threads on server with
4 CPUs will create 8 separate groups.
Examples (first event in brackets is group leader):
# 1 group (cpu-clock,task-clock)
perf record --group -e cpu-clock,task-clock ls
perf record -e '{cpu-clock,task-clock}' ls
# 2 groups (cpu-clock,task-clock) (minor-faults,major-faults)
perf record -e '{cpu-clock,task-clock},{minor-faults,major-faults}' ls
# 1 group (cpu-clock,task-clock,minor-faults,major-faults)
perf record --group -e cpu-clock,task-clock -e minor-faults,major-faults ls
perf record -e '{cpu-clock,task-clock,minor-faults,major-faults}' ls
# 2 groups (cpu-clock,task-clock) (minor-faults,major-faults)
perf record -e '{cpu-clock,task-clock} -e '{minor-faults,major-faults}' \
-e instructions ls
# 1 group
# (cpu-clock,task-clock,minor-faults,major-faults,instructions)
perf record --group -e cpu-clock,task-clock \
-e minor-faults,major-faults -e instructions ls perf record -e
'{cpu-clock,task-clock,minor-faults,major-faults,instructions}' ls
It's possible to use standard event modifier for a group, which spans
over all events in the group and updates each event modifier settings,
for example:
# perf record -r '{faults:k,cache-references}:p'
resulting in ':kp' modifier being used for 'faults' and ':p' modifier
being used for 'cache-references' event.
Reviewed-by: Namhyung Kim <namhyung@kernel.org>
Signed-off-by: Jiri Olsa <jolsa@redhat.com>
Acked-by: Peter Zijlstra <peterz@infradead.org>
Cc: Andi Kleen <andi@firstfloor.org>
Cc: Arnaldo Carvalho de Melo <acme@ghostprotocols.net>
Cc: Corey Ashford <cjashfor@linux.vnet.ibm.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Ulrich Drepper <drepper@gmail.com>
Link: http://lkml.kernel.org/n/tip-ho42u0wcr8mn1otkalqi13qp@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2012-08-08 18:22:36 +08:00
|
|
|
struct perf_evsel *pos;
|
2011-11-25 18:19:45 +08:00
|
|
|
struct perf_evlist *evlist = rec->evlist;
|
|
|
|
struct perf_session *session = rec->session;
|
2013-12-20 01:43:45 +08:00
|
|
|
struct record_opts *opts = &rec->opts;
|
2012-08-27 02:24:47 +08:00
|
|
|
int rc = 0;
|
2011-01-13 00:28:51 +08:00
|
|
|
|
perf record: Generate PERF_RECORD_{MMAP,COMM,EXEC} with --delay
When we use an initial delay, e.g.: 'perf record --delay 1000', we do not
enable the events until that delay has passed after we started the workload,
including the tracking event, i.e. the one for which we have attr.mmap, etc,
enabled to ask the kernel to generate the PERF_RECORD_{MMAP,COMM,EXEC} metadata
events that will then allow us to resolve addresses in samples to the map, dso
and symbol. There will be a shadow that even synthesizing samples won't cover,
i.e. the workload that we start and other processes forking while we
wait for the initial delay to expire.
So use a dummy event to be the tracking one and make it be enabled on exec.
Before:
# perf record --delay 1000 stress --cpu 1 --timeout 5
stress: info: [9029] dispatching hogs: 1 cpu, 0 io, 0 vm, 0 hdd
stress: info: [9029] successful run completed in 5s
[ perf record: Woken up 3 times to write data ]
[ perf record: Captured and wrote 0.624 MB perf.data (15908 samples) ]
# perf script | head
:9031 9031 32001.826888: 1 cycles:ppp: ffffffff831aa30d event_function (/lib/modules/4.14.0-rc6+/build/vmlinux)
:9031 9031 32001.826893: 1 cycles:ppp: ffffffff8300d1a0 intel_bts_enable_local (/lib/modules/4.14.0-rc6+/build/vmlinux)
:9031 9031 32001.826895: 7 cycles:ppp: ffffffff83023870 sched_clock (/lib/modules/4.14.0-rc6+/build/vmlinux)
:9031 9031 32001.826897: 103 cycles:ppp: ffffffff8300c331 intel_pmu_handle_irq (/lib/modules/4.14.0-rc6+/build/vmlinux)
:9031 9031 32001.826899: 1615 cycles:ppp: ffffffff830231f8 native_sched_clock (/lib/modules/4.14.0-rc6+/build/vmlinux)
:9031 9031 32001.826902: 26724 cycles:ppp: ffffffff8384c6a7 native_irq_return_iret (/lib/modules/4.14.0-rc6+/build/vmlinux)
:9031 9031 32001.826913: 329739 cycles:ppp: 7fb2a5410932 [unknown] ([unknown])
:9031 9031 32001.827033: 1225451 cycles:ppp: 7fb2a5410930 [unknown] ([unknown])
:9031 9031 32001.827474: 1391725 cycles:ppp: 7fb2a5410930 [unknown] ([unknown])
:9031 9031 32001.827978: 1233697 cycles:ppp: 7fb2a5410928 [unknown] ([unknown])
#
After:
# perf record --delay 1000 stress --cpu 1 --timeout 5
stress: info: [9741] dispatching hogs: 1 cpu, 0 io, 0 vm, 0 hdd
stress: info: [9741] successful run completed in 5s
[ perf record: Woken up 3 times to write data ]
[ perf record: Captured and wrote 0.751 MB perf.data (15976 samples) ]
# perf script | head
stress 9742 32110.959106: 1 cycles:ppp: ffffffff831b26f6 __perf_event_task_sched_in (/lib/modules/4.14.0-rc6+/build/vmlinux)
stress 9742 32110.959110: 1 cycles:ppp: ffffffff8300c2e9 intel_pmu_handle_irq (/lib/modules/4.14.0-rc6+/build/vmlinux)
stress 9742 32110.959112: 7 cycles:ppp: ffffffff830231e0 native_sched_clock (/lib/modules/4.14.0-rc6+/build/vmlinux)
stress 9742 32110.959115: 101 cycles:ppp: ffffffff83023870 sched_clock (/lib/modules/4.14.0-rc6+/build/vmlinux)
stress 9742 32110.959117: 1533 cycles:ppp: ffffffff830231f8 native_sched_clock (/lib/modules/4.14.0-rc6+/build/vmlinux)
stress 9742 32110.959119: 23992 cycles:ppp: ffffffff831b0900 ctx_sched_in (/lib/modules/4.14.0-rc6+/build/vmlinux)
stress 9742 32110.959129: 329406 cycles:ppp: 7f4b1b661930 __random_r (/usr/lib64/libc-2.25.so)
stress 9742 32110.959249: 1288322 cycles:ppp: 5566e1e7cbc9 hogcpu (/usr/bin/stress)
stress 9742 32110.959712: 1464046 cycles:ppp: 7f4b1b66179e __random (/usr/lib64/libc-2.25.so)
stress 9742 32110.960241: 1266918 cycles:ppp: 7f4b1b66195b __random_r (/usr/lib64/libc-2.25.so)
#
Reported-by: Bram Stolk <b.stolk@gmail.com>
Tested-by: Bram Stolk <b.stolk@gmail.com>
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Andi Kleen <ak@linux.intel.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Wang Nan <wangnan0@huawei.com>
Fixes: 6619a53ef757 ("perf record: Add --initial-delay option")
Link: http://lkml.kernel.org/n/tip-nrdfchshqxf7diszhxcecqb9@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2017-11-04 02:34:34 +08:00
|
|
|
/*
|
|
|
|
* For initial_delay we need to add a dummy event so that we can track
|
|
|
|
* PERF_RECORD_MMAP while we wait for the initial delay to enable the
|
|
|
|
* real events, the ones asked by the user.
|
|
|
|
*/
|
|
|
|
if (opts->initial_delay) {
|
|
|
|
if (perf_evlist__add_dummy(evlist))
|
|
|
|
return -ENOMEM;
|
|
|
|
|
|
|
|
pos = perf_evlist__first(evlist);
|
|
|
|
pos->tracking = 0;
|
|
|
|
pos = perf_evlist__last(evlist);
|
|
|
|
pos->tracking = 1;
|
|
|
|
pos->attr.enable_on_exec = 1;
|
|
|
|
}
|
|
|
|
|
2016-04-12 05:15:29 +08:00
|
|
|
perf_evlist__config(evlist, opts, &callchain_param);
|
2012-11-13 01:34:00 +08:00
|
|
|
|
2016-06-23 22:26:15 +08:00
|
|
|
evlist__for_each_entry(evlist, pos) {
|
2011-01-13 00:28:51 +08:00
|
|
|
try_again:
|
2015-08-21 14:23:14 +08:00
|
|
|
if (perf_evsel__open(pos, pos->cpus, pos->threads) < 0) {
|
2012-12-14 02:10:58 +08:00
|
|
|
if (perf_evsel__fallback(pos, errno, msg, sizeof(msg))) {
|
2017-02-17 16:17:38 +08:00
|
|
|
if (verbose > 0)
|
2012-12-14 01:16:30 +08:00
|
|
|
ui__warning("%s\n", msg);
|
2010-03-18 22:36:05 +08:00
|
|
|
goto try_again;
|
|
|
|
}
|
perf record: Support weak groups
Implement a weak group fallback for 'perf record', similar to the
existing 'perf stat' support. This allows to use groups that might be
longer than the available counters without failing.
Before:
$ perf record -e '{cycles,cache-misses,cache-references,cpu_clk_unhalted.thread,cycles,cycles,cycles}' -a sleep 1
Error:
The sys_perf_event_open() syscall returned with 22 (Invalid argument) for event (cycles).
/bin/dmesg | grep -i perf may provide additional information.
After:
$ ./perf record -e '{cycles,cache-misses,cache-references,cpu_clk_unhalted.thread,cycles,cycles,cycles}:W' -a sleep 1
WARNING: No sample_id_all support, falling back to unordered processing
[ perf record: Woken up 3 times to write data ]
[ perf record: Captured and wrote 8.136 MB perf.data (134069 samples) ]
Signed-off-by: Andi Kleen <ak@linux.intel.com>
Acked-by: Jiri Olsa <jolsa@kernel.org>
Link: http://lkml.kernel.org/r/20181001195927.14211-2-andi@firstfloor.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2018-10-02 03:59:27 +08:00
|
|
|
if ((errno == EINVAL || errno == EBADF) &&
|
|
|
|
pos->leader != pos &&
|
|
|
|
pos->weak_group) {
|
|
|
|
pos = perf_evlist__reset_weak_group(evlist, pos);
|
|
|
|
goto try_again;
|
|
|
|
}
|
2012-12-14 02:10:58 +08:00
|
|
|
rc = -errno;
|
|
|
|
perf_evsel__open_strerror(pos, &opts->target,
|
|
|
|
errno, msg, sizeof(msg));
|
|
|
|
ui__error("%s\n", msg);
|
2012-08-27 02:24:47 +08:00
|
|
|
goto out;
|
2009-10-15 11:22:07 +08:00
|
|
|
}
|
2017-11-18 05:42:58 +08:00
|
|
|
|
|
|
|
pos->supported = true;
|
2009-10-15 11:22:07 +08:00
|
|
|
}
|
2010-12-25 22:12:25 +08:00
|
|
|
|
2015-03-25 06:23:47 +08:00
|
|
|
if (perf_evlist__apply_filters(evlist, &pos)) {
|
2017-06-27 22:22:31 +08:00
|
|
|
pr_err("failed to set filter \"%s\" on event %s with %d (%s)\n",
|
2015-03-25 06:23:47 +08:00
|
|
|
pos->filter, perf_evsel__name(pos), errno,
|
tools: Introduce str_error_r()
The tools so far have been using the strerror_r() GNU variant, that
returns a string, be it the buffer passed or something else.
But that, besides being tricky in cases where we expect that the
function using strerror_r() returns the error formatted in a provided
buffer (we have to check if it returned something else and copy that
instead), breaks the build on systems not using glibc, like Alpine
Linux, where musl libc is used.
So, introduce yet another wrapper, str_error_r(), that has the GNU
interface, but uses the portable XSI variant of strerror_r(), so that
users rest asured that the provided buffer is used and it is what is
returned.
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Wang Nan <wangnan0@huawei.com>
Link: http://lkml.kernel.org/n/tip-d4t42fnf48ytlk8rjxs822tf@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2016-07-06 22:56:20 +08:00
|
|
|
str_error_r(errno, msg, sizeof(msg)));
|
2012-08-27 02:24:47 +08:00
|
|
|
rc = -1;
|
2016-09-16 23:50:03 +08:00
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
|
2016-06-27 18:24:03 +08:00
|
|
|
rc = record__mmap(rec);
|
|
|
|
if (rc)
|
2012-08-27 02:24:47 +08:00
|
|
|
goto out;
|
2011-01-15 01:50:51 +08:00
|
|
|
|
2013-06-05 19:35:06 +08:00
|
|
|
session->evlist = evlist;
|
2012-08-02 06:31:00 +08:00
|
|
|
perf_session__set_id_hdr_size(session);
|
2012-08-27 02:24:47 +08:00
|
|
|
out:
|
|
|
|
return rc;
|
2009-05-05 23:50:27 +08:00
|
|
|
}
|
|
|
|
|
2015-01-29 16:06:44 +08:00
|
|
|
static int process_sample_event(struct perf_tool *tool,
|
|
|
|
union perf_event *event,
|
|
|
|
struct perf_sample *sample,
|
|
|
|
struct perf_evsel *evsel,
|
|
|
|
struct machine *machine)
|
|
|
|
{
|
|
|
|
struct record *rec = container_of(tool, struct record, tool);
|
|
|
|
|
perf record: Record the first and last sample time in the header
In the default 'perf record' configuration, all samples are processed,
to create the HEADER_BUILD_ID table. So it's very easy to get the
first/last samples and save the time to perf file header via the
function write_sample_time().
Later, at post processing time, perf report/script will fetch the time
from perf file header.
Committer testing:
# perf record -a sleep 1
[ perf record: Woken up 1 times to write data ]
[ perf record: Captured and wrote 2.099 MB perf.data (1101 samples) ]
[root@jouet home]# perf report --header | grep "time of "
# time of first sample : 22947.909226
# time of last sample : 22948.910704
#
# perf report -D | grep PERF_RECORD_SAMPLE\(
0 22947909226101 0x20bb68 [0x30]: PERF_RECORD_SAMPLE(IP, 0x4001): 0/0: 0xffffffffa21b1af3 period: 1 addr: 0
0 22947909229928 0x20bb98 [0x30]: PERF_RECORD_SAMPLE(IP, 0x4001): 0/0: 0xffffffffa200d204 period: 1 addr: 0
<SNIP>
3 22948910397351 0x219360 [0x30]: PERF_RECORD_SAMPLE(IP, 0x4001): 28251/28251: 0xffffffffa22071d8 period: 169518 addr: 0
0 22948910652380 0x20f120 [0x30]: PERF_RECORD_SAMPLE(IP, 0x4001): 0/0: 0xffffffffa2856816 period: 198807 addr: 0
2 22948910704034 0x2172d0 [0x30]: PERF_RECORD_SAMPLE(IP, 0x4001): 0/0: 0xffffffffa2856816 period: 88111 addr: 0
#
Changelog:
v7: Just update the patch description according to Arnaldo's suggestion.
v6: Currently '--buildid-all' is not enabled at default. So the walking
on all samples is the default operation. There is no big overhead
to calculate the timestamp boundary in process_sample_event handler
once we already go through all samples. So the timestamp boundary
calculation is enabled by default when '--buildid-all' is not enabled.
While if '--buildid-all' is enabled, we creates a new option
"--timestamp-boundary" for user to decide if it enables the
timestamp boundary calculation.
v5: There is an issue that the sample walking can only work when
'--buildid-all' is not enabled. So we need to let the walking
be able to work even if '--buildid-all' is enabled and let the
processing skips the dso hit marking for this case.
At first, I want to provide a new option "--record-time-boundaries".
While after consideration, I think a new option is not very
necessary.
v3: Remove the definitions of first_sample_time and last_sample_time
from struct record and directly save them in perf_evlist.
Signed-off-by: Jin Yao <yao.jin@linux.intel.com>
Acked-by: Jiri Olsa <jolsa@kernel.org>
Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Andi Kleen <ak@linux.intel.com>
Cc: Kan Liang <kan.liang@intel.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Link: http://lkml.kernel.org/r/1512738826-2628-3-git-send-email-yao.jin@linux.intel.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2017-12-08 21:13:42 +08:00
|
|
|
if (rec->evlist->first_sample_time == 0)
|
|
|
|
rec->evlist->first_sample_time = sample->time;
|
|
|
|
|
|
|
|
rec->evlist->last_sample_time = sample->time;
|
2015-01-29 16:06:44 +08:00
|
|
|
|
perf record: Record the first and last sample time in the header
In the default 'perf record' configuration, all samples are processed,
to create the HEADER_BUILD_ID table. So it's very easy to get the
first/last samples and save the time to perf file header via the
function write_sample_time().
Later, at post processing time, perf report/script will fetch the time
from perf file header.
Committer testing:
# perf record -a sleep 1
[ perf record: Woken up 1 times to write data ]
[ perf record: Captured and wrote 2.099 MB perf.data (1101 samples) ]
[root@jouet home]# perf report --header | grep "time of "
# time of first sample : 22947.909226
# time of last sample : 22948.910704
#
# perf report -D | grep PERF_RECORD_SAMPLE\(
0 22947909226101 0x20bb68 [0x30]: PERF_RECORD_SAMPLE(IP, 0x4001): 0/0: 0xffffffffa21b1af3 period: 1 addr: 0
0 22947909229928 0x20bb98 [0x30]: PERF_RECORD_SAMPLE(IP, 0x4001): 0/0: 0xffffffffa200d204 period: 1 addr: 0
<SNIP>
3 22948910397351 0x219360 [0x30]: PERF_RECORD_SAMPLE(IP, 0x4001): 28251/28251: 0xffffffffa22071d8 period: 169518 addr: 0
0 22948910652380 0x20f120 [0x30]: PERF_RECORD_SAMPLE(IP, 0x4001): 0/0: 0xffffffffa2856816 period: 198807 addr: 0
2 22948910704034 0x2172d0 [0x30]: PERF_RECORD_SAMPLE(IP, 0x4001): 0/0: 0xffffffffa2856816 period: 88111 addr: 0
#
Changelog:
v7: Just update the patch description according to Arnaldo's suggestion.
v6: Currently '--buildid-all' is not enabled at default. So the walking
on all samples is the default operation. There is no big overhead
to calculate the timestamp boundary in process_sample_event handler
once we already go through all samples. So the timestamp boundary
calculation is enabled by default when '--buildid-all' is not enabled.
While if '--buildid-all' is enabled, we creates a new option
"--timestamp-boundary" for user to decide if it enables the
timestamp boundary calculation.
v5: There is an issue that the sample walking can only work when
'--buildid-all' is not enabled. So we need to let the walking
be able to work even if '--buildid-all' is enabled and let the
processing skips the dso hit marking for this case.
At first, I want to provide a new option "--record-time-boundaries".
While after consideration, I think a new option is not very
necessary.
v3: Remove the definitions of first_sample_time and last_sample_time
from struct record and directly save them in perf_evlist.
Signed-off-by: Jin Yao <yao.jin@linux.intel.com>
Acked-by: Jiri Olsa <jolsa@kernel.org>
Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Andi Kleen <ak@linux.intel.com>
Cc: Kan Liang <kan.liang@intel.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Link: http://lkml.kernel.org/r/1512738826-2628-3-git-send-email-yao.jin@linux.intel.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2017-12-08 21:13:42 +08:00
|
|
|
if (rec->buildid_all)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
rec->samples++;
|
2015-01-29 16:06:44 +08:00
|
|
|
return build_id__mark_dso_hit(tool, event, sample, evsel, machine);
|
|
|
|
}
|
|
|
|
|
2013-12-20 01:38:03 +08:00
|
|
|
static int process_buildids(struct record *rec)
|
2010-02-04 02:52:05 +08:00
|
|
|
{
|
2013-10-15 22:27:32 +08:00
|
|
|
struct perf_session *session = rec->session;
|
2010-02-04 02:52:05 +08:00
|
|
|
|
2019-02-21 17:41:29 +08:00
|
|
|
if (perf_data__size(&rec->data) == 0)
|
2010-03-12 02:53:11 +08:00
|
|
|
return 0;
|
|
|
|
|
2014-11-04 09:14:32 +08:00
|
|
|
/*
|
|
|
|
* During this process, it'll load kernel map and replace the
|
|
|
|
* dso->long_name to a real pathname it found. In this case
|
|
|
|
* we prefer the vmlinux path like
|
|
|
|
* /lib/modules/3.16.4/build/vmlinux
|
|
|
|
*
|
|
|
|
* rather than build-id path (in debug directory).
|
|
|
|
* $HOME/.debug/.build-id/f0/6e17aa50adf4d00b88925e03775de107611551
|
|
|
|
*/
|
|
|
|
symbol_conf.ignore_vmlinux_buildid = true;
|
|
|
|
|
2016-01-11 21:37:09 +08:00
|
|
|
/*
|
|
|
|
* If --buildid-all is given, it marks all DSO regardless of hits,
|
perf record: Record the first and last sample time in the header
In the default 'perf record' configuration, all samples are processed,
to create the HEADER_BUILD_ID table. So it's very easy to get the
first/last samples and save the time to perf file header via the
function write_sample_time().
Later, at post processing time, perf report/script will fetch the time
from perf file header.
Committer testing:
# perf record -a sleep 1
[ perf record: Woken up 1 times to write data ]
[ perf record: Captured and wrote 2.099 MB perf.data (1101 samples) ]
[root@jouet home]# perf report --header | grep "time of "
# time of first sample : 22947.909226
# time of last sample : 22948.910704
#
# perf report -D | grep PERF_RECORD_SAMPLE\(
0 22947909226101 0x20bb68 [0x30]: PERF_RECORD_SAMPLE(IP, 0x4001): 0/0: 0xffffffffa21b1af3 period: 1 addr: 0
0 22947909229928 0x20bb98 [0x30]: PERF_RECORD_SAMPLE(IP, 0x4001): 0/0: 0xffffffffa200d204 period: 1 addr: 0
<SNIP>
3 22948910397351 0x219360 [0x30]: PERF_RECORD_SAMPLE(IP, 0x4001): 28251/28251: 0xffffffffa22071d8 period: 169518 addr: 0
0 22948910652380 0x20f120 [0x30]: PERF_RECORD_SAMPLE(IP, 0x4001): 0/0: 0xffffffffa2856816 period: 198807 addr: 0
2 22948910704034 0x2172d0 [0x30]: PERF_RECORD_SAMPLE(IP, 0x4001): 0/0: 0xffffffffa2856816 period: 88111 addr: 0
#
Changelog:
v7: Just update the patch description according to Arnaldo's suggestion.
v6: Currently '--buildid-all' is not enabled at default. So the walking
on all samples is the default operation. There is no big overhead
to calculate the timestamp boundary in process_sample_event handler
once we already go through all samples. So the timestamp boundary
calculation is enabled by default when '--buildid-all' is not enabled.
While if '--buildid-all' is enabled, we creates a new option
"--timestamp-boundary" for user to decide if it enables the
timestamp boundary calculation.
v5: There is an issue that the sample walking can only work when
'--buildid-all' is not enabled. So we need to let the walking
be able to work even if '--buildid-all' is enabled and let the
processing skips the dso hit marking for this case.
At first, I want to provide a new option "--record-time-boundaries".
While after consideration, I think a new option is not very
necessary.
v3: Remove the definitions of first_sample_time and last_sample_time
from struct record and directly save them in perf_evlist.
Signed-off-by: Jin Yao <yao.jin@linux.intel.com>
Acked-by: Jiri Olsa <jolsa@kernel.org>
Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Andi Kleen <ak@linux.intel.com>
Cc: Kan Liang <kan.liang@intel.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Link: http://lkml.kernel.org/r/1512738826-2628-3-git-send-email-yao.jin@linux.intel.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2017-12-08 21:13:42 +08:00
|
|
|
* so no need to process samples. But if timestamp_boundary is enabled,
|
|
|
|
* it still needs to walk on all samples to get the timestamps of
|
|
|
|
* first/last samples.
|
2016-01-11 21:37:09 +08:00
|
|
|
*/
|
perf record: Record the first and last sample time in the header
In the default 'perf record' configuration, all samples are processed,
to create the HEADER_BUILD_ID table. So it's very easy to get the
first/last samples and save the time to perf file header via the
function write_sample_time().
Later, at post processing time, perf report/script will fetch the time
from perf file header.
Committer testing:
# perf record -a sleep 1
[ perf record: Woken up 1 times to write data ]
[ perf record: Captured and wrote 2.099 MB perf.data (1101 samples) ]
[root@jouet home]# perf report --header | grep "time of "
# time of first sample : 22947.909226
# time of last sample : 22948.910704
#
# perf report -D | grep PERF_RECORD_SAMPLE\(
0 22947909226101 0x20bb68 [0x30]: PERF_RECORD_SAMPLE(IP, 0x4001): 0/0: 0xffffffffa21b1af3 period: 1 addr: 0
0 22947909229928 0x20bb98 [0x30]: PERF_RECORD_SAMPLE(IP, 0x4001): 0/0: 0xffffffffa200d204 period: 1 addr: 0
<SNIP>
3 22948910397351 0x219360 [0x30]: PERF_RECORD_SAMPLE(IP, 0x4001): 28251/28251: 0xffffffffa22071d8 period: 169518 addr: 0
0 22948910652380 0x20f120 [0x30]: PERF_RECORD_SAMPLE(IP, 0x4001): 0/0: 0xffffffffa2856816 period: 198807 addr: 0
2 22948910704034 0x2172d0 [0x30]: PERF_RECORD_SAMPLE(IP, 0x4001): 0/0: 0xffffffffa2856816 period: 88111 addr: 0
#
Changelog:
v7: Just update the patch description according to Arnaldo's suggestion.
v6: Currently '--buildid-all' is not enabled at default. So the walking
on all samples is the default operation. There is no big overhead
to calculate the timestamp boundary in process_sample_event handler
once we already go through all samples. So the timestamp boundary
calculation is enabled by default when '--buildid-all' is not enabled.
While if '--buildid-all' is enabled, we creates a new option
"--timestamp-boundary" for user to decide if it enables the
timestamp boundary calculation.
v5: There is an issue that the sample walking can only work when
'--buildid-all' is not enabled. So we need to let the walking
be able to work even if '--buildid-all' is enabled and let the
processing skips the dso hit marking for this case.
At first, I want to provide a new option "--record-time-boundaries".
While after consideration, I think a new option is not very
necessary.
v3: Remove the definitions of first_sample_time and last_sample_time
from struct record and directly save them in perf_evlist.
Signed-off-by: Jin Yao <yao.jin@linux.intel.com>
Acked-by: Jiri Olsa <jolsa@kernel.org>
Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Andi Kleen <ak@linux.intel.com>
Cc: Kan Liang <kan.liang@intel.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Link: http://lkml.kernel.org/r/1512738826-2628-3-git-send-email-yao.jin@linux.intel.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2017-12-08 21:13:42 +08:00
|
|
|
if (rec->buildid_all && !rec->timestamp_boundary)
|
2016-01-11 21:37:09 +08:00
|
|
|
rec->tool.sample = NULL;
|
|
|
|
|
2015-03-03 22:58:45 +08:00
|
|
|
return perf_session__process_events(session);
|
2010-02-04 02:52:05 +08:00
|
|
|
}
|
|
|
|
|
2011-01-30 00:01:45 +08:00
|
|
|
static void perf_event__synthesize_guest_os(struct machine *machine, void *data)
|
2010-04-19 13:32:50 +08:00
|
|
|
{
|
|
|
|
int err;
|
2011-11-28 18:30:20 +08:00
|
|
|
struct perf_tool *tool = data;
|
2010-04-19 13:32:50 +08:00
|
|
|
/*
|
|
|
|
*As for guest kernel when processing subcommand record&report,
|
|
|
|
*we arrange module mmap prior to guest kernel mmap and trigger
|
|
|
|
*a preload dso because default guest module symbols are loaded
|
|
|
|
*from guest kallsyms instead of /lib/modules/XXX/XXX. This
|
|
|
|
*method is used to avoid symbol missing when the first addr is
|
|
|
|
*in module instead of in guest kernel.
|
|
|
|
*/
|
2011-11-28 18:30:20 +08:00
|
|
|
err = perf_event__synthesize_modules(tool, process_synthesized_event,
|
2011-11-28 17:56:39 +08:00
|
|
|
machine);
|
2010-04-19 13:32:50 +08:00
|
|
|
if (err < 0)
|
|
|
|
pr_err("Couldn't record guest kernel [%d]'s reference"
|
2010-04-28 08:17:50 +08:00
|
|
|
" relocation symbol.\n", machine->pid);
|
2010-04-19 13:32:50 +08:00
|
|
|
|
|
|
|
/*
|
|
|
|
* We use _stext for guest kernel because guest kernel's /proc/kallsyms
|
|
|
|
* have no _text sometimes.
|
|
|
|
*/
|
2011-11-28 18:30:20 +08:00
|
|
|
err = perf_event__synthesize_kernel_mmap(tool, process_synthesized_event,
|
2014-01-29 22:14:40 +08:00
|
|
|
machine);
|
2010-04-19 13:32:50 +08:00
|
|
|
if (err < 0)
|
|
|
|
pr_err("Couldn't record guest kernel [%d]'s reference"
|
2010-04-28 08:17:50 +08:00
|
|
|
" relocation symbol.\n", machine->pid);
|
2010-04-19 13:32:50 +08:00
|
|
|
}
|
|
|
|
|
2010-05-03 04:05:29 +08:00
|
|
|
static struct perf_event_header finished_round_event = {
|
|
|
|
.size = sizeof(struct perf_event_header),
|
|
|
|
.type = PERF_RECORD_FINISHED_ROUND,
|
|
|
|
};
|
|
|
|
|
2019-01-23 01:50:57 +08:00
|
|
|
static void record__adjust_affinity(struct record *rec, struct perf_mmap *map)
|
|
|
|
{
|
|
|
|
if (rec->opts.affinity != PERF_AFFINITY_SYS &&
|
|
|
|
!CPU_EQUAL(&rec->affinity_mask, &map->affinity_mask)) {
|
|
|
|
CPU_ZERO(&rec->affinity_mask);
|
|
|
|
CPU_OR(&rec->affinity_mask, &rec->affinity_mask, &map->affinity_mask);
|
|
|
|
sched_setaffinity(0, sizeof(rec->affinity_mask), &rec->affinity_mask);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-07-14 16:34:36 +08:00
|
|
|
static int record__mmap_read_evlist(struct record *rec, struct perf_evlist *evlist,
|
2017-12-05 00:51:07 +08:00
|
|
|
bool overwrite)
|
2010-05-03 04:05:29 +08:00
|
|
|
{
|
2014-07-25 22:56:16 +08:00
|
|
|
u64 bytes_written = rec->bytes_written;
|
2010-05-20 20:45:26 +08:00
|
|
|
int i;
|
2012-08-27 02:24:47 +08:00
|
|
|
int rc = 0;
|
2016-07-14 16:34:36 +08:00
|
|
|
struct perf_mmap *maps;
|
2018-11-06 17:04:58 +08:00
|
|
|
int trace_fd = rec->data.file.fd;
|
|
|
|
off_t off;
|
2010-05-03 04:05:29 +08:00
|
|
|
|
2016-06-27 18:24:04 +08:00
|
|
|
if (!evlist)
|
|
|
|
return 0;
|
2015-04-09 23:53:45 +08:00
|
|
|
|
2017-12-05 00:51:07 +08:00
|
|
|
maps = overwrite ? evlist->overwrite_mmap : evlist->mmap;
|
2016-07-14 16:34:36 +08:00
|
|
|
if (!maps)
|
|
|
|
return 0;
|
|
|
|
|
2017-12-05 00:51:07 +08:00
|
|
|
if (overwrite && evlist->bkw_mmap_state != BKW_MMAP_DATA_PENDING)
|
2016-07-14 16:34:42 +08:00
|
|
|
return 0;
|
|
|
|
|
2018-11-06 17:04:58 +08:00
|
|
|
if (record__aio_enabled(rec))
|
|
|
|
off = record__aio_get_pos(trace_fd);
|
|
|
|
|
2016-06-27 18:24:04 +08:00
|
|
|
for (i = 0; i < evlist->nr_mmaps; i++) {
|
2018-09-13 20:54:05 +08:00
|
|
|
struct perf_mmap *map = &maps[i];
|
2016-06-27 18:24:04 +08:00
|
|
|
|
2018-09-13 20:54:05 +08:00
|
|
|
if (map->base) {
|
2019-01-23 01:50:57 +08:00
|
|
|
record__adjust_affinity(rec, map);
|
2018-11-06 17:04:58 +08:00
|
|
|
if (!record__aio_enabled(rec)) {
|
|
|
|
if (perf_mmap__push(map, rec, record__pushfn) != 0) {
|
|
|
|
rc = -1;
|
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
} else {
|
2018-11-06 17:07:19 +08:00
|
|
|
int idx;
|
2018-11-06 17:04:58 +08:00
|
|
|
/*
|
|
|
|
* Call record__aio_sync() to wait till map->data buffer
|
|
|
|
* becomes available after previous aio write request.
|
|
|
|
*/
|
2018-11-06 17:07:19 +08:00
|
|
|
idx = record__aio_sync(map, false);
|
|
|
|
if (perf_mmap__aio_push(map, rec, idx, record__aio_pushfn, &off) != 0) {
|
2018-11-06 17:04:58 +08:00
|
|
|
record__aio_set_pos(trace_fd, off);
|
|
|
|
rc = -1;
|
|
|
|
goto out;
|
|
|
|
}
|
2012-08-27 02:24:47 +08:00
|
|
|
}
|
|
|
|
}
|
2015-04-09 23:53:45 +08:00
|
|
|
|
2018-09-13 20:54:05 +08:00
|
|
|
if (map->auxtrace_mmap.base && !rec->opts.auxtrace_snapshot_mode &&
|
|
|
|
record__auxtrace_mmap_read(rec, map) != 0) {
|
2015-04-09 23:53:45 +08:00
|
|
|
rc = -1;
|
|
|
|
goto out;
|
|
|
|
}
|
2010-05-03 04:05:29 +08:00
|
|
|
}
|
|
|
|
|
2018-11-06 17:04:58 +08:00
|
|
|
if (record__aio_enabled(rec))
|
|
|
|
record__aio_set_pos(trace_fd, off);
|
|
|
|
|
2014-07-25 22:56:16 +08:00
|
|
|
/*
|
|
|
|
* Mark the round finished in case we wrote
|
|
|
|
* at least one event.
|
|
|
|
*/
|
|
|
|
if (bytes_written != rec->bytes_written)
|
2018-09-13 20:54:06 +08:00
|
|
|
rc = record__write(rec, NULL, &finished_round_event, sizeof(finished_round_event));
|
2012-08-27 02:24:47 +08:00
|
|
|
|
2017-12-05 00:51:07 +08:00
|
|
|
if (overwrite)
|
2016-07-14 16:34:42 +08:00
|
|
|
perf_evlist__toggle_bkw_mmap(evlist, BKW_MMAP_EMPTY);
|
2012-08-27 02:24:47 +08:00
|
|
|
out:
|
|
|
|
return rc;
|
2010-05-03 04:05:29 +08:00
|
|
|
}
|
|
|
|
|
2016-06-27 18:24:04 +08:00
|
|
|
static int record__mmap_read_all(struct record *rec)
|
|
|
|
{
|
|
|
|
int err;
|
|
|
|
|
2016-07-14 16:34:36 +08:00
|
|
|
err = record__mmap_read_evlist(rec, rec->evlist, false);
|
2016-06-27 18:24:04 +08:00
|
|
|
if (err)
|
|
|
|
return err;
|
|
|
|
|
2016-07-14 16:34:43 +08:00
|
|
|
return record__mmap_read_evlist(rec, rec->evlist, true);
|
2016-06-27 18:24:04 +08:00
|
|
|
}
|
|
|
|
|
2013-12-20 01:38:03 +08:00
|
|
|
static void record__init_features(struct record *rec)
|
2013-11-07 02:41:34 +08:00
|
|
|
{
|
|
|
|
struct perf_session *session = rec->session;
|
|
|
|
int feat;
|
|
|
|
|
|
|
|
for (feat = HEADER_FIRST_FEATURE; feat < HEADER_LAST_FEATURE; feat++)
|
|
|
|
perf_header__set_feat(&session->header, feat);
|
|
|
|
|
|
|
|
if (rec->no_buildid)
|
|
|
|
perf_header__clear_feat(&session->header, HEADER_BUILD_ID);
|
|
|
|
|
2014-01-04 02:03:26 +08:00
|
|
|
if (!have_tracepoints(&rec->evlist->entries))
|
2013-11-07 02:41:34 +08:00
|
|
|
perf_header__clear_feat(&session->header, HEADER_TRACING_DATA);
|
|
|
|
|
|
|
|
if (!rec->opts.branch_stack)
|
|
|
|
perf_header__clear_feat(&session->header, HEADER_BRANCH_STACK);
|
2015-04-09 23:53:45 +08:00
|
|
|
|
|
|
|
if (!rec->opts.full_auxtrace)
|
|
|
|
perf_header__clear_feat(&session->header, HEADER_AUXTRACE);
|
2015-10-25 22:51:43 +08:00
|
|
|
|
perf record: Encode -k clockid frequency into Perf trace
Store -k clockid frequency into Perf trace to enable timestamps
derived metrics conversion into wall clock time on reporting stage.
Below is the example of perf report output:
tools/perf/perf record -k raw -- ../../matrix/linux/matrix.gcc
...
[ perf record: Captured and wrote 31.222 MB perf.data (818054 samples) ]
tools/perf/perf report --header
# ========
...
# event : name = cycles:ppp, , size = 112, { sample_period, sample_freq } = 4000, sample_type = IP|TID|TIME|PERIOD, disabled = 1, inherit = 1, mmap = 1, comm = 1, freq = 1, enable_on_exec = 1, task = 1, precise_ip = 3, sample_id_all = 1, exclude_guest = 1, mmap2 = 1, comm_exec = 1, use_clockid = 1, clockid = 4
...
# clockid frequency: 1000 MHz
...
# ========
Signed-off-by: Alexey Budankov <alexey.budankov@linux.intel.com>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Andi Kleen <ak@linux.intel.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Link: http://lkml.kernel.org/r/23a4a1dc-b160-85a0-347d-40a2ed6d007b@linux.intel.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2018-10-09 22:36:24 +08:00
|
|
|
if (!(rec->opts.use_clockid && rec->opts.clockid_res_ns))
|
|
|
|
perf_header__clear_feat(&session->header, HEADER_CLOCKID);
|
|
|
|
|
2019-03-08 21:47:39 +08:00
|
|
|
perf_header__clear_feat(&session->header, HEADER_DIR_FORMAT);
|
|
|
|
|
2015-10-25 22:51:43 +08:00
|
|
|
perf_header__clear_feat(&session->header, HEADER_STAT);
|
2013-11-07 02:41:34 +08:00
|
|
|
}
|
|
|
|
|
2016-02-26 17:32:10 +08:00
|
|
|
static void
|
|
|
|
record__finish_output(struct record *rec)
|
|
|
|
{
|
2017-01-24 05:07:59 +08:00
|
|
|
struct perf_data *data = &rec->data;
|
|
|
|
int fd = perf_data__fd(data);
|
2016-02-26 17:32:10 +08:00
|
|
|
|
2017-01-24 05:07:59 +08:00
|
|
|
if (data->is_pipe)
|
2016-02-26 17:32:10 +08:00
|
|
|
return;
|
|
|
|
|
|
|
|
rec->session->header.data_size += rec->bytes_written;
|
2019-02-21 17:41:29 +08:00
|
|
|
data->file.size = lseek(perf_data__fd(data), 0, SEEK_CUR);
|
2016-02-26 17:32:10 +08:00
|
|
|
|
|
|
|
if (!rec->no_buildid) {
|
|
|
|
process_buildids(rec);
|
|
|
|
|
|
|
|
if (rec->buildid_all)
|
|
|
|
dsos__hit_all(rec->session);
|
|
|
|
}
|
|
|
|
perf_session__write_header(rec->session, rec->evlist, fd, true);
|
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
perf record: Add --tail-synthesize option
When working with overwritable ring buffer there's a inconvenience
problem: if perf dumps data after a long period after it starts,
non-sample events may lost, which makes following 'perf report' unable
to identify proc name and mmap layout. For example:
# perf record -m 4 -e raw_syscalls:* -g --overwrite --switch-output \
dd if=/dev/zero of=/dev/null
send SIGUSR2 after dd runs long enough. The resuling perf.data lost
correct comm and mmap events:
# perf script -i perf.data.2016061522374354
perf 24478 [004] 2581325.601789: raw_syscalls:sys_exit: NR 0 = 512
^^^^
Should be 'dd'
27b2e8 syscall_slow_exit_work+0xfe2000e3 (/lib/modules/4.6.0-rc3+/build/vmlinux)
203cc7 do_syscall_64+0xfe200117 (/lib/modules/4.6.0-rc3+/build/vmlinux)
b18d83 return_from_SYSCALL_64+0xfe200000 (/lib/modules/4.6.0-rc3+/build/vmlinux)
7f47c417edf0 [unknown] ([unknown])
^^^^^^^^^^^^
Fail to unwind
This patch provides a '--tail-synthesize' option, allows perf to collect
system status when finalizing output file. In resuling output file, the
non-sample events reflect system status when dumping data.
After this patch:
# perf record -m 4 -e raw_syscalls:* -g --overwrite --switch-output --tail-synthesize \
dd if=/dev/zero of=/dev/null
# perf script -i perf.data.2016061600544998
dd 27364 [004] 2583244.994464: raw_syscalls:sys_enter: NR 1 (1, ...
^^
Correct comm
203a18 syscall_trace_enter_phase2+0xfe2001a8 ([kernel.kallsyms])
203aa5 syscall_trace_enter+0xfe200055 ([kernel.kallsyms])
203caa do_syscall_64+0xfe2000fa ([kernel.kallsyms])
b18d83 return_from_SYSCALL_64+0xfe200000 ([kernel.kallsyms])
d8e50 __GI___libc_write+0xffff01d9639f4010 (/tmp/oxygen_root-w00229757/lib64/libc-2.18.so)
^^^^^
Correct unwind
This option doesn't aim to solve this problem completely. If a process
terminates before SIGUSR2, we still lost its COMM and MMAP events. For
example, we can't unwind correctly from the final perf.data we get from
the previous example, because when perf collects the final output file
(when we press C-c), 'dd' has been terminated so its '/proc/<pid>/mmap'
becomes empty.
However, this is a cheaper choice. To completely solve this problem we
need to continously output non-sample events. To satisify the
requirement of daemonization, we need to merge them periodically. It is
possible but requires much more code and cycles.
Automatically select --tail-synthesize when --overwrite is provided.
Signed-off-by: Wang Nan <wangnan0@huawei.com>
Cc: He Kuang <hekuang@huawei.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Masami Hiramatsu <mhiramat@kernel.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Nilay Vaish <nilayvaish@gmail.com>
Cc: Zefan Li <lizefan@huawei.com>
Cc: pi3orama@163.com
Link: http://lkml.kernel.org/r/1468485287-33422-16-git-send-email-wangnan0@huawei.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2016-07-14 16:34:47 +08:00
|
|
|
static int record__synthesize_workload(struct record *rec, bool tail)
|
2016-04-21 02:59:54 +08:00
|
|
|
{
|
2017-02-14 21:59:04 +08:00
|
|
|
int err;
|
|
|
|
struct thread_map *thread_map;
|
2016-04-21 02:59:54 +08:00
|
|
|
|
perf record: Add --tail-synthesize option
When working with overwritable ring buffer there's a inconvenience
problem: if perf dumps data after a long period after it starts,
non-sample events may lost, which makes following 'perf report' unable
to identify proc name and mmap layout. For example:
# perf record -m 4 -e raw_syscalls:* -g --overwrite --switch-output \
dd if=/dev/zero of=/dev/null
send SIGUSR2 after dd runs long enough. The resuling perf.data lost
correct comm and mmap events:
# perf script -i perf.data.2016061522374354
perf 24478 [004] 2581325.601789: raw_syscalls:sys_exit: NR 0 = 512
^^^^
Should be 'dd'
27b2e8 syscall_slow_exit_work+0xfe2000e3 (/lib/modules/4.6.0-rc3+/build/vmlinux)
203cc7 do_syscall_64+0xfe200117 (/lib/modules/4.6.0-rc3+/build/vmlinux)
b18d83 return_from_SYSCALL_64+0xfe200000 (/lib/modules/4.6.0-rc3+/build/vmlinux)
7f47c417edf0 [unknown] ([unknown])
^^^^^^^^^^^^
Fail to unwind
This patch provides a '--tail-synthesize' option, allows perf to collect
system status when finalizing output file. In resuling output file, the
non-sample events reflect system status when dumping data.
After this patch:
# perf record -m 4 -e raw_syscalls:* -g --overwrite --switch-output --tail-synthesize \
dd if=/dev/zero of=/dev/null
# perf script -i perf.data.2016061600544998
dd 27364 [004] 2583244.994464: raw_syscalls:sys_enter: NR 1 (1, ...
^^
Correct comm
203a18 syscall_trace_enter_phase2+0xfe2001a8 ([kernel.kallsyms])
203aa5 syscall_trace_enter+0xfe200055 ([kernel.kallsyms])
203caa do_syscall_64+0xfe2000fa ([kernel.kallsyms])
b18d83 return_from_SYSCALL_64+0xfe200000 ([kernel.kallsyms])
d8e50 __GI___libc_write+0xffff01d9639f4010 (/tmp/oxygen_root-w00229757/lib64/libc-2.18.so)
^^^^^
Correct unwind
This option doesn't aim to solve this problem completely. If a process
terminates before SIGUSR2, we still lost its COMM and MMAP events. For
example, we can't unwind correctly from the final perf.data we get from
the previous example, because when perf collects the final output file
(when we press C-c), 'dd' has been terminated so its '/proc/<pid>/mmap'
becomes empty.
However, this is a cheaper choice. To completely solve this problem we
need to continously output non-sample events. To satisify the
requirement of daemonization, we need to merge them periodically. It is
possible but requires much more code and cycles.
Automatically select --tail-synthesize when --overwrite is provided.
Signed-off-by: Wang Nan <wangnan0@huawei.com>
Cc: He Kuang <hekuang@huawei.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Masami Hiramatsu <mhiramat@kernel.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Nilay Vaish <nilayvaish@gmail.com>
Cc: Zefan Li <lizefan@huawei.com>
Cc: pi3orama@163.com
Link: http://lkml.kernel.org/r/1468485287-33422-16-git-send-email-wangnan0@huawei.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2016-07-14 16:34:47 +08:00
|
|
|
if (rec->opts.tail_synthesize != tail)
|
|
|
|
return 0;
|
|
|
|
|
2017-02-14 21:59:04 +08:00
|
|
|
thread_map = thread_map__new_by_tid(rec->evlist->workload.pid);
|
|
|
|
if (thread_map == NULL)
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
err = perf_event__synthesize_thread_map(&rec->tool, thread_map,
|
2016-04-21 02:59:54 +08:00
|
|
|
process_synthesized_event,
|
|
|
|
&rec->session->machines.host,
|
2018-12-05 04:34:20 +08:00
|
|
|
rec->opts.sample_address);
|
2017-02-14 21:59:04 +08:00
|
|
|
thread_map__put(thread_map);
|
|
|
|
return err;
|
2016-04-21 02:59:54 +08:00
|
|
|
}
|
|
|
|
|
perf record: Add --tail-synthesize option
When working with overwritable ring buffer there's a inconvenience
problem: if perf dumps data after a long period after it starts,
non-sample events may lost, which makes following 'perf report' unable
to identify proc name and mmap layout. For example:
# perf record -m 4 -e raw_syscalls:* -g --overwrite --switch-output \
dd if=/dev/zero of=/dev/null
send SIGUSR2 after dd runs long enough. The resuling perf.data lost
correct comm and mmap events:
# perf script -i perf.data.2016061522374354
perf 24478 [004] 2581325.601789: raw_syscalls:sys_exit: NR 0 = 512
^^^^
Should be 'dd'
27b2e8 syscall_slow_exit_work+0xfe2000e3 (/lib/modules/4.6.0-rc3+/build/vmlinux)
203cc7 do_syscall_64+0xfe200117 (/lib/modules/4.6.0-rc3+/build/vmlinux)
b18d83 return_from_SYSCALL_64+0xfe200000 (/lib/modules/4.6.0-rc3+/build/vmlinux)
7f47c417edf0 [unknown] ([unknown])
^^^^^^^^^^^^
Fail to unwind
This patch provides a '--tail-synthesize' option, allows perf to collect
system status when finalizing output file. In resuling output file, the
non-sample events reflect system status when dumping data.
After this patch:
# perf record -m 4 -e raw_syscalls:* -g --overwrite --switch-output --tail-synthesize \
dd if=/dev/zero of=/dev/null
# perf script -i perf.data.2016061600544998
dd 27364 [004] 2583244.994464: raw_syscalls:sys_enter: NR 1 (1, ...
^^
Correct comm
203a18 syscall_trace_enter_phase2+0xfe2001a8 ([kernel.kallsyms])
203aa5 syscall_trace_enter+0xfe200055 ([kernel.kallsyms])
203caa do_syscall_64+0xfe2000fa ([kernel.kallsyms])
b18d83 return_from_SYSCALL_64+0xfe200000 ([kernel.kallsyms])
d8e50 __GI___libc_write+0xffff01d9639f4010 (/tmp/oxygen_root-w00229757/lib64/libc-2.18.so)
^^^^^
Correct unwind
This option doesn't aim to solve this problem completely. If a process
terminates before SIGUSR2, we still lost its COMM and MMAP events. For
example, we can't unwind correctly from the final perf.data we get from
the previous example, because when perf collects the final output file
(when we press C-c), 'dd' has been terminated so its '/proc/<pid>/mmap'
becomes empty.
However, this is a cheaper choice. To completely solve this problem we
need to continously output non-sample events. To satisify the
requirement of daemonization, we need to merge them periodically. It is
possible but requires much more code and cycles.
Automatically select --tail-synthesize when --overwrite is provided.
Signed-off-by: Wang Nan <wangnan0@huawei.com>
Cc: He Kuang <hekuang@huawei.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Masami Hiramatsu <mhiramat@kernel.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Nilay Vaish <nilayvaish@gmail.com>
Cc: Zefan Li <lizefan@huawei.com>
Cc: pi3orama@163.com
Link: http://lkml.kernel.org/r/1468485287-33422-16-git-send-email-wangnan0@huawei.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2016-07-14 16:34:47 +08:00
|
|
|
static int record__synthesize(struct record *rec, bool tail);
|
2016-04-21 02:59:50 +08:00
|
|
|
|
2016-04-13 16:21:07 +08:00
|
|
|
static int
|
|
|
|
record__switch_output(struct record *rec, bool at_exit)
|
|
|
|
{
|
2017-01-24 05:07:59 +08:00
|
|
|
struct perf_data *data = &rec->data;
|
2016-04-13 16:21:07 +08:00
|
|
|
int fd, err;
|
2019-03-15 06:49:55 +08:00
|
|
|
char *new_filename;
|
2016-04-13 16:21:07 +08:00
|
|
|
|
|
|
|
/* Same Size: "2015122520103046"*/
|
|
|
|
char timestamp[] = "InvalidTimestamp";
|
|
|
|
|
2018-11-06 17:04:58 +08:00
|
|
|
record__aio_mmap_read_sync(rec);
|
|
|
|
|
perf record: Add --tail-synthesize option
When working with overwritable ring buffer there's a inconvenience
problem: if perf dumps data after a long period after it starts,
non-sample events may lost, which makes following 'perf report' unable
to identify proc name and mmap layout. For example:
# perf record -m 4 -e raw_syscalls:* -g --overwrite --switch-output \
dd if=/dev/zero of=/dev/null
send SIGUSR2 after dd runs long enough. The resuling perf.data lost
correct comm and mmap events:
# perf script -i perf.data.2016061522374354
perf 24478 [004] 2581325.601789: raw_syscalls:sys_exit: NR 0 = 512
^^^^
Should be 'dd'
27b2e8 syscall_slow_exit_work+0xfe2000e3 (/lib/modules/4.6.0-rc3+/build/vmlinux)
203cc7 do_syscall_64+0xfe200117 (/lib/modules/4.6.0-rc3+/build/vmlinux)
b18d83 return_from_SYSCALL_64+0xfe200000 (/lib/modules/4.6.0-rc3+/build/vmlinux)
7f47c417edf0 [unknown] ([unknown])
^^^^^^^^^^^^
Fail to unwind
This patch provides a '--tail-synthesize' option, allows perf to collect
system status when finalizing output file. In resuling output file, the
non-sample events reflect system status when dumping data.
After this patch:
# perf record -m 4 -e raw_syscalls:* -g --overwrite --switch-output --tail-synthesize \
dd if=/dev/zero of=/dev/null
# perf script -i perf.data.2016061600544998
dd 27364 [004] 2583244.994464: raw_syscalls:sys_enter: NR 1 (1, ...
^^
Correct comm
203a18 syscall_trace_enter_phase2+0xfe2001a8 ([kernel.kallsyms])
203aa5 syscall_trace_enter+0xfe200055 ([kernel.kallsyms])
203caa do_syscall_64+0xfe2000fa ([kernel.kallsyms])
b18d83 return_from_SYSCALL_64+0xfe200000 ([kernel.kallsyms])
d8e50 __GI___libc_write+0xffff01d9639f4010 (/tmp/oxygen_root-w00229757/lib64/libc-2.18.so)
^^^^^
Correct unwind
This option doesn't aim to solve this problem completely. If a process
terminates before SIGUSR2, we still lost its COMM and MMAP events. For
example, we can't unwind correctly from the final perf.data we get from
the previous example, because when perf collects the final output file
(when we press C-c), 'dd' has been terminated so its '/proc/<pid>/mmap'
becomes empty.
However, this is a cheaper choice. To completely solve this problem we
need to continously output non-sample events. To satisify the
requirement of daemonization, we need to merge them periodically. It is
possible but requires much more code and cycles.
Automatically select --tail-synthesize when --overwrite is provided.
Signed-off-by: Wang Nan <wangnan0@huawei.com>
Cc: He Kuang <hekuang@huawei.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Masami Hiramatsu <mhiramat@kernel.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Nilay Vaish <nilayvaish@gmail.com>
Cc: Zefan Li <lizefan@huawei.com>
Cc: pi3orama@163.com
Link: http://lkml.kernel.org/r/1468485287-33422-16-git-send-email-wangnan0@huawei.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2016-07-14 16:34:47 +08:00
|
|
|
record__synthesize(rec, true);
|
|
|
|
if (target__none(&rec->opts.target))
|
|
|
|
record__synthesize_workload(rec, true);
|
|
|
|
|
2016-04-13 16:21:07 +08:00
|
|
|
rec->samples = 0;
|
|
|
|
record__finish_output(rec);
|
|
|
|
err = fetch_current_timestamp(timestamp, sizeof(timestamp));
|
|
|
|
if (err) {
|
|
|
|
pr_err("Failed to get current timestamp\n");
|
|
|
|
return -EINVAL;
|
|
|
|
}
|
|
|
|
|
2017-01-24 05:07:59 +08:00
|
|
|
fd = perf_data__switch(data, timestamp,
|
2016-04-13 16:21:07 +08:00
|
|
|
rec->session->header.data_offset,
|
2019-03-15 06:49:55 +08:00
|
|
|
at_exit, &new_filename);
|
2016-04-13 16:21:07 +08:00
|
|
|
if (fd >= 0 && !at_exit) {
|
|
|
|
rec->bytes_written = 0;
|
|
|
|
rec->session->header.data_size = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!quiet)
|
|
|
|
fprintf(stderr, "[ perf record: Dump %s.%s ]\n",
|
2019-02-21 17:41:30 +08:00
|
|
|
data->path, timestamp);
|
2016-04-21 02:59:50 +08:00
|
|
|
|
2019-03-15 06:49:55 +08:00
|
|
|
if (rec->switch_output.num_files) {
|
|
|
|
int n = rec->switch_output.cur_file + 1;
|
|
|
|
|
|
|
|
if (n >= rec->switch_output.num_files)
|
|
|
|
n = 0;
|
|
|
|
rec->switch_output.cur_file = n;
|
|
|
|
if (rec->switch_output.filenames[n]) {
|
|
|
|
remove(rec->switch_output.filenames[n]);
|
|
|
|
free(rec->switch_output.filenames[n]);
|
|
|
|
}
|
|
|
|
rec->switch_output.filenames[n] = new_filename;
|
|
|
|
} else {
|
|
|
|
free(new_filename);
|
|
|
|
}
|
|
|
|
|
2016-04-21 02:59:50 +08:00
|
|
|
/* Output tracking events */
|
2016-04-21 02:59:54 +08:00
|
|
|
if (!at_exit) {
|
perf record: Add --tail-synthesize option
When working with overwritable ring buffer there's a inconvenience
problem: if perf dumps data after a long period after it starts,
non-sample events may lost, which makes following 'perf report' unable
to identify proc name and mmap layout. For example:
# perf record -m 4 -e raw_syscalls:* -g --overwrite --switch-output \
dd if=/dev/zero of=/dev/null
send SIGUSR2 after dd runs long enough. The resuling perf.data lost
correct comm and mmap events:
# perf script -i perf.data.2016061522374354
perf 24478 [004] 2581325.601789: raw_syscalls:sys_exit: NR 0 = 512
^^^^
Should be 'dd'
27b2e8 syscall_slow_exit_work+0xfe2000e3 (/lib/modules/4.6.0-rc3+/build/vmlinux)
203cc7 do_syscall_64+0xfe200117 (/lib/modules/4.6.0-rc3+/build/vmlinux)
b18d83 return_from_SYSCALL_64+0xfe200000 (/lib/modules/4.6.0-rc3+/build/vmlinux)
7f47c417edf0 [unknown] ([unknown])
^^^^^^^^^^^^
Fail to unwind
This patch provides a '--tail-synthesize' option, allows perf to collect
system status when finalizing output file. In resuling output file, the
non-sample events reflect system status when dumping data.
After this patch:
# perf record -m 4 -e raw_syscalls:* -g --overwrite --switch-output --tail-synthesize \
dd if=/dev/zero of=/dev/null
# perf script -i perf.data.2016061600544998
dd 27364 [004] 2583244.994464: raw_syscalls:sys_enter: NR 1 (1, ...
^^
Correct comm
203a18 syscall_trace_enter_phase2+0xfe2001a8 ([kernel.kallsyms])
203aa5 syscall_trace_enter+0xfe200055 ([kernel.kallsyms])
203caa do_syscall_64+0xfe2000fa ([kernel.kallsyms])
b18d83 return_from_SYSCALL_64+0xfe200000 ([kernel.kallsyms])
d8e50 __GI___libc_write+0xffff01d9639f4010 (/tmp/oxygen_root-w00229757/lib64/libc-2.18.so)
^^^^^
Correct unwind
This option doesn't aim to solve this problem completely. If a process
terminates before SIGUSR2, we still lost its COMM and MMAP events. For
example, we can't unwind correctly from the final perf.data we get from
the previous example, because when perf collects the final output file
(when we press C-c), 'dd' has been terminated so its '/proc/<pid>/mmap'
becomes empty.
However, this is a cheaper choice. To completely solve this problem we
need to continously output non-sample events. To satisify the
requirement of daemonization, we need to merge them periodically. It is
possible but requires much more code and cycles.
Automatically select --tail-synthesize when --overwrite is provided.
Signed-off-by: Wang Nan <wangnan0@huawei.com>
Cc: He Kuang <hekuang@huawei.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Masami Hiramatsu <mhiramat@kernel.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Nilay Vaish <nilayvaish@gmail.com>
Cc: Zefan Li <lizefan@huawei.com>
Cc: pi3orama@163.com
Link: http://lkml.kernel.org/r/1468485287-33422-16-git-send-email-wangnan0@huawei.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2016-07-14 16:34:47 +08:00
|
|
|
record__synthesize(rec, false);
|
2016-04-21 02:59:50 +08:00
|
|
|
|
2016-04-21 02:59:54 +08:00
|
|
|
/*
|
|
|
|
* In 'perf record --switch-output' without -a,
|
|
|
|
* record__synthesize() in record__switch_output() won't
|
|
|
|
* generate tracking events because there's no thread_map
|
|
|
|
* in evlist. Which causes newly created perf.data doesn't
|
|
|
|
* contain map and comm information.
|
|
|
|
* Create a fake thread_map and directly call
|
|
|
|
* perf_event__synthesize_thread_map() for those events.
|
|
|
|
*/
|
|
|
|
if (target__none(&rec->opts.target))
|
perf record: Add --tail-synthesize option
When working with overwritable ring buffer there's a inconvenience
problem: if perf dumps data after a long period after it starts,
non-sample events may lost, which makes following 'perf report' unable
to identify proc name and mmap layout. For example:
# perf record -m 4 -e raw_syscalls:* -g --overwrite --switch-output \
dd if=/dev/zero of=/dev/null
send SIGUSR2 after dd runs long enough. The resuling perf.data lost
correct comm and mmap events:
# perf script -i perf.data.2016061522374354
perf 24478 [004] 2581325.601789: raw_syscalls:sys_exit: NR 0 = 512
^^^^
Should be 'dd'
27b2e8 syscall_slow_exit_work+0xfe2000e3 (/lib/modules/4.6.0-rc3+/build/vmlinux)
203cc7 do_syscall_64+0xfe200117 (/lib/modules/4.6.0-rc3+/build/vmlinux)
b18d83 return_from_SYSCALL_64+0xfe200000 (/lib/modules/4.6.0-rc3+/build/vmlinux)
7f47c417edf0 [unknown] ([unknown])
^^^^^^^^^^^^
Fail to unwind
This patch provides a '--tail-synthesize' option, allows perf to collect
system status when finalizing output file. In resuling output file, the
non-sample events reflect system status when dumping data.
After this patch:
# perf record -m 4 -e raw_syscalls:* -g --overwrite --switch-output --tail-synthesize \
dd if=/dev/zero of=/dev/null
# perf script -i perf.data.2016061600544998
dd 27364 [004] 2583244.994464: raw_syscalls:sys_enter: NR 1 (1, ...
^^
Correct comm
203a18 syscall_trace_enter_phase2+0xfe2001a8 ([kernel.kallsyms])
203aa5 syscall_trace_enter+0xfe200055 ([kernel.kallsyms])
203caa do_syscall_64+0xfe2000fa ([kernel.kallsyms])
b18d83 return_from_SYSCALL_64+0xfe200000 ([kernel.kallsyms])
d8e50 __GI___libc_write+0xffff01d9639f4010 (/tmp/oxygen_root-w00229757/lib64/libc-2.18.so)
^^^^^
Correct unwind
This option doesn't aim to solve this problem completely. If a process
terminates before SIGUSR2, we still lost its COMM and MMAP events. For
example, we can't unwind correctly from the final perf.data we get from
the previous example, because when perf collects the final output file
(when we press C-c), 'dd' has been terminated so its '/proc/<pid>/mmap'
becomes empty.
However, this is a cheaper choice. To completely solve this problem we
need to continously output non-sample events. To satisify the
requirement of daemonization, we need to merge them periodically. It is
possible but requires much more code and cycles.
Automatically select --tail-synthesize when --overwrite is provided.
Signed-off-by: Wang Nan <wangnan0@huawei.com>
Cc: He Kuang <hekuang@huawei.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Masami Hiramatsu <mhiramat@kernel.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Nilay Vaish <nilayvaish@gmail.com>
Cc: Zefan Li <lizefan@huawei.com>
Cc: pi3orama@163.com
Link: http://lkml.kernel.org/r/1468485287-33422-16-git-send-email-wangnan0@huawei.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2016-07-14 16:34:47 +08:00
|
|
|
record__synthesize_workload(rec, false);
|
2016-04-21 02:59:54 +08:00
|
|
|
}
|
2016-04-13 16:21:07 +08:00
|
|
|
return fd;
|
|
|
|
}
|
|
|
|
|
2014-01-03 02:11:25 +08:00
|
|
|
static volatile int workload_exec_errno;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* perf_evlist__prepare_workload will send a SIGUSR1
|
|
|
|
* if the fork fails, since we asked by setting its
|
|
|
|
* want_signal to true.
|
|
|
|
*/
|
2014-05-12 08:47:24 +08:00
|
|
|
static void workload_exec_failed_signal(int signo __maybe_unused,
|
|
|
|
siginfo_t *info,
|
2014-01-03 02:11:25 +08:00
|
|
|
void *ucontext __maybe_unused)
|
|
|
|
{
|
|
|
|
workload_exec_errno = info->si_value.sival_int;
|
|
|
|
done = 1;
|
|
|
|
child_finished = 1;
|
|
|
|
}
|
|
|
|
|
2015-04-30 22:37:32 +08:00
|
|
|
static void snapshot_sig_handler(int sig);
|
2017-01-09 17:52:00 +08:00
|
|
|
static void alarm_sig_handler(int sig);
|
2015-04-30 22:37:32 +08:00
|
|
|
|
2016-03-08 16:38:44 +08:00
|
|
|
int __weak
|
|
|
|
perf_event__synth_time_conv(const struct perf_event_mmap_page *pc __maybe_unused,
|
|
|
|
struct perf_tool *tool __maybe_unused,
|
|
|
|
perf_event__handler_t process __maybe_unused,
|
|
|
|
struct machine *machine __maybe_unused)
|
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2016-06-27 18:24:05 +08:00
|
|
|
static const struct perf_event_mmap_page *
|
|
|
|
perf_evlist__pick_pc(struct perf_evlist *evlist)
|
|
|
|
{
|
2016-07-14 16:34:39 +08:00
|
|
|
if (evlist) {
|
|
|
|
if (evlist->mmap && evlist->mmap[0].base)
|
|
|
|
return evlist->mmap[0].base;
|
2017-12-05 00:51:07 +08:00
|
|
|
if (evlist->overwrite_mmap && evlist->overwrite_mmap[0].base)
|
|
|
|
return evlist->overwrite_mmap[0].base;
|
2016-07-14 16:34:39 +08:00
|
|
|
}
|
2016-06-27 18:24:05 +08:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2016-05-24 10:28:59 +08:00
|
|
|
static const struct perf_event_mmap_page *record__pick_pc(struct record *rec)
|
|
|
|
{
|
2016-06-27 18:24:05 +08:00
|
|
|
const struct perf_event_mmap_page *pc;
|
|
|
|
|
|
|
|
pc = perf_evlist__pick_pc(rec->evlist);
|
|
|
|
if (pc)
|
|
|
|
return pc;
|
2016-05-24 10:28:59 +08:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
perf record: Add --tail-synthesize option
When working with overwritable ring buffer there's a inconvenience
problem: if perf dumps data after a long period after it starts,
non-sample events may lost, which makes following 'perf report' unable
to identify proc name and mmap layout. For example:
# perf record -m 4 -e raw_syscalls:* -g --overwrite --switch-output \
dd if=/dev/zero of=/dev/null
send SIGUSR2 after dd runs long enough. The resuling perf.data lost
correct comm and mmap events:
# perf script -i perf.data.2016061522374354
perf 24478 [004] 2581325.601789: raw_syscalls:sys_exit: NR 0 = 512
^^^^
Should be 'dd'
27b2e8 syscall_slow_exit_work+0xfe2000e3 (/lib/modules/4.6.0-rc3+/build/vmlinux)
203cc7 do_syscall_64+0xfe200117 (/lib/modules/4.6.0-rc3+/build/vmlinux)
b18d83 return_from_SYSCALL_64+0xfe200000 (/lib/modules/4.6.0-rc3+/build/vmlinux)
7f47c417edf0 [unknown] ([unknown])
^^^^^^^^^^^^
Fail to unwind
This patch provides a '--tail-synthesize' option, allows perf to collect
system status when finalizing output file. In resuling output file, the
non-sample events reflect system status when dumping data.
After this patch:
# perf record -m 4 -e raw_syscalls:* -g --overwrite --switch-output --tail-synthesize \
dd if=/dev/zero of=/dev/null
# perf script -i perf.data.2016061600544998
dd 27364 [004] 2583244.994464: raw_syscalls:sys_enter: NR 1 (1, ...
^^
Correct comm
203a18 syscall_trace_enter_phase2+0xfe2001a8 ([kernel.kallsyms])
203aa5 syscall_trace_enter+0xfe200055 ([kernel.kallsyms])
203caa do_syscall_64+0xfe2000fa ([kernel.kallsyms])
b18d83 return_from_SYSCALL_64+0xfe200000 ([kernel.kallsyms])
d8e50 __GI___libc_write+0xffff01d9639f4010 (/tmp/oxygen_root-w00229757/lib64/libc-2.18.so)
^^^^^
Correct unwind
This option doesn't aim to solve this problem completely. If a process
terminates before SIGUSR2, we still lost its COMM and MMAP events. For
example, we can't unwind correctly from the final perf.data we get from
the previous example, because when perf collects the final output file
(when we press C-c), 'dd' has been terminated so its '/proc/<pid>/mmap'
becomes empty.
However, this is a cheaper choice. To completely solve this problem we
need to continously output non-sample events. To satisify the
requirement of daemonization, we need to merge them periodically. It is
possible but requires much more code and cycles.
Automatically select --tail-synthesize when --overwrite is provided.
Signed-off-by: Wang Nan <wangnan0@huawei.com>
Cc: He Kuang <hekuang@huawei.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Masami Hiramatsu <mhiramat@kernel.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Nilay Vaish <nilayvaish@gmail.com>
Cc: Zefan Li <lizefan@huawei.com>
Cc: pi3orama@163.com
Link: http://lkml.kernel.org/r/1468485287-33422-16-git-send-email-wangnan0@huawei.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2016-07-14 16:34:47 +08:00
|
|
|
static int record__synthesize(struct record *rec, bool tail)
|
2016-02-26 17:32:07 +08:00
|
|
|
{
|
|
|
|
struct perf_session *session = rec->session;
|
|
|
|
struct machine *machine = &session->machines.host;
|
2017-01-24 05:07:59 +08:00
|
|
|
struct perf_data *data = &rec->data;
|
2016-02-26 17:32:07 +08:00
|
|
|
struct record_opts *opts = &rec->opts;
|
|
|
|
struct perf_tool *tool = &rec->tool;
|
2017-01-24 05:07:59 +08:00
|
|
|
int fd = perf_data__fd(data);
|
2016-02-26 17:32:07 +08:00
|
|
|
int err = 0;
|
|
|
|
|
perf record: Add --tail-synthesize option
When working with overwritable ring buffer there's a inconvenience
problem: if perf dumps data after a long period after it starts,
non-sample events may lost, which makes following 'perf report' unable
to identify proc name and mmap layout. For example:
# perf record -m 4 -e raw_syscalls:* -g --overwrite --switch-output \
dd if=/dev/zero of=/dev/null
send SIGUSR2 after dd runs long enough. The resuling perf.data lost
correct comm and mmap events:
# perf script -i perf.data.2016061522374354
perf 24478 [004] 2581325.601789: raw_syscalls:sys_exit: NR 0 = 512
^^^^
Should be 'dd'
27b2e8 syscall_slow_exit_work+0xfe2000e3 (/lib/modules/4.6.0-rc3+/build/vmlinux)
203cc7 do_syscall_64+0xfe200117 (/lib/modules/4.6.0-rc3+/build/vmlinux)
b18d83 return_from_SYSCALL_64+0xfe200000 (/lib/modules/4.6.0-rc3+/build/vmlinux)
7f47c417edf0 [unknown] ([unknown])
^^^^^^^^^^^^
Fail to unwind
This patch provides a '--tail-synthesize' option, allows perf to collect
system status when finalizing output file. In resuling output file, the
non-sample events reflect system status when dumping data.
After this patch:
# perf record -m 4 -e raw_syscalls:* -g --overwrite --switch-output --tail-synthesize \
dd if=/dev/zero of=/dev/null
# perf script -i perf.data.2016061600544998
dd 27364 [004] 2583244.994464: raw_syscalls:sys_enter: NR 1 (1, ...
^^
Correct comm
203a18 syscall_trace_enter_phase2+0xfe2001a8 ([kernel.kallsyms])
203aa5 syscall_trace_enter+0xfe200055 ([kernel.kallsyms])
203caa do_syscall_64+0xfe2000fa ([kernel.kallsyms])
b18d83 return_from_SYSCALL_64+0xfe200000 ([kernel.kallsyms])
d8e50 __GI___libc_write+0xffff01d9639f4010 (/tmp/oxygen_root-w00229757/lib64/libc-2.18.so)
^^^^^
Correct unwind
This option doesn't aim to solve this problem completely. If a process
terminates before SIGUSR2, we still lost its COMM and MMAP events. For
example, we can't unwind correctly from the final perf.data we get from
the previous example, because when perf collects the final output file
(when we press C-c), 'dd' has been terminated so its '/proc/<pid>/mmap'
becomes empty.
However, this is a cheaper choice. To completely solve this problem we
need to continously output non-sample events. To satisify the
requirement of daemonization, we need to merge them periodically. It is
possible but requires much more code and cycles.
Automatically select --tail-synthesize when --overwrite is provided.
Signed-off-by: Wang Nan <wangnan0@huawei.com>
Cc: He Kuang <hekuang@huawei.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Masami Hiramatsu <mhiramat@kernel.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Nilay Vaish <nilayvaish@gmail.com>
Cc: Zefan Li <lizefan@huawei.com>
Cc: pi3orama@163.com
Link: http://lkml.kernel.org/r/1468485287-33422-16-git-send-email-wangnan0@huawei.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2016-07-14 16:34:47 +08:00
|
|
|
if (rec->opts.tail_synthesize != tail)
|
|
|
|
return 0;
|
|
|
|
|
2017-01-24 05:07:59 +08:00
|
|
|
if (data->is_pipe) {
|
2018-03-14 17:22:04 +08:00
|
|
|
/*
|
|
|
|
* We need to synthesize events first, because some
|
|
|
|
* features works on top of them (on report side).
|
|
|
|
*/
|
2018-08-30 14:32:15 +08:00
|
|
|
err = perf_event__synthesize_attrs(tool, rec->evlist,
|
2016-02-26 17:32:07 +08:00
|
|
|
process_synthesized_event);
|
|
|
|
if (err < 0) {
|
|
|
|
pr_err("Couldn't synthesize attrs.\n");
|
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
|
2018-03-14 17:22:04 +08:00
|
|
|
err = perf_event__synthesize_features(tool, session, rec->evlist,
|
|
|
|
process_synthesized_event);
|
|
|
|
if (err < 0) {
|
|
|
|
pr_err("Couldn't synthesize features.\n");
|
|
|
|
return err;
|
|
|
|
}
|
|
|
|
|
2016-02-26 17:32:07 +08:00
|
|
|
if (have_tracepoints(&rec->evlist->entries)) {
|
|
|
|
/*
|
|
|
|
* FIXME err <= 0 here actually means that
|
|
|
|
* there were no tracepoints so its not really
|
|
|
|
* an error, just that we don't need to
|
|
|
|
* synthesize anything. We really have to
|
|
|
|
* return this more properly and also
|
|
|
|
* propagate errors that now are calling die()
|
|
|
|
*/
|
|
|
|
err = perf_event__synthesize_tracing_data(tool, fd, rec->evlist,
|
|
|
|
process_synthesized_event);
|
|
|
|
if (err <= 0) {
|
|
|
|
pr_err("Couldn't record tracing data.\n");
|
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
rec->bytes_written += err;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-05-24 10:28:59 +08:00
|
|
|
err = perf_event__synth_time_conv(record__pick_pc(rec), tool,
|
2016-03-08 16:38:44 +08:00
|
|
|
process_synthesized_event, machine);
|
|
|
|
if (err)
|
|
|
|
goto out;
|
|
|
|
|
2016-02-26 17:32:07 +08:00
|
|
|
if (rec->opts.full_auxtrace) {
|
|
|
|
err = perf_event__synthesize_auxtrace_info(rec->itr, tool,
|
|
|
|
session, process_synthesized_event);
|
|
|
|
if (err)
|
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
|
perf record: Ignore kptr_restrict when not sampling the kernel
If we're not sampling the kernel, we shouldn't care about kptr_restrict
neither synthesize anything for assisting in resolving kernel samples,
like the reference relocation symbol or kernel modules information.
Before:
$ cat /proc/sys/kernel/kptr_restrict /proc/sys/kernel/perf_event_paranoid
2
2
$ perf record sleep 1
WARNING: Kernel address maps (/proc/{kallsyms,modules}) are restricted,
check /proc/sys/kernel/kptr_restrict.
Samples in kernel functions may not be resolved if a suitable vmlinux
file is not found in the buildid cache or in the vmlinux path.
Samples in kernel modules won't be resolved at all.
If some relocation was applied (e.g. kexec) symbols may be misresolved
even with a suitable vmlinux or kallsyms file.
Couldn't record kernel reference relocation symbol
Symbol resolution may be skewed if relocation was used (e.g. kexec).
Check /proc/kallsyms permission or run as root.
[ perf record: Woken up 1 times to write data ]
[ perf record: Captured and wrote 0.001 MB perf.data (8 samples) ]
$ perf evlist -v
cycles:uppp: size: 112, { sample_period, sample_freq }: 4000, sample_type: IP|TID|TIME|PERIOD, disabled: 1, inherit: 1, exclude_kernel: 1, mmap: 1, comm: 1, freq: 1, enable_on_exec: 1, task: 1, precise_ip: 3, sample_id_all: 1, exclude_guest: 1, mmap2: 1, comm_exec: 1
$
After:
$ perf record sleep 1
[ perf record: Woken up 1 times to write data ]
[ perf record: Captured and wrote 0.001 MB perf.data (10 samples) ]
$
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Wang Nan <wangnan0@huawei.com>
Link: http://lkml.kernel.org/n/tip-t025e9zftbx2b8cq2w01g5e5@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2017-11-14 22:03:19 +08:00
|
|
|
if (!perf_evlist__exclude_kernel(rec->evlist)) {
|
|
|
|
err = perf_event__synthesize_kernel_mmap(tool, process_synthesized_event,
|
|
|
|
machine);
|
|
|
|
WARN_ONCE(err < 0, "Couldn't record kernel reference relocation symbol\n"
|
|
|
|
"Symbol resolution may be skewed if relocation was used (e.g. kexec).\n"
|
|
|
|
"Check /proc/kallsyms permission or run as root.\n");
|
|
|
|
|
|
|
|
err = perf_event__synthesize_modules(tool, process_synthesized_event,
|
|
|
|
machine);
|
|
|
|
WARN_ONCE(err < 0, "Couldn't record kernel module information.\n"
|
|
|
|
"Symbol resolution may be skewed if relocation was used (e.g. kexec).\n"
|
|
|
|
"Check /proc/modules permission or run as root.\n");
|
|
|
|
}
|
2016-02-26 17:32:07 +08:00
|
|
|
|
|
|
|
if (perf_guest) {
|
|
|
|
machines__process_guests(&session->machines,
|
|
|
|
perf_event__synthesize_guest_os, tool);
|
|
|
|
}
|
|
|
|
|
2017-11-18 05:42:58 +08:00
|
|
|
err = perf_event__synthesize_extra_attr(&rec->tool,
|
|
|
|
rec->evlist,
|
|
|
|
process_synthesized_event,
|
|
|
|
data->is_pipe);
|
|
|
|
if (err)
|
|
|
|
goto out;
|
|
|
|
|
2017-11-18 05:42:59 +08:00
|
|
|
err = perf_event__synthesize_thread_map2(&rec->tool, rec->evlist->threads,
|
|
|
|
process_synthesized_event,
|
|
|
|
NULL);
|
|
|
|
if (err < 0) {
|
|
|
|
pr_err("Couldn't synthesize thread map.\n");
|
|
|
|
return err;
|
|
|
|
}
|
|
|
|
|
|
|
|
err = perf_event__synthesize_cpu_map(&rec->tool, rec->evlist->cpus,
|
|
|
|
process_synthesized_event, NULL);
|
|
|
|
if (err < 0) {
|
|
|
|
pr_err("Couldn't synthesize cpu map.\n");
|
|
|
|
return err;
|
|
|
|
}
|
|
|
|
|
2019-03-12 13:30:41 +08:00
|
|
|
err = perf_event__synthesize_bpf_events(session, process_synthesized_event,
|
perf tools: Synthesize PERF_RECORD_* for loaded BPF programs
This patch synthesize PERF_RECORD_KSYMBOL and PERF_RECORD_BPF_EVENT for
BPF programs loaded before perf-record. This is achieved by gathering
information about all BPF programs via sys_bpf.
Committer notes:
Fix the build on some older systems such as amazonlinux:1 where it was
breaking with:
util/bpf-event.c: In function 'perf_event__synthesize_one_bpf_prog':
util/bpf-event.c:52:9: error: missing initializer for field 'type' of 'struct bpf_prog_info' [-Werror=missing-field-initializers]
struct bpf_prog_info info = {};
^
In file included from /git/linux/tools/lib/bpf/bpf.h:26:0,
from util/bpf-event.c:3:
/git/linux/tools/include/uapi/linux/bpf.h:2699:8: note: 'type' declared here
__u32 type;
^
cc1: all warnings being treated as errors
Further fix on a centos:6 system:
cc1: warnings being treated as errors
util/bpf-event.c: In function 'perf_event__synthesize_one_bpf_prog':
util/bpf-event.c:50: error: 'func_info_rec_size' may be used uninitialized in this function
The compiler is wrong, but to silence it, initialize that variable to
zero.
One more fix, this time for debian:experimental-x-mips, x-mips64 and
x-mipsel:
util/bpf-event.c: In function 'perf_event__synthesize_one_bpf_prog':
util/bpf-event.c:93:16: error: implicit declaration of function 'calloc' [-Werror=implicit-function-declaration]
func_infos = calloc(sub_prog_cnt, func_info_rec_size);
^~~~~~
util/bpf-event.c:93:16: error: incompatible implicit declaration of built-in function 'calloc' [-Werror]
util/bpf-event.c:93:16: note: include '<stdlib.h>' or provide a declaration of 'calloc'
Add the missing header.
Committer testing:
# perf record --bpf-event sleep 1
[ perf record: Woken up 1 times to write data ]
[ perf record: Captured and wrote 0.021 MB perf.data (7 samples) ]
# perf report -D | grep PERF_RECORD_BPF_EVENT | nl
1 0 0x4b10 [0x18]: PERF_RECORD_BPF_EVENT bpf event with type 1, flags 0, id 13
2 0 0x4c60 [0x18]: PERF_RECORD_BPF_EVENT bpf event with type 1, flags 0, id 14
3 0 0x4db0 [0x18]: PERF_RECORD_BPF_EVENT bpf event with type 1, flags 0, id 15
4 0 0x4f00 [0x18]: PERF_RECORD_BPF_EVENT bpf event with type 1, flags 0, id 16
5 0 0x5050 [0x18]: PERF_RECORD_BPF_EVENT bpf event with type 1, flags 0, id 17
6 0 0x51a0 [0x18]: PERF_RECORD_BPF_EVENT bpf event with type 1, flags 0, id 18
7 0 0x52f0 [0x18]: PERF_RECORD_BPF_EVENT bpf event with type 1, flags 0, id 21
8 0 0x5440 [0x18]: PERF_RECORD_BPF_EVENT bpf event with type 1, flags 0, id 22
# bpftool prog
13: cgroup_skb tag 7be49e3934a125ba gpl
loaded_at 2019-01-19T09:09:43-0300 uid 0
xlated 296B jited 229B memlock 4096B map_ids 13,14
14: cgroup_skb tag 2a142ef67aaad174 gpl
loaded_at 2019-01-19T09:09:43-0300 uid 0
xlated 296B jited 229B memlock 4096B map_ids 13,14
15: cgroup_skb tag 7be49e3934a125ba gpl
loaded_at 2019-01-19T09:09:43-0300 uid 0
xlated 296B jited 229B memlock 4096B map_ids 15,16
16: cgroup_skb tag 2a142ef67aaad174 gpl
loaded_at 2019-01-19T09:09:43-0300 uid 0
xlated 296B jited 229B memlock 4096B map_ids 15,16
17: cgroup_skb tag 7be49e3934a125ba gpl
loaded_at 2019-01-19T09:09:44-0300 uid 0
xlated 296B jited 229B memlock 4096B map_ids 17,18
18: cgroup_skb tag 2a142ef67aaad174 gpl
loaded_at 2019-01-19T09:09:44-0300 uid 0
xlated 296B jited 229B memlock 4096B map_ids 17,18
21: cgroup_skb tag 7be49e3934a125ba gpl
loaded_at 2019-01-19T09:09:45-0300 uid 0
xlated 296B jited 229B memlock 4096B map_ids 21,22
22: cgroup_skb tag 2a142ef67aaad174 gpl
loaded_at 2019-01-19T09:09:45-0300 uid 0
xlated 296B jited 229B memlock 4096B map_ids 21,22
#
# perf report -D | grep -B22 PERF_RECORD_KSYMBOL
. ... raw event: size 312 bytes
. 0000: 11 00 00 00 00 00 38 01 ff 44 06 c0 ff ff ff ff ......8..D......
. 0010: e5 00 00 00 01 00 00 00 62 70 66 5f 70 72 6f 67 ........bpf_prog
. 0020: 5f 37 62 65 34 39 65 33 39 33 34 61 31 32 35 62 _7be49e3934a125b
. 0030: 61 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 a...............
<SNIP zeroes>
. 0110: 00 00 00 00 00 00 00 00 21 00 00 00 00 00 00 00 ........!.......
. 0120: 7b e4 9e 39 34 a1 25 ba 00 00 00 00 00 00 00 00 {..94.%.........
. 0130: 00 00 00 00 00 00 00 00 ........
0 0x49d8 [0x138]: PERF_RECORD_KSYMBOL ksymbol event with addr ffffffffc00644ff len 229 type 1 flags 0x0 name bpf_prog_7be49e3934a125ba
--
. ... raw event: size 312 bytes
. 0000: 11 00 00 00 00 00 38 01 48 6d 06 c0 ff ff ff ff ......8.Hm......
. 0010: e5 00 00 00 01 00 00 00 62 70 66 5f 70 72 6f 67 ........bpf_prog
. 0020: 5f 32 61 31 34 32 65 66 36 37 61 61 61 64 31 37 _2a142ef67aaad17
. 0030: 34 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 4...............
<SNIP zeroes>
. 0110: 00 00 00 00 00 00 00 00 21 00 00 00 00 00 00 00 ........!.......
. 0120: 2a 14 2e f6 7a aa d1 74 00 00 00 00 00 00 00 00 *...z..t........
. 0130: 00 00 00 00 00 00 00 00 ........
0 0x4b28 [0x138]: PERF_RECORD_KSYMBOL ksymbol event with addr ffffffffc0066d48 len 229 type 1 flags 0x0 name bpf_prog_2a142ef67aaad174
--
. ... raw event: size 312 bytes
. 0000: 11 00 00 00 00 00 38 01 04 cf 03 c0 ff ff ff ff ......8.........
. 0010: e5 00 00 00 01 00 00 00 62 70 66 5f 70 72 6f 67 ........bpf_prog
. 0020: 5f 37 62 65 34 39 65 33 39 33 34 61 31 32 35 62 _7be49e3934a125b
. 0030: 61 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 a...............
<SNIP zeroes>
. 0110: 00 00 00 00 00 00 00 00 21 00 00 00 00 00 00 00 ........!.......
. 0120: 7b e4 9e 39 34 a1 25 ba 00 00 00 00 00 00 00 00 {..94.%.........
. 0130: 00 00 00 00 00 00 00 00 ........
0 0x4c78 [0x138]: PERF_RECORD_KSYMBOL ksymbol event with addr ffffffffc003cf04 len 229 type 1 flags 0x0 name bpf_prog_7be49e3934a125ba
--
. ... raw event: size 312 bytes
. 0000: 11 00 00 00 00 00 38 01 96 28 04 c0 ff ff ff ff ......8..(......
. 0010: e5 00 00 00 01 00 00 00 62 70 66 5f 70 72 6f 67 ........bpf_prog
. 0020: 5f 32 61 31 34 32 65 66 36 37 61 61 61 64 31 37 _2a142ef67aaad17
. 0030: 34 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 4...............
<SNIP zeroes>
. 0110: 00 00 00 00 00 00 00 00 21 00 00 00 00 00 00 00 ........!.......
. 0120: 2a 14 2e f6 7a aa d1 74 00 00 00 00 00 00 00 00 *...z..t........
. 0130: 00 00 00 00 00 00 00 00 ........
0 0x4dc8 [0x138]: PERF_RECORD_KSYMBOL ksymbol event with addr ffffffffc0042896 len 229 type 1 flags 0x0 name bpf_prog_2a142ef67aaad174
--
. ... raw event: size 312 bytes
. 0000: 11 00 00 00 00 00 38 01 05 13 17 c0 ff ff ff ff ......8.........
. 0010: e5 00 00 00 01 00 00 00 62 70 66 5f 70 72 6f 67 ........bpf_prog
. 0020: 5f 37 62 65 34 39 65 33 39 33 34 61 31 32 35 62 _7be49e3934a125b
. 0030: 61 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 a...............
<SNIP zeroes>
. 0110: 00 00 00 00 00 00 00 00 21 00 00 00 00 00 00 00 ........!.......
. 0120: 7b e4 9e 39 34 a1 25 ba 00 00 00 00 00 00 00 00 {..94.%.........
. 0130: 00 00 00 00 00 00 00 00 ........
0 0x4f18 [0x138]: PERF_RECORD_KSYMBOL ksymbol event with addr ffffffffc0171305 len 229 type 1 flags 0x0 name bpf_prog_7be49e3934a125ba
--
. ... raw event: size 312 bytes
. 0000: 11 00 00 00 00 00 38 01 0a 8c 23 c0 ff ff ff ff ......8...#.....
. 0010: e5 00 00 00 01 00 00 00 62 70 66 5f 70 72 6f 67 ........bpf_prog
. 0020: 5f 32 61 31 34 32 65 66 36 37 61 61 61 64 31 37 _2a142ef67aaad17
. 0030: 34 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 4...............
<SNIP zeroes>
. 0110: 00 00 00 00 00 00 00 00 21 00 00 00 00 00 00 00 ........!.......
. 0120: 2a 14 2e f6 7a aa d1 74 00 00 00 00 00 00 00 00 *...z..t........
. 0130: 00 00 00 00 00 00 00 00 ........
0 0x5068 [0x138]: PERF_RECORD_KSYMBOL ksymbol event with addr ffffffffc0238c0a len 229 type 1 flags 0x0 name bpf_prog_2a142ef67aaad174
--
. ... raw event: size 312 bytes
. 0000: 11 00 00 00 00 00 38 01 2a a5 a4 c0 ff ff ff ff ......8.*.......
. 0010: e5 00 00 00 01 00 00 00 62 70 66 5f 70 72 6f 67 ........bpf_prog
. 0020: 5f 37 62 65 34 39 65 33 39 33 34 61 31 32 35 62 _7be49e3934a125b
. 0030: 61 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 a...............
<SNIP zeroes>
. 0110: 00 00 00 00 00 00 00 00 21 00 00 00 00 00 00 00 ........!.......
. 0120: 7b e4 9e 39 34 a1 25 ba 00 00 00 00 00 00 00 00 {..94.%.........
. 0130: 00 00 00 00 00 00 00 00 ........
0 0x51b8 [0x138]: PERF_RECORD_KSYMBOL ksymbol event with addr ffffffffc0a4a52a len 229 type 1 flags 0x0 name bpf_prog_7be49e3934a125ba
--
. ... raw event: size 312 bytes
. 0000: 11 00 00 00 00 00 38 01 9b c9 a4 c0 ff ff ff ff ......8.........
. 0010: e5 00 00 00 01 00 00 00 62 70 66 5f 70 72 6f 67 ........bpf_prog
. 0020: 5f 32 61 31 34 32 65 66 36 37 61 61 61 64 31 37 _2a142ef67aaad17
. 0030: 34 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 4...............
<SNIP zeroes>
. 0110: 00 00 00 00 00 00 00 00 21 00 00 00 00 00 00 00 ........!.......
. 0120: 2a 14 2e f6 7a aa d1 74 00 00 00 00 00 00 00 00 *...z..t........
. 0130: 00 00 00 00 00 00 00 00 ........
0 0x5308 [0x138]: PERF_RECORD_KSYMBOL ksymbol event with addr ffffffffc0a4c99b len 229 type 1 flags 0x0 name bpf_prog_2a142ef67aaad174
Signed-off-by: Song Liu <songliubraving@fb.com>
Reviewed-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Alexei Starovoitov <ast@kernel.org>
Cc: Daniel Borkmann <daniel@iogearbox.net>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: kernel-team@fb.com
Cc: netdev@vger.kernel.org
Link: http://lkml.kernel.org/r/20190117161521.1341602-8-songliubraving@fb.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2019-01-18 00:15:19 +08:00
|
|
|
machine, opts);
|
|
|
|
if (err < 0)
|
|
|
|
pr_warning("Couldn't synthesize bpf events.\n");
|
|
|
|
|
2016-02-26 17:32:07 +08:00
|
|
|
err = __machine__synthesize_threads(machine, tool, &opts->target, rec->evlist->threads,
|
|
|
|
process_synthesized_event, opts->sample_address,
|
2018-12-05 04:34:20 +08:00
|
|
|
1);
|
2016-02-26 17:32:07 +08:00
|
|
|
out:
|
|
|
|
return err;
|
|
|
|
}
|
|
|
|
|
2013-12-20 01:38:03 +08:00
|
|
|
static int __cmd_record(struct record *rec, int argc, const char **argv)
|
2009-05-05 23:50:27 +08:00
|
|
|
{
|
2013-11-07 02:41:34 +08:00
|
|
|
int err;
|
2014-05-12 08:47:24 +08:00
|
|
|
int status = 0;
|
2009-09-18 01:59:05 +08:00
|
|
|
unsigned long waking = 0;
|
2010-03-18 22:36:04 +08:00
|
|
|
const bool forks = argc > 0;
|
2011-11-28 18:30:20 +08:00
|
|
|
struct perf_tool *tool = &rec->tool;
|
2013-12-20 01:43:45 +08:00
|
|
|
struct record_opts *opts = &rec->opts;
|
2017-01-24 05:07:59 +08:00
|
|
|
struct perf_data *data = &rec->data;
|
2011-11-25 18:19:45 +08:00
|
|
|
struct perf_session *session;
|
2014-08-13 22:33:59 +08:00
|
|
|
bool disabled = false, draining = false;
|
2015-01-29 16:06:48 +08:00
|
|
|
int fd;
|
2009-04-08 21:01:31 +08:00
|
|
|
|
2014-05-12 08:47:24 +08:00
|
|
|
atexit(record__sig_exit);
|
2009-06-19 05:22:55 +08:00
|
|
|
signal(SIGCHLD, sig_handler);
|
|
|
|
signal(SIGINT, sig_handler);
|
2013-05-07 02:24:23 +08:00
|
|
|
signal(SIGTERM, sig_handler);
|
2016-11-26 15:03:28 +08:00
|
|
|
signal(SIGSEGV, sigsegv_handler);
|
2016-04-13 16:21:06 +08:00
|
|
|
|
perf tools: Add PERF_RECORD_NAMESPACES to include namespaces related info
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>
#
Signed-off-by: Hari Bathini <hbathini@linux.vnet.ibm.com>
Acked-by: Jiri Olsa <jolsa@kernel.org>
Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Alexei Starovoitov <ast@fb.com>
Cc: Ananth N Mavinakayanahalli <ananth@linux.vnet.ibm.com>
Cc: Aravinda Prasad <aravinda@linux.vnet.ibm.com>
Cc: Brendan Gregg <brendan.d.gregg@gmail.com>
Cc: Daniel Borkmann <daniel@iogearbox.net>
Cc: Eric Biederman <ebiederm@xmission.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Sargun Dhillon <sargun@sargun.me>
Cc: Steven Rostedt <rostedt@goodmis.org>
Link: http://lkml.kernel.org/r/148891930386.25309.18412039920746995488.stgit@hbathini.in.ibm.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2017-03-08 04:41:43 +08:00
|
|
|
if (rec->opts.record_namespaces)
|
|
|
|
tool->namespace_events = true;
|
|
|
|
|
2017-01-09 17:51:58 +08:00
|
|
|
if (rec->opts.auxtrace_snapshot_mode || rec->switch_output.enabled) {
|
2015-04-30 22:37:32 +08:00
|
|
|
signal(SIGUSR2, snapshot_sig_handler);
|
2016-04-21 02:59:50 +08:00
|
|
|
if (rec->opts.auxtrace_snapshot_mode)
|
|
|
|
trigger_on(&auxtrace_snapshot_trigger);
|
2017-01-09 17:51:58 +08:00
|
|
|
if (rec->switch_output.enabled)
|
2016-04-21 02:59:50 +08:00
|
|
|
trigger_on(&switch_output_trigger);
|
2016-04-13 16:21:06 +08:00
|
|
|
} else {
|
2015-04-30 22:37:32 +08:00
|
|
|
signal(SIGUSR2, SIG_IGN);
|
2016-04-13 16:21:06 +08:00
|
|
|
}
|
2009-06-19 05:22:55 +08:00
|
|
|
|
2017-01-24 05:07:59 +08:00
|
|
|
session = perf_session__new(data, false, tool);
|
2009-12-12 07:24:02 +08:00
|
|
|
if (session == NULL) {
|
2014-04-18 10:00:43 +08:00
|
|
|
pr_err("Perf session creation failed.\n");
|
2009-11-17 11:18:11 +08:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2017-01-24 05:07:59 +08:00
|
|
|
fd = perf_data__fd(data);
|
2011-11-25 18:19:45 +08:00
|
|
|
rec->session = session;
|
|
|
|
|
2013-12-20 01:38:03 +08:00
|
|
|
record__init_features(rec);
|
2012-03-09 06:47:46 +08:00
|
|
|
|
perf record: Encode -k clockid frequency into Perf trace
Store -k clockid frequency into Perf trace to enable timestamps
derived metrics conversion into wall clock time on reporting stage.
Below is the example of perf report output:
tools/perf/perf record -k raw -- ../../matrix/linux/matrix.gcc
...
[ perf record: Captured and wrote 31.222 MB perf.data (818054 samples) ]
tools/perf/perf report --header
# ========
...
# event : name = cycles:ppp, , size = 112, { sample_period, sample_freq } = 4000, sample_type = IP|TID|TIME|PERIOD, disabled = 1, inherit = 1, mmap = 1, comm = 1, freq = 1, enable_on_exec = 1, task = 1, precise_ip = 3, sample_id_all = 1, exclude_guest = 1, mmap2 = 1, comm_exec = 1, use_clockid = 1, clockid = 4
...
# clockid frequency: 1000 MHz
...
# ========
Signed-off-by: Alexey Budankov <alexey.budankov@linux.intel.com>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Andi Kleen <ak@linux.intel.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Link: http://lkml.kernel.org/r/23a4a1dc-b160-85a0-347d-40a2ed6d007b@linux.intel.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2018-10-09 22:36:24 +08:00
|
|
|
if (rec->opts.use_clockid && rec->opts.clockid_res_ns)
|
|
|
|
session->header.env.clockid_res_ns = rec->opts.clockid_res_ns;
|
|
|
|
|
2009-12-28 07:36:57 +08:00
|
|
|
if (forks) {
|
2014-01-04 02:03:26 +08:00
|
|
|
err = perf_evlist__prepare_workload(rec->evlist, &opts->target,
|
2017-01-24 05:07:59 +08:00
|
|
|
argv, data->is_pipe,
|
2014-01-04 01:56:49 +08:00
|
|
|
workload_exec_failed_signal);
|
2011-11-09 18:47:15 +08:00
|
|
|
if (err < 0) {
|
|
|
|
pr_err("Couldn't run the workload!\n");
|
2014-05-12 08:47:24 +08:00
|
|
|
status = err;
|
2011-11-09 18:47:15 +08:00
|
|
|
goto out_delete_session;
|
2009-12-17 00:55:55 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-03-03 00:13:54 +08:00
|
|
|
/*
|
|
|
|
* If we have just single event and are sending data
|
|
|
|
* through pipe, we need to force the ids allocation,
|
|
|
|
* because we synthesize event name through the pipe
|
|
|
|
* and need the id for that.
|
|
|
|
*/
|
|
|
|
if (data->is_pipe && rec->evlist->nr_entries == 1)
|
|
|
|
rec->opts.sample_id = true;
|
|
|
|
|
2013-12-20 01:38:03 +08:00
|
|
|
if (record__open(rec) != 0) {
|
2012-08-27 02:24:47 +08:00
|
|
|
err = -1;
|
2014-05-12 08:47:24 +08:00
|
|
|
goto out_child;
|
2012-08-27 02:24:47 +08:00
|
|
|
}
|
2009-04-08 21:01:31 +08:00
|
|
|
|
perf record: Apply config to BPF objects before recording
bpf__apply_obj_config() is introduced as the core API to apply object
config options to all BPF objects. This patch also does the real work
for setting values for BPF_MAP_TYPE_PERF_ARRAY maps by inserting value
stored in map's private field into the BPF map.
This patch is required because we are not always able to set all BPF
config during parsing. Further patch will set events created by perf to
BPF_MAP_TYPE_PERF_EVENT_ARRAY maps, which is not exist until
perf_evsel__open().
bpf_map_foreach_key() is introduced to iterate over each key needs to be
configured. This function would be extended to support more map types
and different key settings.
In perf record, before start recording, call bpf__apply_config() to turn
on all BPF config options.
Test result:
# cat ./test_bpf_map_1.c
/************************ BEGIN **************************/
#include <uapi/linux/bpf.h>
#define SEC(NAME) __attribute__((section(NAME), used))
struct bpf_map_def {
unsigned int type;
unsigned int key_size;
unsigned int value_size;
unsigned int max_entries;
};
static void *(*map_lookup_elem)(struct bpf_map_def *, void *) =
(void *)BPF_FUNC_map_lookup_elem;
static int (*trace_printk)(const char *fmt, int fmt_size, ...) =
(void *)BPF_FUNC_trace_printk;
struct bpf_map_def SEC("maps") channel = {
.type = BPF_MAP_TYPE_ARRAY,
.key_size = sizeof(int),
.value_size = sizeof(int),
.max_entries = 1,
};
SEC("func=sys_nanosleep")
int func(void *ctx)
{
int key = 0;
char fmt[] = "%d\n";
int *pval = map_lookup_elem(&channel, &key);
if (!pval)
return 0;
trace_printk(fmt, sizeof(fmt), *pval);
return 0;
}
char _license[] SEC("license") = "GPL";
int _version SEC("version") = LINUX_VERSION_CODE;
/************************* END ***************************/
# echo "" > /sys/kernel/debug/tracing/trace
# ./perf record -e './test_bpf_map_1.c/map:channel.value=11/' usleep 10
[ perf record: Woken up 1 times to write data ]
[ perf record: Captured and wrote 0.012 MB perf.data ]
# cat /sys/kernel/debug/tracing/trace
# tracer: nop
#
# entries-in-buffer/entries-written: 1/1 #P:8
[SNIP]
# TASK-PID CPU# |||| TIMESTAMP FUNCTION
# | | | |||| | |
usleep-18593 [007] d... 2394714.395539: : 11
# ./perf record -e './test_bpf_map_1.c/map:channel.value=101/' usleep 10
[ perf record: Woken up 1 times to write data ]
[ perf record: Captured and wrote 0.012 MB perf.data ]
# cat /sys/kernel/debug/tracing/trace
# tracer: nop
#
# entries-in-buffer/entries-written: 1/1 #P:8
[SNIP]
# TASK-PID CPU# |||| TIMESTAMP FUNCTION
# | | | |||| | |
usleep-18593 [007] d... 2394714.395539: : 11
usleep-19000 [006] d... 2394831.057840: : 101
Signed-off-by: Wang Nan <wangnan0@huawei.com>
Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Alexei Starovoitov <ast@kernel.org>
Cc: Brendan Gregg <brendan.d.gregg@gmail.com>
Cc: Cody P Schafer <dev@codyps.com>
Cc: He Kuang <hekuang@huawei.com>
Cc: Jeremie Galarneau <jeremie.galarneau@efficios.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Kirill Smelkov <kirr@nexedi.com>
Cc: Li Zefan <lizefan@huawei.com>
Cc: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Zefan Li <lizefan@huawei.com>
Cc: pi3orama@163.com
Link: http://lkml.kernel.org/r/1456132275-98875-6-git-send-email-wangnan0@huawei.com
Signed-off-by: He Kuang <hekuang@huawei.com>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2016-02-22 17:10:32 +08:00
|
|
|
err = bpf__apply_obj_config();
|
|
|
|
if (err) {
|
|
|
|
char errbuf[BUFSIZ];
|
|
|
|
|
|
|
|
bpf__strerror_apply_obj_config(err, errbuf, sizeof(errbuf));
|
|
|
|
pr_err("ERROR: Apply config to BPF failed: %s\n",
|
|
|
|
errbuf);
|
|
|
|
goto out_child;
|
|
|
|
}
|
|
|
|
|
2015-08-19 22:29:21 +08:00
|
|
|
/*
|
|
|
|
* Normally perf_session__new would do this, but it doesn't have the
|
|
|
|
* evlist.
|
|
|
|
*/
|
|
|
|
if (rec->tool.ordered_events && !perf_evlist__sample_id_all(rec->evlist)) {
|
|
|
|
pr_warning("WARNING: No sample_id_all support, falling back to unordered processing\n");
|
|
|
|
rec->tool.ordered_events = false;
|
|
|
|
}
|
|
|
|
|
2014-01-04 02:03:26 +08:00
|
|
|
if (!rec->evlist->nr_groups)
|
2013-01-22 17:09:31 +08:00
|
|
|
perf_header__clear_feat(&session->header, HEADER_GROUP_DESC);
|
|
|
|
|
2017-01-24 05:07:59 +08:00
|
|
|
if (data->is_pipe) {
|
2015-01-29 16:06:48 +08:00
|
|
|
err = perf_header__write_pipe(fd);
|
2010-04-02 12:59:16 +08:00
|
|
|
if (err < 0)
|
2014-05-12 08:47:24 +08:00
|
|
|
goto out_child;
|
2013-06-05 19:35:06 +08:00
|
|
|
} else {
|
2015-01-29 16:06:48 +08:00
|
|
|
err = perf_session__write_header(session, rec->evlist, fd, false);
|
2009-11-20 00:55:56 +08:00
|
|
|
if (err < 0)
|
2014-05-12 08:47:24 +08:00
|
|
|
goto out_child;
|
2010-01-06 02:50:31 +08:00
|
|
|
}
|
|
|
|
|
2012-02-07 06:27:52 +08:00
|
|
|
if (!rec->no_buildid
|
2011-12-07 17:02:55 +08:00
|
|
|
&& !perf_header__has_feat(&session->header, HEADER_BUILD_ID)) {
|
2012-02-07 06:27:52 +08:00
|
|
|
pr_err("Couldn't generate buildids. "
|
2011-12-07 17:02:55 +08:00
|
|
|
"Use --no-buildid to profile anyway.\n");
|
2012-08-27 02:24:47 +08:00
|
|
|
err = -1;
|
2014-05-12 08:47:24 +08:00
|
|
|
goto out_child;
|
2011-12-07 17:02:55 +08:00
|
|
|
}
|
|
|
|
|
perf record: Add --tail-synthesize option
When working with overwritable ring buffer there's a inconvenience
problem: if perf dumps data after a long period after it starts,
non-sample events may lost, which makes following 'perf report' unable
to identify proc name and mmap layout. For example:
# perf record -m 4 -e raw_syscalls:* -g --overwrite --switch-output \
dd if=/dev/zero of=/dev/null
send SIGUSR2 after dd runs long enough. The resuling perf.data lost
correct comm and mmap events:
# perf script -i perf.data.2016061522374354
perf 24478 [004] 2581325.601789: raw_syscalls:sys_exit: NR 0 = 512
^^^^
Should be 'dd'
27b2e8 syscall_slow_exit_work+0xfe2000e3 (/lib/modules/4.6.0-rc3+/build/vmlinux)
203cc7 do_syscall_64+0xfe200117 (/lib/modules/4.6.0-rc3+/build/vmlinux)
b18d83 return_from_SYSCALL_64+0xfe200000 (/lib/modules/4.6.0-rc3+/build/vmlinux)
7f47c417edf0 [unknown] ([unknown])
^^^^^^^^^^^^
Fail to unwind
This patch provides a '--tail-synthesize' option, allows perf to collect
system status when finalizing output file. In resuling output file, the
non-sample events reflect system status when dumping data.
After this patch:
# perf record -m 4 -e raw_syscalls:* -g --overwrite --switch-output --tail-synthesize \
dd if=/dev/zero of=/dev/null
# perf script -i perf.data.2016061600544998
dd 27364 [004] 2583244.994464: raw_syscalls:sys_enter: NR 1 (1, ...
^^
Correct comm
203a18 syscall_trace_enter_phase2+0xfe2001a8 ([kernel.kallsyms])
203aa5 syscall_trace_enter+0xfe200055 ([kernel.kallsyms])
203caa do_syscall_64+0xfe2000fa ([kernel.kallsyms])
b18d83 return_from_SYSCALL_64+0xfe200000 ([kernel.kallsyms])
d8e50 __GI___libc_write+0xffff01d9639f4010 (/tmp/oxygen_root-w00229757/lib64/libc-2.18.so)
^^^^^
Correct unwind
This option doesn't aim to solve this problem completely. If a process
terminates before SIGUSR2, we still lost its COMM and MMAP events. For
example, we can't unwind correctly from the final perf.data we get from
the previous example, because when perf collects the final output file
(when we press C-c), 'dd' has been terminated so its '/proc/<pid>/mmap'
becomes empty.
However, this is a cheaper choice. To completely solve this problem we
need to continously output non-sample events. To satisify the
requirement of daemonization, we need to merge them periodically. It is
possible but requires much more code and cycles.
Automatically select --tail-synthesize when --overwrite is provided.
Signed-off-by: Wang Nan <wangnan0@huawei.com>
Cc: He Kuang <hekuang@huawei.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Masami Hiramatsu <mhiramat@kernel.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Nilay Vaish <nilayvaish@gmail.com>
Cc: Zefan Li <lizefan@huawei.com>
Cc: pi3orama@163.com
Link: http://lkml.kernel.org/r/1468485287-33422-16-git-send-email-wangnan0@huawei.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2016-07-14 16:34:47 +08:00
|
|
|
err = record__synthesize(rec, false);
|
2016-02-26 17:32:07 +08:00
|
|
|
if (err < 0)
|
2014-05-12 08:47:24 +08:00
|
|
|
goto out_child;
|
2012-08-27 02:24:47 +08:00
|
|
|
|
2011-11-25 18:19:45 +08:00
|
|
|
if (rec->realtime_prio) {
|
2009-04-08 21:01:31 +08:00
|
|
|
struct sched_param param;
|
|
|
|
|
2011-11-25 18:19:45 +08:00
|
|
|
param.sched_priority = rec->realtime_prio;
|
2009-04-08 21:01:31 +08:00
|
|
|
if (sched_setscheduler(0, SCHED_FIFO, ¶m)) {
|
2009-10-22 03:34:06 +08:00
|
|
|
pr_err("Could not set realtime priority.\n");
|
2012-08-27 02:24:47 +08:00
|
|
|
err = -1;
|
2014-05-12 08:47:24 +08:00
|
|
|
goto out_child;
|
2009-04-08 21:01:31 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-11-13 01:34:01 +08:00
|
|
|
/*
|
|
|
|
* When perf is starting the traced process, all the events
|
|
|
|
* (apart from group members) have enable_on_exec=1 set,
|
|
|
|
* so don't spoil it by prematurely enabling them.
|
|
|
|
*/
|
2014-01-12 05:38:27 +08:00
|
|
|
if (!target__none(&opts->target) && !opts->initial_delay)
|
2014-01-04 02:03:26 +08:00
|
|
|
perf_evlist__enable(rec->evlist);
|
2011-08-26 00:17:55 +08:00
|
|
|
|
2009-12-17 00:55:55 +08:00
|
|
|
/*
|
|
|
|
* Let the child rip
|
|
|
|
*/
|
2015-09-22 08:24:55 +08:00
|
|
|
if (forks) {
|
2018-03-07 23:50:04 +08:00
|
|
|
struct machine *machine = &session->machines.host;
|
2015-09-30 09:45:24 +08:00
|
|
|
union perf_event *event;
|
2017-03-08 04:41:51 +08:00
|
|
|
pid_t tgid;
|
2015-09-30 09:45:24 +08:00
|
|
|
|
|
|
|
event = malloc(sizeof(event->comm) + machine->id_hdr_size);
|
|
|
|
if (event == NULL) {
|
|
|
|
err = -ENOMEM;
|
|
|
|
goto out_child;
|
|
|
|
}
|
|
|
|
|
2015-09-22 08:24:55 +08:00
|
|
|
/*
|
|
|
|
* Some H/W events are generated before COMM event
|
|
|
|
* which is emitted during exec(), so perf script
|
|
|
|
* cannot see a correct process name for those events.
|
|
|
|
* Synthesize COMM event to prevent it.
|
|
|
|
*/
|
2017-03-08 04:41:51 +08:00
|
|
|
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);
|
2015-09-30 09:45:24 +08:00
|
|
|
free(event);
|
2015-09-22 08:24:55 +08:00
|
|
|
|
2014-01-04 02:03:26 +08:00
|
|
|
perf_evlist__start_workload(rec->evlist);
|
2015-09-22 08:24:55 +08:00
|
|
|
}
|
2009-12-17 00:55:55 +08:00
|
|
|
|
2014-01-12 05:38:27 +08:00
|
|
|
if (opts->initial_delay) {
|
2016-08-09 02:05:46 +08:00
|
|
|
usleep(opts->initial_delay * USEC_PER_MSEC);
|
2014-01-12 05:38:27 +08:00
|
|
|
perf_evlist__enable(rec->evlist);
|
|
|
|
}
|
|
|
|
|
2016-04-21 02:59:49 +08:00
|
|
|
trigger_ready(&auxtrace_snapshot_trigger);
|
2016-04-21 02:59:50 +08:00
|
|
|
trigger_ready(&switch_output_trigger);
|
2016-11-26 15:03:28 +08:00
|
|
|
perf_hooks__invoke_record_start();
|
2009-06-25 03:12:48 +08:00
|
|
|
for (;;) {
|
perf record: Change 'record.samples' type to unsigned long long
When run "perf record -e", the number of samples showed up is wrong on some
32 bit systems, i.e. powerpc and arm.
For example, run the below commands on 32 bit powerpc:
perf probe -x /lib/libc.so.6 malloc
perf record -e probe_libc:malloc -a ls perf.data
[ perf record: Woken up 1 times to write data ]
[ perf record: Captured and wrote 0.036 MB perf.data (13829241621624967218 samples) ]
Actually, "perf script" just shows 21 samples. The number of samples is also
absurd since samples is long type, but it is printed as PRIu64.
Build test ran on x86-64, x86, aarch64, arm, mips, ppc and ppc64.
Signed-off-by: Yang Shi <yang.shi@linaro.org>
Cc: linaro-kernel@lists.linaro.org
Link: http://lkml.kernel.org/r/1443563383-4064-1-git-send-email-yang.shi@linaro.org
[ Bumped the 'hits' var used together with record.samples to 'unsigned long long' too ]
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2015-09-30 05:49:43 +08:00
|
|
|
unsigned long long hits = rec->samples;
|
2009-04-08 21:01:31 +08:00
|
|
|
|
2016-07-14 16:34:43 +08:00
|
|
|
/*
|
|
|
|
* rec->evlist->bkw_mmap_state is possible to be
|
|
|
|
* BKW_MMAP_EMPTY here: when done == true and
|
|
|
|
* hits != rec->samples in previous round.
|
|
|
|
*
|
|
|
|
* perf_evlist__toggle_bkw_mmap ensure we never
|
|
|
|
* convert BKW_MMAP_EMPTY to BKW_MMAP_DATA_PENDING.
|
|
|
|
*/
|
|
|
|
if (trigger_is_hit(&switch_output_trigger) || done || draining)
|
|
|
|
perf_evlist__toggle_bkw_mmap(rec->evlist, BKW_MMAP_DATA_PENDING);
|
|
|
|
|
2013-12-20 01:38:03 +08:00
|
|
|
if (record__mmap_read_all(rec) < 0) {
|
2016-04-21 02:59:49 +08:00
|
|
|
trigger_error(&auxtrace_snapshot_trigger);
|
2016-04-21 02:59:50 +08:00
|
|
|
trigger_error(&switch_output_trigger);
|
2012-08-27 02:24:47 +08:00
|
|
|
err = -1;
|
2014-05-12 08:47:24 +08:00
|
|
|
goto out_child;
|
2012-08-27 02:24:47 +08:00
|
|
|
}
|
2009-04-08 21:01:31 +08:00
|
|
|
|
2015-04-30 22:37:32 +08:00
|
|
|
if (auxtrace_record__snapshot_started) {
|
|
|
|
auxtrace_record__snapshot_started = 0;
|
2016-04-21 02:59:49 +08:00
|
|
|
if (!trigger_is_error(&auxtrace_snapshot_trigger))
|
2015-04-30 22:37:32 +08:00
|
|
|
record__read_auxtrace_snapshot(rec);
|
2016-04-21 02:59:49 +08:00
|
|
|
if (trigger_is_error(&auxtrace_snapshot_trigger)) {
|
2015-04-30 22:37:32 +08:00
|
|
|
pr_err("AUX area tracing snapshot failed\n");
|
|
|
|
err = -1;
|
|
|
|
goto out_child;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-04-21 02:59:50 +08:00
|
|
|
if (trigger_is_hit(&switch_output_trigger)) {
|
2016-07-14 16:34:43 +08:00
|
|
|
/*
|
|
|
|
* If switch_output_trigger is hit, the data in
|
|
|
|
* overwritable ring buffer should have been collected,
|
|
|
|
* so bkw_mmap_state should be set to BKW_MMAP_EMPTY.
|
|
|
|
*
|
|
|
|
* If SIGUSR2 raise after or during record__mmap_read_all(),
|
|
|
|
* record__mmap_read_all() didn't collect data from
|
|
|
|
* overwritable ring buffer. Read again.
|
|
|
|
*/
|
|
|
|
if (rec->evlist->bkw_mmap_state == BKW_MMAP_RUNNING)
|
|
|
|
continue;
|
2016-04-21 02:59:50 +08:00
|
|
|
trigger_ready(&switch_output_trigger);
|
|
|
|
|
2016-07-14 16:34:43 +08:00
|
|
|
/*
|
|
|
|
* Reenable events in overwrite ring buffer after
|
|
|
|
* record__mmap_read_all(): we should have collected
|
|
|
|
* data from it.
|
|
|
|
*/
|
|
|
|
perf_evlist__toggle_bkw_mmap(rec->evlist, BKW_MMAP_RUNNING);
|
|
|
|
|
2016-04-21 02:59:50 +08:00
|
|
|
if (!quiet)
|
|
|
|
fprintf(stderr, "[ perf record: dump data: Woken up %ld times ]\n",
|
|
|
|
waking);
|
|
|
|
waking = 0;
|
|
|
|
fd = record__switch_output(rec, false);
|
|
|
|
if (fd < 0) {
|
|
|
|
pr_err("Failed to switch to new file\n");
|
|
|
|
trigger_error(&switch_output_trigger);
|
|
|
|
err = fd;
|
|
|
|
goto out_child;
|
|
|
|
}
|
2017-01-09 17:52:00 +08:00
|
|
|
|
|
|
|
/* re-arm the alarm */
|
|
|
|
if (rec->switch_output.time)
|
|
|
|
alarm(rec->switch_output.time);
|
2016-04-21 02:59:50 +08:00
|
|
|
}
|
|
|
|
|
2011-11-25 18:19:45 +08:00
|
|
|
if (hits == rec->samples) {
|
2014-08-13 22:33:59 +08:00
|
|
|
if (done || draining)
|
2009-06-25 03:12:48 +08:00
|
|
|
break;
|
2014-08-19 04:25:59 +08:00
|
|
|
err = perf_evlist__poll(rec->evlist, -1);
|
2014-06-03 01:44:23 +08:00
|
|
|
/*
|
|
|
|
* Propagate error, only if there's any. Ignore positive
|
|
|
|
* number of returned events and interrupt error.
|
|
|
|
*/
|
|
|
|
if (err > 0 || (err < 0 && errno == EINTR))
|
2014-05-12 08:47:24 +08:00
|
|
|
err = 0;
|
2009-09-18 01:59:05 +08:00
|
|
|
waking++;
|
2014-08-13 22:33:59 +08:00
|
|
|
|
|
|
|
if (perf_evlist__filter_pollfd(rec->evlist, POLLERR | POLLHUP) == 0)
|
|
|
|
draining = true;
|
2009-09-18 01:59:05 +08:00
|
|
|
}
|
|
|
|
|
2012-11-13 01:34:01 +08:00
|
|
|
/*
|
|
|
|
* When perf is starting the traced process, at the end events
|
|
|
|
* die with the process and we wait for that. Thus no need to
|
|
|
|
* disable events in this case.
|
|
|
|
*/
|
2013-11-13 03:46:16 +08:00
|
|
|
if (done && !disabled && !target__none(&opts->target)) {
|
2016-04-21 02:59:49 +08:00
|
|
|
trigger_off(&auxtrace_snapshot_trigger);
|
2014-01-04 02:03:26 +08:00
|
|
|
perf_evlist__disable(rec->evlist);
|
2012-11-13 01:34:02 +08:00
|
|
|
disabled = true;
|
|
|
|
}
|
2009-04-08 21:01:31 +08:00
|
|
|
}
|
2016-04-21 02:59:49 +08:00
|
|
|
trigger_off(&auxtrace_snapshot_trigger);
|
2016-04-21 02:59:50 +08:00
|
|
|
trigger_off(&switch_output_trigger);
|
2009-04-08 21:01:31 +08:00
|
|
|
|
2014-01-03 02:11:25 +08:00
|
|
|
if (forks && workload_exec_errno) {
|
2014-08-14 10:22:43 +08:00
|
|
|
char msg[STRERR_BUFSIZE];
|
tools: Introduce str_error_r()
The tools so far have been using the strerror_r() GNU variant, that
returns a string, be it the buffer passed or something else.
But that, besides being tricky in cases where we expect that the
function using strerror_r() returns the error formatted in a provided
buffer (we have to check if it returned something else and copy that
instead), breaks the build on systems not using glibc, like Alpine
Linux, where musl libc is used.
So, introduce yet another wrapper, str_error_r(), that has the GNU
interface, but uses the portable XSI variant of strerror_r(), so that
users rest asured that the provided buffer is used and it is what is
returned.
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Wang Nan <wangnan0@huawei.com>
Link: http://lkml.kernel.org/n/tip-d4t42fnf48ytlk8rjxs822tf@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2016-07-06 22:56:20 +08:00
|
|
|
const char *emsg = str_error_r(workload_exec_errno, msg, sizeof(msg));
|
2014-01-03 02:11:25 +08:00
|
|
|
pr_err("Workload failed: %s\n", emsg);
|
|
|
|
err = -1;
|
2014-05-12 08:47:24 +08:00
|
|
|
goto out_child;
|
2014-01-03 02:11:25 +08:00
|
|
|
}
|
|
|
|
|
2015-01-29 16:06:44 +08:00
|
|
|
if (!quiet)
|
2014-05-12 08:47:24 +08:00
|
|
|
fprintf(stderr, "[ perf record: Woken up %ld times to write data ]\n", waking);
|
2010-10-27 01:20:09 +08:00
|
|
|
|
perf record: Add --tail-synthesize option
When working with overwritable ring buffer there's a inconvenience
problem: if perf dumps data after a long period after it starts,
non-sample events may lost, which makes following 'perf report' unable
to identify proc name and mmap layout. For example:
# perf record -m 4 -e raw_syscalls:* -g --overwrite --switch-output \
dd if=/dev/zero of=/dev/null
send SIGUSR2 after dd runs long enough. The resuling perf.data lost
correct comm and mmap events:
# perf script -i perf.data.2016061522374354
perf 24478 [004] 2581325.601789: raw_syscalls:sys_exit: NR 0 = 512
^^^^
Should be 'dd'
27b2e8 syscall_slow_exit_work+0xfe2000e3 (/lib/modules/4.6.0-rc3+/build/vmlinux)
203cc7 do_syscall_64+0xfe200117 (/lib/modules/4.6.0-rc3+/build/vmlinux)
b18d83 return_from_SYSCALL_64+0xfe200000 (/lib/modules/4.6.0-rc3+/build/vmlinux)
7f47c417edf0 [unknown] ([unknown])
^^^^^^^^^^^^
Fail to unwind
This patch provides a '--tail-synthesize' option, allows perf to collect
system status when finalizing output file. In resuling output file, the
non-sample events reflect system status when dumping data.
After this patch:
# perf record -m 4 -e raw_syscalls:* -g --overwrite --switch-output --tail-synthesize \
dd if=/dev/zero of=/dev/null
# perf script -i perf.data.2016061600544998
dd 27364 [004] 2583244.994464: raw_syscalls:sys_enter: NR 1 (1, ...
^^
Correct comm
203a18 syscall_trace_enter_phase2+0xfe2001a8 ([kernel.kallsyms])
203aa5 syscall_trace_enter+0xfe200055 ([kernel.kallsyms])
203caa do_syscall_64+0xfe2000fa ([kernel.kallsyms])
b18d83 return_from_SYSCALL_64+0xfe200000 ([kernel.kallsyms])
d8e50 __GI___libc_write+0xffff01d9639f4010 (/tmp/oxygen_root-w00229757/lib64/libc-2.18.so)
^^^^^
Correct unwind
This option doesn't aim to solve this problem completely. If a process
terminates before SIGUSR2, we still lost its COMM and MMAP events. For
example, we can't unwind correctly from the final perf.data we get from
the previous example, because when perf collects the final output file
(when we press C-c), 'dd' has been terminated so its '/proc/<pid>/mmap'
becomes empty.
However, this is a cheaper choice. To completely solve this problem we
need to continously output non-sample events. To satisify the
requirement of daemonization, we need to merge them periodically. It is
possible but requires much more code and cycles.
Automatically select --tail-synthesize when --overwrite is provided.
Signed-off-by: Wang Nan <wangnan0@huawei.com>
Cc: He Kuang <hekuang@huawei.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Masami Hiramatsu <mhiramat@kernel.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Nilay Vaish <nilayvaish@gmail.com>
Cc: Zefan Li <lizefan@huawei.com>
Cc: pi3orama@163.com
Link: http://lkml.kernel.org/r/1468485287-33422-16-git-send-email-wangnan0@huawei.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2016-07-14 16:34:47 +08:00
|
|
|
if (target__none(&rec->opts.target))
|
|
|
|
record__synthesize_workload(rec, true);
|
|
|
|
|
2014-05-12 08:47:24 +08:00
|
|
|
out_child:
|
2018-11-06 17:04:58 +08:00
|
|
|
record__aio_mmap_read_sync(rec);
|
|
|
|
|
2014-05-12 08:47:24 +08:00
|
|
|
if (forks) {
|
|
|
|
int exit_status;
|
2009-06-03 05:43:11 +08:00
|
|
|
|
2014-05-12 08:47:24 +08:00
|
|
|
if (!child_finished)
|
|
|
|
kill(rec->evlist->workload.pid, SIGTERM);
|
|
|
|
|
|
|
|
wait(&exit_status);
|
|
|
|
|
|
|
|
if (err < 0)
|
|
|
|
status = err;
|
|
|
|
else if (WIFEXITED(exit_status))
|
|
|
|
status = WEXITSTATUS(exit_status);
|
|
|
|
else if (WIFSIGNALED(exit_status))
|
|
|
|
signr = WTERMSIG(exit_status);
|
|
|
|
} else
|
|
|
|
status = err;
|
|
|
|
|
perf record: Add --tail-synthesize option
When working with overwritable ring buffer there's a inconvenience
problem: if perf dumps data after a long period after it starts,
non-sample events may lost, which makes following 'perf report' unable
to identify proc name and mmap layout. For example:
# perf record -m 4 -e raw_syscalls:* -g --overwrite --switch-output \
dd if=/dev/zero of=/dev/null
send SIGUSR2 after dd runs long enough. The resuling perf.data lost
correct comm and mmap events:
# perf script -i perf.data.2016061522374354
perf 24478 [004] 2581325.601789: raw_syscalls:sys_exit: NR 0 = 512
^^^^
Should be 'dd'
27b2e8 syscall_slow_exit_work+0xfe2000e3 (/lib/modules/4.6.0-rc3+/build/vmlinux)
203cc7 do_syscall_64+0xfe200117 (/lib/modules/4.6.0-rc3+/build/vmlinux)
b18d83 return_from_SYSCALL_64+0xfe200000 (/lib/modules/4.6.0-rc3+/build/vmlinux)
7f47c417edf0 [unknown] ([unknown])
^^^^^^^^^^^^
Fail to unwind
This patch provides a '--tail-synthesize' option, allows perf to collect
system status when finalizing output file. In resuling output file, the
non-sample events reflect system status when dumping data.
After this patch:
# perf record -m 4 -e raw_syscalls:* -g --overwrite --switch-output --tail-synthesize \
dd if=/dev/zero of=/dev/null
# perf script -i perf.data.2016061600544998
dd 27364 [004] 2583244.994464: raw_syscalls:sys_enter: NR 1 (1, ...
^^
Correct comm
203a18 syscall_trace_enter_phase2+0xfe2001a8 ([kernel.kallsyms])
203aa5 syscall_trace_enter+0xfe200055 ([kernel.kallsyms])
203caa do_syscall_64+0xfe2000fa ([kernel.kallsyms])
b18d83 return_from_SYSCALL_64+0xfe200000 ([kernel.kallsyms])
d8e50 __GI___libc_write+0xffff01d9639f4010 (/tmp/oxygen_root-w00229757/lib64/libc-2.18.so)
^^^^^
Correct unwind
This option doesn't aim to solve this problem completely. If a process
terminates before SIGUSR2, we still lost its COMM and MMAP events. For
example, we can't unwind correctly from the final perf.data we get from
the previous example, because when perf collects the final output file
(when we press C-c), 'dd' has been terminated so its '/proc/<pid>/mmap'
becomes empty.
However, this is a cheaper choice. To completely solve this problem we
need to continously output non-sample events. To satisify the
requirement of daemonization, we need to merge them periodically. It is
possible but requires much more code and cycles.
Automatically select --tail-synthesize when --overwrite is provided.
Signed-off-by: Wang Nan <wangnan0@huawei.com>
Cc: He Kuang <hekuang@huawei.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Masami Hiramatsu <mhiramat@kernel.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Nilay Vaish <nilayvaish@gmail.com>
Cc: Zefan Li <lizefan@huawei.com>
Cc: pi3orama@163.com
Link: http://lkml.kernel.org/r/1468485287-33422-16-git-send-email-wangnan0@huawei.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2016-07-14 16:34:47 +08:00
|
|
|
record__synthesize(rec, true);
|
2015-01-29 16:06:44 +08:00
|
|
|
/* this will be recalculated during process_buildids() */
|
|
|
|
rec->samples = 0;
|
|
|
|
|
2016-04-13 16:21:07 +08:00
|
|
|
if (!err) {
|
|
|
|
if (!rec->timestamp_filename) {
|
|
|
|
record__finish_output(rec);
|
|
|
|
} else {
|
|
|
|
fd = record__switch_output(rec, true);
|
|
|
|
if (fd < 0) {
|
|
|
|
status = fd;
|
|
|
|
goto out_delete_session;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2010-07-30 01:08:55 +08:00
|
|
|
|
2016-11-26 15:03:28 +08:00
|
|
|
perf_hooks__invoke_record_end();
|
|
|
|
|
2015-01-29 16:06:44 +08:00
|
|
|
if (!err && !quiet) {
|
|
|
|
char samples[128];
|
2016-04-13 16:21:07 +08:00
|
|
|
const char *postfix = rec->timestamp_filename ?
|
|
|
|
".<timestamp>" : "";
|
2015-01-29 16:06:44 +08:00
|
|
|
|
2015-04-09 23:53:45 +08:00
|
|
|
if (rec->samples && !rec->opts.full_auxtrace)
|
2015-01-29 16:06:44 +08:00
|
|
|
scnprintf(samples, sizeof(samples),
|
|
|
|
" (%" PRIu64 " samples)", rec->samples);
|
|
|
|
else
|
|
|
|
samples[0] = '\0';
|
|
|
|
|
2016-04-13 16:21:07 +08:00
|
|
|
fprintf(stderr, "[ perf record: Captured and wrote %.3f MB %s%s%s ]\n",
|
2017-01-24 05:07:59 +08:00
|
|
|
perf_data__size(data) / 1024.0 / 1024.0,
|
2019-02-21 17:41:30 +08:00
|
|
|
data->path, postfix, samples);
|
2015-01-29 16:06:44 +08:00
|
|
|
}
|
|
|
|
|
2010-07-30 01:08:55 +08:00
|
|
|
out_delete_session:
|
|
|
|
perf_session__delete(session);
|
2014-05-12 08:47:24 +08:00
|
|
|
return status;
|
2009-04-08 21:01:31 +08:00
|
|
|
}
|
2009-05-26 15:17:18 +08:00
|
|
|
|
2016-04-16 03:37:17 +08:00
|
|
|
static void callchain_debug(struct callchain_param *callchain)
|
2013-10-26 22:25:33 +08:00
|
|
|
{
|
2015-01-06 02:23:04 +08:00
|
|
|
static const char *str[CALLCHAIN_MAX] = { "NONE", "FP", "DWARF", "LBR" };
|
2014-02-03 19:44:43 +08:00
|
|
|
|
2016-04-16 03:37:17 +08:00
|
|
|
pr_debug("callchain: type %s\n", str[callchain->record_mode]);
|
2012-08-07 21:20:47 +08:00
|
|
|
|
2016-04-16 03:37:17 +08:00
|
|
|
if (callchain->record_mode == CALLCHAIN_DWARF)
|
2013-10-26 22:25:33 +08:00
|
|
|
pr_debug("callchain: stack dump size %d\n",
|
2016-04-16 03:37:17 +08:00
|
|
|
callchain->dump_size);
|
2013-10-26 22:25:33 +08:00
|
|
|
}
|
|
|
|
|
2016-04-16 03:37:17 +08:00
|
|
|
int record_opts__parse_callchain(struct record_opts *record,
|
|
|
|
struct callchain_param *callchain,
|
|
|
|
const char *arg, bool unset)
|
2013-10-26 22:25:33 +08:00
|
|
|
{
|
|
|
|
int ret;
|
2016-04-16 03:37:17 +08:00
|
|
|
callchain->enabled = !unset;
|
2014-02-03 19:44:42 +08:00
|
|
|
|
2013-10-26 22:25:33 +08:00
|
|
|
/* --no-call-graph */
|
|
|
|
if (unset) {
|
2016-04-16 03:37:17 +08:00
|
|
|
callchain->record_mode = CALLCHAIN_NONE;
|
2013-10-26 22:25:33 +08:00
|
|
|
pr_debug("callchain: disabled\n");
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2016-04-16 03:37:17 +08:00
|
|
|
ret = parse_callchain_record_opt(arg, callchain);
|
2016-01-07 21:30:22 +08:00
|
|
|
if (!ret) {
|
|
|
|
/* Enable data address sampling for DWARF unwind. */
|
2016-04-16 03:37:17 +08:00
|
|
|
if (callchain->record_mode == CALLCHAIN_DWARF)
|
2016-01-07 21:30:22 +08:00
|
|
|
record->sample_address = true;
|
2016-04-16 03:37:17 +08:00
|
|
|
callchain_debug(callchain);
|
2016-01-07 21:30:22 +08:00
|
|
|
}
|
2012-08-07 21:20:47 +08:00
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2016-04-16 03:37:17 +08:00
|
|
|
int record_parse_callchain_opt(const struct option *opt,
|
|
|
|
const char *arg,
|
|
|
|
int unset)
|
|
|
|
{
|
|
|
|
return record_opts__parse_callchain(opt->value, &callchain_param, arg, unset);
|
|
|
|
}
|
|
|
|
|
2015-07-29 17:42:12 +08:00
|
|
|
int record_callchain_opt(const struct option *opt,
|
2013-10-26 22:25:33 +08:00
|
|
|
const char *arg __maybe_unused,
|
|
|
|
int unset __maybe_unused)
|
|
|
|
{
|
2016-04-18 23:09:08 +08:00
|
|
|
struct callchain_param *callchain = opt->value;
|
2015-07-29 17:42:12 +08:00
|
|
|
|
2016-04-18 23:09:08 +08:00
|
|
|
callchain->enabled = true;
|
2013-10-26 22:25:33 +08:00
|
|
|
|
2016-04-18 23:09:08 +08:00
|
|
|
if (callchain->record_mode == CALLCHAIN_NONE)
|
|
|
|
callchain->record_mode = CALLCHAIN_FP;
|
2014-02-03 19:44:42 +08:00
|
|
|
|
2016-04-18 23:09:08 +08:00
|
|
|
callchain_debug(callchain);
|
2013-10-26 22:25:33 +08:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2014-02-03 19:44:42 +08:00
|
|
|
static int perf_record_config(const char *var, const char *value, void *cb)
|
|
|
|
{
|
2015-12-15 09:49:56 +08:00
|
|
|
struct record *rec = cb;
|
|
|
|
|
|
|
|
if (!strcmp(var, "record.build-id")) {
|
|
|
|
if (!strcmp(value, "cache"))
|
|
|
|
rec->no_buildid_cache = false;
|
|
|
|
else if (!strcmp(value, "no-cache"))
|
|
|
|
rec->no_buildid_cache = true;
|
|
|
|
else if (!strcmp(value, "skip"))
|
|
|
|
rec->no_buildid = true;
|
|
|
|
else
|
|
|
|
return -1;
|
|
|
|
return 0;
|
|
|
|
}
|
2018-03-12 19:25:57 +08:00
|
|
|
if (!strcmp(var, "record.call-graph")) {
|
|
|
|
var = "call-graph.record-mode";
|
|
|
|
return perf_default_config(var, value, cb);
|
|
|
|
}
|
2018-11-06 17:07:19 +08:00
|
|
|
#ifdef HAVE_AIO_SUPPORT
|
|
|
|
if (!strcmp(var, "record.aio")) {
|
|
|
|
rec->opts.nr_cblocks = strtol(value, NULL, 0);
|
|
|
|
if (!rec->opts.nr_cblocks)
|
|
|
|
rec->opts.nr_cblocks = nr_cblocks_default;
|
|
|
|
}
|
|
|
|
#endif
|
2014-02-03 19:44:42 +08:00
|
|
|
|
2018-03-12 19:25:57 +08:00
|
|
|
return 0;
|
2014-02-03 19:44:42 +08:00
|
|
|
}
|
|
|
|
|
2015-03-31 06:19:31 +08:00
|
|
|
struct clockid_map {
|
|
|
|
const char *name;
|
|
|
|
int clockid;
|
|
|
|
};
|
|
|
|
|
|
|
|
#define CLOCKID_MAP(n, c) \
|
|
|
|
{ .name = n, .clockid = (c), }
|
|
|
|
|
|
|
|
#define CLOCKID_END { .name = NULL, }
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Add the missing ones, we need to build on many distros...
|
|
|
|
*/
|
|
|
|
#ifndef CLOCK_MONOTONIC_RAW
|
|
|
|
#define CLOCK_MONOTONIC_RAW 4
|
|
|
|
#endif
|
|
|
|
#ifndef CLOCK_BOOTTIME
|
|
|
|
#define CLOCK_BOOTTIME 7
|
|
|
|
#endif
|
|
|
|
#ifndef CLOCK_TAI
|
|
|
|
#define CLOCK_TAI 11
|
|
|
|
#endif
|
|
|
|
|
|
|
|
static const struct clockid_map clockids[] = {
|
|
|
|
/* available for all events, NMI safe */
|
|
|
|
CLOCKID_MAP("monotonic", CLOCK_MONOTONIC),
|
|
|
|
CLOCKID_MAP("monotonic_raw", CLOCK_MONOTONIC_RAW),
|
|
|
|
|
|
|
|
/* available for some events */
|
|
|
|
CLOCKID_MAP("realtime", CLOCK_REALTIME),
|
|
|
|
CLOCKID_MAP("boottime", CLOCK_BOOTTIME),
|
|
|
|
CLOCKID_MAP("tai", CLOCK_TAI),
|
|
|
|
|
|
|
|
/* available for the lazy */
|
|
|
|
CLOCKID_MAP("mono", CLOCK_MONOTONIC),
|
|
|
|
CLOCKID_MAP("raw", CLOCK_MONOTONIC_RAW),
|
|
|
|
CLOCKID_MAP("real", CLOCK_REALTIME),
|
|
|
|
CLOCKID_MAP("boot", CLOCK_BOOTTIME),
|
|
|
|
|
|
|
|
CLOCKID_END,
|
|
|
|
};
|
|
|
|
|
perf record: Encode -k clockid frequency into Perf trace
Store -k clockid frequency into Perf trace to enable timestamps
derived metrics conversion into wall clock time on reporting stage.
Below is the example of perf report output:
tools/perf/perf record -k raw -- ../../matrix/linux/matrix.gcc
...
[ perf record: Captured and wrote 31.222 MB perf.data (818054 samples) ]
tools/perf/perf report --header
# ========
...
# event : name = cycles:ppp, , size = 112, { sample_period, sample_freq } = 4000, sample_type = IP|TID|TIME|PERIOD, disabled = 1, inherit = 1, mmap = 1, comm = 1, freq = 1, enable_on_exec = 1, task = 1, precise_ip = 3, sample_id_all = 1, exclude_guest = 1, mmap2 = 1, comm_exec = 1, use_clockid = 1, clockid = 4
...
# clockid frequency: 1000 MHz
...
# ========
Signed-off-by: Alexey Budankov <alexey.budankov@linux.intel.com>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Andi Kleen <ak@linux.intel.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Link: http://lkml.kernel.org/r/23a4a1dc-b160-85a0-347d-40a2ed6d007b@linux.intel.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2018-10-09 22:36:24 +08:00
|
|
|
static int get_clockid_res(clockid_t clk_id, u64 *res_ns)
|
|
|
|
{
|
|
|
|
struct timespec res;
|
|
|
|
|
|
|
|
*res_ns = 0;
|
|
|
|
if (!clock_getres(clk_id, &res))
|
|
|
|
*res_ns = res.tv_nsec + res.tv_sec * NSEC_PER_SEC;
|
|
|
|
else
|
|
|
|
pr_warning("WARNING: Failed to determine specified clock resolution.\n");
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2015-03-31 06:19:31 +08:00
|
|
|
static int parse_clockid(const struct option *opt, const char *str, int unset)
|
|
|
|
{
|
|
|
|
struct record_opts *opts = (struct record_opts *)opt->value;
|
|
|
|
const struct clockid_map *cm;
|
|
|
|
const char *ostr = str;
|
|
|
|
|
|
|
|
if (unset) {
|
|
|
|
opts->use_clockid = 0;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* no arg passed */
|
|
|
|
if (!str)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
/* no setting it twice */
|
|
|
|
if (opts->use_clockid)
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
opts->use_clockid = true;
|
|
|
|
|
|
|
|
/* if its a number, we're done */
|
|
|
|
if (sscanf(str, "%d", &opts->clockid) == 1)
|
perf record: Encode -k clockid frequency into Perf trace
Store -k clockid frequency into Perf trace to enable timestamps
derived metrics conversion into wall clock time on reporting stage.
Below is the example of perf report output:
tools/perf/perf record -k raw -- ../../matrix/linux/matrix.gcc
...
[ perf record: Captured and wrote 31.222 MB perf.data (818054 samples) ]
tools/perf/perf report --header
# ========
...
# event : name = cycles:ppp, , size = 112, { sample_period, sample_freq } = 4000, sample_type = IP|TID|TIME|PERIOD, disabled = 1, inherit = 1, mmap = 1, comm = 1, freq = 1, enable_on_exec = 1, task = 1, precise_ip = 3, sample_id_all = 1, exclude_guest = 1, mmap2 = 1, comm_exec = 1, use_clockid = 1, clockid = 4
...
# clockid frequency: 1000 MHz
...
# ========
Signed-off-by: Alexey Budankov <alexey.budankov@linux.intel.com>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Andi Kleen <ak@linux.intel.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Link: http://lkml.kernel.org/r/23a4a1dc-b160-85a0-347d-40a2ed6d007b@linux.intel.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2018-10-09 22:36:24 +08:00
|
|
|
return get_clockid_res(opts->clockid, &opts->clockid_res_ns);
|
2015-03-31 06:19:31 +08:00
|
|
|
|
|
|
|
/* allow a "CLOCK_" prefix to the name */
|
|
|
|
if (!strncasecmp(str, "CLOCK_", 6))
|
|
|
|
str += 6;
|
|
|
|
|
|
|
|
for (cm = clockids; cm->name; cm++) {
|
|
|
|
if (!strcasecmp(str, cm->name)) {
|
|
|
|
opts->clockid = cm->clockid;
|
perf record: Encode -k clockid frequency into Perf trace
Store -k clockid frequency into Perf trace to enable timestamps
derived metrics conversion into wall clock time on reporting stage.
Below is the example of perf report output:
tools/perf/perf record -k raw -- ../../matrix/linux/matrix.gcc
...
[ perf record: Captured and wrote 31.222 MB perf.data (818054 samples) ]
tools/perf/perf report --header
# ========
...
# event : name = cycles:ppp, , size = 112, { sample_period, sample_freq } = 4000, sample_type = IP|TID|TIME|PERIOD, disabled = 1, inherit = 1, mmap = 1, comm = 1, freq = 1, enable_on_exec = 1, task = 1, precise_ip = 3, sample_id_all = 1, exclude_guest = 1, mmap2 = 1, comm_exec = 1, use_clockid = 1, clockid = 4
...
# clockid frequency: 1000 MHz
...
# ========
Signed-off-by: Alexey Budankov <alexey.budankov@linux.intel.com>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Andi Kleen <ak@linux.intel.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Link: http://lkml.kernel.org/r/23a4a1dc-b160-85a0-347d-40a2ed6d007b@linux.intel.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2018-10-09 22:36:24 +08:00
|
|
|
return get_clockid_res(opts->clockid,
|
|
|
|
&opts->clockid_res_ns);
|
2015-03-31 06:19:31 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
opts->use_clockid = false;
|
|
|
|
ui__warning("unknown clockid %s, check man page\n", ostr);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2019-01-23 01:52:03 +08:00
|
|
|
static int record__parse_affinity(const struct option *opt, const char *str, int unset)
|
|
|
|
{
|
|
|
|
struct record_opts *opts = (struct record_opts *)opt->value;
|
|
|
|
|
|
|
|
if (unset || !str)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
if (!strcasecmp(str, "node"))
|
|
|
|
opts->affinity = PERF_AFFINITY_NODE;
|
|
|
|
else if (!strcasecmp(str, "cpu"))
|
|
|
|
opts->affinity = PERF_AFFINITY_CPU;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2015-04-09 23:53:46 +08:00
|
|
|
static int record__parse_mmap_pages(const struct option *opt,
|
|
|
|
const char *str,
|
|
|
|
int unset __maybe_unused)
|
|
|
|
{
|
|
|
|
struct record_opts *opts = opt->value;
|
|
|
|
char *s, *p;
|
|
|
|
unsigned int mmap_pages;
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
if (!str)
|
|
|
|
return -EINVAL;
|
|
|
|
|
|
|
|
s = strdup(str);
|
|
|
|
if (!s)
|
|
|
|
return -ENOMEM;
|
|
|
|
|
|
|
|
p = strchr(s, ',');
|
|
|
|
if (p)
|
|
|
|
*p = '\0';
|
|
|
|
|
|
|
|
if (*s) {
|
|
|
|
ret = __perf_evlist__parse_mmap_pages(&mmap_pages, s);
|
|
|
|
if (ret)
|
|
|
|
goto out_free;
|
|
|
|
opts->mmap_pages = mmap_pages;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!p) {
|
|
|
|
ret = 0;
|
|
|
|
goto out_free;
|
|
|
|
}
|
|
|
|
|
|
|
|
ret = __perf_evlist__parse_mmap_pages(&mmap_pages, p + 1);
|
|
|
|
if (ret)
|
|
|
|
goto out_free;
|
|
|
|
|
|
|
|
opts->auxtrace_mmap_pages = mmap_pages;
|
|
|
|
|
|
|
|
out_free:
|
|
|
|
free(s);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2017-01-09 17:51:59 +08:00
|
|
|
static void switch_output_size_warn(struct record *rec)
|
|
|
|
{
|
|
|
|
u64 wakeup_size = perf_evlist__mmap_size(rec->opts.mmap_pages);
|
|
|
|
struct switch_output *s = &rec->switch_output;
|
|
|
|
|
|
|
|
wakeup_size /= 2;
|
|
|
|
|
|
|
|
if (s->size < wakeup_size) {
|
|
|
|
char buf[100];
|
|
|
|
|
|
|
|
unit_number__scnprintf(buf, sizeof(buf), wakeup_size);
|
|
|
|
pr_warning("WARNING: switch-output data size lower than "
|
|
|
|
"wakeup kernel buffer size (%s) "
|
|
|
|
"expect bigger perf.data sizes\n", buf);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-01-09 17:51:57 +08:00
|
|
|
static int switch_output_setup(struct record *rec)
|
|
|
|
{
|
|
|
|
struct switch_output *s = &rec->switch_output;
|
2017-01-09 17:51:58 +08:00
|
|
|
static struct parse_tag tags_size[] = {
|
|
|
|
{ .tag = 'B', .mult = 1 },
|
|
|
|
{ .tag = 'K', .mult = 1 << 10 },
|
|
|
|
{ .tag = 'M', .mult = 1 << 20 },
|
|
|
|
{ .tag = 'G', .mult = 1 << 30 },
|
|
|
|
{ .tag = 0 },
|
|
|
|
};
|
2017-01-09 17:52:00 +08:00
|
|
|
static struct parse_tag tags_time[] = {
|
|
|
|
{ .tag = 's', .mult = 1 },
|
|
|
|
{ .tag = 'm', .mult = 60 },
|
|
|
|
{ .tag = 'h', .mult = 60*60 },
|
|
|
|
{ .tag = 'd', .mult = 60*60*24 },
|
|
|
|
{ .tag = 0 },
|
|
|
|
};
|
2017-01-09 17:51:58 +08:00
|
|
|
unsigned long val;
|
2017-01-09 17:51:57 +08:00
|
|
|
|
|
|
|
if (!s->set)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
if (!strcmp(s->str, "signal")) {
|
|
|
|
s->signal = true;
|
|
|
|
pr_debug("switch-output with SIGUSR2 signal\n");
|
2017-01-09 17:51:58 +08:00
|
|
|
goto enabled;
|
|
|
|
}
|
|
|
|
|
|
|
|
val = parse_tag_value(s->str, tags_size);
|
|
|
|
if (val != (unsigned long) -1) {
|
|
|
|
s->size = val;
|
|
|
|
pr_debug("switch-output with %s size threshold\n", s->str);
|
|
|
|
goto enabled;
|
2017-01-09 17:51:57 +08:00
|
|
|
}
|
|
|
|
|
2017-01-09 17:52:00 +08:00
|
|
|
val = parse_tag_value(s->str, tags_time);
|
|
|
|
if (val != (unsigned long) -1) {
|
|
|
|
s->time = val;
|
|
|
|
pr_debug("switch-output with %s time threshold (%lu seconds)\n",
|
|
|
|
s->str, s->time);
|
|
|
|
goto enabled;
|
|
|
|
}
|
|
|
|
|
2017-01-09 17:51:57 +08:00
|
|
|
return -1;
|
2017-01-09 17:51:58 +08:00
|
|
|
|
|
|
|
enabled:
|
|
|
|
rec->timestamp_filename = true;
|
|
|
|
s->enabled = true;
|
2017-01-09 17:51:59 +08:00
|
|
|
|
|
|
|
if (s->size && !rec->opts.no_buffering)
|
|
|
|
switch_output_size_warn(rec);
|
|
|
|
|
2017-01-09 17:51:58 +08:00
|
|
|
return 0;
|
2017-01-09 17:51:57 +08:00
|
|
|
}
|
|
|
|
|
2014-10-22 23:15:46 +08:00
|
|
|
static const char * const __record_usage[] = {
|
2009-05-28 22:25:34 +08:00
|
|
|
"perf record [<options>] [<command>]",
|
|
|
|
"perf record [<options>] -- <command> [<options>]",
|
2009-05-26 15:17:18 +08:00
|
|
|
NULL
|
|
|
|
};
|
2014-10-22 23:15:46 +08:00
|
|
|
const char * const *record_usage = __record_usage;
|
2009-05-26 15:17:18 +08:00
|
|
|
|
2011-11-25 18:19:45 +08:00
|
|
|
/*
|
2013-12-20 01:38:03 +08:00
|
|
|
* XXX Ideally would be local to cmd_record() and passed to a record__new
|
|
|
|
* because we need to have access to it in record__exit, that is called
|
2011-11-25 18:19:45 +08:00
|
|
|
* after cmd_record() exits, but since record_options need to be accessible to
|
|
|
|
* builtin-script, leave it here.
|
|
|
|
*
|
|
|
|
* At least we don't ouch it in all the other functions here directly.
|
|
|
|
*
|
|
|
|
* Just say no to tons of global variables, sigh.
|
|
|
|
*/
|
2013-12-20 01:38:03 +08:00
|
|
|
static struct record record = {
|
2011-11-25 18:19:45 +08:00
|
|
|
.opts = {
|
2014-07-31 14:45:04 +08:00
|
|
|
.sample_time = true,
|
2011-11-25 18:19:45 +08:00
|
|
|
.mmap_pages = UINT_MAX,
|
|
|
|
.user_freq = UINT_MAX,
|
|
|
|
.user_interval = ULLONG_MAX,
|
2012-05-23 00:14:18 +08:00
|
|
|
.freq = 4000,
|
2012-05-16 17:45:49 +08:00
|
|
|
.target = {
|
|
|
|
.uses_mmap = true,
|
2013-11-15 21:52:29 +08:00
|
|
|
.default_per_cpu = true,
|
2012-05-16 17:45:49 +08:00
|
|
|
},
|
2011-11-25 18:19:45 +08:00
|
|
|
},
|
2015-01-29 16:06:44 +08:00
|
|
|
.tool = {
|
|
|
|
.sample = process_sample_event,
|
|
|
|
.fork = perf_event__process_fork,
|
2015-08-19 22:29:21 +08:00
|
|
|
.exit = perf_event__process_exit,
|
2015-01-29 16:06:44 +08:00
|
|
|
.comm = perf_event__process_comm,
|
perf tools: Add PERF_RECORD_NAMESPACES to include namespaces related info
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>
#
Signed-off-by: Hari Bathini <hbathini@linux.vnet.ibm.com>
Acked-by: Jiri Olsa <jolsa@kernel.org>
Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Alexei Starovoitov <ast@fb.com>
Cc: Ananth N Mavinakayanahalli <ananth@linux.vnet.ibm.com>
Cc: Aravinda Prasad <aravinda@linux.vnet.ibm.com>
Cc: Brendan Gregg <brendan.d.gregg@gmail.com>
Cc: Daniel Borkmann <daniel@iogearbox.net>
Cc: Eric Biederman <ebiederm@xmission.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Sargun Dhillon <sargun@sargun.me>
Cc: Steven Rostedt <rostedt@goodmis.org>
Link: http://lkml.kernel.org/r/148891930386.25309.18412039920746995488.stgit@hbathini.in.ibm.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2017-03-08 04:41:43 +08:00
|
|
|
.namespaces = perf_event__process_namespaces,
|
2015-01-29 16:06:44 +08:00
|
|
|
.mmap = perf_event__process_mmap,
|
|
|
|
.mmap2 = perf_event__process_mmap2,
|
2015-08-19 22:29:21 +08:00
|
|
|
.ordered_events = true,
|
2015-01-29 16:06:44 +08:00
|
|
|
},
|
2011-11-25 18:19:45 +08:00
|
|
|
};
|
2010-04-15 01:42:07 +08:00
|
|
|
|
perf tools: Improve call graph documents and help messages
The --call-graph option is complex so we should provide better guide for
users. Also change help message to be consistent with config option
names. Now perf top will show help like below:
$ perf top --call-graph
Error: option `call-graph' requires a value
Usage: perf top [<options>]
--call-graph <record_mode[,record_size],print_type,threshold[,print_limit],order,sort_key[,branch]>
setup and enables call-graph (stack chain/backtrace):
record_mode: call graph recording mode (fp|dwarf|lbr)
record_size: if record_mode is 'dwarf', max size of stack recording (<bytes>)
default: 8192 (bytes)
print_type: call graph printing style (graph|flat|fractal|none)
threshold: minimum call graph inclusion threshold (<percent>)
print_limit: maximum number of call graph entry (<number>)
order: call graph order (caller|callee)
sort_key: call graph sort key (function|address)
branch: include last branch info to call graph (branch)
Default: fp,graph,0.5,caller,function
Requested-by: Ingo Molnar <mingo@kernel.org>
Signed-off-by: Namhyung Kim <namhyung@kernel.org>
Acked-by: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Borislav Petkov <bp@suse.de>
Cc: Brendan Gregg <brendan.d.gregg@gmail.com>
Cc: Chandler Carruth <chandlerc@gmail.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Stephane Eranian <eranian@google.com>
Cc: Wang Nan <wangnan0@huawei.com>
Link: http://lkml.kernel.org/r/1445524112-5201-2-git-send-email-namhyung@kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2015-10-22 22:28:32 +08:00
|
|
|
const char record_callchain_help[] = CALLCHAIN_RECORD_HELP
|
|
|
|
"\n\t\t\t\tDefault: fp";
|
2012-10-02 02:20:58 +08:00
|
|
|
|
2016-06-16 16:02:41 +08:00
|
|
|
static bool dry_run;
|
|
|
|
|
2011-11-25 18:19:45 +08:00
|
|
|
/*
|
|
|
|
* XXX Will stay a global variable till we fix builtin-script.c to stop messing
|
|
|
|
* with it and switch to use the library functions in perf_evlist that came
|
2013-12-20 01:43:45 +08:00
|
|
|
* from builtin-record.c, i.e. use record_opts,
|
2011-11-25 18:19:45 +08:00
|
|
|
* perf_evlist__prepare_workload, etc instead of fork+exec'in 'perf record',
|
|
|
|
* using pipes, etc.
|
|
|
|
*/
|
2017-01-03 16:19:55 +08:00
|
|
|
static struct option __record_options[] = {
|
2011-11-25 18:19:45 +08:00
|
|
|
OPT_CALLBACK('e', "event", &record.evlist, "event",
|
2009-06-06 18:24:17 +08:00
|
|
|
"event selector. use 'perf list' to list available events",
|
2011-07-14 17:25:32 +08:00
|
|
|
parse_events_option),
|
2011-11-25 18:19:45 +08:00
|
|
|
OPT_CALLBACK(0, "filter", &record.evlist, "filter",
|
2009-10-15 11:22:07 +08:00
|
|
|
"event filter", parse_filter),
|
2015-07-10 15:36:10 +08:00
|
|
|
OPT_CALLBACK_NOOPT(0, "exclude-perf", &record.evlist,
|
|
|
|
NULL, "don't record events from perf itself",
|
|
|
|
exclude_perf),
|
2012-04-26 13:15:15 +08:00
|
|
|
OPT_STRING('p', "pid", &record.opts.target.pid, "pid",
|
2010-03-18 22:36:05 +08:00
|
|
|
"record events on existing process id"),
|
2012-04-26 13:15:15 +08:00
|
|
|
OPT_STRING('t', "tid", &record.opts.target.tid, "tid",
|
2010-03-18 22:36:05 +08:00
|
|
|
"record events on existing thread id"),
|
2011-11-25 18:19:45 +08:00
|
|
|
OPT_INTEGER('r', "realtime", &record.realtime_prio,
|
2009-05-26 15:17:18 +08:00
|
|
|
"collect data with this RT SCHED_FIFO priority"),
|
2014-01-15 04:52:14 +08:00
|
|
|
OPT_BOOLEAN(0, "no-buffering", &record.opts.no_buffering,
|
perf record: Add "nodelay" mode, disabled by default
Sometimes there is a need to use perf in "live-log" mode. The problem
is, for seldom events, actual info output is largely delayed because
perf-record reads sample data in whole pages.
So for such scenarious, add flag for perf-record to go in "nodelay"
mode. To track e.g. what's going on in icmp_rcv while ping is running
Use it with something like this:
(1) $ perf probe -L icmp_rcv | grep -U8 '^ *43\>'
goto error;
}
38 if (!pskb_pull(skb, sizeof(*icmph)))
goto error;
icmph = icmp_hdr(skb);
43 ICMPMSGIN_INC_STATS_BH(net, icmph->type);
/*
* 18 is the highest 'known' ICMP type. Anything else is a mystery
*
* RFC 1122: 3.2.2 Unknown ICMP messages types MUST be silently
* discarded.
*/
50 if (icmph->type > NR_ICMP_TYPES)
goto error;
$ perf probe icmp_rcv:43 'type=icmph->type'
(2) $ cat trace-icmp.py
[...]
def trace_begin():
print "in trace_begin"
def trace_end():
print "in trace_end"
def probe__icmp_rcv(event_name, context, common_cpu,
common_secs, common_nsecs, common_pid, common_comm,
__probe_ip, type):
print_header(event_name, common_cpu, common_secs, common_nsecs,
common_pid, common_comm)
print "__probe_ip=%u, type=%u\n" % \
(__probe_ip, type),
[...]
(3) $ perf record -a -D -e probe:icmp_rcv -o - | \
perf script -i - -s trace-icmp.py
Thanks to Peter Zijlstra for pointing how to do it.
Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Ingo Molnar <mingo@elte.hu>, Mike Galbraith <efault@gmx.de>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Cc: Tom Zanussi <tzanussi@gmail.com>
LKML-Reference: <20110112140613.GA11698@tugrik.mns.mnsspb.ru>
Signed-off-by: Kirill Smelkov <kirr@mns.spb.ru>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2011-01-12 22:59:36 +08:00
|
|
|
"collect data without buffering"),
|
2011-11-25 18:19:45 +08:00
|
|
|
OPT_BOOLEAN('R', "raw-samples", &record.opts.raw_samples,
|
2009-08-13 16:27:19 +08:00
|
|
|
"collect raw sample records from all opened counters"),
|
2012-04-26 13:15:15 +08:00
|
|
|
OPT_BOOLEAN('a', "all-cpus", &record.opts.target.system_wide,
|
2009-05-26 15:17:18 +08:00
|
|
|
"system-wide collection from all CPUs"),
|
2012-04-26 13:15:15 +08:00
|
|
|
OPT_STRING('C', "cpu", &record.opts.target.cpu_list, "cpu",
|
2010-05-28 18:00:01 +08:00
|
|
|
"list of cpus to monitor"),
|
2011-11-25 18:19:45 +08:00
|
|
|
OPT_U64('c', "count", &record.opts.user_interval, "event period to sample"),
|
2019-02-21 17:41:30 +08:00
|
|
|
OPT_STRING('o', "output", &record.data.path, "file",
|
2009-06-03 04:59:57 +08:00
|
|
|
"output file name"),
|
2013-11-18 17:55:57 +08:00
|
|
|
OPT_BOOLEAN_SET('i', "no-inherit", &record.opts.no_inherit,
|
|
|
|
&record.opts.no_inherit_set,
|
|
|
|
"child tasks do not inherit counters"),
|
perf record: Add --tail-synthesize option
When working with overwritable ring buffer there's a inconvenience
problem: if perf dumps data after a long period after it starts,
non-sample events may lost, which makes following 'perf report' unable
to identify proc name and mmap layout. For example:
# perf record -m 4 -e raw_syscalls:* -g --overwrite --switch-output \
dd if=/dev/zero of=/dev/null
send SIGUSR2 after dd runs long enough. The resuling perf.data lost
correct comm and mmap events:
# perf script -i perf.data.2016061522374354
perf 24478 [004] 2581325.601789: raw_syscalls:sys_exit: NR 0 = 512
^^^^
Should be 'dd'
27b2e8 syscall_slow_exit_work+0xfe2000e3 (/lib/modules/4.6.0-rc3+/build/vmlinux)
203cc7 do_syscall_64+0xfe200117 (/lib/modules/4.6.0-rc3+/build/vmlinux)
b18d83 return_from_SYSCALL_64+0xfe200000 (/lib/modules/4.6.0-rc3+/build/vmlinux)
7f47c417edf0 [unknown] ([unknown])
^^^^^^^^^^^^
Fail to unwind
This patch provides a '--tail-synthesize' option, allows perf to collect
system status when finalizing output file. In resuling output file, the
non-sample events reflect system status when dumping data.
After this patch:
# perf record -m 4 -e raw_syscalls:* -g --overwrite --switch-output --tail-synthesize \
dd if=/dev/zero of=/dev/null
# perf script -i perf.data.2016061600544998
dd 27364 [004] 2583244.994464: raw_syscalls:sys_enter: NR 1 (1, ...
^^
Correct comm
203a18 syscall_trace_enter_phase2+0xfe2001a8 ([kernel.kallsyms])
203aa5 syscall_trace_enter+0xfe200055 ([kernel.kallsyms])
203caa do_syscall_64+0xfe2000fa ([kernel.kallsyms])
b18d83 return_from_SYSCALL_64+0xfe200000 ([kernel.kallsyms])
d8e50 __GI___libc_write+0xffff01d9639f4010 (/tmp/oxygen_root-w00229757/lib64/libc-2.18.so)
^^^^^
Correct unwind
This option doesn't aim to solve this problem completely. If a process
terminates before SIGUSR2, we still lost its COMM and MMAP events. For
example, we can't unwind correctly from the final perf.data we get from
the previous example, because when perf collects the final output file
(when we press C-c), 'dd' has been terminated so its '/proc/<pid>/mmap'
becomes empty.
However, this is a cheaper choice. To completely solve this problem we
need to continously output non-sample events. To satisify the
requirement of daemonization, we need to merge them periodically. It is
possible but requires much more code and cycles.
Automatically select --tail-synthesize when --overwrite is provided.
Signed-off-by: Wang Nan <wangnan0@huawei.com>
Cc: He Kuang <hekuang@huawei.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Masami Hiramatsu <mhiramat@kernel.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Nilay Vaish <nilayvaish@gmail.com>
Cc: Zefan Li <lizefan@huawei.com>
Cc: pi3orama@163.com
Link: http://lkml.kernel.org/r/1468485287-33422-16-git-send-email-wangnan0@huawei.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2016-07-14 16:34:47 +08:00
|
|
|
OPT_BOOLEAN(0, "tail-synthesize", &record.opts.tail_synthesize,
|
|
|
|
"synthesize non-sample events at the end of output"),
|
perf tools: Enable overwrite settings
This patch allows following config terms and option:
Globally setting events to overwrite;
# perf record --overwrite ...
Set specific events to be overwrite or no-overwrite.
# perf record --event cycles/overwrite/ ...
# perf record --event cycles/no-overwrite/ ...
Add missing config terms and update the config term array size because
the longest string length has changed.
For overwritable events, it automatically selects attr.write_backward
since perf requires it to be backward for reading.
Test result:
# perf record --overwrite -e syscalls:*enter_nanosleep* usleep 1
[ perf record: Woken up 2 times to write data ]
[ perf record: Captured and wrote 0.011 MB perf.data (1 samples) ]
# perf evlist -v
syscalls:sys_enter_nanosleep: type: 2, size: 112, config: 0x134, { sample_period, sample_freq }: 1, sample_type: IP|TID|TIME|CPU|PERIOD|RAW, disabled: 1, inherit: 1, mmap: 1, comm: 1, enable_on_exec: 1, task: 1, sample_id_all: 1, exclude_guest: 1, mmap2: 1, comm_exec: 1, write_backward: 1
# Tip: use 'perf evlist --trace-fields' to show fields for tracepoint events
Signed-off-by: Wang Nan <wangnan0@huawei.com>
Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Acked-by: Jiri Olsa <jolsa@kernel.org>
Cc: Masami Hiramatsu <mhiramat@kernel.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Nilay Vaish <nilayvaish@gmail.com>
Cc: Zefan Li <lizefan@huawei.com>
Cc: pi3orama@163.com
Link: http://lkml.kernel.org/r/1468485287-33422-14-git-send-email-wangnan0@huawei.com
Signed-off-by: He Kuang <hekuang@huawei.com>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2016-07-14 16:34:45 +08:00
|
|
|
OPT_BOOLEAN(0, "overwrite", &record.opts.overwrite, "use overwrite mode"),
|
2019-03-12 13:30:37 +08:00
|
|
|
OPT_BOOLEAN(0, "no-bpf-event", &record.opts.no_bpf_event, "record bpf events"),
|
perf record: Throttle user defined frequencies to the maximum allowed
# perf record -F 200000 sleep 1
warning: Maximum frequency rate (15,000 Hz) exceeded, throttling from 200,000 Hz to 15,000 Hz.
The limit can be raised via /proc/sys/kernel/perf_event_max_sample_rate.
The kernel will lower it when perf's interrupts take too long.
Use --strict-freq to disable this throttling, refusing to record.
[ perf record: Woken up 1 times to write data ]
[ perf record: Captured and wrote 0.019 MB perf.data (15 samples) ]
# perf evlist -v
cycles:ppp: size: 112, { sample_period, sample_freq }: 15000, sample_type: IP|TID|TIME|PERIOD, disabled: 1, inherit: 1, mmap: 1, comm: 1, freq: 1, enable_on_exec: 1, task: 1, precise_ip: 3, sample_id_all: 1, exclude_guest: 1, mmap2: 1, comm_exec: 1
For those wanting that it fails if the desired frequency can't be used:
# perf record --strict-freq -F 200000 sleep 1
error: Maximum frequency rate (15,000 Hz) exceeded.
Please use -F freq option with a lower value or consider
tweaking /proc/sys/kernel/perf_event_max_sample_rate.
#
Suggested-by: Ingo Molnar <mingo@kernel.org>
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Wang Nan <wangnan0@huawei.com>
Link: https://lkml.kernel.org/n/tip-oyebruc44nlja499nqkr1nzn@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2018-03-02 01:52:50 +08:00
|
|
|
OPT_BOOLEAN(0, "strict-freq", &record.opts.strict_freq,
|
|
|
|
"Fail if the specified frequency can't be used"),
|
perf record: Allow asking for the maximum allowed sample rate
Add the handy '-F max' shortcut to reading and using the
kernel.perf_event_max_sample_rate value as the user supplied
sampling frequency:
# perf record -F max sleep 1
info: Using a maximum frequency rate of 15,000 Hz
[ perf record: Woken up 1 times to write data ]
[ perf record: Captured and wrote 0.019 MB perf.data (14 samples) ]
# sysctl kernel.perf_event_max_sample_rate
kernel.perf_event_max_sample_rate = 15000
# perf evlist -v
cycles:ppp: size: 112, { sample_period, sample_freq }: 15000, sample_type: IP|TID|TIME|PERIOD, disabled: 1, inherit: 1, mmap: 1, comm: 1, freq: 1, enable_on_exec: 1, task: 1, precise_ip: 3, sample_id_all: 1, exclude_guest: 1, mmap2: 1, comm_exec: 1
# perf record -F 10 sleep 1
[ perf record: Woken up 1 times to write data ]
[ perf record: Captured and wrote 0.019 MB perf.data (4 samples) ]
# perf evlist -v
cycles:ppp: size: 112, { sample_period, sample_freq }: 10, sample_type: IP|TID|TIME|PERIOD, disabled: 1, inherit: 1, mmap: 1, comm: 1, freq: 1, enable_on_exec: 1, task: 1, precise_ip: 3, sample_id_all: 1, exclude_guest: 1, mmap2: 1, comm_exec: 1
#
Suggested-by: Ingo Molnar <mingo@kernel.org>
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Wang Nan <wangnan0@huawei.com>
Link: https://lkml.kernel.org/n/tip-4y0tiuws62c64gp4cf0hme0m@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2018-03-02 00:46:23 +08:00
|
|
|
OPT_CALLBACK('F', "freq", &record.opts, "freq or 'max'",
|
|
|
|
"profile at this frequency",
|
|
|
|
record__parse_freq),
|
2015-04-09 23:53:46 +08:00
|
|
|
OPT_CALLBACK('m', "mmap-pages", &record.opts, "pages[,pages]",
|
|
|
|
"number of mmap data pages and AUX area tracing mmap pages",
|
|
|
|
record__parse_mmap_pages),
|
2011-11-25 18:19:45 +08:00
|
|
|
OPT_BOOLEAN(0, "group", &record.opts.group,
|
2011-08-17 18:42:07 +08:00
|
|
|
"put the counters into a counter group"),
|
2016-04-18 23:09:08 +08:00
|
|
|
OPT_CALLBACK_NOOPT('g', NULL, &callchain_param,
|
2013-10-26 22:25:33 +08:00
|
|
|
NULL, "enables call-graph recording" ,
|
|
|
|
&record_callchain_opt),
|
|
|
|
OPT_CALLBACK(0, "call-graph", &record.opts,
|
perf tools: Improve call graph documents and help messages
The --call-graph option is complex so we should provide better guide for
users. Also change help message to be consistent with config option
names. Now perf top will show help like below:
$ perf top --call-graph
Error: option `call-graph' requires a value
Usage: perf top [<options>]
--call-graph <record_mode[,record_size],print_type,threshold[,print_limit],order,sort_key[,branch]>
setup and enables call-graph (stack chain/backtrace):
record_mode: call graph recording mode (fp|dwarf|lbr)
record_size: if record_mode is 'dwarf', max size of stack recording (<bytes>)
default: 8192 (bytes)
print_type: call graph printing style (graph|flat|fractal|none)
threshold: minimum call graph inclusion threshold (<percent>)
print_limit: maximum number of call graph entry (<number>)
order: call graph order (caller|callee)
sort_key: call graph sort key (function|address)
branch: include last branch info to call graph (branch)
Default: fp,graph,0.5,caller,function
Requested-by: Ingo Molnar <mingo@kernel.org>
Signed-off-by: Namhyung Kim <namhyung@kernel.org>
Acked-by: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Borislav Petkov <bp@suse.de>
Cc: Brendan Gregg <brendan.d.gregg@gmail.com>
Cc: Chandler Carruth <chandlerc@gmail.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Stephane Eranian <eranian@google.com>
Cc: Wang Nan <wangnan0@huawei.com>
Link: http://lkml.kernel.org/r/1445524112-5201-2-git-send-email-namhyung@kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2015-10-22 22:28:32 +08:00
|
|
|
"record_mode[,record_size]", record_callchain_help,
|
2013-10-26 22:25:33 +08:00
|
|
|
&record_parse_callchain_opt),
|
2010-04-13 16:37:33 +08:00
|
|
|
OPT_INCR('v', "verbose", &verbose,
|
2009-06-07 23:39:02 +08:00
|
|
|
"be more verbose (show counter open errors, etc)"),
|
2010-10-27 01:20:09 +08:00
|
|
|
OPT_BOOLEAN('q', "quiet", &quiet, "don't print any message"),
|
2011-11-25 18:19:45 +08:00
|
|
|
OPT_BOOLEAN('s', "stat", &record.opts.inherit_stat,
|
2009-06-25 03:12:48 +08:00
|
|
|
"per thread counts"),
|
2015-06-10 22:48:50 +08:00
|
|
|
OPT_BOOLEAN('d', "data", &record.opts.sample_address, "Record the sample addresses"),
|
2017-08-30 01:11:08 +08:00
|
|
|
OPT_BOOLEAN(0, "phys-data", &record.opts.sample_phys_addr,
|
|
|
|
"Record the sample physical addresses"),
|
2016-08-02 02:02:35 +08:00
|
|
|
OPT_BOOLEAN(0, "sample-cpu", &record.opts.sample_cpu, "Record the sample cpu"),
|
2015-07-06 19:51:01 +08:00
|
|
|
OPT_BOOLEAN_SET('T', "timestamp", &record.opts.sample_time,
|
|
|
|
&record.opts.sample_time_set,
|
|
|
|
"Record the sample timestamps"),
|
perf record: Fix period option handling
Stephan reported we don't unset PERIOD sample type when --no-period is
specified. Adding the unset check and reset PERIOD if --no-period is
specified.
Committer notes:
Check the sample_type, it shouldn't have PERF_SAMPLE_PERIOD there when
--no-period is used.
Before:
# perf record --no-period sleep 1
[ perf record: Woken up 1 times to write data ]
[ perf record: Captured and wrote 0.018 MB perf.data (7 samples) ]
# perf evlist -v
cycles:ppp: size: 112, { sample_period, sample_freq }: 4000, sample_type: IP|TID|TIME|PERIOD, disabled: 1, inherit: 1, mmap: 1, comm: 1, freq: 1, enable_on_exec: 1, task: 1, precise_ip: 3, sample_id_all: 1, exclude_guest: 1, mmap2: 1, comm_exec: 1
#
After:
[root@jouet ~]# perf record --no-period sleep 1
[ perf record: Woken up 1 times to write data ]
[ perf record: Captured and wrote 0.019 MB perf.data (17 samples) ]
[root@jouet ~]# perf evlist -v
cycles:ppp: size: 112, { sample_period, sample_freq }: 4000, sample_type: IP|TID|TIME, disabled: 1, inherit: 1, mmap: 1, comm: 1, freq: 1, enable_on_exec: 1, task: 1, precise_ip: 3, sample_id_all: 1, exclude_guest: 1, mmap2: 1, comm_exec: 1
[root@jouet ~]#
Reported-by: Stephane Eranian <eranian@google.com>
Signed-off-by: Jiri Olsa <jolsa@kernel.org>
Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Tested-by: Stephane Eranian <eranian@google.com>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Andi Kleen <ak@linux.intel.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Link: http://lkml.kernel.org/r/20180201083812.11359-3-jolsa@kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2018-02-01 16:38:11 +08:00
|
|
|
OPT_BOOLEAN_SET('P', "period", &record.opts.period, &record.opts.period_set,
|
|
|
|
"Record the sample period"),
|
2011-11-25 18:19:45 +08:00
|
|
|
OPT_BOOLEAN('n', "no-samples", &record.opts.no_samples,
|
2009-06-25 03:12:48 +08:00
|
|
|
"don't sample"),
|
2016-01-25 17:56:19 +08:00
|
|
|
OPT_BOOLEAN_SET('N', "no-buildid-cache", &record.no_buildid_cache,
|
|
|
|
&record.no_buildid_cache_set,
|
|
|
|
"do not update the buildid cache"),
|
|
|
|
OPT_BOOLEAN_SET('B', "no-buildid", &record.no_buildid,
|
|
|
|
&record.no_buildid_set,
|
|
|
|
"do not collect buildids in perf.data"),
|
2011-11-25 18:19:45 +08:00
|
|
|
OPT_CALLBACK('G', "cgroup", &record.evlist, "name",
|
perf tool: Add cgroup support
This patch adds the ability to filter monitoring based on container groups
(cgroups) for both perf stat and perf record. It is possible to monitor
multiple cgroup in parallel. There is one cgroup per event. The cgroups to
monitor are passed via a new -G option followed by a comma separated list of
cgroup names.
The cgroup filesystem has to be mounted. Given a cgroup name, the perf tool
finds the corresponding directory in the cgroup filesystem and opens it. It
then passes that file descriptor to the kernel.
Example:
$ perf stat -B -a -e cycles:u,cycles:u,cycles:u -G test1,,test2 -- sleep 1
Performance counter stats for 'sleep 1':
2,368,667,414 cycles test1
2,369,661,459 cycles
<not counted> cycles test2
1.001856890 seconds time elapsed
Signed-off-by: Stephane Eranian <eranian@google.com>
Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
LKML-Reference: <4d590290.825bdf0a.7d0a.4890@mx.google.com>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
2011-02-14 17:20:01 +08:00
|
|
|
"monitor event in cgroup name only",
|
|
|
|
parse_cgroups),
|
2014-01-15 04:58:12 +08:00
|
|
|
OPT_UINTEGER('D', "delay", &record.opts.initial_delay,
|
2014-01-12 05:38:27 +08:00
|
|
|
"ms to wait before starting measurement after program start"),
|
2012-04-26 13:15:15 +08:00
|
|
|
OPT_STRING('u', "uid", &record.opts.target.uid_str, "user",
|
|
|
|
"user to profile"),
|
2012-03-09 06:47:45 +08:00
|
|
|
|
|
|
|
OPT_CALLBACK_NOOPT('b', "branch-any", &record.opts.branch_stack,
|
|
|
|
"branch any", "sample any taken branches",
|
|
|
|
parse_branch_stack),
|
|
|
|
|
|
|
|
OPT_CALLBACK('j', "branch-filter", &record.opts.branch_stack,
|
|
|
|
"branch filter mask", "branch stack filter modes",
|
2012-02-10 06:21:02 +08:00
|
|
|
parse_branch_stack),
|
2013-01-24 23:10:29 +08:00
|
|
|
OPT_BOOLEAN('W', "weight", &record.opts.sample_weight,
|
|
|
|
"sample by weight (on special events only)"),
|
2013-09-20 22:40:43 +08:00
|
|
|
OPT_BOOLEAN(0, "transaction", &record.opts.sample_transaction,
|
|
|
|
"sample transaction flags (special events only)"),
|
2013-11-15 21:52:29 +08:00
|
|
|
OPT_BOOLEAN(0, "per-thread", &record.opts.target.per_thread,
|
|
|
|
"use per-thread mmaps"),
|
perf record: Add ability to name registers to record
This patch modifies the -I/--int-regs option to enablepassing the name
of the registers to sample on interrupt. Registers can be specified by
their symbolic names. For instance on x86, --intr-regs=ax,si.
The motivation is to reduce the size of the perf.data file and the
overhead of sampling by only collecting the registers useful to a
specific analysis. For instance, for value profiling, sampling only the
registers used to passed arguements to functions.
With no parameter, the --intr-regs still records all possible registers
based on the architecture.
To name registers, it is necessary to use the long form of the option,
i.e., --intr-regs:
$ perf record --intr-regs=si,di,r8,r9 .....
To record any possible registers:
$ perf record -I .....
$ perf report --intr-regs ...
To display the register, one can use perf report -D
To list the available registers:
$ perf record --intr-regs=\?
available registers: AX BX CX DX SI DI BP SP IP FLAGS CS SS R8 R9 R10 R11 R12 R13 R14 R15
Signed-off-by: Stephane Eranian <eranian@google.com>
Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Andi Kleen <ak@linux.intel.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Kan Liang <kan.liang@intel.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Link: http://lkml.kernel.org/r/1441039273-16260-4-git-send-email-eranian@google.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2015-09-01 00:41:12 +08:00
|
|
|
OPT_CALLBACK_OPTARG('I', "intr-regs", &record.opts.sample_intr_regs, NULL, "any register",
|
|
|
|
"sample selected machine registers on interrupt,"
|
|
|
|
" use -I ? to list register names", parse_regs),
|
2017-09-06 01:00:28 +08:00
|
|
|
OPT_CALLBACK_OPTARG(0, "user-regs", &record.opts.sample_user_regs, NULL, "any register",
|
|
|
|
"sample selected machine registers on interrupt,"
|
|
|
|
" use -I ? to list register names", parse_regs),
|
2015-02-25 07:13:40 +08:00
|
|
|
OPT_BOOLEAN(0, "running-time", &record.opts.running_time,
|
|
|
|
"Record running/enabled time of read (:S) events"),
|
2015-03-31 06:19:31 +08:00
|
|
|
OPT_CALLBACK('k', "clockid", &record.opts,
|
|
|
|
"clockid", "clockid to use for events, see clock_gettime()",
|
|
|
|
parse_clockid),
|
2015-04-30 22:37:32 +08:00
|
|
|
OPT_STRING_OPTARG('S', "snapshot", &record.opts.auxtrace_snapshot_opts,
|
|
|
|
"opts", "AUX area tracing Snapshot Mode", ""),
|
2018-12-05 04:34:20 +08:00
|
|
|
OPT_UINTEGER(0, "proc-map-timeout", &proc_map_timeout,
|
2015-06-17 21:51:11 +08:00
|
|
|
"per thread proc mmap processing timeout in ms"),
|
perf tools: Add PERF_RECORD_NAMESPACES to include namespaces related info
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>
#
Signed-off-by: Hari Bathini <hbathini@linux.vnet.ibm.com>
Acked-by: Jiri Olsa <jolsa@kernel.org>
Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Alexei Starovoitov <ast@fb.com>
Cc: Ananth N Mavinakayanahalli <ananth@linux.vnet.ibm.com>
Cc: Aravinda Prasad <aravinda@linux.vnet.ibm.com>
Cc: Brendan Gregg <brendan.d.gregg@gmail.com>
Cc: Daniel Borkmann <daniel@iogearbox.net>
Cc: Eric Biederman <ebiederm@xmission.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Sargun Dhillon <sargun@sargun.me>
Cc: Steven Rostedt <rostedt@goodmis.org>
Link: http://lkml.kernel.org/r/148891930386.25309.18412039920746995488.stgit@hbathini.in.ibm.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2017-03-08 04:41:43 +08:00
|
|
|
OPT_BOOLEAN(0, "namespaces", &record.opts.record_namespaces,
|
|
|
|
"Record namespaces events"),
|
2015-07-21 17:44:04 +08:00
|
|
|
OPT_BOOLEAN(0, "switch-events", &record.opts.record_switch_events,
|
|
|
|
"Record context switch events"),
|
2016-02-15 16:34:31 +08:00
|
|
|
OPT_BOOLEAN_FLAG(0, "all-kernel", &record.opts.all_kernel,
|
|
|
|
"Configure all used events to run in kernel space.",
|
|
|
|
PARSE_OPT_EXCLUSIVE),
|
|
|
|
OPT_BOOLEAN_FLAG(0, "all-user", &record.opts.all_user,
|
|
|
|
"Configure all used events to run in user space.",
|
|
|
|
PARSE_OPT_EXCLUSIVE),
|
2015-10-14 20:41:19 +08:00
|
|
|
OPT_STRING(0, "clang-path", &llvm_param.clang_path, "clang path",
|
|
|
|
"clang binary to use for compiling BPF scriptlets"),
|
|
|
|
OPT_STRING(0, "clang-opt", &llvm_param.clang_opt, "clang options",
|
|
|
|
"options passed to clang when compiling BPF scriptlets"),
|
2015-12-14 18:39:23 +08:00
|
|
|
OPT_STRING(0, "vmlinux", &symbol_conf.vmlinux_name,
|
|
|
|
"file", "vmlinux pathname"),
|
2016-01-11 21:37:09 +08:00
|
|
|
OPT_BOOLEAN(0, "buildid-all", &record.buildid_all,
|
|
|
|
"Record build-id of all DSOs regardless of hits"),
|
2016-04-13 16:21:07 +08:00
|
|
|
OPT_BOOLEAN(0, "timestamp-filename", &record.timestamp_filename,
|
|
|
|
"append timestamp to output filename"),
|
perf record: Record the first and last sample time in the header
In the default 'perf record' configuration, all samples are processed,
to create the HEADER_BUILD_ID table. So it's very easy to get the
first/last samples and save the time to perf file header via the
function write_sample_time().
Later, at post processing time, perf report/script will fetch the time
from perf file header.
Committer testing:
# perf record -a sleep 1
[ perf record: Woken up 1 times to write data ]
[ perf record: Captured and wrote 2.099 MB perf.data (1101 samples) ]
[root@jouet home]# perf report --header | grep "time of "
# time of first sample : 22947.909226
# time of last sample : 22948.910704
#
# perf report -D | grep PERF_RECORD_SAMPLE\(
0 22947909226101 0x20bb68 [0x30]: PERF_RECORD_SAMPLE(IP, 0x4001): 0/0: 0xffffffffa21b1af3 period: 1 addr: 0
0 22947909229928 0x20bb98 [0x30]: PERF_RECORD_SAMPLE(IP, 0x4001): 0/0: 0xffffffffa200d204 period: 1 addr: 0
<SNIP>
3 22948910397351 0x219360 [0x30]: PERF_RECORD_SAMPLE(IP, 0x4001): 28251/28251: 0xffffffffa22071d8 period: 169518 addr: 0
0 22948910652380 0x20f120 [0x30]: PERF_RECORD_SAMPLE(IP, 0x4001): 0/0: 0xffffffffa2856816 period: 198807 addr: 0
2 22948910704034 0x2172d0 [0x30]: PERF_RECORD_SAMPLE(IP, 0x4001): 0/0: 0xffffffffa2856816 period: 88111 addr: 0
#
Changelog:
v7: Just update the patch description according to Arnaldo's suggestion.
v6: Currently '--buildid-all' is not enabled at default. So the walking
on all samples is the default operation. There is no big overhead
to calculate the timestamp boundary in process_sample_event handler
once we already go through all samples. So the timestamp boundary
calculation is enabled by default when '--buildid-all' is not enabled.
While if '--buildid-all' is enabled, we creates a new option
"--timestamp-boundary" for user to decide if it enables the
timestamp boundary calculation.
v5: There is an issue that the sample walking can only work when
'--buildid-all' is not enabled. So we need to let the walking
be able to work even if '--buildid-all' is enabled and let the
processing skips the dso hit marking for this case.
At first, I want to provide a new option "--record-time-boundaries".
While after consideration, I think a new option is not very
necessary.
v3: Remove the definitions of first_sample_time and last_sample_time
from struct record and directly save them in perf_evlist.
Signed-off-by: Jin Yao <yao.jin@linux.intel.com>
Acked-by: Jiri Olsa <jolsa@kernel.org>
Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Andi Kleen <ak@linux.intel.com>
Cc: Kan Liang <kan.liang@intel.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Link: http://lkml.kernel.org/r/1512738826-2628-3-git-send-email-yao.jin@linux.intel.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2017-12-08 21:13:42 +08:00
|
|
|
OPT_BOOLEAN(0, "timestamp-boundary", &record.timestamp_boundary,
|
|
|
|
"Record timestamp boundary (time of first/last samples)"),
|
2017-01-09 17:51:57 +08:00
|
|
|
OPT_STRING_OPTARG_SET(0, "switch-output", &record.switch_output.str,
|
2019-03-15 06:49:56 +08:00
|
|
|
&record.switch_output.set, "signal or size[BKMG] or time[smhd]",
|
|
|
|
"Switch output when receiving SIGUSR2 (signal) or cross a size or time threshold",
|
2017-01-09 17:51:58 +08:00
|
|
|
"signal"),
|
2019-03-15 06:49:55 +08:00
|
|
|
OPT_INTEGER(0, "switch-max-files", &record.switch_output.num_files,
|
|
|
|
"Limit number of switch output generated files"),
|
2016-06-16 16:02:41 +08:00
|
|
|
OPT_BOOLEAN(0, "dry-run", &dry_run,
|
|
|
|
"Parse options then exit"),
|
2018-11-06 17:04:58 +08:00
|
|
|
#ifdef HAVE_AIO_SUPPORT
|
2018-11-06 17:07:19 +08:00
|
|
|
OPT_CALLBACK_OPTARG(0, "aio", &record.opts,
|
|
|
|
&nr_cblocks_default, "n", "Use <n> control blocks in asynchronous trace writing mode (default: 1, max: 4)",
|
2018-11-06 17:04:58 +08:00
|
|
|
record__aio_parse),
|
|
|
|
#endif
|
2019-01-23 01:52:03 +08:00
|
|
|
OPT_CALLBACK(0, "affinity", &record.opts, "node|cpu",
|
|
|
|
"Set affinity mask of trace reading thread to NUMA node cpu mask or cpu of processed mmap buffer",
|
|
|
|
record__parse_affinity),
|
2009-05-26 15:17:18 +08:00
|
|
|
OPT_END()
|
|
|
|
};
|
|
|
|
|
2014-10-22 23:15:46 +08:00
|
|
|
struct option *record_options = __record_options;
|
|
|
|
|
2017-03-27 22:47:20 +08:00
|
|
|
int cmd_record(int argc, const char **argv)
|
2009-05-26 15:17:18 +08:00
|
|
|
{
|
2015-04-09 23:53:45 +08:00
|
|
|
int err;
|
2013-12-20 01:38:03 +08:00
|
|
|
struct record *rec = &record;
|
2012-05-07 13:09:02 +08:00
|
|
|
char errbuf[BUFSIZ];
|
2009-05-26 15:17:18 +08:00
|
|
|
|
perf record: Allow asking for the maximum allowed sample rate
Add the handy '-F max' shortcut to reading and using the
kernel.perf_event_max_sample_rate value as the user supplied
sampling frequency:
# perf record -F max sleep 1
info: Using a maximum frequency rate of 15,000 Hz
[ perf record: Woken up 1 times to write data ]
[ perf record: Captured and wrote 0.019 MB perf.data (14 samples) ]
# sysctl kernel.perf_event_max_sample_rate
kernel.perf_event_max_sample_rate = 15000
# perf evlist -v
cycles:ppp: size: 112, { sample_period, sample_freq }: 15000, sample_type: IP|TID|TIME|PERIOD, disabled: 1, inherit: 1, mmap: 1, comm: 1, freq: 1, enable_on_exec: 1, task: 1, precise_ip: 3, sample_id_all: 1, exclude_guest: 1, mmap2: 1, comm_exec: 1
# perf record -F 10 sleep 1
[ perf record: Woken up 1 times to write data ]
[ perf record: Captured and wrote 0.019 MB perf.data (4 samples) ]
# perf evlist -v
cycles:ppp: size: 112, { sample_period, sample_freq }: 10, sample_type: IP|TID|TIME|PERIOD, disabled: 1, inherit: 1, mmap: 1, comm: 1, freq: 1, enable_on_exec: 1, task: 1, precise_ip: 3, sample_id_all: 1, exclude_guest: 1, mmap2: 1, comm_exec: 1
#
Suggested-by: Ingo Molnar <mingo@kernel.org>
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Wang Nan <wangnan0@huawei.com>
Link: https://lkml.kernel.org/n/tip-4y0tiuws62c64gp4cf0hme0m@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2018-03-02 00:46:23 +08:00
|
|
|
setlocale(LC_ALL, "");
|
|
|
|
|
perf tools: Make options always available, even if required libs not linked
This patch keeps options of perf builtins same in all conditions. If
one option is disabled because of compiling options, users should be
notified.
Masami suggested another implementation in [1] that, by adding a
OPTION_NEXT_DEPENDS option before those options in the 'struct option'
array, options parser knows an option is disabled. However, in some
cases this array is reordered (options__order()). In addition, in
parse-option.c that array is const, so we can't simply merge
information in decorator option into the affacted option.
This patch chooses a simpler implementation that, introducing a
set_option_nobuild() function and two option parsing flags. Builtins
with such options should call set_option_nobuild() before option
parsing. The complexity of this patch is because we want some of options
can be skipped safely. In this case their arguments should also be
consumed.
Options in 'perf record' and 'perf probe' are fixed in this patch.
[1] http://lkml.kernel.org/g/50399556C9727B4D88A595C8584AAB3752627CD4@GSjpTKYDCembx32.service.hitachi.net
Test result:
Normal case:
# ./perf probe --vmlinux /tmp/vmlinux sys_write
Added new event:
probe:sys_write (on sys_write)
You can now use it in all perf tools, such as:
perf record -e probe:sys_write -aR sleep 1
Build with NO_DWARF=1:
# ./perf probe -L sys_write
Error: switch `L' is not available because NO_DWARF=1
Usage: perf probe [<options>] 'PROBEDEF' ['PROBEDEF' ...]
or: perf probe [<options>] --add 'PROBEDEF' [--add 'PROBEDEF' ...]
or: perf probe [<options>] --del '[GROUP:]EVENT' ...
or: perf probe --list [GROUP:]EVENT ...
or: perf probe [<options>] --funcs
-L, --line <FUNC[:RLN[+NUM|-RLN2]]|SRC:ALN[+NUM|-ALN2]>
Show source code lines.
(not built-in because NO_DWARF=1)
# ./perf probe -k /tmp/vmlinux sys_write
Warning: switch `k' is being ignored because NO_DWARF=1
Added new event:
probe:sys_write (on sys_write)
You can now use it in all perf tools, such as:
perf record -e probe:sys_write -aR sleep 1
# ./perf probe --vmlinux /tmp/vmlinux sys_write
Warning: option `vmlinux' is being ignored because NO_DWARF=1
Added new event:
[SNIP]
# ./perf probe -l
Usage: perf probe [<options>] 'PROBEDEF' ['PROBEDEF' ...]
or: perf probe [<options>] --add 'PROBEDEF' [--add 'PROBEDEF' ...]
...
-k, --vmlinux <file> vmlinux pathname
(not built-in because NO_DWARF=1)
-L, --line <FUNC[:RLN[+NUM|-RLN2]]|SRC:ALN[+NUM|-ALN2]>
Show source code lines.
(not built-in because NO_DWARF=1)
...
-V, --vars <FUNC[@SRC][+OFF|%return|:RL|;PT]|SRC:AL|SRC;PT>
Show accessible variables on PROBEDEF
(not built-in because NO_DWARF=1)
--externs Show external variables too (with --vars only)
(not built-in because NO_DWARF=1)
--no-inlines Don't search inlined functions
(not built-in because NO_DWARF=1)
--range Show variables location range in scope (with --vars only)
(not built-in because NO_DWARF=1)
Signed-off-by: Wang Nan <wangnan0@huawei.com>
Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Alexei Starovoitov <ast@kernel.org>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Zefan Li <lizefan@huawei.com>
Cc: pi3orama@163.com
Link: http://lkml.kernel.org/r/1450089563-122430-14-git-send-email-wangnan0@huawei.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2015-12-14 18:39:22 +08:00
|
|
|
#ifndef HAVE_LIBBPF_SUPPORT
|
|
|
|
# define set_nobuild(s, l, c) set_option_nobuild(record_options, s, l, "NO_LIBBPF=1", c)
|
|
|
|
set_nobuild('\0', "clang-path", true);
|
|
|
|
set_nobuild('\0', "clang-opt", true);
|
|
|
|
# undef set_nobuild
|
2015-12-14 18:39:23 +08:00
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifndef HAVE_BPF_PROLOGUE
|
|
|
|
# if !defined (HAVE_DWARF_SUPPORT)
|
|
|
|
# define REASON "NO_DWARF=1"
|
|
|
|
# elif !defined (HAVE_LIBBPF_SUPPORT)
|
|
|
|
# define REASON "NO_LIBBPF=1"
|
|
|
|
# else
|
|
|
|
# define REASON "this architecture doesn't support BPF prologue"
|
|
|
|
# endif
|
|
|
|
# define set_nobuild(s, l, c) set_option_nobuild(record_options, s, l, REASON, c)
|
|
|
|
set_nobuild('\0', "vmlinux", true);
|
|
|
|
# undef set_nobuild
|
|
|
|
# undef REASON
|
perf tools: Make options always available, even if required libs not linked
This patch keeps options of perf builtins same in all conditions. If
one option is disabled because of compiling options, users should be
notified.
Masami suggested another implementation in [1] that, by adding a
OPTION_NEXT_DEPENDS option before those options in the 'struct option'
array, options parser knows an option is disabled. However, in some
cases this array is reordered (options__order()). In addition, in
parse-option.c that array is const, so we can't simply merge
information in decorator option into the affacted option.
This patch chooses a simpler implementation that, introducing a
set_option_nobuild() function and two option parsing flags. Builtins
with such options should call set_option_nobuild() before option
parsing. The complexity of this patch is because we want some of options
can be skipped safely. In this case their arguments should also be
consumed.
Options in 'perf record' and 'perf probe' are fixed in this patch.
[1] http://lkml.kernel.org/g/50399556C9727B4D88A595C8584AAB3752627CD4@GSjpTKYDCembx32.service.hitachi.net
Test result:
Normal case:
# ./perf probe --vmlinux /tmp/vmlinux sys_write
Added new event:
probe:sys_write (on sys_write)
You can now use it in all perf tools, such as:
perf record -e probe:sys_write -aR sleep 1
Build with NO_DWARF=1:
# ./perf probe -L sys_write
Error: switch `L' is not available because NO_DWARF=1
Usage: perf probe [<options>] 'PROBEDEF' ['PROBEDEF' ...]
or: perf probe [<options>] --add 'PROBEDEF' [--add 'PROBEDEF' ...]
or: perf probe [<options>] --del '[GROUP:]EVENT' ...
or: perf probe --list [GROUP:]EVENT ...
or: perf probe [<options>] --funcs
-L, --line <FUNC[:RLN[+NUM|-RLN2]]|SRC:ALN[+NUM|-ALN2]>
Show source code lines.
(not built-in because NO_DWARF=1)
# ./perf probe -k /tmp/vmlinux sys_write
Warning: switch `k' is being ignored because NO_DWARF=1
Added new event:
probe:sys_write (on sys_write)
You can now use it in all perf tools, such as:
perf record -e probe:sys_write -aR sleep 1
# ./perf probe --vmlinux /tmp/vmlinux sys_write
Warning: option `vmlinux' is being ignored because NO_DWARF=1
Added new event:
[SNIP]
# ./perf probe -l
Usage: perf probe [<options>] 'PROBEDEF' ['PROBEDEF' ...]
or: perf probe [<options>] --add 'PROBEDEF' [--add 'PROBEDEF' ...]
...
-k, --vmlinux <file> vmlinux pathname
(not built-in because NO_DWARF=1)
-L, --line <FUNC[:RLN[+NUM|-RLN2]]|SRC:ALN[+NUM|-ALN2]>
Show source code lines.
(not built-in because NO_DWARF=1)
...
-V, --vars <FUNC[@SRC][+OFF|%return|:RL|;PT]|SRC:AL|SRC;PT>
Show accessible variables on PROBEDEF
(not built-in because NO_DWARF=1)
--externs Show external variables too (with --vars only)
(not built-in because NO_DWARF=1)
--no-inlines Don't search inlined functions
(not built-in because NO_DWARF=1)
--range Show variables location range in scope (with --vars only)
(not built-in because NO_DWARF=1)
Signed-off-by: Wang Nan <wangnan0@huawei.com>
Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Alexei Starovoitov <ast@kernel.org>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Zefan Li <lizefan@huawei.com>
Cc: pi3orama@163.com
Link: http://lkml.kernel.org/r/1450089563-122430-14-git-send-email-wangnan0@huawei.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2015-12-14 18:39:22 +08:00
|
|
|
#endif
|
|
|
|
|
2019-01-23 01:47:43 +08:00
|
|
|
CPU_ZERO(&rec->affinity_mask);
|
|
|
|
rec->opts.affinity = PERF_AFFINITY_SYS;
|
|
|
|
|
2014-01-04 02:03:26 +08:00
|
|
|
rec->evlist = perf_evlist__new();
|
|
|
|
if (rec->evlist == NULL)
|
2011-01-12 06:56:53 +08:00
|
|
|
return -ENOMEM;
|
|
|
|
|
2017-01-25 00:44:10 +08:00
|
|
|
err = perf_config(perf_record_config, rec);
|
|
|
|
if (err)
|
|
|
|
return err;
|
2014-02-03 19:44:42 +08:00
|
|
|
|
2010-11-10 22:11:30 +08:00
|
|
|
argc = parse_options(argc, argv, record_options, record_usage,
|
2009-12-16 06:04:40 +08:00
|
|
|
PARSE_OPT_STOP_AT_NON_OPTION);
|
2017-02-17 16:17:42 +08:00
|
|
|
if (quiet)
|
|
|
|
perf_quiet_option();
|
2017-02-18 01:00:18 +08:00
|
|
|
|
|
|
|
/* Make system wide (-a) the default target. */
|
2013-11-13 03:46:16 +08:00
|
|
|
if (!argc && target__none(&rec->opts.target))
|
2017-02-18 01:00:18 +08:00
|
|
|
rec->opts.target.system_wide = true;
|
2009-05-26 15:17:18 +08:00
|
|
|
|
2012-04-26 13:15:15 +08:00
|
|
|
if (nr_cgroups && !rec->opts.target.system_wide) {
|
2015-10-24 23:49:27 +08:00
|
|
|
usage_with_options_msg(record_usage, record_options,
|
|
|
|
"cgroup monitoring only available in system-wide mode");
|
|
|
|
|
perf tool: Add cgroup support
This patch adds the ability to filter monitoring based on container groups
(cgroups) for both perf stat and perf record. It is possible to monitor
multiple cgroup in parallel. There is one cgroup per event. The cgroups to
monitor are passed via a new -G option followed by a comma separated list of
cgroup names.
The cgroup filesystem has to be mounted. Given a cgroup name, the perf tool
finds the corresponding directory in the cgroup filesystem and opens it. It
then passes that file descriptor to the kernel.
Example:
$ perf stat -B -a -e cycles:u,cycles:u,cycles:u -G test1,,test2 -- sleep 1
Performance counter stats for 'sleep 1':
2,368,667,414 cycles test1
2,369,661,459 cycles
<not counted> cycles test2
1.001856890 seconds time elapsed
Signed-off-by: Stephane Eranian <eranian@google.com>
Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
LKML-Reference: <4d590290.825bdf0a.7d0a.4890@mx.google.com>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
2011-02-14 17:20:01 +08:00
|
|
|
}
|
2015-07-21 17:44:04 +08:00
|
|
|
if (rec->opts.record_switch_events &&
|
|
|
|
!perf_can_record_switch_events()) {
|
2015-10-24 23:49:27 +08:00
|
|
|
ui__error("kernel does not support recording context switch events\n");
|
|
|
|
parse_options_usage(record_usage, record_options, "switch-events", 0);
|
|
|
|
return -EINVAL;
|
2015-07-21 17:44:04 +08:00
|
|
|
}
|
perf tool: Add cgroup support
This patch adds the ability to filter monitoring based on container groups
(cgroups) for both perf stat and perf record. It is possible to monitor
multiple cgroup in parallel. There is one cgroup per event. The cgroups to
monitor are passed via a new -G option followed by a comma separated list of
cgroup names.
The cgroup filesystem has to be mounted. Given a cgroup name, the perf tool
finds the corresponding directory in the cgroup filesystem and opens it. It
then passes that file descriptor to the kernel.
Example:
$ perf stat -B -a -e cycles:u,cycles:u,cycles:u -G test1,,test2 -- sleep 1
Performance counter stats for 'sleep 1':
2,368,667,414 cycles test1
2,369,661,459 cycles
<not counted> cycles test2
1.001856890 seconds time elapsed
Signed-off-by: Stephane Eranian <eranian@google.com>
Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
LKML-Reference: <4d590290.825bdf0a.7d0a.4890@mx.google.com>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
2011-02-14 17:20:01 +08:00
|
|
|
|
2017-01-09 17:51:57 +08:00
|
|
|
if (switch_output_setup(rec)) {
|
|
|
|
parse_options_usage(record_usage, record_options, "switch-output", 0);
|
|
|
|
return -EINVAL;
|
|
|
|
}
|
|
|
|
|
2017-01-09 17:52:00 +08:00
|
|
|
if (rec->switch_output.time) {
|
|
|
|
signal(SIGALRM, alarm_sig_handler);
|
|
|
|
alarm(rec->switch_output.time);
|
|
|
|
}
|
|
|
|
|
2019-03-15 06:49:55 +08:00
|
|
|
if (rec->switch_output.num_files) {
|
|
|
|
rec->switch_output.filenames = calloc(sizeof(char *),
|
|
|
|
rec->switch_output.num_files);
|
|
|
|
if (!rec->switch_output.filenames)
|
|
|
|
return -EINVAL;
|
|
|
|
}
|
|
|
|
|
2016-09-23 22:38:39 +08:00
|
|
|
/*
|
|
|
|
* Allow aliases to facilitate the lookup of symbols for address
|
|
|
|
* filters. Refer to auxtrace_parse_filters().
|
|
|
|
*/
|
|
|
|
symbol_conf.allow_aliases = true;
|
|
|
|
|
|
|
|
symbol__init(NULL);
|
|
|
|
|
2018-03-06 17:13:12 +08:00
|
|
|
err = record__auxtrace_init(rec);
|
2016-09-23 22:38:39 +08:00
|
|
|
if (err)
|
|
|
|
goto out;
|
|
|
|
|
2016-06-16 16:02:41 +08:00
|
|
|
if (dry_run)
|
2016-09-23 22:38:37 +08:00
|
|
|
goto out;
|
2016-06-16 16:02:41 +08:00
|
|
|
|
2016-04-08 23:07:24 +08:00
|
|
|
err = bpf__setup_stdout(rec->evlist);
|
|
|
|
if (err) {
|
|
|
|
bpf__strerror_setup_stdout(rec->evlist, err, errbuf, sizeof(errbuf));
|
|
|
|
pr_err("ERROR: Setup BPF stdout failed: %s\n",
|
|
|
|
errbuf);
|
2016-09-23 22:38:37 +08:00
|
|
|
goto out;
|
2016-04-08 23:07:24 +08:00
|
|
|
}
|
|
|
|
|
2015-04-09 23:53:45 +08:00
|
|
|
err = -ENOMEM;
|
|
|
|
|
perf record: Ignore kptr_restrict when not sampling the kernel
If we're not sampling the kernel, we shouldn't care about kptr_restrict
neither synthesize anything for assisting in resolving kernel samples,
like the reference relocation symbol or kernel modules information.
Before:
$ cat /proc/sys/kernel/kptr_restrict /proc/sys/kernel/perf_event_paranoid
2
2
$ perf record sleep 1
WARNING: Kernel address maps (/proc/{kallsyms,modules}) are restricted,
check /proc/sys/kernel/kptr_restrict.
Samples in kernel functions may not be resolved if a suitable vmlinux
file is not found in the buildid cache or in the vmlinux path.
Samples in kernel modules won't be resolved at all.
If some relocation was applied (e.g. kexec) symbols may be misresolved
even with a suitable vmlinux or kallsyms file.
Couldn't record kernel reference relocation symbol
Symbol resolution may be skewed if relocation was used (e.g. kexec).
Check /proc/kallsyms permission or run as root.
[ perf record: Woken up 1 times to write data ]
[ perf record: Captured and wrote 0.001 MB perf.data (8 samples) ]
$ perf evlist -v
cycles:uppp: size: 112, { sample_period, sample_freq }: 4000, sample_type: IP|TID|TIME|PERIOD, disabled: 1, inherit: 1, exclude_kernel: 1, mmap: 1, comm: 1, freq: 1, enable_on_exec: 1, task: 1, precise_ip: 3, sample_id_all: 1, exclude_guest: 1, mmap2: 1, comm_exec: 1
$
After:
$ perf record sleep 1
[ perf record: Woken up 1 times to write data ]
[ perf record: Captured and wrote 0.001 MB perf.data (10 samples) ]
$
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Wang Nan <wangnan0@huawei.com>
Link: http://lkml.kernel.org/n/tip-t025e9zftbx2b8cq2w01g5e5@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2017-11-14 22:03:19 +08:00
|
|
|
if (symbol_conf.kptr_restrict && !perf_evlist__exclude_kernel(rec->evlist))
|
2011-05-27 22:00:41 +08:00
|
|
|
pr_warning(
|
|
|
|
"WARNING: Kernel address maps (/proc/{kallsyms,modules}) are restricted,\n"
|
|
|
|
"check /proc/sys/kernel/kptr_restrict.\n\n"
|
|
|
|
"Samples in kernel functions may not be resolved if a suitable vmlinux\n"
|
|
|
|
"file is not found in the buildid cache or in the vmlinux path.\n\n"
|
|
|
|
"Samples in kernel modules won't be resolved at all.\n\n"
|
|
|
|
"If some relocation was applied (e.g. kexec) symbols may be misresolved\n"
|
|
|
|
"even with a suitable vmlinux or kallsyms file.\n\n");
|
perf symbols: Handle /proc/sys/kernel/kptr_restrict
Perf uses /proc/modules to figure out where kernel modules are loaded.
With the advent of kptr_restrict, non root users get zeroes for all module
start addresses.
So check if kptr_restrict is non zero and don't generate the syntethic
PERF_RECORD_MMAP events for them.
Warn the user about it in perf record and in perf report.
In perf report the reference relocation symbol being zero means that
kptr_restrict was set, thus /proc/kallsyms has only zeroed addresses, so don't
use it to fixup symbol addresses when using a valid kallsyms (in the buildid
cache) or vmlinux (in the vmlinux path) build-id located automatically or
specified by the user.
Provide an explanation about it in 'perf report' if kernel samples were taken,
checking if a suitable vmlinux or kallsyms was found/specified.
Restricted /proc/kallsyms don't go to the buildid cache anymore.
Example:
[acme@emilia ~]$ perf record -F 100000 sleep 1
WARNING: Kernel address maps (/proc/{kallsyms,modules}) are restricted, check
/proc/sys/kernel/kptr_restrict.
Samples in kernel functions may not be resolved if a suitable vmlinux file is
not found in the buildid cache or in the vmlinux path.
Samples in kernel modules won't be resolved at all.
If some relocation was applied (e.g. kexec) symbols may be misresolved even
with a suitable vmlinux or kallsyms file.
[ perf record: Woken up 1 times to write data ]
[ perf record: Captured and wrote 0.005 MB perf.data (~231 samples) ]
[acme@emilia ~]$
[acme@emilia ~]$ perf report --stdio
Kernel address maps (/proc/{kallsyms,modules}) were restricted,
check /proc/sys/kernel/kptr_restrict before running 'perf record'.
If some relocation was applied (e.g. kexec) symbols may be misresolved.
Samples in kernel modules can't be resolved as well.
# Events: 13 cycles
#
# Overhead Command Shared Object Symbol
# ........ ....... ................. .....................
#
20.24% sleep [kernel.kallsyms] [k] page_fault
20.04% sleep [kernel.kallsyms] [k] filemap_fault
19.78% sleep [kernel.kallsyms] [k] __lru_cache_add
19.69% sleep ld-2.12.so [.] memcpy
14.71% sleep [kernel.kallsyms] [k] dput
4.70% sleep [kernel.kallsyms] [k] flush_signal_handlers
0.73% sleep [kernel.kallsyms] [k] perf_event_comm
0.11% sleep [kernel.kallsyms] [k] native_write_msr_safe
#
# (For a higher level overview, try: perf report --sort comm,dso)
#
[acme@emilia ~]$
This is because it found a suitable vmlinux (build-id checked) in
/lib/modules/2.6.39-rc7+/build/vmlinux (use -v in perf report to see the long
file name).
If we remove that file from the vmlinux path:
[root@emilia ~]# mv /lib/modules/2.6.39-rc7+/build/vmlinux \
/lib/modules/2.6.39-rc7+/build/vmlinux.OFF
[acme@emilia ~]$ perf report --stdio
[kernel.kallsyms] with build id 57298cdbe0131f6871667ec0eaab4804dcf6f562
not found, continuing without symbols
Kernel address maps (/proc/{kallsyms,modules}) were restricted, check
/proc/sys/kernel/kptr_restrict before running 'perf record'.
As no suitable kallsyms nor vmlinux was found, kernel samples can't be
resolved.
Samples in kernel modules can't be resolved as well.
# Events: 13 cycles
#
# Overhead Command Shared Object Symbol
# ........ ....... ................. ......
#
80.31% sleep [kernel.kallsyms] [k] 0xffffffff8103425a
19.69% sleep ld-2.12.so [.] memcpy
#
# (For a higher level overview, try: perf report --sort comm,dso)
#
[acme@emilia ~]$
Reported-by: Stephane Eranian <eranian@google.com>
Suggested-by: David Miller <davem@davemloft.net>
Cc: Dave Jones <davej@redhat.com>
Cc: David Miller <davem@davemloft.net>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Kees Cook <kees.cook@canonical.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Pekka Enberg <penberg@cs.helsinki.fi>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Cc: Tom Zanussi <tzanussi@gmail.com>
Link: http://lkml.kernel.org/n/tip-mt512joaxxbhhp1odop04yit@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2011-05-26 20:53:51 +08:00
|
|
|
|
2016-04-21 02:59:52 +08:00
|
|
|
if (rec->no_buildid_cache || rec->no_buildid) {
|
2010-06-17 17:39:01 +08:00
|
|
|
disable_buildid_cache();
|
2017-01-09 17:51:58 +08:00
|
|
|
} else if (rec->switch_output.enabled) {
|
2016-04-21 02:59:52 +08:00
|
|
|
/*
|
|
|
|
* In 'perf record --switch-output', disable buildid
|
|
|
|
* generation by default to reduce data file switching
|
|
|
|
* overhead. Still generate buildid if they are required
|
|
|
|
* explicitly using
|
|
|
|
*
|
2017-01-03 16:19:56 +08:00
|
|
|
* perf record --switch-output --no-no-buildid \
|
2016-04-21 02:59:52 +08:00
|
|
|
* --no-no-buildid-cache
|
|
|
|
*
|
|
|
|
* Following code equals to:
|
|
|
|
*
|
|
|
|
* if ((rec->no_buildid || !rec->no_buildid_set) &&
|
|
|
|
* (rec->no_buildid_cache || !rec->no_buildid_cache_set))
|
|
|
|
* disable_buildid_cache();
|
|
|
|
*/
|
|
|
|
bool disable = true;
|
|
|
|
|
|
|
|
if (rec->no_buildid_set && !rec->no_buildid)
|
|
|
|
disable = false;
|
|
|
|
if (rec->no_buildid_cache_set && !rec->no_buildid_cache)
|
|
|
|
disable = false;
|
|
|
|
if (disable) {
|
|
|
|
rec->no_buildid = true;
|
|
|
|
rec->no_buildid_cache = true;
|
|
|
|
disable_buildid_cache();
|
|
|
|
}
|
|
|
|
}
|
2009-12-16 06:04:40 +08:00
|
|
|
|
perf record: Add --tail-synthesize option
When working with overwritable ring buffer there's a inconvenience
problem: if perf dumps data after a long period after it starts,
non-sample events may lost, which makes following 'perf report' unable
to identify proc name and mmap layout. For example:
# perf record -m 4 -e raw_syscalls:* -g --overwrite --switch-output \
dd if=/dev/zero of=/dev/null
send SIGUSR2 after dd runs long enough. The resuling perf.data lost
correct comm and mmap events:
# perf script -i perf.data.2016061522374354
perf 24478 [004] 2581325.601789: raw_syscalls:sys_exit: NR 0 = 512
^^^^
Should be 'dd'
27b2e8 syscall_slow_exit_work+0xfe2000e3 (/lib/modules/4.6.0-rc3+/build/vmlinux)
203cc7 do_syscall_64+0xfe200117 (/lib/modules/4.6.0-rc3+/build/vmlinux)
b18d83 return_from_SYSCALL_64+0xfe200000 (/lib/modules/4.6.0-rc3+/build/vmlinux)
7f47c417edf0 [unknown] ([unknown])
^^^^^^^^^^^^
Fail to unwind
This patch provides a '--tail-synthesize' option, allows perf to collect
system status when finalizing output file. In resuling output file, the
non-sample events reflect system status when dumping data.
After this patch:
# perf record -m 4 -e raw_syscalls:* -g --overwrite --switch-output --tail-synthesize \
dd if=/dev/zero of=/dev/null
# perf script -i perf.data.2016061600544998
dd 27364 [004] 2583244.994464: raw_syscalls:sys_enter: NR 1 (1, ...
^^
Correct comm
203a18 syscall_trace_enter_phase2+0xfe2001a8 ([kernel.kallsyms])
203aa5 syscall_trace_enter+0xfe200055 ([kernel.kallsyms])
203caa do_syscall_64+0xfe2000fa ([kernel.kallsyms])
b18d83 return_from_SYSCALL_64+0xfe200000 ([kernel.kallsyms])
d8e50 __GI___libc_write+0xffff01d9639f4010 (/tmp/oxygen_root-w00229757/lib64/libc-2.18.so)
^^^^^
Correct unwind
This option doesn't aim to solve this problem completely. If a process
terminates before SIGUSR2, we still lost its COMM and MMAP events. For
example, we can't unwind correctly from the final perf.data we get from
the previous example, because when perf collects the final output file
(when we press C-c), 'dd' has been terminated so its '/proc/<pid>/mmap'
becomes empty.
However, this is a cheaper choice. To completely solve this problem we
need to continously output non-sample events. To satisify the
requirement of daemonization, we need to merge them periodically. It is
possible but requires much more code and cycles.
Automatically select --tail-synthesize when --overwrite is provided.
Signed-off-by: Wang Nan <wangnan0@huawei.com>
Cc: He Kuang <hekuang@huawei.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Masami Hiramatsu <mhiramat@kernel.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Nilay Vaish <nilayvaish@gmail.com>
Cc: Zefan Li <lizefan@huawei.com>
Cc: pi3orama@163.com
Link: http://lkml.kernel.org/r/1468485287-33422-16-git-send-email-wangnan0@huawei.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2016-07-14 16:34:47 +08:00
|
|
|
if (record.opts.overwrite)
|
|
|
|
record.opts.tail_synthesize = true;
|
|
|
|
|
2014-01-04 02:03:26 +08:00
|
|
|
if (rec->evlist->nr_entries == 0 &&
|
perf record: Do not ask for precise_ip with --no-samples
When the user doesn't specify an event with -e/--event, 'perf record'
will use as a default the "cycles" event with the highest level of
precision in perf_event_attr.precise_ip, but --no-samples, if present,
is incompatible with precise_ip != 0, so use the newly introduced
__perf_event__add_default(precise = false) to fix that:
Before:
# perf record -n usleep 1
Please consider tweaking /proc/sys/kernel/perf_event_max_sample_rate.
Error:
The sys_perf_event_open() syscall returned with 22 (Invalid argument) for event (cycles:ppp).
/bin/dmesg may provide additional information.
No CONFIG_PERF_EVENTS=y kernel support configured?
#
After:
# perf record -n usleep 1
Please consider tweaking /proc/sys/kernel/perf_event_max_sample_rate.
[ perf record: Woken up 1 times to write data ]
[ perf record: Captured and wrote 0.018 MB perf.data ]
[root@jouet /]# perf evlist -v
cycles: size: 112, sample_type: IP|TID|TIME|PERIOD, disabled: 1, inherit: 1, mmap: 1, comm: 1, freq: 1, enable_on_exec: 1, task: 1, sample_id_all: 1, exclude_guest: 1, mmap2: 1, comm_exec: 1
[root@jouet /]#
Reported-by: Jiri Olsa <jolsa@kernel.org>
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Wang Nan <wangnan0@huawei.com>
Link: http://lkml.kernel.org/n/tip-q991fw6s6rhjvrd5ye4t7qom@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2017-07-04 00:26:32 +08:00
|
|
|
__perf_evlist__add_default(rec->evlist, !record.opts.no_samples) < 0) {
|
2011-01-04 02:39:04 +08:00
|
|
|
pr_err("Not enough memory for event selector list\n");
|
2016-09-23 22:38:36 +08:00
|
|
|
goto out;
|
2009-06-12 05:11:50 +08:00
|
|
|
}
|
2009-05-26 15:17:18 +08:00
|
|
|
|
2013-11-18 17:55:57 +08:00
|
|
|
if (rec->opts.target.tid && !rec->opts.no_inherit_set)
|
|
|
|
rec->opts.no_inherit = true;
|
|
|
|
|
2013-11-13 03:46:16 +08:00
|
|
|
err = target__validate(&rec->opts.target);
|
2012-05-07 13:09:02 +08:00
|
|
|
if (err) {
|
2013-11-13 03:46:16 +08:00
|
|
|
target__strerror(&rec->opts.target, err, errbuf, BUFSIZ);
|
2018-02-07 02:17:58 +08:00
|
|
|
ui__warning("%s\n", errbuf);
|
2012-05-07 13:09:02 +08:00
|
|
|
}
|
|
|
|
|
2013-11-13 03:46:16 +08:00
|
|
|
err = target__parse_uid(&rec->opts.target);
|
2012-05-07 13:09:02 +08:00
|
|
|
if (err) {
|
|
|
|
int saved_errno = errno;
|
2012-04-26 13:15:18 +08:00
|
|
|
|
2013-11-13 03:46:16 +08:00
|
|
|
target__strerror(&rec->opts.target, err, errbuf, BUFSIZ);
|
2012-05-29 12:22:57 +08:00
|
|
|
ui__error("%s", errbuf);
|
2012-05-07 13:09:02 +08:00
|
|
|
|
|
|
|
err = -saved_errno;
|
2016-09-23 22:38:36 +08:00
|
|
|
goto out;
|
2012-05-07 13:09:02 +08:00
|
|
|
}
|
2012-01-20 00:08:15 +08:00
|
|
|
|
perf evsel: Enable ignore_missing_thread for pid option
While monitoring a multithread process with pid option, perf sometimes
may return sys_perf_event_open failure with 3(No such process) if any of
the process's threads die before we open the event. However, we want
perf continue monitoring the remaining threads and do not exit with
error.
Here, the patch enables perf_evsel::ignore_missing_thread for -p option
to ignore complete failure if any of threads die before we open the event.
But it may still return sys_perf_event_open failure with 22(Invalid) if we
monitors several event groups.
sys_perf_event_open: pid 28960 cpu 40 group_fd 118202 flags 0x8
sys_perf_event_open: pid 28961 cpu 40 group_fd 118203 flags 0x8
WARNING: Ignored open failure for pid 28962
sys_perf_event_open: pid 28962 cpu 40 group_fd [118203] flags 0x8
sys_perf_event_open failed, error -22
That is because when we ignore a missing thread, we change the thread_idx
without dealing with its fds, FD(evsel, cpu, thread). Then get_group_fd()
may return a wrong group_fd for the next thread and sys_perf_event_open()
return with 22.
sys_perf_event_open(){
...
if (group_fd != -1)
perf_fget_light()//to get corresponding group_leader by group_fd
...
if (group_leader)
if (group_leader->ctx->task != ctx->task)//should on the same task
goto err_context
...
}
This patch also fixes this bug by introducing perf_evsel__remove_fd() and
update_fds to allow removing fds for the missing thread.
Changes since v1:
- Change group_fd__remove() into a more genetic way without changing code logic
- Remove redundant condition
Changes since v2:
- Use a proper function name and add some comment.
- Multiline comment style fixes.
Committer testing:
Before this patch the recently added 'perf stat --per-thread' for system
wide counting would race while enumerating all threads using /proc:
[root@jouet ~]# perf stat --per-thread
failed to parse CPUs map: No such file or directory
Usage: perf stat [<options>] [<command>]
-C, --cpu <cpu> list of cpus to monitor in system-wide
-a, --all-cpus system-wide collection from all CPUs
[root@jouet ~]# perf stat --per-thread
failed to parse CPUs map: No such file or directory
Usage: perf stat [<options>] [<command>]
-C, --cpu <cpu> list of cpus to monitor in system-wide
-a, --all-cpus system-wide collection from all CPUs
[root@jouet ~]#
When, say, the kernel was being built, so lots of shortlived threads,
after this patch this doesn't happen.
Signed-off-by: Mengting Zhang <zhangmengting@huawei.com>
Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Acked-by: Jiri Olsa <jolsa@redhat.com>
Cc: Cheng Jian <cj.chengjian@huawei.com>
Cc: Li Bin <huawei.libin@huawei.com>
Cc: Wang Nan <wangnan0@huawei.com>
Link: http://lkml.kernel.org/r/1513148513-6974-1-git-send-email-zhangmengting@huawei.com
[ Remove one use 'evlist' alias variable ]
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2017-12-13 15:01:53 +08:00
|
|
|
/* Enable ignoring missing threads when -u/-p option is defined. */
|
|
|
|
rec->opts.ignore_missing_thread = rec->opts.target.uid != UINT_MAX || rec->opts.target.pid;
|
2016-12-12 18:35:43 +08:00
|
|
|
|
2012-05-07 13:09:02 +08:00
|
|
|
err = -ENOMEM;
|
2014-01-04 02:03:26 +08:00
|
|
|
if (perf_evlist__create_maps(rec->evlist, &rec->opts.target) < 0)
|
2011-01-13 00:28:51 +08:00
|
|
|
usage_with_options(record_usage, record_options);
|
2011-01-04 02:39:04 +08:00
|
|
|
|
2015-04-09 23:53:45 +08:00
|
|
|
err = auxtrace_record__options(rec->itr, rec->evlist, &rec->opts);
|
|
|
|
if (err)
|
2016-09-23 22:38:36 +08:00
|
|
|
goto out;
|
2015-04-09 23:53:45 +08:00
|
|
|
|
2016-01-11 21:37:09 +08:00
|
|
|
/*
|
|
|
|
* We take all buildids when the file contains
|
|
|
|
* AUX area tracing data because we do not decode the
|
|
|
|
* trace because it would take too long.
|
|
|
|
*/
|
|
|
|
if (rec->opts.full_auxtrace)
|
|
|
|
rec->buildid_all = true;
|
|
|
|
|
2013-12-20 01:43:45 +08:00
|
|
|
if (record_opts__config(&rec->opts)) {
|
2010-07-30 01:08:55 +08:00
|
|
|
err = -EINVAL;
|
2016-09-23 22:38:36 +08:00
|
|
|
goto out;
|
2009-10-12 13:56:03 +08:00
|
|
|
}
|
|
|
|
|
2018-11-06 17:07:19 +08:00
|
|
|
if (rec->opts.nr_cblocks > nr_cblocks_max)
|
|
|
|
rec->opts.nr_cblocks = nr_cblocks_max;
|
2018-11-06 17:04:58 +08:00
|
|
|
if (verbose > 0)
|
|
|
|
pr_info("nr_cblocks: %d\n", rec->opts.nr_cblocks);
|
|
|
|
|
2019-01-23 01:47:43 +08:00
|
|
|
pr_debug("affinity: %s\n", affinity_tags[rec->opts.affinity]);
|
|
|
|
|
2011-11-25 18:19:45 +08:00
|
|
|
err = __cmd_record(&record, argc, argv);
|
2016-09-23 22:38:36 +08:00
|
|
|
out:
|
2014-05-12 08:47:24 +08:00
|
|
|
perf_evlist__delete(rec->evlist);
|
2010-07-31 05:31:28 +08:00
|
|
|
symbol__exit();
|
2015-04-09 23:53:45 +08:00
|
|
|
auxtrace_record__free(rec->itr);
|
2010-07-30 01:08:55 +08:00
|
|
|
return err;
|
2009-05-26 15:17:18 +08:00
|
|
|
}
|
2015-04-30 22:37:32 +08:00
|
|
|
|
|
|
|
static void snapshot_sig_handler(int sig __maybe_unused)
|
|
|
|
{
|
2017-01-09 17:51:58 +08:00
|
|
|
struct record *rec = &record;
|
|
|
|
|
2016-04-21 02:59:49 +08:00
|
|
|
if (trigger_is_ready(&auxtrace_snapshot_trigger)) {
|
|
|
|
trigger_hit(&auxtrace_snapshot_trigger);
|
|
|
|
auxtrace_record__snapshot_started = 1;
|
|
|
|
if (auxtrace_record__snapshot_start(record.itr))
|
|
|
|
trigger_error(&auxtrace_snapshot_trigger);
|
|
|
|
}
|
2016-04-21 02:59:50 +08:00
|
|
|
|
2017-01-09 17:51:58 +08:00
|
|
|
if (switch_output_signal(rec))
|
2016-04-21 02:59:50 +08:00
|
|
|
trigger_hit(&switch_output_trigger);
|
2015-04-30 22:37:32 +08:00
|
|
|
}
|
2017-01-09 17:52:00 +08:00
|
|
|
|
|
|
|
static void alarm_sig_handler(int sig __maybe_unused)
|
|
|
|
{
|
|
|
|
struct record *rec = &record;
|
|
|
|
|
|
|
|
if (switch_output_time(rec))
|
|
|
|
trigger_hit(&switch_output_trigger);
|
|
|
|
}
|