aboutsummaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
Diffstat (limited to 'tools')
-rw-r--r--tools/perf/Documentation/perf-annotate.txt37
-rw-r--r--tools/perf/Documentation/perf-buildid-list.txt3
-rw-r--r--tools/perf/Documentation/perf-diff.txt19
-rw-r--r--tools/perf/Documentation/perf-kvm.txt8
-rw-r--r--tools/perf/Documentation/perf-lock.txt15
-rw-r--r--tools/perf/Documentation/perf-probe.txt2
-rw-r--r--tools/perf/Documentation/perf-record.txt17
-rw-r--r--tools/perf/Documentation/perf-report.txt49
-rw-r--r--tools/perf/Documentation/perf-sched.txt18
-rw-r--r--tools/perf/Documentation/perf-script-perl.txt (renamed from tools/perf/Documentation/perf-trace-perl.txt)28
-rw-r--r--tools/perf/Documentation/perf-script-python.txt (renamed from tools/perf/Documentation/perf-trace-python.txt)88
-rw-r--r--tools/perf/Documentation/perf-script.txt (renamed from tools/perf/Documentation/perf-trace.txt)61
-rw-r--r--tools/perf/Documentation/perf-stat.txt44
-rw-r--r--tools/perf/Documentation/perf-test.txt2
-rw-r--r--tools/perf/Documentation/perf-top.txt28
-rw-r--r--tools/perf/MANIFEST1
-rw-r--r--tools/perf/Makefile17
-rw-r--r--tools/perf/bench/mem-memcpy-arch.h12
-rw-r--r--tools/perf/bench/mem-memcpy-x86-64-asm-def.h4
-rw-r--r--tools/perf/bench/mem-memcpy-x86-64-asm.S2
-rw-r--r--tools/perf/bench/mem-memcpy.c219
-rw-r--r--tools/perf/builtin-diff.c2
-rw-r--r--tools/perf/builtin-lock.c6
-rw-r--r--tools/perf/builtin-record.c16
-rw-r--r--tools/perf/builtin-sched.c6
-rw-r--r--tools/perf/builtin-script.c (renamed from tools/perf/builtin-trace.c)73
-rw-r--r--tools/perf/builtin-stat.c325
-rw-r--r--tools/perf/builtin-top.c6
-rw-r--r--tools/perf/builtin.h2
-rw-r--r--tools/perf/command-list.txt2
-rw-r--r--tools/perf/feature-tests.mak4
-rw-r--r--tools/perf/perf.c2
-rw-r--r--tools/perf/scripts/python/Perf-Trace-Util/Context.c2
-rw-r--r--tools/perf/util/debug.c42
-rw-r--r--tools/perf/util/debug.h2
-rw-r--r--tools/perf/util/event.c2
-rw-r--r--tools/perf/util/header.c11
-rw-r--r--tools/perf/util/header.h1
-rw-r--r--tools/perf/util/include/asm/cpufeature.h9
-rw-r--r--tools/perf/util/include/asm/dwarf2.h11
-rw-r--r--tools/perf/util/include/linux/bitops.h5
-rw-r--r--tools/perf/util/include/linux/linkage.h13
-rw-r--r--tools/perf/util/parse-events.c12
-rw-r--r--tools/perf/util/probe-finder.h6
-rw-r--r--tools/perf/util/scripting-engines/trace-event-perl.c6
-rw-r--r--tools/perf/util/scripting-engines/trace-event-python.c4
-rw-r--r--tools/perf/util/session.c295
-rw-r--r--tools/perf/util/session.h8
-rw-r--r--tools/perf/util/symbol.c2
-rw-r--r--tools/perf/util/ui/util.c16
50 files changed, 1113 insertions, 452 deletions
diff --git a/tools/perf/Documentation/perf-annotate.txt b/tools/perf/Documentation/perf-annotate.txt
index b2c63309a651..6f5a498608b2 100644
--- a/tools/perf/Documentation/perf-annotate.txt
+++ b/tools/perf/Documentation/perf-annotate.txt
@@ -24,12 +24,47 @@ OPTIONS
24--input=:: 24--input=::
25 Input file name. (default: perf.data) 25 Input file name. (default: perf.data)
26 26
27-d::
28--dsos=<dso[,dso...]>::
29 Only consider symbols in these dsos.
30-s::
31--symbol=<symbol>::
32 Symbol to annotate.
33
34-f::
35--force::
36 Don't complain, do it.
37
38-v::
39--verbose::
40 Be more verbose. (Show symbol address, etc)
41
42-D::
43--dump-raw-trace::
44 Dump raw trace in ASCII.
45
46-k::
47--vmlinux=<file>::
48 vmlinux pathname.
49
50-m::
51--modules::
52 Load module symbols. WARNING: use only with -k and LIVE kernel.
53
54-l::
55--print-line::
56 Print matching source lines (may be slow).
57
58-P::
59--full-paths::
60 Don't shorten the displayed pathnames.
61
27--stdio:: Use the stdio interface. 62--stdio:: Use the stdio interface.
28 63
29--tui:: Use the TUI interface Use of --tui requires a tty, if one is not 64--tui:: Use the TUI interface Use of --tui requires a tty, if one is not
30 present, as when piping to other commands, the stdio interface is 65 present, as when piping to other commands, the stdio interface is
31 used. This interfaces starts by centering on the line with more 66 used. This interfaces starts by centering on the line with more
32 samples, TAB/UNTAB cycles thru the lines with more samples. 67 samples, TAB/UNTAB cycles through the lines with more samples.
33 68
34SEE ALSO 69SEE ALSO
35-------- 70--------
diff --git a/tools/perf/Documentation/perf-buildid-list.txt b/tools/perf/Documentation/perf-buildid-list.txt
index 01b642c0bf8f..5eaac6f26d51 100644
--- a/tools/perf/Documentation/perf-buildid-list.txt
+++ b/tools/perf/Documentation/perf-buildid-list.txt
@@ -18,6 +18,9 @@ perf report.
18 18
19OPTIONS 19OPTIONS
20------- 20-------
21-H::
22--with-hits::
23 Show only DSOs with hits.
21-i:: 24-i::
22--input=:: 25--input=::
23 Input file name. (default: perf.data) 26 Input file name. (default: perf.data)
diff --git a/tools/perf/Documentation/perf-diff.txt b/tools/perf/Documentation/perf-diff.txt
index 20d97d84ea1c..6a9ec2b35310 100644
--- a/tools/perf/Documentation/perf-diff.txt
+++ b/tools/perf/Documentation/perf-diff.txt
@@ -19,6 +19,18 @@ If no parameters are passed it will assume perf.data.old and perf.data.
19 19
20OPTIONS 20OPTIONS
21------- 21-------
22-M::
23--displacement::
24 Show position displacement relative to baseline.
25
26-D::
27--dump-raw-trace::
28 Dump raw trace in ASCII.
29
30-m::
31--modules::
32 Load module symbols. WARNING: use only with -k and LIVE kernel
33
22-d:: 34-d::
23--dsos=:: 35--dsos=::
24 Only consider symbols in these dsos. CSV that understands 36 Only consider symbols in these dsos. CSV that understands
@@ -42,7 +54,7 @@ OPTIONS
42--field-separator=:: 54--field-separator=::
43 55
44 Use a special separator character and don't pad with spaces, replacing 56 Use a special separator character and don't pad with spaces, replacing
45 all occurances of this separator in symbol names (and other output) 57 all occurrences of this separator in symbol names (and other output)
46 with a '.' character, that thus it's the only non valid separator. 58 with a '.' character, that thus it's the only non valid separator.
47 59
48-v:: 60-v::
@@ -50,6 +62,11 @@ OPTIONS
50 Be verbose, for instance, show the raw counts in addition to the 62 Be verbose, for instance, show the raw counts in addition to the
51 diff. 63 diff.
52 64
65-f::
66--force::
67 Don't complain, do it.
68
69
53SEE ALSO 70SEE ALSO
54-------- 71--------
55linkperf:perf-record[1] 72linkperf:perf-record[1]
diff --git a/tools/perf/Documentation/perf-kvm.txt b/tools/perf/Documentation/perf-kvm.txt
index d004e19fe6d6..dd84cb2f0a88 100644
--- a/tools/perf/Documentation/perf-kvm.txt
+++ b/tools/perf/Documentation/perf-kvm.txt
@@ -22,7 +22,7 @@ There are a couple of variants of perf kvm:
22 a performance counter profile of guest os in realtime 22 a performance counter profile of guest os in realtime
23 of an arbitrary workload. 23 of an arbitrary workload.
24 24
25 'perf kvm record <command>' to record the performance couinter profile 25 'perf kvm record <command>' to record the performance counter profile
26 of an arbitrary workload and save it into a perf data file. If both 26 of an arbitrary workload and save it into a perf data file. If both
27 --host and --guest are input, the perf data file name is perf.data.kvm. 27 --host and --guest are input, the perf data file name is perf.data.kvm.
28 If there is no --host but --guest, the file name is perf.data.guest. 28 If there is no --host but --guest, the file name is perf.data.guest.
@@ -40,6 +40,12 @@ There are a couple of variants of perf kvm:
40 40
41OPTIONS 41OPTIONS
42------- 42-------
43-i::
44--input=::
45 Input file name.
46-o::
47--output::
48 Output file name.
43--host=:: 49--host=::
44 Collect host side performance profile. 50 Collect host side performance profile.
45--guest=:: 51--guest=::
diff --git a/tools/perf/Documentation/perf-lock.txt b/tools/perf/Documentation/perf-lock.txt
index b317102138c8..921de259ea10 100644
--- a/tools/perf/Documentation/perf-lock.txt
+++ b/tools/perf/Documentation/perf-lock.txt
@@ -24,6 +24,21 @@ and statistics with this 'perf lock' command.
24 24
25 'perf lock report' reports statistical data. 25 'perf lock report' reports statistical data.
26 26
27OPTIONS
28-------
29
30-i::
31--input=<file>::
32 Input file name.
33
34-v::
35--verbose::
36 Be more verbose (show symbol address, etc).
37
38-D::
39--dump-raw-trace::
40 Dump raw trace in ASCII.
41
27SEE ALSO 42SEE ALSO
28-------- 43--------
29linkperf:perf[1] 44linkperf:perf[1]
diff --git a/tools/perf/Documentation/perf-probe.txt b/tools/perf/Documentation/perf-probe.txt
index 62de1b7f4e76..4e2323276984 100644
--- a/tools/perf/Documentation/perf-probe.txt
+++ b/tools/perf/Documentation/perf-probe.txt
@@ -115,7 +115,7 @@ Each probe argument follows below syntax.
115 115
116LINE SYNTAX 116LINE SYNTAX
117----------- 117-----------
118Line range is descripted by following syntax. 118Line range is described by following syntax.
119 119
120 "FUNC[:RLN[+NUM|-RLN2]]|SRC:ALN[+NUM|-ALN2]" 120 "FUNC[:RLN[+NUM|-RLN2]]|SRC:ALN[+NUM|-ALN2]"
121 121
diff --git a/tools/perf/Documentation/perf-record.txt b/tools/perf/Documentation/perf-record.txt
index a91f9f9e6e5c..0ad1bc75ab49 100644
--- a/tools/perf/Documentation/perf-record.txt
+++ b/tools/perf/Documentation/perf-record.txt
@@ -39,15 +39,24 @@ OPTIONS
39 be passed as follows: '\mem:addr[:[r][w][x]]'. 39 be passed as follows: '\mem:addr[:[r][w][x]]'.
40 If you want to profile read-write accesses in 0x1000, just set 40 If you want to profile read-write accesses in 0x1000, just set
41 'mem:0x1000:rw'. 41 'mem:0x1000:rw'.
42
43--filter=<filter>::
44 Event filter.
45
42-a:: 46-a::
43 System-wide collection. 47--all-cpus::
48 System-wide collection from all CPUs.
44 49
45-l:: 50-l::
46 Scale counter values. 51 Scale counter values.
47 52
48-p:: 53-p::
49--pid=:: 54--pid=::
50 Record events on existing pid. 55 Record events on existing process ID.
56
57-t::
58--tid=::
59 Record events on existing thread ID.
51 60
52-r:: 61-r::
53--realtime=:: 62--realtime=::
@@ -109,8 +118,8 @@ Collect raw sample records from all opened counters (default for tracepoint coun
109 118
110-C:: 119-C::
111--cpu:: 120--cpu::
112Collect samples only on the list of cpus provided. Multiple CPUs can be provided as a 121Collect samples only on the list of CPUs provided. Multiple CPUs can be provided as a
113comma-sperated list with no space: 0,1. Ranges of CPUs are specified with -: 0-2. 122comma-separated list with no space: 0,1. Ranges of CPUs are specified with -: 0-2.
114In per-thread mode with inheritance mode on (default), samples are captured only when 123In per-thread mode with inheritance mode on (default), samples are captured only when
115the thread executes on the designated CPUs. Default is to monitor all CPUs. 124the thread executes on the designated CPUs. Default is to monitor all CPUs.
116 125
diff --git a/tools/perf/Documentation/perf-report.txt b/tools/perf/Documentation/perf-report.txt
index 12052c9ed0ba..59a1f57f2bb7 100644
--- a/tools/perf/Documentation/perf-report.txt
+++ b/tools/perf/Documentation/perf-report.txt
@@ -20,6 +20,11 @@ OPTIONS
20-i:: 20-i::
21--input=:: 21--input=::
22 Input file name. (default: perf.data) 22 Input file name. (default: perf.data)
23
24-v::
25--verbose::
26 Be more verbose. (show symbol address, etc)
27
23-d:: 28-d::
24--dsos=:: 29--dsos=::
25 Only consider symbols in these dsos. CSV that understands 30 Only consider symbols in these dsos. CSV that understands
@@ -27,6 +32,10 @@ OPTIONS
27-n:: 32-n::
28--show-nr-samples:: 33--show-nr-samples::
29 Show the number of samples for each symbol 34 Show the number of samples for each symbol
35
36--showcpuutilization::
37 Show sample percentage for different cpu modes.
38
30-T:: 39-T::
31--threads:: 40--threads::
32 Show per-thread event counters 41 Show per-thread event counters
@@ -39,12 +48,24 @@ OPTIONS
39 Only consider these symbols. CSV that understands 48 Only consider these symbols. CSV that understands
40 file://filename entries. 49 file://filename entries.
41 50
51-U::
52--hide-unresolved::
53 Only display entries resolved to a symbol.
54
42-s:: 55-s::
43--sort=:: 56--sort=::
44 Sort by key(s): pid, comm, dso, symbol, parent. 57 Sort by key(s): pid, comm, dso, symbol, parent.
45 58
59-p::
60--parent=<regex>::
61 regex filter to identify parent, see: '--sort parent'
62
63-x::
64--exclude-other::
65 Only display entries with parent-match.
66
46-w:: 67-w::
47--field-width=:: 68--column-widths=<width[,width...]>::
48 Force each column width to the provided list, for large terminal 69 Force each column width to the provided list, for large terminal
49 readability. 70 readability.
50 71
@@ -52,19 +73,26 @@ OPTIONS
52--field-separator=:: 73--field-separator=::
53 74
54 Use a special separator character and don't pad with spaces, replacing 75 Use a special separator character and don't pad with spaces, replacing
55 all occurances of this separator in symbol names (and other output) 76 all occurrences of this separator in symbol names (and other output)
56 with a '.' character, that thus it's the only non valid separator. 77 with a '.' character, that thus it's the only non valid separator.
57 78
79-D::
80--dump-raw-trace::
81 Dump raw trace in ASCII.
82
58-g [type,min]:: 83-g [type,min]::
59--call-graph:: 84--call-graph::
60 Display callchains using type and min percent threshold. 85 Display call chains using type and min percent threshold.
61 type can be either: 86 type can be either:
62 - flat: single column, linear exposure of callchains. 87 - flat: single column, linear exposure of call chains.
63 - graph: use a graph tree, displaying absolute overhead rates. 88 - graph: use a graph tree, displaying absolute overhead rates.
64 - fractal: like graph, but displays relative rates. Each branch of 89 - fractal: like graph, but displays relative rates. Each branch of
65 the tree is considered as a new profiled object. + 90 the tree is considered as a new profiled object. +
66 Default: fractal,0.5. 91 Default: fractal,0.5.
67 92
93--pretty=<key>::
94 Pretty printing style. key: normal, raw
95
68--stdio:: Use the stdio interface. 96--stdio:: Use the stdio interface.
69 97
70--tui:: Use the TUI interface, that is integrated with annotate and allows 98--tui:: Use the TUI interface, that is integrated with annotate and allows
@@ -72,6 +100,19 @@ OPTIONS
72 requires a tty, if one is not present, as when piping to other 100 requires a tty, if one is not present, as when piping to other
73 commands, the stdio interface is used. 101 commands, the stdio interface is used.
74 102
103-k::
104--vmlinux=<file>::
105 vmlinux pathname
106
107-m::
108--modules::
109 Load module symbols. WARNING: This should only be used with -k and
110 a LIVE kernel.
111
112-f::
113--force::
114 Don't complain, do it.
115
75SEE ALSO 116SEE ALSO
76-------- 117--------
77linkperf:perf-stat[1] 118linkperf:perf-stat[1]
diff --git a/tools/perf/Documentation/perf-sched.txt b/tools/perf/Documentation/perf-sched.txt
index 8417644a6166..46822d5fde1c 100644
--- a/tools/perf/Documentation/perf-sched.txt
+++ b/tools/perf/Documentation/perf-sched.txt
@@ -8,11 +8,11 @@ perf-sched - Tool to trace/measure scheduler properties (latencies)
8SYNOPSIS 8SYNOPSIS
9-------- 9--------
10[verse] 10[verse]
11'perf sched' {record|latency|replay|trace} 11'perf sched' {record|latency|map|replay|trace}
12 12
13DESCRIPTION 13DESCRIPTION
14----------- 14-----------
15There are four variants of perf sched: 15There are five variants of perf sched:
16 16
17 'perf sched record <command>' to record the scheduling events 17 'perf sched record <command>' to record the scheduling events
18 of an arbitrary workload. 18 of an arbitrary workload.
@@ -30,8 +30,22 @@ There are four variants of perf sched:
30 of the workload as it occurred when it was recorded - and can repeat 30 of the workload as it occurred when it was recorded - and can repeat
31 it a number of times, measuring its performance.) 31 it a number of times, measuring its performance.)
32 32
33 'perf sched map' to print a textual context-switching outline of
34 workload captured via perf sched record. Columns stand for
35 individual CPUs, and the two-letter shortcuts stand for tasks that
36 are running on a CPU. A '*' denotes the CPU that had the event, and
37 a dot signals an idle CPU.
38
33OPTIONS 39OPTIONS
34------- 40-------
41-i::
42--input=<file>::
43 Input file name. (default: perf.data)
44
45-v::
46--verbose::
47 Be more verbose. (show symbol address, etc)
48
35-D:: 49-D::
36--dump-raw-trace=:: 50--dump-raw-trace=::
37 Display verbose dump of the sched data. 51 Display verbose dump of the sched data.
diff --git a/tools/perf/Documentation/perf-trace-perl.txt b/tools/perf/Documentation/perf-script-perl.txt
index ee6525ee6d69..5bb41e55a3ac 100644
--- a/tools/perf/Documentation/perf-trace-perl.txt
+++ b/tools/perf/Documentation/perf-script-perl.txt
@@ -1,19 +1,19 @@
1perf-trace-perl(1) 1perf-script-perl(1)
2================== 2==================
3 3
4NAME 4NAME
5---- 5----
6perf-trace-perl - Process trace data with a Perl script 6perf-script-perl - Process trace data with a Perl script
7 7
8SYNOPSIS 8SYNOPSIS
9-------- 9--------
10[verse] 10[verse]
11'perf trace' [-s [Perl]:script[.pl] ] 11'perf script' [-s [Perl]:script[.pl] ]
12 12
13DESCRIPTION 13DESCRIPTION
14----------- 14-----------
15 15
16This perf trace option is used to process perf trace data using perf's 16This perf script option is used to process perf script data using perf's
17built-in Perl interpreter. It reads and processes the input file and 17built-in Perl interpreter. It reads and processes the input file and
18displays the results of the trace analysis implemented in the given 18displays the results of the trace analysis implemented in the given
19Perl script, if any. 19Perl script, if any.
@@ -21,7 +21,7 @@ Perl script, if any.
21STARTER SCRIPTS 21STARTER SCRIPTS
22--------------- 22---------------
23 23
24You can avoid reading the rest of this document by running 'perf trace 24You can avoid reading the rest of this document by running 'perf script
25-g perl' in the same directory as an existing perf.data trace file. 25-g perl' in the same directory as an existing perf.data trace file.
26That will generate a starter script containing a handler for each of 26That will generate a starter script containing a handler for each of
27the event types in the trace file; it simply prints every available 27the event types in the trace file; it simply prints every available
@@ -30,13 +30,13 @@ field for each event in the trace file.
30You can also look at the existing scripts in 30You can also look at the existing scripts in
31~/libexec/perf-core/scripts/perl for typical examples showing how to 31~/libexec/perf-core/scripts/perl for typical examples showing how to
32do basic things like aggregate event data, print results, etc. Also, 32do basic things like aggregate event data, print results, etc. Also,
33the check-perf-trace.pl script, while not interesting for its results, 33the check-perf-script.pl script, while not interesting for its results,
34attempts to exercise all of the main scripting features. 34attempts to exercise all of the main scripting features.
35 35
36EVENT HANDLERS 36EVENT HANDLERS
37-------------- 37--------------
38 38
39When perf trace is invoked using a trace script, a user-defined 39When perf script is invoked using a trace script, a user-defined
40'handler function' is called for each event in the trace. If there's 40'handler function' is called for each event in the trace. If there's
41no handler function defined for a given event type, the event is 41no handler function defined for a given event type, the event is
42ignored (or passed to a 'trace_handled' function, see below) and the 42ignored (or passed to a 'trace_handled' function, see below) and the
@@ -112,13 +112,13 @@ write a useful trace script. The sections below cover the rest.
112SCRIPT LAYOUT 112SCRIPT LAYOUT
113------------- 113-------------
114 114
115Every perf trace Perl script should start by setting up a Perl module 115Every perf script Perl script should start by setting up a Perl module
116search path and 'use'ing a few support modules (see module 116search path and 'use'ing a few support modules (see module
117descriptions below): 117descriptions below):
118 118
119---- 119----
120 use lib "$ENV{'PERF_EXEC_PATH'}/scripts/perl/Perf-Trace-Util/lib"; 120 use lib "$ENV{'PERF_EXEC_PATH'}/scripts/perl/perf-script-Util/lib";
121 use lib "./Perf-Trace-Util/lib"; 121 use lib "./perf-script-Util/lib";
122 use Perf::Trace::Core; 122 use Perf::Trace::Core;
123 use Perf::Trace::Context; 123 use Perf::Trace::Context;
124 use Perf::Trace::Util; 124 use Perf::Trace::Util;
@@ -162,7 +162,7 @@ sub trace_unhandled
162---- 162----
163 163
164The remaining sections provide descriptions of each of the available 164The remaining sections provide descriptions of each of the available
165built-in perf trace Perl modules and their associated functions. 165built-in perf script Perl modules and their associated functions.
166 166
167AVAILABLE MODULES AND FUNCTIONS 167AVAILABLE MODULES AND FUNCTIONS
168------------------------------- 168-------------------------------
@@ -170,7 +170,7 @@ AVAILABLE MODULES AND FUNCTIONS
170The following sections describe the functions and variables available 170The following sections describe the functions and variables available
171via the various Perf::Trace::* Perl modules. To use the functions and 171via the various Perf::Trace::* Perl modules. To use the functions and
172variables from the given module, add the corresponding 'use 172variables from the given module, add the corresponding 'use
173Perf::Trace::XXX' line to your perf trace script. 173Perf::Trace::XXX' line to your perf script script.
174 174
175Perf::Trace::Core Module 175Perf::Trace::Core Module
176~~~~~~~~~~~~~~~~~~~~~~~~ 176~~~~~~~~~~~~~~~~~~~~~~~~
@@ -204,7 +204,7 @@ argument.
204Perf::Trace::Util Module 204Perf::Trace::Util Module
205~~~~~~~~~~~~~~~~~~~~~~~~ 205~~~~~~~~~~~~~~~~~~~~~~~~
206 206
207Various utility functions for use with perf trace: 207Various utility functions for use with perf script:
208 208
209 nsecs($secs, $nsecs) - returns total nsecs given secs/nsecs pair 209 nsecs($secs, $nsecs) - returns total nsecs given secs/nsecs pair
210 nsecs_secs($nsecs) - returns whole secs portion given nsecs 210 nsecs_secs($nsecs) - returns whole secs portion given nsecs
@@ -214,4 +214,4 @@ Various utility functions for use with perf trace:
214 214
215SEE ALSO 215SEE ALSO
216-------- 216--------
217linkperf:perf-trace[1] 217linkperf:perf-script[1]
diff --git a/tools/perf/Documentation/perf-trace-python.txt b/tools/perf/Documentation/perf-script-python.txt
index 693be804dd3d..36b38277422c 100644
--- a/tools/perf/Documentation/perf-trace-python.txt
+++ b/tools/perf/Documentation/perf-script-python.txt
@@ -1,19 +1,19 @@
1perf-trace-python(1) 1perf-script-python(1)
2==================== 2====================
3 3
4NAME 4NAME
5---- 5----
6perf-trace-python - Process trace data with a Python script 6perf-script-python - Process trace data with a Python script
7 7
8SYNOPSIS 8SYNOPSIS
9-------- 9--------
10[verse] 10[verse]
11'perf trace' [-s [Python]:script[.py] ] 11'perf script' [-s [Python]:script[.py] ]
12 12
13DESCRIPTION 13DESCRIPTION
14----------- 14-----------
15 15
16This perf trace option is used to process perf trace data using perf's 16This perf script option is used to process perf script data using perf's
17built-in Python interpreter. It reads and processes the input file and 17built-in Python interpreter. It reads and processes the input file and
18displays the results of the trace analysis implemented in the given 18displays the results of the trace analysis implemented in the given
19Python script, if any. 19Python script, if any.
@@ -23,15 +23,15 @@ A QUICK EXAMPLE
23 23
24This section shows the process, start to finish, of creating a working 24This section shows the process, start to finish, of creating a working
25Python script that aggregates and extracts useful information from a 25Python script that aggregates and extracts useful information from a
26raw perf trace stream. You can avoid reading the rest of this 26raw perf script stream. You can avoid reading the rest of this
27document if an example is enough for you; the rest of the document 27document if an example is enough for you; the rest of the document
28provides more details on each step and lists the library functions 28provides more details on each step and lists the library functions
29available to script writers. 29available to script writers.
30 30
31This example actually details the steps that were used to create the 31This example actually details the steps that were used to create the
32'syscall-counts' script you see when you list the available perf trace 32'syscall-counts' script you see when you list the available perf script
33scripts via 'perf trace -l'. As such, this script also shows how to 33scripts via 'perf script -l'. As such, this script also shows how to
34integrate your script into the list of general-purpose 'perf trace' 34integrate your script into the list of general-purpose 'perf script'
35scripts listed by that command. 35scripts listed by that command.
36 36
37The syscall-counts script is a simple script, but demonstrates all the 37The syscall-counts script is a simple script, but demonstrates all the
@@ -105,31 +105,31 @@ That single stream will be recorded in a file in the current directory
105called perf.data. 105called perf.data.
106 106
107Once we have a perf.data file containing our data, we can use the -g 107Once we have a perf.data file containing our data, we can use the -g
108'perf trace' option to generate a Python script that will contain a 108'perf script' option to generate a Python script that will contain a
109callback handler for each event type found in the perf.data trace 109callback handler for each event type found in the perf.data trace
110stream (for more details, see the STARTER SCRIPTS section). 110stream (for more details, see the STARTER SCRIPTS section).
111 111
112---- 112----
113# perf trace -g python 113# perf script -g python
114generated Python script: perf-trace.py 114generated Python script: perf-script.py
115 115
116The output file created also in the current directory is named 116The output file created also in the current directory is named
117perf-trace.py. Here's the file in its entirety: 117perf-script.py. Here's the file in its entirety:
118 118
119# perf trace event handlers, generated by perf trace -g python 119# perf script event handlers, generated by perf script -g python
120# Licensed under the terms of the GNU GPL License version 2 120# Licensed under the terms of the GNU GPL License version 2
121 121
122# The common_* event handler fields are the most useful fields common to 122# The common_* event handler fields are the most useful fields common to
123# all events. They don't necessarily correspond to the 'common_*' fields 123# all events. They don't necessarily correspond to the 'common_*' fields
124# in the format files. Those fields not available as handler params can 124# in the format files. Those fields not available as handler params can
125# be retrieved using Python functions of the form common_*(context). 125# be retrieved using Python functions of the form common_*(context).
126# See the perf-trace-python Documentation for the list of available functions. 126# See the perf-script-python Documentation for the list of available functions.
127 127
128import os 128import os
129import sys 129import sys
130 130
131sys.path.append(os.environ['PERF_EXEC_PATH'] + \ 131sys.path.append(os.environ['PERF_EXEC_PATH'] + \
132 '/scripts/python/Perf-Trace-Util/lib/Perf/Trace') 132 '/scripts/python/perf-script-Util/lib/Perf/Trace')
133 133
134from perf_trace_context import * 134from perf_trace_context import *
135from Core import * 135from Core import *
@@ -160,7 +160,7 @@ def print_header(event_name, cpu, secs, nsecs, pid, comm):
160---- 160----
161 161
162At the top is a comment block followed by some import statements and a 162At the top is a comment block followed by some import statements and a
163path append which every perf trace script should include. 163path append which every perf script script should include.
164 164
165Following that are a couple generated functions, trace_begin() and 165Following that are a couple generated functions, trace_begin() and
166trace_end(), which are called at the beginning and the end of the 166trace_end(), which are called at the beginning and the end of the
@@ -189,8 +189,8 @@ simply a utility function used for that purpose. Let's rename the
189script and run it to see the default output: 189script and run it to see the default output:
190 190
191---- 191----
192# mv perf-trace.py syscall-counts.py 192# mv perf-script.py syscall-counts.py
193# perf trace -s syscall-counts.py 193# perf script -s syscall-counts.py
194 194
195raw_syscalls__sys_enter 1 00840.847582083 7506 perf id=1, args= 195raw_syscalls__sys_enter 1 00840.847582083 7506 perf id=1, args=
196raw_syscalls__sys_enter 1 00840.847595764 7506 perf id=1, args= 196raw_syscalls__sys_enter 1 00840.847595764 7506 perf id=1, args=
@@ -216,7 +216,7 @@ import os
216import sys 216import sys
217 217
218sys.path.append(os.environ['PERF_EXEC_PATH'] + \ 218sys.path.append(os.environ['PERF_EXEC_PATH'] + \
219 '/scripts/python/Perf-Trace-Util/lib/Perf/Trace') 219 '/scripts/python/perf-script-Util/lib/Perf/Trace')
220 220
221from perf_trace_context import * 221from perf_trace_context import *
222from Core import * 222from Core import *
@@ -279,7 +279,7 @@ import os
279import sys 279import sys
280 280
281sys.path.append(os.environ['PERF_EXEC_PATH'] + \ 281sys.path.append(os.environ['PERF_EXEC_PATH'] + \
282 '/scripts/python/Perf-Trace-Util/lib/Perf/Trace') 282 '/scripts/python/perf-script-Util/lib/Perf/Trace')
283 283
284from perf_trace_context import * 284from perf_trace_context import *
285from Core import * 285from Core import *
@@ -315,7 +315,7 @@ def print_syscall_totals():
315 315
316The script can be run just as before: 316The script can be run just as before:
317 317
318 # perf trace -s syscall-counts.py 318 # perf script -s syscall-counts.py
319 319
320So those are the essential steps in writing and running a script. The 320So those are the essential steps in writing and running a script. The
321process can be generalized to any tracepoint or set of tracepoints 321process can be generalized to any tracepoint or set of tracepoints
@@ -324,17 +324,17 @@ interested in by looking at the list of available events shown by
324'perf list' and/or look in /sys/kernel/debug/tracing events for 324'perf list' and/or look in /sys/kernel/debug/tracing events for
325detailed event and field info, record the corresponding trace data 325detailed event and field info, record the corresponding trace data
326using 'perf record', passing it the list of interesting events, 326using 'perf record', passing it the list of interesting events,
327generate a skeleton script using 'perf trace -g python' and modify the 327generate a skeleton script using 'perf script -g python' and modify the
328code to aggregate and display it for your particular needs. 328code to aggregate and display it for your particular needs.
329 329
330After you've done that you may end up with a general-purpose script 330After you've done that you may end up with a general-purpose script
331that you want to keep around and have available for future use. By 331that you want to keep around and have available for future use. By
332writing a couple of very simple shell scripts and putting them in the 332writing a couple of very simple shell scripts and putting them in the
333right place, you can have your script listed alongside the other 333right place, you can have your script listed alongside the other
334scripts listed by the 'perf trace -l' command e.g.: 334scripts listed by the 'perf script -l' command e.g.:
335 335
336---- 336----
337root@tropicana:~# perf trace -l 337root@tropicana:~# perf script -l
338List of available trace scripts: 338List of available trace scripts:
339 workqueue-stats workqueue stats (ins/exe/create/destroy) 339 workqueue-stats workqueue stats (ins/exe/create/destroy)
340 wakeup-latency system-wide min/max/avg wakeup latency 340 wakeup-latency system-wide min/max/avg wakeup latency
@@ -365,14 +365,14 @@ perf record -a -e raw_syscalls:sys_enter
365The 'report' script is also a shell script with the same base name as 365The 'report' script is also a shell script with the same base name as
366your script, but with -report appended. It should also be located in 366your script, but with -report appended. It should also be located in
367the perf/scripts/python/bin directory. In that script, you write the 367the perf/scripts/python/bin directory. In that script, you write the
368'perf trace -s' command-line needed for running your script: 368'perf script -s' command-line needed for running your script:
369 369
370---- 370----
371# cat kernel-source/tools/perf/scripts/python/bin/syscall-counts-report 371# cat kernel-source/tools/perf/scripts/python/bin/syscall-counts-report
372 372
373#!/bin/bash 373#!/bin/bash
374# description: system-wide syscall counts 374# description: system-wide syscall counts
375perf trace -s ~/libexec/perf-core/scripts/python/syscall-counts.py 375perf script -s ~/libexec/perf-core/scripts/python/syscall-counts.py
376---- 376----
377 377
378Note that the location of the Python script given in the shell script 378Note that the location of the Python script given in the shell script
@@ -390,17 +390,17 @@ total 32
390drwxr-xr-x 4 trz trz 4096 2010-01-26 22:30 . 390drwxr-xr-x 4 trz trz 4096 2010-01-26 22:30 .
391drwxr-xr-x 4 trz trz 4096 2010-01-26 22:29 .. 391drwxr-xr-x 4 trz trz 4096 2010-01-26 22:29 ..
392drwxr-xr-x 2 trz trz 4096 2010-01-26 22:29 bin 392drwxr-xr-x 2 trz trz 4096 2010-01-26 22:29 bin
393-rw-r--r-- 1 trz trz 2548 2010-01-26 22:29 check-perf-trace.py 393-rw-r--r-- 1 trz trz 2548 2010-01-26 22:29 check-perf-script.py
394drwxr-xr-x 3 trz trz 4096 2010-01-26 22:49 Perf-Trace-Util 394drwxr-xr-x 3 trz trz 4096 2010-01-26 22:49 perf-script-Util
395-rw-r--r-- 1 trz trz 1462 2010-01-26 22:30 syscall-counts.py 395-rw-r--r-- 1 trz trz 1462 2010-01-26 22:30 syscall-counts.py
396---- 396----
397 397
398Once you've done that (don't forget to do a new 'make install', 398Once you've done that (don't forget to do a new 'make install',
399otherwise your script won't show up at run-time), 'perf trace -l' 399otherwise your script won't show up at run-time), 'perf script -l'
400should show a new entry for your script: 400should show a new entry for your script:
401 401
402---- 402----
403root@tropicana:~# perf trace -l 403root@tropicana:~# perf script -l
404List of available trace scripts: 404List of available trace scripts:
405 workqueue-stats workqueue stats (ins/exe/create/destroy) 405 workqueue-stats workqueue stats (ins/exe/create/destroy)
406 wakeup-latency system-wide min/max/avg wakeup latency 406 wakeup-latency system-wide min/max/avg wakeup latency
@@ -409,19 +409,19 @@ List of available trace scripts:
409 syscall-counts system-wide syscall counts 409 syscall-counts system-wide syscall counts
410---- 410----
411 411
412You can now perform the record step via 'perf trace record': 412You can now perform the record step via 'perf script record':
413 413
414 # perf trace record syscall-counts 414 # perf script record syscall-counts
415 415
416and display the output using 'perf trace report': 416and display the output using 'perf script report':
417 417
418 # perf trace report syscall-counts 418 # perf script report syscall-counts
419 419
420STARTER SCRIPTS 420STARTER SCRIPTS
421--------------- 421---------------
422 422
423You can quickly get started writing a script for a particular set of 423You can quickly get started writing a script for a particular set of
424trace data by generating a skeleton script using 'perf trace -g 424trace data by generating a skeleton script using 'perf script -g
425python' in the same directory as an existing perf.data trace file. 425python' in the same directory as an existing perf.data trace file.
426That will generate a starter script containing a handler for each of 426That will generate a starter script containing a handler for each of
427the event types in the trace file; it simply prints every available 427the event types in the trace file; it simply prints every available
@@ -430,13 +430,13 @@ field for each event in the trace file.
430You can also look at the existing scripts in 430You can also look at the existing scripts in
431~/libexec/perf-core/scripts/python for typical examples showing how to 431~/libexec/perf-core/scripts/python for typical examples showing how to
432do basic things like aggregate event data, print results, etc. Also, 432do basic things like aggregate event data, print results, etc. Also,
433the check-perf-trace.py script, while not interesting for its results, 433the check-perf-script.py script, while not interesting for its results,
434attempts to exercise all of the main scripting features. 434attempts to exercise all of the main scripting features.
435 435
436EVENT HANDLERS 436EVENT HANDLERS
437-------------- 437--------------
438 438
439When perf trace is invoked using a trace script, a user-defined 439When perf script is invoked using a trace script, a user-defined
440'handler function' is called for each event in the trace. If there's 440'handler function' is called for each event in the trace. If there's
441no handler function defined for a given event type, the event is 441no handler function defined for a given event type, the event is
442ignored (or passed to a 'trace_handled' function, see below) and the 442ignored (or passed to a 'trace_handled' function, see below) and the
@@ -510,7 +510,7 @@ write a useful trace script. The sections below cover the rest.
510SCRIPT LAYOUT 510SCRIPT LAYOUT
511------------- 511-------------
512 512
513Every perf trace Python script should start by setting up a Python 513Every perf script Python script should start by setting up a Python
514module search path and 'import'ing a few support modules (see module 514module search path and 'import'ing a few support modules (see module
515descriptions below): 515descriptions below):
516 516
@@ -519,7 +519,7 @@ descriptions below):
519 import sys 519 import sys
520 520
521 sys.path.append(os.environ['PERF_EXEC_PATH'] + \ 521 sys.path.append(os.environ['PERF_EXEC_PATH'] + \
522 '/scripts/python/Perf-Trace-Util/lib/Perf/Trace') 522 '/scripts/python/perf-script-Util/lib/Perf/Trace')
523 523
524 from perf_trace_context import * 524 from perf_trace_context import *
525 from Core import * 525 from Core import *
@@ -559,15 +559,15 @@ def trace_unhandled(event_name, context, common_cpu, common_secs,
559---- 559----
560 560
561The remaining sections provide descriptions of each of the available 561The remaining sections provide descriptions of each of the available
562built-in perf trace Python modules and their associated functions. 562built-in perf script Python modules and their associated functions.
563 563
564AVAILABLE MODULES AND FUNCTIONS 564AVAILABLE MODULES AND FUNCTIONS
565------------------------------- 565-------------------------------
566 566
567The following sections describe the functions and variables available 567The following sections describe the functions and variables available
568via the various perf trace Python modules. To use the functions and 568via the various perf script Python modules. To use the functions and
569variables from the given module, add the corresponding 'from XXXX 569variables from the given module, add the corresponding 'from XXXX
570import' line to your perf trace script. 570import' line to your perf script script.
571 571
572Core.py Module 572Core.py Module
573~~~~~~~~~~~~~~ 573~~~~~~~~~~~~~~
@@ -610,7 +610,7 @@ argument.
610Util.py Module 610Util.py Module
611~~~~~~~~~~~~~~ 611~~~~~~~~~~~~~~
612 612
613Various utility functions for use with perf trace: 613Various utility functions for use with perf script:
614 614
615 nsecs(secs, nsecs) - returns total nsecs given secs/nsecs pair 615 nsecs(secs, nsecs) - returns total nsecs given secs/nsecs pair
616 nsecs_secs(nsecs) - returns whole secs portion given nsecs 616 nsecs_secs(nsecs) - returns whole secs portion given nsecs
@@ -620,4 +620,4 @@ Various utility functions for use with perf trace:
620 620
621SEE ALSO 621SEE ALSO
622-------- 622--------
623linkperf:perf-trace[1] 623linkperf:perf-script[1]
diff --git a/tools/perf/Documentation/perf-trace.txt b/tools/perf/Documentation/perf-script.txt
index 26aff6bf9e50..29ad94293cd2 100644
--- a/tools/perf/Documentation/perf-trace.txt
+++ b/tools/perf/Documentation/perf-script.txt
@@ -1,71 +1,71 @@
1perf-trace(1) 1perf-script(1)
2============= 2=============
3 3
4NAME 4NAME
5---- 5----
6perf-trace - Read perf.data (created by perf record) and display trace output 6perf-script - Read perf.data (created by perf record) and display trace output
7 7
8SYNOPSIS 8SYNOPSIS
9-------- 9--------
10[verse] 10[verse]
11'perf trace' [<options>] 11'perf script' [<options>]
12'perf trace' [<options>] record <script> [<record-options>] <command> 12'perf script' [<options>] record <script> [<record-options>] <command>
13'perf trace' [<options>] report <script> [script-args] 13'perf script' [<options>] report <script> [script-args]
14'perf trace' [<options>] <script> <required-script-args> [<record-options>] <command> 14'perf script' [<options>] <script> <required-script-args> [<record-options>] <command>
15'perf trace' [<options>] <top-script> [script-args] 15'perf script' [<options>] <top-script> [script-args]
16 16
17DESCRIPTION 17DESCRIPTION
18----------- 18-----------
19This command reads the input file and displays the trace recorded. 19This command reads the input file and displays the trace recorded.
20 20
21There are several variants of perf trace: 21There are several variants of perf script:
22 22
23 'perf trace' to see a detailed trace of the workload that was 23 'perf script' to see a detailed trace of the workload that was
24 recorded. 24 recorded.
25 25
26 You can also run a set of pre-canned scripts that aggregate and 26 You can also run a set of pre-canned scripts that aggregate and
27 summarize the raw trace data in various ways (the list of scripts is 27 summarize the raw trace data in various ways (the list of scripts is
28 available via 'perf trace -l'). The following variants allow you to 28 available via 'perf script -l'). The following variants allow you to
29 record and run those scripts: 29 record and run those scripts:
30 30
31 'perf trace record <script> <command>' to record the events required 31 'perf script record <script> <command>' to record the events required
32 for 'perf trace report'. <script> is the name displayed in the 32 for 'perf script report'. <script> is the name displayed in the
33 output of 'perf trace --list' i.e. the actual script name minus any 33 output of 'perf script --list' i.e. the actual script name minus any
34 language extension. If <command> is not specified, the events are 34 language extension. If <command> is not specified, the events are
35 recorded using the -a (system-wide) 'perf record' option. 35 recorded using the -a (system-wide) 'perf record' option.
36 36
37 'perf trace report <script> [args]' to run and display the results 37 'perf script report <script> [args]' to run and display the results
38 of <script>. <script> is the name displayed in the output of 'perf 38 of <script>. <script> is the name displayed in the output of 'perf
39 trace --list' i.e. the actual script name minus any language 39 trace --list' i.e. the actual script name minus any language
40 extension. The perf.data output from a previous run of 'perf trace 40 extension. The perf.data output from a previous run of 'perf script
41 record <script>' is used and should be present for this command to 41 record <script>' is used and should be present for this command to
42 succeed. [args] refers to the (mainly optional) args expected by 42 succeed. [args] refers to the (mainly optional) args expected by
43 the script. 43 the script.
44 44
45 'perf trace <script> <required-script-args> <command>' to both 45 'perf script <script> <required-script-args> <command>' to both
46 record the events required for <script> and to run the <script> 46 record the events required for <script> and to run the <script>
47 using 'live-mode' i.e. without writing anything to disk. <script> 47 using 'live-mode' i.e. without writing anything to disk. <script>
48 is the name displayed in the output of 'perf trace --list' i.e. the 48 is the name displayed in the output of 'perf script --list' i.e. the
49 actual script name minus any language extension. If <command> is 49 actual script name minus any language extension. If <command> is
50 not specified, the events are recorded using the -a (system-wide) 50 not specified, the events are recorded using the -a (system-wide)
51 'perf record' option. If <script> has any required args, they 51 'perf record' option. If <script> has any required args, they
52 should be specified before <command>. This mode doesn't allow for 52 should be specified before <command>. This mode doesn't allow for
53 optional script args to be specified; if optional script args are 53 optional script args to be specified; if optional script args are
54 desired, they can be specified using separate 'perf trace record' 54 desired, they can be specified using separate 'perf script record'
55 and 'perf trace report' commands, with the stdout of the record step 55 and 'perf script report' commands, with the stdout of the record step
56 piped to the stdin of the report script, using the '-o -' and '-i -' 56 piped to the stdin of the report script, using the '-o -' and '-i -'
57 options of the corresponding commands. 57 options of the corresponding commands.
58 58
59 'perf trace <top-script>' to both record the events required for 59 'perf script <top-script>' to both record the events required for
60 <top-script> and to run the <top-script> using 'live-mode' 60 <top-script> and to run the <top-script> using 'live-mode'
61 i.e. without writing anything to disk. <top-script> is the name 61 i.e. without writing anything to disk. <top-script> is the name
62 displayed in the output of 'perf trace --list' i.e. the actual 62 displayed in the output of 'perf script --list' i.e. the actual
63 script name minus any language extension; a <top-script> is defined 63 script name minus any language extension; a <top-script> is defined
64 as any script name ending with the string 'top'. 64 as any script name ending with the string 'top'.
65 65
66 [<record-options>] can be passed to the record steps of 'perf trace 66 [<record-options>] can be passed to the record steps of 'perf script
67 record' and 'live-mode' variants; this isn't possible however for 67 record' and 'live-mode' variants; this isn't possible however for
68 <top-script> 'live-mode' or 'perf trace report' variants. 68 <top-script> 'live-mode' or 'perf script report' variants.
69 69
70 See the 'SEE ALSO' section for links to language-specific 70 See the 'SEE ALSO' section for links to language-specific
71 information on how to write and run your own trace scripts. 71 information on how to write and run your own trace scripts.
@@ -76,7 +76,7 @@ OPTIONS
76 Any command you can specify in a shell. 76 Any command you can specify in a shell.
77 77
78-D:: 78-D::
79--dump-raw-trace=:: 79--dump-raw-script=::
80 Display verbose dump of the trace data. 80 Display verbose dump of the trace data.
81 81
82-L:: 82-L::
@@ -95,7 +95,7 @@ OPTIONS
95 95
96-g:: 96-g::
97--gen-script=:: 97--gen-script=::
98 Generate perf-trace.[ext] starter script for given language, 98 Generate perf-script.[ext] starter script for given language,
99 using current perf.data. 99 using current perf.data.
100 100
101-a:: 101-a::
@@ -104,8 +104,15 @@ OPTIONS
104 normally don't - this option allows the latter to be run in 104 normally don't - this option allows the latter to be run in
105 system-wide mode. 105 system-wide mode.
106 106
107-i::
108--input=::
109 Input file name.
110
111-d::
112--debug-mode::
113 Do various checks like samples ordering and lost events.
107 114
108SEE ALSO 115SEE ALSO
109-------- 116--------
110linkperf:perf-record[1], linkperf:perf-trace-perl[1], 117linkperf:perf-record[1], linkperf:perf-script-perl[1],
111linkperf:perf-trace-python[1] 118linkperf:perf-script-python[1]
diff --git a/tools/perf/Documentation/perf-stat.txt b/tools/perf/Documentation/perf-stat.txt
index 4b3a2d46b437..b6da7affbbee 100644
--- a/tools/perf/Documentation/perf-stat.txt
+++ b/tools/perf/Documentation/perf-stat.txt
@@ -8,8 +8,8 @@ perf-stat - Run a command and gather performance counter statistics
8SYNOPSIS 8SYNOPSIS
9-------- 9--------
10[verse] 10[verse]
11'perf stat' [-e <EVENT> | --event=EVENT] [-S] [-a] <command> 11'perf stat' [-e <EVENT> | --event=EVENT] [-a] <command>
12'perf stat' [-e <EVENT> | --event=EVENT] [-S] [-a] -- <command> [<options>] 12'perf stat' [-e <EVENT> | --event=EVENT] [-a] -- <command> [<options>]
13 13
14DESCRIPTION 14DESCRIPTION
15----------- 15-----------
@@ -35,24 +35,54 @@ OPTIONS
35 child tasks do not inherit counters 35 child tasks do not inherit counters
36-p:: 36-p::
37--pid=<pid>:: 37--pid=<pid>::
38 stat events on existing pid 38 stat events on existing process id
39
40-t::
41--tid=<tid>::
42 stat events on existing thread id
43
39 44
40-a:: 45-a::
41 system-wide collection 46--all-cpus::
47 system-wide collection from all CPUs
42 48
43-c:: 49-c::
44 scale counter values 50--scale::
51 scale/normalize counter values
52
53-r::
54--repeat=<n>::
55 repeat command and print average + stddev (max: 100)
45 56
46-B:: 57-B::
58--big-num::
47 print large numbers with thousands' separators according to locale 59 print large numbers with thousands' separators according to locale
48 60
49-C:: 61-C::
50--cpu=:: 62--cpu=::
51Count only on the list of cpus provided. Multiple CPUs can be provided as a 63Count only on the list of CPUs provided. Multiple CPUs can be provided as a
52comma-sperated list with no space: 0,1. Ranges of CPUs are specified with -: 0-2. 64comma-separated list with no space: 0,1. Ranges of CPUs are specified with -: 0-2.
53In per-thread mode, this option is ignored. The -a option is still necessary 65In per-thread mode, this option is ignored. The -a option is still necessary
54to activate system-wide monitoring. Default is to count on all CPUs. 66to activate system-wide monitoring. Default is to count on all CPUs.
55 67
68-A::
69--no-aggr::
70Do not aggregate counts across all monitored CPUs in system-wide mode (-a).
71This option is only valid in system-wide mode.
72
73-n::
74--null::
75 null run - don't start any counters
76
77-v::
78--verbose::
79 be more verbose (show counter open errors, etc)
80
81-x SEP::
82--field-separator SEP::
83print counts using a CSV-style output to make it easy to import directly into
84spreadsheets. Columns are separated by the string specified in SEP.
85
56EXAMPLES 86EXAMPLES
57-------- 87--------
58 88
diff --git a/tools/perf/Documentation/perf-test.txt b/tools/perf/Documentation/perf-test.txt
index 1c4b5f5b7f71..2c3b462f64b0 100644
--- a/tools/perf/Documentation/perf-test.txt
+++ b/tools/perf/Documentation/perf-test.txt
@@ -12,7 +12,7 @@ SYNOPSIS
12 12
13DESCRIPTION 13DESCRIPTION
14----------- 14-----------
15This command does assorted sanity tests, initially thru linked routines but 15This command does assorted sanity tests, initially through linked routines but
16also will look for a directory with more tests in the form of scripts. 16also will look for a directory with more tests in the form of scripts.
17 17
18OPTIONS 18OPTIONS
diff --git a/tools/perf/Documentation/perf-top.txt b/tools/perf/Documentation/perf-top.txt
index 1f9687663f2a..f6eb1cdafb77 100644
--- a/tools/perf/Documentation/perf-top.txt
+++ b/tools/perf/Documentation/perf-top.txt
@@ -12,7 +12,7 @@ SYNOPSIS
12 12
13DESCRIPTION 13DESCRIPTION
14----------- 14-----------
15This command generates and displays a performance counter profile in realtime. 15This command generates and displays a performance counter profile in real time.
16 16
17 17
18OPTIONS 18OPTIONS
@@ -27,8 +27,8 @@ OPTIONS
27 27
28-C <cpu-list>:: 28-C <cpu-list>::
29--cpu=<cpu>:: 29--cpu=<cpu>::
30Monitor only on the list of cpus provided. Multiple CPUs can be provided as a 30Monitor only on the list of CPUs provided. Multiple CPUs can be provided as a
31comma-sperated list with no space: 0,1. Ranges of CPUs are specified with -: 0-2. 31comma-separated list with no space: 0,1. Ranges of CPUs are specified with -: 0-2.
32Default is to monitor all CPUS. 32Default is to monitor all CPUS.
33 33
34-d <seconds>:: 34-d <seconds>::
@@ -50,6 +50,10 @@ Default is to monitor all CPUS.
50--count-filter=<count>:: 50--count-filter=<count>::
51 Only display functions with more events than this. 51 Only display functions with more events than this.
52 52
53-g::
54--group::
55 Put the counters into a counter group.
56
53-F <freq>:: 57-F <freq>::
54--freq=<freq>:: 58--freq=<freq>::
55 Profile at this frequency. 59 Profile at this frequency.
@@ -68,7 +72,11 @@ Default is to monitor all CPUS.
68 72
69-p <pid>:: 73-p <pid>::
70--pid=<pid>:: 74--pid=<pid>::
71 Profile events on existing pid. 75 Profile events on existing Process ID.
76
77-t <tid>::
78--tid=<tid>::
79 Profile events on existing thread ID.
72 80
73-r <priority>:: 81-r <priority>::
74--realtime=<priority>:: 82--realtime=<priority>::
@@ -78,6 +86,18 @@ Default is to monitor all CPUS.
78--sym-annotate=<symbol>:: 86--sym-annotate=<symbol>::
79 Annotate this symbol. 87 Annotate this symbol.
80 88
89-K::
90--hide_kernel_symbols::
91 Hide kernel symbols.
92
93-U::
94--hide_user_symbols::
95 Hide user symbols.
96
97-D::
98--dump-symtab::
99 Dump the symbol table used for profiling.
100
81-v:: 101-v::
82--verbose:: 102--verbose::
83 Be more verbose (show counter open errors, etc). 103 Be more verbose (show counter open errors, etc).
diff --git a/tools/perf/MANIFEST b/tools/perf/MANIFEST
index 8c7fc0c8f0b8..c12659d8cb26 100644
--- a/tools/perf/MANIFEST
+++ b/tools/perf/MANIFEST
@@ -7,6 +7,7 @@ include/linux/stringify.h
7lib/rbtree.c 7lib/rbtree.c
8include/linux/swab.h 8include/linux/swab.h
9arch/*/include/asm/unistd*.h 9arch/*/include/asm/unistd*.h
10arch/*/lib/memcpy*.S
10include/linux/poison.h 11include/linux/poison.h
11include/linux/magic.h 12include/linux/magic.h
12include/linux/hw_breakpoint.h 13include/linux/hw_breakpoint.h
diff --git a/tools/perf/Makefile b/tools/perf/Makefile
index d1db0f676a4b..d88137a4356e 100644
--- a/tools/perf/Makefile
+++ b/tools/perf/Makefile
@@ -185,7 +185,10 @@ ifeq ($(ARCH),i386)
185 ARCH := x86 185 ARCH := x86
186endif 186endif
187ifeq ($(ARCH),x86_64) 187ifeq ($(ARCH),x86_64)
188 RAW_ARCH := x86_64
188 ARCH := x86 189 ARCH := x86
190 ARCH_CFLAGS := -DARCH_X86_64
191 ARCH_INCLUDE = ../../arch/x86/lib/memcpy_64.S
189endif 192endif
190 193
191# CFLAGS and LDFLAGS are for the users to override from the command line. 194# CFLAGS and LDFLAGS are for the users to override from the command line.
@@ -375,6 +378,7 @@ LIB_H += util/include/linux/prefetch.h
375LIB_H += util/include/linux/rbtree.h 378LIB_H += util/include/linux/rbtree.h
376LIB_H += util/include/linux/string.h 379LIB_H += util/include/linux/string.h
377LIB_H += util/include/linux/types.h 380LIB_H += util/include/linux/types.h
381LIB_H += util/include/linux/linkage.h
378LIB_H += util/include/asm/asm-offsets.h 382LIB_H += util/include/asm/asm-offsets.h
379LIB_H += util/include/asm/bug.h 383LIB_H += util/include/asm/bug.h
380LIB_H += util/include/asm/byteorder.h 384LIB_H += util/include/asm/byteorder.h
@@ -383,6 +387,8 @@ LIB_H += util/include/asm/swab.h
383LIB_H += util/include/asm/system.h 387LIB_H += util/include/asm/system.h
384LIB_H += util/include/asm/uaccess.h 388LIB_H += util/include/asm/uaccess.h
385LIB_H += util/include/dwarf-regs.h 389LIB_H += util/include/dwarf-regs.h
390LIB_H += util/include/asm/dwarf2.h
391LIB_H += util/include/asm/cpufeature.h
386LIB_H += perf.h 392LIB_H += perf.h
387LIB_H += util/cache.h 393LIB_H += util/cache.h
388LIB_H += util/callchain.h 394LIB_H += util/callchain.h
@@ -417,6 +423,7 @@ LIB_H += util/probe-finder.h
417LIB_H += util/probe-event.h 423LIB_H += util/probe-event.h
418LIB_H += util/pstack.h 424LIB_H += util/pstack.h
419LIB_H += util/cpumap.h 425LIB_H += util/cpumap.h
426LIB_H += $(ARCH_INCLUDE)
420 427
421LIB_OBJS += $(OUTPUT)util/abspath.o 428LIB_OBJS += $(OUTPUT)util/abspath.o
422LIB_OBJS += $(OUTPUT)util/alias.o 429LIB_OBJS += $(OUTPUT)util/alias.o
@@ -472,6 +479,9 @@ BUILTIN_OBJS += $(OUTPUT)builtin-bench.o
472# Benchmark modules 479# Benchmark modules
473BUILTIN_OBJS += $(OUTPUT)bench/sched-messaging.o 480BUILTIN_OBJS += $(OUTPUT)bench/sched-messaging.o
474BUILTIN_OBJS += $(OUTPUT)bench/sched-pipe.o 481BUILTIN_OBJS += $(OUTPUT)bench/sched-pipe.o
482ifeq ($(RAW_ARCH),x86_64)
483BUILTIN_OBJS += $(OUTPUT)bench/mem-memcpy-x86-64-asm.o
484endif
475BUILTIN_OBJS += $(OUTPUT)bench/mem-memcpy.o 485BUILTIN_OBJS += $(OUTPUT)bench/mem-memcpy.o
476 486
477BUILTIN_OBJS += $(OUTPUT)builtin-diff.o 487BUILTIN_OBJS += $(OUTPUT)builtin-diff.o
@@ -485,7 +495,7 @@ BUILTIN_OBJS += $(OUTPUT)builtin-report.o
485BUILTIN_OBJS += $(OUTPUT)builtin-stat.o 495BUILTIN_OBJS += $(OUTPUT)builtin-stat.o
486BUILTIN_OBJS += $(OUTPUT)builtin-timechart.o 496BUILTIN_OBJS += $(OUTPUT)builtin-timechart.o
487BUILTIN_OBJS += $(OUTPUT)builtin-top.o 497BUILTIN_OBJS += $(OUTPUT)builtin-top.o
488BUILTIN_OBJS += $(OUTPUT)builtin-trace.o 498BUILTIN_OBJS += $(OUTPUT)builtin-script.o
489BUILTIN_OBJS += $(OUTPUT)builtin-probe.o 499BUILTIN_OBJS += $(OUTPUT)builtin-probe.o
490BUILTIN_OBJS += $(OUTPUT)builtin-kmem.o 500BUILTIN_OBJS += $(OUTPUT)builtin-kmem.o
491BUILTIN_OBJS += $(OUTPUT)builtin-lock.o 501BUILTIN_OBJS += $(OUTPUT)builtin-lock.o
@@ -507,7 +517,7 @@ PERFLIBS = $(LIB_FILE)
507-include config.mak 517-include config.mak
508 518
509ifndef NO_DWARF 519ifndef NO_DWARF
510FLAGS_DWARF=$(ALL_CFLAGS) -I/usr/include/elfutils -ldw -lelf $(ALL_LDFLAGS) $(EXTLIBS) 520FLAGS_DWARF=$(ALL_CFLAGS) -ldw -lelf $(ALL_LDFLAGS) $(EXTLIBS)
511ifneq ($(call try-cc,$(SOURCE_DWARF),$(FLAGS_DWARF)),y) 521ifneq ($(call try-cc,$(SOURCE_DWARF),$(FLAGS_DWARF)),y)
512 msg := $(warning No libdw.h found or old libdw.h found or elfutils is older than 0.138, disables dwarf support. Please install new elfutils-devel/libdw-dev); 522 msg := $(warning No libdw.h found or old libdw.h found or elfutils is older than 0.138, disables dwarf support. Please install new elfutils-devel/libdw-dev);
513 NO_DWARF := 1 523 NO_DWARF := 1
@@ -554,7 +564,7 @@ ifndef NO_DWARF
554ifeq ($(origin PERF_HAVE_DWARF_REGS), undefined) 564ifeq ($(origin PERF_HAVE_DWARF_REGS), undefined)
555 msg := $(warning DWARF register mappings have not been defined for architecture $(ARCH), DWARF support disabled); 565 msg := $(warning DWARF register mappings have not been defined for architecture $(ARCH), DWARF support disabled);
556else 566else
557 BASIC_CFLAGS += -I/usr/include/elfutils -DDWARF_SUPPORT 567 BASIC_CFLAGS += -DDWARF_SUPPORT
558 EXTLIBS += -lelf -ldw 568 EXTLIBS += -lelf -ldw
559 LIB_OBJS += $(OUTPUT)util/probe-finder.o 569 LIB_OBJS += $(OUTPUT)util/probe-finder.o
560endif # PERF_HAVE_DWARF_REGS 570endif # PERF_HAVE_DWARF_REGS
@@ -898,6 +908,7 @@ BASIC_CFLAGS += -DSHA1_HEADER='$(SHA1_HEADER_SQ)' \
898LIB_OBJS += $(COMPAT_OBJS) 908LIB_OBJS += $(COMPAT_OBJS)
899 909
900ALL_CFLAGS += $(BASIC_CFLAGS) 910ALL_CFLAGS += $(BASIC_CFLAGS)
911ALL_CFLAGS += $(ARCH_CFLAGS)
901ALL_LDFLAGS += $(BASIC_LDFLAGS) 912ALL_LDFLAGS += $(BASIC_LDFLAGS)
902 913
903export TAR INSTALL DESTDIR SHELL_PATH 914export TAR INSTALL DESTDIR SHELL_PATH
diff --git a/tools/perf/bench/mem-memcpy-arch.h b/tools/perf/bench/mem-memcpy-arch.h
new file mode 100644
index 000000000000..a72e36cb5394
--- /dev/null
+++ b/tools/perf/bench/mem-memcpy-arch.h
@@ -0,0 +1,12 @@
1
2#ifdef ARCH_X86_64
3
4#define MEMCPY_FN(fn, name, desc) \
5 extern void *fn(void *, const void *, size_t);
6
7#include "mem-memcpy-x86-64-asm-def.h"
8
9#undef MEMCPY_FN
10
11#endif
12
diff --git a/tools/perf/bench/mem-memcpy-x86-64-asm-def.h b/tools/perf/bench/mem-memcpy-x86-64-asm-def.h
new file mode 100644
index 000000000000..d588b87696fc
--- /dev/null
+++ b/tools/perf/bench/mem-memcpy-x86-64-asm-def.h
@@ -0,0 +1,4 @@
1
2MEMCPY_FN(__memcpy,
3 "x86-64-unrolled",
4 "unrolled memcpy() in arch/x86/lib/memcpy_64.S")
diff --git a/tools/perf/bench/mem-memcpy-x86-64-asm.S b/tools/perf/bench/mem-memcpy-x86-64-asm.S
new file mode 100644
index 000000000000..a57b66e853c2
--- /dev/null
+++ b/tools/perf/bench/mem-memcpy-x86-64-asm.S
@@ -0,0 +1,2 @@
1
2#include "../../../arch/x86/lib/memcpy_64.S"
diff --git a/tools/perf/bench/mem-memcpy.c b/tools/perf/bench/mem-memcpy.c
index 38dae7465142..db82021f4b91 100644
--- a/tools/perf/bench/mem-memcpy.c
+++ b/tools/perf/bench/mem-memcpy.c
@@ -12,6 +12,7 @@
12#include "../util/parse-options.h" 12#include "../util/parse-options.h"
13#include "../util/header.h" 13#include "../util/header.h"
14#include "bench.h" 14#include "bench.h"
15#include "mem-memcpy-arch.h"
15 16
16#include <stdio.h> 17#include <stdio.h>
17#include <stdlib.h> 18#include <stdlib.h>
@@ -23,8 +24,10 @@
23 24
24static const char *length_str = "1MB"; 25static const char *length_str = "1MB";
25static const char *routine = "default"; 26static const char *routine = "default";
26static bool use_clock = false; 27static bool use_clock;
27static int clock_fd; 28static int clock_fd;
29static bool only_prefault;
30static bool no_prefault;
28 31
29static const struct option options[] = { 32static const struct option options[] = {
30 OPT_STRING('l', "length", &length_str, "1MB", 33 OPT_STRING('l', "length", &length_str, "1MB",
@@ -34,19 +37,33 @@ static const struct option options[] = {
34 "Specify routine to copy"), 37 "Specify routine to copy"),
35 OPT_BOOLEAN('c', "clock", &use_clock, 38 OPT_BOOLEAN('c', "clock", &use_clock,
36 "Use CPU clock for measuring"), 39 "Use CPU clock for measuring"),
40 OPT_BOOLEAN('o', "only-prefault", &only_prefault,
41 "Show only the result with page faults before memcpy()"),
42 OPT_BOOLEAN('n', "no-prefault", &no_prefault,
43 "Show only the result without page faults before memcpy()"),
37 OPT_END() 44 OPT_END()
38}; 45};
39 46
47typedef void *(*memcpy_t)(void *, const void *, size_t);
48
40struct routine { 49struct routine {
41 const char *name; 50 const char *name;
42 const char *desc; 51 const char *desc;
43 void * (*fn)(void *dst, const void *src, size_t len); 52 memcpy_t fn;
44}; 53};
45 54
46struct routine routines[] = { 55struct routine routines[] = {
47 { "default", 56 { "default",
48 "Default memcpy() provided by glibc", 57 "Default memcpy() provided by glibc",
49 memcpy }, 58 memcpy },
59#ifdef ARCH_X86_64
60
61#define MEMCPY_FN(fn, name, desc) { name, desc, fn },
62#include "mem-memcpy-x86-64-asm-def.h"
63#undef MEMCPY_FN
64
65#endif
66
50 { NULL, 67 { NULL,
51 NULL, 68 NULL,
52 NULL } 69 NULL }
@@ -89,29 +106,98 @@ static double timeval2double(struct timeval *ts)
89 (double)ts->tv_usec / (double)1000000; 106 (double)ts->tv_usec / (double)1000000;
90} 107}
91 108
109static void alloc_mem(void **dst, void **src, size_t length)
110{
111 *dst = zalloc(length);
112 if (!dst)
113 die("memory allocation failed - maybe length is too large?\n");
114
115 *src = zalloc(length);
116 if (!src)
117 die("memory allocation failed - maybe length is too large?\n");
118}
119
120static u64 do_memcpy_clock(memcpy_t fn, size_t len, bool prefault)
121{
122 u64 clock_start = 0ULL, clock_end = 0ULL;
123 void *src = NULL, *dst = NULL;
124
125 alloc_mem(&src, &dst, len);
126
127 if (prefault)
128 fn(dst, src, len);
129
130 clock_start = get_clock();
131 fn(dst, src, len);
132 clock_end = get_clock();
133
134 free(src);
135 free(dst);
136 return clock_end - clock_start;
137}
138
139static double do_memcpy_gettimeofday(memcpy_t fn, size_t len, bool prefault)
140{
141 struct timeval tv_start, tv_end, tv_diff;
142 void *src = NULL, *dst = NULL;
143
144 alloc_mem(&src, &dst, len);
145
146 if (prefault)
147 fn(dst, src, len);
148
149 BUG_ON(gettimeofday(&tv_start, NULL));
150 fn(dst, src, len);
151 BUG_ON(gettimeofday(&tv_end, NULL));
152
153 timersub(&tv_end, &tv_start, &tv_diff);
154
155 free(src);
156 free(dst);
157 return (double)((double)len / timeval2double(&tv_diff));
158}
159
160#define pf (no_prefault ? 0 : 1)
161
162#define print_bps(x) do { \
163 if (x < K) \
164 printf(" %14lf B/Sec", x); \
165 else if (x < K * K) \
166 printf(" %14lfd KB/Sec", x / K); \
167 else if (x < K * K * K) \
168 printf(" %14lf MB/Sec", x / K / K); \
169 else \
170 printf(" %14lf GB/Sec", x / K / K / K); \
171 } while (0)
172
92int bench_mem_memcpy(int argc, const char **argv, 173int bench_mem_memcpy(int argc, const char **argv,
93 const char *prefix __used) 174 const char *prefix __used)
94{ 175{
95 int i; 176 int i;
96 void *dst, *src; 177 size_t len;
97 size_t length; 178 double result_bps[2];
98 double bps = 0.0; 179 u64 result_clock[2];
99 struct timeval tv_start, tv_end, tv_diff;
100 u64 clock_start, clock_end, clock_diff;
101 180
102 clock_start = clock_end = clock_diff = 0ULL;
103 argc = parse_options(argc, argv, options, 181 argc = parse_options(argc, argv, options,
104 bench_mem_memcpy_usage, 0); 182 bench_mem_memcpy_usage, 0);
105 183
106 tv_diff.tv_sec = 0; 184 if (use_clock)
107 tv_diff.tv_usec = 0; 185 init_clock();
108 length = (size_t)perf_atoll((char *)length_str); 186
187 len = (size_t)perf_atoll((char *)length_str);
109 188
110 if ((s64)length <= 0) { 189 result_clock[0] = result_clock[1] = 0ULL;
190 result_bps[0] = result_bps[1] = 0.0;
191
192 if ((s64)len <= 0) {
111 fprintf(stderr, "Invalid length:%s\n", length_str); 193 fprintf(stderr, "Invalid length:%s\n", length_str);
112 return 1; 194 return 1;
113 } 195 }
114 196
197 /* same to without specifying either of prefault and no-prefault */
198 if (only_prefault && no_prefault)
199 only_prefault = no_prefault = false;
200
115 for (i = 0; routines[i].name; i++) { 201 for (i = 0; routines[i].name; i++) {
116 if (!strcmp(routines[i].name, routine)) 202 if (!strcmp(routines[i].name, routine))
117 break; 203 break;
@@ -126,61 +212,80 @@ int bench_mem_memcpy(int argc, const char **argv,
126 return 1; 212 return 1;
127 } 213 }
128 214
129 dst = zalloc(length); 215 if (bench_format == BENCH_FORMAT_DEFAULT)
130 if (!dst) 216 printf("# Copying %s Bytes ...\n\n", length_str);
131 die("memory allocation failed - maybe length is too large?\n");
132
133 src = zalloc(length);
134 if (!src)
135 die("memory allocation failed - maybe length is too large?\n");
136
137 if (bench_format == BENCH_FORMAT_DEFAULT) {
138 printf("# Copying %s Bytes from %p to %p ...\n\n",
139 length_str, src, dst);
140 }
141
142 if (use_clock) {
143 init_clock();
144 clock_start = get_clock();
145 } else {
146 BUG_ON(gettimeofday(&tv_start, NULL));
147 }
148
149 routines[i].fn(dst, src, length);
150 217
151 if (use_clock) { 218 if (!only_prefault && !no_prefault) {
152 clock_end = get_clock(); 219 /* show both of results */
153 clock_diff = clock_end - clock_start; 220 if (use_clock) {
221 result_clock[0] =
222 do_memcpy_clock(routines[i].fn, len, false);
223 result_clock[1] =
224 do_memcpy_clock(routines[i].fn, len, true);
225 } else {
226 result_bps[0] =
227 do_memcpy_gettimeofday(routines[i].fn,
228 len, false);
229 result_bps[1] =
230 do_memcpy_gettimeofday(routines[i].fn,
231 len, true);
232 }
154 } else { 233 } else {
155 BUG_ON(gettimeofday(&tv_end, NULL)); 234 if (use_clock) {
156 timersub(&tv_end, &tv_start, &tv_diff); 235 result_clock[pf] =
157 bps = (double)((double)length / timeval2double(&tv_diff)); 236 do_memcpy_clock(routines[i].fn,
237 len, only_prefault);
238 } else {
239 result_bps[pf] =
240 do_memcpy_gettimeofday(routines[i].fn,
241 len, only_prefault);
242 }
158 } 243 }
159 244
160 switch (bench_format) { 245 switch (bench_format) {
161 case BENCH_FORMAT_DEFAULT: 246 case BENCH_FORMAT_DEFAULT:
162 if (use_clock) { 247 if (!only_prefault && !no_prefault) {
163 printf(" %14lf Clock/Byte\n", 248 if (use_clock) {
164 (double)clock_diff / (double)length); 249 printf(" %14lf Clock/Byte\n",
165 } else { 250 (double)result_clock[0]
166 if (bps < K) 251 / (double)len);
167 printf(" %14lf B/Sec\n", bps); 252 printf(" %14lf Clock/Byte (with prefault)\n",
168 else if (bps < K * K) 253 (double)result_clock[1]
169 printf(" %14lfd KB/Sec\n", bps / 1024); 254 / (double)len);
170 else if (bps < K * K * K) 255 } else {
171 printf(" %14lf MB/Sec\n", bps / 1024 / 1024); 256 print_bps(result_bps[0]);
172 else { 257 printf("\n");
173 printf(" %14lf GB/Sec\n", 258 print_bps(result_bps[1]);
174 bps / 1024 / 1024 / 1024); 259 printf(" (with prefault)\n");
175 } 260 }
261 } else {
262 if (use_clock) {
263 printf(" %14lf Clock/Byte",
264 (double)result_clock[pf]
265 / (double)len);
266 } else
267 print_bps(result_bps[pf]);
268
269 printf("%s\n", only_prefault ? " (with prefault)" : "");
176 } 270 }
177 break; 271 break;
178 case BENCH_FORMAT_SIMPLE: 272 case BENCH_FORMAT_SIMPLE:
179 if (use_clock) { 273 if (!only_prefault && !no_prefault) {
180 printf("%14lf\n", 274 if (use_clock) {
181 (double)clock_diff / (double)length); 275 printf("%lf %lf\n",
182 } else 276 (double)result_clock[0] / (double)len,
183 printf("%lf\n", bps); 277 (double)result_clock[1] / (double)len);
278 } else {
279 printf("%lf %lf\n",
280 result_bps[0], result_bps[1]);
281 }
282 } else {
283 if (use_clock) {
284 printf("%lf\n", (double)result_clock[pf]
285 / (double)len);
286 } else
287 printf("%lf\n", result_bps[pf]);
288 }
184 break; 289 break;
185 default: 290 default:
186 /* reaching this means there's some disaster: */ 291 /* reaching this means there's some disaster: */
diff --git a/tools/perf/builtin-diff.c b/tools/perf/builtin-diff.c
index fca1d4402910..221b823bc26f 100644
--- a/tools/perf/builtin-diff.c
+++ b/tools/perf/builtin-diff.c
@@ -173,7 +173,7 @@ static const char * const diff_usage[] = {
173static const struct option options[] = { 173static const struct option options[] = {
174 OPT_INCR('v', "verbose", &verbose, 174 OPT_INCR('v', "verbose", &verbose,
175 "be more verbose (show symbol address, etc)"), 175 "be more verbose (show symbol address, etc)"),
176 OPT_BOOLEAN('m', "displacement", &show_displacement, 176 OPT_BOOLEAN('M', "displacement", &show_displacement,
177 "Show position displacement relative to baseline"), 177 "Show position displacement relative to baseline"),
178 OPT_BOOLEAN('D', "dump-raw-trace", &dump_trace, 178 OPT_BOOLEAN('D', "dump-raw-trace", &dump_trace,
179 "dump raw trace in ASCII"), 179 "dump raw trace in ASCII"),
diff --git a/tools/perf/builtin-lock.c b/tools/perf/builtin-lock.c
index 821c1586a22b..8452a2ae2191 100644
--- a/tools/perf/builtin-lock.c
+++ b/tools/perf/builtin-lock.c
@@ -982,9 +982,9 @@ int cmd_lock(int argc, const char **argv, const char *prefix __used)
982 usage_with_options(report_usage, report_options); 982 usage_with_options(report_usage, report_options);
983 } 983 }
984 __cmd_report(); 984 __cmd_report();
985 } else if (!strcmp(argv[0], "trace")) { 985 } else if (!strcmp(argv[0], "script")) {
986 /* Aliased to 'perf trace' */ 986 /* Aliased to 'perf script' */
987 return cmd_trace(argc, argv, prefix); 987 return cmd_script(argc, argv, prefix);
988 } else if (!strcmp(argv[0], "info")) { 988 } else if (!strcmp(argv[0], "info")) {
989 if (argc) { 989 if (argc) {
990 argc = parse_options(argc, argv, 990 argc = parse_options(argc, argv,
diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c
index e2c2de201eec..024e1441d76b 100644
--- a/tools/perf/builtin-record.c
+++ b/tools/perf/builtin-record.c
@@ -61,6 +61,7 @@ static bool inherit_stat = false;
61static bool no_samples = false; 61static bool no_samples = false;
62static bool sample_address = false; 62static bool sample_address = false;
63static bool no_buildid = false; 63static bool no_buildid = false;
64static bool no_buildid_cache = false;
64 65
65static long samples = 0; 66static long samples = 0;
66static u64 bytes_written = 0; 67static u64 bytes_written = 0;
@@ -326,7 +327,7 @@ try_again:
326 goto try_again; 327 goto try_again;
327 } 328 }
328 printf("\n"); 329 printf("\n");
329 error("perfcounter syscall returned with %d (%s)\n", 330 error("sys_perf_event_open() syscall returned with %d (%s). /bin/dmesg may provide additional information.\n",
330 fd[nr_cpu][counter][thread_index], strerror(err)); 331 fd[nr_cpu][counter][thread_index], strerror(err));
331 332
332#if defined(__i386__) || defined(__x86_64__) 333#if defined(__i386__) || defined(__x86_64__)
@@ -437,7 +438,8 @@ static void atexit_header(void)
437 if (!pipe_output) { 438 if (!pipe_output) {
438 session->header.data_size += bytes_written; 439 session->header.data_size += bytes_written;
439 440
440 process_buildids(); 441 if (!no_buildid)
442 process_buildids();
441 perf_header__write(&session->header, output, true); 443 perf_header__write(&session->header, output, true);
442 perf_session__delete(session); 444 perf_session__delete(session);
443 symbol__exit(); 445 symbol__exit();
@@ -557,6 +559,9 @@ static int __cmd_record(int argc, const char **argv)
557 return -1; 559 return -1;
558 } 560 }
559 561
562 if (!no_buildid)
563 perf_header__set_feat(&session->header, HEADER_BUILD_ID);
564
560 if (!file_new) { 565 if (!file_new) {
561 err = perf_header__read(session, output); 566 err = perf_header__read(session, output);
562 if (err < 0) 567 if (err < 0)
@@ -831,8 +836,10 @@ const struct option record_options[] = {
831 "Sample addresses"), 836 "Sample addresses"),
832 OPT_BOOLEAN('n', "no-samples", &no_samples, 837 OPT_BOOLEAN('n', "no-samples", &no_samples,
833 "don't sample"), 838 "don't sample"),
834 OPT_BOOLEAN('N', "no-buildid-cache", &no_buildid, 839 OPT_BOOLEAN('N', "no-buildid-cache", &no_buildid_cache,
835 "do not update the buildid cache"), 840 "do not update the buildid cache"),
841 OPT_BOOLEAN('B', "no-buildid", &no_buildid,
842 "do not collect buildids in perf.data"),
836 OPT_END() 843 OPT_END()
837}; 844};
838 845
@@ -857,7 +864,8 @@ int cmd_record(int argc, const char **argv, const char *prefix __used)
857 } 864 }
858 865
859 symbol__init(); 866 symbol__init();
860 if (no_buildid) 867
868 if (no_buildid_cache || no_buildid)
861 disable_buildid_cache(); 869 disable_buildid_cache();
862 870
863 if (!nr_counters) { 871 if (!nr_counters) {
diff --git a/tools/perf/builtin-sched.c b/tools/perf/builtin-sched.c
index 55f3b5dcc731..26523c939791 100644
--- a/tools/perf/builtin-sched.c
+++ b/tools/perf/builtin-sched.c
@@ -1888,10 +1888,10 @@ int cmd_sched(int argc, const char **argv, const char *prefix __used)
1888 usage_with_options(sched_usage, sched_options); 1888 usage_with_options(sched_usage, sched_options);
1889 1889
1890 /* 1890 /*
1891 * Aliased to 'perf trace' for now: 1891 * Aliased to 'perf script' for now:
1892 */ 1892 */
1893 if (!strcmp(argv[0], "trace")) 1893 if (!strcmp(argv[0], "script"))
1894 return cmd_trace(argc, argv, prefix); 1894 return cmd_script(argc, argv, prefix);
1895 1895
1896 symbol__init(); 1896 symbol__init();
1897 if (!strncmp(argv[0], "rec", 3)) { 1897 if (!strncmp(argv[0], "rec", 3)) {
diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-script.c
index 86cfe3800e6b..4539551ab40e 100644
--- a/tools/perf/builtin-trace.c
+++ b/tools/perf/builtin-script.c
@@ -56,7 +56,7 @@ static void setup_scripting(void)
56 56
57static int cleanup_scripting(void) 57static int cleanup_scripting(void)
58{ 58{
59 pr_debug("\nperf trace script stopped\n"); 59 pr_debug("\nperf script stopped\n");
60 60
61 return scripting_ops->stop_script(); 61 return scripting_ops->stop_script();
62} 62}
@@ -137,7 +137,7 @@ static void sig_handler(int sig __unused)
137 session_done = 1; 137 session_done = 1;
138} 138}
139 139
140static int __cmd_trace(struct perf_session *session) 140static int __cmd_script(struct perf_session *session)
141{ 141{
142 int ret; 142 int ret;
143 143
@@ -247,7 +247,7 @@ static void list_available_languages(void)
247 247
248 fprintf(stderr, "\n"); 248 fprintf(stderr, "\n");
249 fprintf(stderr, "Scripting language extensions (used in " 249 fprintf(stderr, "Scripting language extensions (used in "
250 "perf trace -s [spec:]script.[spec]):\n\n"); 250 "perf script -s [spec:]script.[spec]):\n\n");
251 251
252 list_for_each_entry(s, &script_specs, node) 252 list_for_each_entry(s, &script_specs, node)
253 fprintf(stderr, " %-42s [%s]\n", s->spec, s->ops->name); 253 fprintf(stderr, " %-42s [%s]\n", s->spec, s->ops->name);
@@ -301,17 +301,34 @@ static int parse_scriptname(const struct option *opt __used,
301 return 0; 301 return 0;
302} 302}
303 303
304#define for_each_lang(scripts_dir, lang_dirent, lang_next) \ 304/* Helper function for filesystems that return a dent->d_type DT_UNKNOWN */
305static int is_directory(const char *base_path, const struct dirent *dent)
306{
307 char path[PATH_MAX];
308 struct stat st;
309
310 sprintf(path, "%s/%s", base_path, dent->d_name);
311 if (stat(path, &st))
312 return 0;
313
314 return S_ISDIR(st.st_mode);
315}
316
317#define for_each_lang(scripts_path, scripts_dir, lang_dirent, lang_next)\
305 while (!readdir_r(scripts_dir, &lang_dirent, &lang_next) && \ 318 while (!readdir_r(scripts_dir, &lang_dirent, &lang_next) && \
306 lang_next) \ 319 lang_next) \
307 if (lang_dirent.d_type == DT_DIR && \ 320 if ((lang_dirent.d_type == DT_DIR || \
321 (lang_dirent.d_type == DT_UNKNOWN && \
322 is_directory(scripts_path, &lang_dirent))) && \
308 (strcmp(lang_dirent.d_name, ".")) && \ 323 (strcmp(lang_dirent.d_name, ".")) && \
309 (strcmp(lang_dirent.d_name, ".."))) 324 (strcmp(lang_dirent.d_name, "..")))
310 325
311#define for_each_script(lang_dir, script_dirent, script_next) \ 326#define for_each_script(lang_path, lang_dir, script_dirent, script_next)\
312 while (!readdir_r(lang_dir, &script_dirent, &script_next) && \ 327 while (!readdir_r(lang_dir, &script_dirent, &script_next) && \
313 script_next) \ 328 script_next) \
314 if (script_dirent.d_type != DT_DIR) 329 if (script_dirent.d_type != DT_DIR && \
330 (script_dirent.d_type != DT_UNKNOWN || \
331 !is_directory(lang_path, &script_dirent)))
315 332
316 333
317#define RECORD_SUFFIX "-record" 334#define RECORD_SUFFIX "-record"
@@ -466,14 +483,14 @@ static int list_available_scripts(const struct option *opt __used,
466 if (!scripts_dir) 483 if (!scripts_dir)
467 return -1; 484 return -1;
468 485
469 for_each_lang(scripts_dir, lang_dirent, lang_next) { 486 for_each_lang(scripts_path, scripts_dir, lang_dirent, lang_next) {
470 snprintf(lang_path, MAXPATHLEN, "%s/%s/bin", scripts_path, 487 snprintf(lang_path, MAXPATHLEN, "%s/%s/bin", scripts_path,
471 lang_dirent.d_name); 488 lang_dirent.d_name);
472 lang_dir = opendir(lang_path); 489 lang_dir = opendir(lang_path);
473 if (!lang_dir) 490 if (!lang_dir)
474 continue; 491 continue;
475 492
476 for_each_script(lang_dir, script_dirent, script_next) { 493 for_each_script(lang_path, lang_dir, script_dirent, script_next) {
477 script_root = strdup(script_dirent.d_name); 494 script_root = strdup(script_dirent.d_name);
478 str = ends_with(script_root, REPORT_SUFFIX); 495 str = ends_with(script_root, REPORT_SUFFIX);
479 if (str) { 496 if (str) {
@@ -514,14 +531,14 @@ static char *get_script_path(const char *script_root, const char *suffix)
514 if (!scripts_dir) 531 if (!scripts_dir)
515 return NULL; 532 return NULL;
516 533
517 for_each_lang(scripts_dir, lang_dirent, lang_next) { 534 for_each_lang(scripts_path, scripts_dir, lang_dirent, lang_next) {
518 snprintf(lang_path, MAXPATHLEN, "%s/%s/bin", scripts_path, 535 snprintf(lang_path, MAXPATHLEN, "%s/%s/bin", scripts_path,
519 lang_dirent.d_name); 536 lang_dirent.d_name);
520 lang_dir = opendir(lang_path); 537 lang_dir = opendir(lang_path);
521 if (!lang_dir) 538 if (!lang_dir)
522 continue; 539 continue;
523 540
524 for_each_script(lang_dir, script_dirent, script_next) { 541 for_each_script(lang_path, lang_dir, script_dirent, script_next) {
525 __script_root = strdup(script_dirent.d_name); 542 __script_root = strdup(script_dirent.d_name);
526 str = ends_with(__script_root, suffix); 543 str = ends_with(__script_root, suffix);
527 if (str) { 544 if (str) {
@@ -569,12 +586,12 @@ out:
569 return n_args; 586 return n_args;
570} 587}
571 588
572static const char * const trace_usage[] = { 589static const char * const script_usage[] = {
573 "perf trace [<options>]", 590 "perf script [<options>]",
574 "perf trace [<options>] record <script> [<record-options>] <command>", 591 "perf script [<options>] record <script> [<record-options>] <command>",
575 "perf trace [<options>] report <script> [script-args]", 592 "perf script [<options>] report <script> [script-args]",
576 "perf trace [<options>] <script> [<record-options>] <command>", 593 "perf script [<options>] <script> [<record-options>] <command>",
577 "perf trace [<options>] <top-script> [script-args]", 594 "perf script [<options>] <top-script> [script-args]",
578 NULL 595 NULL
579}; 596};
580 597
@@ -591,7 +608,7 @@ static const struct option options[] = {
591 "script file name (lang:script name, script name, or *)", 608 "script file name (lang:script name, script name, or *)",
592 parse_scriptname), 609 parse_scriptname),
593 OPT_STRING('g', "gen-script", &generate_script_lang, "lang", 610 OPT_STRING('g', "gen-script", &generate_script_lang, "lang",
594 "generate perf-trace.xx script in specified language"), 611 "generate perf-script.xx script in specified language"),
595 OPT_STRING('i', "input", &input_name, "file", 612 OPT_STRING('i', "input", &input_name, "file",
596 "input file name"), 613 "input file name"),
597 OPT_BOOLEAN('d', "debug-mode", &debug_mode, 614 OPT_BOOLEAN('d', "debug-mode", &debug_mode,
@@ -614,7 +631,7 @@ static bool have_cmd(int argc, const char **argv)
614 return argc != 0; 631 return argc != 0;
615} 632}
616 633
617int cmd_trace(int argc, const char **argv, const char *prefix __used) 634int cmd_script(int argc, const char **argv, const char *prefix __used)
618{ 635{
619 char *rec_script_path = NULL; 636 char *rec_script_path = NULL;
620 char *rep_script_path = NULL; 637 char *rep_script_path = NULL;
@@ -626,7 +643,7 @@ int cmd_trace(int argc, const char **argv, const char *prefix __used)
626 643
627 setup_scripting(); 644 setup_scripting();
628 645
629 argc = parse_options(argc, argv, options, trace_usage, 646 argc = parse_options(argc, argv, options, script_usage,
630 PARSE_OPT_STOP_AT_NON_OPTION); 647 PARSE_OPT_STOP_AT_NON_OPTION);
631 648
632 if (argc > 1 && !strncmp(argv[0], "rec", strlen("rec"))) { 649 if (argc > 1 && !strncmp(argv[0], "rec", strlen("rec"))) {
@@ -640,7 +657,7 @@ int cmd_trace(int argc, const char **argv, const char *prefix __used)
640 if (!rep_script_path) { 657 if (!rep_script_path) {
641 fprintf(stderr, 658 fprintf(stderr,
642 "Please specify a valid report script" 659 "Please specify a valid report script"
643 "(see 'perf trace -l' for listing)\n"); 660 "(see 'perf script -l' for listing)\n");
644 return -1; 661 return -1;
645 } 662 }
646 } 663 }
@@ -658,8 +675,8 @@ int cmd_trace(int argc, const char **argv, const char *prefix __used)
658 675
659 if (!rec_script_path && !rep_script_path) { 676 if (!rec_script_path && !rep_script_path) {
660 fprintf(stderr, " Couldn't find script %s\n\n See perf" 677 fprintf(stderr, " Couldn't find script %s\n\n See perf"
661 " trace -l for available scripts.\n", argv[0]); 678 " script -l for available scripts.\n", argv[0]);
662 usage_with_options(trace_usage, options); 679 usage_with_options(script_usage, options);
663 } 680 }
664 681
665 if (is_top_script(argv[0])) { 682 if (is_top_script(argv[0])) {
@@ -671,9 +688,9 @@ int cmd_trace(int argc, const char **argv, const char *prefix __used)
671 rec_args = (argc - 1) - rep_args; 688 rec_args = (argc - 1) - rep_args;
672 if (rec_args < 0) { 689 if (rec_args < 0) {
673 fprintf(stderr, " %s script requires options." 690 fprintf(stderr, " %s script requires options."
674 "\n\n See perf trace -l for available " 691 "\n\n See perf script -l for available "
675 "scripts and options.\n", argv[0]); 692 "scripts and options.\n", argv[0]);
676 usage_with_options(trace_usage, options); 693 usage_with_options(script_usage, options);
677 } 694 }
678 } 695 }
679 696
@@ -806,7 +823,7 @@ int cmd_trace(int argc, const char **argv, const char *prefix __used)
806 return -1; 823 return -1;
807 } 824 }
808 825
809 err = scripting_ops->generate_script("perf-trace"); 826 err = scripting_ops->generate_script("perf-script");
810 goto out; 827 goto out;
811 } 828 }
812 829
@@ -814,10 +831,10 @@ int cmd_trace(int argc, const char **argv, const char *prefix __used)
814 err = scripting_ops->start_script(script_name, argc, argv); 831 err = scripting_ops->start_script(script_name, argc, argv);
815 if (err) 832 if (err)
816 goto out; 833 goto out;
817 pr_debug("perf trace started with script %s\n\n", script_name); 834 pr_debug("perf script started with script %s\n\n", script_name);
818 } 835 }
819 836
820 err = __cmd_trace(session); 837 err = __cmd_script(session);
821 838
822 perf_session__delete(session); 839 perf_session__delete(session);
823 cleanup_scripting(); 840 cleanup_scripting();
diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c
index a6b4d44f9502..7ff746da7e6c 100644
--- a/tools/perf/builtin-stat.c
+++ b/tools/perf/builtin-stat.c
@@ -52,6 +52,8 @@
52#include <math.h> 52#include <math.h>
53#include <locale.h> 53#include <locale.h>
54 54
55#define DEFAULT_SEPARATOR " "
56
55static struct perf_event_attr default_attrs[] = { 57static struct perf_event_attr default_attrs[] = {
56 58
57 { .type = PERF_TYPE_SOFTWARE, .config = PERF_COUNT_SW_TASK_CLOCK }, 59 { .type = PERF_TYPE_SOFTWARE, .config = PERF_COUNT_SW_TASK_CLOCK },
@@ -75,20 +77,30 @@ static int run_idx = 0;
75static int run_count = 1; 77static int run_count = 1;
76static bool no_inherit = false; 78static bool no_inherit = false;
77static bool scale = true; 79static bool scale = true;
80static bool no_aggr = false;
78static pid_t target_pid = -1; 81static pid_t target_pid = -1;
79static pid_t target_tid = -1; 82static pid_t target_tid = -1;
80static pid_t *all_tids = NULL; 83static pid_t *all_tids = NULL;
81static int thread_num = 0; 84static int thread_num = 0;
82static pid_t child_pid = -1; 85static pid_t child_pid = -1;
83static bool null_run = false; 86static bool null_run = false;
84static bool big_num = false; 87static bool big_num = true;
88static int big_num_opt = -1;
85static const char *cpu_list; 89static const char *cpu_list;
90static const char *csv_sep = NULL;
91static bool csv_output = false;
86 92
87 93
88static int *fd[MAX_NR_CPUS][MAX_COUNTERS]; 94static int *fd[MAX_NR_CPUS][MAX_COUNTERS];
89 95
90static int event_scaled[MAX_COUNTERS]; 96static int event_scaled[MAX_COUNTERS];
91 97
98static struct {
99 u64 val;
100 u64 ena;
101 u64 run;
102} cpu_counts[MAX_NR_CPUS][MAX_COUNTERS];
103
92static volatile int done = 0; 104static volatile int done = 0;
93 105
94struct stats 106struct stats
@@ -136,19 +148,19 @@ static double stddev_stats(struct stats *stats)
136} 148}
137 149
138struct stats event_res_stats[MAX_COUNTERS][3]; 150struct stats event_res_stats[MAX_COUNTERS][3];
139struct stats runtime_nsecs_stats; 151struct stats runtime_nsecs_stats[MAX_NR_CPUS];
152struct stats runtime_cycles_stats[MAX_NR_CPUS];
153struct stats runtime_branches_stats[MAX_NR_CPUS];
140struct stats walltime_nsecs_stats; 154struct stats walltime_nsecs_stats;
141struct stats runtime_cycles_stats;
142struct stats runtime_branches_stats;
143 155
144#define MATCH_EVENT(t, c, counter) \ 156#define MATCH_EVENT(t, c, counter) \
145 (attrs[counter].type == PERF_TYPE_##t && \ 157 (attrs[counter].type == PERF_TYPE_##t && \
146 attrs[counter].config == PERF_COUNT_##c) 158 attrs[counter].config == PERF_COUNT_##c)
147 159
148#define ERR_PERF_OPEN \ 160#define ERR_PERF_OPEN \
149"Error: counter %d, sys_perf_event_open() syscall returned with %d (%s)\n" 161"counter %d, sys_perf_event_open() syscall returned with %d (%s). /bin/dmesg may provide additional information."
150 162
151static int create_perf_stat_counter(int counter) 163static int create_perf_stat_counter(int counter, bool *perm_err)
152{ 164{
153 struct perf_event_attr *attr = attrs + counter; 165 struct perf_event_attr *attr = attrs + counter;
154 int thread; 166 int thread;
@@ -164,11 +176,14 @@ static int create_perf_stat_counter(int counter)
164 for (cpu = 0; cpu < nr_cpus; cpu++) { 176 for (cpu = 0; cpu < nr_cpus; cpu++) {
165 fd[cpu][counter][0] = sys_perf_event_open(attr, 177 fd[cpu][counter][0] = sys_perf_event_open(attr,
166 -1, cpumap[cpu], -1, 0); 178 -1, cpumap[cpu], -1, 0);
167 if (fd[cpu][counter][0] < 0) 179 if (fd[cpu][counter][0] < 0) {
168 pr_debug(ERR_PERF_OPEN, counter, 180 if (errno == EPERM || errno == EACCES)
181 *perm_err = true;
182 error(ERR_PERF_OPEN, counter,
169 fd[cpu][counter][0], strerror(errno)); 183 fd[cpu][counter][0], strerror(errno));
170 else 184 } else {
171 ++ncreated; 185 ++ncreated;
186 }
172 } 187 }
173 } else { 188 } else {
174 attr->inherit = !no_inherit; 189 attr->inherit = !no_inherit;
@@ -179,12 +194,15 @@ static int create_perf_stat_counter(int counter)
179 for (thread = 0; thread < thread_num; thread++) { 194 for (thread = 0; thread < thread_num; thread++) {
180 fd[0][counter][thread] = sys_perf_event_open(attr, 195 fd[0][counter][thread] = sys_perf_event_open(attr,
181 all_tids[thread], -1, -1, 0); 196 all_tids[thread], -1, -1, 0);
182 if (fd[0][counter][thread] < 0) 197 if (fd[0][counter][thread] < 0) {
183 pr_debug(ERR_PERF_OPEN, counter, 198 if (errno == EPERM || errno == EACCES)
199 *perm_err = true;
200 error(ERR_PERF_OPEN, counter,
184 fd[0][counter][thread], 201 fd[0][counter][thread],
185 strerror(errno)); 202 strerror(errno));
186 else 203 } else {
187 ++ncreated; 204 ++ncreated;
205 }
188 } 206 }
189 } 207 }
190 208
@@ -205,8 +223,9 @@ static inline int nsec_counter(int counter)
205 223
206/* 224/*
207 * Read out the results of a single counter: 225 * Read out the results of a single counter:
226 * aggregate counts across CPUs in system-wide mode
208 */ 227 */
209static void read_counter(int counter) 228static void read_counter_aggr(int counter)
210{ 229{
211 u64 count[3], single_count[3]; 230 u64 count[3], single_count[3];
212 int cpu; 231 int cpu;
@@ -264,11 +283,58 @@ static void read_counter(int counter)
264 * Save the full runtime - to allow normalization during printout: 283 * Save the full runtime - to allow normalization during printout:
265 */ 284 */
266 if (MATCH_EVENT(SOFTWARE, SW_TASK_CLOCK, counter)) 285 if (MATCH_EVENT(SOFTWARE, SW_TASK_CLOCK, counter))
267 update_stats(&runtime_nsecs_stats, count[0]); 286 update_stats(&runtime_nsecs_stats[0], count[0]);
268 if (MATCH_EVENT(HARDWARE, HW_CPU_CYCLES, counter)) 287 if (MATCH_EVENT(HARDWARE, HW_CPU_CYCLES, counter))
269 update_stats(&runtime_cycles_stats, count[0]); 288 update_stats(&runtime_cycles_stats[0], count[0]);
270 if (MATCH_EVENT(HARDWARE, HW_BRANCH_INSTRUCTIONS, counter)) 289 if (MATCH_EVENT(HARDWARE, HW_BRANCH_INSTRUCTIONS, counter))
271 update_stats(&runtime_branches_stats, count[0]); 290 update_stats(&runtime_branches_stats[0], count[0]);
291}
292
293/*
294 * Read out the results of a single counter:
295 * do not aggregate counts across CPUs in system-wide mode
296 */
297static void read_counter(int counter)
298{
299 u64 count[3];
300 int cpu;
301 size_t res, nv;
302
303 count[0] = count[1] = count[2] = 0;
304
305 nv = scale ? 3 : 1;
306
307 for (cpu = 0; cpu < nr_cpus; cpu++) {
308
309 if (fd[cpu][counter][0] < 0)
310 continue;
311
312 res = read(fd[cpu][counter][0], count, nv * sizeof(u64));
313
314 assert(res == nv * sizeof(u64));
315
316 close(fd[cpu][counter][0]);
317 fd[cpu][counter][0] = -1;
318
319 if (scale) {
320 if (count[2] == 0) {
321 count[0] = 0;
322 } else if (count[2] < count[1]) {
323 count[0] = (unsigned long long)
324 ((double)count[0] * count[1] / count[2] + 0.5);
325 }
326 }
327 cpu_counts[cpu][counter].val = count[0]; /* scaled count */
328 cpu_counts[cpu][counter].ena = count[1];
329 cpu_counts[cpu][counter].run = count[2];
330
331 if (MATCH_EVENT(SOFTWARE, SW_TASK_CLOCK, counter))
332 update_stats(&runtime_nsecs_stats[cpu], count[0]);
333 if (MATCH_EVENT(HARDWARE, HW_CPU_CYCLES, counter))
334 update_stats(&runtime_cycles_stats[cpu], count[0]);
335 if (MATCH_EVENT(HARDWARE, HW_BRANCH_INSTRUCTIONS, counter))
336 update_stats(&runtime_branches_stats[cpu], count[0]);
337 }
272} 338}
273 339
274static int run_perf_stat(int argc __used, const char **argv) 340static int run_perf_stat(int argc __used, const char **argv)
@@ -277,6 +343,7 @@ static int run_perf_stat(int argc __used, const char **argv)
277 int status = 0; 343 int status = 0;
278 int counter, ncreated = 0; 344 int counter, ncreated = 0;
279 int child_ready_pipe[2], go_pipe[2]; 345 int child_ready_pipe[2], go_pipe[2];
346 bool perm_err = false;
280 const bool forks = (argc > 0); 347 const bool forks = (argc > 0);
281 char buf; 348 char buf;
282 349
@@ -335,12 +402,15 @@ static int run_perf_stat(int argc __used, const char **argv)
335 } 402 }
336 403
337 for (counter = 0; counter < nr_counters; counter++) 404 for (counter = 0; counter < nr_counters; counter++)
338 ncreated += create_perf_stat_counter(counter); 405 ncreated += create_perf_stat_counter(counter, &perm_err);
339 406
340 if (ncreated == 0) { 407 if (ncreated < nr_counters) {
341 pr_err("No permission to collect %sstats.\n" 408 if (perm_err)
342 "Consider tweaking /proc/sys/kernel/perf_event_paranoid.\n", 409 error("You may not have permission to collect %sstats.\n"
343 system_wide ? "system-wide " : ""); 410 "\t Consider tweaking"
411 " /proc/sys/kernel/perf_event_paranoid or running as root.",
412 system_wide ? "system-wide " : "");
413 die("Not all events could be opened.\n");
344 if (child_pid != -1) 414 if (child_pid != -1)
345 kill(child_pid, SIGTERM); 415 kill(child_pid, SIGTERM);
346 return -1; 416 return -1;
@@ -362,9 +432,13 @@ static int run_perf_stat(int argc __used, const char **argv)
362 432
363 update_stats(&walltime_nsecs_stats, t1 - t0); 433 update_stats(&walltime_nsecs_stats, t1 - t0);
364 434
365 for (counter = 0; counter < nr_counters; counter++) 435 if (no_aggr) {
366 read_counter(counter); 436 for (counter = 0; counter < nr_counters; counter++)
367 437 read_counter(counter);
438 } else {
439 for (counter = 0; counter < nr_counters; counter++)
440 read_counter_aggr(counter);
441 }
368 return WEXITSTATUS(status); 442 return WEXITSTATUS(status);
369} 443}
370 444
@@ -377,11 +451,21 @@ static void print_noise(int counter, double avg)
377 100 * stddev_stats(&event_res_stats[counter][0]) / avg); 451 100 * stddev_stats(&event_res_stats[counter][0]) / avg);
378} 452}
379 453
380static void nsec_printout(int counter, double avg) 454static void nsec_printout(int cpu, int counter, double avg)
381{ 455{
382 double msecs = avg / 1e6; 456 double msecs = avg / 1e6;
457 char cpustr[16] = { '\0', };
458 const char *fmt = csv_output ? "%s%.6f%s%s" : "%s%18.6f%s%-24s";
459
460 if (no_aggr)
461 sprintf(cpustr, "CPU%*d%s",
462 csv_output ? 0 : -4,
463 cpumap[cpu], csv_sep);
383 464
384 fprintf(stderr, " %18.6f %-24s", msecs, event_name(counter)); 465 fprintf(stderr, fmt, cpustr, msecs, csv_sep, event_name(counter));
466
467 if (csv_output)
468 return;
385 469
386 if (MATCH_EVENT(SOFTWARE, SW_TASK_CLOCK, counter)) { 470 if (MATCH_EVENT(SOFTWARE, SW_TASK_CLOCK, counter)) {
387 fprintf(stderr, " # %10.3f CPUs ", 471 fprintf(stderr, " # %10.3f CPUs ",
@@ -389,33 +473,49 @@ static void nsec_printout(int counter, double avg)
389 } 473 }
390} 474}
391 475
392static void abs_printout(int counter, double avg) 476static void abs_printout(int cpu, int counter, double avg)
393{ 477{
394 double total, ratio = 0.0; 478 double total, ratio = 0.0;
479 char cpustr[16] = { '\0', };
480 const char *fmt;
481
482 if (csv_output)
483 fmt = "%s%.0f%s%s";
484 else if (big_num)
485 fmt = "%s%'18.0f%s%-24s";
486 else
487 fmt = "%s%18.0f%s%-24s";
395 488
396 if (big_num) 489 if (no_aggr)
397 fprintf(stderr, " %'18.0f %-24s", avg, event_name(counter)); 490 sprintf(cpustr, "CPU%*d%s",
491 csv_output ? 0 : -4,
492 cpumap[cpu], csv_sep);
398 else 493 else
399 fprintf(stderr, " %18.0f %-24s", avg, event_name(counter)); 494 cpu = 0;
495
496 fprintf(stderr, fmt, cpustr, avg, csv_sep, event_name(counter));
497
498 if (csv_output)
499 return;
400 500
401 if (MATCH_EVENT(HARDWARE, HW_INSTRUCTIONS, counter)) { 501 if (MATCH_EVENT(HARDWARE, HW_INSTRUCTIONS, counter)) {
402 total = avg_stats(&runtime_cycles_stats); 502 total = avg_stats(&runtime_cycles_stats[cpu]);
403 503
404 if (total) 504 if (total)
405 ratio = avg / total; 505 ratio = avg / total;
406 506
407 fprintf(stderr, " # %10.3f IPC ", ratio); 507 fprintf(stderr, " # %10.3f IPC ", ratio);
408 } else if (MATCH_EVENT(HARDWARE, HW_BRANCH_MISSES, counter) && 508 } else if (MATCH_EVENT(HARDWARE, HW_BRANCH_MISSES, counter) &&
409 runtime_branches_stats.n != 0) { 509 runtime_branches_stats[cpu].n != 0) {
410 total = avg_stats(&runtime_branches_stats); 510 total = avg_stats(&runtime_branches_stats[cpu]);
411 511
412 if (total) 512 if (total)
413 ratio = avg * 100 / total; 513 ratio = avg * 100 / total;
414 514
415 fprintf(stderr, " # %10.3f %% ", ratio); 515 fprintf(stderr, " # %10.3f %% ", ratio);
416 516
417 } else if (runtime_nsecs_stats.n != 0) { 517 } else if (runtime_nsecs_stats[cpu].n != 0) {
418 total = avg_stats(&runtime_nsecs_stats); 518 total = avg_stats(&runtime_nsecs_stats[cpu]);
419 519
420 if (total) 520 if (total)
421 ratio = 1000.0 * avg / total; 521 ratio = 1000.0 * avg / total;
@@ -426,22 +526,29 @@ static void abs_printout(int counter, double avg)
426 526
427/* 527/*
428 * Print out the results of a single counter: 528 * Print out the results of a single counter:
529 * aggregated counts in system-wide mode
429 */ 530 */
430static void print_counter(int counter) 531static void print_counter_aggr(int counter)
431{ 532{
432 double avg = avg_stats(&event_res_stats[counter][0]); 533 double avg = avg_stats(&event_res_stats[counter][0]);
433 int scaled = event_scaled[counter]; 534 int scaled = event_scaled[counter];
434 535
435 if (scaled == -1) { 536 if (scaled == -1) {
436 fprintf(stderr, " %18s %-24s\n", 537 fprintf(stderr, "%*s%s%-24s\n",
437 "<not counted>", event_name(counter)); 538 csv_output ? 0 : 18,
539 "<not counted>", csv_sep, event_name(counter));
438 return; 540 return;
439 } 541 }
440 542
441 if (nsec_counter(counter)) 543 if (nsec_counter(counter))
442 nsec_printout(counter, avg); 544 nsec_printout(-1, counter, avg);
443 else 545 else
444 abs_printout(counter, avg); 546 abs_printout(-1, counter, avg);
547
548 if (csv_output) {
549 fputc('\n', stderr);
550 return;
551 }
445 552
446 print_noise(counter, avg); 553 print_noise(counter, avg);
447 554
@@ -458,40 +565,91 @@ static void print_counter(int counter)
458 fprintf(stderr, "\n"); 565 fprintf(stderr, "\n");
459} 566}
460 567
568/*
569 * Print out the results of a single counter:
570 * does not use aggregated count in system-wide
571 */
572static void print_counter(int counter)
573{
574 u64 ena, run, val;
575 int cpu;
576
577 for (cpu = 0; cpu < nr_cpus; cpu++) {
578 val = cpu_counts[cpu][counter].val;
579 ena = cpu_counts[cpu][counter].ena;
580 run = cpu_counts[cpu][counter].run;
581 if (run == 0 || ena == 0) {
582 fprintf(stderr, "CPU%*d%s%*s%s%-24s",
583 csv_output ? 0 : -4,
584 cpumap[cpu], csv_sep,
585 csv_output ? 0 : 18,
586 "<not counted>", csv_sep,
587 event_name(counter));
588
589 fprintf(stderr, "\n");
590 continue;
591 }
592
593 if (nsec_counter(counter))
594 nsec_printout(cpu, counter, val);
595 else
596 abs_printout(cpu, counter, val);
597
598 if (!csv_output) {
599 print_noise(counter, 1.0);
600
601 if (run != ena) {
602 fprintf(stderr, " (scaled from %.2f%%)",
603 100.0 * run / ena);
604 }
605 }
606 fprintf(stderr, "\n");
607 }
608}
609
461static void print_stat(int argc, const char **argv) 610static void print_stat(int argc, const char **argv)
462{ 611{
463 int i, counter; 612 int i, counter;
464 613
465 fflush(stdout); 614 fflush(stdout);
466 615
467 fprintf(stderr, "\n"); 616 if (!csv_output) {
468 fprintf(stderr, " Performance counter stats for "); 617 fprintf(stderr, "\n");
469 if(target_pid == -1 && target_tid == -1) { 618 fprintf(stderr, " Performance counter stats for ");
470 fprintf(stderr, "\'%s", argv[0]); 619 if(target_pid == -1 && target_tid == -1) {
471 for (i = 1; i < argc; i++) 620 fprintf(stderr, "\'%s", argv[0]);
472 fprintf(stderr, " %s", argv[i]); 621 for (i = 1; i < argc; i++)
473 } else if (target_pid != -1) 622 fprintf(stderr, " %s", argv[i]);
474 fprintf(stderr, "process id \'%d", target_pid); 623 } else if (target_pid != -1)
475 else 624 fprintf(stderr, "process id \'%d", target_pid);
476 fprintf(stderr, "thread id \'%d", target_tid); 625 else
477 626 fprintf(stderr, "thread id \'%d", target_tid);
478 fprintf(stderr, "\'"); 627
479 if (run_count > 1) 628 fprintf(stderr, "\'");
480 fprintf(stderr, " (%d runs)", run_count); 629 if (run_count > 1)
481 fprintf(stderr, ":\n\n"); 630 fprintf(stderr, " (%d runs)", run_count);
631 fprintf(stderr, ":\n\n");
632 }
482 633
483 for (counter = 0; counter < nr_counters; counter++) 634 if (no_aggr) {
484 print_counter(counter); 635 for (counter = 0; counter < nr_counters; counter++)
636 print_counter(counter);
637 } else {
638 for (counter = 0; counter < nr_counters; counter++)
639 print_counter_aggr(counter);
640 }
485 641
486 fprintf(stderr, "\n"); 642 if (!csv_output) {
487 fprintf(stderr, " %18.9f seconds time elapsed", 643 fprintf(stderr, "\n");
488 avg_stats(&walltime_nsecs_stats)/1e9); 644 fprintf(stderr, " %18.9f seconds time elapsed",
489 if (run_count > 1) { 645 avg_stats(&walltime_nsecs_stats)/1e9);
490 fprintf(stderr, " ( +- %7.3f%% )", 646 if (run_count > 1) {
647 fprintf(stderr, " ( +- %7.3f%% )",
491 100*stddev_stats(&walltime_nsecs_stats) / 648 100*stddev_stats(&walltime_nsecs_stats) /
492 avg_stats(&walltime_nsecs_stats)); 649 avg_stats(&walltime_nsecs_stats));
650 }
651 fprintf(stderr, "\n\n");
493 } 652 }
494 fprintf(stderr, "\n\n");
495} 653}
496 654
497static volatile int signr = -1; 655static volatile int signr = -1;
@@ -521,6 +679,13 @@ static const char * const stat_usage[] = {
521 NULL 679 NULL
522}; 680};
523 681
682static int stat__set_big_num(const struct option *opt __used,
683 const char *s __used, int unset)
684{
685 big_num_opt = unset ? 0 : 1;
686 return 0;
687}
688
524static const struct option options[] = { 689static const struct option options[] = {
525 OPT_CALLBACK('e', "event", NULL, "event", 690 OPT_CALLBACK('e', "event", NULL, "event",
526 "event selector. use 'perf list' to list available events", 691 "event selector. use 'perf list' to list available events",
@@ -541,10 +706,15 @@ static const struct option options[] = {
541 "repeat command and print average + stddev (max: 100)"), 706 "repeat command and print average + stddev (max: 100)"),
542 OPT_BOOLEAN('n', "null", &null_run, 707 OPT_BOOLEAN('n', "null", &null_run,
543 "null run - dont start any counters"), 708 "null run - dont start any counters"),
544 OPT_BOOLEAN('B', "big-num", &big_num, 709 OPT_CALLBACK_NOOPT('B', "big-num", NULL, NULL,
545 "print large numbers with thousands\' separators"), 710 "print large numbers with thousands\' separators",
711 stat__set_big_num),
546 OPT_STRING('C', "cpu", &cpu_list, "cpu", 712 OPT_STRING('C', "cpu", &cpu_list, "cpu",
547 "list of cpus to monitor in system-wide"), 713 "list of cpus to monitor in system-wide"),
714 OPT_BOOLEAN('A', "no-aggr", &no_aggr,
715 "disable CPU count aggregation"),
716 OPT_STRING('x', "field-separator", &csv_sep, "separator",
717 "print counts with custom separator"),
548 OPT_END() 718 OPT_END()
549}; 719};
550 720
@@ -557,11 +727,34 @@ int cmd_stat(int argc, const char **argv, const char *prefix __used)
557 727
558 argc = parse_options(argc, argv, options, stat_usage, 728 argc = parse_options(argc, argv, options, stat_usage,
559 PARSE_OPT_STOP_AT_NON_OPTION); 729 PARSE_OPT_STOP_AT_NON_OPTION);
730
731 if (csv_sep)
732 csv_output = true;
733 else
734 csv_sep = DEFAULT_SEPARATOR;
735
736 /*
737 * let the spreadsheet do the pretty-printing
738 */
739 if (csv_output) {
740 /* User explicitely passed -B? */
741 if (big_num_opt == 1) {
742 fprintf(stderr, "-B option not supported with -x\n");
743 usage_with_options(stat_usage, options);
744 } else /* Nope, so disable big number formatting */
745 big_num = false;
746 } else if (big_num_opt == 0) /* User passed --no-big-num */
747 big_num = false;
748
560 if (!argc && target_pid == -1 && target_tid == -1) 749 if (!argc && target_pid == -1 && target_tid == -1)
561 usage_with_options(stat_usage, options); 750 usage_with_options(stat_usage, options);
562 if (run_count <= 0) 751 if (run_count <= 0)
563 usage_with_options(stat_usage, options); 752 usage_with_options(stat_usage, options);
564 753
754 /* no_aggr is for system-wide only */
755 if (no_aggr && !system_wide)
756 usage_with_options(stat_usage, options);
757
565 /* Set attrs and nr_counters if no event is selected and !null_run */ 758 /* Set attrs and nr_counters if no event is selected and !null_run */
566 if (!null_run && !nr_counters) { 759 if (!null_run && !nr_counters) {
567 memcpy(attrs, default_attrs, sizeof(default_attrs)); 760 memcpy(attrs, default_attrs, sizeof(default_attrs));
diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c
index dd625808c2a5..3d2b47d5121a 100644
--- a/tools/perf/builtin-top.c
+++ b/tools/perf/builtin-top.c
@@ -1214,7 +1214,9 @@ try_again:
1214 int err = errno; 1214 int err = errno;
1215 1215
1216 if (err == EPERM || err == EACCES) 1216 if (err == EPERM || err == EACCES)
1217 die("No permission - are you root?\n"); 1217 die("Permission error - are you root?\n"
1218 "\t Consider tweaking"
1219 " /proc/sys/kernel/perf_event_paranoid.\n");
1218 /* 1220 /*
1219 * If it's cycles then fall back to hrtimer 1221 * If it's cycles then fall back to hrtimer
1220 * based cpu-clock-tick sw counter, which 1222 * based cpu-clock-tick sw counter, which
@@ -1231,7 +1233,7 @@ try_again:
1231 goto try_again; 1233 goto try_again;
1232 } 1234 }
1233 printf("\n"); 1235 printf("\n");
1234 error("perfcounter syscall returned with %d (%s)\n", 1236 error("sys_perf_event_open() syscall returned with %d (%s). /bin/dmesg may provide additional information.\n",
1235 fd[i][counter][thread_index], strerror(err)); 1237 fd[i][counter][thread_index], strerror(err));
1236 die("No CONFIG_PERF_EVENTS=y kernel support configured?\n"); 1238 die("No CONFIG_PERF_EVENTS=y kernel support configured?\n");
1237 exit(-1); 1239 exit(-1);
diff --git a/tools/perf/builtin.h b/tools/perf/builtin.h
index 921245b28583..c7798c7f24ed 100644
--- a/tools/perf/builtin.h
+++ b/tools/perf/builtin.h
@@ -27,7 +27,7 @@ extern int cmd_report(int argc, const char **argv, const char *prefix);
27extern int cmd_stat(int argc, const char **argv, const char *prefix); 27extern int cmd_stat(int argc, const char **argv, const char *prefix);
28extern int cmd_timechart(int argc, const char **argv, const char *prefix); 28extern int cmd_timechart(int argc, const char **argv, const char *prefix);
29extern int cmd_top(int argc, const char **argv, const char *prefix); 29extern int cmd_top(int argc, const char **argv, const char *prefix);
30extern int cmd_trace(int argc, const char **argv, const char *prefix); 30extern int cmd_script(int argc, const char **argv, const char *prefix);
31extern int cmd_version(int argc, const char **argv, const char *prefix); 31extern int cmd_version(int argc, const char **argv, const char *prefix);
32extern int cmd_probe(int argc, const char **argv, const char *prefix); 32extern int cmd_probe(int argc, const char **argv, const char *prefix);
33extern int cmd_kmem(int argc, const char **argv, const char *prefix); 33extern int cmd_kmem(int argc, const char **argv, const char *prefix);
diff --git a/tools/perf/command-list.txt b/tools/perf/command-list.txt
index 949d77fc0b97..16b5088cf8f4 100644
--- a/tools/perf/command-list.txt
+++ b/tools/perf/command-list.txt
@@ -16,7 +16,7 @@ perf-report mainporcelain common
16perf-stat mainporcelain common 16perf-stat mainporcelain common
17perf-timechart mainporcelain common 17perf-timechart mainporcelain common
18perf-top mainporcelain common 18perf-top mainporcelain common
19perf-trace mainporcelain common 19perf-script mainporcelain common
20perf-probe mainporcelain common 20perf-probe mainporcelain common
21perf-kmem mainporcelain common 21perf-kmem mainporcelain common
22perf-lock mainporcelain common 22perf-lock mainporcelain common
diff --git a/tools/perf/feature-tests.mak b/tools/perf/feature-tests.mak
index b253db634f04..b041ca67a2cb 100644
--- a/tools/perf/feature-tests.mak
+++ b/tools/perf/feature-tests.mak
@@ -9,8 +9,8 @@ endef
9ifndef NO_DWARF 9ifndef NO_DWARF
10define SOURCE_DWARF 10define SOURCE_DWARF
11#include <dwarf.h> 11#include <dwarf.h>
12#include <libdw.h> 12#include <elfutils/libdw.h>
13#include <version.h> 13#include <elfutils/version.h>
14#ifndef _ELFUTILS_PREREQ 14#ifndef _ELFUTILS_PREREQ
15#error 15#error
16#endif 16#endif
diff --git a/tools/perf/perf.c b/tools/perf/perf.c
index cdd6c03f1e14..595d0f4a7103 100644
--- a/tools/perf/perf.c
+++ b/tools/perf/perf.c
@@ -323,7 +323,7 @@ static void handle_internal_command(int argc, const char **argv)
323 { "top", cmd_top, 0 }, 323 { "top", cmd_top, 0 },
324 { "annotate", cmd_annotate, 0 }, 324 { "annotate", cmd_annotate, 0 },
325 { "version", cmd_version, 0 }, 325 { "version", cmd_version, 0 },
326 { "trace", cmd_trace, 0 }, 326 { "script", cmd_script, 0 },
327 { "sched", cmd_sched, 0 }, 327 { "sched", cmd_sched, 0 },
328 { "probe", cmd_probe, 0 }, 328 { "probe", cmd_probe, 0 },
329 { "kmem", cmd_kmem, 0 }, 329 { "kmem", cmd_kmem, 0 },
diff --git a/tools/perf/scripts/python/Perf-Trace-Util/Context.c b/tools/perf/scripts/python/Perf-Trace-Util/Context.c
index 957085dd5d8d..315067b8f552 100644
--- a/tools/perf/scripts/python/Perf-Trace-Util/Context.c
+++ b/tools/perf/scripts/python/Perf-Trace-Util/Context.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Context.c. Python interfaces for perf trace. 2 * Context.c. Python interfaces for perf script.
3 * 3 *
4 * Copyright (C) 2010 Tom Zanussi <tzanussi@gmail.com> 4 * Copyright (C) 2010 Tom Zanussi <tzanussi@gmail.com>
5 * 5 *
diff --git a/tools/perf/util/debug.c b/tools/perf/util/debug.c
index c8d81b00089d..01bbe8ecec3f 100644
--- a/tools/perf/util/debug.c
+++ b/tools/perf/util/debug.c
@@ -46,20 +46,16 @@ int dump_printf(const char *fmt, ...)
46 return ret; 46 return ret;
47} 47}
48 48
49static int dump_printf_color(const char *fmt, const char *color, ...) 49#ifdef NO_NEWT_SUPPORT
50void ui__warning(const char *format, ...)
50{ 51{
51 va_list args; 52 va_list args;
52 int ret = 0;
53 53
54 if (dump_trace) { 54 va_start(args, format);
55 va_start(args, color); 55 vfprintf(stderr, format, args);
56 ret = color_vfprintf(stdout, color, fmt, args); 56 va_end(args);
57 va_end(args);
58 }
59
60 return ret;
61} 57}
62 58#endif
63 59
64void trace_event(event_t *event) 60void trace_event(event_t *event)
65{ 61{
@@ -70,29 +66,29 @@ void trace_event(event_t *event)
70 if (!dump_trace) 66 if (!dump_trace)
71 return; 67 return;
72 68
73 dump_printf("."); 69 printf(".");
74 dump_printf_color("\n. ... raw event: size %d bytes\n", color, 70 color_fprintf(stdout, color, "\n. ... raw event: size %d bytes\n",
75 event->header.size); 71 event->header.size);
76 72
77 for (i = 0; i < event->header.size; i++) { 73 for (i = 0; i < event->header.size; i++) {
78 if ((i & 15) == 0) { 74 if ((i & 15) == 0) {
79 dump_printf("."); 75 printf(".");
80 dump_printf_color(" %04x: ", color, i); 76 color_fprintf(stdout, color, " %04x: ", i);
81 } 77 }
82 78
83 dump_printf_color(" %02x", color, raw_event[i]); 79 color_fprintf(stdout, color, " %02x", raw_event[i]);
84 80
85 if (((i & 15) == 15) || i == event->header.size-1) { 81 if (((i & 15) == 15) || i == event->header.size-1) {
86 dump_printf_color(" ", color); 82 color_fprintf(stdout, color, " ");
87 for (j = 0; j < 15-(i & 15); j++) 83 for (j = 0; j < 15-(i & 15); j++)
88 dump_printf_color(" ", color); 84 color_fprintf(stdout, color, " ");
89 for (j = i & ~15; j <= i; j++) { 85 for (j = i & ~15; j <= i; j++) {
90 dump_printf_color("%c", color, 86 color_fprintf(stdout, color, "%c",
91 isprint(raw_event[j]) ? 87 isprint(raw_event[j]) ?
92 raw_event[j] : '.'); 88 raw_event[j] : '.');
93 } 89 }
94 dump_printf_color("\n", color); 90 color_fprintf(stdout, color, "\n");
95 } 91 }
96 } 92 }
97 dump_printf(".\n"); 93 printf(".\n");
98} 94}
diff --git a/tools/perf/util/debug.h b/tools/perf/util/debug.h
index 7b514082bbaf..ca35fd66b5df 100644
--- a/tools/perf/util/debug.h
+++ b/tools/perf/util/debug.h
@@ -35,4 +35,6 @@ int ui_helpline__show_help(const char *format, va_list ap);
35#include "ui/progress.h" 35#include "ui/progress.h"
36#endif 36#endif
37 37
38void ui__warning(const char *format, ...) __attribute__((format(printf, 1, 2)));
39
38#endif /* __PERF_DEBUG_H */ 40#endif /* __PERF_DEBUG_H */
diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c
index dab9e754a281..7260db75b93d 100644
--- a/tools/perf/util/event.c
+++ b/tools/perf/util/event.c
@@ -392,7 +392,7 @@ static void event_set_kernel_mmap_len(struct map **maps, event_t *self)
392 * a zero sized synthesized MMAP event for the kernel. 392 * a zero sized synthesized MMAP event for the kernel.
393 */ 393 */
394 if (maps[MAP__FUNCTION]->end == 0) 394 if (maps[MAP__FUNCTION]->end == 0)
395 maps[MAP__FUNCTION]->end = ~0UL; 395 maps[MAP__FUNCTION]->end = ~0ULL;
396} 396}
397 397
398static int event__process_kernel_mmap(event_t *self, 398static int event__process_kernel_mmap(event_t *self,
diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c
index d7e67b167ea3..f65d7dc127b6 100644
--- a/tools/perf/util/header.c
+++ b/tools/perf/util/header.c
@@ -152,6 +152,11 @@ void perf_header__set_feat(struct perf_header *self, int feat)
152 set_bit(feat, self->adds_features); 152 set_bit(feat, self->adds_features);
153} 153}
154 154
155void perf_header__clear_feat(struct perf_header *self, int feat)
156{
157 clear_bit(feat, self->adds_features);
158}
159
155bool perf_header__has_feat(const struct perf_header *self, int feat) 160bool perf_header__has_feat(const struct perf_header *self, int feat)
156{ 161{
157 return test_bit(feat, self->adds_features); 162 return test_bit(feat, self->adds_features);
@@ -431,8 +436,10 @@ static int perf_header__adds_write(struct perf_header *self, int fd)
431 int idx = 0, err; 436 int idx = 0, err;
432 437
433 session = container_of(self, struct perf_session, header); 438 session = container_of(self, struct perf_session, header);
434 if (perf_session__read_build_ids(session, true)) 439
435 perf_header__set_feat(self, HEADER_BUILD_ID); 440 if (perf_header__has_feat(self, HEADER_BUILD_ID &&
441 !perf_session__read_build_ids(session, true)))
442 perf_header__clear_feat(self, HEADER_BUILD_ID);
436 443
437 nr_sections = bitmap_weight(self->adds_features, HEADER_FEAT_BITS); 444 nr_sections = bitmap_weight(self->adds_features, HEADER_FEAT_BITS);
438 if (!nr_sections) 445 if (!nr_sections)
diff --git a/tools/perf/util/header.h b/tools/perf/util/header.h
index 402ac2454cf8..ed550bffd655 100644
--- a/tools/perf/util/header.h
+++ b/tools/perf/util/header.h
@@ -84,6 +84,7 @@ u64 perf_header__sample_type(struct perf_header *header);
84struct perf_event_attr * 84struct perf_event_attr *
85perf_header__find_attr(u64 id, struct perf_header *header); 85perf_header__find_attr(u64 id, struct perf_header *header);
86void perf_header__set_feat(struct perf_header *self, int feat); 86void perf_header__set_feat(struct perf_header *self, int feat);
87void perf_header__clear_feat(struct perf_header *self, int feat);
87bool perf_header__has_feat(const struct perf_header *self, int feat); 88bool perf_header__has_feat(const struct perf_header *self, int feat);
88 89
89int perf_header__process_sections(struct perf_header *self, int fd, 90int perf_header__process_sections(struct perf_header *self, int fd,
diff --git a/tools/perf/util/include/asm/cpufeature.h b/tools/perf/util/include/asm/cpufeature.h
new file mode 100644
index 000000000000..acffd5e4d1d4
--- /dev/null
+++ b/tools/perf/util/include/asm/cpufeature.h
@@ -0,0 +1,9 @@
1
2#ifndef PERF_CPUFEATURE_H
3#define PERF_CPUFEATURE_H
4
5/* cpufeature.h ... dummy header file for including arch/x86/lib/memcpy_64.S */
6
7#define X86_FEATURE_REP_GOOD 0
8
9#endif /* PERF_CPUFEATURE_H */
diff --git a/tools/perf/util/include/asm/dwarf2.h b/tools/perf/util/include/asm/dwarf2.h
new file mode 100644
index 000000000000..bb4198e7837a
--- /dev/null
+++ b/tools/perf/util/include/asm/dwarf2.h
@@ -0,0 +1,11 @@
1
2#ifndef PERF_DWARF2_H
3#define PERF_DWARF2_H
4
5/* dwarf2.h ... dummy header file for including arch/x86/lib/memcpy_64.S */
6
7#define CFI_STARTPROC
8#define CFI_ENDPROC
9
10#endif /* PERF_DWARF2_H */
11
diff --git a/tools/perf/util/include/linux/bitops.h b/tools/perf/util/include/linux/bitops.h
index bb4ac2e05385..8be0b968ca0b 100644
--- a/tools/perf/util/include/linux/bitops.h
+++ b/tools/perf/util/include/linux/bitops.h
@@ -13,6 +13,11 @@ static inline void set_bit(int nr, unsigned long *addr)
13 addr[nr / BITS_PER_LONG] |= 1UL << (nr % BITS_PER_LONG); 13 addr[nr / BITS_PER_LONG] |= 1UL << (nr % BITS_PER_LONG);
14} 14}
15 15
16static inline void clear_bit(int nr, unsigned long *addr)
17{
18 addr[nr / BITS_PER_LONG] &= ~(1UL << (nr % BITS_PER_LONG));
19}
20
16static __always_inline int test_bit(unsigned int nr, const unsigned long *addr) 21static __always_inline int test_bit(unsigned int nr, const unsigned long *addr)
17{ 22{
18 return ((1UL << (nr % BITS_PER_LONG)) & 23 return ((1UL << (nr % BITS_PER_LONG)) &
diff --git a/tools/perf/util/include/linux/linkage.h b/tools/perf/util/include/linux/linkage.h
new file mode 100644
index 000000000000..06387cffe125
--- /dev/null
+++ b/tools/perf/util/include/linux/linkage.h
@@ -0,0 +1,13 @@
1
2#ifndef PERF_LINUX_LINKAGE_H_
3#define PERF_LINUX_LINKAGE_H_
4
5/* linkage.h ... for including arch/x86/lib/memcpy_64.S */
6
7#define ENTRY(name) \
8 .globl name; \
9 name:
10
11#define ENDPROC(name)
12
13#endif /* PERF_LINUX_LINKAGE_H_ */
diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c
index 4af5bd59cfd1..c305305a3884 100644
--- a/tools/perf/util/parse-events.c
+++ b/tools/perf/util/parse-events.c
@@ -434,7 +434,7 @@ parse_single_tracepoint_event(char *sys_name,
434 id = atoll(id_buf); 434 id = atoll(id_buf);
435 attr->config = id; 435 attr->config = id;
436 attr->type = PERF_TYPE_TRACEPOINT; 436 attr->type = PERF_TYPE_TRACEPOINT;
437 *strp = evt_name + evt_length; 437 *strp += strlen(sys_name) + evt_length + 1; /* + 1 for the ':' */
438 438
439 attr->sample_type |= PERF_SAMPLE_RAW; 439 attr->sample_type |= PERF_SAMPLE_RAW;
440 attr->sample_type |= PERF_SAMPLE_TIME; 440 attr->sample_type |= PERF_SAMPLE_TIME;
@@ -495,7 +495,7 @@ static enum event_result parse_tracepoint_event(const char **strp,
495 struct perf_event_attr *attr) 495 struct perf_event_attr *attr)
496{ 496{
497 const char *evt_name; 497 const char *evt_name;
498 char *flags; 498 char *flags = NULL, *comma_loc;
499 char sys_name[MAX_EVENT_LENGTH]; 499 char sys_name[MAX_EVENT_LENGTH];
500 unsigned int sys_length, evt_length; 500 unsigned int sys_length, evt_length;
501 501
@@ -514,6 +514,11 @@ static enum event_result parse_tracepoint_event(const char **strp,
514 sys_name[sys_length] = '\0'; 514 sys_name[sys_length] = '\0';
515 evt_name = evt_name + 1; 515 evt_name = evt_name + 1;
516 516
517 comma_loc = strchr(evt_name, ',');
518 if (comma_loc) {
519 /* take the event name up to the comma */
520 evt_name = strndup(evt_name, comma_loc - evt_name);
521 }
517 flags = strchr(evt_name, ':'); 522 flags = strchr(evt_name, ':');
518 if (flags) { 523 if (flags) {
519 /* split it out: */ 524 /* split it out: */
@@ -524,9 +529,8 @@ static enum event_result parse_tracepoint_event(const char **strp,
524 evt_length = strlen(evt_name); 529 evt_length = strlen(evt_name);
525 if (evt_length >= MAX_EVENT_LENGTH) 530 if (evt_length >= MAX_EVENT_LENGTH)
526 return EVT_FAILED; 531 return EVT_FAILED;
527
528 if (strpbrk(evt_name, "*?")) { 532 if (strpbrk(evt_name, "*?")) {
529 *strp = evt_name + evt_length; 533 *strp += strlen(sys_name) + evt_length;
530 return parse_multiple_tracepoint_event(sys_name, evt_name, 534 return parse_multiple_tracepoint_event(sys_name, evt_name,
531 flags); 535 flags);
532 } else 536 } else
diff --git a/tools/perf/util/probe-finder.h b/tools/perf/util/probe-finder.h
index bba69d455699..beaefc3c1223 100644
--- a/tools/perf/util/probe-finder.h
+++ b/tools/perf/util/probe-finder.h
@@ -34,9 +34,9 @@ extern int find_available_vars_at(int fd, struct perf_probe_event *pev,
34 bool externs); 34 bool externs);
35 35
36#include <dwarf.h> 36#include <dwarf.h>
37#include <libdw.h> 37#include <elfutils/libdw.h>
38#include <libdwfl.h> 38#include <elfutils/libdwfl.h>
39#include <version.h> 39#include <elfutils/version.h>
40 40
41struct probe_finder { 41struct probe_finder {
42 struct perf_probe_event *pev; /* Target probe event */ 42 struct perf_probe_event *pev; /* Target probe event */
diff --git a/tools/perf/util/scripting-engines/trace-event-perl.c b/tools/perf/util/scripting-engines/trace-event-perl.c
index b059dc50cc2d..93680818e244 100644
--- a/tools/perf/util/scripting-engines/trace-event-perl.c
+++ b/tools/perf/util/scripting-engines/trace-event-perl.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * trace-event-perl. Feed perf trace events to an embedded Perl interpreter. 2 * trace-event-perl. Feed perf script events to an embedded Perl interpreter.
3 * 3 *
4 * Copyright (C) 2009 Tom Zanussi <tzanussi@gmail.com> 4 * Copyright (C) 2009 Tom Zanussi <tzanussi@gmail.com>
5 * 5 *
@@ -411,8 +411,8 @@ static int perl_generate_script(const char *outfile)
411 return -1; 411 return -1;
412 } 412 }
413 413
414 fprintf(ofp, "# perf trace event handlers, " 414 fprintf(ofp, "# perf script event handlers, "
415 "generated by perf trace -g perl\n"); 415 "generated by perf script -g perl\n");
416 416
417 fprintf(ofp, "# Licensed under the terms of the GNU GPL" 417 fprintf(ofp, "# Licensed under the terms of the GNU GPL"
418 " License version 2\n\n"); 418 " License version 2\n\n");
diff --git a/tools/perf/util/scripting-engines/trace-event-python.c b/tools/perf/util/scripting-engines/trace-event-python.c
index 33a632523743..c6d99334bdfa 100644
--- a/tools/perf/util/scripting-engines/trace-event-python.c
+++ b/tools/perf/util/scripting-engines/trace-event-python.c
@@ -442,8 +442,8 @@ static int python_generate_script(const char *outfile)
442 fprintf(stderr, "couldn't open %s\n", fname); 442 fprintf(stderr, "couldn't open %s\n", fname);
443 return -1; 443 return -1;
444 } 444 }
445 fprintf(ofp, "# perf trace event handlers, " 445 fprintf(ofp, "# perf script event handlers, "
446 "generated by perf trace -g python\n"); 446 "generated by perf script -g python\n");
447 447
448 fprintf(ofp, "# Licensed under the terms of the GNU GPL" 448 fprintf(ofp, "# Licensed under the terms of the GNU GPL"
449 " License version 2\n\n"); 449 " License version 2\n\n");
diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c
index fa9d652c2dc3..52672dad1fe9 100644
--- a/tools/perf/util/session.c
+++ b/tools/perf/util/session.c
@@ -101,10 +101,20 @@ struct perf_session *perf_session__new(const char *filename, int mode, bool forc
101 INIT_LIST_HEAD(&self->dead_threads); 101 INIT_LIST_HEAD(&self->dead_threads);
102 self->hists_tree = RB_ROOT; 102 self->hists_tree = RB_ROOT;
103 self->last_match = NULL; 103 self->last_match = NULL;
104 self->mmap_window = 32; 104 /*
105 * On 64bit we can mmap the data file in one go. No need for tiny mmap
106 * slices. On 32bit we use 32MB.
107 */
108#if BITS_PER_LONG == 64
109 self->mmap_window = ULLONG_MAX;
110#else
111 self->mmap_window = 32 * 1024 * 1024ULL;
112#endif
105 self->machines = RB_ROOT; 113 self->machines = RB_ROOT;
106 self->repipe = repipe; 114 self->repipe = repipe;
107 INIT_LIST_HEAD(&self->ordered_samples.samples_head); 115 INIT_LIST_HEAD(&self->ordered_samples.samples);
116 INIT_LIST_HEAD(&self->ordered_samples.sample_cache);
117 INIT_LIST_HEAD(&self->ordered_samples.to_free);
108 machine__init(&self->host_machine, "", HOST_KERNEL_ID); 118 machine__init(&self->host_machine, "", HOST_KERNEL_ID);
109 119
110 if (mode == O_RDONLY) { 120 if (mode == O_RDONLY) {
@@ -262,7 +272,7 @@ static void perf_event_ops__fill_defaults(struct perf_event_ops *handler)
262 if (handler->exit == NULL) 272 if (handler->exit == NULL)
263 handler->exit = process_event_stub; 273 handler->exit = process_event_stub;
264 if (handler->lost == NULL) 274 if (handler->lost == NULL)
265 handler->lost = process_event_stub; 275 handler->lost = event__process_lost;
266 if (handler->read == NULL) 276 if (handler->read == NULL)
267 handler->read = process_event_stub; 277 handler->read = process_event_stub;
268 if (handler->throttle == NULL) 278 if (handler->throttle == NULL)
@@ -386,33 +396,51 @@ static event__swap_op event__swap_ops[] = {
386 396
387struct sample_queue { 397struct sample_queue {
388 u64 timestamp; 398 u64 timestamp;
389 struct sample_event *event; 399 event_t *event;
390 struct list_head list; 400 struct list_head list;
391}; 401};
392 402
403static void perf_session_free_sample_buffers(struct perf_session *session)
404{
405 struct ordered_samples *os = &session->ordered_samples;
406
407 while (!list_empty(&os->to_free)) {
408 struct sample_queue *sq;
409
410 sq = list_entry(os->to_free.next, struct sample_queue, list);
411 list_del(&sq->list);
412 free(sq);
413 }
414}
415
393static void flush_sample_queue(struct perf_session *s, 416static void flush_sample_queue(struct perf_session *s,
394 struct perf_event_ops *ops) 417 struct perf_event_ops *ops)
395{ 418{
396 struct list_head *head = &s->ordered_samples.samples_head; 419 struct ordered_samples *os = &s->ordered_samples;
397 u64 limit = s->ordered_samples.next_flush; 420 struct list_head *head = &os->samples;
398 struct sample_queue *tmp, *iter; 421 struct sample_queue *tmp, *iter;
422 u64 limit = os->next_flush;
423 u64 last_ts = os->last_sample ? os->last_sample->timestamp : 0ULL;
399 424
400 if (!ops->ordered_samples || !limit) 425 if (!ops->ordered_samples || !limit)
401 return; 426 return;
402 427
403 list_for_each_entry_safe(iter, tmp, head, list) { 428 list_for_each_entry_safe(iter, tmp, head, list) {
404 if (iter->timestamp > limit) 429 if (iter->timestamp > limit)
405 return; 430 break;
406
407 if (iter == s->ordered_samples.last_inserted)
408 s->ordered_samples.last_inserted = NULL;
409 431
410 ops->sample((event_t *)iter->event, s); 432 ops->sample(iter->event, s);
411 433
412 s->ordered_samples.last_flush = iter->timestamp; 434 os->last_flush = iter->timestamp;
413 list_del(&iter->list); 435 list_del(&iter->list);
414 free(iter->event); 436 list_add(&iter->list, &os->sample_cache);
415 free(iter); 437 }
438
439 if (list_empty(head)) {
440 os->last_sample = NULL;
441 } else if (last_ts <= limit) {
442 os->last_sample =
443 list_entry(head->prev, struct sample_queue, list);
416 } 444 }
417} 445}
418 446
@@ -465,104 +493,87 @@ static int process_finished_round(event_t *event __used,
465 return 0; 493 return 0;
466} 494}
467 495
468static void __queue_sample_end(struct sample_queue *new, struct list_head *head)
469{
470 struct sample_queue *iter;
471
472 list_for_each_entry_reverse(iter, head, list) {
473 if (iter->timestamp < new->timestamp) {
474 list_add(&new->list, &iter->list);
475 return;
476 }
477 }
478
479 list_add(&new->list, head);
480}
481
482static void __queue_sample_before(struct sample_queue *new,
483 struct sample_queue *iter,
484 struct list_head *head)
485{
486 list_for_each_entry_continue_reverse(iter, head, list) {
487 if (iter->timestamp < new->timestamp) {
488 list_add(&new->list, &iter->list);
489 return;
490 }
491 }
492
493 list_add(&new->list, head);
494}
495
496static void __queue_sample_after(struct sample_queue *new,
497 struct sample_queue *iter,
498 struct list_head *head)
499{
500 list_for_each_entry_continue(iter, head, list) {
501 if (iter->timestamp > new->timestamp) {
502 list_add_tail(&new->list, &iter->list);
503 return;
504 }
505 }
506 list_add_tail(&new->list, head);
507}
508
509/* The queue is ordered by time */ 496/* The queue is ordered by time */
510static void __queue_sample_event(struct sample_queue *new, 497static void __queue_sample_event(struct sample_queue *new,
511 struct perf_session *s) 498 struct perf_session *s)
512{ 499{
513 struct sample_queue *last_inserted = s->ordered_samples.last_inserted; 500 struct ordered_samples *os = &s->ordered_samples;
514 struct list_head *head = &s->ordered_samples.samples_head; 501 struct sample_queue *sample = os->last_sample;
502 u64 timestamp = new->timestamp;
503 struct list_head *p;
515 504
505 os->last_sample = new;
516 506
517 if (!last_inserted) { 507 if (!sample) {
518 __queue_sample_end(new, head); 508 list_add(&new->list, &os->samples);
509 os->max_timestamp = timestamp;
519 return; 510 return;
520 } 511 }
521 512
522 /* 513 /*
523 * Most of the time the current event has a timestamp 514 * last_sample might point to some random place in the list as it's
524 * very close to the last event inserted, unless we just switched 515 * the last queued event. We expect that the new event is close to
525 * to another event buffer. Having a sorting based on a list and 516 * this.
526 * on the last inserted event that is close to the current one is
527 * probably more efficient than an rbtree based sorting.
528 */ 517 */
529 if (last_inserted->timestamp >= new->timestamp) 518 if (sample->timestamp <= timestamp) {
530 __queue_sample_before(new, last_inserted, head); 519 while (sample->timestamp <= timestamp) {
531 else 520 p = sample->list.next;
532 __queue_sample_after(new, last_inserted, head); 521 if (p == &os->samples) {
522 list_add_tail(&new->list, &os->samples);
523 os->max_timestamp = timestamp;
524 return;
525 }
526 sample = list_entry(p, struct sample_queue, list);
527 }
528 list_add_tail(&new->list, &sample->list);
529 } else {
530 while (sample->timestamp > timestamp) {
531 p = sample->list.prev;
532 if (p == &os->samples) {
533 list_add(&new->list, &os->samples);
534 return;
535 }
536 sample = list_entry(p, struct sample_queue, list);
537 }
538 list_add(&new->list, &sample->list);
539 }
533} 540}
534 541
542#define MAX_SAMPLE_BUFFER (64 * 1024 / sizeof(struct sample_queue))
543
535static int queue_sample_event(event_t *event, struct sample_data *data, 544static int queue_sample_event(event_t *event, struct sample_data *data,
536 struct perf_session *s) 545 struct perf_session *s)
537{ 546{
547 struct ordered_samples *os = &s->ordered_samples;
548 struct list_head *sc = &os->sample_cache;
538 u64 timestamp = data->time; 549 u64 timestamp = data->time;
539 struct sample_queue *new; 550 struct sample_queue *new;
540 551
541
542 if (timestamp < s->ordered_samples.last_flush) { 552 if (timestamp < s->ordered_samples.last_flush) {
543 printf("Warning: Timestamp below last timeslice flush\n"); 553 printf("Warning: Timestamp below last timeslice flush\n");
544 return -EINVAL; 554 return -EINVAL;
545 } 555 }
546 556
547 new = malloc(sizeof(*new)); 557 if (!list_empty(sc)) {
548 if (!new) 558 new = list_entry(sc->next, struct sample_queue, list);
549 return -ENOMEM; 559 list_del(&new->list);
550 560 } else if (os->sample_buffer) {
551 new->timestamp = timestamp; 561 new = os->sample_buffer + os->sample_buffer_idx;
552 562 if (++os->sample_buffer_idx == MAX_SAMPLE_BUFFER)
553 new->event = malloc(event->header.size); 563 os->sample_buffer = NULL;
554 if (!new->event) { 564 } else {
555 free(new); 565 os->sample_buffer = malloc(MAX_SAMPLE_BUFFER * sizeof(*new));
556 return -ENOMEM; 566 if (!os->sample_buffer)
567 return -ENOMEM;
568 list_add(&os->sample_buffer->list, &os->to_free);
569 os->sample_buffer_idx = 2;
570 new = os->sample_buffer + 1;
557 } 571 }
558 572
559 memcpy(new->event, event, event->header.size); 573 new->timestamp = timestamp;
574 new->event = event;
560 575
561 __queue_sample_event(new, s); 576 __queue_sample_event(new, s);
562 s->ordered_samples.last_inserted = new;
563
564 if (new->timestamp > s->ordered_samples.max_timestamp)
565 s->ordered_samples.max_timestamp = new->timestamp;
566 577
567 return 0; 578 return 0;
568} 579}
@@ -586,13 +597,13 @@ static int perf_session__process_sample(event_t *event, struct perf_session *s,
586static int perf_session__process_event(struct perf_session *self, 597static int perf_session__process_event(struct perf_session *self,
587 event_t *event, 598 event_t *event,
588 struct perf_event_ops *ops, 599 struct perf_event_ops *ops,
589 u64 offset, u64 head) 600 u64 file_offset)
590{ 601{
591 trace_event(event); 602 trace_event(event);
592 603
593 if (event->header.type < PERF_RECORD_HEADER_MAX) { 604 if (event->header.type < PERF_RECORD_HEADER_MAX) {
594 dump_printf("%#Lx [%#x]: PERF_RECORD_%s", 605 dump_printf("%#Lx [%#x]: PERF_RECORD_%s",
595 offset + head, event->header.size, 606 file_offset, event->header.size,
596 event__name[event->header.type]); 607 event__name[event->header.type]);
597 hists__inc_nr_events(&self->hists, event->header.type); 608 hists__inc_nr_events(&self->hists, event->header.type);
598 } 609 }
@@ -625,7 +636,7 @@ static int perf_session__process_event(struct perf_session *self,
625 return ops->event_type(event, self); 636 return ops->event_type(event, self);
626 case PERF_RECORD_HEADER_TRACING_DATA: 637 case PERF_RECORD_HEADER_TRACING_DATA:
627 /* setup for reading amidst mmap */ 638 /* setup for reading amidst mmap */
628 lseek(self->fd, offset + head, SEEK_SET); 639 lseek(self->fd, file_offset, SEEK_SET);
629 return ops->tracing_data(event, self); 640 return ops->tracing_data(event, self);
630 case PERF_RECORD_HEADER_BUILD_ID: 641 case PERF_RECORD_HEADER_BUILD_ID:
631 return ops->build_id(event, self); 642 return ops->build_id(event, self);
@@ -724,8 +735,7 @@ more:
724 } 735 }
725 736
726 if (size == 0 || 737 if (size == 0 ||
727 (skip = perf_session__process_event(self, &event, ops, 738 (skip = perf_session__process_event(self, &event, ops, head)) < 0) {
728 0, head)) < 0) {
729 dump_printf("%#Lx [%#x]: skipping unknown header type: %d\n", 739 dump_printf("%#Lx [%#x]: skipping unknown header type: %d\n",
730 head, event.header.size, event.header.type); 740 head, event.header.size, event.header.type);
731 /* 741 /*
@@ -751,82 +761,93 @@ more:
751done: 761done:
752 err = 0; 762 err = 0;
753out_err: 763out_err:
764 perf_session_free_sample_buffers(self);
754 return err; 765 return err;
755} 766}
756 767
757int __perf_session__process_events(struct perf_session *self, 768int __perf_session__process_events(struct perf_session *session,
758 u64 data_offset, u64 data_size, 769 u64 data_offset, u64 data_size,
759 u64 file_size, struct perf_event_ops *ops) 770 u64 file_size, struct perf_event_ops *ops)
760{ 771{
761 int err, mmap_prot, mmap_flags; 772 u64 head, page_offset, file_offset, file_pos, progress_next;
762 u64 head, shift; 773 int err, mmap_prot, mmap_flags, map_idx = 0;
763 u64 offset = 0; 774 struct ui_progress *progress;
764 size_t page_size; 775 size_t page_size, mmap_size;
776 char *buf, *mmaps[8];
765 event_t *event; 777 event_t *event;
766 uint32_t size; 778 uint32_t size;
767 char *buf;
768 struct ui_progress *progress = ui_progress__new("Processing events...",
769 self->size);
770 if (progress == NULL)
771 return -1;
772 779
773 perf_event_ops__fill_defaults(ops); 780 perf_event_ops__fill_defaults(ops);
774 781
775 page_size = sysconf(_SC_PAGESIZE); 782 page_size = sysconf(_SC_PAGESIZE);
776 783
777 head = data_offset; 784 page_offset = page_size * (data_offset / page_size);
778 shift = page_size * (head / page_size); 785 file_offset = page_offset;
779 offset += shift; 786 head = data_offset - page_offset;
780 head -= shift; 787
788 if (data_offset + data_size < file_size)
789 file_size = data_offset + data_size;
790
791 progress_next = file_size / 16;
792 progress = ui_progress__new("Processing events...", file_size);
793 if (progress == NULL)
794 return -1;
795
796 mmap_size = session->mmap_window;
797 if (mmap_size > file_size)
798 mmap_size = file_size;
799
800 memset(mmaps, 0, sizeof(mmaps));
781 801
782 mmap_prot = PROT_READ; 802 mmap_prot = PROT_READ;
783 mmap_flags = MAP_SHARED; 803 mmap_flags = MAP_SHARED;
784 804
785 if (self->header.needs_swap) { 805 if (session->header.needs_swap) {
786 mmap_prot |= PROT_WRITE; 806 mmap_prot |= PROT_WRITE;
787 mmap_flags = MAP_PRIVATE; 807 mmap_flags = MAP_PRIVATE;
788 } 808 }
789remap: 809remap:
790 buf = mmap(NULL, page_size * self->mmap_window, mmap_prot, 810 buf = mmap(NULL, mmap_size, mmap_prot, mmap_flags, session->fd,
791 mmap_flags, self->fd, offset); 811 file_offset);
792 if (buf == MAP_FAILED) { 812 if (buf == MAP_FAILED) {
793 pr_err("failed to mmap file\n"); 813 pr_err("failed to mmap file\n");
794 err = -errno; 814 err = -errno;
795 goto out_err; 815 goto out_err;
796 } 816 }
817 mmaps[map_idx] = buf;
818 map_idx = (map_idx + 1) & (ARRAY_SIZE(mmaps) - 1);
819 file_pos = file_offset + head;
797 820
798more: 821more:
799 event = (event_t *)(buf + head); 822 event = (event_t *)(buf + head);
800 ui_progress__update(progress, offset);
801 823
802 if (self->header.needs_swap) 824 if (session->header.needs_swap)
803 perf_event_header__bswap(&event->header); 825 perf_event_header__bswap(&event->header);
804 size = event->header.size; 826 size = event->header.size;
805 if (size == 0) 827 if (size == 0)
806 size = 8; 828 size = 8;
807 829
808 if (head + event->header.size >= page_size * self->mmap_window) { 830 if (head + event->header.size >= mmap_size) {
809 int munmap_ret; 831 if (mmaps[map_idx]) {
810 832 munmap(mmaps[map_idx], mmap_size);
811 shift = page_size * (head / page_size); 833 mmaps[map_idx] = NULL;
812 834 }
813 munmap_ret = munmap(buf, page_size * self->mmap_window);
814 assert(munmap_ret == 0);
815 835
816 offset += shift; 836 page_offset = page_size * (head / page_size);
817 head -= shift; 837 file_offset += page_offset;
838 head -= page_offset;
818 goto remap; 839 goto remap;
819 } 840 }
820 841
821 size = event->header.size; 842 size = event->header.size;
822 843
823 dump_printf("\n%#Lx [%#x]: event: %d\n", 844 dump_printf("\n%#Lx [%#x]: event: %d\n",
824 offset + head, event->header.size, event->header.type); 845 file_pos, event->header.size, event->header.type);
825 846
826 if (size == 0 || 847 if (size == 0 ||
827 perf_session__process_event(self, event, ops, offset, head) < 0) { 848 perf_session__process_event(session, event, ops, file_pos) < 0) {
828 dump_printf("%#Lx [%#x]: skipping unknown header type: %d\n", 849 dump_printf("%#Lx [%#x]: skipping unknown header type: %d\n",
829 offset + head, event->header.size, 850 file_offset + head, event->header.size,
830 event->header.type); 851 event->header.type);
831 /* 852 /*
832 * assume we lost track of the stream, check alignment, and 853 * assume we lost track of the stream, check alignment, and
@@ -839,19 +860,41 @@ more:
839 } 860 }
840 861
841 head += size; 862 head += size;
863 file_pos += size;
842 864
843 if (offset + head >= data_offset + data_size) 865 if (file_pos >= progress_next) {
844 goto done; 866 progress_next += file_size / 16;
867 ui_progress__update(progress, file_pos);
868 }
845 869
846 if (offset + head < file_size) 870 if (file_pos < file_size)
847 goto more; 871 goto more;
848done: 872
849 err = 0; 873 err = 0;
850 /* do the final flush for ordered samples */ 874 /* do the final flush for ordered samples */
851 self->ordered_samples.next_flush = ULLONG_MAX; 875 session->ordered_samples.next_flush = ULLONG_MAX;
852 flush_sample_queue(self, ops); 876 flush_sample_queue(session, ops);
853out_err: 877out_err:
854 ui_progress__delete(progress); 878 ui_progress__delete(progress);
879
880 if (ops->lost == event__process_lost &&
881 session->hists.stats.total_lost != 0) {
882 ui__warning("Processed %Lu events and LOST %Lu!\n\n"
883 "Check IO/CPU overload!\n\n",
884 session->hists.stats.total_period,
885 session->hists.stats.total_lost);
886 }
887
888 if (session->hists.stats.nr_unknown_events != 0) {
889 ui__warning("Found %u unknown events!\n\n"
890 "Is this an older tool processing a perf.data "
891 "file generated by a more recent tool?\n\n"
892 "If that is not the case, consider "
893 "reporting to linux-kernel@vger.kernel.org.\n\n",
894 session->hists.stats.nr_unknown_events);
895 }
896
897 perf_session_free_sample_buffers(session);
855 return err; 898 return err;
856} 899}
857 900
diff --git a/tools/perf/util/session.h b/tools/perf/util/session.h
index 9fa0fc2a863f..5bf6efa3788a 100644
--- a/tools/perf/util/session.h
+++ b/tools/perf/util/session.h
@@ -17,8 +17,12 @@ struct ordered_samples {
17 u64 last_flush; 17 u64 last_flush;
18 u64 next_flush; 18 u64 next_flush;
19 u64 max_timestamp; 19 u64 max_timestamp;
20 struct list_head samples_head; 20 struct list_head samples;
21 struct sample_queue *last_inserted; 21 struct list_head sample_cache;
22 struct list_head to_free;
23 struct sample_queue *sample_buffer;
24 struct sample_queue *last_sample;
25 int sample_buffer_idx;
22}; 26};
23 27
24struct perf_session { 28struct perf_session {
diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c
index 0500895a45af..a348906b587d 100644
--- a/tools/perf/util/symbol.c
+++ b/tools/perf/util/symbol.c
@@ -121,7 +121,7 @@ static void __map_groups__fixup_end(struct map_groups *self, enum map_type type)
121 * We still haven't the actual symbols, so guess the 121 * We still haven't the actual symbols, so guess the
122 * last map final address. 122 * last map final address.
123 */ 123 */
124 curr->end = ~0UL; 124 curr->end = ~0ULL;
125} 125}
126 126
127static void map_groups__fixup_end(struct map_groups *self) 127static void map_groups__fixup_end(struct map_groups *self)
diff --git a/tools/perf/util/ui/util.c b/tools/perf/util/ui/util.c
index 056c69521a38..7b5a8926624e 100644
--- a/tools/perf/util/ui/util.c
+++ b/tools/perf/util/ui/util.c
@@ -104,10 +104,24 @@ out_destroy_form:
104 return rc; 104 return rc;
105} 105}
106 106
107static const char yes[] = "Yes", no[] = "No"; 107static const char yes[] = "Yes", no[] = "No",
108 warning_str[] = "Warning!", ok[] = "Ok";
108 109
109bool ui__dialog_yesno(const char *msg) 110bool ui__dialog_yesno(const char *msg)
110{ 111{
111 /* newtWinChoice should really be accepting const char pointers... */ 112 /* newtWinChoice should really be accepting const char pointers... */
112 return newtWinChoice(NULL, (char *)yes, (char *)no, (char *)msg) == 1; 113 return newtWinChoice(NULL, (char *)yes, (char *)no, (char *)msg) == 1;
113} 114}
115
116void ui__warning(const char *format, ...)
117{
118 va_list args;
119
120 va_start(args, format);
121 if (use_browser > 0)
122 newtWinMessagev((char *)warning_str, (char *)ok,
123 (char *)format, args);
124 else
125 vfprintf(stderr, format, args);
126 va_end(args);
127}