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
|
|
|
|
2010-02-04 02:52:05 +08:00
|
|
|
#include "util/build-id.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"
|
2019-09-23 23:20:38 +08:00
|
|
|
#include "util/mmap.h"
|
2019-08-23 02:40:29 +08:00
|
|
|
#include "util/target.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"
|
2019-08-23 02:40:29 +08:00
|
|
|
#include "util/record.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"
|
2020-05-05 22:49:08 +08:00
|
|
|
#include "util/perf_api_probe.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"
|
2019-09-18 22:36:13 +08:00
|
|
|
#include "util/synthetic-events.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"
|
2020-04-22 23:50:38 +08:00
|
|
|
#include "util/util.h"
|
2020-05-06 02:29:43 +08:00
|
|
|
#include "util/pfm.h"
|
2020-08-05 17:34:38 +08:00
|
|
|
#include "util/clockid.h"
|
2016-02-26 17:32:06 +08:00
|
|
|
#include "asm/bug.h"
|
2019-08-30 02:20:59 +08:00
|
|
|
#include "perf.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>
|
2020-04-22 23:50:38 +08:00
|
|
|
#include <pthread.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>
|
2020-05-13 10:20:23 +08:00
|
|
|
#ifdef HAVE_EVENTFD_SUPPORT
|
|
|
|
#include <sys/eventfd.h>
|
|
|
|
#endif
|
2010-05-19 05:29:23 +08:00
|
|
|
#include <sys/mman.h>
|
2017-04-20 06:06:30 +08:00
|
|
|
#include <sys/wait.h>
|
perf record: Put a copy of kcore into the perf.data directory
Add a new 'perf record' option '--kcore' which will put a copy of
/proc/kcore, kallsyms and modules into a perf.data directory. Note, that
without the --kcore option, output goes to a file as previously. The
tools' -o and -i options work with either a file name or directory name.
Example:
$ sudo perf record --kcore uname
$ sudo tree perf.data
perf.data
├── kcore_dir
│ ├── kallsyms
│ ├── kcore
│ └── modules
└── data
$ sudo perf script -v
build id event received for vmlinux: 1eaa285996affce2d74d8e66dcea09a80c9941de
build id event received for [vdso]: 8bbaf5dc62a9b644b4d4e4539737e104e4a84541
Samples for 'cycles' event do not have CPU attribute set. Skipping 'cpu' field.
Using CPUID GenuineIntel-6-8E-A
Using perf.data/kcore_dir/kcore for kernel data
Using perf.data/kcore_dir/kallsyms for symbols
perf 19058 506778.423729: 1 cycles: ffffffffa2caa548 native_write_msr+0x8 (vmlinux)
perf 19058 506778.423733: 1 cycles: ffffffffa2caa548 native_write_msr+0x8 (vmlinux)
perf 19058 506778.423734: 7 cycles: ffffffffa2caa548 native_write_msr+0x8 (vmlinux)
perf 19058 506778.423736: 117 cycles: ffffffffa2caa54a native_write_msr+0xa (vmlinux)
perf 19058 506778.423738: 2092 cycles: ffffffffa2c9b7b0 native_apic_msr_write+0x0 (vmlinux)
perf 19058 506778.423740: 37380 cycles: ffffffffa2f121d0 perf_event_addr_filters_exec+0x0 (vmlinux)
uname 19058 506778.423751: 582673 cycles: ffffffffa303a407 propagate_protected_usage+0x147 (vmlinux)
uname 19058 506778.423892: 2241841 cycles: ffffffffa2cae0c9 unwind_next_frame.part.5+0x79 (vmlinux)
uname 19058 506778.424430: 2457397 cycles: ffffffffa3019232 check_memory_region+0x52 (vmlinux)
Committer testing:
# rm -rf perf.data*
# perf record sleep 1
[ perf record: Woken up 1 times to write data ]
[ perf record: Captured and wrote 0.024 MB perf.data (7 samples) ]
# ls -l perf.data
-rw-------. 1 root root 34772 Oct 21 11:08 perf.data
# perf record --kcore uname
Linux
[ perf record: Woken up 1 times to write data ]
[ perf record: Captured and wrote 0.024 MB perf.data (7 samples) ]
ls[root@quaco ~]# ls -lad perf.data*
drwx------. 3 root root 4096 Oct 21 11:08 perf.data
-rw-------. 1 root root 34772 Oct 21 11:08 perf.data.old
# perf evlist -v
cycles: size: 112, { sample_period, sample_freq }: 4000, sample_type: IP|TID|TIME|PERIOD, read_format: ID, 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, ksymbol: 1, bpf_event: 1
# perf evlist -v -i perf.data/data
cycles: size: 112, { sample_period, sample_freq }: 4000, sample_type: IP|TID|TIME|PERIOD, read_format: ID, 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, ksymbol: 1, bpf_event: 1
#
Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
Reviewed-by: Jiri Olsa <jolsa@kernel.org>
Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Link: http://lore.kernel.org/lkml/20191004083121.12182-6-adrian.hunter@intel.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2019-10-04 16:31:21 +08:00
|
|
|
#include <sys/types.h>
|
|
|
|
#include <sys/stat.h>
|
|
|
|
#include <fcntl.h>
|
2019-08-22 15:20:49 +08:00
|
|
|
#include <linux/err.h>
|
2019-08-30 03:18:59 +08:00
|
|
|
#include <linux/string.h>
|
2016-08-09 02:05:46 +08:00
|
|
|
#include <linux/time64.h>
|
2019-07-04 23:06:20 +08:00
|
|
|
#include <linux/zalloc.h>
|
2019-12-03 19:45:27 +08:00
|
|
|
#include <linux/bitmap.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;
|
2019-07-21 19:23:52 +08:00
|
|
|
struct evlist *evlist;
|
2011-11-25 18:19:45 +08:00
|
|
|
struct perf_session *session;
|
2020-04-24 21:24:04 +08:00
|
|
|
struct evlist *sb_evlist;
|
2020-04-28 04:56:37 +08:00
|
|
|
pthread_t thread_id;
|
2011-11-25 18:19:45 +08:00
|
|
|
int realtime_prio;
|
2020-04-28 04:56:37 +08:00
|
|
|
bool switch_output_event_set;
|
2011-11-25 18:19:45 +08:00
|
|
|
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-12-03 19:45:27 +08:00
|
|
|
struct mmap_cpu_mask affinity_mask;
|
2019-10-22 16:09:01 +08:00
|
|
|
unsigned long output_max_size; /* = 0: unlimited */
|
2011-11-09 00:41:57 +08:00
|
|
|
};
|
2009-06-06 15:58:57 +08:00
|
|
|
|
2019-10-22 16:09:01 +08:00
|
|
|
static volatile int done;
|
|
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
2019-10-22 16:09:01 +08:00
|
|
|
static bool record__output_max_size_exceeded(struct record *rec)
|
|
|
|
{
|
|
|
|
return rec->output_max_size &&
|
|
|
|
(rec->bytes_written >= rec->output_max_size);
|
|
|
|
}
|
|
|
|
|
2019-07-28 02:30:53 +08:00
|
|
|
static int record__write(struct record *rec, struct mmap *map __maybe_unused,
|
2018-09-13 20:54:06 +08:00
|
|
|
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
|
|
|
|
2019-10-22 16:09:01 +08:00
|
|
|
if (record__output_max_size_exceeded(rec) && !done) {
|
|
|
|
fprintf(stderr, "[ perf record: perf size limit reached (%" PRIu64 " KB),"
|
|
|
|
" stopping session ]\n",
|
|
|
|
rec->bytes_written >> 10);
|
|
|
|
done = 1;
|
|
|
|
}
|
|
|
|
|
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
|
|
|
}
|
|
|
|
|
2019-03-19 01:44:12 +08:00
|
|
|
static int record__aio_enabled(struct record *rec);
|
|
|
|
static int record__comp_enabled(struct record *rec);
|
2019-03-19 01:43:35 +08:00
|
|
|
static size_t zstd_compress(struct perf_session *session, void *dst, size_t dst_size,
|
|
|
|
void *src, size_t src_size);
|
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2019-07-28 02:30:53 +08:00
|
|
|
static int record__aio_complete(struct mmap *md, struct aiocb *cblock)
|
2018-11-06 17:04:58 +08:00
|
|
|
{
|
|
|
|
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;
|
|
|
|
/*
|
2019-03-19 01:44:12 +08:00
|
|
|
* md->refcount is incremented in record__aio_pushfn() for
|
|
|
|
* every aio write request started in record__aio_push() so
|
|
|
|
* decrement it because the request is now complete.
|
2018-11-06 17:04:58 +08:00
|
|
|
*/
|
2019-10-07 20:53:15 +08:00
|
|
|
perf_mmap__put(&md->core);
|
2018-11-06 17:04:58 +08:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2019-07-28 02:30:53 +08:00
|
|
|
static int record__aio_sync(struct 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);
|
|
|
|
}
|
|
|
|
|
2019-03-19 01:44:12 +08:00
|
|
|
struct record_aio {
|
|
|
|
struct record *rec;
|
|
|
|
void *data;
|
|
|
|
size_t size;
|
|
|
|
};
|
|
|
|
|
2019-07-28 02:30:53 +08:00
|
|
|
static int record__aio_pushfn(struct mmap *map, void *to, void *buf, size_t size)
|
2018-11-06 17:04:58 +08:00
|
|
|
{
|
2019-03-19 01:44:12 +08:00
|
|
|
struct record_aio *aio = to;
|
2018-11-06 17:04:58 +08:00
|
|
|
|
2019-03-19 01:44:12 +08:00
|
|
|
/*
|
2019-07-28 04:07:44 +08:00
|
|
|
* map->core.base data pointed by buf is copied into free map->aio.data[] buffer
|
2019-03-19 01:44:12 +08:00
|
|
|
* to release space in the kernel buffer as fast as possible, calling
|
|
|
|
* perf_mmap__consume() from perf_mmap__push() function.
|
|
|
|
*
|
|
|
|
* That lets the kernel to proceed with storing more profiling data into
|
|
|
|
* the kernel buffer earlier than other per-cpu kernel buffers are handled.
|
|
|
|
*
|
|
|
|
* Coping can be done in two steps in case the chunk of profiling data
|
|
|
|
* crosses the upper bound of the kernel buffer. In this case we first move
|
|
|
|
* part of data from map->start till the upper bound and then the reminder
|
|
|
|
* from the beginning of the kernel buffer till the end of the data chunk.
|
|
|
|
*/
|
|
|
|
|
|
|
|
if (record__comp_enabled(aio->rec)) {
|
|
|
|
size = zstd_compress(aio->rec->session, aio->data + aio->size,
|
2019-10-07 20:53:11 +08:00
|
|
|
mmap__mmap_len(map) - aio->size,
|
2019-03-19 01:44:12 +08:00
|
|
|
buf, size);
|
|
|
|
} else {
|
|
|
|
memcpy(aio->data + aio->size, buf, size);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!aio->size) {
|
|
|
|
/*
|
|
|
|
* Increment map->refcount to guard map->aio.data[] buffer
|
|
|
|
* from premature deallocation because map object can be
|
|
|
|
* released earlier than aio write request started on
|
|
|
|
* map->aio.data[] buffer is complete.
|
|
|
|
*
|
|
|
|
* perf_mmap__put() is done at record__aio_complete()
|
|
|
|
* after started aio request completion or at record__aio_push()
|
|
|
|
* if the request failed to start.
|
|
|
|
*/
|
2019-10-07 20:53:13 +08:00
|
|
|
perf_mmap__get(&map->core);
|
2019-03-19 01:44:12 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
aio->size += size;
|
|
|
|
|
|
|
|
return size;
|
|
|
|
}
|
|
|
|
|
2019-07-28 02:30:53 +08:00
|
|
|
static int record__aio_push(struct record *rec, struct mmap *map, off_t *off)
|
2019-03-19 01:44:12 +08:00
|
|
|
{
|
|
|
|
int ret, idx;
|
|
|
|
int trace_fd = rec->session->data->file.fd;
|
|
|
|
struct record_aio aio = { .rec = rec, .size = 0 };
|
2018-11-06 17:04:58 +08:00
|
|
|
|
2019-03-19 01:44:12 +08:00
|
|
|
/*
|
|
|
|
* Call record__aio_sync() to wait till map->aio.data[] buffer
|
|
|
|
* becomes available after previous aio write operation.
|
|
|
|
*/
|
|
|
|
|
|
|
|
idx = record__aio_sync(map, false);
|
|
|
|
aio.data = map->aio.data[idx];
|
|
|
|
ret = perf_mmap__push(map, &aio, record__aio_pushfn);
|
|
|
|
if (ret != 0) /* ret > 0 - no data, ret < 0 - error */
|
|
|
|
return ret;
|
|
|
|
|
|
|
|
rec->samples++;
|
|
|
|
ret = record__aio_write(&(map->aio.cblocks[idx]), trace_fd, aio.data, aio.size, *off);
|
2018-11-06 17:04:58 +08:00
|
|
|
if (!ret) {
|
2019-03-19 01:44:12 +08:00
|
|
|
*off += aio.size;
|
|
|
|
rec->bytes_written += aio.size;
|
2018-11-06 17:04:58 +08:00
|
|
|
if (switch_output_size(rec))
|
|
|
|
trigger_hit(&switch_output_trigger);
|
2019-03-19 01:44:12 +08:00
|
|
|
} else {
|
|
|
|
/*
|
|
|
|
* Decrement map->refcount incremented in record__aio_pushfn()
|
|
|
|
* back if record__aio_write() operation failed to start, otherwise
|
|
|
|
* map->refcount is decremented in record__aio_complete() after
|
|
|
|
* aio write operation finishes successfully.
|
|
|
|
*/
|
2019-10-07 20:53:15 +08:00
|
|
|
perf_mmap__put(&map->core);
|
2018-11-06 17:04:58 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
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;
|
2019-07-21 19:23:52 +08:00
|
|
|
struct evlist *evlist = rec->evlist;
|
2019-07-28 02:30:53 +08:00
|
|
|
struct mmap *maps = evlist->mmap;
|
2018-11-06 17:04:58 +08:00
|
|
|
|
2019-03-19 01:44:12 +08:00
|
|
|
if (!record__aio_enabled(rec))
|
2018-11-06 17:04:58 +08:00
|
|
|
return;
|
|
|
|
|
2019-07-30 19:04:59 +08:00
|
|
|
for (i = 0; i < evlist->core.nr_mmaps; i++) {
|
2019-07-28 02:30:53 +08:00
|
|
|
struct mmap *map = &maps[i];
|
2018-11-06 17:04:58 +08:00
|
|
|
|
2019-07-28 04:07:44 +08:00
|
|
|
if (map->core.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;
|
|
|
|
|
2019-07-28 02:30:53 +08:00
|
|
|
static int record__aio_push(struct record *rec __maybe_unused, struct mmap *map __maybe_unused,
|
2019-03-19 01:44:12 +08:00
|
|
|
off_t *off __maybe_unused)
|
2018-11-06 17:04:58 +08:00
|
|
|
{
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
perf record: Implement --mmap-flush=<number> option
Implement a --mmap-flush option that specifies minimal number of bytes
that is extracted from mmaped kernel buffer to store into a trace. The
default option value is 1 byte what means every time trace writing
thread finds some new data in the mmaped buffer the data is extracted,
possibly compressed and written to a trace.
$ tools/perf/perf record --mmap-flush 1024 -e cycles -- matrix.gcc
$ tools/perf/perf record --aio --mmap-flush 1K -e cycles -- matrix.gcc
The option is independent from -z setting, doesn't vary with compression
level and can serve two purposes.
The first purpose is to increase the compression ratio of a trace data.
Larger data chunks are compressed more effectively so the implemented
option allows specifying data chunk size to compress. Also at some cases
executing more write syscalls with smaller data size can take longer
than executing less write syscalls with bigger data size due to syscall
overhead so extracting bigger data chunks specified by the option value
could additionally decrease runtime overhead.
The second purpose is to avoid self monitoring live-lock issue in system
wide (-a) profiling mode. Profiling in system wide mode with compression
(-a -z) can additionally induce data into the kernel buffers along with
the data from monitored processes. If performance data rate and volume
from the monitored processes is high then trace streaming and
compression activity in the tool is also high. High tool process
activity can lead to subtle live-lock effect when compression of single
new byte from some of mmaped kernel buffer leads to generation of the
next single byte at some mmaped buffer. So perf tool process ends up in
endless self monitoring.
Implemented synch parameter is the mean to force data move independently
from the specified flush threshold value. Despite the provided flush
value the tool needs capability to unconditionally drain memory buffers,
at least in the end of the collection.
Committer testing:
Running with the default value, i.e. as soon as there is something to
read go on consuming, we first write the synthesized events, small
chunks of about 128 bytes:
# perf trace -m 2048 --call-graph dwarf -e write -- perf record
<SNIP>
101.142 ( 0.004 ms): perf/25821 write(fd: 3</root/perf.data>, buf: 0x210db60, count: 120) = 120
__libc_write (/usr/lib64/libpthread-2.28.so)
ion (/home/acme/bin/perf)
record__write (inlined)
process_synthesized_event (/home/acme/bin/perf)
perf_tool__process_synth_event (inlined)
perf_event__synthesize_mmap_events (/home/acme/bin/perf)
Then we move to reading the mmap buffers consuming the events put there
by the kernel perf infrastructure:
107.561 ( 0.005 ms): perf/25821 write(fd: 3</root/perf.data>, buf: 0x7f1befc02000, count: 336) = 336
__libc_write (/usr/lib64/libpthread-2.28.so)
ion (/home/acme/bin/perf)
record__write (inlined)
record__pushfn (/home/acme/bin/perf)
perf_mmap__push (/home/acme/bin/perf)
record__mmap_read_evlist (inlined)
record__mmap_read_all (inlined)
__cmd_record (inlined)
cmd_record (/home/acme/bin/perf)
12919.953 ( 0.136 ms): perf/25821 write(fd: 3</root/perf.data>, buf: 0x7f1befc83150, count: 184984) = 184984
<SNIP same backtrace as in the 107.561 timestamp>
12920.094 ( 0.155 ms): perf/25821 write(fd: 3</root/perf.data>, buf: 0x7f1befc02150, count: 261816) = 261816
<SNIP same backtrace as in the 107.561 timestamp>
12920.253 ( 0.093 ms): perf/25821 write(fd: 3</root/perf.data>, buf: 0x7f1befb81120, count: 170832) = 170832
<SNIP same backtrace as in the 107.561 timestamp>
If we limit it to write only when more than 16MB are available for
reading, it throttles that to a quarter of the --mmap-pages set for
'perf record', which by default get to 528384 bytes, found out using
'record -v':
mmap flush: 132096
mmap size 528384B
With that in place all the writes coming from
record__mmap_read_evlist(), i.e. from the mmap buffers setup by the
kernel perf infrastructure were at least 132096 bytes long.
Trying with a bigger mmap size:
perf trace -e write perf record -v -m 2048 --mmap-flush 16M
74982.928 ( 2.471 ms): perf/26500 write(fd: 3</root/perf.data>, buf: 0x7ff94a6cc000, count: 3580888) = 3580888
74985.406 ( 2.353 ms): perf/26500 write(fd: 3</root/perf.data>, buf: 0x7ff949ecb000, count: 3453256) = 3453256
74987.764 ( 2.629 ms): perf/26500 write(fd: 3</root/perf.data>, buf: 0x7ff9496ca000, count: 3859232) = 3859232
74990.399 ( 2.341 ms): perf/26500 write(fd: 3</root/perf.data>, buf: 0x7ff948ec9000, count: 3769032) = 3769032
74992.744 ( 2.064 ms): perf/26500 write(fd: 3</root/perf.data>, buf: 0x7ff9486c8000, count: 3310520) = 3310520
74994.814 ( 2.619 ms): perf/26500 write(fd: 3</root/perf.data>, buf: 0x7ff947ec7000, count: 4194688) = 4194688
74997.439 ( 2.787 ms): perf/26500 write(fd: 3</root/perf.data>, buf: 0x7ff9476c6000, count: 4029760) = 4029760
Was again limited to a quarter of the mmap size:
mmap flush: 2098176
mmap size 8392704B
A warning about that would be good to have but can be added later,
something like:
"max flush is a quarter of the mmap size, if wanting to bump the mmap
flush further, bump the mmap size as well using -m/--mmap-pages"
Also rename the 'sync' parameters to 'synch' to keep tools/perf building
with older glibcs:
cc1: warnings being treated as errors
builtin-record.c: In function 'record__mmap_read_evlist':
builtin-record.c:775: warning: declaration of 'sync' shadows a global declaration
/usr/include/unistd.h:933: warning: shadowed declaration is here
builtin-record.c: In function 'record__mmap_read_all':
builtin-record.c:856: warning: declaration of 'sync' shadows a global declaration
/usr/include/unistd.h:933: warning: shadowed declaration is here
Signed-off-by: Alexey Budankov <alexey.budankov@linux.intel.com>
Reviewed-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: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Link: http://lkml.kernel.org/r/f6600d72-ecfa-2eb7-7e51-f6954547d500@linux.intel.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2019-03-19 01:40:26 +08:00
|
|
|
#define MMAP_FLUSH_DEFAULT 1
|
|
|
|
static int record__mmap_flush_parse(const struct option *opt,
|
|
|
|
const char *str,
|
|
|
|
int unset)
|
|
|
|
{
|
|
|
|
int flush_max;
|
|
|
|
struct record_opts *opts = (struct record_opts *)opt->value;
|
|
|
|
static struct parse_tag tags[] = {
|
|
|
|
{ .tag = 'B', .mult = 1 },
|
|
|
|
{ .tag = 'K', .mult = 1 << 10 },
|
|
|
|
{ .tag = 'M', .mult = 1 << 20 },
|
|
|
|
{ .tag = 'G', .mult = 1 << 30 },
|
|
|
|
{ .tag = 0 },
|
|
|
|
};
|
|
|
|
|
|
|
|
if (unset)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
if (str) {
|
|
|
|
opts->mmap_flush = parse_tag_value(str, tags);
|
|
|
|
if (opts->mmap_flush == (int)-1)
|
|
|
|
opts->mmap_flush = strtol(str, NULL, 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!opts->mmap_flush)
|
|
|
|
opts->mmap_flush = MMAP_FLUSH_DEFAULT;
|
|
|
|
|
2019-07-28 18:45:35 +08:00
|
|
|
flush_max = evlist__mmap_size(opts->mmap_pages);
|
perf record: Implement --mmap-flush=<number> option
Implement a --mmap-flush option that specifies minimal number of bytes
that is extracted from mmaped kernel buffer to store into a trace. The
default option value is 1 byte what means every time trace writing
thread finds some new data in the mmaped buffer the data is extracted,
possibly compressed and written to a trace.
$ tools/perf/perf record --mmap-flush 1024 -e cycles -- matrix.gcc
$ tools/perf/perf record --aio --mmap-flush 1K -e cycles -- matrix.gcc
The option is independent from -z setting, doesn't vary with compression
level and can serve two purposes.
The first purpose is to increase the compression ratio of a trace data.
Larger data chunks are compressed more effectively so the implemented
option allows specifying data chunk size to compress. Also at some cases
executing more write syscalls with smaller data size can take longer
than executing less write syscalls with bigger data size due to syscall
overhead so extracting bigger data chunks specified by the option value
could additionally decrease runtime overhead.
The second purpose is to avoid self monitoring live-lock issue in system
wide (-a) profiling mode. Profiling in system wide mode with compression
(-a -z) can additionally induce data into the kernel buffers along with
the data from monitored processes. If performance data rate and volume
from the monitored processes is high then trace streaming and
compression activity in the tool is also high. High tool process
activity can lead to subtle live-lock effect when compression of single
new byte from some of mmaped kernel buffer leads to generation of the
next single byte at some mmaped buffer. So perf tool process ends up in
endless self monitoring.
Implemented synch parameter is the mean to force data move independently
from the specified flush threshold value. Despite the provided flush
value the tool needs capability to unconditionally drain memory buffers,
at least in the end of the collection.
Committer testing:
Running with the default value, i.e. as soon as there is something to
read go on consuming, we first write the synthesized events, small
chunks of about 128 bytes:
# perf trace -m 2048 --call-graph dwarf -e write -- perf record
<SNIP>
101.142 ( 0.004 ms): perf/25821 write(fd: 3</root/perf.data>, buf: 0x210db60, count: 120) = 120
__libc_write (/usr/lib64/libpthread-2.28.so)
ion (/home/acme/bin/perf)
record__write (inlined)
process_synthesized_event (/home/acme/bin/perf)
perf_tool__process_synth_event (inlined)
perf_event__synthesize_mmap_events (/home/acme/bin/perf)
Then we move to reading the mmap buffers consuming the events put there
by the kernel perf infrastructure:
107.561 ( 0.005 ms): perf/25821 write(fd: 3</root/perf.data>, buf: 0x7f1befc02000, count: 336) = 336
__libc_write (/usr/lib64/libpthread-2.28.so)
ion (/home/acme/bin/perf)
record__write (inlined)
record__pushfn (/home/acme/bin/perf)
perf_mmap__push (/home/acme/bin/perf)
record__mmap_read_evlist (inlined)
record__mmap_read_all (inlined)
__cmd_record (inlined)
cmd_record (/home/acme/bin/perf)
12919.953 ( 0.136 ms): perf/25821 write(fd: 3</root/perf.data>, buf: 0x7f1befc83150, count: 184984) = 184984
<SNIP same backtrace as in the 107.561 timestamp>
12920.094 ( 0.155 ms): perf/25821 write(fd: 3</root/perf.data>, buf: 0x7f1befc02150, count: 261816) = 261816
<SNIP same backtrace as in the 107.561 timestamp>
12920.253 ( 0.093 ms): perf/25821 write(fd: 3</root/perf.data>, buf: 0x7f1befb81120, count: 170832) = 170832
<SNIP same backtrace as in the 107.561 timestamp>
If we limit it to write only when more than 16MB are available for
reading, it throttles that to a quarter of the --mmap-pages set for
'perf record', which by default get to 528384 bytes, found out using
'record -v':
mmap flush: 132096
mmap size 528384B
With that in place all the writes coming from
record__mmap_read_evlist(), i.e. from the mmap buffers setup by the
kernel perf infrastructure were at least 132096 bytes long.
Trying with a bigger mmap size:
perf trace -e write perf record -v -m 2048 --mmap-flush 16M
74982.928 ( 2.471 ms): perf/26500 write(fd: 3</root/perf.data>, buf: 0x7ff94a6cc000, count: 3580888) = 3580888
74985.406 ( 2.353 ms): perf/26500 write(fd: 3</root/perf.data>, buf: 0x7ff949ecb000, count: 3453256) = 3453256
74987.764 ( 2.629 ms): perf/26500 write(fd: 3</root/perf.data>, buf: 0x7ff9496ca000, count: 3859232) = 3859232
74990.399 ( 2.341 ms): perf/26500 write(fd: 3</root/perf.data>, buf: 0x7ff948ec9000, count: 3769032) = 3769032
74992.744 ( 2.064 ms): perf/26500 write(fd: 3</root/perf.data>, buf: 0x7ff9486c8000, count: 3310520) = 3310520
74994.814 ( 2.619 ms): perf/26500 write(fd: 3</root/perf.data>, buf: 0x7ff947ec7000, count: 4194688) = 4194688
74997.439 ( 2.787 ms): perf/26500 write(fd: 3</root/perf.data>, buf: 0x7ff9476c6000, count: 4029760) = 4029760
Was again limited to a quarter of the mmap size:
mmap flush: 2098176
mmap size 8392704B
A warning about that would be good to have but can be added later,
something like:
"max flush is a quarter of the mmap size, if wanting to bump the mmap
flush further, bump the mmap size as well using -m/--mmap-pages"
Also rename the 'sync' parameters to 'synch' to keep tools/perf building
with older glibcs:
cc1: warnings being treated as errors
builtin-record.c: In function 'record__mmap_read_evlist':
builtin-record.c:775: warning: declaration of 'sync' shadows a global declaration
/usr/include/unistd.h:933: warning: shadowed declaration is here
builtin-record.c: In function 'record__mmap_read_all':
builtin-record.c:856: warning: declaration of 'sync' shadows a global declaration
/usr/include/unistd.h:933: warning: shadowed declaration is here
Signed-off-by: Alexey Budankov <alexey.budankov@linux.intel.com>
Reviewed-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: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Link: http://lkml.kernel.org/r/f6600d72-ecfa-2eb7-7e51-f6954547d500@linux.intel.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2019-03-19 01:40:26 +08:00
|
|
|
flush_max /= 4;
|
|
|
|
if (opts->mmap_flush > flush_max)
|
|
|
|
opts->mmap_flush = flush_max;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
perf record: Implement -z,--compression_level[=<n>] option
Implemented -z,--compression_level[=<n>] option that enables compression
of mmaped kernel data buffers content in runtime during perf record mode
collection. Default option value is 1 (fastest compression).
Compression overhead has been measured for serial and AIO streaming when
profiling matrix multiplication workload:
-------------------------------------------------------------
| SERIAL | AIO-1 |
----------------------------------------------------------------|
|-z | OVH(x) | ratio(x) size(MiB) | OVH(x) | ratio(x) size(MiB) |
|---------------------------------------------------------------|
| 0 | 1,00 | 1,000 179,424 | 1,00 | 1,000 187,527 |
| 1 | 1,04 | 8,427 181,148 | 1,01 | 8,474 188,562 |
| 2 | 1,07 | 8,055 186,953 | 1,03 | 7,912 191,773 |
| 3 | 1,04 | 8,283 181,908 | 1,03 | 8,220 191,078 |
| 5 | 1,09 | 8,101 187,705 | 1,05 | 7,780 190,065 |
| 8 | 1,05 | 9,217 179,191 | 1,12 | 6,111 193,024 |
-----------------------------------------------------------------
OVH = (Execution time with -z N) / (Execution time with -z 0)
ratio - compression ratio
size - number of bytes that was compressed
size ~= trace size x ratio
Committer notes:
Testing it I noticed that it failed to disable build id processing when
compression is enabled, and as we'd have to uncompress everything to
look for the PERF_RECORD_{MMAP,SAMPLE,etc} to figure out which build ids
to read from DSOs, we better disable build id processing when
compression is enabled, logging with pr_debug() when doing so:
Original patch:
# perf record -z2
^C[ perf record: Woken up 1 times to write data ]
0x1746e0 [0x76]: failed to process type: 81 [Invalid argument]
[ perf record: Captured and wrote 1.568 MB perf.data, compressed (original 0.452 MB, ratio is 3.995) ]
#
After auto-disabling build id processing when compression is enabled:
$ perf record -z2 sleep 1
[ perf record: Woken up 1 times to write data ]
[ perf record: Captured and wrote 0.001 MB perf.data, compressed (original 0.001 MB, ratio is 2.292) ]
$ perf record -v -z2 sleep 1
Compression enabled, disabling build id collection at the end of the session.
<SNIP extra -v pr_debug() messages>
[ perf record: Woken up 1 times to write data ]
[ perf record: Captured and wrote 0.001 MB perf.data, compressed (original 0.001 MB, ratio is 2.305) ]
$
Also, with parts of the patch originally after this one moved to just
before this one we get:
$ perf record -z2 sleep 1
[ perf record: Woken up 1 times to write data ]
[ perf record: Captured and wrote 0.001 MB perf.data, compressed (original 0.001 MB, ratio is 2.371) ]
$ perf report -D | grep COMPRESS
0 0x1b8 [0x155]: PERF_RECORD_COMPRESSED: unhandled!
0 0x30d [0x80]: PERF_RECORD_COMPRESSED: unhandled!
COMPRESSED events: 2
COMPRESSED events: 0
$
I.e. when faced with PERF_RECORD_COMPRESSED that we still have no code
to process, we just show it as not being handled, skip them and
continue, while before we had:
$ perf report -D | grep COMPRESS
0x1b8 [0x169]: failed to process type: 81 [Invalid argument]
Error:
failed to process sample
0 0x1b8 [0x169]: PERF_RECORD_COMPRESSED
$
Signed-off-by: Alexey Budankov <alexey.budankov@linux.intel.com>
Reviewed-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: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Link: http://lkml.kernel.org/r/9ff06518-ae63-a908-e44d-5d9e56dd66d9@linux.intel.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2019-03-19 01:44:42 +08:00
|
|
|
#ifdef HAVE_ZSTD_SUPPORT
|
|
|
|
static unsigned int comp_level_default = 1;
|
|
|
|
|
|
|
|
static int record__parse_comp_level(const struct option *opt, const char *str, int unset)
|
|
|
|
{
|
|
|
|
struct record_opts *opts = opt->value;
|
|
|
|
|
|
|
|
if (unset) {
|
|
|
|
opts->comp_level = 0;
|
|
|
|
} else {
|
|
|
|
if (str)
|
|
|
|
opts->comp_level = strtol(str, NULL, 0);
|
|
|
|
if (!opts->comp_level)
|
|
|
|
opts->comp_level = comp_level_default;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
#endif
|
2019-03-19 01:42:19 +08:00
|
|
|
static unsigned int comp_level_max = 22;
|
|
|
|
|
2019-03-19 01:41:33 +08:00
|
|
|
static int record__comp_enabled(struct record *rec)
|
|
|
|
{
|
|
|
|
return rec->opts.comp_level > 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
|
|
|
}
|
|
|
|
|
2020-04-22 23:50:38 +08:00
|
|
|
static int process_locked_synthesized_event(struct perf_tool *tool,
|
|
|
|
union perf_event *event,
|
|
|
|
struct perf_sample *sample __maybe_unused,
|
|
|
|
struct machine *machine __maybe_unused)
|
|
|
|
{
|
|
|
|
static pthread_mutex_t synth_lock = PTHREAD_MUTEX_INITIALIZER;
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
pthread_mutex_lock(&synth_lock);
|
|
|
|
ret = process_synthesized_event(tool, event, sample, machine);
|
|
|
|
pthread_mutex_unlock(&synth_lock);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2019-07-28 02:30:53 +08:00
|
|
|
static int record__pushfn(struct mmap *map, void *to, void *bf, size_t size)
|
2017-10-06 03:39:55 +08:00
|
|
|
{
|
|
|
|
struct record *rec = to;
|
|
|
|
|
2019-03-19 01:43:35 +08:00
|
|
|
if (record__comp_enabled(rec)) {
|
2019-10-07 20:53:11 +08:00
|
|
|
size = zstd_compress(rec->session, map->data, mmap__mmap_len(map), bf, size);
|
2019-03-19 01:43:35 +08:00
|
|
|
bf = map->data;
|
|
|
|
}
|
|
|
|
|
2017-10-06 03:39:55 +08:00
|
|
|
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 signr = -1;
|
|
|
|
static volatile int child_finished;
|
2020-05-13 10:20:23 +08:00
|
|
|
#ifdef HAVE_EVENTFD_SUPPORT
|
|
|
|
static int done_fd = -1;
|
|
|
|
#endif
|
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;
|
2020-05-13 10:20:23 +08:00
|
|
|
#ifdef HAVE_EVENTFD_SUPPORT
|
|
|
|
{
|
|
|
|
u64 tmp = 1;
|
|
|
|
/*
|
|
|
|
* It is possible for this signal handler to run after done is checked
|
|
|
|
* in the main loop, but before the perf counter fds are polled. If this
|
|
|
|
* happens, the poll() will continue to wait even though done is set,
|
|
|
|
* and will only break out if either another signal is received, or the
|
|
|
|
* counters are ready for read. To ensure the poll() doesn't sleep when
|
|
|
|
* done is set, use an eventfd (done_fd) to wake up the poll().
|
|
|
|
*/
|
|
|
|
if (write(done_fd, &tmp, sizeof(tmp)) < 0)
|
|
|
|
pr_err("failed to signal wakeup fd, error: %m\n");
|
|
|
|
}
|
|
|
|
#endif // HAVE_EVENTFD_SUPPORT
|
2015-04-30 22:37:32 +08:00
|
|
|
}
|
|
|
|
|
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,
|
2019-07-28 02:30:53 +08:00
|
|
|
struct 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-10-04 16:31:20 +08:00
|
|
|
if (!perf_data__is_pipe(data) && perf_data__is_single_file(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,
|
2019-07-28 02:30:53 +08:00
|
|
|
struct 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,
|
2019-07-28 02:30:53 +08:00
|
|
|
struct 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;
|
|
|
|
|
2019-07-30 19:04:59 +08:00
|
|
|
for (i = 0; i < rec->evlist->core.nr_mmaps; i++) {
|
2019-07-28 02:30:53 +08:00
|
|
|
struct 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;
|
|
|
|
}
|
|
|
|
|
2019-08-06 22:41:01 +08:00
|
|
|
static void record__read_auxtrace_snapshot(struct record *rec, bool on_exit)
|
2015-04-30 22:37:32 +08:00
|
|
|
{
|
|
|
|
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 {
|
2019-08-06 22:41:01 +08:00
|
|
|
if (auxtrace_record__snapshot_finish(rec->itr, on_exit))
|
2016-04-21 02:59:49 +08:00
|
|
|
trigger_error(&auxtrace_snapshot_trigger);
|
|
|
|
else
|
|
|
|
trigger_ready(&auxtrace_snapshot_trigger);
|
2015-04-30 22:37:32 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-08-06 22:41:01 +08:00
|
|
|
static int record__auxtrace_snapshot_exit(struct record *rec)
|
|
|
|
{
|
|
|
|
if (trigger_is_error(&auxtrace_snapshot_trigger))
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
if (!auxtrace_record__snapshot_started &&
|
|
|
|
auxtrace_record__snapshot_start(rec->itr))
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
record__read_auxtrace_snapshot(rec, true);
|
|
|
|
if (trigger_is_error(&auxtrace_snapshot_trigger))
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
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;
|
|
|
|
|
2019-11-15 20:42:16 +08:00
|
|
|
err = auxtrace_parse_sample_options(rec->itr, rec->evlist, &rec->opts,
|
|
|
|
rec->opts.auxtrace_sample_opts);
|
|
|
|
if (err)
|
|
|
|
return err;
|
|
|
|
|
2018-03-06 17:13:12 +08:00
|
|
|
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,
|
2019-07-28 02:30:53 +08:00
|
|
|
struct mmap *map __maybe_unused)
|
2015-04-30 22:37:27 +08:00
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2015-04-30 22:37:32 +08:00
|
|
|
static inline
|
2019-08-06 22:41:01 +08:00
|
|
|
void record__read_auxtrace_snapshot(struct record *rec __maybe_unused,
|
|
|
|
bool on_exit __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
|
|
|
}
|
|
|
|
|
2019-08-06 22:41:01 +08:00
|
|
|
static inline
|
|
|
|
int record__auxtrace_snapshot_exit(struct record *rec __maybe_unused)
|
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
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
|
|
|
|
|
2020-05-12 20:19:18 +08:00
|
|
|
static int record__config_text_poke(struct evlist *evlist)
|
|
|
|
{
|
|
|
|
struct evsel *evsel;
|
|
|
|
int err;
|
|
|
|
|
|
|
|
/* Nothing to do if text poke is already configured */
|
|
|
|
evlist__for_each_entry(evlist, evsel) {
|
|
|
|
if (evsel->core.attr.text_poke)
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
err = parse_events(evlist, "dummy:u", NULL);
|
|
|
|
if (err)
|
|
|
|
return err;
|
|
|
|
|
|
|
|
evsel = evlist__last(evlist);
|
|
|
|
|
|
|
|
evsel->core.attr.freq = 0;
|
|
|
|
evsel->core.attr.sample_period = 1;
|
|
|
|
evsel->core.attr.text_poke = 1;
|
|
|
|
evsel->core.attr.ksymbol = 1;
|
|
|
|
|
|
|
|
evsel->core.system_wide = true;
|
|
|
|
evsel->no_aux_samples = true;
|
|
|
|
evsel->immediate = true;
|
|
|
|
|
|
|
|
/* Text poke must be collected on all CPUs */
|
|
|
|
perf_cpu_map__put(evsel->core.own_cpus);
|
|
|
|
evsel->core.own_cpus = perf_cpu_map__new(NULL);
|
|
|
|
perf_cpu_map__put(evsel->core.cpus);
|
|
|
|
evsel->core.cpus = perf_cpu_map__get(evsel->core.own_cpus);
|
|
|
|
|
|
|
|
evsel__set_sample_bit(evsel, TIME);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
perf record: Put a copy of kcore into the perf.data directory
Add a new 'perf record' option '--kcore' which will put a copy of
/proc/kcore, kallsyms and modules into a perf.data directory. Note, that
without the --kcore option, output goes to a file as previously. The
tools' -o and -i options work with either a file name or directory name.
Example:
$ sudo perf record --kcore uname
$ sudo tree perf.data
perf.data
├── kcore_dir
│ ├── kallsyms
│ ├── kcore
│ └── modules
└── data
$ sudo perf script -v
build id event received for vmlinux: 1eaa285996affce2d74d8e66dcea09a80c9941de
build id event received for [vdso]: 8bbaf5dc62a9b644b4d4e4539737e104e4a84541
Samples for 'cycles' event do not have CPU attribute set. Skipping 'cpu' field.
Using CPUID GenuineIntel-6-8E-A
Using perf.data/kcore_dir/kcore for kernel data
Using perf.data/kcore_dir/kallsyms for symbols
perf 19058 506778.423729: 1 cycles: ffffffffa2caa548 native_write_msr+0x8 (vmlinux)
perf 19058 506778.423733: 1 cycles: ffffffffa2caa548 native_write_msr+0x8 (vmlinux)
perf 19058 506778.423734: 7 cycles: ffffffffa2caa548 native_write_msr+0x8 (vmlinux)
perf 19058 506778.423736: 117 cycles: ffffffffa2caa54a native_write_msr+0xa (vmlinux)
perf 19058 506778.423738: 2092 cycles: ffffffffa2c9b7b0 native_apic_msr_write+0x0 (vmlinux)
perf 19058 506778.423740: 37380 cycles: ffffffffa2f121d0 perf_event_addr_filters_exec+0x0 (vmlinux)
uname 19058 506778.423751: 582673 cycles: ffffffffa303a407 propagate_protected_usage+0x147 (vmlinux)
uname 19058 506778.423892: 2241841 cycles: ffffffffa2cae0c9 unwind_next_frame.part.5+0x79 (vmlinux)
uname 19058 506778.424430: 2457397 cycles: ffffffffa3019232 check_memory_region+0x52 (vmlinux)
Committer testing:
# rm -rf perf.data*
# perf record sleep 1
[ perf record: Woken up 1 times to write data ]
[ perf record: Captured and wrote 0.024 MB perf.data (7 samples) ]
# ls -l perf.data
-rw-------. 1 root root 34772 Oct 21 11:08 perf.data
# perf record --kcore uname
Linux
[ perf record: Woken up 1 times to write data ]
[ perf record: Captured and wrote 0.024 MB perf.data (7 samples) ]
ls[root@quaco ~]# ls -lad perf.data*
drwx------. 3 root root 4096 Oct 21 11:08 perf.data
-rw-------. 1 root root 34772 Oct 21 11:08 perf.data.old
# perf evlist -v
cycles: size: 112, { sample_period, sample_freq }: 4000, sample_type: IP|TID|TIME|PERIOD, read_format: ID, 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, ksymbol: 1, bpf_event: 1
# perf evlist -v -i perf.data/data
cycles: size: 112, { sample_period, sample_freq }: 4000, sample_type: IP|TID|TIME|PERIOD, read_format: ID, 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, ksymbol: 1, bpf_event: 1
#
Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
Reviewed-by: Jiri Olsa <jolsa@kernel.org>
Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Link: http://lore.kernel.org/lkml/20191004083121.12182-6-adrian.hunter@intel.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2019-10-04 16:31:21 +08:00
|
|
|
static bool record__kcore_readable(struct machine *machine)
|
|
|
|
{
|
|
|
|
char kcore[PATH_MAX];
|
|
|
|
int fd;
|
|
|
|
|
|
|
|
scnprintf(kcore, sizeof(kcore), "%s/proc/kcore", machine->root_dir);
|
|
|
|
|
|
|
|
fd = open(kcore, O_RDONLY);
|
|
|
|
if (fd < 0)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
close(fd);
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int record__kcore_copy(struct machine *machine, struct perf_data *data)
|
|
|
|
{
|
|
|
|
char from_dir[PATH_MAX];
|
|
|
|
char kcore_dir[PATH_MAX];
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
snprintf(from_dir, sizeof(from_dir), "%s/proc", machine->root_dir);
|
|
|
|
|
|
|
|
ret = perf_data__make_kcore_dir(data, kcore_dir, sizeof(kcore_dir));
|
|
|
|
if (ret)
|
|
|
|
return ret;
|
|
|
|
|
|
|
|
return kcore_copy(from_dir, kcore_dir);
|
|
|
|
}
|
|
|
|
|
2016-06-27 18:24:03 +08:00
|
|
|
static int record__mmap_evlist(struct record *rec,
|
2019-07-21 19:23:52 +08:00
|
|
|
struct evlist *evlist)
|
2016-06-27 18:24:03 +08:00
|
|
|
{
|
|
|
|
struct record_opts *opts = &rec->opts;
|
2019-11-15 20:42:16 +08:00
|
|
|
bool auxtrace_overwrite = opts->auxtrace_snapshot_mode ||
|
|
|
|
opts->auxtrace_sample_mode;
|
2016-06-27 18:24:03 +08:00
|
|
|
char msg[512];
|
|
|
|
|
2019-01-23 01:50:57 +08:00
|
|
|
if (opts->affinity != PERF_AFFINITY_SYS)
|
|
|
|
cpu__setup_cpunode_map();
|
|
|
|
|
2019-07-28 18:45:35 +08:00
|
|
|
if (evlist__mmap_ex(evlist, opts->mmap_pages,
|
2016-06-27 18:24:03 +08:00
|
|
|
opts->auxtrace_mmap_pages,
|
2019-11-15 20:42:16 +08:00
|
|
|
auxtrace_overwrite,
|
perf record: Implement --mmap-flush=<number> option
Implement a --mmap-flush option that specifies minimal number of bytes
that is extracted from mmaped kernel buffer to store into a trace. The
default option value is 1 byte what means every time trace writing
thread finds some new data in the mmaped buffer the data is extracted,
possibly compressed and written to a trace.
$ tools/perf/perf record --mmap-flush 1024 -e cycles -- matrix.gcc
$ tools/perf/perf record --aio --mmap-flush 1K -e cycles -- matrix.gcc
The option is independent from -z setting, doesn't vary with compression
level and can serve two purposes.
The first purpose is to increase the compression ratio of a trace data.
Larger data chunks are compressed more effectively so the implemented
option allows specifying data chunk size to compress. Also at some cases
executing more write syscalls with smaller data size can take longer
than executing less write syscalls with bigger data size due to syscall
overhead so extracting bigger data chunks specified by the option value
could additionally decrease runtime overhead.
The second purpose is to avoid self monitoring live-lock issue in system
wide (-a) profiling mode. Profiling in system wide mode with compression
(-a -z) can additionally induce data into the kernel buffers along with
the data from monitored processes. If performance data rate and volume
from the monitored processes is high then trace streaming and
compression activity in the tool is also high. High tool process
activity can lead to subtle live-lock effect when compression of single
new byte from some of mmaped kernel buffer leads to generation of the
next single byte at some mmaped buffer. So perf tool process ends up in
endless self monitoring.
Implemented synch parameter is the mean to force data move independently
from the specified flush threshold value. Despite the provided flush
value the tool needs capability to unconditionally drain memory buffers,
at least in the end of the collection.
Committer testing:
Running with the default value, i.e. as soon as there is something to
read go on consuming, we first write the synthesized events, small
chunks of about 128 bytes:
# perf trace -m 2048 --call-graph dwarf -e write -- perf record
<SNIP>
101.142 ( 0.004 ms): perf/25821 write(fd: 3</root/perf.data>, buf: 0x210db60, count: 120) = 120
__libc_write (/usr/lib64/libpthread-2.28.so)
ion (/home/acme/bin/perf)
record__write (inlined)
process_synthesized_event (/home/acme/bin/perf)
perf_tool__process_synth_event (inlined)
perf_event__synthesize_mmap_events (/home/acme/bin/perf)
Then we move to reading the mmap buffers consuming the events put there
by the kernel perf infrastructure:
107.561 ( 0.005 ms): perf/25821 write(fd: 3</root/perf.data>, buf: 0x7f1befc02000, count: 336) = 336
__libc_write (/usr/lib64/libpthread-2.28.so)
ion (/home/acme/bin/perf)
record__write (inlined)
record__pushfn (/home/acme/bin/perf)
perf_mmap__push (/home/acme/bin/perf)
record__mmap_read_evlist (inlined)
record__mmap_read_all (inlined)
__cmd_record (inlined)
cmd_record (/home/acme/bin/perf)
12919.953 ( 0.136 ms): perf/25821 write(fd: 3</root/perf.data>, buf: 0x7f1befc83150, count: 184984) = 184984
<SNIP same backtrace as in the 107.561 timestamp>
12920.094 ( 0.155 ms): perf/25821 write(fd: 3</root/perf.data>, buf: 0x7f1befc02150, count: 261816) = 261816
<SNIP same backtrace as in the 107.561 timestamp>
12920.253 ( 0.093 ms): perf/25821 write(fd: 3</root/perf.data>, buf: 0x7f1befb81120, count: 170832) = 170832
<SNIP same backtrace as in the 107.561 timestamp>
If we limit it to write only when more than 16MB are available for
reading, it throttles that to a quarter of the --mmap-pages set for
'perf record', which by default get to 528384 bytes, found out using
'record -v':
mmap flush: 132096
mmap size 528384B
With that in place all the writes coming from
record__mmap_read_evlist(), i.e. from the mmap buffers setup by the
kernel perf infrastructure were at least 132096 bytes long.
Trying with a bigger mmap size:
perf trace -e write perf record -v -m 2048 --mmap-flush 16M
74982.928 ( 2.471 ms): perf/26500 write(fd: 3</root/perf.data>, buf: 0x7ff94a6cc000, count: 3580888) = 3580888
74985.406 ( 2.353 ms): perf/26500 write(fd: 3</root/perf.data>, buf: 0x7ff949ecb000, count: 3453256) = 3453256
74987.764 ( 2.629 ms): perf/26500 write(fd: 3</root/perf.data>, buf: 0x7ff9496ca000, count: 3859232) = 3859232
74990.399 ( 2.341 ms): perf/26500 write(fd: 3</root/perf.data>, buf: 0x7ff948ec9000, count: 3769032) = 3769032
74992.744 ( 2.064 ms): perf/26500 write(fd: 3</root/perf.data>, buf: 0x7ff9486c8000, count: 3310520) = 3310520
74994.814 ( 2.619 ms): perf/26500 write(fd: 3</root/perf.data>, buf: 0x7ff947ec7000, count: 4194688) = 4194688
74997.439 ( 2.787 ms): perf/26500 write(fd: 3</root/perf.data>, buf: 0x7ff9476c6000, count: 4029760) = 4029760
Was again limited to a quarter of the mmap size:
mmap flush: 2098176
mmap size 8392704B
A warning about that would be good to have but can be added later,
something like:
"max flush is a quarter of the mmap size, if wanting to bump the mmap
flush further, bump the mmap size as well using -m/--mmap-pages"
Also rename the 'sync' parameters to 'synch' to keep tools/perf building
with older glibcs:
cc1: warnings being treated as errors
builtin-record.c: In function 'record__mmap_read_evlist':
builtin-record.c:775: warning: declaration of 'sync' shadows a global declaration
/usr/include/unistd.h:933: warning: shadowed declaration is here
builtin-record.c: In function 'record__mmap_read_all':
builtin-record.c:856: warning: declaration of 'sync' shadows a global declaration
/usr/include/unistd.h:933: warning: shadowed declaration is here
Signed-off-by: Alexey Budankov <alexey.budankov@linux.intel.com>
Reviewed-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: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Link: http://lkml.kernel.org/r/f6600d72-ecfa-2eb7-7e51-f6954547d500@linux.intel.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2019-03-19 01:40:26 +08:00
|
|
|
opts->nr_cblocks, opts->affinity,
|
2019-03-19 01:42:19 +08:00
|
|
|
opts->mmap_flush, opts->comp_level) < 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];
|
2019-07-21 19:23:51 +08:00
|
|
|
struct evsel *pos;
|
2019-07-21 19:23:52 +08:00
|
|
|
struct evlist *evlist = rec->evlist;
|
2011-11-25 18:19:45 +08:00
|
|
|
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
|
|
|
/*
|
2020-04-23 01:36:15 +08:00
|
|
|
* For initial_delay or system wide, we need to add a dummy event so
|
|
|
|
* that we can track PERF_RECORD_MMAP to cover the delay of waiting or
|
|
|
|
* event synthesis.
|
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
|
|
|
*/
|
2020-04-23 01:36:15 +08:00
|
|
|
if (opts->initial_delay || target__has_cpu(&opts->target)) {
|
2020-06-29 17:19:51 +08:00
|
|
|
pos = perf_evlist__get_tracking_event(evlist);
|
|
|
|
if (!evsel__is_dummy_event(pos)) {
|
|
|
|
/* Set up dummy event. */
|
2020-07-09 00:49:15 +08:00
|
|
|
if (evlist__add_dummy(evlist))
|
2020-06-29 17:19:51 +08:00
|
|
|
return -ENOMEM;
|
|
|
|
pos = evlist__last(evlist);
|
|
|
|
perf_evlist__set_tracking_event(evlist, pos);
|
|
|
|
}
|
|
|
|
|
2020-04-23 01:36:15 +08:00
|
|
|
/*
|
|
|
|
* Enable the dummy event when the process is forked for
|
|
|
|
* initial_delay, immediately for system wide.
|
|
|
|
*/
|
2020-06-29 17:19:51 +08:00
|
|
|
if (opts->initial_delay && !pos->immediate)
|
2020-04-23 01:36:15 +08:00
|
|
|
pos->core.attr.enable_on_exec = 1;
|
|
|
|
else
|
|
|
|
pos->immediate = 1;
|
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
|
|
|
}
|
|
|
|
|
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:
|
2019-07-21 19:24:39 +08:00
|
|
|
if (evsel__open(pos, pos->core.cpus, pos->core.threads) < 0) {
|
2020-04-30 22:46:15 +08:00
|
|
|
if (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) {
|
2019-11-21 08:15:19 +08:00
|
|
|
pos = perf_evlist__reset_weak_group(evlist, pos, true);
|
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
|
|
|
goto try_again;
|
|
|
|
}
|
2012-12-14 02:10:58 +08:00
|
|
|
rc = -errno;
|
2020-05-05 00:43:03 +08:00
|
|
|
evsel__open_strerror(pos, &opts->target, errno, msg, sizeof(msg));
|
2012-12-14 02:10:58 +08:00
|
|
|
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
|
|
|
|
perf record: Move restricted maps check to after a possible fallback to not collect kernel samples
Before:
[acme@quaco ~]$ perf record -b -e cycles date
WARNING: Kernel address maps (/proc/{kallsyms,modules}) are restricted,
check /proc/sys/kernel/kptr_restrict and /proc/sys/kernel/perf_event_paranoid.
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.
Mon 23 Sep 2019 11:00:59 AM -03
[ perf record: Woken up 1 times to write data ]
[ perf record: Captured and wrote 0.005 MB perf.data (14 samples) ]
[acme@quaco ~]$
But we did a fallback and exclude_kernel was set, so no need for
resolving kernel symbols:
$ perf evlist -v
cycles:u: size: 112, { sample_period, sample_freq }: 4000, sample_type: IP|TID|TIME|PERIOD|BRANCH_STACK, read_format: ID, disabled: 1, inherit: 1, exclude_kernel: 1, exclude_hv: 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, ksymbol: 1, bpf_event: 1, branch_sample_type: ANY
$
After:
[acme@quaco ~]$ perf record -b -e cycles date
Mon 23 Sep 2019 11:07:18 AM -03
[ perf record: Woken up 1 times to write data ]
[ perf record: Captured and wrote 0.007 MB perf.data (16 samples) ]
[acme@quaco ~]$ perf evlist -v
cycles:u: size: 112, { sample_period, sample_freq }: 4000, sample_type: IP|TID|TIME|PERIOD|BRANCH_STACK, read_format: ID, disabled: 1, inherit: 1, exclude_kernel: 1, exclude_hv: 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, ksymbol: 1, bpf_event: 1, branch_sample_type: ANY
[acme@quaco ~]$
No needless warning is emitted.
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Stephane Eranian <eranian@google.com>
Link: https://lkml.kernel.org/n/tip-5yqnr8xcqwhr15xktj2097ac@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2019-09-23 22:07:29 +08:00
|
|
|
if (symbol_conf.kptr_restrict && !perf_evlist__exclude_kernel(evlist)) {
|
|
|
|
pr_warning(
|
|
|
|
"WARNING: Kernel address maps (/proc/{kallsyms,modules}) are restricted,\n"
|
|
|
|
"check /proc/sys/kernel/kptr_restrict and /proc/sys/kernel/perf_event_paranoid.\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");
|
|
|
|
}
|
|
|
|
|
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",
|
2020-04-30 03:07:09 +08:00
|
|
|
pos->filter, 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,
|
2019-07-21 19:23:51 +08:00
|
|
|
struct evsel *evsel,
|
2015-01-29 16:06:44 +08:00
|
|
|
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-07-28 02:30:53 +08:00
|
|
|
static void record__adjust_affinity(struct record *rec, struct mmap *map)
|
2019-01-23 01:50:57 +08:00
|
|
|
{
|
|
|
|
if (rec->opts.affinity != PERF_AFFINITY_SYS &&
|
2019-12-03 19:45:27 +08:00
|
|
|
!bitmap_equal(rec->affinity_mask.bits, map->affinity_mask.bits,
|
|
|
|
rec->affinity_mask.nbits)) {
|
|
|
|
bitmap_zero(rec->affinity_mask.bits, rec->affinity_mask.nbits);
|
|
|
|
bitmap_or(rec->affinity_mask.bits, rec->affinity_mask.bits,
|
|
|
|
map->affinity_mask.bits, rec->affinity_mask.nbits);
|
|
|
|
sched_setaffinity(0, MMAP_CPU_MASK_BYTES(&rec->affinity_mask),
|
|
|
|
(cpu_set_t *)rec->affinity_mask.bits);
|
|
|
|
if (verbose == 2)
|
|
|
|
mmap_cpu_mask__scnprintf(&rec->affinity_mask, "thread");
|
2019-01-23 01:50:57 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-03-19 01:43:35 +08:00
|
|
|
static size_t process_comp_header(void *record, size_t increment)
|
|
|
|
{
|
2019-08-28 21:57:16 +08:00
|
|
|
struct perf_record_compressed *event = record;
|
2019-03-19 01:43:35 +08:00
|
|
|
size_t size = sizeof(*event);
|
|
|
|
|
|
|
|
if (increment) {
|
|
|
|
event->header.size += increment;
|
|
|
|
return increment;
|
|
|
|
}
|
|
|
|
|
|
|
|
event->header.type = PERF_RECORD_COMPRESSED;
|
|
|
|
event->header.size = size;
|
|
|
|
|
|
|
|
return size;
|
|
|
|
}
|
|
|
|
|
|
|
|
static size_t zstd_compress(struct perf_session *session, void *dst, size_t dst_size,
|
|
|
|
void *src, size_t src_size)
|
|
|
|
{
|
|
|
|
size_t compressed;
|
2019-08-28 21:57:16 +08:00
|
|
|
size_t max_record_size = PERF_SAMPLE_MAX_SIZE - sizeof(struct perf_record_compressed) - 1;
|
2019-03-19 01:43:35 +08:00
|
|
|
|
|
|
|
compressed = zstd_compress_stream_to_records(&session->zstd_data, dst, dst_size, src, src_size,
|
|
|
|
max_record_size, process_comp_header);
|
|
|
|
|
|
|
|
session->bytes_transferred += src_size;
|
|
|
|
session->bytes_compressed += compressed;
|
|
|
|
|
|
|
|
return compressed;
|
|
|
|
}
|
|
|
|
|
2019-07-21 19:23:52 +08:00
|
|
|
static int record__mmap_read_evlist(struct record *rec, struct evlist *evlist,
|
perf record: Implement --mmap-flush=<number> option
Implement a --mmap-flush option that specifies minimal number of bytes
that is extracted from mmaped kernel buffer to store into a trace. The
default option value is 1 byte what means every time trace writing
thread finds some new data in the mmaped buffer the data is extracted,
possibly compressed and written to a trace.
$ tools/perf/perf record --mmap-flush 1024 -e cycles -- matrix.gcc
$ tools/perf/perf record --aio --mmap-flush 1K -e cycles -- matrix.gcc
The option is independent from -z setting, doesn't vary with compression
level and can serve two purposes.
The first purpose is to increase the compression ratio of a trace data.
Larger data chunks are compressed more effectively so the implemented
option allows specifying data chunk size to compress. Also at some cases
executing more write syscalls with smaller data size can take longer
than executing less write syscalls with bigger data size due to syscall
overhead so extracting bigger data chunks specified by the option value
could additionally decrease runtime overhead.
The second purpose is to avoid self monitoring live-lock issue in system
wide (-a) profiling mode. Profiling in system wide mode with compression
(-a -z) can additionally induce data into the kernel buffers along with
the data from monitored processes. If performance data rate and volume
from the monitored processes is high then trace streaming and
compression activity in the tool is also high. High tool process
activity can lead to subtle live-lock effect when compression of single
new byte from some of mmaped kernel buffer leads to generation of the
next single byte at some mmaped buffer. So perf tool process ends up in
endless self monitoring.
Implemented synch parameter is the mean to force data move independently
from the specified flush threshold value. Despite the provided flush
value the tool needs capability to unconditionally drain memory buffers,
at least in the end of the collection.
Committer testing:
Running with the default value, i.e. as soon as there is something to
read go on consuming, we first write the synthesized events, small
chunks of about 128 bytes:
# perf trace -m 2048 --call-graph dwarf -e write -- perf record
<SNIP>
101.142 ( 0.004 ms): perf/25821 write(fd: 3</root/perf.data>, buf: 0x210db60, count: 120) = 120
__libc_write (/usr/lib64/libpthread-2.28.so)
ion (/home/acme/bin/perf)
record__write (inlined)
process_synthesized_event (/home/acme/bin/perf)
perf_tool__process_synth_event (inlined)
perf_event__synthesize_mmap_events (/home/acme/bin/perf)
Then we move to reading the mmap buffers consuming the events put there
by the kernel perf infrastructure:
107.561 ( 0.005 ms): perf/25821 write(fd: 3</root/perf.data>, buf: 0x7f1befc02000, count: 336) = 336
__libc_write (/usr/lib64/libpthread-2.28.so)
ion (/home/acme/bin/perf)
record__write (inlined)
record__pushfn (/home/acme/bin/perf)
perf_mmap__push (/home/acme/bin/perf)
record__mmap_read_evlist (inlined)
record__mmap_read_all (inlined)
__cmd_record (inlined)
cmd_record (/home/acme/bin/perf)
12919.953 ( 0.136 ms): perf/25821 write(fd: 3</root/perf.data>, buf: 0x7f1befc83150, count: 184984) = 184984
<SNIP same backtrace as in the 107.561 timestamp>
12920.094 ( 0.155 ms): perf/25821 write(fd: 3</root/perf.data>, buf: 0x7f1befc02150, count: 261816) = 261816
<SNIP same backtrace as in the 107.561 timestamp>
12920.253 ( 0.093 ms): perf/25821 write(fd: 3</root/perf.data>, buf: 0x7f1befb81120, count: 170832) = 170832
<SNIP same backtrace as in the 107.561 timestamp>
If we limit it to write only when more than 16MB are available for
reading, it throttles that to a quarter of the --mmap-pages set for
'perf record', which by default get to 528384 bytes, found out using
'record -v':
mmap flush: 132096
mmap size 528384B
With that in place all the writes coming from
record__mmap_read_evlist(), i.e. from the mmap buffers setup by the
kernel perf infrastructure were at least 132096 bytes long.
Trying with a bigger mmap size:
perf trace -e write perf record -v -m 2048 --mmap-flush 16M
74982.928 ( 2.471 ms): perf/26500 write(fd: 3</root/perf.data>, buf: 0x7ff94a6cc000, count: 3580888) = 3580888
74985.406 ( 2.353 ms): perf/26500 write(fd: 3</root/perf.data>, buf: 0x7ff949ecb000, count: 3453256) = 3453256
74987.764 ( 2.629 ms): perf/26500 write(fd: 3</root/perf.data>, buf: 0x7ff9496ca000, count: 3859232) = 3859232
74990.399 ( 2.341 ms): perf/26500 write(fd: 3</root/perf.data>, buf: 0x7ff948ec9000, count: 3769032) = 3769032
74992.744 ( 2.064 ms): perf/26500 write(fd: 3</root/perf.data>, buf: 0x7ff9486c8000, count: 3310520) = 3310520
74994.814 ( 2.619 ms): perf/26500 write(fd: 3</root/perf.data>, buf: 0x7ff947ec7000, count: 4194688) = 4194688
74997.439 ( 2.787 ms): perf/26500 write(fd: 3</root/perf.data>, buf: 0x7ff9476c6000, count: 4029760) = 4029760
Was again limited to a quarter of the mmap size:
mmap flush: 2098176
mmap size 8392704B
A warning about that would be good to have but can be added later,
something like:
"max flush is a quarter of the mmap size, if wanting to bump the mmap
flush further, bump the mmap size as well using -m/--mmap-pages"
Also rename the 'sync' parameters to 'synch' to keep tools/perf building
with older glibcs:
cc1: warnings being treated as errors
builtin-record.c: In function 'record__mmap_read_evlist':
builtin-record.c:775: warning: declaration of 'sync' shadows a global declaration
/usr/include/unistd.h:933: warning: shadowed declaration is here
builtin-record.c: In function 'record__mmap_read_all':
builtin-record.c:856: warning: declaration of 'sync' shadows a global declaration
/usr/include/unistd.h:933: warning: shadowed declaration is here
Signed-off-by: Alexey Budankov <alexey.budankov@linux.intel.com>
Reviewed-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: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Link: http://lkml.kernel.org/r/f6600d72-ecfa-2eb7-7e51-f6954547d500@linux.intel.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2019-03-19 01:40:26 +08:00
|
|
|
bool overwrite, bool synch)
|
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;
|
2019-07-28 02:30:53 +08:00
|
|
|
struct mmap *maps;
|
2018-11-06 17:04:58 +08:00
|
|
|
int trace_fd = rec->data.file.fd;
|
2019-03-19 01:44:12 +08:00
|
|
|
off_t off = 0;
|
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);
|
|
|
|
|
2019-07-30 19:04:59 +08:00
|
|
|
for (i = 0; i < evlist->core.nr_mmaps; i++) {
|
perf record: Implement --mmap-flush=<number> option
Implement a --mmap-flush option that specifies minimal number of bytes
that is extracted from mmaped kernel buffer to store into a trace. The
default option value is 1 byte what means every time trace writing
thread finds some new data in the mmaped buffer the data is extracted,
possibly compressed and written to a trace.
$ tools/perf/perf record --mmap-flush 1024 -e cycles -- matrix.gcc
$ tools/perf/perf record --aio --mmap-flush 1K -e cycles -- matrix.gcc
The option is independent from -z setting, doesn't vary with compression
level and can serve two purposes.
The first purpose is to increase the compression ratio of a trace data.
Larger data chunks are compressed more effectively so the implemented
option allows specifying data chunk size to compress. Also at some cases
executing more write syscalls with smaller data size can take longer
than executing less write syscalls with bigger data size due to syscall
overhead so extracting bigger data chunks specified by the option value
could additionally decrease runtime overhead.
The second purpose is to avoid self monitoring live-lock issue in system
wide (-a) profiling mode. Profiling in system wide mode with compression
(-a -z) can additionally induce data into the kernel buffers along with
the data from monitored processes. If performance data rate and volume
from the monitored processes is high then trace streaming and
compression activity in the tool is also high. High tool process
activity can lead to subtle live-lock effect when compression of single
new byte from some of mmaped kernel buffer leads to generation of the
next single byte at some mmaped buffer. So perf tool process ends up in
endless self monitoring.
Implemented synch parameter is the mean to force data move independently
from the specified flush threshold value. Despite the provided flush
value the tool needs capability to unconditionally drain memory buffers,
at least in the end of the collection.
Committer testing:
Running with the default value, i.e. as soon as there is something to
read go on consuming, we first write the synthesized events, small
chunks of about 128 bytes:
# perf trace -m 2048 --call-graph dwarf -e write -- perf record
<SNIP>
101.142 ( 0.004 ms): perf/25821 write(fd: 3</root/perf.data>, buf: 0x210db60, count: 120) = 120
__libc_write (/usr/lib64/libpthread-2.28.so)
ion (/home/acme/bin/perf)
record__write (inlined)
process_synthesized_event (/home/acme/bin/perf)
perf_tool__process_synth_event (inlined)
perf_event__synthesize_mmap_events (/home/acme/bin/perf)
Then we move to reading the mmap buffers consuming the events put there
by the kernel perf infrastructure:
107.561 ( 0.005 ms): perf/25821 write(fd: 3</root/perf.data>, buf: 0x7f1befc02000, count: 336) = 336
__libc_write (/usr/lib64/libpthread-2.28.so)
ion (/home/acme/bin/perf)
record__write (inlined)
record__pushfn (/home/acme/bin/perf)
perf_mmap__push (/home/acme/bin/perf)
record__mmap_read_evlist (inlined)
record__mmap_read_all (inlined)
__cmd_record (inlined)
cmd_record (/home/acme/bin/perf)
12919.953 ( 0.136 ms): perf/25821 write(fd: 3</root/perf.data>, buf: 0x7f1befc83150, count: 184984) = 184984
<SNIP same backtrace as in the 107.561 timestamp>
12920.094 ( 0.155 ms): perf/25821 write(fd: 3</root/perf.data>, buf: 0x7f1befc02150, count: 261816) = 261816
<SNIP same backtrace as in the 107.561 timestamp>
12920.253 ( 0.093 ms): perf/25821 write(fd: 3</root/perf.data>, buf: 0x7f1befb81120, count: 170832) = 170832
<SNIP same backtrace as in the 107.561 timestamp>
If we limit it to write only when more than 16MB are available for
reading, it throttles that to a quarter of the --mmap-pages set for
'perf record', which by default get to 528384 bytes, found out using
'record -v':
mmap flush: 132096
mmap size 528384B
With that in place all the writes coming from
record__mmap_read_evlist(), i.e. from the mmap buffers setup by the
kernel perf infrastructure were at least 132096 bytes long.
Trying with a bigger mmap size:
perf trace -e write perf record -v -m 2048 --mmap-flush 16M
74982.928 ( 2.471 ms): perf/26500 write(fd: 3</root/perf.data>, buf: 0x7ff94a6cc000, count: 3580888) = 3580888
74985.406 ( 2.353 ms): perf/26500 write(fd: 3</root/perf.data>, buf: 0x7ff949ecb000, count: 3453256) = 3453256
74987.764 ( 2.629 ms): perf/26500 write(fd: 3</root/perf.data>, buf: 0x7ff9496ca000, count: 3859232) = 3859232
74990.399 ( 2.341 ms): perf/26500 write(fd: 3</root/perf.data>, buf: 0x7ff948ec9000, count: 3769032) = 3769032
74992.744 ( 2.064 ms): perf/26500 write(fd: 3</root/perf.data>, buf: 0x7ff9486c8000, count: 3310520) = 3310520
74994.814 ( 2.619 ms): perf/26500 write(fd: 3</root/perf.data>, buf: 0x7ff947ec7000, count: 4194688) = 4194688
74997.439 ( 2.787 ms): perf/26500 write(fd: 3</root/perf.data>, buf: 0x7ff9476c6000, count: 4029760) = 4029760
Was again limited to a quarter of the mmap size:
mmap flush: 2098176
mmap size 8392704B
A warning about that would be good to have but can be added later,
something like:
"max flush is a quarter of the mmap size, if wanting to bump the mmap
flush further, bump the mmap size as well using -m/--mmap-pages"
Also rename the 'sync' parameters to 'synch' to keep tools/perf building
with older glibcs:
cc1: warnings being treated as errors
builtin-record.c: In function 'record__mmap_read_evlist':
builtin-record.c:775: warning: declaration of 'sync' shadows a global declaration
/usr/include/unistd.h:933: warning: shadowed declaration is here
builtin-record.c: In function 'record__mmap_read_all':
builtin-record.c:856: warning: declaration of 'sync' shadows a global declaration
/usr/include/unistd.h:933: warning: shadowed declaration is here
Signed-off-by: Alexey Budankov <alexey.budankov@linux.intel.com>
Reviewed-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: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Link: http://lkml.kernel.org/r/f6600d72-ecfa-2eb7-7e51-f6954547d500@linux.intel.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2019-03-19 01:40:26 +08:00
|
|
|
u64 flush = 0;
|
2019-07-28 02:30:53 +08:00
|
|
|
struct mmap *map = &maps[i];
|
2016-06-27 18:24:04 +08:00
|
|
|
|
2019-07-28 04:07:44 +08:00
|
|
|
if (map->core.base) {
|
2019-01-23 01:50:57 +08:00
|
|
|
record__adjust_affinity(rec, map);
|
perf record: Implement --mmap-flush=<number> option
Implement a --mmap-flush option that specifies minimal number of bytes
that is extracted from mmaped kernel buffer to store into a trace. The
default option value is 1 byte what means every time trace writing
thread finds some new data in the mmaped buffer the data is extracted,
possibly compressed and written to a trace.
$ tools/perf/perf record --mmap-flush 1024 -e cycles -- matrix.gcc
$ tools/perf/perf record --aio --mmap-flush 1K -e cycles -- matrix.gcc
The option is independent from -z setting, doesn't vary with compression
level and can serve two purposes.
The first purpose is to increase the compression ratio of a trace data.
Larger data chunks are compressed more effectively so the implemented
option allows specifying data chunk size to compress. Also at some cases
executing more write syscalls with smaller data size can take longer
than executing less write syscalls with bigger data size due to syscall
overhead so extracting bigger data chunks specified by the option value
could additionally decrease runtime overhead.
The second purpose is to avoid self monitoring live-lock issue in system
wide (-a) profiling mode. Profiling in system wide mode with compression
(-a -z) can additionally induce data into the kernel buffers along with
the data from monitored processes. If performance data rate and volume
from the monitored processes is high then trace streaming and
compression activity in the tool is also high. High tool process
activity can lead to subtle live-lock effect when compression of single
new byte from some of mmaped kernel buffer leads to generation of the
next single byte at some mmaped buffer. So perf tool process ends up in
endless self monitoring.
Implemented synch parameter is the mean to force data move independently
from the specified flush threshold value. Despite the provided flush
value the tool needs capability to unconditionally drain memory buffers,
at least in the end of the collection.
Committer testing:
Running with the default value, i.e. as soon as there is something to
read go on consuming, we first write the synthesized events, small
chunks of about 128 bytes:
# perf trace -m 2048 --call-graph dwarf -e write -- perf record
<SNIP>
101.142 ( 0.004 ms): perf/25821 write(fd: 3</root/perf.data>, buf: 0x210db60, count: 120) = 120
__libc_write (/usr/lib64/libpthread-2.28.so)
ion (/home/acme/bin/perf)
record__write (inlined)
process_synthesized_event (/home/acme/bin/perf)
perf_tool__process_synth_event (inlined)
perf_event__synthesize_mmap_events (/home/acme/bin/perf)
Then we move to reading the mmap buffers consuming the events put there
by the kernel perf infrastructure:
107.561 ( 0.005 ms): perf/25821 write(fd: 3</root/perf.data>, buf: 0x7f1befc02000, count: 336) = 336
__libc_write (/usr/lib64/libpthread-2.28.so)
ion (/home/acme/bin/perf)
record__write (inlined)
record__pushfn (/home/acme/bin/perf)
perf_mmap__push (/home/acme/bin/perf)
record__mmap_read_evlist (inlined)
record__mmap_read_all (inlined)
__cmd_record (inlined)
cmd_record (/home/acme/bin/perf)
12919.953 ( 0.136 ms): perf/25821 write(fd: 3</root/perf.data>, buf: 0x7f1befc83150, count: 184984) = 184984
<SNIP same backtrace as in the 107.561 timestamp>
12920.094 ( 0.155 ms): perf/25821 write(fd: 3</root/perf.data>, buf: 0x7f1befc02150, count: 261816) = 261816
<SNIP same backtrace as in the 107.561 timestamp>
12920.253 ( 0.093 ms): perf/25821 write(fd: 3</root/perf.data>, buf: 0x7f1befb81120, count: 170832) = 170832
<SNIP same backtrace as in the 107.561 timestamp>
If we limit it to write only when more than 16MB are available for
reading, it throttles that to a quarter of the --mmap-pages set for
'perf record', which by default get to 528384 bytes, found out using
'record -v':
mmap flush: 132096
mmap size 528384B
With that in place all the writes coming from
record__mmap_read_evlist(), i.e. from the mmap buffers setup by the
kernel perf infrastructure were at least 132096 bytes long.
Trying with a bigger mmap size:
perf trace -e write perf record -v -m 2048 --mmap-flush 16M
74982.928 ( 2.471 ms): perf/26500 write(fd: 3</root/perf.data>, buf: 0x7ff94a6cc000, count: 3580888) = 3580888
74985.406 ( 2.353 ms): perf/26500 write(fd: 3</root/perf.data>, buf: 0x7ff949ecb000, count: 3453256) = 3453256
74987.764 ( 2.629 ms): perf/26500 write(fd: 3</root/perf.data>, buf: 0x7ff9496ca000, count: 3859232) = 3859232
74990.399 ( 2.341 ms): perf/26500 write(fd: 3</root/perf.data>, buf: 0x7ff948ec9000, count: 3769032) = 3769032
74992.744 ( 2.064 ms): perf/26500 write(fd: 3</root/perf.data>, buf: 0x7ff9486c8000, count: 3310520) = 3310520
74994.814 ( 2.619 ms): perf/26500 write(fd: 3</root/perf.data>, buf: 0x7ff947ec7000, count: 4194688) = 4194688
74997.439 ( 2.787 ms): perf/26500 write(fd: 3</root/perf.data>, buf: 0x7ff9476c6000, count: 4029760) = 4029760
Was again limited to a quarter of the mmap size:
mmap flush: 2098176
mmap size 8392704B
A warning about that would be good to have but can be added later,
something like:
"max flush is a quarter of the mmap size, if wanting to bump the mmap
flush further, bump the mmap size as well using -m/--mmap-pages"
Also rename the 'sync' parameters to 'synch' to keep tools/perf building
with older glibcs:
cc1: warnings being treated as errors
builtin-record.c: In function 'record__mmap_read_evlist':
builtin-record.c:775: warning: declaration of 'sync' shadows a global declaration
/usr/include/unistd.h:933: warning: shadowed declaration is here
builtin-record.c: In function 'record__mmap_read_all':
builtin-record.c:856: warning: declaration of 'sync' shadows a global declaration
/usr/include/unistd.h:933: warning: shadowed declaration is here
Signed-off-by: Alexey Budankov <alexey.budankov@linux.intel.com>
Reviewed-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: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Link: http://lkml.kernel.org/r/f6600d72-ecfa-2eb7-7e51-f6954547d500@linux.intel.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2019-03-19 01:40:26 +08:00
|
|
|
if (synch) {
|
2019-08-27 22:05:18 +08:00
|
|
|
flush = map->core.flush;
|
|
|
|
map->core.flush = 1;
|
perf record: Implement --mmap-flush=<number> option
Implement a --mmap-flush option that specifies minimal number of bytes
that is extracted from mmaped kernel buffer to store into a trace. The
default option value is 1 byte what means every time trace writing
thread finds some new data in the mmaped buffer the data is extracted,
possibly compressed and written to a trace.
$ tools/perf/perf record --mmap-flush 1024 -e cycles -- matrix.gcc
$ tools/perf/perf record --aio --mmap-flush 1K -e cycles -- matrix.gcc
The option is independent from -z setting, doesn't vary with compression
level and can serve two purposes.
The first purpose is to increase the compression ratio of a trace data.
Larger data chunks are compressed more effectively so the implemented
option allows specifying data chunk size to compress. Also at some cases
executing more write syscalls with smaller data size can take longer
than executing less write syscalls with bigger data size due to syscall
overhead so extracting bigger data chunks specified by the option value
could additionally decrease runtime overhead.
The second purpose is to avoid self monitoring live-lock issue in system
wide (-a) profiling mode. Profiling in system wide mode with compression
(-a -z) can additionally induce data into the kernel buffers along with
the data from monitored processes. If performance data rate and volume
from the monitored processes is high then trace streaming and
compression activity in the tool is also high. High tool process
activity can lead to subtle live-lock effect when compression of single
new byte from some of mmaped kernel buffer leads to generation of the
next single byte at some mmaped buffer. So perf tool process ends up in
endless self monitoring.
Implemented synch parameter is the mean to force data move independently
from the specified flush threshold value. Despite the provided flush
value the tool needs capability to unconditionally drain memory buffers,
at least in the end of the collection.
Committer testing:
Running with the default value, i.e. as soon as there is something to
read go on consuming, we first write the synthesized events, small
chunks of about 128 bytes:
# perf trace -m 2048 --call-graph dwarf -e write -- perf record
<SNIP>
101.142 ( 0.004 ms): perf/25821 write(fd: 3</root/perf.data>, buf: 0x210db60, count: 120) = 120
__libc_write (/usr/lib64/libpthread-2.28.so)
ion (/home/acme/bin/perf)
record__write (inlined)
process_synthesized_event (/home/acme/bin/perf)
perf_tool__process_synth_event (inlined)
perf_event__synthesize_mmap_events (/home/acme/bin/perf)
Then we move to reading the mmap buffers consuming the events put there
by the kernel perf infrastructure:
107.561 ( 0.005 ms): perf/25821 write(fd: 3</root/perf.data>, buf: 0x7f1befc02000, count: 336) = 336
__libc_write (/usr/lib64/libpthread-2.28.so)
ion (/home/acme/bin/perf)
record__write (inlined)
record__pushfn (/home/acme/bin/perf)
perf_mmap__push (/home/acme/bin/perf)
record__mmap_read_evlist (inlined)
record__mmap_read_all (inlined)
__cmd_record (inlined)
cmd_record (/home/acme/bin/perf)
12919.953 ( 0.136 ms): perf/25821 write(fd: 3</root/perf.data>, buf: 0x7f1befc83150, count: 184984) = 184984
<SNIP same backtrace as in the 107.561 timestamp>
12920.094 ( 0.155 ms): perf/25821 write(fd: 3</root/perf.data>, buf: 0x7f1befc02150, count: 261816) = 261816
<SNIP same backtrace as in the 107.561 timestamp>
12920.253 ( 0.093 ms): perf/25821 write(fd: 3</root/perf.data>, buf: 0x7f1befb81120, count: 170832) = 170832
<SNIP same backtrace as in the 107.561 timestamp>
If we limit it to write only when more than 16MB are available for
reading, it throttles that to a quarter of the --mmap-pages set for
'perf record', which by default get to 528384 bytes, found out using
'record -v':
mmap flush: 132096
mmap size 528384B
With that in place all the writes coming from
record__mmap_read_evlist(), i.e. from the mmap buffers setup by the
kernel perf infrastructure were at least 132096 bytes long.
Trying with a bigger mmap size:
perf trace -e write perf record -v -m 2048 --mmap-flush 16M
74982.928 ( 2.471 ms): perf/26500 write(fd: 3</root/perf.data>, buf: 0x7ff94a6cc000, count: 3580888) = 3580888
74985.406 ( 2.353 ms): perf/26500 write(fd: 3</root/perf.data>, buf: 0x7ff949ecb000, count: 3453256) = 3453256
74987.764 ( 2.629 ms): perf/26500 write(fd: 3</root/perf.data>, buf: 0x7ff9496ca000, count: 3859232) = 3859232
74990.399 ( 2.341 ms): perf/26500 write(fd: 3</root/perf.data>, buf: 0x7ff948ec9000, count: 3769032) = 3769032
74992.744 ( 2.064 ms): perf/26500 write(fd: 3</root/perf.data>, buf: 0x7ff9486c8000, count: 3310520) = 3310520
74994.814 ( 2.619 ms): perf/26500 write(fd: 3</root/perf.data>, buf: 0x7ff947ec7000, count: 4194688) = 4194688
74997.439 ( 2.787 ms): perf/26500 write(fd: 3</root/perf.data>, buf: 0x7ff9476c6000, count: 4029760) = 4029760
Was again limited to a quarter of the mmap size:
mmap flush: 2098176
mmap size 8392704B
A warning about that would be good to have but can be added later,
something like:
"max flush is a quarter of the mmap size, if wanting to bump the mmap
flush further, bump the mmap size as well using -m/--mmap-pages"
Also rename the 'sync' parameters to 'synch' to keep tools/perf building
with older glibcs:
cc1: warnings being treated as errors
builtin-record.c: In function 'record__mmap_read_evlist':
builtin-record.c:775: warning: declaration of 'sync' shadows a global declaration
/usr/include/unistd.h:933: warning: shadowed declaration is here
builtin-record.c: In function 'record__mmap_read_all':
builtin-record.c:856: warning: declaration of 'sync' shadows a global declaration
/usr/include/unistd.h:933: warning: shadowed declaration is here
Signed-off-by: Alexey Budankov <alexey.budankov@linux.intel.com>
Reviewed-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: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Link: http://lkml.kernel.org/r/f6600d72-ecfa-2eb7-7e51-f6954547d500@linux.intel.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2019-03-19 01:40:26 +08:00
|
|
|
}
|
2018-11-06 17:04:58 +08:00
|
|
|
if (!record__aio_enabled(rec)) {
|
2019-03-19 01:44:12 +08:00
|
|
|
if (perf_mmap__push(map, rec, record__pushfn) < 0) {
|
perf record: Implement --mmap-flush=<number> option
Implement a --mmap-flush option that specifies minimal number of bytes
that is extracted from mmaped kernel buffer to store into a trace. The
default option value is 1 byte what means every time trace writing
thread finds some new data in the mmaped buffer the data is extracted,
possibly compressed and written to a trace.
$ tools/perf/perf record --mmap-flush 1024 -e cycles -- matrix.gcc
$ tools/perf/perf record --aio --mmap-flush 1K -e cycles -- matrix.gcc
The option is independent from -z setting, doesn't vary with compression
level and can serve two purposes.
The first purpose is to increase the compression ratio of a trace data.
Larger data chunks are compressed more effectively so the implemented
option allows specifying data chunk size to compress. Also at some cases
executing more write syscalls with smaller data size can take longer
than executing less write syscalls with bigger data size due to syscall
overhead so extracting bigger data chunks specified by the option value
could additionally decrease runtime overhead.
The second purpose is to avoid self monitoring live-lock issue in system
wide (-a) profiling mode. Profiling in system wide mode with compression
(-a -z) can additionally induce data into the kernel buffers along with
the data from monitored processes. If performance data rate and volume
from the monitored processes is high then trace streaming and
compression activity in the tool is also high. High tool process
activity can lead to subtle live-lock effect when compression of single
new byte from some of mmaped kernel buffer leads to generation of the
next single byte at some mmaped buffer. So perf tool process ends up in
endless self monitoring.
Implemented synch parameter is the mean to force data move independently
from the specified flush threshold value. Despite the provided flush
value the tool needs capability to unconditionally drain memory buffers,
at least in the end of the collection.
Committer testing:
Running with the default value, i.e. as soon as there is something to
read go on consuming, we first write the synthesized events, small
chunks of about 128 bytes:
# perf trace -m 2048 --call-graph dwarf -e write -- perf record
<SNIP>
101.142 ( 0.004 ms): perf/25821 write(fd: 3</root/perf.data>, buf: 0x210db60, count: 120) = 120
__libc_write (/usr/lib64/libpthread-2.28.so)
ion (/home/acme/bin/perf)
record__write (inlined)
process_synthesized_event (/home/acme/bin/perf)
perf_tool__process_synth_event (inlined)
perf_event__synthesize_mmap_events (/home/acme/bin/perf)
Then we move to reading the mmap buffers consuming the events put there
by the kernel perf infrastructure:
107.561 ( 0.005 ms): perf/25821 write(fd: 3</root/perf.data>, buf: 0x7f1befc02000, count: 336) = 336
__libc_write (/usr/lib64/libpthread-2.28.so)
ion (/home/acme/bin/perf)
record__write (inlined)
record__pushfn (/home/acme/bin/perf)
perf_mmap__push (/home/acme/bin/perf)
record__mmap_read_evlist (inlined)
record__mmap_read_all (inlined)
__cmd_record (inlined)
cmd_record (/home/acme/bin/perf)
12919.953 ( 0.136 ms): perf/25821 write(fd: 3</root/perf.data>, buf: 0x7f1befc83150, count: 184984) = 184984
<SNIP same backtrace as in the 107.561 timestamp>
12920.094 ( 0.155 ms): perf/25821 write(fd: 3</root/perf.data>, buf: 0x7f1befc02150, count: 261816) = 261816
<SNIP same backtrace as in the 107.561 timestamp>
12920.253 ( 0.093 ms): perf/25821 write(fd: 3</root/perf.data>, buf: 0x7f1befb81120, count: 170832) = 170832
<SNIP same backtrace as in the 107.561 timestamp>
If we limit it to write only when more than 16MB are available for
reading, it throttles that to a quarter of the --mmap-pages set for
'perf record', which by default get to 528384 bytes, found out using
'record -v':
mmap flush: 132096
mmap size 528384B
With that in place all the writes coming from
record__mmap_read_evlist(), i.e. from the mmap buffers setup by the
kernel perf infrastructure were at least 132096 bytes long.
Trying with a bigger mmap size:
perf trace -e write perf record -v -m 2048 --mmap-flush 16M
74982.928 ( 2.471 ms): perf/26500 write(fd: 3</root/perf.data>, buf: 0x7ff94a6cc000, count: 3580888) = 3580888
74985.406 ( 2.353 ms): perf/26500 write(fd: 3</root/perf.data>, buf: 0x7ff949ecb000, count: 3453256) = 3453256
74987.764 ( 2.629 ms): perf/26500 write(fd: 3</root/perf.data>, buf: 0x7ff9496ca000, count: 3859232) = 3859232
74990.399 ( 2.341 ms): perf/26500 write(fd: 3</root/perf.data>, buf: 0x7ff948ec9000, count: 3769032) = 3769032
74992.744 ( 2.064 ms): perf/26500 write(fd: 3</root/perf.data>, buf: 0x7ff9486c8000, count: 3310520) = 3310520
74994.814 ( 2.619 ms): perf/26500 write(fd: 3</root/perf.data>, buf: 0x7ff947ec7000, count: 4194688) = 4194688
74997.439 ( 2.787 ms): perf/26500 write(fd: 3</root/perf.data>, buf: 0x7ff9476c6000, count: 4029760) = 4029760
Was again limited to a quarter of the mmap size:
mmap flush: 2098176
mmap size 8392704B
A warning about that would be good to have but can be added later,
something like:
"max flush is a quarter of the mmap size, if wanting to bump the mmap
flush further, bump the mmap size as well using -m/--mmap-pages"
Also rename the 'sync' parameters to 'synch' to keep tools/perf building
with older glibcs:
cc1: warnings being treated as errors
builtin-record.c: In function 'record__mmap_read_evlist':
builtin-record.c:775: warning: declaration of 'sync' shadows a global declaration
/usr/include/unistd.h:933: warning: shadowed declaration is here
builtin-record.c: In function 'record__mmap_read_all':
builtin-record.c:856: warning: declaration of 'sync' shadows a global declaration
/usr/include/unistd.h:933: warning: shadowed declaration is here
Signed-off-by: Alexey Budankov <alexey.budankov@linux.intel.com>
Reviewed-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: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Link: http://lkml.kernel.org/r/f6600d72-ecfa-2eb7-7e51-f6954547d500@linux.intel.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2019-03-19 01:40:26 +08:00
|
|
|
if (synch)
|
2019-08-27 22:05:18 +08:00
|
|
|
map->core.flush = flush;
|
2018-11-06 17:04:58 +08:00
|
|
|
rc = -1;
|
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
} else {
|
2019-03-19 01:44:12 +08:00
|
|
|
if (record__aio_push(rec, map, &off) < 0) {
|
2018-11-06 17:04:58 +08:00
|
|
|
record__aio_set_pos(trace_fd, off);
|
perf record: Implement --mmap-flush=<number> option
Implement a --mmap-flush option that specifies minimal number of bytes
that is extracted from mmaped kernel buffer to store into a trace. The
default option value is 1 byte what means every time trace writing
thread finds some new data in the mmaped buffer the data is extracted,
possibly compressed and written to a trace.
$ tools/perf/perf record --mmap-flush 1024 -e cycles -- matrix.gcc
$ tools/perf/perf record --aio --mmap-flush 1K -e cycles -- matrix.gcc
The option is independent from -z setting, doesn't vary with compression
level and can serve two purposes.
The first purpose is to increase the compression ratio of a trace data.
Larger data chunks are compressed more effectively so the implemented
option allows specifying data chunk size to compress. Also at some cases
executing more write syscalls with smaller data size can take longer
than executing less write syscalls with bigger data size due to syscall
overhead so extracting bigger data chunks specified by the option value
could additionally decrease runtime overhead.
The second purpose is to avoid self monitoring live-lock issue in system
wide (-a) profiling mode. Profiling in system wide mode with compression
(-a -z) can additionally induce data into the kernel buffers along with
the data from monitored processes. If performance data rate and volume
from the monitored processes is high then trace streaming and
compression activity in the tool is also high. High tool process
activity can lead to subtle live-lock effect when compression of single
new byte from some of mmaped kernel buffer leads to generation of the
next single byte at some mmaped buffer. So perf tool process ends up in
endless self monitoring.
Implemented synch parameter is the mean to force data move independently
from the specified flush threshold value. Despite the provided flush
value the tool needs capability to unconditionally drain memory buffers,
at least in the end of the collection.
Committer testing:
Running with the default value, i.e. as soon as there is something to
read go on consuming, we first write the synthesized events, small
chunks of about 128 bytes:
# perf trace -m 2048 --call-graph dwarf -e write -- perf record
<SNIP>
101.142 ( 0.004 ms): perf/25821 write(fd: 3</root/perf.data>, buf: 0x210db60, count: 120) = 120
__libc_write (/usr/lib64/libpthread-2.28.so)
ion (/home/acme/bin/perf)
record__write (inlined)
process_synthesized_event (/home/acme/bin/perf)
perf_tool__process_synth_event (inlined)
perf_event__synthesize_mmap_events (/home/acme/bin/perf)
Then we move to reading the mmap buffers consuming the events put there
by the kernel perf infrastructure:
107.561 ( 0.005 ms): perf/25821 write(fd: 3</root/perf.data>, buf: 0x7f1befc02000, count: 336) = 336
__libc_write (/usr/lib64/libpthread-2.28.so)
ion (/home/acme/bin/perf)
record__write (inlined)
record__pushfn (/home/acme/bin/perf)
perf_mmap__push (/home/acme/bin/perf)
record__mmap_read_evlist (inlined)
record__mmap_read_all (inlined)
__cmd_record (inlined)
cmd_record (/home/acme/bin/perf)
12919.953 ( 0.136 ms): perf/25821 write(fd: 3</root/perf.data>, buf: 0x7f1befc83150, count: 184984) = 184984
<SNIP same backtrace as in the 107.561 timestamp>
12920.094 ( 0.155 ms): perf/25821 write(fd: 3</root/perf.data>, buf: 0x7f1befc02150, count: 261816) = 261816
<SNIP same backtrace as in the 107.561 timestamp>
12920.253 ( 0.093 ms): perf/25821 write(fd: 3</root/perf.data>, buf: 0x7f1befb81120, count: 170832) = 170832
<SNIP same backtrace as in the 107.561 timestamp>
If we limit it to write only when more than 16MB are available for
reading, it throttles that to a quarter of the --mmap-pages set for
'perf record', which by default get to 528384 bytes, found out using
'record -v':
mmap flush: 132096
mmap size 528384B
With that in place all the writes coming from
record__mmap_read_evlist(), i.e. from the mmap buffers setup by the
kernel perf infrastructure were at least 132096 bytes long.
Trying with a bigger mmap size:
perf trace -e write perf record -v -m 2048 --mmap-flush 16M
74982.928 ( 2.471 ms): perf/26500 write(fd: 3</root/perf.data>, buf: 0x7ff94a6cc000, count: 3580888) = 3580888
74985.406 ( 2.353 ms): perf/26500 write(fd: 3</root/perf.data>, buf: 0x7ff949ecb000, count: 3453256) = 3453256
74987.764 ( 2.629 ms): perf/26500 write(fd: 3</root/perf.data>, buf: 0x7ff9496ca000, count: 3859232) = 3859232
74990.399 ( 2.341 ms): perf/26500 write(fd: 3</root/perf.data>, buf: 0x7ff948ec9000, count: 3769032) = 3769032
74992.744 ( 2.064 ms): perf/26500 write(fd: 3</root/perf.data>, buf: 0x7ff9486c8000, count: 3310520) = 3310520
74994.814 ( 2.619 ms): perf/26500 write(fd: 3</root/perf.data>, buf: 0x7ff947ec7000, count: 4194688) = 4194688
74997.439 ( 2.787 ms): perf/26500 write(fd: 3</root/perf.data>, buf: 0x7ff9476c6000, count: 4029760) = 4029760
Was again limited to a quarter of the mmap size:
mmap flush: 2098176
mmap size 8392704B
A warning about that would be good to have but can be added later,
something like:
"max flush is a quarter of the mmap size, if wanting to bump the mmap
flush further, bump the mmap size as well using -m/--mmap-pages"
Also rename the 'sync' parameters to 'synch' to keep tools/perf building
with older glibcs:
cc1: warnings being treated as errors
builtin-record.c: In function 'record__mmap_read_evlist':
builtin-record.c:775: warning: declaration of 'sync' shadows a global declaration
/usr/include/unistd.h:933: warning: shadowed declaration is here
builtin-record.c: In function 'record__mmap_read_all':
builtin-record.c:856: warning: declaration of 'sync' shadows a global declaration
/usr/include/unistd.h:933: warning: shadowed declaration is here
Signed-off-by: Alexey Budankov <alexey.budankov@linux.intel.com>
Reviewed-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: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Link: http://lkml.kernel.org/r/f6600d72-ecfa-2eb7-7e51-f6954547d500@linux.intel.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2019-03-19 01:40:26 +08:00
|
|
|
if (synch)
|
2019-08-27 22:05:18 +08:00
|
|
|
map->core.flush = flush;
|
2018-11-06 17:04:58 +08:00
|
|
|
rc = -1;
|
|
|
|
goto out;
|
|
|
|
}
|
2012-08-27 02:24:47 +08:00
|
|
|
}
|
perf record: Implement --mmap-flush=<number> option
Implement a --mmap-flush option that specifies minimal number of bytes
that is extracted from mmaped kernel buffer to store into a trace. The
default option value is 1 byte what means every time trace writing
thread finds some new data in the mmaped buffer the data is extracted,
possibly compressed and written to a trace.
$ tools/perf/perf record --mmap-flush 1024 -e cycles -- matrix.gcc
$ tools/perf/perf record --aio --mmap-flush 1K -e cycles -- matrix.gcc
The option is independent from -z setting, doesn't vary with compression
level and can serve two purposes.
The first purpose is to increase the compression ratio of a trace data.
Larger data chunks are compressed more effectively so the implemented
option allows specifying data chunk size to compress. Also at some cases
executing more write syscalls with smaller data size can take longer
than executing less write syscalls with bigger data size due to syscall
overhead so extracting bigger data chunks specified by the option value
could additionally decrease runtime overhead.
The second purpose is to avoid self monitoring live-lock issue in system
wide (-a) profiling mode. Profiling in system wide mode with compression
(-a -z) can additionally induce data into the kernel buffers along with
the data from monitored processes. If performance data rate and volume
from the monitored processes is high then trace streaming and
compression activity in the tool is also high. High tool process
activity can lead to subtle live-lock effect when compression of single
new byte from some of mmaped kernel buffer leads to generation of the
next single byte at some mmaped buffer. So perf tool process ends up in
endless self monitoring.
Implemented synch parameter is the mean to force data move independently
from the specified flush threshold value. Despite the provided flush
value the tool needs capability to unconditionally drain memory buffers,
at least in the end of the collection.
Committer testing:
Running with the default value, i.e. as soon as there is something to
read go on consuming, we first write the synthesized events, small
chunks of about 128 bytes:
# perf trace -m 2048 --call-graph dwarf -e write -- perf record
<SNIP>
101.142 ( 0.004 ms): perf/25821 write(fd: 3</root/perf.data>, buf: 0x210db60, count: 120) = 120
__libc_write (/usr/lib64/libpthread-2.28.so)
ion (/home/acme/bin/perf)
record__write (inlined)
process_synthesized_event (/home/acme/bin/perf)
perf_tool__process_synth_event (inlined)
perf_event__synthesize_mmap_events (/home/acme/bin/perf)
Then we move to reading the mmap buffers consuming the events put there
by the kernel perf infrastructure:
107.561 ( 0.005 ms): perf/25821 write(fd: 3</root/perf.data>, buf: 0x7f1befc02000, count: 336) = 336
__libc_write (/usr/lib64/libpthread-2.28.so)
ion (/home/acme/bin/perf)
record__write (inlined)
record__pushfn (/home/acme/bin/perf)
perf_mmap__push (/home/acme/bin/perf)
record__mmap_read_evlist (inlined)
record__mmap_read_all (inlined)
__cmd_record (inlined)
cmd_record (/home/acme/bin/perf)
12919.953 ( 0.136 ms): perf/25821 write(fd: 3</root/perf.data>, buf: 0x7f1befc83150, count: 184984) = 184984
<SNIP same backtrace as in the 107.561 timestamp>
12920.094 ( 0.155 ms): perf/25821 write(fd: 3</root/perf.data>, buf: 0x7f1befc02150, count: 261816) = 261816
<SNIP same backtrace as in the 107.561 timestamp>
12920.253 ( 0.093 ms): perf/25821 write(fd: 3</root/perf.data>, buf: 0x7f1befb81120, count: 170832) = 170832
<SNIP same backtrace as in the 107.561 timestamp>
If we limit it to write only when more than 16MB are available for
reading, it throttles that to a quarter of the --mmap-pages set for
'perf record', which by default get to 528384 bytes, found out using
'record -v':
mmap flush: 132096
mmap size 528384B
With that in place all the writes coming from
record__mmap_read_evlist(), i.e. from the mmap buffers setup by the
kernel perf infrastructure were at least 132096 bytes long.
Trying with a bigger mmap size:
perf trace -e write perf record -v -m 2048 --mmap-flush 16M
74982.928 ( 2.471 ms): perf/26500 write(fd: 3</root/perf.data>, buf: 0x7ff94a6cc000, count: 3580888) = 3580888
74985.406 ( 2.353 ms): perf/26500 write(fd: 3</root/perf.data>, buf: 0x7ff949ecb000, count: 3453256) = 3453256
74987.764 ( 2.629 ms): perf/26500 write(fd: 3</root/perf.data>, buf: 0x7ff9496ca000, count: 3859232) = 3859232
74990.399 ( 2.341 ms): perf/26500 write(fd: 3</root/perf.data>, buf: 0x7ff948ec9000, count: 3769032) = 3769032
74992.744 ( 2.064 ms): perf/26500 write(fd: 3</root/perf.data>, buf: 0x7ff9486c8000, count: 3310520) = 3310520
74994.814 ( 2.619 ms): perf/26500 write(fd: 3</root/perf.data>, buf: 0x7ff947ec7000, count: 4194688) = 4194688
74997.439 ( 2.787 ms): perf/26500 write(fd: 3</root/perf.data>, buf: 0x7ff9476c6000, count: 4029760) = 4029760
Was again limited to a quarter of the mmap size:
mmap flush: 2098176
mmap size 8392704B
A warning about that would be good to have but can be added later,
something like:
"max flush is a quarter of the mmap size, if wanting to bump the mmap
flush further, bump the mmap size as well using -m/--mmap-pages"
Also rename the 'sync' parameters to 'synch' to keep tools/perf building
with older glibcs:
cc1: warnings being treated as errors
builtin-record.c: In function 'record__mmap_read_evlist':
builtin-record.c:775: warning: declaration of 'sync' shadows a global declaration
/usr/include/unistd.h:933: warning: shadowed declaration is here
builtin-record.c: In function 'record__mmap_read_all':
builtin-record.c:856: warning: declaration of 'sync' shadows a global declaration
/usr/include/unistd.h:933: warning: shadowed declaration is here
Signed-off-by: Alexey Budankov <alexey.budankov@linux.intel.com>
Reviewed-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: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Link: http://lkml.kernel.org/r/f6600d72-ecfa-2eb7-7e51-f6954547d500@linux.intel.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2019-03-19 01:40:26 +08:00
|
|
|
if (synch)
|
2019-08-27 22:05:18 +08:00
|
|
|
map->core.flush = flush;
|
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 &&
|
2019-11-15 20:42:16 +08:00
|
|
|
!rec->opts.auxtrace_sample_mode &&
|
2018-09-13 20:54:05 +08:00
|
|
|
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
|
|
|
}
|
|
|
|
|
perf record: Implement --mmap-flush=<number> option
Implement a --mmap-flush option that specifies minimal number of bytes
that is extracted from mmaped kernel buffer to store into a trace. The
default option value is 1 byte what means every time trace writing
thread finds some new data in the mmaped buffer the data is extracted,
possibly compressed and written to a trace.
$ tools/perf/perf record --mmap-flush 1024 -e cycles -- matrix.gcc
$ tools/perf/perf record --aio --mmap-flush 1K -e cycles -- matrix.gcc
The option is independent from -z setting, doesn't vary with compression
level and can serve two purposes.
The first purpose is to increase the compression ratio of a trace data.
Larger data chunks are compressed more effectively so the implemented
option allows specifying data chunk size to compress. Also at some cases
executing more write syscalls with smaller data size can take longer
than executing less write syscalls with bigger data size due to syscall
overhead so extracting bigger data chunks specified by the option value
could additionally decrease runtime overhead.
The second purpose is to avoid self monitoring live-lock issue in system
wide (-a) profiling mode. Profiling in system wide mode with compression
(-a -z) can additionally induce data into the kernel buffers along with
the data from monitored processes. If performance data rate and volume
from the monitored processes is high then trace streaming and
compression activity in the tool is also high. High tool process
activity can lead to subtle live-lock effect when compression of single
new byte from some of mmaped kernel buffer leads to generation of the
next single byte at some mmaped buffer. So perf tool process ends up in
endless self monitoring.
Implemented synch parameter is the mean to force data move independently
from the specified flush threshold value. Despite the provided flush
value the tool needs capability to unconditionally drain memory buffers,
at least in the end of the collection.
Committer testing:
Running with the default value, i.e. as soon as there is something to
read go on consuming, we first write the synthesized events, small
chunks of about 128 bytes:
# perf trace -m 2048 --call-graph dwarf -e write -- perf record
<SNIP>
101.142 ( 0.004 ms): perf/25821 write(fd: 3</root/perf.data>, buf: 0x210db60, count: 120) = 120
__libc_write (/usr/lib64/libpthread-2.28.so)
ion (/home/acme/bin/perf)
record__write (inlined)
process_synthesized_event (/home/acme/bin/perf)
perf_tool__process_synth_event (inlined)
perf_event__synthesize_mmap_events (/home/acme/bin/perf)
Then we move to reading the mmap buffers consuming the events put there
by the kernel perf infrastructure:
107.561 ( 0.005 ms): perf/25821 write(fd: 3</root/perf.data>, buf: 0x7f1befc02000, count: 336) = 336
__libc_write (/usr/lib64/libpthread-2.28.so)
ion (/home/acme/bin/perf)
record__write (inlined)
record__pushfn (/home/acme/bin/perf)
perf_mmap__push (/home/acme/bin/perf)
record__mmap_read_evlist (inlined)
record__mmap_read_all (inlined)
__cmd_record (inlined)
cmd_record (/home/acme/bin/perf)
12919.953 ( 0.136 ms): perf/25821 write(fd: 3</root/perf.data>, buf: 0x7f1befc83150, count: 184984) = 184984
<SNIP same backtrace as in the 107.561 timestamp>
12920.094 ( 0.155 ms): perf/25821 write(fd: 3</root/perf.data>, buf: 0x7f1befc02150, count: 261816) = 261816
<SNIP same backtrace as in the 107.561 timestamp>
12920.253 ( 0.093 ms): perf/25821 write(fd: 3</root/perf.data>, buf: 0x7f1befb81120, count: 170832) = 170832
<SNIP same backtrace as in the 107.561 timestamp>
If we limit it to write only when more than 16MB are available for
reading, it throttles that to a quarter of the --mmap-pages set for
'perf record', which by default get to 528384 bytes, found out using
'record -v':
mmap flush: 132096
mmap size 528384B
With that in place all the writes coming from
record__mmap_read_evlist(), i.e. from the mmap buffers setup by the
kernel perf infrastructure were at least 132096 bytes long.
Trying with a bigger mmap size:
perf trace -e write perf record -v -m 2048 --mmap-flush 16M
74982.928 ( 2.471 ms): perf/26500 write(fd: 3</root/perf.data>, buf: 0x7ff94a6cc000, count: 3580888) = 3580888
74985.406 ( 2.353 ms): perf/26500 write(fd: 3</root/perf.data>, buf: 0x7ff949ecb000, count: 3453256) = 3453256
74987.764 ( 2.629 ms): perf/26500 write(fd: 3</root/perf.data>, buf: 0x7ff9496ca000, count: 3859232) = 3859232
74990.399 ( 2.341 ms): perf/26500 write(fd: 3</root/perf.data>, buf: 0x7ff948ec9000, count: 3769032) = 3769032
74992.744 ( 2.064 ms): perf/26500 write(fd: 3</root/perf.data>, buf: 0x7ff9486c8000, count: 3310520) = 3310520
74994.814 ( 2.619 ms): perf/26500 write(fd: 3</root/perf.data>, buf: 0x7ff947ec7000, count: 4194688) = 4194688
74997.439 ( 2.787 ms): perf/26500 write(fd: 3</root/perf.data>, buf: 0x7ff9476c6000, count: 4029760) = 4029760
Was again limited to a quarter of the mmap size:
mmap flush: 2098176
mmap size 8392704B
A warning about that would be good to have but can be added later,
something like:
"max flush is a quarter of the mmap size, if wanting to bump the mmap
flush further, bump the mmap size as well using -m/--mmap-pages"
Also rename the 'sync' parameters to 'synch' to keep tools/perf building
with older glibcs:
cc1: warnings being treated as errors
builtin-record.c: In function 'record__mmap_read_evlist':
builtin-record.c:775: warning: declaration of 'sync' shadows a global declaration
/usr/include/unistd.h:933: warning: shadowed declaration is here
builtin-record.c: In function 'record__mmap_read_all':
builtin-record.c:856: warning: declaration of 'sync' shadows a global declaration
/usr/include/unistd.h:933: warning: shadowed declaration is here
Signed-off-by: Alexey Budankov <alexey.budankov@linux.intel.com>
Reviewed-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: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Link: http://lkml.kernel.org/r/f6600d72-ecfa-2eb7-7e51-f6954547d500@linux.intel.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2019-03-19 01:40:26 +08:00
|
|
|
static int record__mmap_read_all(struct record *rec, bool synch)
|
2016-06-27 18:24:04 +08:00
|
|
|
{
|
|
|
|
int err;
|
|
|
|
|
perf record: Implement --mmap-flush=<number> option
Implement a --mmap-flush option that specifies minimal number of bytes
that is extracted from mmaped kernel buffer to store into a trace. The
default option value is 1 byte what means every time trace writing
thread finds some new data in the mmaped buffer the data is extracted,
possibly compressed and written to a trace.
$ tools/perf/perf record --mmap-flush 1024 -e cycles -- matrix.gcc
$ tools/perf/perf record --aio --mmap-flush 1K -e cycles -- matrix.gcc
The option is independent from -z setting, doesn't vary with compression
level and can serve two purposes.
The first purpose is to increase the compression ratio of a trace data.
Larger data chunks are compressed more effectively so the implemented
option allows specifying data chunk size to compress. Also at some cases
executing more write syscalls with smaller data size can take longer
than executing less write syscalls with bigger data size due to syscall
overhead so extracting bigger data chunks specified by the option value
could additionally decrease runtime overhead.
The second purpose is to avoid self monitoring live-lock issue in system
wide (-a) profiling mode. Profiling in system wide mode with compression
(-a -z) can additionally induce data into the kernel buffers along with
the data from monitored processes. If performance data rate and volume
from the monitored processes is high then trace streaming and
compression activity in the tool is also high. High tool process
activity can lead to subtle live-lock effect when compression of single
new byte from some of mmaped kernel buffer leads to generation of the
next single byte at some mmaped buffer. So perf tool process ends up in
endless self monitoring.
Implemented synch parameter is the mean to force data move independently
from the specified flush threshold value. Despite the provided flush
value the tool needs capability to unconditionally drain memory buffers,
at least in the end of the collection.
Committer testing:
Running with the default value, i.e. as soon as there is something to
read go on consuming, we first write the synthesized events, small
chunks of about 128 bytes:
# perf trace -m 2048 --call-graph dwarf -e write -- perf record
<SNIP>
101.142 ( 0.004 ms): perf/25821 write(fd: 3</root/perf.data>, buf: 0x210db60, count: 120) = 120
__libc_write (/usr/lib64/libpthread-2.28.so)
ion (/home/acme/bin/perf)
record__write (inlined)
process_synthesized_event (/home/acme/bin/perf)
perf_tool__process_synth_event (inlined)
perf_event__synthesize_mmap_events (/home/acme/bin/perf)
Then we move to reading the mmap buffers consuming the events put there
by the kernel perf infrastructure:
107.561 ( 0.005 ms): perf/25821 write(fd: 3</root/perf.data>, buf: 0x7f1befc02000, count: 336) = 336
__libc_write (/usr/lib64/libpthread-2.28.so)
ion (/home/acme/bin/perf)
record__write (inlined)
record__pushfn (/home/acme/bin/perf)
perf_mmap__push (/home/acme/bin/perf)
record__mmap_read_evlist (inlined)
record__mmap_read_all (inlined)
__cmd_record (inlined)
cmd_record (/home/acme/bin/perf)
12919.953 ( 0.136 ms): perf/25821 write(fd: 3</root/perf.data>, buf: 0x7f1befc83150, count: 184984) = 184984
<SNIP same backtrace as in the 107.561 timestamp>
12920.094 ( 0.155 ms): perf/25821 write(fd: 3</root/perf.data>, buf: 0x7f1befc02150, count: 261816) = 261816
<SNIP same backtrace as in the 107.561 timestamp>
12920.253 ( 0.093 ms): perf/25821 write(fd: 3</root/perf.data>, buf: 0x7f1befb81120, count: 170832) = 170832
<SNIP same backtrace as in the 107.561 timestamp>
If we limit it to write only when more than 16MB are available for
reading, it throttles that to a quarter of the --mmap-pages set for
'perf record', which by default get to 528384 bytes, found out using
'record -v':
mmap flush: 132096
mmap size 528384B
With that in place all the writes coming from
record__mmap_read_evlist(), i.e. from the mmap buffers setup by the
kernel perf infrastructure were at least 132096 bytes long.
Trying with a bigger mmap size:
perf trace -e write perf record -v -m 2048 --mmap-flush 16M
74982.928 ( 2.471 ms): perf/26500 write(fd: 3</root/perf.data>, buf: 0x7ff94a6cc000, count: 3580888) = 3580888
74985.406 ( 2.353 ms): perf/26500 write(fd: 3</root/perf.data>, buf: 0x7ff949ecb000, count: 3453256) = 3453256
74987.764 ( 2.629 ms): perf/26500 write(fd: 3</root/perf.data>, buf: 0x7ff9496ca000, count: 3859232) = 3859232
74990.399 ( 2.341 ms): perf/26500 write(fd: 3</root/perf.data>, buf: 0x7ff948ec9000, count: 3769032) = 3769032
74992.744 ( 2.064 ms): perf/26500 write(fd: 3</root/perf.data>, buf: 0x7ff9486c8000, count: 3310520) = 3310520
74994.814 ( 2.619 ms): perf/26500 write(fd: 3</root/perf.data>, buf: 0x7ff947ec7000, count: 4194688) = 4194688
74997.439 ( 2.787 ms): perf/26500 write(fd: 3</root/perf.data>, buf: 0x7ff9476c6000, count: 4029760) = 4029760
Was again limited to a quarter of the mmap size:
mmap flush: 2098176
mmap size 8392704B
A warning about that would be good to have but can be added later,
something like:
"max flush is a quarter of the mmap size, if wanting to bump the mmap
flush further, bump the mmap size as well using -m/--mmap-pages"
Also rename the 'sync' parameters to 'synch' to keep tools/perf building
with older glibcs:
cc1: warnings being treated as errors
builtin-record.c: In function 'record__mmap_read_evlist':
builtin-record.c:775: warning: declaration of 'sync' shadows a global declaration
/usr/include/unistd.h:933: warning: shadowed declaration is here
builtin-record.c: In function 'record__mmap_read_all':
builtin-record.c:856: warning: declaration of 'sync' shadows a global declaration
/usr/include/unistd.h:933: warning: shadowed declaration is here
Signed-off-by: Alexey Budankov <alexey.budankov@linux.intel.com>
Reviewed-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: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Link: http://lkml.kernel.org/r/f6600d72-ecfa-2eb7-7e51-f6954547d500@linux.intel.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2019-03-19 01:40:26 +08:00
|
|
|
err = record__mmap_read_evlist(rec, rec->evlist, false, synch);
|
2016-06-27 18:24:04 +08:00
|
|
|
if (err)
|
|
|
|
return err;
|
|
|
|
|
perf record: Implement --mmap-flush=<number> option
Implement a --mmap-flush option that specifies minimal number of bytes
that is extracted from mmaped kernel buffer to store into a trace. The
default option value is 1 byte what means every time trace writing
thread finds some new data in the mmaped buffer the data is extracted,
possibly compressed and written to a trace.
$ tools/perf/perf record --mmap-flush 1024 -e cycles -- matrix.gcc
$ tools/perf/perf record --aio --mmap-flush 1K -e cycles -- matrix.gcc
The option is independent from -z setting, doesn't vary with compression
level and can serve two purposes.
The first purpose is to increase the compression ratio of a trace data.
Larger data chunks are compressed more effectively so the implemented
option allows specifying data chunk size to compress. Also at some cases
executing more write syscalls with smaller data size can take longer
than executing less write syscalls with bigger data size due to syscall
overhead so extracting bigger data chunks specified by the option value
could additionally decrease runtime overhead.
The second purpose is to avoid self monitoring live-lock issue in system
wide (-a) profiling mode. Profiling in system wide mode with compression
(-a -z) can additionally induce data into the kernel buffers along with
the data from monitored processes. If performance data rate and volume
from the monitored processes is high then trace streaming and
compression activity in the tool is also high. High tool process
activity can lead to subtle live-lock effect when compression of single
new byte from some of mmaped kernel buffer leads to generation of the
next single byte at some mmaped buffer. So perf tool process ends up in
endless self monitoring.
Implemented synch parameter is the mean to force data move independently
from the specified flush threshold value. Despite the provided flush
value the tool needs capability to unconditionally drain memory buffers,
at least in the end of the collection.
Committer testing:
Running with the default value, i.e. as soon as there is something to
read go on consuming, we first write the synthesized events, small
chunks of about 128 bytes:
# perf trace -m 2048 --call-graph dwarf -e write -- perf record
<SNIP>
101.142 ( 0.004 ms): perf/25821 write(fd: 3</root/perf.data>, buf: 0x210db60, count: 120) = 120
__libc_write (/usr/lib64/libpthread-2.28.so)
ion (/home/acme/bin/perf)
record__write (inlined)
process_synthesized_event (/home/acme/bin/perf)
perf_tool__process_synth_event (inlined)
perf_event__synthesize_mmap_events (/home/acme/bin/perf)
Then we move to reading the mmap buffers consuming the events put there
by the kernel perf infrastructure:
107.561 ( 0.005 ms): perf/25821 write(fd: 3</root/perf.data>, buf: 0x7f1befc02000, count: 336) = 336
__libc_write (/usr/lib64/libpthread-2.28.so)
ion (/home/acme/bin/perf)
record__write (inlined)
record__pushfn (/home/acme/bin/perf)
perf_mmap__push (/home/acme/bin/perf)
record__mmap_read_evlist (inlined)
record__mmap_read_all (inlined)
__cmd_record (inlined)
cmd_record (/home/acme/bin/perf)
12919.953 ( 0.136 ms): perf/25821 write(fd: 3</root/perf.data>, buf: 0x7f1befc83150, count: 184984) = 184984
<SNIP same backtrace as in the 107.561 timestamp>
12920.094 ( 0.155 ms): perf/25821 write(fd: 3</root/perf.data>, buf: 0x7f1befc02150, count: 261816) = 261816
<SNIP same backtrace as in the 107.561 timestamp>
12920.253 ( 0.093 ms): perf/25821 write(fd: 3</root/perf.data>, buf: 0x7f1befb81120, count: 170832) = 170832
<SNIP same backtrace as in the 107.561 timestamp>
If we limit it to write only when more than 16MB are available for
reading, it throttles that to a quarter of the --mmap-pages set for
'perf record', which by default get to 528384 bytes, found out using
'record -v':
mmap flush: 132096
mmap size 528384B
With that in place all the writes coming from
record__mmap_read_evlist(), i.e. from the mmap buffers setup by the
kernel perf infrastructure were at least 132096 bytes long.
Trying with a bigger mmap size:
perf trace -e write perf record -v -m 2048 --mmap-flush 16M
74982.928 ( 2.471 ms): perf/26500 write(fd: 3</root/perf.data>, buf: 0x7ff94a6cc000, count: 3580888) = 3580888
74985.406 ( 2.353 ms): perf/26500 write(fd: 3</root/perf.data>, buf: 0x7ff949ecb000, count: 3453256) = 3453256
74987.764 ( 2.629 ms): perf/26500 write(fd: 3</root/perf.data>, buf: 0x7ff9496ca000, count: 3859232) = 3859232
74990.399 ( 2.341 ms): perf/26500 write(fd: 3</root/perf.data>, buf: 0x7ff948ec9000, count: 3769032) = 3769032
74992.744 ( 2.064 ms): perf/26500 write(fd: 3</root/perf.data>, buf: 0x7ff9486c8000, count: 3310520) = 3310520
74994.814 ( 2.619 ms): perf/26500 write(fd: 3</root/perf.data>, buf: 0x7ff947ec7000, count: 4194688) = 4194688
74997.439 ( 2.787 ms): perf/26500 write(fd: 3</root/perf.data>, buf: 0x7ff9476c6000, count: 4029760) = 4029760
Was again limited to a quarter of the mmap size:
mmap flush: 2098176
mmap size 8392704B
A warning about that would be good to have but can be added later,
something like:
"max flush is a quarter of the mmap size, if wanting to bump the mmap
flush further, bump the mmap size as well using -m/--mmap-pages"
Also rename the 'sync' parameters to 'synch' to keep tools/perf building
with older glibcs:
cc1: warnings being treated as errors
builtin-record.c: In function 'record__mmap_read_evlist':
builtin-record.c:775: warning: declaration of 'sync' shadows a global declaration
/usr/include/unistd.h:933: warning: shadowed declaration is here
builtin-record.c: In function 'record__mmap_read_all':
builtin-record.c:856: warning: declaration of 'sync' shadows a global declaration
/usr/include/unistd.h:933: warning: shadowed declaration is here
Signed-off-by: Alexey Budankov <alexey.budankov@linux.intel.com>
Reviewed-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: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Link: http://lkml.kernel.org/r/f6600d72-ecfa-2eb7-7e51-f6954547d500@linux.intel.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2019-03-19 01:40:26 +08:00
|
|
|
return record__mmap_read_evlist(rec, rec->evlist, true, synch);
|
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);
|
|
|
|
|
2019-07-21 19:24:23 +08:00
|
|
|
if (!have_tracepoints(&rec->evlist->core.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);
|
2019-03-19 01:41:33 +08:00
|
|
|
if (!record__comp_enabled(rec))
|
|
|
|
perf_header__clear_feat(&session->header, HEADER_COMPRESSED);
|
2019-03-08 21:47:39 +08:00
|
|
|
|
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;
|
2019-07-21 19:23:50 +08:00
|
|
|
struct perf_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);
|
2019-07-21 19:24:20 +08:00
|
|
|
perf_thread_map__put(thread_map);
|
2017-02-14 21:59:04 +08:00
|
|
|
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]);
|
2019-07-04 23:06:20 +08:00
|
|
|
zfree(&rec->switch_output.filenames[n]);
|
2019-03-15 06:49:55 +08:00
|
|
|
}
|
|
|
|
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-06-27 18:24:05 +08:00
|
|
|
static const struct perf_event_mmap_page *
|
2019-07-21 19:23:52 +08:00
|
|
|
perf_evlist__pick_pc(struct evlist *evlist)
|
2016-06-27 18:24:05 +08:00
|
|
|
{
|
2016-07-14 16:34:39 +08:00
|
|
|
if (evlist) {
|
2019-07-28 04:07:44 +08:00
|
|
|
if (evlist->mmap && evlist->mmap[0].core.base)
|
|
|
|
return evlist->mmap[0].core.base;
|
|
|
|
if (evlist->overwrite_mmap && evlist->overwrite_mmap[0].core.base)
|
|
|
|
return evlist->overwrite_mmap[0].core.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;
|
2020-04-22 23:50:38 +08:00
|
|
|
event_op f = process_synthesized_event;
|
2016-02-26 17:32:07 +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-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;
|
|
|
|
}
|
|
|
|
|
2019-07-21 19:24:23 +08:00
|
|
|
if (have_tracepoints(&rec->evlist->core.entries)) {
|
2016-02-26 17:32:07 +08:00
|
|
|
/*
|
|
|
|
* 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;
|
|
|
|
|
2019-11-15 20:42:16 +08:00
|
|
|
/* Synthesize id_index before auxtrace_info */
|
|
|
|
if (rec->opts.auxtrace_sample_mode) {
|
|
|
|
err = perf_event__synthesize_id_index(tool,
|
|
|
|
process_synthesized_event,
|
|
|
|
session->evlist, 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;
|
|
|
|
|
2019-07-21 19:24:42 +08:00
|
|
|
err = perf_event__synthesize_thread_map2(&rec->tool, rec->evlist->core.threads,
|
2017-11-18 05:42:59 +08:00
|
|
|
process_synthesized_event,
|
|
|
|
NULL);
|
|
|
|
if (err < 0) {
|
|
|
|
pr_err("Couldn't synthesize thread map.\n");
|
|
|
|
return err;
|
|
|
|
}
|
|
|
|
|
2019-07-21 19:24:41 +08:00
|
|
|
err = perf_event__synthesize_cpu_map(&rec->tool, rec->evlist->core.cpus,
|
2017-11-18 05:42:59 +08:00
|
|
|
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");
|
|
|
|
|
2020-03-25 20:45:33 +08:00
|
|
|
err = perf_event__synthesize_cgroups(tool, process_synthesized_event,
|
|
|
|
machine);
|
|
|
|
if (err < 0)
|
|
|
|
pr_warning("Couldn't synthesize cgroup events.\n");
|
|
|
|
|
2020-04-22 23:50:38 +08:00
|
|
|
if (rec->opts.nr_threads_synthesize > 1) {
|
|
|
|
perf_set_multithreaded();
|
|
|
|
f = process_locked_synthesized_event;
|
|
|
|
}
|
|
|
|
|
2019-07-21 19:24:42 +08:00
|
|
|
err = __machine__synthesize_threads(machine, tool, &opts->target, rec->evlist->core.threads,
|
2020-04-22 23:50:38 +08:00
|
|
|
f, opts->sample_address,
|
|
|
|
rec->opts.nr_threads_synthesize);
|
|
|
|
|
|
|
|
if (rec->opts.nr_threads_synthesize > 1)
|
|
|
|
perf_set_singlethreaded();
|
|
|
|
|
2016-02-26 17:32:07 +08:00
|
|
|
out:
|
|
|
|
return err;
|
|
|
|
}
|
|
|
|
|
2020-04-28 04:56:37 +08:00
|
|
|
static int record__process_signal_event(union perf_event *event __maybe_unused, void *data)
|
|
|
|
{
|
|
|
|
struct record *rec = data;
|
|
|
|
pthread_kill(rec->thread_id, SIGUSR2);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2020-04-29 01:58:29 +08:00
|
|
|
static int record__setup_sb_evlist(struct record *rec)
|
|
|
|
{
|
|
|
|
struct record_opts *opts = &rec->opts;
|
|
|
|
|
|
|
|
if (rec->sb_evlist != NULL) {
|
|
|
|
/*
|
|
|
|
* We get here if --switch-output-event populated the
|
|
|
|
* sb_evlist, so associate a callback that will send a SIGUSR2
|
|
|
|
* to the main thread.
|
|
|
|
*/
|
|
|
|
evlist__set_cb(rec->sb_evlist, record__process_signal_event, rec);
|
|
|
|
rec->thread_id = pthread_self();
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!opts->no_bpf_event) {
|
|
|
|
if (rec->sb_evlist == NULL) {
|
|
|
|
rec->sb_evlist = evlist__new();
|
|
|
|
|
|
|
|
if (rec->sb_evlist == NULL) {
|
|
|
|
pr_err("Couldn't create side band evlist.\n.");
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (evlist__add_bpf_sb_event(rec->sb_evlist, &rec->session->header.env)) {
|
|
|
|
pr_err("Couldn't ask for PERF_RECORD_BPF_EVENT side band events.\n.");
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (perf_evlist__start_sb_thread(rec->sb_evlist, &rec->opts.target)) {
|
|
|
|
pr_debug("Couldn't start the BPF side band thread:\nBPF programs starting from now on won't be annotatable\n");
|
|
|
|
opts->no_bpf_event = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
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;
|
2019-03-19 01:41:02 +08:00
|
|
|
float ratio = 0;
|
2020-07-17 15:07:50 +08:00
|
|
|
enum evlist_ctl_cmd cmd = EVLIST_CTL_CMD_UNSUPPORTED;
|
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;
|
|
|
|
|
2020-03-25 20:45:34 +08:00
|
|
|
if (rec->opts.record_cgroup) {
|
|
|
|
#ifdef HAVE_FILE_HANDLE
|
|
|
|
tool->cgroup_events = true;
|
|
|
|
#else
|
|
|
|
pr_err("cgroup tracking is not supported\n");
|
|
|
|
return -1;
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
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);
|
2019-08-22 15:20:49 +08:00
|
|
|
if (IS_ERR(session)) {
|
2014-04-18 10:00:43 +08:00
|
|
|
pr_err("Perf session creation failed.\n");
|
2019-08-22 15:20:49 +08:00
|
|
|
return PTR_ERR(session);
|
2009-11-17 11:18:11 +08:00
|
|
|
}
|
|
|
|
|
2017-01-24 05:07:59 +08:00
|
|
|
fd = perf_data__fd(data);
|
2011-11-25 18:19:45 +08:00
|
|
|
rec->session = session;
|
|
|
|
|
2019-03-19 01:43:35 +08:00
|
|
|
if (zstd_init(&session->zstd_data, rec->opts.comp_level) < 0) {
|
|
|
|
pr_err("Compression initialization failed.\n");
|
|
|
|
return -1;
|
|
|
|
}
|
2020-05-13 10:20:23 +08:00
|
|
|
#ifdef HAVE_EVENTFD_SUPPORT
|
|
|
|
done_fd = eventfd(0, EFD_NONBLOCK);
|
|
|
|
if (done_fd < 0) {
|
|
|
|
pr_err("Failed to create wakeup eventfd, error: %m\n");
|
|
|
|
status = -1;
|
|
|
|
goto out_delete_session;
|
|
|
|
}
|
|
|
|
err = evlist__add_pollfd(rec->evlist, done_fd);
|
|
|
|
if (err < 0) {
|
|
|
|
pr_err("Failed to add wakeup eventfd to poll list\n");
|
|
|
|
status = err;
|
|
|
|
goto out_delete_session;
|
|
|
|
}
|
|
|
|
#endif // HAVE_EVENTFD_SUPPORT
|
2019-03-19 01:43:35 +08:00
|
|
|
|
|
|
|
session->header.env.comp_type = PERF_COMP_ZSTD;
|
|
|
|
session->header.env.comp_level = rec->opts.comp_level;
|
|
|
|
|
perf record: Put a copy of kcore into the perf.data directory
Add a new 'perf record' option '--kcore' which will put a copy of
/proc/kcore, kallsyms and modules into a perf.data directory. Note, that
without the --kcore option, output goes to a file as previously. The
tools' -o and -i options work with either a file name or directory name.
Example:
$ sudo perf record --kcore uname
$ sudo tree perf.data
perf.data
├── kcore_dir
│ ├── kallsyms
│ ├── kcore
│ └── modules
└── data
$ sudo perf script -v
build id event received for vmlinux: 1eaa285996affce2d74d8e66dcea09a80c9941de
build id event received for [vdso]: 8bbaf5dc62a9b644b4d4e4539737e104e4a84541
Samples for 'cycles' event do not have CPU attribute set. Skipping 'cpu' field.
Using CPUID GenuineIntel-6-8E-A
Using perf.data/kcore_dir/kcore for kernel data
Using perf.data/kcore_dir/kallsyms for symbols
perf 19058 506778.423729: 1 cycles: ffffffffa2caa548 native_write_msr+0x8 (vmlinux)
perf 19058 506778.423733: 1 cycles: ffffffffa2caa548 native_write_msr+0x8 (vmlinux)
perf 19058 506778.423734: 7 cycles: ffffffffa2caa548 native_write_msr+0x8 (vmlinux)
perf 19058 506778.423736: 117 cycles: ffffffffa2caa54a native_write_msr+0xa (vmlinux)
perf 19058 506778.423738: 2092 cycles: ffffffffa2c9b7b0 native_apic_msr_write+0x0 (vmlinux)
perf 19058 506778.423740: 37380 cycles: ffffffffa2f121d0 perf_event_addr_filters_exec+0x0 (vmlinux)
uname 19058 506778.423751: 582673 cycles: ffffffffa303a407 propagate_protected_usage+0x147 (vmlinux)
uname 19058 506778.423892: 2241841 cycles: ffffffffa2cae0c9 unwind_next_frame.part.5+0x79 (vmlinux)
uname 19058 506778.424430: 2457397 cycles: ffffffffa3019232 check_memory_region+0x52 (vmlinux)
Committer testing:
# rm -rf perf.data*
# perf record sleep 1
[ perf record: Woken up 1 times to write data ]
[ perf record: Captured and wrote 0.024 MB perf.data (7 samples) ]
# ls -l perf.data
-rw-------. 1 root root 34772 Oct 21 11:08 perf.data
# perf record --kcore uname
Linux
[ perf record: Woken up 1 times to write data ]
[ perf record: Captured and wrote 0.024 MB perf.data (7 samples) ]
ls[root@quaco ~]# ls -lad perf.data*
drwx------. 3 root root 4096 Oct 21 11:08 perf.data
-rw-------. 1 root root 34772 Oct 21 11:08 perf.data.old
# perf evlist -v
cycles: size: 112, { sample_period, sample_freq }: 4000, sample_type: IP|TID|TIME|PERIOD, read_format: ID, 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, ksymbol: 1, bpf_event: 1
# perf evlist -v -i perf.data/data
cycles: size: 112, { sample_period, sample_freq }: 4000, sample_type: IP|TID|TIME|PERIOD, read_format: ID, 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, ksymbol: 1, bpf_event: 1
#
Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
Reviewed-by: Jiri Olsa <jolsa@kernel.org>
Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Link: http://lore.kernel.org/lkml/20191004083121.12182-6-adrian.hunter@intel.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2019-10-04 16:31:21 +08:00
|
|
|
if (rec->opts.kcore &&
|
|
|
|
!record__kcore_readable(&session->machines.host)) {
|
|
|
|
pr_err("ERROR: kcore is not readable.\n");
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
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.
|
|
|
|
*/
|
2019-07-21 19:24:28 +08:00
|
|
|
if (data->is_pipe && rec->evlist->core.nr_entries == 1)
|
2018-03-03 00:13:54 +08:00
|
|
|
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
|
|
|
}
|
2019-08-06 21:14:05 +08:00
|
|
|
session->header.env.comp_mmap_len = session->evlist->core.mmap_len;
|
2009-04-08 21:01:31 +08:00
|
|
|
|
perf record: Put a copy of kcore into the perf.data directory
Add a new 'perf record' option '--kcore' which will put a copy of
/proc/kcore, kallsyms and modules into a perf.data directory. Note, that
without the --kcore option, output goes to a file as previously. The
tools' -o and -i options work with either a file name or directory name.
Example:
$ sudo perf record --kcore uname
$ sudo tree perf.data
perf.data
├── kcore_dir
│ ├── kallsyms
│ ├── kcore
│ └── modules
└── data
$ sudo perf script -v
build id event received for vmlinux: 1eaa285996affce2d74d8e66dcea09a80c9941de
build id event received for [vdso]: 8bbaf5dc62a9b644b4d4e4539737e104e4a84541
Samples for 'cycles' event do not have CPU attribute set. Skipping 'cpu' field.
Using CPUID GenuineIntel-6-8E-A
Using perf.data/kcore_dir/kcore for kernel data
Using perf.data/kcore_dir/kallsyms for symbols
perf 19058 506778.423729: 1 cycles: ffffffffa2caa548 native_write_msr+0x8 (vmlinux)
perf 19058 506778.423733: 1 cycles: ffffffffa2caa548 native_write_msr+0x8 (vmlinux)
perf 19058 506778.423734: 7 cycles: ffffffffa2caa548 native_write_msr+0x8 (vmlinux)
perf 19058 506778.423736: 117 cycles: ffffffffa2caa54a native_write_msr+0xa (vmlinux)
perf 19058 506778.423738: 2092 cycles: ffffffffa2c9b7b0 native_apic_msr_write+0x0 (vmlinux)
perf 19058 506778.423740: 37380 cycles: ffffffffa2f121d0 perf_event_addr_filters_exec+0x0 (vmlinux)
uname 19058 506778.423751: 582673 cycles: ffffffffa303a407 propagate_protected_usage+0x147 (vmlinux)
uname 19058 506778.423892: 2241841 cycles: ffffffffa2cae0c9 unwind_next_frame.part.5+0x79 (vmlinux)
uname 19058 506778.424430: 2457397 cycles: ffffffffa3019232 check_memory_region+0x52 (vmlinux)
Committer testing:
# rm -rf perf.data*
# perf record sleep 1
[ perf record: Woken up 1 times to write data ]
[ perf record: Captured and wrote 0.024 MB perf.data (7 samples) ]
# ls -l perf.data
-rw-------. 1 root root 34772 Oct 21 11:08 perf.data
# perf record --kcore uname
Linux
[ perf record: Woken up 1 times to write data ]
[ perf record: Captured and wrote 0.024 MB perf.data (7 samples) ]
ls[root@quaco ~]# ls -lad perf.data*
drwx------. 3 root root 4096 Oct 21 11:08 perf.data
-rw-------. 1 root root 34772 Oct 21 11:08 perf.data.old
# perf evlist -v
cycles: size: 112, { sample_period, sample_freq }: 4000, sample_type: IP|TID|TIME|PERIOD, read_format: ID, 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, ksymbol: 1, bpf_event: 1
# perf evlist -v -i perf.data/data
cycles: size: 112, { sample_period, sample_freq }: 4000, sample_type: IP|TID|TIME|PERIOD, read_format: ID, 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, ksymbol: 1, bpf_event: 1
#
Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
Reviewed-by: Jiri Olsa <jolsa@kernel.org>
Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Link: http://lore.kernel.org/lkml/20191004083121.12182-6-adrian.hunter@intel.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2019-10-04 16:31:21 +08:00
|
|
|
if (rec->opts.kcore) {
|
|
|
|
err = record__kcore_copy(&session->machines.host, data);
|
|
|
|
if (err) {
|
|
|
|
pr_err("ERROR: Failed to copy kcore\n");
|
|
|
|
goto out_child;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
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.
|
|
|
|
*/
|
2020-06-17 20:29:48 +08:00
|
|
|
if (rec->tool.ordered_events && !evlist__sample_id_all(rec->evlist)) {
|
2015-08-19 22:29:21 +08:00
|
|
|
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
|
|
|
}
|
|
|
|
|
2020-04-24 23:24:51 +08:00
|
|
|
err = -1;
|
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");
|
2014-05-12 08:47:24 +08:00
|
|
|
goto out_child;
|
2011-12-07 17:02:55 +08:00
|
|
|
}
|
|
|
|
|
2020-04-29 01:58:29 +08:00
|
|
|
err = record__setup_sb_evlist(rec);
|
|
|
|
if (err)
|
|
|
|
goto out_child;
|
2019-03-12 13:30:50 +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)
|
2019-07-21 19:24:08 +08:00
|
|
|
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
|
|
|
|
2020-07-17 15:08:23 +08:00
|
|
|
if (evlist__initialize_ctlfd(rec->evlist, opts->ctl_fd, opts->ctl_fd_ack))
|
|
|
|
goto out_child;
|
|
|
|
|
2014-01-12 05:38:27 +08:00
|
|
|
if (opts->initial_delay) {
|
2020-07-17 15:07:03 +08:00
|
|
|
pr_info(EVLIST_DISABLED_MSG);
|
|
|
|
if (opts->initial_delay > 0) {
|
|
|
|
usleep(opts->initial_delay * USEC_PER_MSEC);
|
|
|
|
evlist__enable(rec->evlist);
|
|
|
|
pr_info(EVLIST_ENABLED_MSG);
|
|
|
|
}
|
2014-01-12 05:38:27 +08:00
|
|
|
}
|
|
|
|
|
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);
|
|
|
|
|
perf record: Implement --mmap-flush=<number> option
Implement a --mmap-flush option that specifies minimal number of bytes
that is extracted from mmaped kernel buffer to store into a trace. The
default option value is 1 byte what means every time trace writing
thread finds some new data in the mmaped buffer the data is extracted,
possibly compressed and written to a trace.
$ tools/perf/perf record --mmap-flush 1024 -e cycles -- matrix.gcc
$ tools/perf/perf record --aio --mmap-flush 1K -e cycles -- matrix.gcc
The option is independent from -z setting, doesn't vary with compression
level and can serve two purposes.
The first purpose is to increase the compression ratio of a trace data.
Larger data chunks are compressed more effectively so the implemented
option allows specifying data chunk size to compress. Also at some cases
executing more write syscalls with smaller data size can take longer
than executing less write syscalls with bigger data size due to syscall
overhead so extracting bigger data chunks specified by the option value
could additionally decrease runtime overhead.
The second purpose is to avoid self monitoring live-lock issue in system
wide (-a) profiling mode. Profiling in system wide mode with compression
(-a -z) can additionally induce data into the kernel buffers along with
the data from monitored processes. If performance data rate and volume
from the monitored processes is high then trace streaming and
compression activity in the tool is also high. High tool process
activity can lead to subtle live-lock effect when compression of single
new byte from some of mmaped kernel buffer leads to generation of the
next single byte at some mmaped buffer. So perf tool process ends up in
endless self monitoring.
Implemented synch parameter is the mean to force data move independently
from the specified flush threshold value. Despite the provided flush
value the tool needs capability to unconditionally drain memory buffers,
at least in the end of the collection.
Committer testing:
Running with the default value, i.e. as soon as there is something to
read go on consuming, we first write the synthesized events, small
chunks of about 128 bytes:
# perf trace -m 2048 --call-graph dwarf -e write -- perf record
<SNIP>
101.142 ( 0.004 ms): perf/25821 write(fd: 3</root/perf.data>, buf: 0x210db60, count: 120) = 120
__libc_write (/usr/lib64/libpthread-2.28.so)
ion (/home/acme/bin/perf)
record__write (inlined)
process_synthesized_event (/home/acme/bin/perf)
perf_tool__process_synth_event (inlined)
perf_event__synthesize_mmap_events (/home/acme/bin/perf)
Then we move to reading the mmap buffers consuming the events put there
by the kernel perf infrastructure:
107.561 ( 0.005 ms): perf/25821 write(fd: 3</root/perf.data>, buf: 0x7f1befc02000, count: 336) = 336
__libc_write (/usr/lib64/libpthread-2.28.so)
ion (/home/acme/bin/perf)
record__write (inlined)
record__pushfn (/home/acme/bin/perf)
perf_mmap__push (/home/acme/bin/perf)
record__mmap_read_evlist (inlined)
record__mmap_read_all (inlined)
__cmd_record (inlined)
cmd_record (/home/acme/bin/perf)
12919.953 ( 0.136 ms): perf/25821 write(fd: 3</root/perf.data>, buf: 0x7f1befc83150, count: 184984) = 184984
<SNIP same backtrace as in the 107.561 timestamp>
12920.094 ( 0.155 ms): perf/25821 write(fd: 3</root/perf.data>, buf: 0x7f1befc02150, count: 261816) = 261816
<SNIP same backtrace as in the 107.561 timestamp>
12920.253 ( 0.093 ms): perf/25821 write(fd: 3</root/perf.data>, buf: 0x7f1befb81120, count: 170832) = 170832
<SNIP same backtrace as in the 107.561 timestamp>
If we limit it to write only when more than 16MB are available for
reading, it throttles that to a quarter of the --mmap-pages set for
'perf record', which by default get to 528384 bytes, found out using
'record -v':
mmap flush: 132096
mmap size 528384B
With that in place all the writes coming from
record__mmap_read_evlist(), i.e. from the mmap buffers setup by the
kernel perf infrastructure were at least 132096 bytes long.
Trying with a bigger mmap size:
perf trace -e write perf record -v -m 2048 --mmap-flush 16M
74982.928 ( 2.471 ms): perf/26500 write(fd: 3</root/perf.data>, buf: 0x7ff94a6cc000, count: 3580888) = 3580888
74985.406 ( 2.353 ms): perf/26500 write(fd: 3</root/perf.data>, buf: 0x7ff949ecb000, count: 3453256) = 3453256
74987.764 ( 2.629 ms): perf/26500 write(fd: 3</root/perf.data>, buf: 0x7ff9496ca000, count: 3859232) = 3859232
74990.399 ( 2.341 ms): perf/26500 write(fd: 3</root/perf.data>, buf: 0x7ff948ec9000, count: 3769032) = 3769032
74992.744 ( 2.064 ms): perf/26500 write(fd: 3</root/perf.data>, buf: 0x7ff9486c8000, count: 3310520) = 3310520
74994.814 ( 2.619 ms): perf/26500 write(fd: 3</root/perf.data>, buf: 0x7ff947ec7000, count: 4194688) = 4194688
74997.439 ( 2.787 ms): perf/26500 write(fd: 3</root/perf.data>, buf: 0x7ff9476c6000, count: 4029760) = 4029760
Was again limited to a quarter of the mmap size:
mmap flush: 2098176
mmap size 8392704B
A warning about that would be good to have but can be added later,
something like:
"max flush is a quarter of the mmap size, if wanting to bump the mmap
flush further, bump the mmap size as well using -m/--mmap-pages"
Also rename the 'sync' parameters to 'synch' to keep tools/perf building
with older glibcs:
cc1: warnings being treated as errors
builtin-record.c: In function 'record__mmap_read_evlist':
builtin-record.c:775: warning: declaration of 'sync' shadows a global declaration
/usr/include/unistd.h:933: warning: shadowed declaration is here
builtin-record.c: In function 'record__mmap_read_all':
builtin-record.c:856: warning: declaration of 'sync' shadows a global declaration
/usr/include/unistd.h:933: warning: shadowed declaration is here
Signed-off-by: Alexey Budankov <alexey.budankov@linux.intel.com>
Reviewed-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: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Link: http://lkml.kernel.org/r/f6600d72-ecfa-2eb7-7e51-f6954547d500@linux.intel.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2019-03-19 01:40:26 +08:00
|
|
|
if (record__mmap_read_all(rec, false) < 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))
|
2019-08-06 22:41:01 +08:00
|
|
|
record__read_auxtrace_snapshot(rec, false);
|
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;
|
2019-09-01 04:48:33 +08:00
|
|
|
err = 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
|
|
|
|
2019-08-16 22:00:45 +08:00
|
|
|
if (evlist__filter_pollfd(rec->evlist, POLLERR | POLLHUP) == 0)
|
2014-08-13 22:33:59 +08:00
|
|
|
draining = true;
|
2009-09-18 01:59:05 +08:00
|
|
|
}
|
|
|
|
|
2020-07-17 15:07:50 +08:00
|
|
|
if (evlist__ctlfd_process(rec->evlist, &cmd) > 0) {
|
|
|
|
switch (cmd) {
|
|
|
|
case EVLIST_CTL_CMD_ENABLE:
|
|
|
|
pr_info(EVLIST_ENABLED_MSG);
|
|
|
|
break;
|
|
|
|
case EVLIST_CTL_CMD_DISABLE:
|
|
|
|
pr_info(EVLIST_DISABLED_MSG);
|
|
|
|
break;
|
|
|
|
case EVLIST_CTL_CMD_ACK:
|
|
|
|
case EVLIST_CTL_CMD_UNSUPPORTED:
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
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);
|
2019-07-21 19:24:09 +08:00
|
|
|
evlist__disable(rec->evlist);
|
2012-11-13 01:34:02 +08:00
|
|
|
disabled = true;
|
|
|
|
}
|
2009-04-08 21:01:31 +08:00
|
|
|
}
|
2019-08-06 22:41:01 +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
|
|
|
|
2019-08-06 22:41:01 +08:00
|
|
|
if (opts->auxtrace_snapshot_on_exit)
|
|
|
|
record__auxtrace_snapshot_exit(rec);
|
|
|
|
|
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:
|
2020-07-17 15:08:23 +08:00
|
|
|
evlist__finalize_ctlfd(rec->evlist);
|
perf record: Implement --mmap-flush=<number> option
Implement a --mmap-flush option that specifies minimal number of bytes
that is extracted from mmaped kernel buffer to store into a trace. The
default option value is 1 byte what means every time trace writing
thread finds some new data in the mmaped buffer the data is extracted,
possibly compressed and written to a trace.
$ tools/perf/perf record --mmap-flush 1024 -e cycles -- matrix.gcc
$ tools/perf/perf record --aio --mmap-flush 1K -e cycles -- matrix.gcc
The option is independent from -z setting, doesn't vary with compression
level and can serve two purposes.
The first purpose is to increase the compression ratio of a trace data.
Larger data chunks are compressed more effectively so the implemented
option allows specifying data chunk size to compress. Also at some cases
executing more write syscalls with smaller data size can take longer
than executing less write syscalls with bigger data size due to syscall
overhead so extracting bigger data chunks specified by the option value
could additionally decrease runtime overhead.
The second purpose is to avoid self monitoring live-lock issue in system
wide (-a) profiling mode. Profiling in system wide mode with compression
(-a -z) can additionally induce data into the kernel buffers along with
the data from monitored processes. If performance data rate and volume
from the monitored processes is high then trace streaming and
compression activity in the tool is also high. High tool process
activity can lead to subtle live-lock effect when compression of single
new byte from some of mmaped kernel buffer leads to generation of the
next single byte at some mmaped buffer. So perf tool process ends up in
endless self monitoring.
Implemented synch parameter is the mean to force data move independently
from the specified flush threshold value. Despite the provided flush
value the tool needs capability to unconditionally drain memory buffers,
at least in the end of the collection.
Committer testing:
Running with the default value, i.e. as soon as there is something to
read go on consuming, we first write the synthesized events, small
chunks of about 128 bytes:
# perf trace -m 2048 --call-graph dwarf -e write -- perf record
<SNIP>
101.142 ( 0.004 ms): perf/25821 write(fd: 3</root/perf.data>, buf: 0x210db60, count: 120) = 120
__libc_write (/usr/lib64/libpthread-2.28.so)
ion (/home/acme/bin/perf)
record__write (inlined)
process_synthesized_event (/home/acme/bin/perf)
perf_tool__process_synth_event (inlined)
perf_event__synthesize_mmap_events (/home/acme/bin/perf)
Then we move to reading the mmap buffers consuming the events put there
by the kernel perf infrastructure:
107.561 ( 0.005 ms): perf/25821 write(fd: 3</root/perf.data>, buf: 0x7f1befc02000, count: 336) = 336
__libc_write (/usr/lib64/libpthread-2.28.so)
ion (/home/acme/bin/perf)
record__write (inlined)
record__pushfn (/home/acme/bin/perf)
perf_mmap__push (/home/acme/bin/perf)
record__mmap_read_evlist (inlined)
record__mmap_read_all (inlined)
__cmd_record (inlined)
cmd_record (/home/acme/bin/perf)
12919.953 ( 0.136 ms): perf/25821 write(fd: 3</root/perf.data>, buf: 0x7f1befc83150, count: 184984) = 184984
<SNIP same backtrace as in the 107.561 timestamp>
12920.094 ( 0.155 ms): perf/25821 write(fd: 3</root/perf.data>, buf: 0x7f1befc02150, count: 261816) = 261816
<SNIP same backtrace as in the 107.561 timestamp>
12920.253 ( 0.093 ms): perf/25821 write(fd: 3</root/perf.data>, buf: 0x7f1befb81120, count: 170832) = 170832
<SNIP same backtrace as in the 107.561 timestamp>
If we limit it to write only when more than 16MB are available for
reading, it throttles that to a quarter of the --mmap-pages set for
'perf record', which by default get to 528384 bytes, found out using
'record -v':
mmap flush: 132096
mmap size 528384B
With that in place all the writes coming from
record__mmap_read_evlist(), i.e. from the mmap buffers setup by the
kernel perf infrastructure were at least 132096 bytes long.
Trying with a bigger mmap size:
perf trace -e write perf record -v -m 2048 --mmap-flush 16M
74982.928 ( 2.471 ms): perf/26500 write(fd: 3</root/perf.data>, buf: 0x7ff94a6cc000, count: 3580888) = 3580888
74985.406 ( 2.353 ms): perf/26500 write(fd: 3</root/perf.data>, buf: 0x7ff949ecb000, count: 3453256) = 3453256
74987.764 ( 2.629 ms): perf/26500 write(fd: 3</root/perf.data>, buf: 0x7ff9496ca000, count: 3859232) = 3859232
74990.399 ( 2.341 ms): perf/26500 write(fd: 3</root/perf.data>, buf: 0x7ff948ec9000, count: 3769032) = 3769032
74992.744 ( 2.064 ms): perf/26500 write(fd: 3</root/perf.data>, buf: 0x7ff9486c8000, count: 3310520) = 3310520
74994.814 ( 2.619 ms): perf/26500 write(fd: 3</root/perf.data>, buf: 0x7ff947ec7000, count: 4194688) = 4194688
74997.439 ( 2.787 ms): perf/26500 write(fd: 3</root/perf.data>, buf: 0x7ff9476c6000, count: 4029760) = 4029760
Was again limited to a quarter of the mmap size:
mmap flush: 2098176
mmap size 8392704B
A warning about that would be good to have but can be added later,
something like:
"max flush is a quarter of the mmap size, if wanting to bump the mmap
flush further, bump the mmap size as well using -m/--mmap-pages"
Also rename the 'sync' parameters to 'synch' to keep tools/perf building
with older glibcs:
cc1: warnings being treated as errors
builtin-record.c: In function 'record__mmap_read_evlist':
builtin-record.c:775: warning: declaration of 'sync' shadows a global declaration
/usr/include/unistd.h:933: warning: shadowed declaration is here
builtin-record.c: In function 'record__mmap_read_all':
builtin-record.c:856: warning: declaration of 'sync' shadows a global declaration
/usr/include/unistd.h:933: warning: shadowed declaration is here
Signed-off-by: Alexey Budankov <alexey.budankov@linux.intel.com>
Reviewed-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: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Link: http://lkml.kernel.org/r/f6600d72-ecfa-2eb7-7e51-f6954547d500@linux.intel.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2019-03-19 01:40:26 +08:00
|
|
|
record__mmap_read_all(rec, true);
|
2018-11-06 17:04:58 +08:00
|
|
|
record__aio_mmap_read_sync(rec);
|
|
|
|
|
2019-03-19 01:41:02 +08:00
|
|
|
if (rec->session->bytes_transferred && rec->session->bytes_compressed) {
|
|
|
|
ratio = (float)rec->session->bytes_transferred/(float)rec->session->bytes_compressed;
|
|
|
|
session->header.env.comp_ratio = ratio + 0.5;
|
|
|
|
}
|
|
|
|
|
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';
|
|
|
|
|
2019-03-19 01:41:02 +08:00
|
|
|
fprintf(stderr, "[ perf record: Captured and wrote %.3f MB %s%s%s",
|
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);
|
2019-03-19 01:41:02 +08:00
|
|
|
if (ratio) {
|
|
|
|
fprintf(stderr, ", compressed (original %.3f MB, ratio is %.3f)",
|
|
|
|
rec->session->bytes_transferred / 1024.0 / 1024.0,
|
|
|
|
ratio);
|
|
|
|
}
|
|
|
|
fprintf(stderr, " ]\n");
|
2015-01-29 16:06:44 +08:00
|
|
|
}
|
|
|
|
|
2010-07-30 01:08:55 +08:00
|
|
|
out_delete_session:
|
2020-05-13 10:20:23 +08:00
|
|
|
#ifdef HAVE_EVENTFD_SUPPORT
|
|
|
|
if (done_fd >= 0)
|
|
|
|
close(done_fd);
|
|
|
|
#endif
|
2019-03-19 01:43:35 +08:00
|
|
|
zstd_fini(&session->zstd_data);
|
2010-07-30 01:08:55 +08:00
|
|
|
perf_session__delete(session);
|
2019-03-12 13:30:50 +08:00
|
|
|
|
|
|
|
if (!opts->no_bpf_event)
|
2020-04-24 21:24:04 +08:00
|
|
|
perf_evlist__stop_sb_thread(rec->sb_evlist);
|
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
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2019-10-22 16:09:01 +08:00
|
|
|
static int parse_output_max_size(const struct option *opt,
|
|
|
|
const char *str, int unset)
|
|
|
|
{
|
|
|
|
unsigned long *s = (unsigned long *)opt->value;
|
|
|
|
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 },
|
|
|
|
};
|
|
|
|
unsigned long val;
|
|
|
|
|
|
|
|
if (unset) {
|
|
|
|
*s = 0;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
val = parse_tag_value(str, tags_size);
|
|
|
|
if (val != (unsigned long) -1) {
|
|
|
|
*s = val;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2020-07-17 15:08:23 +08:00
|
|
|
static int parse_control_option(const struct option *opt,
|
|
|
|
const char *str,
|
|
|
|
int unset __maybe_unused)
|
|
|
|
{
|
|
|
|
char *comma = NULL, *endptr = NULL;
|
|
|
|
struct record_opts *config = (struct record_opts *)opt->value;
|
|
|
|
|
|
|
|
if (strncmp(str, "fd:", 3))
|
|
|
|
return -EINVAL;
|
|
|
|
|
|
|
|
config->ctl_fd = strtoul(&str[3], &endptr, 0);
|
|
|
|
if (endptr == &str[3])
|
|
|
|
return -EINVAL;
|
|
|
|
|
|
|
|
comma = strchr(str, ',');
|
|
|
|
if (comma) {
|
|
|
|
if (endptr != comma)
|
|
|
|
return -EINVAL;
|
|
|
|
|
|
|
|
config->ctl_fd_ack = strtoul(comma + 1, &endptr, 0);
|
|
|
|
if (endptr == comma + 1 || *endptr != '\0')
|
|
|
|
return -EINVAL;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2017-01-09 17:51:59 +08:00
|
|
|
static void switch_output_size_warn(struct record *rec)
|
|
|
|
{
|
2019-07-28 18:45:35 +08:00
|
|
|
u64 wakeup_size = evlist__mmap_size(rec->opts.mmap_pages);
|
2017-01-09 17:51:59 +08:00
|
|
|
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
|
|
|
|
2020-04-28 04:56:37 +08:00
|
|
|
/*
|
|
|
|
* If we're using --switch-output-events, then we imply its
|
|
|
|
* --switch-output=signal, as we'll send a SIGUSR2 from the side band
|
|
|
|
* thread to its parent.
|
|
|
|
*/
|
|
|
|
if (rec->switch_output_event_set)
|
|
|
|
goto do_signal;
|
|
|
|
|
2017-01-09 17:51:57 +08:00
|
|
|
if (!s->set)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
if (!strcmp(s->str, "signal")) {
|
2020-04-28 04:56:37 +08:00
|
|
|
do_signal:
|
2017-01-09 17:51:57 +08:00
|
|
|
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
|
|
|
|
2019-11-14 23:15:34 +08:00
|
|
|
static int build_id__process_mmap(struct perf_tool *tool, union perf_event *event,
|
|
|
|
struct perf_sample *sample, struct machine *machine)
|
|
|
|
{
|
|
|
|
/*
|
|
|
|
* We already have the kernel maps, put in place via perf_session__create_kernel_maps()
|
|
|
|
* no need to add them twice.
|
|
|
|
*/
|
|
|
|
if (!(event->header.misc & PERF_RECORD_MISC_USER))
|
|
|
|
return 0;
|
|
|
|
return perf_event__process_mmap(tool, event, sample, machine);
|
|
|
|
}
|
|
|
|
|
|
|
|
static int build_id__process_mmap2(struct perf_tool *tool, union perf_event *event,
|
|
|
|
struct perf_sample *sample, struct machine *machine)
|
|
|
|
{
|
|
|
|
/*
|
|
|
|
* We already have the kernel maps, put in place via perf_session__create_kernel_maps()
|
|
|
|
* no need to add them twice.
|
|
|
|
*/
|
|
|
|
if (!(event->header.misc & PERF_RECORD_MISC_USER))
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
return perf_event__process_mmap2(tool, event, sample, machine);
|
|
|
|
}
|
|
|
|
|
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
|
|
|
},
|
perf record: Implement --mmap-flush=<number> option
Implement a --mmap-flush option that specifies minimal number of bytes
that is extracted from mmaped kernel buffer to store into a trace. The
default option value is 1 byte what means every time trace writing
thread finds some new data in the mmaped buffer the data is extracted,
possibly compressed and written to a trace.
$ tools/perf/perf record --mmap-flush 1024 -e cycles -- matrix.gcc
$ tools/perf/perf record --aio --mmap-flush 1K -e cycles -- matrix.gcc
The option is independent from -z setting, doesn't vary with compression
level and can serve two purposes.
The first purpose is to increase the compression ratio of a trace data.
Larger data chunks are compressed more effectively so the implemented
option allows specifying data chunk size to compress. Also at some cases
executing more write syscalls with smaller data size can take longer
than executing less write syscalls with bigger data size due to syscall
overhead so extracting bigger data chunks specified by the option value
could additionally decrease runtime overhead.
The second purpose is to avoid self monitoring live-lock issue in system
wide (-a) profiling mode. Profiling in system wide mode with compression
(-a -z) can additionally induce data into the kernel buffers along with
the data from monitored processes. If performance data rate and volume
from the monitored processes is high then trace streaming and
compression activity in the tool is also high. High tool process
activity can lead to subtle live-lock effect when compression of single
new byte from some of mmaped kernel buffer leads to generation of the
next single byte at some mmaped buffer. So perf tool process ends up in
endless self monitoring.
Implemented synch parameter is the mean to force data move independently
from the specified flush threshold value. Despite the provided flush
value the tool needs capability to unconditionally drain memory buffers,
at least in the end of the collection.
Committer testing:
Running with the default value, i.e. as soon as there is something to
read go on consuming, we first write the synthesized events, small
chunks of about 128 bytes:
# perf trace -m 2048 --call-graph dwarf -e write -- perf record
<SNIP>
101.142 ( 0.004 ms): perf/25821 write(fd: 3</root/perf.data>, buf: 0x210db60, count: 120) = 120
__libc_write (/usr/lib64/libpthread-2.28.so)
ion (/home/acme/bin/perf)
record__write (inlined)
process_synthesized_event (/home/acme/bin/perf)
perf_tool__process_synth_event (inlined)
perf_event__synthesize_mmap_events (/home/acme/bin/perf)
Then we move to reading the mmap buffers consuming the events put there
by the kernel perf infrastructure:
107.561 ( 0.005 ms): perf/25821 write(fd: 3</root/perf.data>, buf: 0x7f1befc02000, count: 336) = 336
__libc_write (/usr/lib64/libpthread-2.28.so)
ion (/home/acme/bin/perf)
record__write (inlined)
record__pushfn (/home/acme/bin/perf)
perf_mmap__push (/home/acme/bin/perf)
record__mmap_read_evlist (inlined)
record__mmap_read_all (inlined)
__cmd_record (inlined)
cmd_record (/home/acme/bin/perf)
12919.953 ( 0.136 ms): perf/25821 write(fd: 3</root/perf.data>, buf: 0x7f1befc83150, count: 184984) = 184984
<SNIP same backtrace as in the 107.561 timestamp>
12920.094 ( 0.155 ms): perf/25821 write(fd: 3</root/perf.data>, buf: 0x7f1befc02150, count: 261816) = 261816
<SNIP same backtrace as in the 107.561 timestamp>
12920.253 ( 0.093 ms): perf/25821 write(fd: 3</root/perf.data>, buf: 0x7f1befb81120, count: 170832) = 170832
<SNIP same backtrace as in the 107.561 timestamp>
If we limit it to write only when more than 16MB are available for
reading, it throttles that to a quarter of the --mmap-pages set for
'perf record', which by default get to 528384 bytes, found out using
'record -v':
mmap flush: 132096
mmap size 528384B
With that in place all the writes coming from
record__mmap_read_evlist(), i.e. from the mmap buffers setup by the
kernel perf infrastructure were at least 132096 bytes long.
Trying with a bigger mmap size:
perf trace -e write perf record -v -m 2048 --mmap-flush 16M
74982.928 ( 2.471 ms): perf/26500 write(fd: 3</root/perf.data>, buf: 0x7ff94a6cc000, count: 3580888) = 3580888
74985.406 ( 2.353 ms): perf/26500 write(fd: 3</root/perf.data>, buf: 0x7ff949ecb000, count: 3453256) = 3453256
74987.764 ( 2.629 ms): perf/26500 write(fd: 3</root/perf.data>, buf: 0x7ff9496ca000, count: 3859232) = 3859232
74990.399 ( 2.341 ms): perf/26500 write(fd: 3</root/perf.data>, buf: 0x7ff948ec9000, count: 3769032) = 3769032
74992.744 ( 2.064 ms): perf/26500 write(fd: 3</root/perf.data>, buf: 0x7ff9486c8000, count: 3310520) = 3310520
74994.814 ( 2.619 ms): perf/26500 write(fd: 3</root/perf.data>, buf: 0x7ff947ec7000, count: 4194688) = 4194688
74997.439 ( 2.787 ms): perf/26500 write(fd: 3</root/perf.data>, buf: 0x7ff9476c6000, count: 4029760) = 4029760
Was again limited to a quarter of the mmap size:
mmap flush: 2098176
mmap size 8392704B
A warning about that would be good to have but can be added later,
something like:
"max flush is a quarter of the mmap size, if wanting to bump the mmap
flush further, bump the mmap size as well using -m/--mmap-pages"
Also rename the 'sync' parameters to 'synch' to keep tools/perf building
with older glibcs:
cc1: warnings being treated as errors
builtin-record.c: In function 'record__mmap_read_evlist':
builtin-record.c:775: warning: declaration of 'sync' shadows a global declaration
/usr/include/unistd.h:933: warning: shadowed declaration is here
builtin-record.c: In function 'record__mmap_read_all':
builtin-record.c:856: warning: declaration of 'sync' shadows a global declaration
/usr/include/unistd.h:933: warning: shadowed declaration is here
Signed-off-by: Alexey Budankov <alexey.budankov@linux.intel.com>
Reviewed-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: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Link: http://lkml.kernel.org/r/f6600d72-ecfa-2eb7-7e51-f6954547d500@linux.intel.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2019-03-19 01:40:26 +08:00
|
|
|
.mmap_flush = MMAP_FLUSH_DEFAULT,
|
2020-04-22 23:50:38 +08:00
|
|
|
.nr_threads_synthesize = 1,
|
2020-07-17 15:08:23 +08:00
|
|
|
.ctl_fd = -1,
|
|
|
|
.ctl_fd_ack = -1,
|
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,
|
2019-11-14 23:15:34 +08:00
|
|
|
.mmap = build_id__process_mmap,
|
|
|
|
.mmap2 = build_id__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),
|
perf record: Implement --mmap-flush=<number> option
Implement a --mmap-flush option that specifies minimal number of bytes
that is extracted from mmaped kernel buffer to store into a trace. The
default option value is 1 byte what means every time trace writing
thread finds some new data in the mmaped buffer the data is extracted,
possibly compressed and written to a trace.
$ tools/perf/perf record --mmap-flush 1024 -e cycles -- matrix.gcc
$ tools/perf/perf record --aio --mmap-flush 1K -e cycles -- matrix.gcc
The option is independent from -z setting, doesn't vary with compression
level and can serve two purposes.
The first purpose is to increase the compression ratio of a trace data.
Larger data chunks are compressed more effectively so the implemented
option allows specifying data chunk size to compress. Also at some cases
executing more write syscalls with smaller data size can take longer
than executing less write syscalls with bigger data size due to syscall
overhead so extracting bigger data chunks specified by the option value
could additionally decrease runtime overhead.
The second purpose is to avoid self monitoring live-lock issue in system
wide (-a) profiling mode. Profiling in system wide mode with compression
(-a -z) can additionally induce data into the kernel buffers along with
the data from monitored processes. If performance data rate and volume
from the monitored processes is high then trace streaming and
compression activity in the tool is also high. High tool process
activity can lead to subtle live-lock effect when compression of single
new byte from some of mmaped kernel buffer leads to generation of the
next single byte at some mmaped buffer. So perf tool process ends up in
endless self monitoring.
Implemented synch parameter is the mean to force data move independently
from the specified flush threshold value. Despite the provided flush
value the tool needs capability to unconditionally drain memory buffers,
at least in the end of the collection.
Committer testing:
Running with the default value, i.e. as soon as there is something to
read go on consuming, we first write the synthesized events, small
chunks of about 128 bytes:
# perf trace -m 2048 --call-graph dwarf -e write -- perf record
<SNIP>
101.142 ( 0.004 ms): perf/25821 write(fd: 3</root/perf.data>, buf: 0x210db60, count: 120) = 120
__libc_write (/usr/lib64/libpthread-2.28.so)
ion (/home/acme/bin/perf)
record__write (inlined)
process_synthesized_event (/home/acme/bin/perf)
perf_tool__process_synth_event (inlined)
perf_event__synthesize_mmap_events (/home/acme/bin/perf)
Then we move to reading the mmap buffers consuming the events put there
by the kernel perf infrastructure:
107.561 ( 0.005 ms): perf/25821 write(fd: 3</root/perf.data>, buf: 0x7f1befc02000, count: 336) = 336
__libc_write (/usr/lib64/libpthread-2.28.so)
ion (/home/acme/bin/perf)
record__write (inlined)
record__pushfn (/home/acme/bin/perf)
perf_mmap__push (/home/acme/bin/perf)
record__mmap_read_evlist (inlined)
record__mmap_read_all (inlined)
__cmd_record (inlined)
cmd_record (/home/acme/bin/perf)
12919.953 ( 0.136 ms): perf/25821 write(fd: 3</root/perf.data>, buf: 0x7f1befc83150, count: 184984) = 184984
<SNIP same backtrace as in the 107.561 timestamp>
12920.094 ( 0.155 ms): perf/25821 write(fd: 3</root/perf.data>, buf: 0x7f1befc02150, count: 261816) = 261816
<SNIP same backtrace as in the 107.561 timestamp>
12920.253 ( 0.093 ms): perf/25821 write(fd: 3</root/perf.data>, buf: 0x7f1befb81120, count: 170832) = 170832
<SNIP same backtrace as in the 107.561 timestamp>
If we limit it to write only when more than 16MB are available for
reading, it throttles that to a quarter of the --mmap-pages set for
'perf record', which by default get to 528384 bytes, found out using
'record -v':
mmap flush: 132096
mmap size 528384B
With that in place all the writes coming from
record__mmap_read_evlist(), i.e. from the mmap buffers setup by the
kernel perf infrastructure were at least 132096 bytes long.
Trying with a bigger mmap size:
perf trace -e write perf record -v -m 2048 --mmap-flush 16M
74982.928 ( 2.471 ms): perf/26500 write(fd: 3</root/perf.data>, buf: 0x7ff94a6cc000, count: 3580888) = 3580888
74985.406 ( 2.353 ms): perf/26500 write(fd: 3</root/perf.data>, buf: 0x7ff949ecb000, count: 3453256) = 3453256
74987.764 ( 2.629 ms): perf/26500 write(fd: 3</root/perf.data>, buf: 0x7ff9496ca000, count: 3859232) = 3859232
74990.399 ( 2.341 ms): perf/26500 write(fd: 3</root/perf.data>, buf: 0x7ff948ec9000, count: 3769032) = 3769032
74992.744 ( 2.064 ms): perf/26500 write(fd: 3</root/perf.data>, buf: 0x7ff9486c8000, count: 3310520) = 3310520
74994.814 ( 2.619 ms): perf/26500 write(fd: 3</root/perf.data>, buf: 0x7ff947ec7000, count: 4194688) = 4194688
74997.439 ( 2.787 ms): perf/26500 write(fd: 3</root/perf.data>, buf: 0x7ff9476c6000, count: 4029760) = 4029760
Was again limited to a quarter of the mmap size:
mmap flush: 2098176
mmap size 8392704B
A warning about that would be good to have but can be added later,
something like:
"max flush is a quarter of the mmap size, if wanting to bump the mmap
flush further, bump the mmap size as well using -m/--mmap-pages"
Also rename the 'sync' parameters to 'synch' to keep tools/perf building
with older glibcs:
cc1: warnings being treated as errors
builtin-record.c: In function 'record__mmap_read_evlist':
builtin-record.c:775: warning: declaration of 'sync' shadows a global declaration
/usr/include/unistd.h:933: warning: shadowed declaration is here
builtin-record.c: In function 'record__mmap_read_all':
builtin-record.c:856: warning: declaration of 'sync' shadows a global declaration
/usr/include/unistd.h:933: warning: shadowed declaration is here
Signed-off-by: Alexey Budankov <alexey.budankov@linux.intel.com>
Reviewed-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: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Link: http://lkml.kernel.org/r/f6600d72-ecfa-2eb7-7e51-f6954547d500@linux.intel.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2019-03-19 01:40:26 +08:00
|
|
|
OPT_CALLBACK(0, "mmap-flush", &record.opts, "number",
|
|
|
|
"Minimal number of bytes that is extracted from mmap data pages (default: 1)",
|
|
|
|
record__mmap_flush_parse),
|
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),
|
2020-07-17 15:07:03 +08:00
|
|
|
OPT_INTEGER('D', "delay", &record.opts.initial_delay,
|
|
|
|
"ms to wait before starting measurement after program start (-1: start with events disabled)"),
|
perf record: Put a copy of kcore into the perf.data directory
Add a new 'perf record' option '--kcore' which will put a copy of
/proc/kcore, kallsyms and modules into a perf.data directory. Note, that
without the --kcore option, output goes to a file as previously. The
tools' -o and -i options work with either a file name or directory name.
Example:
$ sudo perf record --kcore uname
$ sudo tree perf.data
perf.data
├── kcore_dir
│ ├── kallsyms
│ ├── kcore
│ └── modules
└── data
$ sudo perf script -v
build id event received for vmlinux: 1eaa285996affce2d74d8e66dcea09a80c9941de
build id event received for [vdso]: 8bbaf5dc62a9b644b4d4e4539737e104e4a84541
Samples for 'cycles' event do not have CPU attribute set. Skipping 'cpu' field.
Using CPUID GenuineIntel-6-8E-A
Using perf.data/kcore_dir/kcore for kernel data
Using perf.data/kcore_dir/kallsyms for symbols
perf 19058 506778.423729: 1 cycles: ffffffffa2caa548 native_write_msr+0x8 (vmlinux)
perf 19058 506778.423733: 1 cycles: ffffffffa2caa548 native_write_msr+0x8 (vmlinux)
perf 19058 506778.423734: 7 cycles: ffffffffa2caa548 native_write_msr+0x8 (vmlinux)
perf 19058 506778.423736: 117 cycles: ffffffffa2caa54a native_write_msr+0xa (vmlinux)
perf 19058 506778.423738: 2092 cycles: ffffffffa2c9b7b0 native_apic_msr_write+0x0 (vmlinux)
perf 19058 506778.423740: 37380 cycles: ffffffffa2f121d0 perf_event_addr_filters_exec+0x0 (vmlinux)
uname 19058 506778.423751: 582673 cycles: ffffffffa303a407 propagate_protected_usage+0x147 (vmlinux)
uname 19058 506778.423892: 2241841 cycles: ffffffffa2cae0c9 unwind_next_frame.part.5+0x79 (vmlinux)
uname 19058 506778.424430: 2457397 cycles: ffffffffa3019232 check_memory_region+0x52 (vmlinux)
Committer testing:
# rm -rf perf.data*
# perf record sleep 1
[ perf record: Woken up 1 times to write data ]
[ perf record: Captured and wrote 0.024 MB perf.data (7 samples) ]
# ls -l perf.data
-rw-------. 1 root root 34772 Oct 21 11:08 perf.data
# perf record --kcore uname
Linux
[ perf record: Woken up 1 times to write data ]
[ perf record: Captured and wrote 0.024 MB perf.data (7 samples) ]
ls[root@quaco ~]# ls -lad perf.data*
drwx------. 3 root root 4096 Oct 21 11:08 perf.data
-rw-------. 1 root root 34772 Oct 21 11:08 perf.data.old
# perf evlist -v
cycles: size: 112, { sample_period, sample_freq }: 4000, sample_type: IP|TID|TIME|PERIOD, read_format: ID, 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, ksymbol: 1, bpf_event: 1
# perf evlist -v -i perf.data/data
cycles: size: 112, { sample_period, sample_freq }: 4000, sample_type: IP|TID|TIME|PERIOD, read_format: ID, 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, ksymbol: 1, bpf_event: 1
#
Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
Reviewed-by: Jiri Olsa <jolsa@kernel.org>
Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Link: http://lore.kernel.org/lkml/20191004083121.12182-6-adrian.hunter@intel.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2019-10-04 16:31:21 +08:00
|
|
|
OPT_BOOLEAN(0, "kcore", &record.opts.kcore, "copy /proc/kcore"),
|
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,"
|
2019-05-15 04:19:32 +08:00
|
|
|
" use '-I?' to list register names", parse_intr_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,"
|
2019-05-15 04:19:32 +08:00
|
|
|
" use '--user-regs=?' to list register names", parse_user_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", ""),
|
2019-11-15 20:42:16 +08:00
|
|
|
OPT_STRING_OPTARG(0, "aux-sample", &record.opts.auxtrace_sample_opts,
|
|
|
|
"opts", "sample AUX area", ""),
|
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"),
|
2020-03-25 20:45:34 +08:00
|
|
|
OPT_BOOLEAN(0, "all-cgroups", &record.opts.record_cgroup,
|
|
|
|
"Record cgroup events"),
|
2020-05-28 20:08:58 +08:00
|
|
|
OPT_BOOLEAN_SET(0, "switch-events", &record.opts.record_switch_events,
|
|
|
|
&record.opts.record_switch_events_set,
|
|
|
|
"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),
|
2019-05-30 21:29:22 +08:00
|
|
|
OPT_BOOLEAN(0, "kernel-callchains", &record.opts.kernel_callchains,
|
|
|
|
"collect kernel callchains"),
|
|
|
|
OPT_BOOLEAN(0, "user-callchains", &record.opts.user_callchains,
|
|
|
|
"collect user callchains"),
|
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"),
|
2020-04-28 04:56:37 +08:00
|
|
|
OPT_CALLBACK_SET(0, "switch-output-event", &record.sb_evlist, &record.switch_output_event_set, "switch output event",
|
|
|
|
"switch output event selector. use 'perf list' to list available events",
|
|
|
|
parse_events_option_new_evlist),
|
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),
|
perf record: Implement -z,--compression_level[=<n>] option
Implemented -z,--compression_level[=<n>] option that enables compression
of mmaped kernel data buffers content in runtime during perf record mode
collection. Default option value is 1 (fastest compression).
Compression overhead has been measured for serial and AIO streaming when
profiling matrix multiplication workload:
-------------------------------------------------------------
| SERIAL | AIO-1 |
----------------------------------------------------------------|
|-z | OVH(x) | ratio(x) size(MiB) | OVH(x) | ratio(x) size(MiB) |
|---------------------------------------------------------------|
| 0 | 1,00 | 1,000 179,424 | 1,00 | 1,000 187,527 |
| 1 | 1,04 | 8,427 181,148 | 1,01 | 8,474 188,562 |
| 2 | 1,07 | 8,055 186,953 | 1,03 | 7,912 191,773 |
| 3 | 1,04 | 8,283 181,908 | 1,03 | 8,220 191,078 |
| 5 | 1,09 | 8,101 187,705 | 1,05 | 7,780 190,065 |
| 8 | 1,05 | 9,217 179,191 | 1,12 | 6,111 193,024 |
-----------------------------------------------------------------
OVH = (Execution time with -z N) / (Execution time with -z 0)
ratio - compression ratio
size - number of bytes that was compressed
size ~= trace size x ratio
Committer notes:
Testing it I noticed that it failed to disable build id processing when
compression is enabled, and as we'd have to uncompress everything to
look for the PERF_RECORD_{MMAP,SAMPLE,etc} to figure out which build ids
to read from DSOs, we better disable build id processing when
compression is enabled, logging with pr_debug() when doing so:
Original patch:
# perf record -z2
^C[ perf record: Woken up 1 times to write data ]
0x1746e0 [0x76]: failed to process type: 81 [Invalid argument]
[ perf record: Captured and wrote 1.568 MB perf.data, compressed (original 0.452 MB, ratio is 3.995) ]
#
After auto-disabling build id processing when compression is enabled:
$ perf record -z2 sleep 1
[ perf record: Woken up 1 times to write data ]
[ perf record: Captured and wrote 0.001 MB perf.data, compressed (original 0.001 MB, ratio is 2.292) ]
$ perf record -v -z2 sleep 1
Compression enabled, disabling build id collection at the end of the session.
<SNIP extra -v pr_debug() messages>
[ perf record: Woken up 1 times to write data ]
[ perf record: Captured and wrote 0.001 MB perf.data, compressed (original 0.001 MB, ratio is 2.305) ]
$
Also, with parts of the patch originally after this one moved to just
before this one we get:
$ perf record -z2 sleep 1
[ perf record: Woken up 1 times to write data ]
[ perf record: Captured and wrote 0.001 MB perf.data, compressed (original 0.001 MB, ratio is 2.371) ]
$ perf report -D | grep COMPRESS
0 0x1b8 [0x155]: PERF_RECORD_COMPRESSED: unhandled!
0 0x30d [0x80]: PERF_RECORD_COMPRESSED: unhandled!
COMPRESSED events: 2
COMPRESSED events: 0
$
I.e. when faced with PERF_RECORD_COMPRESSED that we still have no code
to process, we just show it as not being handled, skip them and
continue, while before we had:
$ perf report -D | grep COMPRESS
0x1b8 [0x169]: failed to process type: 81 [Invalid argument]
Error:
failed to process sample
0 0x1b8 [0x169]: PERF_RECORD_COMPRESSED
$
Signed-off-by: Alexey Budankov <alexey.budankov@linux.intel.com>
Reviewed-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: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Link: http://lkml.kernel.org/r/9ff06518-ae63-a908-e44d-5d9e56dd66d9@linux.intel.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2019-03-19 01:44:42 +08:00
|
|
|
#ifdef HAVE_ZSTD_SUPPORT
|
|
|
|
OPT_CALLBACK_OPTARG('z', "compression-level", &record.opts, &comp_level_default,
|
|
|
|
"n", "Compressed records using specified level (default: 1 - fastest compression, 22 - greatest compression)",
|
|
|
|
record__parse_comp_level),
|
|
|
|
#endif
|
2019-10-22 16:09:01 +08:00
|
|
|
OPT_CALLBACK(0, "max-size", &record.output_max_size,
|
|
|
|
"size", "Limit the maximum size of the output file", parse_output_max_size),
|
2020-04-22 23:50:38 +08:00
|
|
|
OPT_UINTEGER(0, "num-thread-synthesize",
|
|
|
|
&record.opts.nr_threads_synthesize,
|
|
|
|
"number of threads to run for event synthesis"),
|
2020-05-06 02:29:43 +08:00
|
|
|
#ifdef HAVE_LIBPFM
|
|
|
|
OPT_CALLBACK(0, "pfm-events", &record.evlist, "event",
|
|
|
|
"libpfm4 event selector. use 'perf list' to list available events",
|
|
|
|
parse_libpfm_events_option),
|
|
|
|
#endif
|
2020-07-17 15:08:23 +08:00
|
|
|
OPT_CALLBACK(0, "control", &record.opts, "fd:ctl-fd[,ack-fd]",
|
|
|
|
"Listen on ctl-fd descriptor for command to control measurement ('enable': enable events, 'disable': disable events).\n"
|
|
|
|
"\t\t\t Optionally send control command completion ('ack\\n') to ack-fd descriptor.",
|
|
|
|
parse_control_option),
|
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
|
|
|
rec->opts.affinity = PERF_AFFINITY_SYS;
|
|
|
|
|
2019-07-21 19:23:55 +08:00
|
|
|
rec->evlist = evlist__new();
|
2014-01-04 02:03:26 +08:00
|
|
|
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
|
|
|
}
|
perf record: Implement -z,--compression_level[=<n>] option
Implemented -z,--compression_level[=<n>] option that enables compression
of mmaped kernel data buffers content in runtime during perf record mode
collection. Default option value is 1 (fastest compression).
Compression overhead has been measured for serial and AIO streaming when
profiling matrix multiplication workload:
-------------------------------------------------------------
| SERIAL | AIO-1 |
----------------------------------------------------------------|
|-z | OVH(x) | ratio(x) size(MiB) | OVH(x) | ratio(x) size(MiB) |
|---------------------------------------------------------------|
| 0 | 1,00 | 1,000 179,424 | 1,00 | 1,000 187,527 |
| 1 | 1,04 | 8,427 181,148 | 1,01 | 8,474 188,562 |
| 2 | 1,07 | 8,055 186,953 | 1,03 | 7,912 191,773 |
| 3 | 1,04 | 8,283 181,908 | 1,03 | 8,220 191,078 |
| 5 | 1,09 | 8,101 187,705 | 1,05 | 7,780 190,065 |
| 8 | 1,05 | 9,217 179,191 | 1,12 | 6,111 193,024 |
-----------------------------------------------------------------
OVH = (Execution time with -z N) / (Execution time with -z 0)
ratio - compression ratio
size - number of bytes that was compressed
size ~= trace size x ratio
Committer notes:
Testing it I noticed that it failed to disable build id processing when
compression is enabled, and as we'd have to uncompress everything to
look for the PERF_RECORD_{MMAP,SAMPLE,etc} to figure out which build ids
to read from DSOs, we better disable build id processing when
compression is enabled, logging with pr_debug() when doing so:
Original patch:
# perf record -z2
^C[ perf record: Woken up 1 times to write data ]
0x1746e0 [0x76]: failed to process type: 81 [Invalid argument]
[ perf record: Captured and wrote 1.568 MB perf.data, compressed (original 0.452 MB, ratio is 3.995) ]
#
After auto-disabling build id processing when compression is enabled:
$ perf record -z2 sleep 1
[ perf record: Woken up 1 times to write data ]
[ perf record: Captured and wrote 0.001 MB perf.data, compressed (original 0.001 MB, ratio is 2.292) ]
$ perf record -v -z2 sleep 1
Compression enabled, disabling build id collection at the end of the session.
<SNIP extra -v pr_debug() messages>
[ perf record: Woken up 1 times to write data ]
[ perf record: Captured and wrote 0.001 MB perf.data, compressed (original 0.001 MB, ratio is 2.305) ]
$
Also, with parts of the patch originally after this one moved to just
before this one we get:
$ perf record -z2 sleep 1
[ perf record: Woken up 1 times to write data ]
[ perf record: Captured and wrote 0.001 MB perf.data, compressed (original 0.001 MB, ratio is 2.371) ]
$ perf report -D | grep COMPRESS
0 0x1b8 [0x155]: PERF_RECORD_COMPRESSED: unhandled!
0 0x30d [0x80]: PERF_RECORD_COMPRESSED: unhandled!
COMPRESSED events: 2
COMPRESSED events: 0
$
I.e. when faced with PERF_RECORD_COMPRESSED that we still have no code
to process, we just show it as not being handled, skip them and
continue, while before we had:
$ perf report -D | grep COMPRESS
0x1b8 [0x169]: failed to process type: 81 [Invalid argument]
Error:
failed to process sample
0 0x1b8 [0x169]: PERF_RECORD_COMPRESSED
$
Signed-off-by: Alexey Budankov <alexey.budankov@linux.intel.com>
Reviewed-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: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Link: http://lkml.kernel.org/r/9ff06518-ae63-a908-e44d-5d9e56dd66d9@linux.intel.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2019-03-19 01:44:42 +08:00
|
|
|
|
perf record: Put a copy of kcore into the perf.data directory
Add a new 'perf record' option '--kcore' which will put a copy of
/proc/kcore, kallsyms and modules into a perf.data directory. Note, that
without the --kcore option, output goes to a file as previously. The
tools' -o and -i options work with either a file name or directory name.
Example:
$ sudo perf record --kcore uname
$ sudo tree perf.data
perf.data
├── kcore_dir
│ ├── kallsyms
│ ├── kcore
│ └── modules
└── data
$ sudo perf script -v
build id event received for vmlinux: 1eaa285996affce2d74d8e66dcea09a80c9941de
build id event received for [vdso]: 8bbaf5dc62a9b644b4d4e4539737e104e4a84541
Samples for 'cycles' event do not have CPU attribute set. Skipping 'cpu' field.
Using CPUID GenuineIntel-6-8E-A
Using perf.data/kcore_dir/kcore for kernel data
Using perf.data/kcore_dir/kallsyms for symbols
perf 19058 506778.423729: 1 cycles: ffffffffa2caa548 native_write_msr+0x8 (vmlinux)
perf 19058 506778.423733: 1 cycles: ffffffffa2caa548 native_write_msr+0x8 (vmlinux)
perf 19058 506778.423734: 7 cycles: ffffffffa2caa548 native_write_msr+0x8 (vmlinux)
perf 19058 506778.423736: 117 cycles: ffffffffa2caa54a native_write_msr+0xa (vmlinux)
perf 19058 506778.423738: 2092 cycles: ffffffffa2c9b7b0 native_apic_msr_write+0x0 (vmlinux)
perf 19058 506778.423740: 37380 cycles: ffffffffa2f121d0 perf_event_addr_filters_exec+0x0 (vmlinux)
uname 19058 506778.423751: 582673 cycles: ffffffffa303a407 propagate_protected_usage+0x147 (vmlinux)
uname 19058 506778.423892: 2241841 cycles: ffffffffa2cae0c9 unwind_next_frame.part.5+0x79 (vmlinux)
uname 19058 506778.424430: 2457397 cycles: ffffffffa3019232 check_memory_region+0x52 (vmlinux)
Committer testing:
# rm -rf perf.data*
# perf record sleep 1
[ perf record: Woken up 1 times to write data ]
[ perf record: Captured and wrote 0.024 MB perf.data (7 samples) ]
# ls -l perf.data
-rw-------. 1 root root 34772 Oct 21 11:08 perf.data
# perf record --kcore uname
Linux
[ perf record: Woken up 1 times to write data ]
[ perf record: Captured and wrote 0.024 MB perf.data (7 samples) ]
ls[root@quaco ~]# ls -lad perf.data*
drwx------. 3 root root 4096 Oct 21 11:08 perf.data
-rw-------. 1 root root 34772 Oct 21 11:08 perf.data.old
# perf evlist -v
cycles: size: 112, { sample_period, sample_freq }: 4000, sample_type: IP|TID|TIME|PERIOD, read_format: ID, 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, ksymbol: 1, bpf_event: 1
# perf evlist -v -i perf.data/data
cycles: size: 112, { sample_period, sample_freq }: 4000, sample_type: IP|TID|TIME|PERIOD, read_format: ID, 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, ksymbol: 1, bpf_event: 1
#
Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
Reviewed-by: Jiri Olsa <jolsa@kernel.org>
Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Link: http://lore.kernel.org/lkml/20191004083121.12182-6-adrian.hunter@intel.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2019-10-04 16:31:21 +08:00
|
|
|
if (rec->opts.kcore)
|
|
|
|
rec->data.is_dir = true;
|
|
|
|
|
perf record: Implement -z,--compression_level[=<n>] option
Implemented -z,--compression_level[=<n>] option that enables compression
of mmaped kernel data buffers content in runtime during perf record mode
collection. Default option value is 1 (fastest compression).
Compression overhead has been measured for serial and AIO streaming when
profiling matrix multiplication workload:
-------------------------------------------------------------
| SERIAL | AIO-1 |
----------------------------------------------------------------|
|-z | OVH(x) | ratio(x) size(MiB) | OVH(x) | ratio(x) size(MiB) |
|---------------------------------------------------------------|
| 0 | 1,00 | 1,000 179,424 | 1,00 | 1,000 187,527 |
| 1 | 1,04 | 8,427 181,148 | 1,01 | 8,474 188,562 |
| 2 | 1,07 | 8,055 186,953 | 1,03 | 7,912 191,773 |
| 3 | 1,04 | 8,283 181,908 | 1,03 | 8,220 191,078 |
| 5 | 1,09 | 8,101 187,705 | 1,05 | 7,780 190,065 |
| 8 | 1,05 | 9,217 179,191 | 1,12 | 6,111 193,024 |
-----------------------------------------------------------------
OVH = (Execution time with -z N) / (Execution time with -z 0)
ratio - compression ratio
size - number of bytes that was compressed
size ~= trace size x ratio
Committer notes:
Testing it I noticed that it failed to disable build id processing when
compression is enabled, and as we'd have to uncompress everything to
look for the PERF_RECORD_{MMAP,SAMPLE,etc} to figure out which build ids
to read from DSOs, we better disable build id processing when
compression is enabled, logging with pr_debug() when doing so:
Original patch:
# perf record -z2
^C[ perf record: Woken up 1 times to write data ]
0x1746e0 [0x76]: failed to process type: 81 [Invalid argument]
[ perf record: Captured and wrote 1.568 MB perf.data, compressed (original 0.452 MB, ratio is 3.995) ]
#
After auto-disabling build id processing when compression is enabled:
$ perf record -z2 sleep 1
[ perf record: Woken up 1 times to write data ]
[ perf record: Captured and wrote 0.001 MB perf.data, compressed (original 0.001 MB, ratio is 2.292) ]
$ perf record -v -z2 sleep 1
Compression enabled, disabling build id collection at the end of the session.
<SNIP extra -v pr_debug() messages>
[ perf record: Woken up 1 times to write data ]
[ perf record: Captured and wrote 0.001 MB perf.data, compressed (original 0.001 MB, ratio is 2.305) ]
$
Also, with parts of the patch originally after this one moved to just
before this one we get:
$ perf record -z2 sleep 1
[ perf record: Woken up 1 times to write data ]
[ perf record: Captured and wrote 0.001 MB perf.data, compressed (original 0.001 MB, ratio is 2.371) ]
$ perf report -D | grep COMPRESS
0 0x1b8 [0x155]: PERF_RECORD_COMPRESSED: unhandled!
0 0x30d [0x80]: PERF_RECORD_COMPRESSED: unhandled!
COMPRESSED events: 2
COMPRESSED events: 0
$
I.e. when faced with PERF_RECORD_COMPRESSED that we still have no code
to process, we just show it as not being handled, skip them and
continue, while before we had:
$ perf report -D | grep COMPRESS
0x1b8 [0x169]: failed to process type: 81 [Invalid argument]
Error:
failed to process sample
0 0x1b8 [0x169]: PERF_RECORD_COMPRESSED
$
Signed-off-by: Alexey Budankov <alexey.budankov@linux.intel.com>
Reviewed-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: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Link: http://lkml.kernel.org/r/9ff06518-ae63-a908-e44d-5d9e56dd66d9@linux.intel.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2019-03-19 01:44:42 +08:00
|
|
|
if (rec->opts.comp_level != 0) {
|
|
|
|
pr_debug("Compression enabled, disabling build id collection at the end of the session.\n");
|
|
|
|
rec->no_buildid = true;
|
|
|
|
}
|
|
|
|
|
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);
|
|
|
|
|
2019-12-03 19:45:27 +08:00
|
|
|
if (rec->opts.affinity != PERF_AFFINITY_SYS) {
|
|
|
|
rec->affinity_mask.nbits = cpu__max_cpu();
|
|
|
|
rec->affinity_mask.bits = bitmap_alloc(rec->affinity_mask.nbits);
|
|
|
|
if (!rec->affinity_mask.bits) {
|
|
|
|
pr_err("Failed to allocate thread mask for %zd cpus\n", rec->affinity_mask.nbits);
|
|
|
|
return -ENOMEM;
|
|
|
|
}
|
|
|
|
pr_debug2("thread mask[%zd]: empty\n", rec->affinity_mask.nbits);
|
|
|
|
}
|
|
|
|
|
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;
|
|
|
|
|
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;
|
|
|
|
|
2019-07-21 19:24:28 +08:00
|
|
|
if (rec->evlist->core.nr_entries == 0 &&
|
2020-06-17 20:16:20 +08:00
|
|
|
__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;
|
|
|
|
|
2020-05-12 20:19:18 +08:00
|
|
|
if (rec->opts.text_poke) {
|
|
|
|
err = record__config_text_poke(rec->evlist);
|
|
|
|
if (err) {
|
|
|
|
pr_err("record__config_text_poke failed, error %d\n", err);
|
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
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;
|
2019-03-19 01:43:35 +08:00
|
|
|
pr_debug("nr_cblocks: %d\n", rec->opts.nr_cblocks);
|
2018-11-06 17:04:58 +08:00
|
|
|
|
2019-01-23 01:47:43 +08:00
|
|
|
pr_debug("affinity: %s\n", affinity_tags[rec->opts.affinity]);
|
perf record: Implement --mmap-flush=<number> option
Implement a --mmap-flush option that specifies minimal number of bytes
that is extracted from mmaped kernel buffer to store into a trace. The
default option value is 1 byte what means every time trace writing
thread finds some new data in the mmaped buffer the data is extracted,
possibly compressed and written to a trace.
$ tools/perf/perf record --mmap-flush 1024 -e cycles -- matrix.gcc
$ tools/perf/perf record --aio --mmap-flush 1K -e cycles -- matrix.gcc
The option is independent from -z setting, doesn't vary with compression
level and can serve two purposes.
The first purpose is to increase the compression ratio of a trace data.
Larger data chunks are compressed more effectively so the implemented
option allows specifying data chunk size to compress. Also at some cases
executing more write syscalls with smaller data size can take longer
than executing less write syscalls with bigger data size due to syscall
overhead so extracting bigger data chunks specified by the option value
could additionally decrease runtime overhead.
The second purpose is to avoid self monitoring live-lock issue in system
wide (-a) profiling mode. Profiling in system wide mode with compression
(-a -z) can additionally induce data into the kernel buffers along with
the data from monitored processes. If performance data rate and volume
from the monitored processes is high then trace streaming and
compression activity in the tool is also high. High tool process
activity can lead to subtle live-lock effect when compression of single
new byte from some of mmaped kernel buffer leads to generation of the
next single byte at some mmaped buffer. So perf tool process ends up in
endless self monitoring.
Implemented synch parameter is the mean to force data move independently
from the specified flush threshold value. Despite the provided flush
value the tool needs capability to unconditionally drain memory buffers,
at least in the end of the collection.
Committer testing:
Running with the default value, i.e. as soon as there is something to
read go on consuming, we first write the synthesized events, small
chunks of about 128 bytes:
# perf trace -m 2048 --call-graph dwarf -e write -- perf record
<SNIP>
101.142 ( 0.004 ms): perf/25821 write(fd: 3</root/perf.data>, buf: 0x210db60, count: 120) = 120
__libc_write (/usr/lib64/libpthread-2.28.so)
ion (/home/acme/bin/perf)
record__write (inlined)
process_synthesized_event (/home/acme/bin/perf)
perf_tool__process_synth_event (inlined)
perf_event__synthesize_mmap_events (/home/acme/bin/perf)
Then we move to reading the mmap buffers consuming the events put there
by the kernel perf infrastructure:
107.561 ( 0.005 ms): perf/25821 write(fd: 3</root/perf.data>, buf: 0x7f1befc02000, count: 336) = 336
__libc_write (/usr/lib64/libpthread-2.28.so)
ion (/home/acme/bin/perf)
record__write (inlined)
record__pushfn (/home/acme/bin/perf)
perf_mmap__push (/home/acme/bin/perf)
record__mmap_read_evlist (inlined)
record__mmap_read_all (inlined)
__cmd_record (inlined)
cmd_record (/home/acme/bin/perf)
12919.953 ( 0.136 ms): perf/25821 write(fd: 3</root/perf.data>, buf: 0x7f1befc83150, count: 184984) = 184984
<SNIP same backtrace as in the 107.561 timestamp>
12920.094 ( 0.155 ms): perf/25821 write(fd: 3</root/perf.data>, buf: 0x7f1befc02150, count: 261816) = 261816
<SNIP same backtrace as in the 107.561 timestamp>
12920.253 ( 0.093 ms): perf/25821 write(fd: 3</root/perf.data>, buf: 0x7f1befb81120, count: 170832) = 170832
<SNIP same backtrace as in the 107.561 timestamp>
If we limit it to write only when more than 16MB are available for
reading, it throttles that to a quarter of the --mmap-pages set for
'perf record', which by default get to 528384 bytes, found out using
'record -v':
mmap flush: 132096
mmap size 528384B
With that in place all the writes coming from
record__mmap_read_evlist(), i.e. from the mmap buffers setup by the
kernel perf infrastructure were at least 132096 bytes long.
Trying with a bigger mmap size:
perf trace -e write perf record -v -m 2048 --mmap-flush 16M
74982.928 ( 2.471 ms): perf/26500 write(fd: 3</root/perf.data>, buf: 0x7ff94a6cc000, count: 3580888) = 3580888
74985.406 ( 2.353 ms): perf/26500 write(fd: 3</root/perf.data>, buf: 0x7ff949ecb000, count: 3453256) = 3453256
74987.764 ( 2.629 ms): perf/26500 write(fd: 3</root/perf.data>, buf: 0x7ff9496ca000, count: 3859232) = 3859232
74990.399 ( 2.341 ms): perf/26500 write(fd: 3</root/perf.data>, buf: 0x7ff948ec9000, count: 3769032) = 3769032
74992.744 ( 2.064 ms): perf/26500 write(fd: 3</root/perf.data>, buf: 0x7ff9486c8000, count: 3310520) = 3310520
74994.814 ( 2.619 ms): perf/26500 write(fd: 3</root/perf.data>, buf: 0x7ff947ec7000, count: 4194688) = 4194688
74997.439 ( 2.787 ms): perf/26500 write(fd: 3</root/perf.data>, buf: 0x7ff9476c6000, count: 4029760) = 4029760
Was again limited to a quarter of the mmap size:
mmap flush: 2098176
mmap size 8392704B
A warning about that would be good to have but can be added later,
something like:
"max flush is a quarter of the mmap size, if wanting to bump the mmap
flush further, bump the mmap size as well using -m/--mmap-pages"
Also rename the 'sync' parameters to 'synch' to keep tools/perf building
with older glibcs:
cc1: warnings being treated as errors
builtin-record.c: In function 'record__mmap_read_evlist':
builtin-record.c:775: warning: declaration of 'sync' shadows a global declaration
/usr/include/unistd.h:933: warning: shadowed declaration is here
builtin-record.c: In function 'record__mmap_read_all':
builtin-record.c:856: warning: declaration of 'sync' shadows a global declaration
/usr/include/unistd.h:933: warning: shadowed declaration is here
Signed-off-by: Alexey Budankov <alexey.budankov@linux.intel.com>
Reviewed-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: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Link: http://lkml.kernel.org/r/f6600d72-ecfa-2eb7-7e51-f6954547d500@linux.intel.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2019-03-19 01:40:26 +08:00
|
|
|
pr_debug("mmap flush: %d\n", rec->opts.mmap_flush);
|
2019-01-23 01:47:43 +08:00
|
|
|
|
2019-03-19 01:42:19 +08:00
|
|
|
if (rec->opts.comp_level > comp_level_max)
|
|
|
|
rec->opts.comp_level = comp_level_max;
|
|
|
|
pr_debug("comp level: %d\n", rec->opts.comp_level);
|
|
|
|
|
2011-11-25 18:19:45 +08:00
|
|
|
err = __cmd_record(&record, argc, argv);
|
2016-09-23 22:38:36 +08:00
|
|
|
out:
|
2019-12-03 19:45:27 +08:00
|
|
|
bitmap_free(rec->affinity_mask.bits);
|
2019-07-21 19:23:56 +08:00
|
|
|
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);
|
|
|
|
}
|