aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf
diff options
context:
space:
mode:
authorDaniel Vetter <daniel.vetter@ffwll.ch>2017-03-14 10:07:33 -0400
committerDaniel Vetter <daniel.vetter@ffwll.ch>2017-03-14 10:07:33 -0400
commitb70366e5d31788650b2a5cec5cd13ea80ac7e44a (patch)
treed972ffd190111d699200448494fda333d28b2486 /tools/perf
parentf42e181935d5e5670c87d31ae48063a495bbacae (diff)
parentdb6ccf23e8ba40fc2e8914ec9c0eb950df71d9fe (diff)
Merge tag 'doc-4.11-images' of git://git.lwn.net/linux into drm-misc-next
Pointer for Markus's image conversion work. We need this so we can merge all the pretty drm graphs for 4.12. Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
Diffstat (limited to 'tools/perf')
-rw-r--r--tools/perf/Build5
-rw-r--r--tools/perf/Documentation/perf-annotate.txt4
-rw-r--r--tools/perf/Documentation/perf-c2c.txt2
-rw-r--r--tools/perf/Documentation/perf-config.txt12
-rw-r--r--tools/perf/Documentation/perf-diff.txt19
-rw-r--r--tools/perf/Documentation/perf-ftrace.txt36
-rw-r--r--tools/perf/Documentation/perf-kallsyms.txt24
-rw-r--r--tools/perf/Documentation/perf-record.txt16
-rw-r--r--tools/perf/Documentation/perf-report.txt4
-rw-r--r--tools/perf/Documentation/perf-sched.txt2
-rw-r--r--tools/perf/Documentation/perf-script.txt4
-rw-r--r--tools/perf/Documentation/perf-stat.txt2
-rw-r--r--tools/perf/Documentation/perf-trace.txt8
-rw-r--r--tools/perf/Documentation/tips.txt2
-rw-r--r--tools/perf/MANIFEST1
-rw-r--r--tools/perf/Makefile.config17
-rw-r--r--tools/perf/Makefile.perf5
-rw-r--r--tools/perf/arch/arm64/Makefile1
-rw-r--r--tools/perf/arch/arm64/include/dwarf-regs-table.h12
-rw-r--r--tools/perf/arch/arm64/util/dwarf-regs.c15
-rw-r--r--tools/perf/bench/futex-hash.c4
-rw-r--r--tools/perf/bench/futex-lock-pi.c3
-rw-r--r--tools/perf/bench/futex-requeue.c2
-rw-r--r--tools/perf/bench/futex-wake-parallel.c4
-rw-r--r--tools/perf/bench/futex-wake.c3
-rw-r--r--tools/perf/bench/futex.h4
-rw-r--r--tools/perf/bench/numa.c7
-rw-r--r--tools/perf/builtin-annotate.c4
-rw-r--r--tools/perf/builtin-c2c.c3
-rw-r--r--tools/perf/builtin-diff.c92
-rw-r--r--tools/perf/builtin-ftrace.c265
-rw-r--r--tools/perf/builtin-help.c8
-rw-r--r--tools/perf/builtin-kallsyms.c67
-rw-r--r--tools/perf/builtin-kmem.c12
-rw-r--r--tools/perf/builtin-list.c3
-rw-r--r--tools/perf/builtin-mem.c4
-rw-r--r--tools/perf/builtin-probe.c2
-rw-r--r--tools/perf/builtin-record.c185
-rw-r--r--tools/perf/builtin-report.c25
-rw-r--r--tools/perf/builtin-sched.c144
-rw-r--r--tools/perf/builtin-script.c3
-rw-r--r--tools/perf/builtin-stat.c13
-rw-r--r--tools/perf/builtin-top.c10
-rw-r--r--tools/perf/builtin-trace.c126
-rw-r--r--tools/perf/builtin.h2
-rw-r--r--tools/perf/command-list.txt2
-rw-r--r--tools/perf/perf.c20
-rw-r--r--tools/perf/pmu-events/arch/x86/broadwellde/uncore-cache.json317
-rw-r--r--tools/perf/pmu-events/arch/x86/broadwellde/uncore-memory.json83
-rw-r--r--tools/perf/pmu-events/arch/x86/broadwellde/uncore-power.json84
-rw-r--r--tools/perf/pmu-events/arch/x86/broadwellx/uncore-cache.json317
-rw-r--r--tools/perf/pmu-events/arch/x86/broadwellx/uncore-interconnect.json28
-rw-r--r--tools/perf/pmu-events/arch/x86/broadwellx/uncore-memory.json83
-rw-r--r--tools/perf/pmu-events/arch/x86/broadwellx/uncore-power.json84
-rw-r--r--tools/perf/pmu-events/arch/x86/haswellx/uncore-cache.json317
-rw-r--r--tools/perf/pmu-events/arch/x86/haswellx/uncore-interconnect.json28
-rw-r--r--tools/perf/pmu-events/arch/x86/haswellx/uncore-memory.json83
-rw-r--r--tools/perf/pmu-events/arch/x86/haswellx/uncore-power.json84
-rw-r--r--tools/perf/pmu-events/arch/x86/ivytown/uncore-cache.json322
-rw-r--r--tools/perf/pmu-events/arch/x86/ivytown/uncore-interconnect.json46
-rw-r--r--tools/perf/pmu-events/arch/x86/ivytown/uncore-memory.json75
-rw-r--r--tools/perf/pmu-events/arch/x86/ivytown/uncore-power.json249
-rw-r--r--tools/perf/pmu-events/arch/x86/jaketown/uncore-cache.json209
-rw-r--r--tools/perf/pmu-events/arch/x86/jaketown/uncore-interconnect.json46
-rw-r--r--tools/perf/pmu-events/arch/x86/jaketown/uncore-memory.json79
-rw-r--r--tools/perf/pmu-events/arch/x86/jaketown/uncore-power.json248
-rw-r--r--tools/perf/pmu-events/arch/x86/knightslanding/uncore-memory.json42
-rw-r--r--tools/perf/pmu-events/jevents.c84
-rw-r--r--tools/perf/pmu-events/jevents.h4
-rw-r--r--tools/perf/pmu-events/json.c2
-rw-r--r--tools/perf/pmu-events/pmu-events.h3
-rw-r--r--tools/perf/tests/Build1
-rw-r--r--tools/perf/tests/attr.c2
-rw-r--r--tools/perf/tests/bpf.c42
-rw-r--r--tools/perf/tests/builtin-test.c6
-rw-r--r--tools/perf/tests/code-reading.c2
-rw-r--r--tools/perf/tests/fdarray.c2
-rw-r--r--tools/perf/tests/llvm.c4
-rw-r--r--tools/perf/tests/parse-events.c10
-rw-r--r--tools/perf/tests/parse-no-sample-id-all.c19
-rw-r--r--tools/perf/tests/perf-record.c6
-rw-r--r--tools/perf/tests/python-use.c2
-rw-r--r--tools/perf/tests/tests.h1
-rw-r--r--tools/perf/tests/thread-map.c6
-rw-r--r--tools/perf/tests/topology.c4
-rw-r--r--tools/perf/tests/unit_number__scnprintf.c37
-rw-r--r--tools/perf/tests/vmlinux-kallsyms.c2
-rw-r--r--tools/perf/ui/browsers/hists.c60
-rw-r--r--tools/perf/ui/browsers/map.c6
-rw-r--r--tools/perf/ui/hist.c2
-rw-r--r--tools/perf/ui/setup.c1
-rw-r--r--tools/perf/util/Build1
-rw-r--r--tools/perf/util/annotate.c2
-rw-r--r--tools/perf/util/bpf-loader.c4
-rw-r--r--tools/perf/util/callchain.c16
-rw-r--r--tools/perf/util/cgroup.c26
-rw-r--r--tools/perf/util/config.c23
-rw-r--r--tools/perf/util/cpumap.c22
-rw-r--r--tools/perf/util/cpumap.h1
-rw-r--r--tools/perf/util/data-convert-bt.c7
-rw-r--r--tools/perf/util/debug.c17
-rw-r--r--tools/perf/util/debug.h1
-rw-r--r--tools/perf/util/dso.c52
-rw-r--r--tools/perf/util/env.c2
-rw-r--r--tools/perf/util/event.c2
-rw-r--r--tools/perf/util/evlist.c12
-rw-r--r--tools/perf/util/evlist.h2
-rw-r--r--tools/perf/util/evsel.c66
-rw-r--r--tools/perf/util/evsel_fprintf.c1
-rw-r--r--tools/perf/util/header.c40
-rw-r--r--tools/perf/util/hist.c10
-rw-r--r--tools/perf/util/intel-pt-decoder/Build6
-rw-r--r--tools/perf/util/intel-pt-decoder/intel-pt-decoder.c5
-rw-r--r--tools/perf/util/intel-pt-decoder/intel-pt-pkt-decoder.c2
-rw-r--r--tools/perf/util/intel-pt.c4
-rw-r--r--tools/perf/util/llvm-utils.c4
-rw-r--r--tools/perf/util/machine.c25
-rw-r--r--tools/perf/util/machine.h1
-rw-r--r--tools/perf/util/map.c4
-rw-r--r--tools/perf/util/parse-events.c155
-rw-r--r--tools/perf/util/parse-events.h2
-rw-r--r--tools/perf/util/parse-events.y49
-rw-r--r--tools/perf/util/pmu.c132
-rw-r--r--tools/perf/util/pmu.h1
-rw-r--r--tools/perf/util/probe-event.c15
-rw-r--r--tools/perf/util/probe-finder.c4
-rw-r--r--tools/perf/util/scripting-engines/Build2
-rw-r--r--tools/perf/util/scripting-engines/trace-event-perl.c11
-rw-r--r--tools/perf/util/scripting-engines/trace-event-python.c5
-rw-r--r--tools/perf/util/session.c6
-rw-r--r--tools/perf/util/setup.py9
-rw-r--r--tools/perf/util/sort.c8
-rw-r--r--tools/perf/util/sort.h2
-rw-r--r--tools/perf/util/stat.c2
-rw-r--r--tools/perf/util/strfilter.c1
-rw-r--r--tools/perf/util/string.c2
-rw-r--r--tools/perf/util/symbol-elf.c2
-rw-r--r--tools/perf/util/symbol.c6
-rw-r--r--tools/perf/util/symbol_fprintf.c2
-rw-r--r--tools/perf/util/thread_map.c2
-rw-r--r--tools/perf/util/trace-event-info.c71
-rw-r--r--tools/perf/util/trace-event-parse.c17
-rw-r--r--tools/perf/util/trace-event-read.c77
-rw-r--r--tools/perf/util/trace-event.h1
-rw-r--r--tools/perf/util/unwind-libunwind-local.c54
-rw-r--r--tools/perf/util/util.c15
-rw-r--r--tools/perf/util/util.h3
147 files changed, 4816 insertions, 538 deletions
diff --git a/tools/perf/Build b/tools/perf/Build
index b12d5d1666e3..9b79f8d7db50 100644
--- a/tools/perf/Build
+++ b/tools/perf/Build
@@ -3,10 +3,12 @@ perf-y += builtin-annotate.o
3perf-y += builtin-config.o 3perf-y += builtin-config.o
4perf-y += builtin-diff.o 4perf-y += builtin-diff.o
5perf-y += builtin-evlist.o 5perf-y += builtin-evlist.o
6perf-y += builtin-ftrace.o
6perf-y += builtin-help.o 7perf-y += builtin-help.o
7perf-y += builtin-sched.o 8perf-y += builtin-sched.o
8perf-y += builtin-buildid-list.o 9perf-y += builtin-buildid-list.o
9perf-y += builtin-buildid-cache.o 10perf-y += builtin-buildid-cache.o
11perf-y += builtin-kallsyms.o
10perf-y += builtin-list.o 12perf-y += builtin-list.o
11perf-y += builtin-record.o 13perf-y += builtin-record.o
12perf-y += builtin-report.o 14perf-y += builtin-report.o
@@ -39,8 +41,7 @@ CFLAGS_builtin-help.o += $(paths)
39CFLAGS_builtin-timechart.o += $(paths) 41CFLAGS_builtin-timechart.o += $(paths)
40CFLAGS_perf.o += -DPERF_HTML_PATH="BUILD_STR($(htmldir_SQ))" \ 42CFLAGS_perf.o += -DPERF_HTML_PATH="BUILD_STR($(htmldir_SQ))" \
41 -DPERF_EXEC_PATH="BUILD_STR($(perfexecdir_SQ))" \ 43 -DPERF_EXEC_PATH="BUILD_STR($(perfexecdir_SQ))" \
42 -DPREFIX="BUILD_STR($(prefix_SQ))" \ 44 -DPREFIX="BUILD_STR($(prefix_SQ))"
43 -include $(OUTPUT)PERF-VERSION-FILE
44CFLAGS_builtin-trace.o += -DSTRACE_GROUPS_DIR="BUILD_STR($(STRACE_GROUPS_DIR_SQ))" 45CFLAGS_builtin-trace.o += -DSTRACE_GROUPS_DIR="BUILD_STR($(STRACE_GROUPS_DIR_SQ))"
45CFLAGS_builtin-report.o += -DTIPDIR="BUILD_STR($(tipdir_SQ))" 46CFLAGS_builtin-report.o += -DTIPDIR="BUILD_STR($(tipdir_SQ))"
46CFLAGS_builtin-report.o += -DDOCDIR="BUILD_STR($(srcdir_SQ)/Documentation)" 47CFLAGS_builtin-report.o += -DDOCDIR="BUILD_STR($(srcdir_SQ)/Documentation)"
diff --git a/tools/perf/Documentation/perf-annotate.txt b/tools/perf/Documentation/perf-annotate.txt
index 8ffbd272952d..a89273d8e744 100644
--- a/tools/perf/Documentation/perf-annotate.txt
+++ b/tools/perf/Documentation/perf-annotate.txt
@@ -39,6 +39,10 @@ OPTIONS
39--verbose:: 39--verbose::
40 Be more verbose. (Show symbol address, etc) 40 Be more verbose. (Show symbol address, etc)
41 41
42-q::
43--quiet::
44 Do not show any message. (Suppress -v)
45
42-D:: 46-D::
43--dump-raw-trace:: 47--dump-raw-trace::
44 Dump raw trace in ASCII. 48 Dump raw trace in ASCII.
diff --git a/tools/perf/Documentation/perf-c2c.txt b/tools/perf/Documentation/perf-c2c.txt
index 3f06730c7f47..2da07e51e119 100644
--- a/tools/perf/Documentation/perf-c2c.txt
+++ b/tools/perf/Documentation/perf-c2c.txt
@@ -248,7 +248,7 @@ output fields set for caheline offsets output:
248 Code address, Code symbol, Shared Object, Source line 248 Code address, Code symbol, Shared Object, Source line
249 dso - coalesced by shared object 249 dso - coalesced by shared object
250 250
251By default the coalescing is setup with 'pid,tid,iaddr'. 251By default the coalescing is setup with 'pid,iaddr'.
252 252
253STDIO OUTPUT 253STDIO OUTPUT
254------------ 254------------
diff --git a/tools/perf/Documentation/perf-config.txt b/tools/perf/Documentation/perf-config.txt
index 9365b75fd04f..5b4fff3adc4b 100644
--- a/tools/perf/Documentation/perf-config.txt
+++ b/tools/perf/Documentation/perf-config.txt
@@ -498,6 +498,18 @@ record.*::
498 But if this option is 'no-cache', it will not update the build-id cache. 498 But if this option is 'no-cache', it will not update the build-id cache.
499 'skip' skips post-processing and does not update the cache. 499 'skip' skips post-processing and does not update the cache.
500 500
501diff.*::
502 diff.order::
503 This option sets the number of columns to sort the result.
504 The default is 0, which means sorting by baseline.
505 Setting it to 1 will sort the result by delta (or other
506 compute method selected).
507
508 diff.compute::
509 This options sets the method for computing the diff result.
510 Possible values are 'delta', 'delta-abs', 'ratio' and
511 'wdiff'. Default is 'delta'.
512
501SEE ALSO 513SEE ALSO
502-------- 514--------
503linkperf:perf[1] 515linkperf:perf[1]
diff --git a/tools/perf/Documentation/perf-diff.txt b/tools/perf/Documentation/perf-diff.txt
index 3e9490b9c533..a79c84ae61aa 100644
--- a/tools/perf/Documentation/perf-diff.txt
+++ b/tools/perf/Documentation/perf-diff.txt
@@ -73,6 +73,10 @@ OPTIONS
73 Be verbose, for instance, show the raw counts in addition to the 73 Be verbose, for instance, show the raw counts in addition to the
74 diff. 74 diff.
75 75
76-q::
77--quiet::
78 Do not show any message. (Suppress -v)
79
76-f:: 80-f::
77--force:: 81--force::
78 Don't do ownership validation. 82 Don't do ownership validation.
@@ -86,8 +90,9 @@ OPTIONS
86 90
87-c:: 91-c::
88--compute:: 92--compute::
89 Differential computation selection - delta,ratio,wdiff (default is delta). 93 Differential computation selection - delta, ratio, wdiff, delta-abs
90 See COMPARISON METHODS section for more info. 94 (default is delta-abs). Default can be changed using diff.compute
95 config option. See COMPARISON METHODS section for more info.
91 96
92-p:: 97-p::
93--period:: 98--period::
@@ -99,7 +104,11 @@ OPTIONS
99 104
100-o:: 105-o::
101--order:: 106--order::
102 Specify compute sorting column number. 107 Specify compute sorting column number. 0 means sorting by baseline
108 overhead and 1 (default) means sorting by computed value of column 1
109 (data from the first file other base baseline). Values more than 1
110 can be used only if enough data files are provided.
111 The default value can be set using the diff.order config option.
103 112
104--percentage:: 113--percentage::
105 Determine how to display the overhead percentage of filtered entries. 114 Determine how to display the overhead percentage of filtered entries.
@@ -181,6 +190,10 @@ with:
181 relative to how entries are filtered. Use --percentage=absolute to 190 relative to how entries are filtered. Use --percentage=absolute to
182 prevent such fluctuation. 191 prevent such fluctuation.
183 192
193delta-abs
194~~~~~~~~~
195Same as 'delta` method, but sort the result with the absolute values.
196
184ratio 197ratio
185~~~~~ 198~~~~~
186If specified the 'Ratio' column is displayed with value 'r' computed as: 199If specified the 'Ratio' column is displayed with value 'r' computed as:
diff --git a/tools/perf/Documentation/perf-ftrace.txt b/tools/perf/Documentation/perf-ftrace.txt
new file mode 100644
index 000000000000..2d96de6132a9
--- /dev/null
+++ b/tools/perf/Documentation/perf-ftrace.txt
@@ -0,0 +1,36 @@
1perf-ftrace(1)
2=============
3
4NAME
5----
6perf-ftrace - simple wrapper for kernel's ftrace functionality
7
8
9SYNOPSIS
10--------
11[verse]
12'perf ftrace' <command>
13
14DESCRIPTION
15-----------
16The 'perf ftrace' command is a simple wrapper of kernel's ftrace
17functionality. It only supports single thread tracing currently and
18just reads trace_pipe in text and then write it to stdout.
19
20The following options apply to perf ftrace.
21
22OPTIONS
23-------
24
25-t::
26--tracer=::
27 Tracer to use: function_graph or function.
28
29-v::
30--verbose=::
31 Verbosity level.
32
33
34SEE ALSO
35--------
36linkperf:perf-record[1], linkperf:perf-trace[1]
diff --git a/tools/perf/Documentation/perf-kallsyms.txt b/tools/perf/Documentation/perf-kallsyms.txt
new file mode 100644
index 000000000000..954ea9e21236
--- /dev/null
+++ b/tools/perf/Documentation/perf-kallsyms.txt
@@ -0,0 +1,24 @@
1perf-kallsyms(1)
2==============
3
4NAME
5----
6perf-kallsyms - Searches running kernel for symbols
7
8SYNOPSIS
9--------
10[verse]
11'perf kallsyms <options> symbol_name[,symbol_name...]'
12
13DESCRIPTION
14-----------
15This command searches the running kernel kallsyms file for the given symbol(s)
16and prints information about it, including the DSO, the kallsyms begin/end
17addresses and the addresses in the ELF kallsyms symbol table (for symbols in
18modules).
19
20OPTIONS
21-------
22-v::
23--verbose=::
24 Increase verbosity level, showing details about symbol table loading, etc.
diff --git a/tools/perf/Documentation/perf-record.txt b/tools/perf/Documentation/perf-record.txt
index 5054d9147f0f..b16003ec14a7 100644
--- a/tools/perf/Documentation/perf-record.txt
+++ b/tools/perf/Documentation/perf-record.txt
@@ -157,7 +157,7 @@ OPTIONS
157 157
158-a:: 158-a::
159--all-cpus:: 159--all-cpus::
160 System-wide collection from all CPUs. 160 System-wide collection from all CPUs (default if no target is specified).
161 161
162-p:: 162-p::
163--pid=:: 163--pid=::
@@ -421,9 +421,19 @@ Configure all used events to run in user space.
421--timestamp-filename 421--timestamp-filename
422Append timestamp to output file name. 422Append timestamp to output file name.
423 423
424--switch-output:: 424--switch-output[=mode]::
425Generate multiple perf.data files, timestamp prefixed, switching to a new one 425Generate multiple perf.data files, timestamp prefixed, switching to a new one
426when receiving a SIGUSR2. 426based on 'mode' value:
427 "signal" - when receiving a SIGUSR2 (default value) or
428 <size> - when reaching the size threshold, size is expected to
429 be a number with appended unit character - B/K/M/G
430 <time> - when reaching the time threshold, size is expected to
431 be a number with appended unit character - s/m/h/d
432
433 Note: the precision of the size threshold hugely depends
434 on your configuration - the number and size of your ring
435 buffers (-m). It is generally more precise for higher sizes
436 (like >5M), for lower values expect different sizes.
427 437
428A possible use case is to, given an external event, slice the perf.data file 438A possible use case is to, given an external event, slice the perf.data file
429that gets then processed, possibly via a perf script, to decide if that 439that gets then processed, possibly via a perf script, to decide if that
diff --git a/tools/perf/Documentation/perf-report.txt b/tools/perf/Documentation/perf-report.txt
index f2914f03ae7b..c04cc0647c16 100644
--- a/tools/perf/Documentation/perf-report.txt
+++ b/tools/perf/Documentation/perf-report.txt
@@ -25,6 +25,10 @@ OPTIONS
25--verbose:: 25--verbose::
26 Be more verbose. (show symbol address, etc) 26 Be more verbose. (show symbol address, etc)
27 27
28-q::
29--quiet::
30 Do not show any message. (Suppress -v)
31
28-n:: 32-n::
29--show-nr-samples:: 33--show-nr-samples::
30 Show the number of samples for each symbol 34 Show the number of samples for each symbol
diff --git a/tools/perf/Documentation/perf-sched.txt b/tools/perf/Documentation/perf-sched.txt
index 76173969ab80..d33deddb0146 100644
--- a/tools/perf/Documentation/perf-sched.txt
+++ b/tools/perf/Documentation/perf-sched.txt
@@ -143,6 +143,8 @@ OPTIONS for 'perf sched timehist'
143 stop time is not given (i.e, time string is 'x.y,') then analysis goes 143 stop time is not given (i.e, time string is 'x.y,') then analysis goes
144 to end of file. 144 to end of file.
145 145
146--state::
147 Show task state when it switched out.
146 148
147SEE ALSO 149SEE ALSO
148-------- 150--------
diff --git a/tools/perf/Documentation/perf-script.txt b/tools/perf/Documentation/perf-script.txt
index 5dc5c6a09ac4..4ed5f239ba7d 100644
--- a/tools/perf/Documentation/perf-script.txt
+++ b/tools/perf/Documentation/perf-script.txt
@@ -36,7 +36,7 @@ There are several variants of perf script:
36 36
37 'perf script 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 script --list' i.e. the actual script name minus any language
40 extension. The perf.data output from a previous run of 'perf script 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
@@ -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-script=:: 79--dump-raw-trace=::
80 Display verbose dump of the trace data. 80 Display verbose dump of the trace data.
81 81
82-L:: 82-L::
diff --git a/tools/perf/Documentation/perf-stat.txt b/tools/perf/Documentation/perf-stat.txt
index d96ccd4844df..aecf2a87e7d6 100644
--- a/tools/perf/Documentation/perf-stat.txt
+++ b/tools/perf/Documentation/perf-stat.txt
@@ -63,7 +63,7 @@ report::
63 63
64-a:: 64-a::
65--all-cpus:: 65--all-cpus::
66 system-wide collection from all CPUs 66 system-wide collection from all CPUs (default if no target is specified)
67 67
68-c:: 68-c::
69--scale:: 69--scale::
diff --git a/tools/perf/Documentation/perf-trace.txt b/tools/perf/Documentation/perf-trace.txt
index 781b019751a4..afd728672b6f 100644
--- a/tools/perf/Documentation/perf-trace.txt
+++ b/tools/perf/Documentation/perf-trace.txt
@@ -35,7 +35,10 @@ OPTIONS
35 35
36-e:: 36-e::
37--expr:: 37--expr::
38 List of syscalls to show, currently only syscall names. 38--event::
39 List of syscalls and other perf events (tracepoints, HW cache events,
40 etc) to show.
41 See 'perf list' for a complete list of events.
39 Prefixing with ! shows all syscalls but the ones specified. You may 42 Prefixing with ! shows all syscalls but the ones specified. You may
40 need to escape it. 43 need to escape it.
41 44
@@ -135,9 +138,6 @@ the thread executes on the designated CPUs. Default is to monitor all CPUs.
135--kernel-syscall-graph:: 138--kernel-syscall-graph::
136 Show the kernel callchains on the syscall exit path. 139 Show the kernel callchains on the syscall exit path.
137 140
138--event::
139 Trace other events, see 'perf list' for a complete list.
140
141--max-stack:: 141--max-stack::
142 Set the stack depth limit when parsing the callchain, anything 142 Set the stack depth limit when parsing the callchain, anything
143 beyond the specified depth will be ignored. Note that at this point 143 beyond the specified depth will be ignored. Note that at this point
diff --git a/tools/perf/Documentation/tips.txt b/tools/perf/Documentation/tips.txt
index 8a6479c0eac9..170b0289a7bc 100644
--- a/tools/perf/Documentation/tips.txt
+++ b/tools/perf/Documentation/tips.txt
@@ -22,7 +22,7 @@ If you have debuginfo enabled, try: perf report -s sym,srcline
22For memory address profiling, try: perf mem record / perf mem report 22For memory address profiling, try: perf mem record / perf mem report
23For tracepoint events, try: perf report -s trace_fields 23For tracepoint events, try: perf report -s trace_fields
24To record callchains for each sample: perf record -g 24To record callchains for each sample: perf record -g
25To record every process run by an user: perf record -u <user> 25To record every process run by a user: perf record -u <user>
26Skip collecing build-id when recording: perf record -B 26Skip collecing build-id when recording: perf record -B
27To change sampling frequency to 100 Hz: perf record -F 100 27To change sampling frequency to 100 Hz: perf record -F 100
28See assembly instructions with percentage: perf annotate <symbol> 28See assembly instructions with percentage: perf annotate <symbol>
diff --git a/tools/perf/MANIFEST b/tools/perf/MANIFEST
index a511e5f31e36..8672f835ae4e 100644
--- a/tools/perf/MANIFEST
+++ b/tools/perf/MANIFEST
@@ -61,6 +61,7 @@ tools/include/asm-generic/bitops.h
61tools/include/linux/atomic.h 61tools/include/linux/atomic.h
62tools/include/linux/bitops.h 62tools/include/linux/bitops.h
63tools/include/linux/compiler.h 63tools/include/linux/compiler.h
64tools/include/linux/compiler-gcc.h
64tools/include/linux/coresight-pmu.h 65tools/include/linux/coresight-pmu.h
65tools/include/linux/filter.h 66tools/include/linux/filter.h
66tools/include/linux/hash.h 67tools/include/linux/hash.h
diff --git a/tools/perf/Makefile.config b/tools/perf/Makefile.config
index 76c84f0eec52..27c9fbca7bd9 100644
--- a/tools/perf/Makefile.config
+++ b/tools/perf/Makefile.config
@@ -144,8 +144,12 @@ ifndef DEBUG
144endif 144endif
145 145
146ifeq ($(DEBUG),0) 146ifeq ($(DEBUG),0)
147ifeq ($(CC), clang)
148 CFLAGS += -O3
149else
147 CFLAGS += -O6 150 CFLAGS += -O6
148endif 151endif
152endif
149 153
150ifdef PARSER_DEBUG 154ifdef PARSER_DEBUG
151 PARSER_DEBUG_BISON := -t 155 PARSER_DEBUG_BISON := -t
@@ -171,6 +175,10 @@ PYTHON_CONFIG_SQ := $(call shell-sq,$(PYTHON_CONFIG))
171PYTHON_EMBED_LDOPTS := $(shell $(PYTHON_CONFIG_SQ) --ldflags 2>/dev/null) 175PYTHON_EMBED_LDOPTS := $(shell $(PYTHON_CONFIG_SQ) --ldflags 2>/dev/null)
172PYTHON_EMBED_CCOPTS := $(shell $(PYTHON_CONFIG_SQ) --cflags 2>/dev/null) 176PYTHON_EMBED_CCOPTS := $(shell $(PYTHON_CONFIG_SQ) --cflags 2>/dev/null)
173 177
178ifeq ($(CC), clang)
179 PYTHON_EMBED_CCOPTS := $(filter-out -specs=%,$(PYTHON_EMBED_CCOPTS))
180endif
181
174FEATURE_CHECK_CFLAGS-libpython := $(PYTHON_EMBED_CCOPTS) 182FEATURE_CHECK_CFLAGS-libpython := $(PYTHON_EMBED_CCOPTS)
175FEATURE_CHECK_LDFLAGS-libpython := $(PYTHON_EMBED_LDOPTS) 183FEATURE_CHECK_LDFLAGS-libpython := $(PYTHON_EMBED_LDOPTS)
176FEATURE_CHECK_CFLAGS-libpython-version := $(PYTHON_EMBED_CCOPTS) 184FEATURE_CHECK_CFLAGS-libpython-version := $(PYTHON_EMBED_CCOPTS)
@@ -291,8 +299,10 @@ else
291 endif 299 endif
292 endif 300 endif
293 ifneq ($(feature-dwarf), 1) 301 ifneq ($(feature-dwarf), 1)
294 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); 302 ifndef NO_DWARF
295 NO_DWARF := 1 303 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);
304 NO_DWARF := 1
305 endif
296 else 306 else
297 ifneq ($(feature-dwarf_getlocations), 1) 307 ifneq ($(feature-dwarf_getlocations), 1)
298 msg := $(warning Old libdw.h, finding variables at given 'perf probe' point will not work, install elfutils-devel/libdw-dev >= 0.157); 308 msg := $(warning Old libdw.h, finding variables at given 'perf probe' point will not work, install elfutils-devel/libdw-dev >= 0.157);
@@ -595,6 +605,9 @@ else
595 PYTHON_EMBED_LDFLAGS := $(call strip-libs,$(PYTHON_EMBED_LDOPTS)) 605 PYTHON_EMBED_LDFLAGS := $(call strip-libs,$(PYTHON_EMBED_LDOPTS))
596 PYTHON_EMBED_LIBADD := $(call grep-libs,$(PYTHON_EMBED_LDOPTS)) -lutil 606 PYTHON_EMBED_LIBADD := $(call grep-libs,$(PYTHON_EMBED_LDOPTS)) -lutil
597 PYTHON_EMBED_CCOPTS := $(shell $(PYTHON_CONFIG_SQ) --cflags 2>/dev/null) 607 PYTHON_EMBED_CCOPTS := $(shell $(PYTHON_CONFIG_SQ) --cflags 2>/dev/null)
608 ifeq ($(CC), clang)
609 PYTHON_EMBED_CCOPTS := $(filter-out -specs=%,$(PYTHON_EMBED_CCOPTS))
610 endif
598 FLAGS_PYTHON_EMBED := $(PYTHON_EMBED_CCOPTS) $(PYTHON_EMBED_LDOPTS) 611 FLAGS_PYTHON_EMBED := $(PYTHON_EMBED_CCOPTS) $(PYTHON_EMBED_LDOPTS)
599 612
600 ifneq ($(feature-libpython), 1) 613 ifneq ($(feature-libpython), 1)
diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf
index 8bb16aa9d661..79fe31f20a17 100644
--- a/tools/perf/Makefile.perf
+++ b/tools/perf/Makefile.perf
@@ -661,6 +661,7 @@ ifndef NO_PERF_READ_VDSOX32
661endif 661endif
662ifndef NO_JVMTI 662ifndef NO_JVMTI
663 $(call QUIET_INSTALL, $(LIBJVMTI)) \ 663 $(call QUIET_INSTALL, $(LIBJVMTI)) \
664 $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(libdir_SQ)'; \
664 $(INSTALL) $(OUTPUT)$(LIBJVMTI) '$(DESTDIR_SQ)$(libdir_SQ)'; 665 $(INSTALL) $(OUTPUT)$(LIBJVMTI) '$(DESTDIR_SQ)$(libdir_SQ)';
665endif 666endif
666 $(call QUIET_INSTALL, libexec) \ 667 $(call QUIET_INSTALL, libexec) \
@@ -725,13 +726,13 @@ config-clean:
725 $(call QUIET_CLEAN, config) 726 $(call QUIET_CLEAN, config)
726 $(Q)$(MAKE) -C $(srctree)/tools/build/feature/ $(if $(OUTPUT),OUTPUT=$(OUTPUT)feature/,) clean >/dev/null 727 $(Q)$(MAKE) -C $(srctree)/tools/build/feature/ $(if $(OUTPUT),OUTPUT=$(OUTPUT)feature/,) clean >/dev/null
727 728
728clean:: $(LIBTRACEEVENT)-clean $(LIBAPI)-clean $(LIBBPF)-clean $(LIBSUBCMD)-clean config-clean 729clean:: $(LIBTRACEEVENT)-clean $(LIBAPI)-clean $(LIBBPF)-clean $(LIBSUBCMD)-clean config-clean fixdep-clean
729 $(call QUIET_CLEAN, core-objs) $(RM) $(LIB_FILE) $(OUTPUT)perf-archive $(OUTPUT)perf-with-kcore $(LANG_BINDINGS) 730 $(call QUIET_CLEAN, core-objs) $(RM) $(LIB_FILE) $(OUTPUT)perf-archive $(OUTPUT)perf-with-kcore $(LANG_BINDINGS)
730 $(Q)find $(if $(OUTPUT),$(OUTPUT),.) -name '*.o' -delete -o -name '\.*.cmd' -delete -o -name '\.*.d' -delete 731 $(Q)find $(if $(OUTPUT),$(OUTPUT),.) -name '*.o' -delete -o -name '\.*.cmd' -delete -o -name '\.*.d' -delete
731 $(Q)$(RM) $(OUTPUT).config-detected 732 $(Q)$(RM) $(OUTPUT).config-detected
732 $(call QUIET_CLEAN, core-progs) $(RM) $(ALL_PROGRAMS) perf perf-read-vdso32 perf-read-vdsox32 $(OUTPUT)pmu-events/jevents $(OUTPUT)$(LIBJVMTI).so 733 $(call QUIET_CLEAN, core-progs) $(RM) $(ALL_PROGRAMS) perf perf-read-vdso32 perf-read-vdsox32 $(OUTPUT)pmu-events/jevents $(OUTPUT)$(LIBJVMTI).so
733 $(call QUIET_CLEAN, core-gen) $(RM) *.spec *.pyc *.pyo */*.pyc */*.pyo $(OUTPUT)common-cmds.h TAGS tags cscope* $(OUTPUT)PERF-VERSION-FILE $(OUTPUT)FEATURE-DUMP $(OUTPUT)util/*-bison* $(OUTPUT)util/*-flex* \ 734 $(call QUIET_CLEAN, core-gen) $(RM) *.spec *.pyc *.pyo */*.pyc */*.pyo $(OUTPUT)common-cmds.h TAGS tags cscope* $(OUTPUT)PERF-VERSION-FILE $(OUTPUT)FEATURE-DUMP $(OUTPUT)util/*-bison* $(OUTPUT)util/*-flex* \
734 $(OUTPUT)util/intel-pt-decoder/inat-tables.c $(OUTPUT)fixdep \ 735 $(OUTPUT)util/intel-pt-decoder/inat-tables.c \
735 $(OUTPUT)tests/llvm-src-{base,kbuild,prologue,relocation}.c \ 736 $(OUTPUT)tests/llvm-src-{base,kbuild,prologue,relocation}.c \
736 $(OUTPUT)pmu-events/pmu-events.c 737 $(OUTPUT)pmu-events/pmu-events.c
737 $(QUIET_SUBDIR0)Documentation $(QUIET_SUBDIR1) clean 738 $(QUIET_SUBDIR0)Documentation $(QUIET_SUBDIR1) clean
diff --git a/tools/perf/arch/arm64/Makefile b/tools/perf/arch/arm64/Makefile
index 18b13518d8d8..eebe1ec9d2ee 100644
--- a/tools/perf/arch/arm64/Makefile
+++ b/tools/perf/arch/arm64/Makefile
@@ -2,3 +2,4 @@ ifndef NO_DWARF
2PERF_HAVE_DWARF_REGS := 1 2PERF_HAVE_DWARF_REGS := 1
3endif 3endif
4PERF_HAVE_JITDUMP := 1 4PERF_HAVE_JITDUMP := 1
5PERF_HAVE_ARCH_REGS_QUERY_REGISTER_OFFSET := 1
diff --git a/tools/perf/arch/arm64/include/dwarf-regs-table.h b/tools/perf/arch/arm64/include/dwarf-regs-table.h
index 26759363f921..36e375f5a211 100644
--- a/tools/perf/arch/arm64/include/dwarf-regs-table.h
+++ b/tools/perf/arch/arm64/include/dwarf-regs-table.h
@@ -2,12 +2,12 @@
2/* This is included in perf/util/dwarf-regs.c */ 2/* This is included in perf/util/dwarf-regs.c */
3 3
4static const char * const aarch64_regstr_tbl[] = { 4static const char * const aarch64_regstr_tbl[] = {
5 "%r0", "%r1", "%r2", "%r3", "%r4", 5 "%x0", "%x1", "%x2", "%x3", "%x4",
6 "%r5", "%r6", "%r7", "%r8", "%r9", 6 "%x5", "%x6", "%x7", "%x8", "%x9",
7 "%r10", "%r11", "%r12", "%r13", "%r14", 7 "%x10", "%x11", "%x12", "%x13", "%x14",
8 "%r15", "%r16", "%r17", "%r18", "%r19", 8 "%x15", "%x16", "%x17", "%x18", "%x19",
9 "%r20", "%r21", "%r22", "%r23", "%r24", 9 "%x20", "%x21", "%x22", "%x23", "%x24",
10 "%r25", "%r26", "%r27", "%r28", "%r29", 10 "%x25", "%x26", "%x27", "%x28", "%x29",
11 "%lr", "%sp", 11 "%lr", "%sp",
12}; 12};
13#endif 13#endif
diff --git a/tools/perf/arch/arm64/util/dwarf-regs.c b/tools/perf/arch/arm64/util/dwarf-regs.c
index d49efeb8172e..068b6189157b 100644
--- a/tools/perf/arch/arm64/util/dwarf-regs.c
+++ b/tools/perf/arch/arm64/util/dwarf-regs.c
@@ -10,17 +10,20 @@
10 10
11#include <stddef.h> 11#include <stddef.h>
12#include <dwarf-regs.h> 12#include <dwarf-regs.h>
13#include <linux/ptrace.h> /* for struct user_pt_regs */
14#include "util.h"
13 15
14struct pt_regs_dwarfnum { 16struct pt_regs_dwarfnum {
15 const char *name; 17 const char *name;
16 unsigned int dwarfnum; 18 unsigned int dwarfnum;
17}; 19};
18 20
19#define STR(s) #s
20#define REG_DWARFNUM_NAME(r, num) {.name = r, .dwarfnum = num} 21#define REG_DWARFNUM_NAME(r, num) {.name = r, .dwarfnum = num}
21#define GPR_DWARFNUM_NAME(num) \ 22#define GPR_DWARFNUM_NAME(num) \
22 {.name = STR(%x##num), .dwarfnum = num} 23 {.name = STR(%x##num), .dwarfnum = num}
23#define REG_DWARFNUM_END {.name = NULL, .dwarfnum = 0} 24#define REG_DWARFNUM_END {.name = NULL, .dwarfnum = 0}
25#define DWARFNUM2OFFSET(index) \
26 (index * sizeof((struct user_pt_regs *)0)->regs[0])
24 27
25/* 28/*
26 * Reference: 29 * Reference:
@@ -78,3 +81,13 @@ const char *get_arch_regstr(unsigned int n)
78 return roff->name; 81 return roff->name;
79 return NULL; 82 return NULL;
80} 83}
84
85int regs_query_register_offset(const char *name)
86{
87 const struct pt_regs_dwarfnum *roff;
88
89 for (roff = regdwarfnum_table; roff->name != NULL; roff++)
90 if (!strcmp(roff->name, name))
91 return DWARFNUM2OFFSET(roff->dwarfnum);
92 return -EINVAL;
93}
diff --git a/tools/perf/bench/futex-hash.c b/tools/perf/bench/futex-hash.c
index bfbb6b5f609c..da04b8c5568a 100644
--- a/tools/perf/bench/futex-hash.c
+++ b/tools/perf/bench/futex-hash.c
@@ -130,8 +130,6 @@ int bench_futex_hash(int argc, const char **argv,
130 } 130 }
131 131
132 ncpus = sysconf(_SC_NPROCESSORS_ONLN); 132 ncpus = sysconf(_SC_NPROCESSORS_ONLN);
133 nsecs = futexbench_sanitize_numeric(nsecs);
134 nfutexes = futexbench_sanitize_numeric(nfutexes);
135 133
136 sigfillset(&act.sa_mask); 134 sigfillset(&act.sa_mask);
137 act.sa_sigaction = toggle_done; 135 act.sa_sigaction = toggle_done;
@@ -139,8 +137,6 @@ int bench_futex_hash(int argc, const char **argv,
139 137
140 if (!nthreads) /* default to the number of CPUs */ 138 if (!nthreads) /* default to the number of CPUs */
141 nthreads = ncpus; 139 nthreads = ncpus;
142 else
143 nthreads = futexbench_sanitize_numeric(nthreads);
144 140
145 worker = calloc(nthreads, sizeof(*worker)); 141 worker = calloc(nthreads, sizeof(*worker));
146 if (!worker) 142 if (!worker)
diff --git a/tools/perf/bench/futex-lock-pi.c b/tools/perf/bench/futex-lock-pi.c
index 6d9d6c40a916..91877777ec6e 100644
--- a/tools/perf/bench/futex-lock-pi.c
+++ b/tools/perf/bench/futex-lock-pi.c
@@ -152,7 +152,6 @@ int bench_futex_lock_pi(int argc, const char **argv,
152 goto err; 152 goto err;
153 153
154 ncpus = sysconf(_SC_NPROCESSORS_ONLN); 154 ncpus = sysconf(_SC_NPROCESSORS_ONLN);
155 nsecs = futexbench_sanitize_numeric(nsecs);
156 155
157 sigfillset(&act.sa_mask); 156 sigfillset(&act.sa_mask);
158 act.sa_sigaction = toggle_done; 157 act.sa_sigaction = toggle_done;
@@ -160,8 +159,6 @@ int bench_futex_lock_pi(int argc, const char **argv,
160 159
161 if (!nthreads) 160 if (!nthreads)
162 nthreads = ncpus; 161 nthreads = ncpus;
163 else
164 nthreads = futexbench_sanitize_numeric(nthreads);
165 162
166 worker = calloc(nthreads, sizeof(*worker)); 163 worker = calloc(nthreads, sizeof(*worker));
167 if (!worker) 164 if (!worker)
diff --git a/tools/perf/bench/futex-requeue.c b/tools/perf/bench/futex-requeue.c
index fd4ee95b689a..2b9705a8734c 100644
--- a/tools/perf/bench/futex-requeue.c
+++ b/tools/perf/bench/futex-requeue.c
@@ -128,8 +128,6 @@ int bench_futex_requeue(int argc, const char **argv,
128 128
129 if (!nthreads) 129 if (!nthreads)
130 nthreads = ncpus; 130 nthreads = ncpus;
131 else
132 nthreads = futexbench_sanitize_numeric(nthreads);
133 131
134 worker = calloc(nthreads, sizeof(*worker)); 132 worker = calloc(nthreads, sizeof(*worker));
135 if (!worker) 133 if (!worker)
diff --git a/tools/perf/bench/futex-wake-parallel.c b/tools/perf/bench/futex-wake-parallel.c
index beaa6c142477..2c8fa67ad537 100644
--- a/tools/perf/bench/futex-wake-parallel.c
+++ b/tools/perf/bench/futex-wake-parallel.c
@@ -217,12 +217,8 @@ int bench_futex_wake_parallel(int argc, const char **argv,
217 sigaction(SIGINT, &act, NULL); 217 sigaction(SIGINT, &act, NULL);
218 218
219 ncpus = sysconf(_SC_NPROCESSORS_ONLN); 219 ncpus = sysconf(_SC_NPROCESSORS_ONLN);
220 nwaking_threads = futexbench_sanitize_numeric(nwaking_threads);
221
222 if (!nblocked_threads) 220 if (!nblocked_threads)
223 nblocked_threads = ncpus; 221 nblocked_threads = ncpus;
224 else
225 nblocked_threads = futexbench_sanitize_numeric(nblocked_threads);
226 222
227 /* some sanity checks */ 223 /* some sanity checks */
228 if (nwaking_threads > nblocked_threads || !nwaking_threads) 224 if (nwaking_threads > nblocked_threads || !nwaking_threads)
diff --git a/tools/perf/bench/futex-wake.c b/tools/perf/bench/futex-wake.c
index 46efcb98b5a4..e246b1b8388a 100644
--- a/tools/perf/bench/futex-wake.c
+++ b/tools/perf/bench/futex-wake.c
@@ -129,7 +129,6 @@ int bench_futex_wake(int argc, const char **argv,
129 } 129 }
130 130
131 ncpus = sysconf(_SC_NPROCESSORS_ONLN); 131 ncpus = sysconf(_SC_NPROCESSORS_ONLN);
132 nwakes = futexbench_sanitize_numeric(nwakes);
133 132
134 sigfillset(&act.sa_mask); 133 sigfillset(&act.sa_mask);
135 act.sa_sigaction = toggle_done; 134 act.sa_sigaction = toggle_done;
@@ -137,8 +136,6 @@ int bench_futex_wake(int argc, const char **argv,
137 136
138 if (!nthreads) 137 if (!nthreads)
139 nthreads = ncpus; 138 nthreads = ncpus;
140 else
141 nthreads = futexbench_sanitize_numeric(nthreads);
142 139
143 worker = calloc(nthreads, sizeof(*worker)); 140 worker = calloc(nthreads, sizeof(*worker));
144 if (!worker) 141 if (!worker)
diff --git a/tools/perf/bench/futex.h b/tools/perf/bench/futex.h
index ba7c735c0c62..b2e06d1190d0 100644
--- a/tools/perf/bench/futex.h
+++ b/tools/perf/bench/futex.h
@@ -7,7 +7,6 @@
7#ifndef _FUTEX_H 7#ifndef _FUTEX_H
8#define _FUTEX_H 8#define _FUTEX_H
9 9
10#include <stdlib.h>
11#include <unistd.h> 10#include <unistd.h>
12#include <sys/syscall.h> 11#include <sys/syscall.h>
13#include <sys/types.h> 12#include <sys/types.h>
@@ -100,7 +99,4 @@ static inline int pthread_attr_setaffinity_np(pthread_attr_t *attr,
100} 99}
101#endif 100#endif
102 101
103/* User input sanitation */
104#define futexbench_sanitize_numeric(__n) abs((__n))
105
106#endif /* _FUTEX_H */ 102#endif /* _FUTEX_H */
diff --git a/tools/perf/bench/numa.c b/tools/perf/bench/numa.c
index 8efe904e486b..3083fc36282b 100644
--- a/tools/perf/bench/numa.c
+++ b/tools/perf/bench/numa.c
@@ -43,6 +43,7 @@
43/* 43/*
44 * Debug printf: 44 * Debug printf:
45 */ 45 */
46#undef dprintf
46#define dprintf(x...) do { if (g && g->p.show_details >= 1) printf(x); } while (0) 47#define dprintf(x...) do { if (g && g->p.show_details >= 1) printf(x); } while (0)
47 48
48struct thread_data { 49struct thread_data {
@@ -1573,13 +1574,13 @@ static int __bench_numa(const char *name)
1573 "GB/sec,", "total-speed", "GB/sec total speed"); 1574 "GB/sec,", "total-speed", "GB/sec total speed");
1574 1575
1575 if (g->p.show_details >= 2) { 1576 if (g->p.show_details >= 2) {
1576 char tname[32]; 1577 char tname[14 + 2 * 10 + 1];
1577 struct thread_data *td; 1578 struct thread_data *td;
1578 for (p = 0; p < g->p.nr_proc; p++) { 1579 for (p = 0; p < g->p.nr_proc; p++) {
1579 for (t = 0; t < g->p.nr_threads; t++) { 1580 for (t = 0; t < g->p.nr_threads; t++) {
1580 memset(tname, 0, 32); 1581 memset(tname, 0, sizeof(tname));
1581 td = g->threads + p*g->p.nr_threads + t; 1582 td = g->threads + p*g->p.nr_threads + t;
1582 snprintf(tname, 32, "process%d:thread%d", p, t); 1583 snprintf(tname, sizeof(tname), "process%d:thread%d", p, t);
1583 print_res(tname, td->speed_gbs, 1584 print_res(tname, td->speed_gbs,
1584 "GB/sec", "thread-speed", "GB/sec/thread speed"); 1585 "GB/sec", "thread-speed", "GB/sec/thread speed");
1585 print_res(tname, td->system_time_ns / NSEC_PER_SEC, 1586 print_res(tname, td->system_time_ns / NSEC_PER_SEC,
diff --git a/tools/perf/builtin-annotate.c b/tools/perf/builtin-annotate.c
index ebb628332a6e..4f52d85f5ebc 100644
--- a/tools/perf/builtin-annotate.c
+++ b/tools/perf/builtin-annotate.c
@@ -410,6 +410,7 @@ int cmd_annotate(int argc, const char **argv, const char *prefix __maybe_unused)
410 OPT_BOOLEAN('f', "force", &file.force, "don't complain, do it"), 410 OPT_BOOLEAN('f', "force", &file.force, "don't complain, do it"),
411 OPT_INCR('v', "verbose", &verbose, 411 OPT_INCR('v', "verbose", &verbose,
412 "be more verbose (show symbol address, etc)"), 412 "be more verbose (show symbol address, etc)"),
413 OPT_BOOLEAN('q', "quiet", &quiet, "do now show any message"),
413 OPT_BOOLEAN('D', "dump-raw-trace", &dump_trace, 414 OPT_BOOLEAN('D', "dump-raw-trace", &dump_trace,
414 "dump raw trace in ASCII"), 415 "dump raw trace in ASCII"),
415 OPT_BOOLEAN(0, "gtk", &annotate.use_gtk, "Use the GTK interface"), 416 OPT_BOOLEAN(0, "gtk", &annotate.use_gtk, "Use the GTK interface"),
@@ -463,6 +464,9 @@ int cmd_annotate(int argc, const char **argv, const char *prefix __maybe_unused)
463 annotate.sym_hist_filter = argv[0]; 464 annotate.sym_hist_filter = argv[0];
464 } 465 }
465 466
467 if (quiet)
468 perf_quiet_option();
469
466 file.path = input_name; 470 file.path = input_name;
467 471
468 annotate.session = perf_session__new(&file, false, &annotate.tool); 472 annotate.session = perf_session__new(&file, false, &annotate.tool);
diff --git a/tools/perf/builtin-c2c.c b/tools/perf/builtin-c2c.c
index f8ca7a4ebabc..e2b21723bbf8 100644
--- a/tools/perf/builtin-c2c.c
+++ b/tools/perf/builtin-c2c.c
@@ -58,7 +58,7 @@ struct c2c_hist_entry {
58 struct hist_entry he; 58 struct hist_entry he;
59}; 59};
60 60
61static char const *coalesce_default = "pid,tid,iaddr"; 61static char const *coalesce_default = "pid,iaddr";
62 62
63struct perf_c2c { 63struct perf_c2c {
64 struct perf_tool tool; 64 struct perf_tool tool;
@@ -2476,6 +2476,7 @@ static int build_cl_output(char *cl_sort, bool no_source)
2476 "mean_rmt," 2476 "mean_rmt,"
2477 "mean_lcl," 2477 "mean_lcl,"
2478 "mean_load," 2478 "mean_load,"
2479 "tot_recs,"
2479 "cpucnt,", 2480 "cpucnt,",
2480 add_sym ? "symbol," : "", 2481 add_sym ? "symbol," : "",
2481 add_dso ? "dso," : "", 2482 add_dso ? "dso," : "",
diff --git a/tools/perf/builtin-diff.c b/tools/perf/builtin-diff.c
index 933aeec46f4a..1b96a3122228 100644
--- a/tools/perf/builtin-diff.c
+++ b/tools/perf/builtin-diff.c
@@ -17,6 +17,7 @@
17#include "util/symbol.h" 17#include "util/symbol.h"
18#include "util/util.h" 18#include "util/util.h"
19#include "util/data.h" 19#include "util/data.h"
20#include "util/config.h"
20 21
21#include <stdlib.h> 22#include <stdlib.h>
22#include <math.h> 23#include <math.h>
@@ -30,6 +31,7 @@ enum {
30 PERF_HPP_DIFF__RATIO, 31 PERF_HPP_DIFF__RATIO,
31 PERF_HPP_DIFF__WEIGHTED_DIFF, 32 PERF_HPP_DIFF__WEIGHTED_DIFF,
32 PERF_HPP_DIFF__FORMULA, 33 PERF_HPP_DIFF__FORMULA,
34 PERF_HPP_DIFF__DELTA_ABS,
33 35
34 PERF_HPP_DIFF__MAX_INDEX 36 PERF_HPP_DIFF__MAX_INDEX
35}; 37};
@@ -64,7 +66,7 @@ static bool force;
64static bool show_period; 66static bool show_period;
65static bool show_formula; 67static bool show_formula;
66static bool show_baseline_only; 68static bool show_baseline_only;
67static unsigned int sort_compute; 69static unsigned int sort_compute = 1;
68 70
69static s64 compute_wdiff_w1; 71static s64 compute_wdiff_w1;
70static s64 compute_wdiff_w2; 72static s64 compute_wdiff_w2;
@@ -73,19 +75,22 @@ enum {
73 COMPUTE_DELTA, 75 COMPUTE_DELTA,
74 COMPUTE_RATIO, 76 COMPUTE_RATIO,
75 COMPUTE_WEIGHTED_DIFF, 77 COMPUTE_WEIGHTED_DIFF,
78 COMPUTE_DELTA_ABS,
76 COMPUTE_MAX, 79 COMPUTE_MAX,
77}; 80};
78 81
79const char *compute_names[COMPUTE_MAX] = { 82const char *compute_names[COMPUTE_MAX] = {
80 [COMPUTE_DELTA] = "delta", 83 [COMPUTE_DELTA] = "delta",
84 [COMPUTE_DELTA_ABS] = "delta-abs",
81 [COMPUTE_RATIO] = "ratio", 85 [COMPUTE_RATIO] = "ratio",
82 [COMPUTE_WEIGHTED_DIFF] = "wdiff", 86 [COMPUTE_WEIGHTED_DIFF] = "wdiff",
83}; 87};
84 88
85static int compute; 89static int compute = COMPUTE_DELTA_ABS;
86 90
87static int compute_2_hpp[COMPUTE_MAX] = { 91static int compute_2_hpp[COMPUTE_MAX] = {
88 [COMPUTE_DELTA] = PERF_HPP_DIFF__DELTA, 92 [COMPUTE_DELTA] = PERF_HPP_DIFF__DELTA,
93 [COMPUTE_DELTA_ABS] = PERF_HPP_DIFF__DELTA_ABS,
89 [COMPUTE_RATIO] = PERF_HPP_DIFF__RATIO, 94 [COMPUTE_RATIO] = PERF_HPP_DIFF__RATIO,
90 [COMPUTE_WEIGHTED_DIFF] = PERF_HPP_DIFF__WEIGHTED_DIFF, 95 [COMPUTE_WEIGHTED_DIFF] = PERF_HPP_DIFF__WEIGHTED_DIFF,
91}; 96};
@@ -111,6 +116,10 @@ static struct header_column {
111 .name = "Delta", 116 .name = "Delta",
112 .width = 7, 117 .width = 7,
113 }, 118 },
119 [PERF_HPP_DIFF__DELTA_ABS] = {
120 .name = "Delta Abs",
121 .width = 7,
122 },
114 [PERF_HPP_DIFF__RATIO] = { 123 [PERF_HPP_DIFF__RATIO] = {
115 .name = "Ratio", 124 .name = "Ratio",
116 .width = 14, 125 .width = 14,
@@ -298,6 +307,7 @@ static int formula_fprintf(struct hist_entry *he, struct hist_entry *pair,
298{ 307{
299 switch (compute) { 308 switch (compute) {
300 case COMPUTE_DELTA: 309 case COMPUTE_DELTA:
310 case COMPUTE_DELTA_ABS:
301 return formula_delta(he, pair, buf, size); 311 return formula_delta(he, pair, buf, size);
302 case COMPUTE_RATIO: 312 case COMPUTE_RATIO:
303 return formula_ratio(he, pair, buf, size); 313 return formula_ratio(he, pair, buf, size);
@@ -461,6 +471,7 @@ static void hists__precompute(struct hists *hists)
461 471
462 switch (compute) { 472 switch (compute) {
463 case COMPUTE_DELTA: 473 case COMPUTE_DELTA:
474 case COMPUTE_DELTA_ABS:
464 compute_delta(he, pair); 475 compute_delta(he, pair);
465 break; 476 break;
466 case COMPUTE_RATIO: 477 case COMPUTE_RATIO:
@@ -498,6 +509,13 @@ __hist_entry__cmp_compute(struct hist_entry *left, struct hist_entry *right,
498 509
499 return cmp_doubles(l, r); 510 return cmp_doubles(l, r);
500 } 511 }
512 case COMPUTE_DELTA_ABS:
513 {
514 double l = fabs(left->diff.period_ratio_delta);
515 double r = fabs(right->diff.period_ratio_delta);
516
517 return cmp_doubles(l, r);
518 }
501 case COMPUTE_RATIO: 519 case COMPUTE_RATIO:
502 { 520 {
503 double l = left->diff.period_ratio; 521 double l = left->diff.period_ratio;
@@ -564,7 +582,7 @@ hist_entry__cmp_compute_idx(struct hist_entry *left, struct hist_entry *right,
564 if (!p_left || !p_right) 582 if (!p_left || !p_right)
565 return p_left ? -1 : 1; 583 return p_left ? -1 : 1;
566 584
567 if (c != COMPUTE_DELTA) { 585 if (c != COMPUTE_DELTA && c != COMPUTE_DELTA_ABS) {
568 /* 586 /*
569 * The delta can be computed without the baseline, but 587 * The delta can be computed without the baseline, but
570 * others are not. Put those entries which have no 588 * others are not. Put those entries which have no
@@ -607,6 +625,15 @@ hist_entry__cmp_delta(struct perf_hpp_fmt *fmt,
607} 625}
608 626
609static int64_t 627static int64_t
628hist_entry__cmp_delta_abs(struct perf_hpp_fmt *fmt,
629 struct hist_entry *left, struct hist_entry *right)
630{
631 struct data__file *d = fmt_to_data_file(fmt);
632
633 return hist_entry__cmp_compute(right, left, COMPUTE_DELTA_ABS, d->idx);
634}
635
636static int64_t
610hist_entry__cmp_ratio(struct perf_hpp_fmt *fmt, 637hist_entry__cmp_ratio(struct perf_hpp_fmt *fmt,
611 struct hist_entry *left, struct hist_entry *right) 638 struct hist_entry *left, struct hist_entry *right)
612{ 639{
@@ -633,6 +660,14 @@ hist_entry__cmp_delta_idx(struct perf_hpp_fmt *fmt __maybe_unused,
633} 660}
634 661
635static int64_t 662static int64_t
663hist_entry__cmp_delta_abs_idx(struct perf_hpp_fmt *fmt __maybe_unused,
664 struct hist_entry *left, struct hist_entry *right)
665{
666 return hist_entry__cmp_compute_idx(right, left, COMPUTE_DELTA_ABS,
667 sort_compute);
668}
669
670static int64_t
636hist_entry__cmp_ratio_idx(struct perf_hpp_fmt *fmt __maybe_unused, 671hist_entry__cmp_ratio_idx(struct perf_hpp_fmt *fmt __maybe_unused,
637 struct hist_entry *left, struct hist_entry *right) 672 struct hist_entry *left, struct hist_entry *right)
638{ 673{
@@ -656,7 +691,7 @@ static void hists__process(struct hists *hists)
656 hists__precompute(hists); 691 hists__precompute(hists);
657 hists__output_resort(hists, NULL); 692 hists__output_resort(hists, NULL);
658 693
659 hists__fprintf(hists, true, 0, 0, 0, stdout, 694 hists__fprintf(hists, !quiet, 0, 0, 0, stdout,
660 symbol_conf.use_callchain); 695 symbol_conf.use_callchain);
661} 696}
662 697
@@ -704,12 +739,14 @@ static void data_process(void)
704 hists__link(hists_base, hists); 739 hists__link(hists_base, hists);
705 } 740 }
706 741
707 fprintf(stdout, "%s# Event '%s'\n#\n", first ? "" : "\n", 742 if (!quiet) {
708 perf_evsel__name(evsel_base)); 743 fprintf(stdout, "%s# Event '%s'\n#\n", first ? "" : "\n",
744 perf_evsel__name(evsel_base));
745 }
709 746
710 first = false; 747 first = false;
711 748
712 if (verbose || data__files_cnt > 2) 749 if (verbose > 0 || ((data__files_cnt > 2) && !quiet))
713 data__fprintf(); 750 data__fprintf();
714 751
715 /* Don't sort callchain for perf diff */ 752 /* Don't sort callchain for perf diff */
@@ -772,10 +809,11 @@ static const char * const diff_usage[] = {
772static const struct option options[] = { 809static const struct option options[] = {
773 OPT_INCR('v', "verbose", &verbose, 810 OPT_INCR('v', "verbose", &verbose,
774 "be more verbose (show symbol address, etc)"), 811 "be more verbose (show symbol address, etc)"),
812 OPT_BOOLEAN('q', "quiet", &quiet, "Do not show any message"),
775 OPT_BOOLEAN('b', "baseline-only", &show_baseline_only, 813 OPT_BOOLEAN('b', "baseline-only", &show_baseline_only,
776 "Show only items with match in baseline"), 814 "Show only items with match in baseline"),
777 OPT_CALLBACK('c', "compute", &compute, 815 OPT_CALLBACK('c', "compute", &compute,
778 "delta,ratio,wdiff:w1,w2 (default delta)", 816 "delta,delta-abs,ratio,wdiff:w1,w2 (default delta-abs)",
779 "Entries differential computation selection", 817 "Entries differential computation selection",
780 setup_compute), 818 setup_compute),
781 OPT_BOOLEAN('p', "period", &show_period, 819 OPT_BOOLEAN('p', "period", &show_period,
@@ -945,6 +983,7 @@ hpp__entry_pair(struct hist_entry *he, struct hist_entry *pair,
945 983
946 switch (idx) { 984 switch (idx) {
947 case PERF_HPP_DIFF__DELTA: 985 case PERF_HPP_DIFF__DELTA:
986 case PERF_HPP_DIFF__DELTA_ABS:
948 if (pair->diff.computed) 987 if (pair->diff.computed)
949 diff = pair->diff.period_ratio_delta; 988 diff = pair->diff.period_ratio_delta;
950 else 989 else
@@ -1118,6 +1157,10 @@ static void data__hpp_register(struct data__file *d, int idx)
1118 fmt->color = hpp__color_wdiff; 1157 fmt->color = hpp__color_wdiff;
1119 fmt->sort = hist_entry__cmp_wdiff; 1158 fmt->sort = hist_entry__cmp_wdiff;
1120 break; 1159 break;
1160 case PERF_HPP_DIFF__DELTA_ABS:
1161 fmt->color = hpp__color_delta;
1162 fmt->sort = hist_entry__cmp_delta_abs;
1163 break;
1121 default: 1164 default:
1122 fmt->sort = hist_entry__cmp_nop; 1165 fmt->sort = hist_entry__cmp_nop;
1123 break; 1166 break;
@@ -1195,6 +1238,9 @@ static int ui_init(void)
1195 case COMPUTE_WEIGHTED_DIFF: 1238 case COMPUTE_WEIGHTED_DIFF:
1196 fmt->sort = hist_entry__cmp_wdiff_idx; 1239 fmt->sort = hist_entry__cmp_wdiff_idx;
1197 break; 1240 break;
1241 case COMPUTE_DELTA_ABS:
1242 fmt->sort = hist_entry__cmp_delta_abs_idx;
1243 break;
1198 default: 1244 default:
1199 BUG_ON(1); 1245 BUG_ON(1);
1200 } 1246 }
@@ -1249,6 +1295,31 @@ static int data_init(int argc, const char **argv)
1249 return 0; 1295 return 0;
1250} 1296}
1251 1297
1298static int diff__config(const char *var, const char *value,
1299 void *cb __maybe_unused)
1300{
1301 if (!strcmp(var, "diff.order")) {
1302 sort_compute = perf_config_int(var, value);
1303 return 0;
1304 }
1305 if (!strcmp(var, "diff.compute")) {
1306 if (!strcmp(value, "delta")) {
1307 compute = COMPUTE_DELTA;
1308 } else if (!strcmp(value, "delta-abs")) {
1309 compute = COMPUTE_DELTA_ABS;
1310 } else if (!strcmp(value, "ratio")) {
1311 compute = COMPUTE_RATIO;
1312 } else if (!strcmp(value, "wdiff")) {
1313 compute = COMPUTE_WEIGHTED_DIFF;
1314 } else {
1315 pr_err("Invalid compute method: %s\n", value);
1316 return -1;
1317 }
1318 }
1319
1320 return 0;
1321}
1322
1252int cmd_diff(int argc, const char **argv, const char *prefix __maybe_unused) 1323int cmd_diff(int argc, const char **argv, const char *prefix __maybe_unused)
1253{ 1324{
1254 int ret = hists__init(); 1325 int ret = hists__init();
@@ -1256,8 +1327,13 @@ int cmd_diff(int argc, const char **argv, const char *prefix __maybe_unused)
1256 if (ret < 0) 1327 if (ret < 0)
1257 return ret; 1328 return ret;
1258 1329
1330 perf_config(diff__config, NULL);
1331
1259 argc = parse_options(argc, argv, options, diff_usage, 0); 1332 argc = parse_options(argc, argv, options, diff_usage, 0);
1260 1333
1334 if (quiet)
1335 perf_quiet_option();
1336
1261 if (symbol__init(NULL) < 0) 1337 if (symbol__init(NULL) < 0)
1262 return -1; 1338 return -1;
1263 1339
diff --git a/tools/perf/builtin-ftrace.c b/tools/perf/builtin-ftrace.c
new file mode 100644
index 000000000000..c3e643666c72
--- /dev/null
+++ b/tools/perf/builtin-ftrace.c
@@ -0,0 +1,265 @@
1/*
2 * builtin-ftrace.c
3 *
4 * Copyright (c) 2013 LG Electronics, Namhyung Kim <namhyung@kernel.org>
5 *
6 * Released under the GPL v2.
7 */
8
9#include "builtin.h"
10#include "perf.h"
11
12#include <unistd.h>
13#include <signal.h>
14
15#include "debug.h"
16#include <subcmd/parse-options.h>
17#include "evlist.h"
18#include "target.h"
19#include "thread_map.h"
20#include "util/config.h"
21
22
23#define DEFAULT_TRACER "function_graph"
24
25struct perf_ftrace {
26 struct perf_evlist *evlist;
27 struct target target;
28 const char *tracer;
29};
30
31static bool done;
32
33static void sig_handler(int sig __maybe_unused)
34{
35 done = true;
36}
37
38/*
39 * perf_evlist__prepare_workload will send a SIGUSR1 if the fork fails, since
40 * we asked by setting its exec_error to the function below,
41 * ftrace__workload_exec_failed_signal.
42 *
43 * XXX We need to handle this more appropriately, emitting an error, etc.
44 */
45static void ftrace__workload_exec_failed_signal(int signo __maybe_unused,
46 siginfo_t *info __maybe_unused,
47 void *ucontext __maybe_unused)
48{
49 /* workload_exec_errno = info->si_value.sival_int; */
50 done = true;
51}
52
53static int write_tracing_file(const char *name, const char *val)
54{
55 char *file;
56 int fd, ret = -1;
57 ssize_t size = strlen(val);
58
59 file = get_tracing_file(name);
60 if (!file) {
61 pr_debug("cannot get tracing file: %s\n", name);
62 return -1;
63 }
64
65 fd = open(file, O_WRONLY);
66 if (fd < 0) {
67 pr_debug("cannot open tracing file: %s\n", name);
68 goto out;
69 }
70
71 if (write(fd, val, size) == size)
72 ret = 0;
73 else
74 pr_debug("write '%s' to tracing/%s failed\n", val, name);
75
76 close(fd);
77out:
78 put_tracing_file(file);
79 return ret;
80}
81
82static int reset_tracing_files(struct perf_ftrace *ftrace __maybe_unused)
83{
84 if (write_tracing_file("tracing_on", "0") < 0)
85 return -1;
86
87 if (write_tracing_file("current_tracer", "nop") < 0)
88 return -1;
89
90 if (write_tracing_file("set_ftrace_pid", " ") < 0)
91 return -1;
92
93 return 0;
94}
95
96static int __cmd_ftrace(struct perf_ftrace *ftrace, int argc, const char **argv)
97{
98 char *trace_file;
99 int trace_fd;
100 char *trace_pid;
101 char buf[4096];
102 struct pollfd pollfd = {
103 .events = POLLIN,
104 };
105
106 if (geteuid() != 0) {
107 pr_err("ftrace only works for root!\n");
108 return -1;
109 }
110
111 if (argc < 1)
112 return -1;
113
114 signal(SIGINT, sig_handler);
115 signal(SIGUSR1, sig_handler);
116 signal(SIGCHLD, sig_handler);
117
118 reset_tracing_files(ftrace);
119
120 /* reset ftrace buffer */
121 if (write_tracing_file("trace", "0") < 0)
122 goto out;
123
124 if (perf_evlist__prepare_workload(ftrace->evlist, &ftrace->target,
125 argv, false, ftrace__workload_exec_failed_signal) < 0)
126 goto out;
127
128 if (write_tracing_file("current_tracer", ftrace->tracer) < 0) {
129 pr_err("failed to set current_tracer to %s\n", ftrace->tracer);
130 goto out;
131 }
132
133 if (asprintf(&trace_pid, "%d", thread_map__pid(ftrace->evlist->threads, 0)) < 0) {
134 pr_err("failed to allocate pid string\n");
135 goto out;
136 }
137
138 if (write_tracing_file("set_ftrace_pid", trace_pid) < 0) {
139 pr_err("failed to set pid: %s\n", trace_pid);
140 goto out_free_pid;
141 }
142
143 trace_file = get_tracing_file("trace_pipe");
144 if (!trace_file) {
145 pr_err("failed to open trace_pipe\n");
146 goto out_free_pid;
147 }
148
149 trace_fd = open(trace_file, O_RDONLY);
150
151 put_tracing_file(trace_file);
152
153 if (trace_fd < 0) {
154 pr_err("failed to open trace_pipe\n");
155 goto out_free_pid;
156 }
157
158 fcntl(trace_fd, F_SETFL, O_NONBLOCK);
159 pollfd.fd = trace_fd;
160
161 if (write_tracing_file("tracing_on", "1") < 0) {
162 pr_err("can't enable tracing\n");
163 goto out_close_fd;
164 }
165
166 perf_evlist__start_workload(ftrace->evlist);
167
168 while (!done) {
169 if (poll(&pollfd, 1, -1) < 0)
170 break;
171
172 if (pollfd.revents & POLLIN) {
173 int n = read(trace_fd, buf, sizeof(buf));
174 if (n < 0)
175 break;
176 if (fwrite(buf, n, 1, stdout) != 1)
177 break;
178 }
179 }
180
181 write_tracing_file("tracing_on", "0");
182
183 /* read remaining buffer contents */
184 while (true) {
185 int n = read(trace_fd, buf, sizeof(buf));
186 if (n <= 0)
187 break;
188 if (fwrite(buf, n, 1, stdout) != 1)
189 break;
190 }
191
192out_close_fd:
193 close(trace_fd);
194out_free_pid:
195 free(trace_pid);
196out:
197 reset_tracing_files(ftrace);
198
199 return done ? 0 : -1;
200}
201
202static int perf_ftrace_config(const char *var, const char *value, void *cb)
203{
204 struct perf_ftrace *ftrace = cb;
205
206 if (prefixcmp(var, "ftrace."))
207 return 0;
208
209 if (strcmp(var, "ftrace.tracer"))
210 return -1;
211
212 if (!strcmp(value, "function_graph") ||
213 !strcmp(value, "function")) {
214 ftrace->tracer = value;
215 return 0;
216 }
217
218 pr_err("Please select \"function_graph\" (default) or \"function\"\n");
219 return -1;
220}
221
222int cmd_ftrace(int argc, const char **argv, const char *prefix __maybe_unused)
223{
224 int ret;
225 struct perf_ftrace ftrace = {
226 .tracer = DEFAULT_TRACER,
227 .target = { .uid = UINT_MAX, },
228 };
229 const char * const ftrace_usage[] = {
230 "perf ftrace [<options>] <command>",
231 "perf ftrace [<options>] -- <command> [<options>]",
232 NULL
233 };
234 const struct option ftrace_options[] = {
235 OPT_STRING('t', "tracer", &ftrace.tracer, "tracer",
236 "tracer to use: function_graph(default) or function"),
237 OPT_INCR('v', "verbose", &verbose,
238 "be more verbose"),
239 OPT_END()
240 };
241
242 ret = perf_config(perf_ftrace_config, &ftrace);
243 if (ret < 0)
244 return -1;
245
246 argc = parse_options(argc, argv, ftrace_options, ftrace_usage,
247 PARSE_OPT_STOP_AT_NON_OPTION);
248 if (!argc)
249 usage_with_options(ftrace_usage, ftrace_options);
250
251 ftrace.evlist = perf_evlist__new();
252 if (ftrace.evlist == NULL)
253 return -ENOMEM;
254
255 ret = perf_evlist__create_maps(ftrace.evlist, &ftrace.target);
256 if (ret < 0)
257 goto out_delete_evlist;
258
259 ret = __cmd_ftrace(&ftrace, argc, argv);
260
261out_delete_evlist:
262 perf_evlist__delete(ftrace.evlist);
263
264 return ret;
265}
diff --git a/tools/perf/builtin-help.c b/tools/perf/builtin-help.c
index 3bdb2c78a21b..aed0d844e8c2 100644
--- a/tools/perf/builtin-help.c
+++ b/tools/perf/builtin-help.c
@@ -434,7 +434,7 @@ int cmd_help(int argc, const char **argv, const char *prefix __maybe_unused)
434 const char * const builtin_help_subcommands[] = { 434 const char * const builtin_help_subcommands[] = {
435 "buildid-cache", "buildid-list", "diff", "evlist", "help", "list", 435 "buildid-cache", "buildid-list", "diff", "evlist", "help", "list",
436 "record", "report", "bench", "stat", "timechart", "top", "annotate", 436 "record", "report", "bench", "stat", "timechart", "top", "annotate",
437 "script", "sched", "kmem", "lock", "kvm", "test", "inject", "mem", "data", 437 "script", "sched", "kallsyms", "kmem", "lock", "kvm", "test", "inject", "mem", "data",
438#ifdef HAVE_LIBELF_SUPPORT 438#ifdef HAVE_LIBELF_SUPPORT
439 "probe", 439 "probe",
440#endif 440#endif
@@ -447,11 +447,13 @@ int cmd_help(int argc, const char **argv, const char *prefix __maybe_unused)
447 NULL 447 NULL
448 }; 448 };
449 const char *alias; 449 const char *alias;
450 int rc = 0; 450 int rc;
451 451
452 load_command_list("perf-", &main_cmds, &other_cmds); 452 load_command_list("perf-", &main_cmds, &other_cmds);
453 453
454 perf_config(perf_help_config, &help_format); 454 rc = perf_config(perf_help_config, &help_format);
455 if (rc)
456 return rc;
455 457
456 argc = parse_options_subcommand(argc, argv, builtin_help_options, 458 argc = parse_options_subcommand(argc, argv, builtin_help_options,
457 builtin_help_subcommands, builtin_help_usage, 0); 459 builtin_help_subcommands, builtin_help_usage, 0);
diff --git a/tools/perf/builtin-kallsyms.c b/tools/perf/builtin-kallsyms.c
new file mode 100644
index 000000000000..224bfc454b4a
--- /dev/null
+++ b/tools/perf/builtin-kallsyms.c
@@ -0,0 +1,67 @@
1/*
2 * builtin-kallsyms.c
3 *
4 * Builtin command: Look for a symbol in the running kernel and its modules
5 *
6 * Copyright (C) 2017, Red Hat Inc, Arnaldo Carvalho de Melo <acme@redhat.com>
7 *
8 * Released under the GPL v2. (and only v2, not any later version)
9 */
10#include "builtin.h"
11#include <linux/compiler.h>
12#include <subcmd/parse-options.h>
13#include "debug.h"
14#include "machine.h"
15#include "symbol.h"
16
17static int __cmd_kallsyms(int argc, const char **argv)
18{
19 int i;
20 struct machine *machine = machine__new_kallsyms();
21
22 if (machine == NULL) {
23 pr_err("Couldn't read /proc/kallsyms\n");
24 return -1;
25 }
26
27 for (i = 0; i < argc; ++i) {
28 struct map *map;
29 struct symbol *symbol = machine__find_kernel_function_by_name(machine, argv[i], &map);
30
31 if (symbol == NULL) {
32 printf("%s: not found\n", argv[i]);
33 continue;
34 }
35
36 printf("%s: %s %s %#" PRIx64 "-%#" PRIx64 " (%#" PRIx64 "-%#" PRIx64")\n",
37 symbol->name, map->dso->short_name, map->dso->long_name,
38 map->unmap_ip(map, symbol->start), map->unmap_ip(map, symbol->end),
39 symbol->start, symbol->end);
40 }
41
42 machine__delete(machine);
43 return 0;
44}
45
46int cmd_kallsyms(int argc, const char **argv, const char *prefix __maybe_unused)
47{
48 const struct option options[] = {
49 OPT_INCR('v', "verbose", &verbose, "be more verbose (show counter open errors, etc)"),
50 OPT_END()
51 };
52 const char * const kallsyms_usage[] = {
53 "perf kallsyms [<options>] symbol_name",
54 NULL
55 };
56
57 argc = parse_options(argc, argv, options, kallsyms_usage, 0);
58 if (argc < 1)
59 usage_with_options(kallsyms_usage, options);
60
61 symbol_conf.sort_by_name = true;
62 symbol_conf.try_vmlinux_path = (symbol_conf.vmlinux_name == NULL);
63 if (symbol__init(NULL) < 0)
64 return -1;
65
66 return __cmd_kallsyms(argc, argv);
67}
diff --git a/tools/perf/builtin-kmem.c b/tools/perf/builtin-kmem.c
index 915869e00d86..6da8d083e4e5 100644
--- a/tools/perf/builtin-kmem.c
+++ b/tools/perf/builtin-kmem.c
@@ -1065,7 +1065,7 @@ static void __print_page_alloc_result(struct perf_session *session, int n_lines)
1065 1065
1066 data = rb_entry(next, struct page_stat, node); 1066 data = rb_entry(next, struct page_stat, node);
1067 sym = machine__find_kernel_function(machine, data->callsite, &map); 1067 sym = machine__find_kernel_function(machine, data->callsite, &map);
1068 if (sym && sym->name) 1068 if (sym)
1069 caller = sym->name; 1069 caller = sym->name;
1070 else 1070 else
1071 scnprintf(buf, sizeof(buf), "%"PRIx64, data->callsite); 1071 scnprintf(buf, sizeof(buf), "%"PRIx64, data->callsite);
@@ -1107,7 +1107,7 @@ static void __print_page_caller_result(struct perf_session *session, int n_lines
1107 1107
1108 data = rb_entry(next, struct page_stat, node); 1108 data = rb_entry(next, struct page_stat, node);
1109 sym = machine__find_kernel_function(machine, data->callsite, &map); 1109 sym = machine__find_kernel_function(machine, data->callsite, &map);
1110 if (sym && sym->name) 1110 if (sym)
1111 caller = sym->name; 1111 caller = sym->name;
1112 else 1112 else
1113 scnprintf(buf, sizeof(buf), "%"PRIx64, data->callsite); 1113 scnprintf(buf, sizeof(buf), "%"PRIx64, data->callsite);
@@ -1920,10 +1920,12 @@ int cmd_kmem(int argc, const char **argv, const char *prefix __maybe_unused)
1920 NULL 1920 NULL
1921 }; 1921 };
1922 struct perf_session *session; 1922 struct perf_session *session;
1923 int ret = -1;
1924 const char errmsg[] = "No %s allocation events found. Have you run 'perf kmem record --%s'?\n"; 1923 const char errmsg[] = "No %s allocation events found. Have you run 'perf kmem record --%s'?\n";
1924 int ret = perf_config(kmem_config, NULL);
1925
1926 if (ret)
1927 return ret;
1925 1928
1926 perf_config(kmem_config, NULL);
1927 argc = parse_options_subcommand(argc, argv, kmem_options, 1929 argc = parse_options_subcommand(argc, argv, kmem_options,
1928 kmem_subcommands, kmem_usage, 0); 1930 kmem_subcommands, kmem_usage, 0);
1929 1931
@@ -1948,6 +1950,8 @@ int cmd_kmem(int argc, const char **argv, const char *prefix __maybe_unused)
1948 if (session == NULL) 1950 if (session == NULL)
1949 return -1; 1951 return -1;
1950 1952
1953 ret = -1;
1954
1951 if (kmem_slab) { 1955 if (kmem_slab) {
1952 if (!perf_evlist__find_tracepoint_by_name(session->evlist, 1956 if (!perf_evlist__find_tracepoint_by_name(session->evlist,
1953 "kmem:kmalloc")) { 1957 "kmem:kmalloc")) {
diff --git a/tools/perf/builtin-list.c b/tools/perf/builtin-list.c
index ba9322ff858b..3b9d98b5feef 100644
--- a/tools/perf/builtin-list.c
+++ b/tools/perf/builtin-list.c
@@ -14,6 +14,7 @@
14#include "util/parse-events.h" 14#include "util/parse-events.h"
15#include "util/cache.h" 15#include "util/cache.h"
16#include "util/pmu.h" 16#include "util/pmu.h"
17#include "util/debug.h"
17#include <subcmd/parse-options.h> 18#include <subcmd/parse-options.h>
18 19
19static bool desc_flag = true; 20static bool desc_flag = true;
@@ -29,6 +30,8 @@ int cmd_list(int argc, const char **argv, const char *prefix __maybe_unused)
29 "Print extra event descriptions. --no-desc to not print."), 30 "Print extra event descriptions. --no-desc to not print."),
30 OPT_BOOLEAN('v', "long-desc", &long_desc_flag, 31 OPT_BOOLEAN('v', "long-desc", &long_desc_flag,
31 "Print longer event descriptions."), 32 "Print longer event descriptions."),
33 OPT_INCR(0, "debug", &verbose,
34 "Enable debugging output"),
32 OPT_END() 35 OPT_END()
33 }; 36 };
34 const char * const list_usage[] = { 37 const char * const list_usage[] = {
diff --git a/tools/perf/builtin-mem.c b/tools/perf/builtin-mem.c
index cd7bc4d104e2..6114e07ca613 100644
--- a/tools/perf/builtin-mem.c
+++ b/tools/perf/builtin-mem.c
@@ -42,8 +42,8 @@ static int parse_record_events(const struct option *opt,
42 42
43 fprintf(stderr, "%-13s%-*s%s\n", 43 fprintf(stderr, "%-13s%-*s%s\n",
44 e->tag, 44 e->tag,
45 verbose ? 25 : 0, 45 verbose > 0 ? 25 : 0,
46 verbose ? perf_mem_events__name(j) : "", 46 verbose > 0 ? perf_mem_events__name(j) : "",
47 e->supported ? ": available" : ""); 47 e->supported ? ": available" : "");
48 } 48 }
49 exit(0); 49 exit(0);
diff --git a/tools/perf/builtin-probe.c b/tools/perf/builtin-probe.c
index f87996b0cb29..1fcebc31a508 100644
--- a/tools/perf/builtin-probe.c
+++ b/tools/perf/builtin-probe.c
@@ -552,6 +552,8 @@ __cmd_probe(int argc, const char **argv, const char *prefix __maybe_unused)
552 OPT_BOOLEAN(0, "demangle-kernel", &symbol_conf.demangle_kernel, 552 OPT_BOOLEAN(0, "demangle-kernel", &symbol_conf.demangle_kernel,
553 "Enable kernel symbol demangling"), 553 "Enable kernel symbol demangling"),
554 OPT_BOOLEAN(0, "cache", &probe_conf.cache, "Manipulate probe cache"), 554 OPT_BOOLEAN(0, "cache", &probe_conf.cache, "Manipulate probe cache"),
555 OPT_STRING(0, "symfs", &symbol_conf.symfs, "directory",
556 "Look for files with symbols relative to this directory"),
555 OPT_END() 557 OPT_END()
556 }; 558 };
557 int ret; 559 int ret;
diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c
index 4ec10e9427d9..bc84a375295d 100644
--- a/tools/perf/builtin-record.c
+++ b/tools/perf/builtin-record.c
@@ -46,6 +46,15 @@
46#include <asm/bug.h> 46#include <asm/bug.h>
47#include <linux/time64.h> 47#include <linux/time64.h>
48 48
49struct switch_output {
50 bool enabled;
51 bool signal;
52 unsigned long size;
53 unsigned long time;
54 const char *str;
55 bool set;
56};
57
49struct record { 58struct record {
50 struct perf_tool tool; 59 struct perf_tool tool;
51 struct record_opts opts; 60 struct record_opts opts;
@@ -62,10 +71,33 @@ struct record {
62 bool no_buildid_cache_set; 71 bool no_buildid_cache_set;
63 bool buildid_all; 72 bool buildid_all;
64 bool timestamp_filename; 73 bool timestamp_filename;
65 bool switch_output; 74 struct switch_output switch_output;
66 unsigned long long samples; 75 unsigned long long samples;
67}; 76};
68 77
78static volatile int auxtrace_record__snapshot_started;
79static DEFINE_TRIGGER(auxtrace_snapshot_trigger);
80static DEFINE_TRIGGER(switch_output_trigger);
81
82static bool switch_output_signal(struct record *rec)
83{
84 return rec->switch_output.signal &&
85 trigger_is_ready(&switch_output_trigger);
86}
87
88static bool switch_output_size(struct record *rec)
89{
90 return rec->switch_output.size &&
91 trigger_is_ready(&switch_output_trigger) &&
92 (rec->bytes_written >= rec->switch_output.size);
93}
94
95static bool switch_output_time(struct record *rec)
96{
97 return rec->switch_output.time &&
98 trigger_is_ready(&switch_output_trigger);
99}
100
69static int record__write(struct record *rec, void *bf, size_t size) 101static int record__write(struct record *rec, void *bf, size_t size)
70{ 102{
71 if (perf_data_file__write(rec->session->file, bf, size) < 0) { 103 if (perf_data_file__write(rec->session->file, bf, size) < 0) {
@@ -74,6 +106,10 @@ static int record__write(struct record *rec, void *bf, size_t size)
74 } 106 }
75 107
76 rec->bytes_written += size; 108 rec->bytes_written += size;
109
110 if (switch_output_size(rec))
111 trigger_hit(&switch_output_trigger);
112
77 return 0; 113 return 0;
78} 114}
79 115
@@ -193,10 +229,6 @@ static volatile int done;
193static volatile int signr = -1; 229static volatile int signr = -1;
194static volatile int child_finished; 230static volatile int child_finished;
195 231
196static volatile int auxtrace_record__snapshot_started;
197static DEFINE_TRIGGER(auxtrace_snapshot_trigger);
198static DEFINE_TRIGGER(switch_output_trigger);
199
200static void sig_handler(int sig) 232static void sig_handler(int sig)
201{ 233{
202 if (sig == SIGCHLD) 234 if (sig == SIGCHLD)
@@ -386,7 +418,7 @@ static int record__mmap(struct record *rec)
386 418
387static int record__open(struct record *rec) 419static int record__open(struct record *rec)
388{ 420{
389 char msg[512]; 421 char msg[BUFSIZ];
390 struct perf_evsel *pos; 422 struct perf_evsel *pos;
391 struct perf_evlist *evlist = rec->evlist; 423 struct perf_evlist *evlist = rec->evlist;
392 struct perf_session *session = rec->session; 424 struct perf_session *session = rec->session;
@@ -400,7 +432,7 @@ static int record__open(struct record *rec)
400try_again: 432try_again:
401 if (perf_evsel__open(pos, pos->cpus, pos->threads) < 0) { 433 if (perf_evsel__open(pos, pos->cpus, pos->threads) < 0) {
402 if (perf_evsel__fallback(pos, errno, msg, sizeof(msg))) { 434 if (perf_evsel__fallback(pos, errno, msg, sizeof(msg))) {
403 if (verbose) 435 if (verbose > 0)
404 ui__warning("%s\n", msg); 436 ui__warning("%s\n", msg);
405 goto try_again; 437 goto try_again;
406 } 438 }
@@ -623,22 +655,23 @@ record__finish_output(struct record *rec)
623 655
624static int record__synthesize_workload(struct record *rec, bool tail) 656static int record__synthesize_workload(struct record *rec, bool tail)
625{ 657{
626 struct { 658 int err;
627 struct thread_map map; 659 struct thread_map *thread_map;
628 struct thread_map_data map_data;
629 } thread_map;
630 660
631 if (rec->opts.tail_synthesize != tail) 661 if (rec->opts.tail_synthesize != tail)
632 return 0; 662 return 0;
633 663
634 thread_map.map.nr = 1; 664 thread_map = thread_map__new_by_tid(rec->evlist->workload.pid);
635 thread_map.map.map[0].pid = rec->evlist->workload.pid; 665 if (thread_map == NULL)
636 thread_map.map.map[0].comm = NULL; 666 return -1;
637 return perf_event__synthesize_thread_map(&rec->tool, &thread_map.map, 667
668 err = perf_event__synthesize_thread_map(&rec->tool, thread_map,
638 process_synthesized_event, 669 process_synthesized_event,
639 &rec->session->machines.host, 670 &rec->session->machines.host,
640 rec->opts.sample_address, 671 rec->opts.sample_address,
641 rec->opts.proc_map_timeout); 672 rec->opts.proc_map_timeout);
673 thread_map__put(thread_map);
674 return err;
642} 675}
643 676
644static int record__synthesize(struct record *rec, bool tail); 677static int record__synthesize(struct record *rec, bool tail);
@@ -712,6 +745,7 @@ static void workload_exec_failed_signal(int signo __maybe_unused,
712} 745}
713 746
714static void snapshot_sig_handler(int sig); 747static void snapshot_sig_handler(int sig);
748static void alarm_sig_handler(int sig);
715 749
716int __weak 750int __weak
717perf_event__synth_time_conv(const struct perf_event_mmap_page *pc __maybe_unused, 751perf_event__synth_time_conv(const struct perf_event_mmap_page *pc __maybe_unused,
@@ -842,11 +876,11 @@ static int __cmd_record(struct record *rec, int argc, const char **argv)
842 signal(SIGTERM, sig_handler); 876 signal(SIGTERM, sig_handler);
843 signal(SIGSEGV, sigsegv_handler); 877 signal(SIGSEGV, sigsegv_handler);
844 878
845 if (rec->opts.auxtrace_snapshot_mode || rec->switch_output) { 879 if (rec->opts.auxtrace_snapshot_mode || rec->switch_output.enabled) {
846 signal(SIGUSR2, snapshot_sig_handler); 880 signal(SIGUSR2, snapshot_sig_handler);
847 if (rec->opts.auxtrace_snapshot_mode) 881 if (rec->opts.auxtrace_snapshot_mode)
848 trigger_on(&auxtrace_snapshot_trigger); 882 trigger_on(&auxtrace_snapshot_trigger);
849 if (rec->switch_output) 883 if (rec->switch_output.enabled)
850 trigger_on(&switch_output_trigger); 884 trigger_on(&switch_output_trigger);
851 } else { 885 } else {
852 signal(SIGUSR2, SIG_IGN); 886 signal(SIGUSR2, SIG_IGN);
@@ -1043,6 +1077,10 @@ static int __cmd_record(struct record *rec, int argc, const char **argv)
1043 err = fd; 1077 err = fd;
1044 goto out_child; 1078 goto out_child;
1045 } 1079 }
1080
1081 /* re-arm the alarm */
1082 if (rec->switch_output.time)
1083 alarm(rec->switch_output.time);
1046 } 1084 }
1047 1085
1048 if (hits == rec->samples) { 1086 if (hits == rec->samples) {
@@ -1352,6 +1390,78 @@ out_free:
1352 return ret; 1390 return ret;
1353} 1391}
1354 1392
1393static void switch_output_size_warn(struct record *rec)
1394{
1395 u64 wakeup_size = perf_evlist__mmap_size(rec->opts.mmap_pages);
1396 struct switch_output *s = &rec->switch_output;
1397
1398 wakeup_size /= 2;
1399
1400 if (s->size < wakeup_size) {
1401 char buf[100];
1402
1403 unit_number__scnprintf(buf, sizeof(buf), wakeup_size);
1404 pr_warning("WARNING: switch-output data size lower than "
1405 "wakeup kernel buffer size (%s) "
1406 "expect bigger perf.data sizes\n", buf);
1407 }
1408}
1409
1410static int switch_output_setup(struct record *rec)
1411{
1412 struct switch_output *s = &rec->switch_output;
1413 static struct parse_tag tags_size[] = {
1414 { .tag = 'B', .mult = 1 },
1415 { .tag = 'K', .mult = 1 << 10 },
1416 { .tag = 'M', .mult = 1 << 20 },
1417 { .tag = 'G', .mult = 1 << 30 },
1418 { .tag = 0 },
1419 };
1420 static struct parse_tag tags_time[] = {
1421 { .tag = 's', .mult = 1 },
1422 { .tag = 'm', .mult = 60 },
1423 { .tag = 'h', .mult = 60*60 },
1424 { .tag = 'd', .mult = 60*60*24 },
1425 { .tag = 0 },
1426 };
1427 unsigned long val;
1428
1429 if (!s->set)
1430 return 0;
1431
1432 if (!strcmp(s->str, "signal")) {
1433 s->signal = true;
1434 pr_debug("switch-output with SIGUSR2 signal\n");
1435 goto enabled;
1436 }
1437
1438 val = parse_tag_value(s->str, tags_size);
1439 if (val != (unsigned long) -1) {
1440 s->size = val;
1441 pr_debug("switch-output with %s size threshold\n", s->str);
1442 goto enabled;
1443 }
1444
1445 val = parse_tag_value(s->str, tags_time);
1446 if (val != (unsigned long) -1) {
1447 s->time = val;
1448 pr_debug("switch-output with %s time threshold (%lu seconds)\n",
1449 s->str, s->time);
1450 goto enabled;
1451 }
1452
1453 return -1;
1454
1455enabled:
1456 rec->timestamp_filename = true;
1457 s->enabled = true;
1458
1459 if (s->size && !rec->opts.no_buffering)
1460 switch_output_size_warn(rec);
1461
1462 return 0;
1463}
1464
1355static const char * const __record_usage[] = { 1465static const char * const __record_usage[] = {
1356 "perf record [<options>] [<command>]", 1466 "perf record [<options>] [<command>]",
1357 "perf record [<options>] -- <command> [<options>]", 1467 "perf record [<options>] -- <command> [<options>]",
@@ -1519,8 +1629,10 @@ static struct option __record_options[] = {
1519 "Record build-id of all DSOs regardless of hits"), 1629 "Record build-id of all DSOs regardless of hits"),
1520 OPT_BOOLEAN(0, "timestamp-filename", &record.timestamp_filename, 1630 OPT_BOOLEAN(0, "timestamp-filename", &record.timestamp_filename,
1521 "append timestamp to output filename"), 1631 "append timestamp to output filename"),
1522 OPT_BOOLEAN(0, "switch-output", &record.switch_output, 1632 OPT_STRING_OPTARG_SET(0, "switch-output", &record.switch_output.str,
1523 "Switch output when receive SIGUSR2"), 1633 &record.switch_output.set, "signal,size,time",
1634 "Switch output when receive SIGUSR2 or cross size,time threshold",
1635 "signal"),
1524 OPT_BOOLEAN(0, "dry-run", &dry_run, 1636 OPT_BOOLEAN(0, "dry-run", &dry_run,
1525 "Parse options then exit"), 1637 "Parse options then exit"),
1526 OPT_END() 1638 OPT_END()
@@ -1559,12 +1671,18 @@ int cmd_record(int argc, const char **argv, const char *prefix __maybe_unused)
1559 if (rec->evlist == NULL) 1671 if (rec->evlist == NULL)
1560 return -ENOMEM; 1672 return -ENOMEM;
1561 1673
1562 perf_config(perf_record_config, rec); 1674 err = perf_config(perf_record_config, rec);
1675 if (err)
1676 return err;
1563 1677
1564 argc = parse_options(argc, argv, record_options, record_usage, 1678 argc = parse_options(argc, argv, record_options, record_usage,
1565 PARSE_OPT_STOP_AT_NON_OPTION); 1679 PARSE_OPT_STOP_AT_NON_OPTION);
1680 if (quiet)
1681 perf_quiet_option();
1682
1683 /* Make system wide (-a) the default target. */
1566 if (!argc && target__none(&rec->opts.target)) 1684 if (!argc && target__none(&rec->opts.target))
1567 usage_with_options(record_usage, record_options); 1685 rec->opts.target.system_wide = true;
1568 1686
1569 if (nr_cgroups && !rec->opts.target.system_wide) { 1687 if (nr_cgroups && !rec->opts.target.system_wide) {
1570 usage_with_options_msg(record_usage, record_options, 1688 usage_with_options_msg(record_usage, record_options,
@@ -1578,8 +1696,15 @@ int cmd_record(int argc, const char **argv, const char *prefix __maybe_unused)
1578 return -EINVAL; 1696 return -EINVAL;
1579 } 1697 }
1580 1698
1581 if (rec->switch_output) 1699 if (switch_output_setup(rec)) {
1582 rec->timestamp_filename = true; 1700 parse_options_usage(record_usage, record_options, "switch-output", 0);
1701 return -EINVAL;
1702 }
1703
1704 if (rec->switch_output.time) {
1705 signal(SIGALRM, alarm_sig_handler);
1706 alarm(rec->switch_output.time);
1707 }
1583 1708
1584 if (!rec->itr) { 1709 if (!rec->itr) {
1585 rec->itr = auxtrace_record__init(rec->evlist, &err); 1710 rec->itr = auxtrace_record__init(rec->evlist, &err);
@@ -1629,7 +1754,7 @@ int cmd_record(int argc, const char **argv, const char *prefix __maybe_unused)
1629 1754
1630 if (rec->no_buildid_cache || rec->no_buildid) { 1755 if (rec->no_buildid_cache || rec->no_buildid) {
1631 disable_buildid_cache(); 1756 disable_buildid_cache();
1632 } else if (rec->switch_output) { 1757 } else if (rec->switch_output.enabled) {
1633 /* 1758 /*
1634 * In 'perf record --switch-output', disable buildid 1759 * In 'perf record --switch-output', disable buildid
1635 * generation by default to reduce data file switching 1760 * generation by default to reduce data file switching
@@ -1721,6 +1846,8 @@ out:
1721 1846
1722static void snapshot_sig_handler(int sig __maybe_unused) 1847static void snapshot_sig_handler(int sig __maybe_unused)
1723{ 1848{
1849 struct record *rec = &record;
1850
1724 if (trigger_is_ready(&auxtrace_snapshot_trigger)) { 1851 if (trigger_is_ready(&auxtrace_snapshot_trigger)) {
1725 trigger_hit(&auxtrace_snapshot_trigger); 1852 trigger_hit(&auxtrace_snapshot_trigger);
1726 auxtrace_record__snapshot_started = 1; 1853 auxtrace_record__snapshot_started = 1;
@@ -1728,6 +1855,14 @@ static void snapshot_sig_handler(int sig __maybe_unused)
1728 trigger_error(&auxtrace_snapshot_trigger); 1855 trigger_error(&auxtrace_snapshot_trigger);
1729 } 1856 }
1730 1857
1731 if (trigger_is_ready(&switch_output_trigger)) 1858 if (switch_output_signal(rec))
1859 trigger_hit(&switch_output_trigger);
1860}
1861
1862static void alarm_sig_handler(int sig __maybe_unused)
1863{
1864 struct record *rec = &record;
1865
1866 if (switch_output_time(rec))
1732 trigger_hit(&switch_output_trigger); 1867 trigger_hit(&switch_output_trigger);
1733} 1868}
diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c
index 06cc759a4597..0a88670e56f3 100644
--- a/tools/perf/builtin-report.c
+++ b/tools/perf/builtin-report.c
@@ -320,6 +320,9 @@ static size_t hists__fprintf_nr_sample_events(struct hists *hists, struct report
320 size_t size = sizeof(buf); 320 size_t size = sizeof(buf);
321 int socked_id = hists->socket_filter; 321 int socked_id = hists->socket_filter;
322 322
323 if (quiet)
324 return 0;
325
323 if (symbol_conf.filter_relative) { 326 if (symbol_conf.filter_relative) {
324 nr_samples = hists->stats.nr_non_filtered_samples; 327 nr_samples = hists->stats.nr_non_filtered_samples;
325 nr_events = hists->stats.total_non_filtered_period; 328 nr_events = hists->stats.total_non_filtered_period;
@@ -372,7 +375,11 @@ static int perf_evlist__tty_browse_hists(struct perf_evlist *evlist,
372{ 375{
373 struct perf_evsel *pos; 376 struct perf_evsel *pos;
374 377
375 fprintf(stdout, "#\n# Total Lost Samples: %" PRIu64 "\n#\n", evlist->stats.total_lost_samples); 378 if (!quiet) {
379 fprintf(stdout, "#\n# Total Lost Samples: %" PRIu64 "\n#\n",
380 evlist->stats.total_lost_samples);
381 }
382
376 evlist__for_each_entry(evlist, pos) { 383 evlist__for_each_entry(evlist, pos) {
377 struct hists *hists = evsel__hists(pos); 384 struct hists *hists = evsel__hists(pos);
378 const char *evname = perf_evsel__name(pos); 385 const char *evname = perf_evsel__name(pos);
@@ -382,7 +389,7 @@ static int perf_evlist__tty_browse_hists(struct perf_evlist *evlist,
382 continue; 389 continue;
383 390
384 hists__fprintf_nr_sample_events(hists, rep, evname, stdout); 391 hists__fprintf_nr_sample_events(hists, rep, evname, stdout);
385 hists__fprintf(hists, true, 0, 0, rep->min_percent, stdout, 392 hists__fprintf(hists, !quiet, 0, 0, rep->min_percent, stdout,
386 symbol_conf.use_callchain); 393 symbol_conf.use_callchain);
387 fprintf(stdout, "\n\n"); 394 fprintf(stdout, "\n\n");
388 } 395 }
@@ -716,6 +723,7 @@ int cmd_report(int argc, const char **argv, const char *prefix __maybe_unused)
716 "input file name"), 723 "input file name"),
717 OPT_INCR('v', "verbose", &verbose, 724 OPT_INCR('v', "verbose", &verbose,
718 "be more verbose (show symbol address, etc)"), 725 "be more verbose (show symbol address, etc)"),
726 OPT_BOOLEAN('q', "quiet", &quiet, "Do not show any message"),
719 OPT_BOOLEAN('D', "dump-raw-trace", &dump_trace, 727 OPT_BOOLEAN('D', "dump-raw-trace", &dump_trace,
720 "dump raw trace in ASCII"), 728 "dump raw trace in ASCII"),
721 OPT_STRING('k', "vmlinux", &symbol_conf.vmlinux_name, 729 OPT_STRING('k', "vmlinux", &symbol_conf.vmlinux_name,
@@ -847,7 +855,9 @@ int cmd_report(int argc, const char **argv, const char *prefix __maybe_unused)
847 if (ret < 0) 855 if (ret < 0)
848 return ret; 856 return ret;
849 857
850 perf_config(report__config, &report); 858 ret = perf_config(report__config, &report);
859 if (ret)
860 return ret;
851 861
852 argc = parse_options(argc, argv, options, report_usage, 0); 862 argc = parse_options(argc, argv, options, report_usage, 0);
853 if (argc) { 863 if (argc) {
@@ -861,6 +871,9 @@ int cmd_report(int argc, const char **argv, const char *prefix __maybe_unused)
861 report.symbol_filter_str = argv[0]; 871 report.symbol_filter_str = argv[0];
862 } 872 }
863 873
874 if (quiet)
875 perf_quiet_option();
876
864 if (symbol_conf.vmlinux_name && 877 if (symbol_conf.vmlinux_name &&
865 access(symbol_conf.vmlinux_name, R_OK)) { 878 access(symbol_conf.vmlinux_name, R_OK)) {
866 pr_err("Invalid file: %s\n", symbol_conf.vmlinux_name); 879 pr_err("Invalid file: %s\n", symbol_conf.vmlinux_name);
@@ -981,14 +994,14 @@ repeat:
981 goto error; 994 goto error;
982 } 995 }
983 996
984 if (report.header || report.header_only) { 997 if ((report.header || report.header_only) && !quiet) {
985 perf_session__fprintf_info(session, stdout, 998 perf_session__fprintf_info(session, stdout,
986 report.show_full_info); 999 report.show_full_info);
987 if (report.header_only) { 1000 if (report.header_only) {
988 ret = 0; 1001 ret = 0;
989 goto error; 1002 goto error;
990 } 1003 }
991 } else if (use_browser == 0) { 1004 } else if (use_browser == 0 && !quiet) {
992 fputs("# To display the perf.data header info, please use --header/--header-only options.\n#\n", 1005 fputs("# To display the perf.data header info, please use --header/--header-only options.\n#\n",
993 stdout); 1006 stdout);
994 } 1007 }
@@ -1007,7 +1020,7 @@ repeat:
1007 * providing it only in verbose mode not to bloat too 1020 * providing it only in verbose mode not to bloat too
1008 * much struct symbol. 1021 * much struct symbol.
1009 */ 1022 */
1010 if (verbose) { 1023 if (verbose > 0) {
1011 /* 1024 /*
1012 * XXX: Need to provide a less kludgy way to ask for 1025 * XXX: Need to provide a less kludgy way to ask for
1013 * more space per symbol, the u32 is for the index on 1026 * more space per symbol, the u32 is for the index on
diff --git a/tools/perf/builtin-sched.c b/tools/perf/builtin-sched.c
index 5b134b0d1ff3..b94cf0de715a 100644
--- a/tools/perf/builtin-sched.c
+++ b/tools/perf/builtin-sched.c
@@ -77,6 +77,22 @@ struct sched_atom {
77 77
78#define TASK_STATE_TO_CHAR_STR "RSDTtZXxKWP" 78#define TASK_STATE_TO_CHAR_STR "RSDTtZXxKWP"
79 79
80/* task state bitmask, copied from include/linux/sched.h */
81#define TASK_RUNNING 0
82#define TASK_INTERRUPTIBLE 1
83#define TASK_UNINTERRUPTIBLE 2
84#define __TASK_STOPPED 4
85#define __TASK_TRACED 8
86/* in tsk->exit_state */
87#define EXIT_DEAD 16
88#define EXIT_ZOMBIE 32
89#define EXIT_TRACE (EXIT_ZOMBIE | EXIT_DEAD)
90/* in tsk->state again */
91#define TASK_DEAD 64
92#define TASK_WAKEKILL 128
93#define TASK_WAKING 256
94#define TASK_PARKED 512
95
80enum thread_state { 96enum thread_state {
81 THREAD_SLEEPING = 0, 97 THREAD_SLEEPING = 0,
82 THREAD_WAIT_CPU, 98 THREAD_WAIT_CPU,
@@ -206,6 +222,7 @@ struct perf_sched {
206 bool show_cpu_visual; 222 bool show_cpu_visual;
207 bool show_wakeups; 223 bool show_wakeups;
208 bool show_migrations; 224 bool show_migrations;
225 bool show_state;
209 u64 skipped_samples; 226 u64 skipped_samples;
210 const char *time_str; 227 const char *time_str;
211 struct perf_time_interval ptime; 228 struct perf_time_interval ptime;
@@ -216,13 +233,20 @@ struct perf_sched {
216struct thread_runtime { 233struct thread_runtime {
217 u64 last_time; /* time of previous sched in/out event */ 234 u64 last_time; /* time of previous sched in/out event */
218 u64 dt_run; /* run time */ 235 u64 dt_run; /* run time */
219 u64 dt_wait; /* time between CPU access (off cpu) */ 236 u64 dt_sleep; /* time between CPU access by sleep (off cpu) */
237 u64 dt_iowait; /* time between CPU access by iowait (off cpu) */
238 u64 dt_preempt; /* time between CPU access by preempt (off cpu) */
220 u64 dt_delay; /* time between wakeup and sched-in */ 239 u64 dt_delay; /* time between wakeup and sched-in */
221 u64 ready_to_run; /* time of wakeup */ 240 u64 ready_to_run; /* time of wakeup */
222 241
223 struct stats run_stats; 242 struct stats run_stats;
224 u64 total_run_time; 243 u64 total_run_time;
244 u64 total_sleep_time;
245 u64 total_iowait_time;
246 u64 total_preempt_time;
247 u64 total_delay_time;
225 248
249 int last_state;
226 u64 migrations; 250 u64 migrations;
227}; 251};
228 252
@@ -436,7 +460,7 @@ static struct task_desc *register_pid(struct perf_sched *sched,
436 BUG_ON(!sched->tasks); 460 BUG_ON(!sched->tasks);
437 sched->tasks[task->nr] = task; 461 sched->tasks[task->nr] = task;
438 462
439 if (verbose) 463 if (verbose > 0)
440 printf("registered task #%ld, PID %ld (%s)\n", sched->nr_tasks, pid, comm); 464 printf("registered task #%ld, PID %ld (%s)\n", sched->nr_tasks, pid, comm);
441 465
442 return task; 466 return task;
@@ -770,7 +794,7 @@ replay_wakeup_event(struct perf_sched *sched,
770 const u32 pid = perf_evsel__intval(evsel, sample, "pid"); 794 const u32 pid = perf_evsel__intval(evsel, sample, "pid");
771 struct task_desc *waker, *wakee; 795 struct task_desc *waker, *wakee;
772 796
773 if (verbose) { 797 if (verbose > 0) {
774 printf("sched_wakeup event %p\n", evsel); 798 printf("sched_wakeup event %p\n", evsel);
775 799
776 printf(" ... pid %d woke up %s/%d\n", sample->tid, comm, pid); 800 printf(" ... pid %d woke up %s/%d\n", sample->tid, comm, pid);
@@ -798,7 +822,7 @@ static int replay_switch_event(struct perf_sched *sched,
798 int cpu = sample->cpu; 822 int cpu = sample->cpu;
799 s64 delta; 823 s64 delta;
800 824
801 if (verbose) 825 if (verbose > 0)
802 printf("sched_switch event %p\n", evsel); 826 printf("sched_switch event %p\n", evsel);
803 827
804 if (cpu >= MAX_CPUS || cpu < 0) 828 if (cpu >= MAX_CPUS || cpu < 0)
@@ -846,7 +870,7 @@ static int replay_fork_event(struct perf_sched *sched,
846 goto out_put; 870 goto out_put;
847 } 871 }
848 872
849 if (verbose) { 873 if (verbose > 0) {
850 printf("fork event\n"); 874 printf("fork event\n");
851 printf("... parent: %s/%d\n", thread__comm_str(parent), parent->tid); 875 printf("... parent: %s/%d\n", thread__comm_str(parent), parent->tid);
852 printf("... child: %s/%d\n", thread__comm_str(child), child->tid); 876 printf("... child: %s/%d\n", thread__comm_str(child), child->tid);
@@ -1549,7 +1573,7 @@ static int map_switch_event(struct perf_sched *sched, struct perf_evsel *evsel,
1549 1573
1550 timestamp__scnprintf_usec(timestamp, stimestamp, sizeof(stimestamp)); 1574 timestamp__scnprintf_usec(timestamp, stimestamp, sizeof(stimestamp));
1551 color_fprintf(stdout, color, " %12s secs ", stimestamp); 1575 color_fprintf(stdout, color, " %12s secs ", stimestamp);
1552 if (new_shortname || (verbose && sched_in->tid)) { 1576 if (new_shortname || (verbose > 0 && sched_in->tid)) {
1553 const char *pid_color = color; 1577 const char *pid_color = color;
1554 1578
1555 if (thread__has_color(sched_in)) 1579 if (thread__has_color(sched_in))
@@ -1821,6 +1845,9 @@ static void timehist_header(struct perf_sched *sched)
1821 printf(" %-*s %9s %9s %9s", comm_width, 1845 printf(" %-*s %9s %9s %9s", comm_width,
1822 "task name", "wait time", "sch delay", "run time"); 1846 "task name", "wait time", "sch delay", "run time");
1823 1847
1848 if (sched->show_state)
1849 printf(" %s", "state");
1850
1824 printf("\n"); 1851 printf("\n");
1825 1852
1826 /* 1853 /*
@@ -1831,9 +1858,14 @@ static void timehist_header(struct perf_sched *sched)
1831 if (sched->show_cpu_visual) 1858 if (sched->show_cpu_visual)
1832 printf(" %*s ", ncpus, ""); 1859 printf(" %*s ", ncpus, "");
1833 1860
1834 printf(" %-*s %9s %9s %9s\n", comm_width, 1861 printf(" %-*s %9s %9s %9s", comm_width,
1835 "[tid/pid]", "(msec)", "(msec)", "(msec)"); 1862 "[tid/pid]", "(msec)", "(msec)", "(msec)");
1836 1863
1864 if (sched->show_state)
1865 printf(" %5s", "");
1866
1867 printf("\n");
1868
1837 /* 1869 /*
1838 * separator 1870 * separator
1839 */ 1871 */
@@ -1846,18 +1878,34 @@ static void timehist_header(struct perf_sched *sched)
1846 graph_dotted_line, graph_dotted_line, graph_dotted_line, 1878 graph_dotted_line, graph_dotted_line, graph_dotted_line,
1847 graph_dotted_line); 1879 graph_dotted_line);
1848 1880
1881 if (sched->show_state)
1882 printf(" %.5s", graph_dotted_line);
1883
1849 printf("\n"); 1884 printf("\n");
1850} 1885}
1851 1886
1887static char task_state_char(struct thread *thread, int state)
1888{
1889 static const char state_to_char[] = TASK_STATE_TO_CHAR_STR;
1890 unsigned bit = state ? ffs(state) : 0;
1891
1892 /* 'I' for idle */
1893 if (thread->tid == 0)
1894 return 'I';
1895
1896 return bit < sizeof(state_to_char) - 1 ? state_to_char[bit] : '?';
1897}
1898
1852static void timehist_print_sample(struct perf_sched *sched, 1899static void timehist_print_sample(struct perf_sched *sched,
1853 struct perf_sample *sample, 1900 struct perf_sample *sample,
1854 struct addr_location *al, 1901 struct addr_location *al,
1855 struct thread *thread, 1902 struct thread *thread,
1856 u64 t) 1903 u64 t, int state)
1857{ 1904{
1858 struct thread_runtime *tr = thread__priv(thread); 1905 struct thread_runtime *tr = thread__priv(thread);
1859 u32 max_cpus = sched->max_cpu + 1; 1906 u32 max_cpus = sched->max_cpu + 1;
1860 char tstr[64]; 1907 char tstr[64];
1908 u64 wait_time;
1861 1909
1862 timestamp__scnprintf_usec(t, tstr, sizeof(tstr)); 1910 timestamp__scnprintf_usec(t, tstr, sizeof(tstr));
1863 printf("%15s [%04d] ", tstr, sample->cpu); 1911 printf("%15s [%04d] ", tstr, sample->cpu);
@@ -1880,10 +1928,15 @@ static void timehist_print_sample(struct perf_sched *sched,
1880 1928
1881 printf(" %-*s ", comm_width, timehist_get_commstr(thread)); 1929 printf(" %-*s ", comm_width, timehist_get_commstr(thread));
1882 1930
1883 print_sched_time(tr->dt_wait, 6); 1931 wait_time = tr->dt_sleep + tr->dt_iowait + tr->dt_preempt;
1932 print_sched_time(wait_time, 6);
1933
1884 print_sched_time(tr->dt_delay, 6); 1934 print_sched_time(tr->dt_delay, 6);
1885 print_sched_time(tr->dt_run, 6); 1935 print_sched_time(tr->dt_run, 6);
1886 1936
1937 if (sched->show_state)
1938 printf(" %5c ", task_state_char(thread, state));
1939
1887 if (sched->show_wakeups) 1940 if (sched->show_wakeups)
1888 printf(" %-*s", comm_width, ""); 1941 printf(" %-*s", comm_width, "");
1889 1942
@@ -1930,8 +1983,11 @@ static void timehist_update_runtime_stats(struct thread_runtime *r,
1930 u64 t, u64 tprev) 1983 u64 t, u64 tprev)
1931{ 1984{
1932 r->dt_delay = 0; 1985 r->dt_delay = 0;
1933 r->dt_wait = 0; 1986 r->dt_sleep = 0;
1987 r->dt_iowait = 0;
1988 r->dt_preempt = 0;
1934 r->dt_run = 0; 1989 r->dt_run = 0;
1990
1935 if (tprev) { 1991 if (tprev) {
1936 r->dt_run = t - tprev; 1992 r->dt_run = t - tprev;
1937 if (r->ready_to_run) { 1993 if (r->ready_to_run) {
@@ -1943,12 +1999,25 @@ static void timehist_update_runtime_stats(struct thread_runtime *r,
1943 1999
1944 if (r->last_time > tprev) 2000 if (r->last_time > tprev)
1945 pr_debug("time travel: last sched out time for task > previous sched_switch event\n"); 2001 pr_debug("time travel: last sched out time for task > previous sched_switch event\n");
1946 else if (r->last_time) 2002 else if (r->last_time) {
1947 r->dt_wait = tprev - r->last_time; 2003 u64 dt_wait = tprev - r->last_time;
2004
2005 if (r->last_state == TASK_RUNNING)
2006 r->dt_preempt = dt_wait;
2007 else if (r->last_state == TASK_UNINTERRUPTIBLE)
2008 r->dt_iowait = dt_wait;
2009 else
2010 r->dt_sleep = dt_wait;
2011 }
1948 } 2012 }
1949 2013
1950 update_stats(&r->run_stats, r->dt_run); 2014 update_stats(&r->run_stats, r->dt_run);
1951 r->total_run_time += r->dt_run; 2015
2016 r->total_run_time += r->dt_run;
2017 r->total_delay_time += r->dt_delay;
2018 r->total_sleep_time += r->dt_sleep;
2019 r->total_iowait_time += r->dt_iowait;
2020 r->total_preempt_time += r->dt_preempt;
1952} 2021}
1953 2022
1954static bool is_idle_sample(struct perf_sample *sample, 2023static bool is_idle_sample(struct perf_sample *sample,
@@ -1981,7 +2050,7 @@ static void save_task_callchain(struct perf_sched *sched,
1981 2050
1982 if (thread__resolve_callchain(thread, cursor, evsel, sample, 2051 if (thread__resolve_callchain(thread, cursor, evsel, sample,
1983 NULL, NULL, sched->max_stack + 2) != 0) { 2052 NULL, NULL, sched->max_stack + 2) != 0) {
1984 if (verbose) 2053 if (verbose > 0)
1985 error("Failed to resolve callchain. Skipping\n"); 2054 error("Failed to resolve callchain. Skipping\n");
1986 2055
1987 return; 2056 return;
@@ -1998,7 +2067,7 @@ static void save_task_callchain(struct perf_sched *sched,
1998 break; 2067 break;
1999 2068
2000 sym = node->sym; 2069 sym = node->sym;
2001 if (sym && sym->name) { 2070 if (sym) {
2002 if (!strcmp(sym->name, "schedule") || 2071 if (!strcmp(sym->name, "schedule") ||
2003 !strcmp(sym->name, "__schedule") || 2072 !strcmp(sym->name, "__schedule") ||
2004 !strcmp(sym->name, "preempt_schedule")) 2073 !strcmp(sym->name, "preempt_schedule"))
@@ -2373,6 +2442,8 @@ static int timehist_sched_change_event(struct perf_tool *tool,
2373 struct thread_runtime *tr = NULL; 2442 struct thread_runtime *tr = NULL;
2374 u64 tprev, t = sample->time; 2443 u64 tprev, t = sample->time;
2375 int rc = 0; 2444 int rc = 0;
2445 int state = perf_evsel__intval(evsel, sample, "prev_state");
2446
2376 2447
2377 if (machine__resolve(machine, &al, sample) < 0) { 2448 if (machine__resolve(machine, &al, sample) < 0) {
2378 pr_err("problem processing %d event. skipping it\n", 2449 pr_err("problem processing %d event. skipping it\n",
@@ -2447,8 +2518,10 @@ static int timehist_sched_change_event(struct perf_tool *tool,
2447 * time. we only care total run time and run stat. 2518 * time. we only care total run time and run stat.
2448 */ 2519 */
2449 last_tr->dt_run = 0; 2520 last_tr->dt_run = 0;
2450 last_tr->dt_wait = 0;
2451 last_tr->dt_delay = 0; 2521 last_tr->dt_delay = 0;
2522 last_tr->dt_sleep = 0;
2523 last_tr->dt_iowait = 0;
2524 last_tr->dt_preempt = 0;
2452 2525
2453 if (itr->cursor.nr) 2526 if (itr->cursor.nr)
2454 callchain_append(&itr->callchain, &itr->cursor, t - tprev); 2527 callchain_append(&itr->callchain, &itr->cursor, t - tprev);
@@ -2458,7 +2531,7 @@ static int timehist_sched_change_event(struct perf_tool *tool,
2458 } 2531 }
2459 2532
2460 if (!sched->summary_only) 2533 if (!sched->summary_only)
2461 timehist_print_sample(sched, sample, &al, thread, t); 2534 timehist_print_sample(sched, sample, &al, thread, t, state);
2462 2535
2463out: 2536out:
2464 if (sched->hist_time.start == 0 && t >= ptime->start) 2537 if (sched->hist_time.start == 0 && t >= ptime->start)
@@ -2470,6 +2543,9 @@ out:
2470 /* time of this sched_switch event becomes last time task seen */ 2543 /* time of this sched_switch event becomes last time task seen */
2471 tr->last_time = sample->time; 2544 tr->last_time = sample->time;
2472 2545
2546 /* last state is used to determine where to account wait time */
2547 tr->last_state = state;
2548
2473 /* sched out event for task so reset ready to run time */ 2549 /* sched out event for task so reset ready to run time */
2474 tr->ready_to_run = 0; 2550 tr->ready_to_run = 0;
2475 } 2551 }
@@ -2526,7 +2602,26 @@ static void print_thread_runtime(struct thread *t,
2526 printf("\n"); 2602 printf("\n");
2527} 2603}
2528 2604
2605static void print_thread_waittime(struct thread *t,
2606 struct thread_runtime *r)
2607{
2608 printf("%*s %5d %9" PRIu64 " ",
2609 comm_width, timehist_get_commstr(t), t->ppid,
2610 (u64) r->run_stats.n);
2611
2612 print_sched_time(r->total_run_time, 8);
2613 print_sched_time(r->total_sleep_time, 6);
2614 printf(" ");
2615 print_sched_time(r->total_iowait_time, 6);
2616 printf(" ");
2617 print_sched_time(r->total_preempt_time, 6);
2618 printf(" ");
2619 print_sched_time(r->total_delay_time, 6);
2620 printf("\n");
2621}
2622
2529struct total_run_stats { 2623struct total_run_stats {
2624 struct perf_sched *sched;
2530 u64 sched_count; 2625 u64 sched_count;
2531 u64 task_count; 2626 u64 task_count;
2532 u64 total_run_time; 2627 u64 total_run_time;
@@ -2545,7 +2640,11 @@ static int __show_thread_runtime(struct thread *t, void *priv)
2545 stats->task_count++; 2640 stats->task_count++;
2546 stats->sched_count += r->run_stats.n; 2641 stats->sched_count += r->run_stats.n;
2547 stats->total_run_time += r->total_run_time; 2642 stats->total_run_time += r->total_run_time;
2548 print_thread_runtime(t, r); 2643
2644 if (stats->sched->show_state)
2645 print_thread_waittime(t, r);
2646 else
2647 print_thread_runtime(t, r);
2549 } 2648 }
2550 2649
2551 return 0; 2650 return 0;
@@ -2633,18 +2732,24 @@ static void timehist_print_summary(struct perf_sched *sched,
2633 u64 hist_time = sched->hist_time.end - sched->hist_time.start; 2732 u64 hist_time = sched->hist_time.end - sched->hist_time.start;
2634 2733
2635 memset(&totals, 0, sizeof(totals)); 2734 memset(&totals, 0, sizeof(totals));
2735 totals.sched = sched;
2636 2736
2637 if (sched->idle_hist) { 2737 if (sched->idle_hist) {
2638 printf("\nIdle-time summary\n"); 2738 printf("\nIdle-time summary\n");
2639 printf("%*s parent sched-out ", comm_width, "comm"); 2739 printf("%*s parent sched-out ", comm_width, "comm");
2640 printf(" idle-time min-idle avg-idle max-idle stddev migrations\n"); 2740 printf(" idle-time min-idle avg-idle max-idle stddev migrations\n");
2741 } else if (sched->show_state) {
2742 printf("\nWait-time summary\n");
2743 printf("%*s parent sched-in ", comm_width, "comm");
2744 printf(" run-time sleep iowait preempt delay\n");
2641 } else { 2745 } else {
2642 printf("\nRuntime summary\n"); 2746 printf("\nRuntime summary\n");
2643 printf("%*s parent sched-in ", comm_width, "comm"); 2747 printf("%*s parent sched-in ", comm_width, "comm");
2644 printf(" run-time min-run avg-run max-run stddev migrations\n"); 2748 printf(" run-time min-run avg-run max-run stddev migrations\n");
2645 } 2749 }
2646 printf("%*s (count) ", comm_width, ""); 2750 printf("%*s (count) ", comm_width, "");
2647 printf(" (msec) (msec) (msec) (msec) %%\n"); 2751 printf(" (msec) (msec) (msec) (msec) %s\n",
2752 sched->show_state ? "(msec)" : "%");
2648 printf("%.117s\n", graph_dotted_line); 2753 printf("%.117s\n", graph_dotted_line);
2649 2754
2650 machine__for_each_thread(m, show_thread_runtime, &totals); 2755 machine__for_each_thread(m, show_thread_runtime, &totals);
@@ -3240,6 +3345,7 @@ int cmd_sched(int argc, const char **argv, const char *prefix __maybe_unused)
3240 OPT_BOOLEAN('I', "idle-hist", &sched.idle_hist, "Show idle events only"), 3345 OPT_BOOLEAN('I', "idle-hist", &sched.idle_hist, "Show idle events only"),
3241 OPT_STRING(0, "time", &sched.time_str, "str", 3346 OPT_STRING(0, "time", &sched.time_str, "str",
3242 "Time span for analysis (start,stop)"), 3347 "Time span for analysis (start,stop)"),
3348 OPT_BOOLEAN(0, "state", &sched.show_state, "Show task state when sched-out"),
3243 OPT_PARENT(sched_options) 3349 OPT_PARENT(sched_options)
3244 }; 3350 };
3245 3351
diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c
index 2f3ff69fc4e7..c0783b4f7b6c 100644
--- a/tools/perf/builtin-script.c
+++ b/tools/perf/builtin-script.c
@@ -2180,7 +2180,7 @@ int cmd_script(int argc, const char **argv, const char *prefix __maybe_unused)
2180 "Show the mmap events"), 2180 "Show the mmap events"),
2181 OPT_BOOLEAN('\0', "show-switch-events", &script.show_switch_events, 2181 OPT_BOOLEAN('\0', "show-switch-events", &script.show_switch_events,
2182 "Show context switch events (if recorded)"), 2182 "Show context switch events (if recorded)"),
2183 OPT_BOOLEAN('f', "force", &file.force, "don't complain, do it"), 2183 OPT_BOOLEAN('f', "force", &symbol_conf.force, "don't complain, do it"),
2184 OPT_BOOLEAN(0, "ns", &nanosecs, 2184 OPT_BOOLEAN(0, "ns", &nanosecs,
2185 "Use 9 decimal places when displaying time"), 2185 "Use 9 decimal places when displaying time"),
2186 OPT_CALLBACK_OPTARG(0, "itrace", &itrace_synth_opts, NULL, "opts", 2186 OPT_CALLBACK_OPTARG(0, "itrace", &itrace_synth_opts, NULL, "opts",
@@ -2212,6 +2212,7 @@ int cmd_script(int argc, const char **argv, const char *prefix __maybe_unused)
2212 PARSE_OPT_STOP_AT_NON_OPTION); 2212 PARSE_OPT_STOP_AT_NON_OPTION);
2213 2213
2214 file.path = input_name; 2214 file.path = input_name;
2215 file.force = symbol_conf.force;
2215 2216
2216 if (argc > 1 && !strncmp(argv[0], "rec", strlen("rec"))) { 2217 if (argc > 1 && !strncmp(argv[0], "rec", strlen("rec"))) {
2217 rec_script_path = get_script_path(argv[1], RECORD_SUFFIX); 2218 rec_script_path = get_script_path(argv[1], RECORD_SUFFIX);
diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c
index a02f2e965628..13b54999ad79 100644
--- a/tools/perf/builtin-stat.c
+++ b/tools/perf/builtin-stat.c
@@ -533,7 +533,7 @@ static int store_counter_ids(struct perf_evsel *counter)
533static int __run_perf_stat(int argc, const char **argv) 533static int __run_perf_stat(int argc, const char **argv)
534{ 534{
535 int interval = stat_config.interval; 535 int interval = stat_config.interval;
536 char msg[512]; 536 char msg[BUFSIZ];
537 unsigned long long t0, t1; 537 unsigned long long t0, t1;
538 struct perf_evsel *counter; 538 struct perf_evsel *counter;
539 struct timespec ts; 539 struct timespec ts;
@@ -573,7 +573,7 @@ try_again:
573 if (errno == EINVAL || errno == ENOSYS || 573 if (errno == EINVAL || errno == ENOSYS ||
574 errno == ENOENT || errno == EOPNOTSUPP || 574 errno == ENOENT || errno == EOPNOTSUPP ||
575 errno == ENXIO) { 575 errno == ENXIO) {
576 if (verbose) 576 if (verbose > 0)
577 ui__warning("%s event is not supported by the kernel.\n", 577 ui__warning("%s event is not supported by the kernel.\n",
578 perf_evsel__name(counter)); 578 perf_evsel__name(counter));
579 counter->supported = false; 579 counter->supported = false;
@@ -582,7 +582,7 @@ try_again:
582 !(counter->leader->nr_members > 1)) 582 !(counter->leader->nr_members > 1))
583 continue; 583 continue;
584 } else if (perf_evsel__fallback(counter, errno, msg, sizeof(msg))) { 584 } else if (perf_evsel__fallback(counter, errno, msg, sizeof(msg))) {
585 if (verbose) 585 if (verbose > 0)
586 ui__warning("%s\n", msg); 586 ui__warning("%s\n", msg);
587 goto try_again; 587 goto try_again;
588 } 588 }
@@ -1765,7 +1765,7 @@ static inline int perf_env__get_cpu(struct perf_env *env, struct cpu_map *map, i
1765 1765
1766 cpu = map->map[idx]; 1766 cpu = map->map[idx];
1767 1767
1768 if (cpu >= env->nr_cpus_online) 1768 if (cpu >= env->nr_cpus_avail)
1769 return -1; 1769 return -1;
1770 1770
1771 return cpu; 1771 return cpu;
@@ -2445,8 +2445,9 @@ int cmd_stat(int argc, const char **argv, const char *prefix __maybe_unused)
2445 } else if (big_num_opt == 0) /* User passed --no-big-num */ 2445 } else if (big_num_opt == 0) /* User passed --no-big-num */
2446 big_num = false; 2446 big_num = false;
2447 2447
2448 /* Make system wide (-a) the default target. */
2448 if (!argc && target__none(&target)) 2449 if (!argc && target__none(&target))
2449 usage_with_options(stat_usage, stat_options); 2450 target.system_wide = true;
2450 2451
2451 if (run_count < 0) { 2452 if (run_count < 0) {
2452 pr_err("Run count must be a positive number\n"); 2453 pr_err("Run count must be a positive number\n");
@@ -2538,7 +2539,7 @@ int cmd_stat(int argc, const char **argv, const char *prefix __maybe_unused)
2538 2539
2539 status = 0; 2540 status = 0;
2540 for (run_idx = 0; forever || run_idx < run_count; run_idx++) { 2541 for (run_idx = 0; forever || run_idx < run_count; run_idx++) {
2541 if (run_count != 1 && verbose) 2542 if (run_count != 1 && verbose > 0)
2542 fprintf(output, "[ perf stat: executing run #%d ... ]\n", 2543 fprintf(output, "[ perf stat: executing run #%d ... ]\n",
2543 run_idx + 1); 2544 run_idx + 1);
2544 2545
diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c
index 3df4178ba378..ab9077915763 100644
--- a/tools/perf/builtin-top.c
+++ b/tools/perf/builtin-top.c
@@ -643,7 +643,7 @@ repeat:
643 case -1: 643 case -1:
644 if (errno == EINTR) 644 if (errno == EINTR)
645 continue; 645 continue;
646 /* Fall trhu */ 646 __fallthrough;
647 default: 647 default:
648 c = getc(stdin); 648 c = getc(stdin);
649 tcsetattr(0, TCSAFLUSH, &save); 649 tcsetattr(0, TCSAFLUSH, &save);
@@ -859,7 +859,7 @@ static void perf_top__mmap_read(struct perf_top *top)
859 859
860static int perf_top__start_counters(struct perf_top *top) 860static int perf_top__start_counters(struct perf_top *top)
861{ 861{
862 char msg[512]; 862 char msg[BUFSIZ];
863 struct perf_evsel *counter; 863 struct perf_evsel *counter;
864 struct perf_evlist *evlist = top->evlist; 864 struct perf_evlist *evlist = top->evlist;
865 struct record_opts *opts = &top->record_opts; 865 struct record_opts *opts = &top->record_opts;
@@ -871,7 +871,7 @@ try_again:
871 if (perf_evsel__open(counter, top->evlist->cpus, 871 if (perf_evsel__open(counter, top->evlist->cpus,
872 top->evlist->threads) < 0) { 872 top->evlist->threads) < 0) {
873 if (perf_evsel__fallback(counter, errno, msg, sizeof(msg))) { 873 if (perf_evsel__fallback(counter, errno, msg, sizeof(msg))) {
874 if (verbose) 874 if (verbose > 0)
875 ui__warning("%s\n", msg); 875 ui__warning("%s\n", msg);
876 goto try_again; 876 goto try_again;
877 } 877 }
@@ -1216,7 +1216,9 @@ int cmd_top(int argc, const char **argv, const char *prefix __maybe_unused)
1216 if (top.evlist == NULL) 1216 if (top.evlist == NULL)
1217 return -ENOMEM; 1217 return -ENOMEM;
1218 1218
1219 perf_config(perf_top_config, &top); 1219 status = perf_config(perf_top_config, &top);
1220 if (status)
1221 return status;
1220 1222
1221 argc = parse_options(argc, argv, options, top_usage, 0); 1223 argc = parse_options(argc, argv, options, top_usage, 0);
1222 if (argc) 1224 if (argc)
diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c
index 206bf72b77fc..256f1fac6f7e 100644
--- a/tools/perf/builtin-trace.c
+++ b/tools/perf/builtin-trace.c
@@ -40,6 +40,7 @@
40 40
41#include <libaudit.h> /* FIXME: Still needed for audit_errno_to_name */ 41#include <libaudit.h> /* FIXME: Still needed for audit_errno_to_name */
42#include <stdlib.h> 42#include <stdlib.h>
43#include <string.h>
43#include <linux/err.h> 44#include <linux/err.h>
44#include <linux/filter.h> 45#include <linux/filter.h>
45#include <linux/audit.h> 46#include <linux/audit.h>
@@ -1398,7 +1399,7 @@ static struct syscall *trace__syscall_info(struct trace *trace,
1398 return &trace->syscalls.table[id]; 1399 return &trace->syscalls.table[id];
1399 1400
1400out_cant_read: 1401out_cant_read:
1401 if (verbose) { 1402 if (verbose > 0) {
1402 fprintf(trace->output, "Problems reading syscall %d", id); 1403 fprintf(trace->output, "Problems reading syscall %d", id);
1403 if (id <= trace->syscalls.max && trace->syscalls.table[id].name != NULL) 1404 if (id <= trace->syscalls.max && trace->syscalls.table[id].name != NULL)
1404 fprintf(trace->output, "(%s)", trace->syscalls.table[id].name); 1405 fprintf(trace->output, "(%s)", trace->syscalls.table[id].name);
@@ -1800,10 +1801,10 @@ static void print_location(FILE *f, struct perf_sample *sample,
1800 bool print_dso, bool print_sym) 1801 bool print_dso, bool print_sym)
1801{ 1802{
1802 1803
1803 if ((verbose || print_dso) && al->map) 1804 if ((verbose > 0 || print_dso) && al->map)
1804 fprintf(f, "%s@", al->map->dso->long_name); 1805 fprintf(f, "%s@", al->map->dso->long_name);
1805 1806
1806 if ((verbose || print_sym) && al->sym) 1807 if ((verbose > 0 || print_sym) && al->sym)
1807 fprintf(f, "%s+0x%" PRIx64, al->sym->name, 1808 fprintf(f, "%s+0x%" PRIx64, al->sym->name,
1808 al->addr - al->sym->start); 1809 al->addr - al->sym->start);
1809 else if (al->map) 1810 else if (al->map)
@@ -2699,6 +2700,91 @@ static void evlist__set_evsel_handler(struct perf_evlist *evlist, void *handler)
2699 evsel->handler = handler; 2700 evsel->handler = handler;
2700} 2701}
2701 2702
2703/*
2704 * XXX: Hackish, just splitting the combined -e+--event (syscalls
2705 * (raw_syscalls:{sys_{enter,exit}} + events (tracepoints, HW, SW, etc) to use
2706 * existing facilities unchanged (trace->ev_qualifier + parse_options()).
2707 *
2708 * It'd be better to introduce a parse_options() variant that would return a
2709 * list with the terms it didn't match to an event...
2710 */
2711static int trace__parse_events_option(const struct option *opt, const char *str,
2712 int unset __maybe_unused)
2713{
2714 struct trace *trace = (struct trace *)opt->value;
2715 const char *s = str;
2716 char *sep = NULL, *lists[2] = { NULL, NULL, };
2717 int len = strlen(str), err = -1, list;
2718 char *strace_groups_dir = system_path(STRACE_GROUPS_DIR);
2719 char group_name[PATH_MAX];
2720
2721 if (strace_groups_dir == NULL)
2722 return -1;
2723
2724 if (*s == '!') {
2725 ++s;
2726 trace->not_ev_qualifier = true;
2727 }
2728
2729 while (1) {
2730 if ((sep = strchr(s, ',')) != NULL)
2731 *sep = '\0';
2732
2733 list = 0;
2734 if (syscalltbl__id(trace->sctbl, s) >= 0) {
2735 list = 1;
2736 } else {
2737 path__join(group_name, sizeof(group_name), strace_groups_dir, s);
2738 if (access(group_name, R_OK) == 0)
2739 list = 1;
2740 }
2741
2742 if (lists[list]) {
2743 sprintf(lists[list] + strlen(lists[list]), ",%s", s);
2744 } else {
2745 lists[list] = malloc(len);
2746 if (lists[list] == NULL)
2747 goto out;
2748 strcpy(lists[list], s);
2749 }
2750
2751 if (!sep)
2752 break;
2753
2754 *sep = ',';
2755 s = sep + 1;
2756 }
2757
2758 if (lists[1] != NULL) {
2759 struct strlist_config slist_config = {
2760 .dirname = strace_groups_dir,
2761 };
2762
2763 trace->ev_qualifier = strlist__new(lists[1], &slist_config);
2764 if (trace->ev_qualifier == NULL) {
2765 fputs("Not enough memory to parse event qualifier", trace->output);
2766 goto out;
2767 }
2768
2769 if (trace__validate_ev_qualifier(trace))
2770 goto out;
2771 }
2772
2773 err = 0;
2774
2775 if (lists[0]) {
2776 struct option o = OPT_CALLBACK('e', "event", &trace->evlist, "event",
2777 "event selector. use 'perf list' to list available events",
2778 parse_events_option);
2779 err = parse_events_option(&o, lists[0], 0);
2780 }
2781out:
2782 if (sep)
2783 *sep = ',';
2784
2785 return err;
2786}
2787
2702int cmd_trace(int argc, const char **argv, const char *prefix __maybe_unused) 2788int cmd_trace(int argc, const char **argv, const char *prefix __maybe_unused)
2703{ 2789{
2704 const char *trace_usage[] = { 2790 const char *trace_usage[] = {
@@ -2730,15 +2816,15 @@ int cmd_trace(int argc, const char **argv, const char *prefix __maybe_unused)
2730 .max_stack = UINT_MAX, 2816 .max_stack = UINT_MAX,
2731 }; 2817 };
2732 const char *output_name = NULL; 2818 const char *output_name = NULL;
2733 const char *ev_qualifier_str = NULL;
2734 const struct option trace_options[] = { 2819 const struct option trace_options[] = {
2735 OPT_CALLBACK(0, "event", &trace.evlist, "event", 2820 OPT_CALLBACK('e', "event", &trace, "event",
2736 "event selector. use 'perf list' to list available events", 2821 "event/syscall selector. use 'perf list' to list available events",
2737 parse_events_option), 2822 trace__parse_events_option),
2738 OPT_BOOLEAN(0, "comm", &trace.show_comm, 2823 OPT_BOOLEAN(0, "comm", &trace.show_comm,
2739 "show the thread COMM next to its id"), 2824 "show the thread COMM next to its id"),
2740 OPT_BOOLEAN(0, "tool_stats", &trace.show_tool_stats, "show tool stats"), 2825 OPT_BOOLEAN(0, "tool_stats", &trace.show_tool_stats, "show tool stats"),
2741 OPT_STRING('e', "expr", &ev_qualifier_str, "expr", "list of syscalls to trace"), 2826 OPT_CALLBACK(0, "expr", &trace, "expr", "list of syscalls/events to trace",
2827 trace__parse_events_option),
2742 OPT_STRING('o', "output", &output_name, "file", "output file name"), 2828 OPT_STRING('o', "output", &output_name, "file", "output file name"),
2743 OPT_STRING('i', "input", &input_name, "file", "Analyze events in file"), 2829 OPT_STRING('i', "input", &input_name, "file", "Analyze events in file"),
2744 OPT_STRING('p', "pid", &trace.opts.target.pid, "pid", 2830 OPT_STRING('p', "pid", &trace.opts.target.pid, "pid",
@@ -2863,7 +2949,7 @@ int cmd_trace(int argc, const char **argv, const char *prefix __maybe_unused)
2863 return -1; 2949 return -1;
2864 } 2950 }
2865 2951
2866 if (!trace.trace_syscalls && ev_qualifier_str) { 2952 if (!trace.trace_syscalls && trace.ev_qualifier) {
2867 pr_err("The -e option can't be used with --no-syscalls.\n"); 2953 pr_err("The -e option can't be used with --no-syscalls.\n");
2868 goto out; 2954 goto out;
2869 } 2955 }
@@ -2878,28 +2964,6 @@ int cmd_trace(int argc, const char **argv, const char *prefix __maybe_unused)
2878 2964
2879 trace.open_id = syscalltbl__id(trace.sctbl, "open"); 2965 trace.open_id = syscalltbl__id(trace.sctbl, "open");
2880 2966
2881 if (ev_qualifier_str != NULL) {
2882 const char *s = ev_qualifier_str;
2883 struct strlist_config slist_config = {
2884 .dirname = system_path(STRACE_GROUPS_DIR),
2885 };
2886
2887 trace.not_ev_qualifier = *s == '!';
2888 if (trace.not_ev_qualifier)
2889 ++s;
2890 trace.ev_qualifier = strlist__new(s, &slist_config);
2891 if (trace.ev_qualifier == NULL) {
2892 fputs("Not enough memory to parse event qualifier",
2893 trace.output);
2894 err = -ENOMEM;
2895 goto out_close;
2896 }
2897
2898 err = trace__validate_ev_qualifier(&trace);
2899 if (err)
2900 goto out_close;
2901 }
2902
2903 err = target__validate(&trace.opts.target); 2967 err = target__validate(&trace.opts.target);
2904 if (err) { 2968 if (err) {
2905 target__strerror(&trace.opts.target, err, bf, sizeof(bf)); 2969 target__strerror(&trace.opts.target, err, bf, sizeof(bf));
diff --git a/tools/perf/builtin.h b/tools/perf/builtin.h
index 0bcf68e98ccc..036e1e35b1a8 100644
--- a/tools/perf/builtin.h
+++ b/tools/perf/builtin.h
@@ -23,6 +23,7 @@ int cmd_diff(int argc, const char **argv, const char *prefix);
23int cmd_evlist(int argc, const char **argv, const char *prefix); 23int cmd_evlist(int argc, const char **argv, const char *prefix);
24int cmd_help(int argc, const char **argv, const char *prefix); 24int cmd_help(int argc, const char **argv, const char *prefix);
25int cmd_sched(int argc, const char **argv, const char *prefix); 25int cmd_sched(int argc, const char **argv, const char *prefix);
26int cmd_kallsyms(int argc, const char **argv, const char *prefix);
26int cmd_list(int argc, const char **argv, const char *prefix); 27int cmd_list(int argc, const char **argv, const char *prefix);
27int cmd_record(int argc, const char **argv, const char *prefix); 28int cmd_record(int argc, const char **argv, const char *prefix);
28int cmd_report(int argc, const char **argv, const char *prefix); 29int cmd_report(int argc, const char **argv, const char *prefix);
@@ -40,6 +41,7 @@ int cmd_trace(int argc, const char **argv, const char *prefix);
40int cmd_inject(int argc, const char **argv, const char *prefix); 41int cmd_inject(int argc, const char **argv, const char *prefix);
41int cmd_mem(int argc, const char **argv, const char *prefix); 42int cmd_mem(int argc, const char **argv, const char *prefix);
42int cmd_data(int argc, const char **argv, const char *prefix); 43int cmd_data(int argc, const char **argv, const char *prefix);
44int cmd_ftrace(int argc, const char **argv, const char *prefix);
43 45
44int find_scripts(char **scripts_array, char **scripts_path_array); 46int find_scripts(char **scripts_array, char **scripts_path_array);
45#endif 47#endif
diff --git a/tools/perf/command-list.txt b/tools/perf/command-list.txt
index ab5cbaa170d0..ac3efd396a72 100644
--- a/tools/perf/command-list.txt
+++ b/tools/perf/command-list.txt
@@ -11,7 +11,9 @@ perf-data mainporcelain common
11perf-diff mainporcelain common 11perf-diff mainporcelain common
12perf-config mainporcelain common 12perf-config mainporcelain common
13perf-evlist mainporcelain common 13perf-evlist mainporcelain common
14perf-ftrace mainporcelain common
14perf-inject mainporcelain common 15perf-inject mainporcelain common
16perf-kallsyms mainporcelain common
15perf-kmem mainporcelain common 17perf-kmem mainporcelain common
16perf-kvm mainporcelain common 18perf-kvm mainporcelain common
17perf-list mainporcelain common 19perf-list mainporcelain common
diff --git a/tools/perf/perf.c b/tools/perf/perf.c
index aa23b3347d6b..6d5479e03e0d 100644
--- a/tools/perf/perf.c
+++ b/tools/perf/perf.c
@@ -29,7 +29,6 @@ const char perf_usage_string[] =
29const char perf_more_info_string[] = 29const char perf_more_info_string[] =
30 "See 'perf help COMMAND' for more information on a specific command."; 30 "See 'perf help COMMAND' for more information on a specific command.";
31 31
32int use_browser = -1;
33static int use_pager = -1; 32static int use_pager = -1;
34const char *input_name; 33const char *input_name;
35 34
@@ -47,6 +46,7 @@ static struct cmd_struct commands[] = {
47 { "diff", cmd_diff, 0 }, 46 { "diff", cmd_diff, 0 },
48 { "evlist", cmd_evlist, 0 }, 47 { "evlist", cmd_evlist, 0 },
49 { "help", cmd_help, 0 }, 48 { "help", cmd_help, 0 },
49 { "kallsyms", cmd_kallsyms, 0 },
50 { "list", cmd_list, 0 }, 50 { "list", cmd_list, 0 },
51 { "record", cmd_record, 0 }, 51 { "record", cmd_record, 0 },
52 { "report", cmd_report, 0 }, 52 { "report", cmd_report, 0 },
@@ -71,6 +71,7 @@ static struct cmd_struct commands[] = {
71 { "inject", cmd_inject, 0 }, 71 { "inject", cmd_inject, 0 },
72 { "mem", cmd_mem, 0 }, 72 { "mem", cmd_mem, 0 },
73 { "data", cmd_data, 0 }, 73 { "data", cmd_data, 0 },
74 { "ftrace", cmd_ftrace, 0 },
74}; 75};
75 76
76struct pager_config { 77struct pager_config {
@@ -89,11 +90,12 @@ static int pager_command_config(const char *var, const char *value, void *data)
89/* returns 0 for "no pager", 1 for "use pager", and -1 for "not specified" */ 90/* returns 0 for "no pager", 1 for "use pager", and -1 for "not specified" */
90int check_pager_config(const char *cmd) 91int check_pager_config(const char *cmd)
91{ 92{
93 int err;
92 struct pager_config c; 94 struct pager_config c;
93 c.cmd = cmd; 95 c.cmd = cmd;
94 c.val = -1; 96 c.val = -1;
95 perf_config(pager_command_config, &c); 97 err = perf_config(pager_command_config, &c);
96 return c.val; 98 return err ?: c.val;
97} 99}
98 100
99static int browser_command_config(const char *var, const char *value, void *data) 101static int browser_command_config(const char *var, const char *value, void *data)
@@ -112,11 +114,12 @@ static int browser_command_config(const char *var, const char *value, void *data
112 */ 114 */
113static int check_browser_config(const char *cmd) 115static int check_browser_config(const char *cmd)
114{ 116{
117 int err;
115 struct pager_config c; 118 struct pager_config c;
116 c.cmd = cmd; 119 c.cmd = cmd;
117 c.val = -1; 120 c.val = -1;
118 perf_config(browser_command_config, &c); 121 err = perf_config(browser_command_config, &c);
119 return c.val; 122 return err ?: c.val;
120} 123}
121 124
122static void commit_pager_choice(void) 125static void commit_pager_choice(void)
@@ -329,8 +332,6 @@ static int handle_alias(int *argcp, const char ***argv)
329 return ret; 332 return ret;
330} 333}
331 334
332const char perf_version_string[] = PERF_VERSION;
333
334#define RUN_SETUP (1<<0) 335#define RUN_SETUP (1<<0)
335#define USE_PAGER (1<<1) 336#define USE_PAGER (1<<1)
336 337
@@ -510,6 +511,7 @@ static void cache_line_size(int *cacheline_sizep)
510 511
511int main(int argc, const char **argv) 512int main(int argc, const char **argv)
512{ 513{
514 int err;
513 const char *cmd; 515 const char *cmd;
514 char sbuf[STRERR_BUFSIZE]; 516 char sbuf[STRERR_BUFSIZE];
515 int value; 517 int value;
@@ -535,7 +537,9 @@ int main(int argc, const char **argv)
535 srandom(time(NULL)); 537 srandom(time(NULL));
536 538
537 perf_config__init(); 539 perf_config__init();
538 perf_config(perf_default_config, NULL); 540 err = perf_config(perf_default_config, NULL);
541 if (err)
542 return err;
539 set_buildid_dir(NULL); 543 set_buildid_dir(NULL);
540 544
541 /* get debugfs/tracefs mount point from /proc/mounts */ 545 /* get debugfs/tracefs mount point from /proc/mounts */
diff --git a/tools/perf/pmu-events/arch/x86/broadwellde/uncore-cache.json b/tools/perf/pmu-events/arch/x86/broadwellde/uncore-cache.json
new file mode 100644
index 000000000000..076459c51d4e
--- /dev/null
+++ b/tools/perf/pmu-events/arch/x86/broadwellde/uncore-cache.json
@@ -0,0 +1,317 @@
1[
2 {
3 "BriefDescription": "Uncore cache clock ticks. Derived from unc_c_clockticks",
4 "Counter": "0,1,2,3",
5 "EventName": "UNC_C_CLOCKTICKS",
6 "PerPkg": "1",
7 "Unit": "CBO"
8 },
9 {
10 "BriefDescription": "All LLC Misses (code+ data rd + data wr - including demand and prefetch). Derived from unc_c_llc_lookup.any",
11 "Counter": "0,1,2,3",
12 "EventCode": "0x34",
13 "EventName": "UNC_C_LLC_LOOKUP.ANY",
14 "Filter": "filter_state=0x1",
15 "PerPkg": "1",
16 "ScaleUnit": "64Bytes",
17 "UMask": "0x11",
18 "Unit": "CBO"
19 },
20 {
21 "BriefDescription": "M line evictions from LLC (writebacks to memory). Derived from unc_c_llc_victims.m_state",
22 "Counter": "0,1,2,3",
23 "EventCode": "0x37",
24 "EventName": "UNC_C_LLC_VICTIMS.M_STATE",
25 "PerPkg": "1",
26 "ScaleUnit": "64Bytes",
27 "UMask": "0x1",
28 "Unit": "CBO"
29 },
30 {
31 "BriefDescription": "LLC misses - demand and prefetch data reads - excludes LLC prefetches. Derived from unc_c_tor_inserts.miss_opcode",
32 "Counter": "0,1,2,3",
33 "EventCode": "0x35",
34 "EventName": "LLC_MISSES.DATA_READ",
35 "Filter": "filter_opc=0x182",
36 "PerPkg": "1",
37 "ScaleUnit": "64Bytes",
38 "UMask": "0x3",
39 "Unit": "CBO"
40 },
41 {
42 "BriefDescription": "LLC misses - Uncacheable reads (from cpu) . Derived from unc_c_tor_inserts.miss_opcode",
43 "Counter": "0,1,2,3",
44 "EventCode": "0x35",
45 "EventName": "LLC_MISSES.UNCACHEABLE",
46 "Filter": "filter_opc=0x187",
47 "PerPkg": "1",
48 "ScaleUnit": "64Bytes",
49 "UMask": "0x3",
50 "Unit": "CBO"
51 },
52 {
53 "BriefDescription": "MMIO reads. Derived from unc_c_tor_inserts.miss_opcode",
54 "Counter": "0,1,2,3",
55 "EventCode": "0x35",
56 "EventName": "LLC_MISSES.MMIO_READ",
57 "Filter": "filter_opc=0x187,filter_nc=1",
58 "PerPkg": "1",
59 "ScaleUnit": "64Bytes",
60 "UMask": "0x3",
61 "Unit": "CBO"
62 },
63 {
64 "BriefDescription": "MMIO writes. Derived from unc_c_tor_inserts.miss_opcode",
65 "Counter": "0,1,2,3",
66 "EventCode": "0x35",
67 "EventName": "LLC_MISSES.MMIO_WRITE",
68 "Filter": "filter_opc=0x18f,filter_nc=1",
69 "PerPkg": "1",
70 "ScaleUnit": "64Bytes",
71 "UMask": "0x3",
72 "Unit": "CBO"
73 },
74 {
75 "BriefDescription": "LLC prefetch misses for RFO. Derived from unc_c_tor_inserts.miss_opcode",
76 "Counter": "0,1,2,3",
77 "EventCode": "0x35",
78 "EventName": "LLC_MISSES.RFO_LLC_PREFETCH",
79 "Filter": "filter_opc=0x190",
80 "PerPkg": "1",
81 "ScaleUnit": "64Bytes",
82 "UMask": "0x3",
83 "Unit": "CBO"
84 },
85 {
86 "BriefDescription": "LLC prefetch misses for code reads. Derived from unc_c_tor_inserts.miss_opcode",
87 "Counter": "0,1,2,3",
88 "EventCode": "0x35",
89 "EventName": "LLC_MISSES.CODE_LLC_PREFETCH",
90 "Filter": "filter_opc=0x191",
91 "PerPkg": "1",
92 "ScaleUnit": "64Bytes",
93 "UMask": "0x3",
94 "Unit": "CBO"
95 },
96 {
97 "BriefDescription": "LLC prefetch misses for data reads. Derived from unc_c_tor_inserts.miss_opcode",
98 "Counter": "0,1,2,3",
99 "EventCode": "0x35",
100 "EventName": "LLC_MISSES.DATA_LLC_PREFETCH",
101 "Filter": "filter_opc=0x192",
102 "PerPkg": "1",
103 "ScaleUnit": "64Bytes",
104 "UMask": "0x3",
105 "Unit": "CBO"
106 },
107 {
108 "BriefDescription": "LLC misses for PCIe read current. Derived from unc_c_tor_inserts.miss_opcode",
109 "Counter": "0,1,2,3",
110 "EventCode": "0x35",
111 "EventName": "LLC_MISSES.PCIE_READ",
112 "Filter": "filter_opc=0x19e",
113 "PerPkg": "1",
114 "ScaleUnit": "64Bytes",
115 "UMask": "0x3",
116 "Unit": "CBO"
117 },
118 {
119 "BriefDescription": "ItoM write misses (as part of fast string memcpy stores) + PCIe full line writes. Derived from unc_c_tor_inserts.miss_opcode",
120 "Counter": "0,1,2,3",
121 "EventCode": "0x35",
122 "EventName": "LLC_MISSES.PCIE_WRITE",
123 "Filter": "filter_opc=0x1c8",
124 "PerPkg": "1",
125 "ScaleUnit": "64Bytes",
126 "UMask": "0x3",
127 "Unit": "CBO"
128 },
129 {
130 "BriefDescription": "PCIe write misses (full cache line). Derived from unc_c_tor_inserts.miss_opcode",
131 "Counter": "0,1,2,3",
132 "EventCode": "0x35",
133 "EventName": "LLC_MISSES.PCIE_NON_SNOOP_WRITE",
134 "Filter": "filter_opc=0x1c8,filter_tid=0x3e",
135 "PerPkg": "1",
136 "ScaleUnit": "64Bytes",
137 "UMask": "0x3",
138 "Unit": "CBO"
139 },
140 {
141 "BriefDescription": "PCIe writes (partial cache line). Derived from unc_c_tor_inserts.opcode",
142 "Counter": "0,1,2,3",
143 "EventCode": "0x35",
144 "EventName": "LLC_REFERENCES.PCIE_NS_PARTIAL_WRITE",
145 "Filter": "filter_opc=0x180,filter_tid=0x3e",
146 "PerPkg": "1",
147 "UMask": "0x1",
148 "Unit": "CBO"
149 },
150 {
151 "BriefDescription": "L2 demand and L2 prefetch code references to LLC. Derived from unc_c_tor_inserts.opcode",
152 "Counter": "0,1,2,3",
153 "EventCode": "0x35",
154 "EventName": "LLC_REFERENCES.CODE_LLC_PREFETCH",
155 "Filter": "filter_opc=0x181",
156 "PerPkg": "1",
157 "ScaleUnit": "64Bytes",
158 "UMask": "0x1",
159 "Unit": "CBO"
160 },
161 {
162 "BriefDescription": "Streaming stores (full cache line). Derived from unc_c_tor_inserts.opcode",
163 "Counter": "0,1,2,3",
164 "EventCode": "0x35",
165 "EventName": "LLC_REFERENCES.STREAMING_FULL",
166 "Filter": "filter_opc=0x18c",
167 "PerPkg": "1",
168 "ScaleUnit": "64Bytes",
169 "UMask": "0x1",
170 "Unit": "CBO"
171 },
172 {
173 "BriefDescription": "Streaming stores (partial cache line). Derived from unc_c_tor_inserts.opcode",
174 "Counter": "0,1,2,3",
175 "EventCode": "0x35",
176 "EventName": "LLC_REFERENCES.STREAMING_PARTIAL",
177 "Filter": "filter_opc=0x18d",
178 "PerPkg": "1",
179 "ScaleUnit": "64Bytes",
180 "UMask": "0x1",
181 "Unit": "CBO"
182 },
183 {
184 "BriefDescription": "PCIe read current. Derived from unc_c_tor_inserts.opcode",
185 "Counter": "0,1,2,3",
186 "EventCode": "0x35",
187 "EventName": "LLC_REFERENCES.PCIE_READ",
188 "Filter": "filter_opc=0x19e",
189 "PerPkg": "1",
190 "ScaleUnit": "64Bytes",
191 "UMask": "0x1",
192 "Unit": "CBO"
193 },
194 {
195 "BriefDescription": "PCIe write references (full cache line). Derived from unc_c_tor_inserts.opcode",
196 "Counter": "0,1,2,3",
197 "EventCode": "0x35",
198 "EventName": "LLC_REFERENCES.PCIE_WRITE",
199 "Filter": "filter_opc=0x1c8,filter_tid=0x3e",
200 "PerPkg": "1",
201 "ScaleUnit": "64Bytes",
202 "UMask": "0x1",
203 "Unit": "CBO"
204 },
205 {
206 "BriefDescription": "Occupancy counter for LLC data reads (demand and L2 prefetch). Derived from unc_c_tor_occupancy.miss_opcode",
207 "EventCode": "0x36",
208 "EventName": "UNC_C_TOR_OCCUPANCY.LLC_DATA_READ",
209 "Filter": "filter_opc=0x182",
210 "PerPkg": "1",
211 "UMask": "0x3",
212 "Unit": "CBO"
213 },
214 {
215 "BriefDescription": "read requests to home agent. Derived from unc_h_requests.reads",
216 "Counter": "0,1,2,3",
217 "EventCode": "0x1",
218 "EventName": "UNC_H_REQUESTS.READS",
219 "PerPkg": "1",
220 "UMask": "0x3",
221 "Unit": "HA"
222 },
223 {
224 "BriefDescription": "read requests to local home agent. Derived from unc_h_requests.reads_local",
225 "Counter": "0,1,2,3",
226 "EventCode": "0x1",
227 "EventName": "UNC_H_REQUESTS.READS_LOCAL",
228 "PerPkg": "1",
229 "UMask": "0x1",
230 "Unit": "HA"
231 },
232 {
233 "BriefDescription": "read requests to remote home agent. Derived from unc_h_requests.reads_remote",
234 "Counter": "0,1,2,3",
235 "EventCode": "0x1",
236 "EventName": "UNC_H_REQUESTS.READS_REMOTE",
237 "PerPkg": "1",
238 "UMask": "0x2",
239 "Unit": "HA"
240 },
241 {
242 "BriefDescription": "write requests to home agent. Derived from unc_h_requests.writes",
243 "Counter": "0,1,2,3",
244 "EventCode": "0x1",
245 "EventName": "UNC_H_REQUESTS.WRITES",
246 "PerPkg": "1",
247 "UMask": "0xC",
248 "Unit": "HA"
249 },
250 {
251 "BriefDescription": "write requests to local home agent. Derived from unc_h_requests.writes_local",
252 "Counter": "0,1,2,3",
253 "EventCode": "0x1",
254 "EventName": "UNC_H_REQUESTS.WRITES_LOCAL",
255 "PerPkg": "1",
256 "UMask": "0x4",
257 "Unit": "HA"
258 },
259 {
260 "BriefDescription": "write requests to remote home agent. Derived from unc_h_requests.writes_remote",
261 "Counter": "0,1,2,3",
262 "EventCode": "0x1",
263 "EventName": "UNC_H_REQUESTS.WRITES_REMOTE",
264 "PerPkg": "1",
265 "UMask": "0x8",
266 "Unit": "HA"
267 },
268 {
269 "BriefDescription": "Conflict requests (requests for same address from multiple agents simultaneously). Derived from unc_h_snoop_resp.rspcnflct",
270 "Counter": "0,1,2,3",
271 "EventCode": "0x21",
272 "EventName": "UNC_H_SNOOP_RESP.RSPCNFLCT",
273 "PerPkg": "1",
274 "UMask": "0x40",
275 "Unit": "HA"
276 },
277 {
278 "BriefDescription": "M line forwarded from remote cache along with writeback to memory. Derived from unc_h_snoop_resp.rsp_fwd_wb",
279 "Counter": "0,1,2,3",
280 "EventCode": "0x21",
281 "EventName": "UNC_H_SNOOP_RESP.RSP_FWD_WB",
282 "PerPkg": "1",
283 "ScaleUnit": "64Bytes",
284 "UMask": "0x20",
285 "Unit": "HA"
286 },
287 {
288 "BriefDescription": "M line forwarded from remote cache with no writeback to memory. Derived from unc_h_snoop_resp.rspifwd",
289 "Counter": "0,1,2,3",
290 "EventCode": "0x21",
291 "EventName": "UNC_H_SNOOP_RESP.RSPIFWD",
292 "PerPkg": "1",
293 "ScaleUnit": "64Bytes",
294 "UMask": "0x4",
295 "Unit": "HA"
296 },
297 {
298 "BriefDescription": "Shared line response from remote cache. Derived from unc_h_snoop_resp.rsps",
299 "Counter": "0,1,2,3",
300 "EventCode": "0x21",
301 "EventName": "UNC_H_SNOOP_RESP.RSPS",
302 "PerPkg": "1",
303 "ScaleUnit": "64Bytes",
304 "UMask": "0x2",
305 "Unit": "HA"
306 },
307 {
308 "BriefDescription": "Shared line forwarded from remote cache. Derived from unc_h_snoop_resp.rspsfwd",
309 "Counter": "0,1,2,3",
310 "EventCode": "0x21",
311 "EventName": "UNC_H_SNOOP_RESP.RSPSFWD",
312 "PerPkg": "1",
313 "ScaleUnit": "64Bytes",
314 "UMask": "0x8",
315 "Unit": "HA"
316 }
317]
diff --git a/tools/perf/pmu-events/arch/x86/broadwellde/uncore-memory.json b/tools/perf/pmu-events/arch/x86/broadwellde/uncore-memory.json
new file mode 100644
index 000000000000..d17dc235f734
--- /dev/null
+++ b/tools/perf/pmu-events/arch/x86/broadwellde/uncore-memory.json
@@ -0,0 +1,83 @@
1[
2 {
3 "BriefDescription": "read requests to memory controller. Derived from unc_m_cas_count.rd",
4 "Counter": "0,1,2,3",
5 "EventCode": "0x4",
6 "EventName": "UNC_M_CAS_COUNT.RD",
7 "PerPkg": "1",
8 "ScaleUnit": "64Bytes",
9 "UMask": "0x3",
10 "Unit": "iMC"
11 },
12 {
13 "BriefDescription": "write requests to memory controller. Derived from unc_m_cas_count.wr",
14 "Counter": "0,1,2,3",
15 "EventCode": "0x4",
16 "EventName": "UNC_M_CAS_COUNT.WR",
17 "PerPkg": "1",
18 "ScaleUnit": "64Bytes",
19 "UMask": "0xC",
20 "Unit": "iMC"
21 },
22 {
23 "BriefDescription": "Memory controller clock ticks. Derived from unc_m_clockticks",
24 "Counter": "0,1,2,3",
25 "EventName": "UNC_M_CLOCKTICKS",
26 "PerPkg": "1",
27 "Unit": "iMC"
28 },
29 {
30 "BriefDescription": "Cycles where DRAM ranks are in power down (CKE) mode. Derived from unc_m_power_channel_ppd",
31 "Counter": "0,1,2,3",
32 "EventCode": "0x85",
33 "EventName": "UNC_M_POWER_CHANNEL_PPD",
34 "MetricExpr": "(UNC_M_POWER_CHANNEL_PPD / UNC_M_CLOCKTICKS) * 100.",
35 "PerPkg": "1",
36 "Unit": "iMC"
37 },
38 {
39 "BriefDescription": "Cycles all ranks are in critical thermal throttle. Derived from unc_m_power_critical_throttle_cycles",
40 "Counter": "0,1,2,3",
41 "EventCode": "0x86",
42 "EventName": "UNC_M_POWER_CRITICAL_THROTTLE_CYCLES",
43 "MetricExpr": "(UNC_M_POWER_CRITICAL_THROTTLE_CYCLES / UNC_M_CLOCKTICKS) * 100.",
44 "PerPkg": "1",
45 "Unit": "iMC"
46 },
47 {
48 "BriefDescription": "Cycles Memory is in self refresh power mode. Derived from unc_m_power_self_refresh",
49 "Counter": "0,1,2,3",
50 "EventCode": "0x43",
51 "EventName": "UNC_M_POWER_SELF_REFRESH",
52 "MetricExpr": "(UNC_M_POWER_SELF_REFRESH / UNC_M_CLOCKTICKS) * 100.",
53 "PerPkg": "1",
54 "Unit": "iMC"
55 },
56 {
57 "BriefDescription": "Pre-charges due to page misses. Derived from unc_m_pre_count.page_miss",
58 "Counter": "0,1,2,3",
59 "EventCode": "0x2",
60 "EventName": "UNC_M_PRE_COUNT.PAGE_MISS",
61 "PerPkg": "1",
62 "UMask": "0x1",
63 "Unit": "iMC"
64 },
65 {
66 "BriefDescription": "Pre-charge for reads. Derived from unc_m_pre_count.rd",
67 "Counter": "0,1,2,3",
68 "EventCode": "0x2",
69 "EventName": "UNC_M_PRE_COUNT.RD",
70 "PerPkg": "1",
71 "UMask": "0x4",
72 "Unit": "iMC"
73 },
74 {
75 "BriefDescription": "Pre-charge for writes. Derived from unc_m_pre_count.wr",
76 "Counter": "0,1,2,3",
77 "EventCode": "0x2",
78 "EventName": "UNC_M_PRE_COUNT.WR",
79 "PerPkg": "1",
80 "UMask": "0x8",
81 "Unit": "iMC"
82 }
83]
diff --git a/tools/perf/pmu-events/arch/x86/broadwellde/uncore-power.json b/tools/perf/pmu-events/arch/x86/broadwellde/uncore-power.json
new file mode 100644
index 000000000000..b44d43088bbb
--- /dev/null
+++ b/tools/perf/pmu-events/arch/x86/broadwellde/uncore-power.json
@@ -0,0 +1,84 @@
1[
2 {
3 "BriefDescription": "PCU clock ticks. Use to get percentages of PCU cycles events. Derived from unc_p_clockticks",
4 "Counter": "0,1,2,3",
5 "EventName": "UNC_P_CLOCKTICKS",
6 "PerPkg": "1",
7 "Unit": "PCU"
8 },
9 {
10 "BriefDescription": "C0 and C1. Derived from unc_p_power_state_occupancy.cores_c0",
11 "Counter": "0,1,2,3",
12 "EventCode": "0x80",
13 "EventName": "UNC_P_POWER_STATE_OCCUPANCY.CORES_C0",
14 "Filter": "occ_sel=1",
15 "MetricExpr": "(UNC_P_POWER_STATE_OCCUPANCY.CORES_C0 / UNC_P_CLOCKTICKS) * 100.",
16 "PerPkg": "1",
17 "Unit": "PCU"
18 },
19 {
20 "BriefDescription": "C3. Derived from unc_p_power_state_occupancy.cores_c3",
21 "Counter": "0,1,2,3",
22 "EventCode": "0x80",
23 "EventName": "UNC_P_POWER_STATE_OCCUPANCY.CORES_C3",
24 "Filter": "occ_sel=2",
25 "MetricExpr": "(UNC_P_POWER_STATE_OCCUPANCY.CORES_C3 / UNC_P_CLOCKTICKS) * 100.",
26 "PerPkg": "1",
27 "Unit": "PCU"
28 },
29 {
30 "BriefDescription": "C6 and C7. Derived from unc_p_power_state_occupancy.cores_c6",
31 "Counter": "0,1,2,3",
32 "EventCode": "0x80",
33 "EventName": "UNC_P_POWER_STATE_OCCUPANCY.CORES_C6",
34 "Filter": "occ_sel=3",
35 "MetricExpr": "(UNC_P_POWER_STATE_OCCUPANCY.CORES_C6 / UNC_P_CLOCKTICKS) * 100.",
36 "PerPkg": "1",
37 "Unit": "PCU"
38 },
39 {
40 "BriefDescription": "External Prochot. Derived from unc_p_prochot_external_cycles",
41 "Counter": "0,1,2,3",
42 "EventCode": "0xA",
43 "EventName": "UNC_P_PROCHOT_EXTERNAL_CYCLES",
44 "MetricExpr": "(UNC_P_PROCHOT_EXTERNAL_CYCLES / UNC_P_CLOCKTICKS) * 100.",
45 "PerPkg": "1",
46 "Unit": "PCU"
47 },
48 {
49 "BriefDescription": "Thermal Strongest Upper Limit Cycles. Derived from unc_p_freq_max_limit_thermal_cycles",
50 "Counter": "0,1,2,3",
51 "EventCode": "0x4",
52 "EventName": "UNC_P_FREQ_MAX_LIMIT_THERMAL_CYCLES",
53 "MetricExpr": "(UNC_P_FREQ_MAX_LIMIT_THERMAL_CYCLES / UNC_P_CLOCKTICKS) * 100.",
54 "PerPkg": "1",
55 "Unit": "PCU"
56 },
57 {
58 "BriefDescription": "OS Strongest Upper Limit Cycles. Derived from unc_p_freq_max_os_cycles",
59 "Counter": "0,1,2,3",
60 "EventCode": "0x6",
61 "EventName": "UNC_P_FREQ_MAX_OS_CYCLES",
62 "MetricExpr": "(UNC_P_FREQ_MAX_OS_CYCLES / UNC_P_CLOCKTICKS) * 100.",
63 "PerPkg": "1",
64 "Unit": "PCU"
65 },
66 {
67 "BriefDescription": "Power Strongest Upper Limit Cycles. Derived from unc_p_freq_max_power_cycles",
68 "Counter": "0,1,2,3",
69 "EventCode": "0x5",
70 "EventName": "UNC_P_FREQ_MAX_POWER_CYCLES",
71 "MetricExpr": "(UNC_P_FREQ_MAX_POWER_CYCLES / UNC_P_CLOCKTICKS) * 100.",
72 "PerPkg": "1",
73 "Unit": "PCU"
74 },
75 {
76 "BriefDescription": "Cycles spent changing Frequency. Derived from unc_p_freq_trans_cycles",
77 "Counter": "0,1,2,3",
78 "EventCode": "0x74",
79 "EventName": "UNC_P_FREQ_TRANS_CYCLES",
80 "MetricExpr": "(UNC_P_FREQ_TRANS_CYCLES / UNC_P_CLOCKTICKS) * 100.",
81 "PerPkg": "1",
82 "Unit": "PCU"
83 }
84]
diff --git a/tools/perf/pmu-events/arch/x86/broadwellx/uncore-cache.json b/tools/perf/pmu-events/arch/x86/broadwellx/uncore-cache.json
new file mode 100644
index 000000000000..076459c51d4e
--- /dev/null
+++ b/tools/perf/pmu-events/arch/x86/broadwellx/uncore-cache.json
@@ -0,0 +1,317 @@
1[
2 {
3 "BriefDescription": "Uncore cache clock ticks. Derived from unc_c_clockticks",
4 "Counter": "0,1,2,3",
5 "EventName": "UNC_C_CLOCKTICKS",
6 "PerPkg": "1",
7 "Unit": "CBO"
8 },
9 {
10 "BriefDescription": "All LLC Misses (code+ data rd + data wr - including demand and prefetch). Derived from unc_c_llc_lookup.any",
11 "Counter": "0,1,2,3",
12 "EventCode": "0x34",
13 "EventName": "UNC_C_LLC_LOOKUP.ANY",
14 "Filter": "filter_state=0x1",
15 "PerPkg": "1",
16 "ScaleUnit": "64Bytes",
17 "UMask": "0x11",
18 "Unit": "CBO"
19 },
20 {
21 "BriefDescription": "M line evictions from LLC (writebacks to memory). Derived from unc_c_llc_victims.m_state",
22 "Counter": "0,1,2,3",
23 "EventCode": "0x37",
24 "EventName": "UNC_C_LLC_VICTIMS.M_STATE",
25 "PerPkg": "1",
26 "ScaleUnit": "64Bytes",
27 "UMask": "0x1",
28 "Unit": "CBO"
29 },
30 {
31 "BriefDescription": "LLC misses - demand and prefetch data reads - excludes LLC prefetches. Derived from unc_c_tor_inserts.miss_opcode",
32 "Counter": "0,1,2,3",
33 "EventCode": "0x35",
34 "EventName": "LLC_MISSES.DATA_READ",
35 "Filter": "filter_opc=0x182",
36 "PerPkg": "1",
37 "ScaleUnit": "64Bytes",
38 "UMask": "0x3",
39 "Unit": "CBO"
40 },
41 {
42 "BriefDescription": "LLC misses - Uncacheable reads (from cpu) . Derived from unc_c_tor_inserts.miss_opcode",
43 "Counter": "0,1,2,3",
44 "EventCode": "0x35",
45 "EventName": "LLC_MISSES.UNCACHEABLE",
46 "Filter": "filter_opc=0x187",
47 "PerPkg": "1",
48 "ScaleUnit": "64Bytes",
49 "UMask": "0x3",
50 "Unit": "CBO"
51 },
52 {
53 "BriefDescription": "MMIO reads. Derived from unc_c_tor_inserts.miss_opcode",
54 "Counter": "0,1,2,3",
55 "EventCode": "0x35",
56 "EventName": "LLC_MISSES.MMIO_READ",
57 "Filter": "filter_opc=0x187,filter_nc=1",
58 "PerPkg": "1",
59 "ScaleUnit": "64Bytes",
60 "UMask": "0x3",
61 "Unit": "CBO"
62 },
63 {
64 "BriefDescription": "MMIO writes. Derived from unc_c_tor_inserts.miss_opcode",
65 "Counter": "0,1,2,3",
66 "EventCode": "0x35",
67 "EventName": "LLC_MISSES.MMIO_WRITE",
68 "Filter": "filter_opc=0x18f,filter_nc=1",
69 "PerPkg": "1",
70 "ScaleUnit": "64Bytes",
71 "UMask": "0x3",
72 "Unit": "CBO"
73 },
74 {
75 "BriefDescription": "LLC prefetch misses for RFO. Derived from unc_c_tor_inserts.miss_opcode",
76 "Counter": "0,1,2,3",
77 "EventCode": "0x35",
78 "EventName": "LLC_MISSES.RFO_LLC_PREFETCH",
79 "Filter": "filter_opc=0x190",
80 "PerPkg": "1",
81 "ScaleUnit": "64Bytes",
82 "UMask": "0x3",
83 "Unit": "CBO"
84 },
85 {
86 "BriefDescription": "LLC prefetch misses for code reads. Derived from unc_c_tor_inserts.miss_opcode",
87 "Counter": "0,1,2,3",
88 "EventCode": "0x35",
89 "EventName": "LLC_MISSES.CODE_LLC_PREFETCH",
90 "Filter": "filter_opc=0x191",
91 "PerPkg": "1",
92 "ScaleUnit": "64Bytes",
93 "UMask": "0x3",
94 "Unit": "CBO"
95 },
96 {
97 "BriefDescription": "LLC prefetch misses for data reads. Derived from unc_c_tor_inserts.miss_opcode",
98 "Counter": "0,1,2,3",
99 "EventCode": "0x35",
100 "EventName": "LLC_MISSES.DATA_LLC_PREFETCH",
101 "Filter": "filter_opc=0x192",
102 "PerPkg": "1",
103 "ScaleUnit": "64Bytes",
104 "UMask": "0x3",
105 "Unit": "CBO"
106 },
107 {
108 "BriefDescription": "LLC misses for PCIe read current. Derived from unc_c_tor_inserts.miss_opcode",
109 "Counter": "0,1,2,3",
110 "EventCode": "0x35",
111 "EventName": "LLC_MISSES.PCIE_READ",
112 "Filter": "filter_opc=0x19e",
113 "PerPkg": "1",
114 "ScaleUnit": "64Bytes",
115 "UMask": "0x3",
116 "Unit": "CBO"
117 },
118 {
119 "BriefDescription": "ItoM write misses (as part of fast string memcpy stores) + PCIe full line writes. Derived from unc_c_tor_inserts.miss_opcode",
120 "Counter": "0,1,2,3",
121 "EventCode": "0x35",
122 "EventName": "LLC_MISSES.PCIE_WRITE",
123 "Filter": "filter_opc=0x1c8",
124 "PerPkg": "1",
125 "ScaleUnit": "64Bytes",
126 "UMask": "0x3",
127 "Unit": "CBO"
128 },
129 {
130 "BriefDescription": "PCIe write misses (full cache line). Derived from unc_c_tor_inserts.miss_opcode",
131 "Counter": "0,1,2,3",
132 "EventCode": "0x35",
133 "EventName": "LLC_MISSES.PCIE_NON_SNOOP_WRITE",
134 "Filter": "filter_opc=0x1c8,filter_tid=0x3e",
135 "PerPkg": "1",
136 "ScaleUnit": "64Bytes",
137 "UMask": "0x3",
138 "Unit": "CBO"
139 },
140 {
141 "BriefDescription": "PCIe writes (partial cache line). Derived from unc_c_tor_inserts.opcode",
142 "Counter": "0,1,2,3",
143 "EventCode": "0x35",
144 "EventName": "LLC_REFERENCES.PCIE_NS_PARTIAL_WRITE",
145 "Filter": "filter_opc=0x180,filter_tid=0x3e",
146 "PerPkg": "1",
147 "UMask": "0x1",
148 "Unit": "CBO"
149 },
150 {
151 "BriefDescription": "L2 demand and L2 prefetch code references to LLC. Derived from unc_c_tor_inserts.opcode",
152 "Counter": "0,1,2,3",
153 "EventCode": "0x35",
154 "EventName": "LLC_REFERENCES.CODE_LLC_PREFETCH",
155 "Filter": "filter_opc=0x181",
156 "PerPkg": "1",
157 "ScaleUnit": "64Bytes",
158 "UMask": "0x1",
159 "Unit": "CBO"
160 },
161 {
162 "BriefDescription": "Streaming stores (full cache line). Derived from unc_c_tor_inserts.opcode",
163 "Counter": "0,1,2,3",
164 "EventCode": "0x35",
165 "EventName": "LLC_REFERENCES.STREAMING_FULL",
166 "Filter": "filter_opc=0x18c",
167 "PerPkg": "1",
168 "ScaleUnit": "64Bytes",
169 "UMask": "0x1",
170 "Unit": "CBO"
171 },
172 {
173 "BriefDescription": "Streaming stores (partial cache line). Derived from unc_c_tor_inserts.opcode",
174 "Counter": "0,1,2,3",
175 "EventCode": "0x35",
176 "EventName": "LLC_REFERENCES.STREAMING_PARTIAL",
177 "Filter": "filter_opc=0x18d",
178 "PerPkg": "1",
179 "ScaleUnit": "64Bytes",
180 "UMask": "0x1",
181 "Unit": "CBO"
182 },
183 {
184 "BriefDescription": "PCIe read current. Derived from unc_c_tor_inserts.opcode",
185 "Counter": "0,1,2,3",
186 "EventCode": "0x35",
187 "EventName": "LLC_REFERENCES.PCIE_READ",
188 "Filter": "filter_opc=0x19e",
189 "PerPkg": "1",
190 "ScaleUnit": "64Bytes",
191 "UMask": "0x1",
192 "Unit": "CBO"
193 },
194 {
195 "BriefDescription": "PCIe write references (full cache line). Derived from unc_c_tor_inserts.opcode",
196 "Counter": "0,1,2,3",
197 "EventCode": "0x35",
198 "EventName": "LLC_REFERENCES.PCIE_WRITE",
199 "Filter": "filter_opc=0x1c8,filter_tid=0x3e",
200 "PerPkg": "1",
201 "ScaleUnit": "64Bytes",
202 "UMask": "0x1",
203 "Unit": "CBO"
204 },
205 {
206 "BriefDescription": "Occupancy counter for LLC data reads (demand and L2 prefetch). Derived from unc_c_tor_occupancy.miss_opcode",
207 "EventCode": "0x36",
208 "EventName": "UNC_C_TOR_OCCUPANCY.LLC_DATA_READ",
209 "Filter": "filter_opc=0x182",
210 "PerPkg": "1",
211 "UMask": "0x3",
212 "Unit": "CBO"
213 },
214 {
215 "BriefDescription": "read requests to home agent. Derived from unc_h_requests.reads",
216 "Counter": "0,1,2,3",
217 "EventCode": "0x1",
218 "EventName": "UNC_H_REQUESTS.READS",
219 "PerPkg": "1",
220 "UMask": "0x3",
221 "Unit": "HA"
222 },
223 {
224 "BriefDescription": "read requests to local home agent. Derived from unc_h_requests.reads_local",
225 "Counter": "0,1,2,3",
226 "EventCode": "0x1",
227 "EventName": "UNC_H_REQUESTS.READS_LOCAL",
228 "PerPkg": "1",
229 "UMask": "0x1",
230 "Unit": "HA"
231 },
232 {
233 "BriefDescription": "read requests to remote home agent. Derived from unc_h_requests.reads_remote",
234 "Counter": "0,1,2,3",
235 "EventCode": "0x1",
236 "EventName": "UNC_H_REQUESTS.READS_REMOTE",
237 "PerPkg": "1",
238 "UMask": "0x2",
239 "Unit": "HA"
240 },
241 {
242 "BriefDescription": "write requests to home agent. Derived from unc_h_requests.writes",
243 "Counter": "0,1,2,3",
244 "EventCode": "0x1",
245 "EventName": "UNC_H_REQUESTS.WRITES",
246 "PerPkg": "1",
247 "UMask": "0xC",
248 "Unit": "HA"
249 },
250 {
251 "BriefDescription": "write requests to local home agent. Derived from unc_h_requests.writes_local",
252 "Counter": "0,1,2,3",
253 "EventCode": "0x1",
254 "EventName": "UNC_H_REQUESTS.WRITES_LOCAL",
255 "PerPkg": "1",
256 "UMask": "0x4",
257 "Unit": "HA"
258 },
259 {
260 "BriefDescription": "write requests to remote home agent. Derived from unc_h_requests.writes_remote",
261 "Counter": "0,1,2,3",
262 "EventCode": "0x1",
263 "EventName": "UNC_H_REQUESTS.WRITES_REMOTE",
264 "PerPkg": "1",
265 "UMask": "0x8",
266 "Unit": "HA"
267 },
268 {
269 "BriefDescription": "Conflict requests (requests for same address from multiple agents simultaneously). Derived from unc_h_snoop_resp.rspcnflct",
270 "Counter": "0,1,2,3",
271 "EventCode": "0x21",
272 "EventName": "UNC_H_SNOOP_RESP.RSPCNFLCT",
273 "PerPkg": "1",
274 "UMask": "0x40",
275 "Unit": "HA"
276 },
277 {
278 "BriefDescription": "M line forwarded from remote cache along with writeback to memory. Derived from unc_h_snoop_resp.rsp_fwd_wb",
279 "Counter": "0,1,2,3",
280 "EventCode": "0x21",
281 "EventName": "UNC_H_SNOOP_RESP.RSP_FWD_WB",
282 "PerPkg": "1",
283 "ScaleUnit": "64Bytes",
284 "UMask": "0x20",
285 "Unit": "HA"
286 },
287 {
288 "BriefDescription": "M line forwarded from remote cache with no writeback to memory. Derived from unc_h_snoop_resp.rspifwd",
289 "Counter": "0,1,2,3",
290 "EventCode": "0x21",
291 "EventName": "UNC_H_SNOOP_RESP.RSPIFWD",
292 "PerPkg": "1",
293 "ScaleUnit": "64Bytes",
294 "UMask": "0x4",
295 "Unit": "HA"
296 },
297 {
298 "BriefDescription": "Shared line response from remote cache. Derived from unc_h_snoop_resp.rsps",
299 "Counter": "0,1,2,3",
300 "EventCode": "0x21",
301 "EventName": "UNC_H_SNOOP_RESP.RSPS",
302 "PerPkg": "1",
303 "ScaleUnit": "64Bytes",
304 "UMask": "0x2",
305 "Unit": "HA"
306 },
307 {
308 "BriefDescription": "Shared line forwarded from remote cache. Derived from unc_h_snoop_resp.rspsfwd",
309 "Counter": "0,1,2,3",
310 "EventCode": "0x21",
311 "EventName": "UNC_H_SNOOP_RESP.RSPSFWD",
312 "PerPkg": "1",
313 "ScaleUnit": "64Bytes",
314 "UMask": "0x8",
315 "Unit": "HA"
316 }
317]
diff --git a/tools/perf/pmu-events/arch/x86/broadwellx/uncore-interconnect.json b/tools/perf/pmu-events/arch/x86/broadwellx/uncore-interconnect.json
new file mode 100644
index 000000000000..39387f7909b2
--- /dev/null
+++ b/tools/perf/pmu-events/arch/x86/broadwellx/uncore-interconnect.json
@@ -0,0 +1,28 @@
1[
2 {
3 "BriefDescription": "QPI clock ticks. Derived from unc_q_clockticks",
4 "Counter": "0,1,2,3",
5 "EventCode": "0x14",
6 "EventName": "UNC_Q_CLOCKTICKS",
7 "PerPkg": "1",
8 "Unit": "QPI LL"
9 },
10 {
11 "BriefDescription": "Number of data flits transmitted . Derived from unc_q_txl_flits_g0.data",
12 "Counter": "0,1,2,3",
13 "EventName": "UNC_Q_TxL_FLITS_G0.DATA",
14 "PerPkg": "1",
15 "ScaleUnit": "8Bytes",
16 "UMask": "0x2",
17 "Unit": "QPI LL"
18 },
19 {
20 "BriefDescription": "Number of non data (control) flits transmitted . Derived from unc_q_txl_flits_g0.non_data",
21 "Counter": "0,1,2,3",
22 "EventName": "UNC_Q_TxL_FLITS_G0.NON_DATA",
23 "PerPkg": "1",
24 "ScaleUnit": "8Bytes",
25 "UMask": "0x4",
26 "Unit": "QPI LL"
27 }
28]
diff --git a/tools/perf/pmu-events/arch/x86/broadwellx/uncore-memory.json b/tools/perf/pmu-events/arch/x86/broadwellx/uncore-memory.json
new file mode 100644
index 000000000000..d17dc235f734
--- /dev/null
+++ b/tools/perf/pmu-events/arch/x86/broadwellx/uncore-memory.json
@@ -0,0 +1,83 @@
1[
2 {
3 "BriefDescription": "read requests to memory controller. Derived from unc_m_cas_count.rd",
4 "Counter": "0,1,2,3",
5 "EventCode": "0x4",
6 "EventName": "UNC_M_CAS_COUNT.RD",
7 "PerPkg": "1",
8 "ScaleUnit": "64Bytes",
9 "UMask": "0x3",
10 "Unit": "iMC"
11 },
12 {
13 "BriefDescription": "write requests to memory controller. Derived from unc_m_cas_count.wr",
14 "Counter": "0,1,2,3",
15 "EventCode": "0x4",
16 "EventName": "UNC_M_CAS_COUNT.WR",
17 "PerPkg": "1",
18 "ScaleUnit": "64Bytes",
19 "UMask": "0xC",
20 "Unit": "iMC"
21 },
22 {
23 "BriefDescription": "Memory controller clock ticks. Derived from unc_m_clockticks",
24 "Counter": "0,1,2,3",
25 "EventName": "UNC_M_CLOCKTICKS",
26 "PerPkg": "1",
27 "Unit": "iMC"
28 },
29 {
30 "BriefDescription": "Cycles where DRAM ranks are in power down (CKE) mode. Derived from unc_m_power_channel_ppd",
31 "Counter": "0,1,2,3",
32 "EventCode": "0x85",
33 "EventName": "UNC_M_POWER_CHANNEL_PPD",
34 "MetricExpr": "(UNC_M_POWER_CHANNEL_PPD / UNC_M_CLOCKTICKS) * 100.",
35 "PerPkg": "1",
36 "Unit": "iMC"
37 },
38 {
39 "BriefDescription": "Cycles all ranks are in critical thermal throttle. Derived from unc_m_power_critical_throttle_cycles",
40 "Counter": "0,1,2,3",
41 "EventCode": "0x86",
42 "EventName": "UNC_M_POWER_CRITICAL_THROTTLE_CYCLES",
43 "MetricExpr": "(UNC_M_POWER_CRITICAL_THROTTLE_CYCLES / UNC_M_CLOCKTICKS) * 100.",
44 "PerPkg": "1",
45 "Unit": "iMC"
46 },
47 {
48 "BriefDescription": "Cycles Memory is in self refresh power mode. Derived from unc_m_power_self_refresh",
49 "Counter": "0,1,2,3",
50 "EventCode": "0x43",
51 "EventName": "UNC_M_POWER_SELF_REFRESH",
52 "MetricExpr": "(UNC_M_POWER_SELF_REFRESH / UNC_M_CLOCKTICKS) * 100.",
53 "PerPkg": "1",
54 "Unit": "iMC"
55 },
56 {
57 "BriefDescription": "Pre-charges due to page misses. Derived from unc_m_pre_count.page_miss",
58 "Counter": "0,1,2,3",
59 "EventCode": "0x2",
60 "EventName": "UNC_M_PRE_COUNT.PAGE_MISS",
61 "PerPkg": "1",
62 "UMask": "0x1",
63 "Unit": "iMC"
64 },
65 {
66 "BriefDescription": "Pre-charge for reads. Derived from unc_m_pre_count.rd",
67 "Counter": "0,1,2,3",
68 "EventCode": "0x2",
69 "EventName": "UNC_M_PRE_COUNT.RD",
70 "PerPkg": "1",
71 "UMask": "0x4",
72 "Unit": "iMC"
73 },
74 {
75 "BriefDescription": "Pre-charge for writes. Derived from unc_m_pre_count.wr",
76 "Counter": "0,1,2,3",
77 "EventCode": "0x2",
78 "EventName": "UNC_M_PRE_COUNT.WR",
79 "PerPkg": "1",
80 "UMask": "0x8",
81 "Unit": "iMC"
82 }
83]
diff --git a/tools/perf/pmu-events/arch/x86/broadwellx/uncore-power.json b/tools/perf/pmu-events/arch/x86/broadwellx/uncore-power.json
new file mode 100644
index 000000000000..b44d43088bbb
--- /dev/null
+++ b/tools/perf/pmu-events/arch/x86/broadwellx/uncore-power.json
@@ -0,0 +1,84 @@
1[
2 {
3 "BriefDescription": "PCU clock ticks. Use to get percentages of PCU cycles events. Derived from unc_p_clockticks",
4 "Counter": "0,1,2,3",
5 "EventName": "UNC_P_CLOCKTICKS",
6 "PerPkg": "1",
7 "Unit": "PCU"
8 },
9 {
10 "BriefDescription": "C0 and C1. Derived from unc_p_power_state_occupancy.cores_c0",
11 "Counter": "0,1,2,3",
12 "EventCode": "0x80",
13 "EventName": "UNC_P_POWER_STATE_OCCUPANCY.CORES_C0",
14 "Filter": "occ_sel=1",
15 "MetricExpr": "(UNC_P_POWER_STATE_OCCUPANCY.CORES_C0 / UNC_P_CLOCKTICKS) * 100.",
16 "PerPkg": "1",
17 "Unit": "PCU"
18 },
19 {
20 "BriefDescription": "C3. Derived from unc_p_power_state_occupancy.cores_c3",
21 "Counter": "0,1,2,3",
22 "EventCode": "0x80",
23 "EventName": "UNC_P_POWER_STATE_OCCUPANCY.CORES_C3",
24 "Filter": "occ_sel=2",
25 "MetricExpr": "(UNC_P_POWER_STATE_OCCUPANCY.CORES_C3 / UNC_P_CLOCKTICKS) * 100.",
26 "PerPkg": "1",
27 "Unit": "PCU"
28 },
29 {
30 "BriefDescription": "C6 and C7. Derived from unc_p_power_state_occupancy.cores_c6",
31 "Counter": "0,1,2,3",
32 "EventCode": "0x80",
33 "EventName": "UNC_P_POWER_STATE_OCCUPANCY.CORES_C6",
34 "Filter": "occ_sel=3",
35 "MetricExpr": "(UNC_P_POWER_STATE_OCCUPANCY.CORES_C6 / UNC_P_CLOCKTICKS) * 100.",
36 "PerPkg": "1",
37 "Unit": "PCU"
38 },
39 {
40 "BriefDescription": "External Prochot. Derived from unc_p_prochot_external_cycles",
41 "Counter": "0,1,2,3",
42 "EventCode": "0xA",
43 "EventName": "UNC_P_PROCHOT_EXTERNAL_CYCLES",
44 "MetricExpr": "(UNC_P_PROCHOT_EXTERNAL_CYCLES / UNC_P_CLOCKTICKS) * 100.",
45 "PerPkg": "1",
46 "Unit": "PCU"
47 },
48 {
49 "BriefDescription": "Thermal Strongest Upper Limit Cycles. Derived from unc_p_freq_max_limit_thermal_cycles",
50 "Counter": "0,1,2,3",
51 "EventCode": "0x4",
52 "EventName": "UNC_P_FREQ_MAX_LIMIT_THERMAL_CYCLES",
53 "MetricExpr": "(UNC_P_FREQ_MAX_LIMIT_THERMAL_CYCLES / UNC_P_CLOCKTICKS) * 100.",
54 "PerPkg": "1",
55 "Unit": "PCU"
56 },
57 {
58 "BriefDescription": "OS Strongest Upper Limit Cycles. Derived from unc_p_freq_max_os_cycles",
59 "Counter": "0,1,2,3",
60 "EventCode": "0x6",
61 "EventName": "UNC_P_FREQ_MAX_OS_CYCLES",
62 "MetricExpr": "(UNC_P_FREQ_MAX_OS_CYCLES / UNC_P_CLOCKTICKS) * 100.",
63 "PerPkg": "1",
64 "Unit": "PCU"
65 },
66 {
67 "BriefDescription": "Power Strongest Upper Limit Cycles. Derived from unc_p_freq_max_power_cycles",
68 "Counter": "0,1,2,3",
69 "EventCode": "0x5",
70 "EventName": "UNC_P_FREQ_MAX_POWER_CYCLES",
71 "MetricExpr": "(UNC_P_FREQ_MAX_POWER_CYCLES / UNC_P_CLOCKTICKS) * 100.",
72 "PerPkg": "1",
73 "Unit": "PCU"
74 },
75 {
76 "BriefDescription": "Cycles spent changing Frequency. Derived from unc_p_freq_trans_cycles",
77 "Counter": "0,1,2,3",
78 "EventCode": "0x74",
79 "EventName": "UNC_P_FREQ_TRANS_CYCLES",
80 "MetricExpr": "(UNC_P_FREQ_TRANS_CYCLES / UNC_P_CLOCKTICKS) * 100.",
81 "PerPkg": "1",
82 "Unit": "PCU"
83 }
84]
diff --git a/tools/perf/pmu-events/arch/x86/haswellx/uncore-cache.json b/tools/perf/pmu-events/arch/x86/haswellx/uncore-cache.json
new file mode 100644
index 000000000000..076459c51d4e
--- /dev/null
+++ b/tools/perf/pmu-events/arch/x86/haswellx/uncore-cache.json
@@ -0,0 +1,317 @@
1[
2 {
3 "BriefDescription": "Uncore cache clock ticks. Derived from unc_c_clockticks",
4 "Counter": "0,1,2,3",
5 "EventName": "UNC_C_CLOCKTICKS",
6 "PerPkg": "1",
7 "Unit": "CBO"
8 },
9 {
10 "BriefDescription": "All LLC Misses (code+ data rd + data wr - including demand and prefetch). Derived from unc_c_llc_lookup.any",
11 "Counter": "0,1,2,3",
12 "EventCode": "0x34",
13 "EventName": "UNC_C_LLC_LOOKUP.ANY",
14 "Filter": "filter_state=0x1",
15 "PerPkg": "1",
16 "ScaleUnit": "64Bytes",
17 "UMask": "0x11",
18 "Unit": "CBO"
19 },
20 {
21 "BriefDescription": "M line evictions from LLC (writebacks to memory). Derived from unc_c_llc_victims.m_state",
22 "Counter": "0,1,2,3",
23 "EventCode": "0x37",
24 "EventName": "UNC_C_LLC_VICTIMS.M_STATE",
25 "PerPkg": "1",
26 "ScaleUnit": "64Bytes",
27 "UMask": "0x1",
28 "Unit": "CBO"
29 },
30 {
31 "BriefDescription": "LLC misses - demand and prefetch data reads - excludes LLC prefetches. Derived from unc_c_tor_inserts.miss_opcode",
32 "Counter": "0,1,2,3",
33 "EventCode": "0x35",
34 "EventName": "LLC_MISSES.DATA_READ",
35 "Filter": "filter_opc=0x182",
36 "PerPkg": "1",
37 "ScaleUnit": "64Bytes",
38 "UMask": "0x3",
39 "Unit": "CBO"
40 },
41 {
42 "BriefDescription": "LLC misses - Uncacheable reads (from cpu) . Derived from unc_c_tor_inserts.miss_opcode",
43 "Counter": "0,1,2,3",
44 "EventCode": "0x35",
45 "EventName": "LLC_MISSES.UNCACHEABLE",
46 "Filter": "filter_opc=0x187",
47 "PerPkg": "1",
48 "ScaleUnit": "64Bytes",
49 "UMask": "0x3",
50 "Unit": "CBO"
51 },
52 {
53 "BriefDescription": "MMIO reads. Derived from unc_c_tor_inserts.miss_opcode",
54 "Counter": "0,1,2,3",
55 "EventCode": "0x35",
56 "EventName": "LLC_MISSES.MMIO_READ",
57 "Filter": "filter_opc=0x187,filter_nc=1",
58 "PerPkg": "1",
59 "ScaleUnit": "64Bytes",
60 "UMask": "0x3",
61 "Unit": "CBO"
62 },
63 {
64 "BriefDescription": "MMIO writes. Derived from unc_c_tor_inserts.miss_opcode",
65 "Counter": "0,1,2,3",
66 "EventCode": "0x35",
67 "EventName": "LLC_MISSES.MMIO_WRITE",
68 "Filter": "filter_opc=0x18f,filter_nc=1",
69 "PerPkg": "1",
70 "ScaleUnit": "64Bytes",
71 "UMask": "0x3",
72 "Unit": "CBO"
73 },
74 {
75 "BriefDescription": "LLC prefetch misses for RFO. Derived from unc_c_tor_inserts.miss_opcode",
76 "Counter": "0,1,2,3",
77 "EventCode": "0x35",
78 "EventName": "LLC_MISSES.RFO_LLC_PREFETCH",
79 "Filter": "filter_opc=0x190",
80 "PerPkg": "1",
81 "ScaleUnit": "64Bytes",
82 "UMask": "0x3",
83 "Unit": "CBO"
84 },
85 {
86 "BriefDescription": "LLC prefetch misses for code reads. Derived from unc_c_tor_inserts.miss_opcode",
87 "Counter": "0,1,2,3",
88 "EventCode": "0x35",
89 "EventName": "LLC_MISSES.CODE_LLC_PREFETCH",
90 "Filter": "filter_opc=0x191",
91 "PerPkg": "1",
92 "ScaleUnit": "64Bytes",
93 "UMask": "0x3",
94 "Unit": "CBO"
95 },
96 {
97 "BriefDescription": "LLC prefetch misses for data reads. Derived from unc_c_tor_inserts.miss_opcode",
98 "Counter": "0,1,2,3",
99 "EventCode": "0x35",
100 "EventName": "LLC_MISSES.DATA_LLC_PREFETCH",
101 "Filter": "filter_opc=0x192",
102 "PerPkg": "1",
103 "ScaleUnit": "64Bytes",
104 "UMask": "0x3",
105 "Unit": "CBO"
106 },
107 {
108 "BriefDescription": "LLC misses for PCIe read current. Derived from unc_c_tor_inserts.miss_opcode",
109 "Counter": "0,1,2,3",
110 "EventCode": "0x35",
111 "EventName": "LLC_MISSES.PCIE_READ",
112 "Filter": "filter_opc=0x19e",
113 "PerPkg": "1",
114 "ScaleUnit": "64Bytes",
115 "UMask": "0x3",
116 "Unit": "CBO"
117 },
118 {
119 "BriefDescription": "ItoM write misses (as part of fast string memcpy stores) + PCIe full line writes. Derived from unc_c_tor_inserts.miss_opcode",
120 "Counter": "0,1,2,3",
121 "EventCode": "0x35",
122 "EventName": "LLC_MISSES.PCIE_WRITE",
123 "Filter": "filter_opc=0x1c8",
124 "PerPkg": "1",
125 "ScaleUnit": "64Bytes",
126 "UMask": "0x3",
127 "Unit": "CBO"
128 },
129 {
130 "BriefDescription": "PCIe write misses (full cache line). Derived from unc_c_tor_inserts.miss_opcode",
131 "Counter": "0,1,2,3",
132 "EventCode": "0x35",
133 "EventName": "LLC_MISSES.PCIE_NON_SNOOP_WRITE",
134 "Filter": "filter_opc=0x1c8,filter_tid=0x3e",
135 "PerPkg": "1",
136 "ScaleUnit": "64Bytes",
137 "UMask": "0x3",
138 "Unit": "CBO"
139 },
140 {
141 "BriefDescription": "PCIe writes (partial cache line). Derived from unc_c_tor_inserts.opcode",
142 "Counter": "0,1,2,3",
143 "EventCode": "0x35",
144 "EventName": "LLC_REFERENCES.PCIE_NS_PARTIAL_WRITE",
145 "Filter": "filter_opc=0x180,filter_tid=0x3e",
146 "PerPkg": "1",
147 "UMask": "0x1",
148 "Unit": "CBO"
149 },
150 {
151 "BriefDescription": "L2 demand and L2 prefetch code references to LLC. Derived from unc_c_tor_inserts.opcode",
152 "Counter": "0,1,2,3",
153 "EventCode": "0x35",
154 "EventName": "LLC_REFERENCES.CODE_LLC_PREFETCH",
155 "Filter": "filter_opc=0x181",
156 "PerPkg": "1",
157 "ScaleUnit": "64Bytes",
158 "UMask": "0x1",
159 "Unit": "CBO"
160 },
161 {
162 "BriefDescription": "Streaming stores (full cache line). Derived from unc_c_tor_inserts.opcode",
163 "Counter": "0,1,2,3",
164 "EventCode": "0x35",
165 "EventName": "LLC_REFERENCES.STREAMING_FULL",
166 "Filter": "filter_opc=0x18c",
167 "PerPkg": "1",
168 "ScaleUnit": "64Bytes",
169 "UMask": "0x1",
170 "Unit": "CBO"
171 },
172 {
173 "BriefDescription": "Streaming stores (partial cache line). Derived from unc_c_tor_inserts.opcode",
174 "Counter": "0,1,2,3",
175 "EventCode": "0x35",
176 "EventName": "LLC_REFERENCES.STREAMING_PARTIAL",
177 "Filter": "filter_opc=0x18d",
178 "PerPkg": "1",
179 "ScaleUnit": "64Bytes",
180 "UMask": "0x1",
181 "Unit": "CBO"
182 },
183 {
184 "BriefDescription": "PCIe read current. Derived from unc_c_tor_inserts.opcode",
185 "Counter": "0,1,2,3",
186 "EventCode": "0x35",
187 "EventName": "LLC_REFERENCES.PCIE_READ",
188 "Filter": "filter_opc=0x19e",
189 "PerPkg": "1",
190 "ScaleUnit": "64Bytes",
191 "UMask": "0x1",
192 "Unit": "CBO"
193 },
194 {
195 "BriefDescription": "PCIe write references (full cache line). Derived from unc_c_tor_inserts.opcode",
196 "Counter": "0,1,2,3",
197 "EventCode": "0x35",
198 "EventName": "LLC_REFERENCES.PCIE_WRITE",
199 "Filter": "filter_opc=0x1c8,filter_tid=0x3e",
200 "PerPkg": "1",
201 "ScaleUnit": "64Bytes",
202 "UMask": "0x1",
203 "Unit": "CBO"
204 },
205 {
206 "BriefDescription": "Occupancy counter for LLC data reads (demand and L2 prefetch). Derived from unc_c_tor_occupancy.miss_opcode",
207 "EventCode": "0x36",
208 "EventName": "UNC_C_TOR_OCCUPANCY.LLC_DATA_READ",
209 "Filter": "filter_opc=0x182",
210 "PerPkg": "1",
211 "UMask": "0x3",
212 "Unit": "CBO"
213 },
214 {
215 "BriefDescription": "read requests to home agent. Derived from unc_h_requests.reads",
216 "Counter": "0,1,2,3",
217 "EventCode": "0x1",
218 "EventName": "UNC_H_REQUESTS.READS",
219 "PerPkg": "1",
220 "UMask": "0x3",
221 "Unit": "HA"
222 },
223 {
224 "BriefDescription": "read requests to local home agent. Derived from unc_h_requests.reads_local",
225 "Counter": "0,1,2,3",
226 "EventCode": "0x1",
227 "EventName": "UNC_H_REQUESTS.READS_LOCAL",
228 "PerPkg": "1",
229 "UMask": "0x1",
230 "Unit": "HA"
231 },
232 {
233 "BriefDescription": "read requests to remote home agent. Derived from unc_h_requests.reads_remote",
234 "Counter": "0,1,2,3",
235 "EventCode": "0x1",
236 "EventName": "UNC_H_REQUESTS.READS_REMOTE",
237 "PerPkg": "1",
238 "UMask": "0x2",
239 "Unit": "HA"
240 },
241 {
242 "BriefDescription": "write requests to home agent. Derived from unc_h_requests.writes",
243 "Counter": "0,1,2,3",
244 "EventCode": "0x1",
245 "EventName": "UNC_H_REQUESTS.WRITES",
246 "PerPkg": "1",
247 "UMask": "0xC",
248 "Unit": "HA"
249 },
250 {
251 "BriefDescription": "write requests to local home agent. Derived from unc_h_requests.writes_local",
252 "Counter": "0,1,2,3",
253 "EventCode": "0x1",
254 "EventName": "UNC_H_REQUESTS.WRITES_LOCAL",
255 "PerPkg": "1",
256 "UMask": "0x4",
257 "Unit": "HA"
258 },
259 {
260 "BriefDescription": "write requests to remote home agent. Derived from unc_h_requests.writes_remote",
261 "Counter": "0,1,2,3",
262 "EventCode": "0x1",
263 "EventName": "UNC_H_REQUESTS.WRITES_REMOTE",
264 "PerPkg": "1",
265 "UMask": "0x8",
266 "Unit": "HA"
267 },
268 {
269 "BriefDescription": "Conflict requests (requests for same address from multiple agents simultaneously). Derived from unc_h_snoop_resp.rspcnflct",
270 "Counter": "0,1,2,3",
271 "EventCode": "0x21",
272 "EventName": "UNC_H_SNOOP_RESP.RSPCNFLCT",
273 "PerPkg": "1",
274 "UMask": "0x40",
275 "Unit": "HA"
276 },
277 {
278 "BriefDescription": "M line forwarded from remote cache along with writeback to memory. Derived from unc_h_snoop_resp.rsp_fwd_wb",
279 "Counter": "0,1,2,3",
280 "EventCode": "0x21",
281 "EventName": "UNC_H_SNOOP_RESP.RSP_FWD_WB",
282 "PerPkg": "1",
283 "ScaleUnit": "64Bytes",
284 "UMask": "0x20",
285 "Unit": "HA"
286 },
287 {
288 "BriefDescription": "M line forwarded from remote cache with no writeback to memory. Derived from unc_h_snoop_resp.rspifwd",
289 "Counter": "0,1,2,3",
290 "EventCode": "0x21",
291 "EventName": "UNC_H_SNOOP_RESP.RSPIFWD",
292 "PerPkg": "1",
293 "ScaleUnit": "64Bytes",
294 "UMask": "0x4",
295 "Unit": "HA"
296 },
297 {
298 "BriefDescription": "Shared line response from remote cache. Derived from unc_h_snoop_resp.rsps",
299 "Counter": "0,1,2,3",
300 "EventCode": "0x21",
301 "EventName": "UNC_H_SNOOP_RESP.RSPS",
302 "PerPkg": "1",
303 "ScaleUnit": "64Bytes",
304 "UMask": "0x2",
305 "Unit": "HA"
306 },
307 {
308 "BriefDescription": "Shared line forwarded from remote cache. Derived from unc_h_snoop_resp.rspsfwd",
309 "Counter": "0,1,2,3",
310 "EventCode": "0x21",
311 "EventName": "UNC_H_SNOOP_RESP.RSPSFWD",
312 "PerPkg": "1",
313 "ScaleUnit": "64Bytes",
314 "UMask": "0x8",
315 "Unit": "HA"
316 }
317]
diff --git a/tools/perf/pmu-events/arch/x86/haswellx/uncore-interconnect.json b/tools/perf/pmu-events/arch/x86/haswellx/uncore-interconnect.json
new file mode 100644
index 000000000000..39387f7909b2
--- /dev/null
+++ b/tools/perf/pmu-events/arch/x86/haswellx/uncore-interconnect.json
@@ -0,0 +1,28 @@
1[
2 {
3 "BriefDescription": "QPI clock ticks. Derived from unc_q_clockticks",
4 "Counter": "0,1,2,3",
5 "EventCode": "0x14",
6 "EventName": "UNC_Q_CLOCKTICKS",
7 "PerPkg": "1",
8 "Unit": "QPI LL"
9 },
10 {
11 "BriefDescription": "Number of data flits transmitted . Derived from unc_q_txl_flits_g0.data",
12 "Counter": "0,1,2,3",
13 "EventName": "UNC_Q_TxL_FLITS_G0.DATA",
14 "PerPkg": "1",
15 "ScaleUnit": "8Bytes",
16 "UMask": "0x2",
17 "Unit": "QPI LL"
18 },
19 {
20 "BriefDescription": "Number of non data (control) flits transmitted . Derived from unc_q_txl_flits_g0.non_data",
21 "Counter": "0,1,2,3",
22 "EventName": "UNC_Q_TxL_FLITS_G0.NON_DATA",
23 "PerPkg": "1",
24 "ScaleUnit": "8Bytes",
25 "UMask": "0x4",
26 "Unit": "QPI LL"
27 }
28]
diff --git a/tools/perf/pmu-events/arch/x86/haswellx/uncore-memory.json b/tools/perf/pmu-events/arch/x86/haswellx/uncore-memory.json
new file mode 100644
index 000000000000..d17dc235f734
--- /dev/null
+++ b/tools/perf/pmu-events/arch/x86/haswellx/uncore-memory.json
@@ -0,0 +1,83 @@
1[
2 {
3 "BriefDescription": "read requests to memory controller. Derived from unc_m_cas_count.rd",
4 "Counter": "0,1,2,3",
5 "EventCode": "0x4",
6 "EventName": "UNC_M_CAS_COUNT.RD",
7 "PerPkg": "1",
8 "ScaleUnit": "64Bytes",
9 "UMask": "0x3",
10 "Unit": "iMC"
11 },
12 {
13 "BriefDescription": "write requests to memory controller. Derived from unc_m_cas_count.wr",
14 "Counter": "0,1,2,3",
15 "EventCode": "0x4",
16 "EventName": "UNC_M_CAS_COUNT.WR",
17 "PerPkg": "1",
18 "ScaleUnit": "64Bytes",
19 "UMask": "0xC",
20 "Unit": "iMC"
21 },
22 {
23 "BriefDescription": "Memory controller clock ticks. Derived from unc_m_clockticks",
24 "Counter": "0,1,2,3",
25 "EventName": "UNC_M_CLOCKTICKS",
26 "PerPkg": "1",
27 "Unit": "iMC"
28 },
29 {
30 "BriefDescription": "Cycles where DRAM ranks are in power down (CKE) mode. Derived from unc_m_power_channel_ppd",
31 "Counter": "0,1,2,3",
32 "EventCode": "0x85",
33 "EventName": "UNC_M_POWER_CHANNEL_PPD",
34 "MetricExpr": "(UNC_M_POWER_CHANNEL_PPD / UNC_M_CLOCKTICKS) * 100.",
35 "PerPkg": "1",
36 "Unit": "iMC"
37 },
38 {
39 "BriefDescription": "Cycles all ranks are in critical thermal throttle. Derived from unc_m_power_critical_throttle_cycles",
40 "Counter": "0,1,2,3",
41 "EventCode": "0x86",
42 "EventName": "UNC_M_POWER_CRITICAL_THROTTLE_CYCLES",
43 "MetricExpr": "(UNC_M_POWER_CRITICAL_THROTTLE_CYCLES / UNC_M_CLOCKTICKS) * 100.",
44 "PerPkg": "1",
45 "Unit": "iMC"
46 },
47 {
48 "BriefDescription": "Cycles Memory is in self refresh power mode. Derived from unc_m_power_self_refresh",
49 "Counter": "0,1,2,3",
50 "EventCode": "0x43",
51 "EventName": "UNC_M_POWER_SELF_REFRESH",
52 "MetricExpr": "(UNC_M_POWER_SELF_REFRESH / UNC_M_CLOCKTICKS) * 100.",
53 "PerPkg": "1",
54 "Unit": "iMC"
55 },
56 {
57 "BriefDescription": "Pre-charges due to page misses. Derived from unc_m_pre_count.page_miss",
58 "Counter": "0,1,2,3",
59 "EventCode": "0x2",
60 "EventName": "UNC_M_PRE_COUNT.PAGE_MISS",
61 "PerPkg": "1",
62 "UMask": "0x1",
63 "Unit": "iMC"
64 },
65 {
66 "BriefDescription": "Pre-charge for reads. Derived from unc_m_pre_count.rd",
67 "Counter": "0,1,2,3",
68 "EventCode": "0x2",
69 "EventName": "UNC_M_PRE_COUNT.RD",
70 "PerPkg": "1",
71 "UMask": "0x4",
72 "Unit": "iMC"
73 },
74 {
75 "BriefDescription": "Pre-charge for writes. Derived from unc_m_pre_count.wr",
76 "Counter": "0,1,2,3",
77 "EventCode": "0x2",
78 "EventName": "UNC_M_PRE_COUNT.WR",
79 "PerPkg": "1",
80 "UMask": "0x8",
81 "Unit": "iMC"
82 }
83]
diff --git a/tools/perf/pmu-events/arch/x86/haswellx/uncore-power.json b/tools/perf/pmu-events/arch/x86/haswellx/uncore-power.json
new file mode 100644
index 000000000000..b44d43088bbb
--- /dev/null
+++ b/tools/perf/pmu-events/arch/x86/haswellx/uncore-power.json
@@ -0,0 +1,84 @@
1[
2 {
3 "BriefDescription": "PCU clock ticks. Use to get percentages of PCU cycles events. Derived from unc_p_clockticks",
4 "Counter": "0,1,2,3",
5 "EventName": "UNC_P_CLOCKTICKS",
6 "PerPkg": "1",
7 "Unit": "PCU"
8 },
9 {
10 "BriefDescription": "C0 and C1. Derived from unc_p_power_state_occupancy.cores_c0",
11 "Counter": "0,1,2,3",
12 "EventCode": "0x80",
13 "EventName": "UNC_P_POWER_STATE_OCCUPANCY.CORES_C0",
14 "Filter": "occ_sel=1",
15 "MetricExpr": "(UNC_P_POWER_STATE_OCCUPANCY.CORES_C0 / UNC_P_CLOCKTICKS) * 100.",
16 "PerPkg": "1",
17 "Unit": "PCU"
18 },
19 {
20 "BriefDescription": "C3. Derived from unc_p_power_state_occupancy.cores_c3",
21 "Counter": "0,1,2,3",
22 "EventCode": "0x80",
23 "EventName": "UNC_P_POWER_STATE_OCCUPANCY.CORES_C3",
24 "Filter": "occ_sel=2",
25 "MetricExpr": "(UNC_P_POWER_STATE_OCCUPANCY.CORES_C3 / UNC_P_CLOCKTICKS) * 100.",
26 "PerPkg": "1",
27 "Unit": "PCU"
28 },
29 {
30 "BriefDescription": "C6 and C7. Derived from unc_p_power_state_occupancy.cores_c6",
31 "Counter": "0,1,2,3",
32 "EventCode": "0x80",
33 "EventName": "UNC_P_POWER_STATE_OCCUPANCY.CORES_C6",
34 "Filter": "occ_sel=3",
35 "MetricExpr": "(UNC_P_POWER_STATE_OCCUPANCY.CORES_C6 / UNC_P_CLOCKTICKS) * 100.",
36 "PerPkg": "1",
37 "Unit": "PCU"
38 },
39 {
40 "BriefDescription": "External Prochot. Derived from unc_p_prochot_external_cycles",
41 "Counter": "0,1,2,3",
42 "EventCode": "0xA",
43 "EventName": "UNC_P_PROCHOT_EXTERNAL_CYCLES",
44 "MetricExpr": "(UNC_P_PROCHOT_EXTERNAL_CYCLES / UNC_P_CLOCKTICKS) * 100.",
45 "PerPkg": "1",
46 "Unit": "PCU"
47 },
48 {
49 "BriefDescription": "Thermal Strongest Upper Limit Cycles. Derived from unc_p_freq_max_limit_thermal_cycles",
50 "Counter": "0,1,2,3",
51 "EventCode": "0x4",
52 "EventName": "UNC_P_FREQ_MAX_LIMIT_THERMAL_CYCLES",
53 "MetricExpr": "(UNC_P_FREQ_MAX_LIMIT_THERMAL_CYCLES / UNC_P_CLOCKTICKS) * 100.",
54 "PerPkg": "1",
55 "Unit": "PCU"
56 },
57 {
58 "BriefDescription": "OS Strongest Upper Limit Cycles. Derived from unc_p_freq_max_os_cycles",
59 "Counter": "0,1,2,3",
60 "EventCode": "0x6",
61 "EventName": "UNC_P_FREQ_MAX_OS_CYCLES",
62 "MetricExpr": "(UNC_P_FREQ_MAX_OS_CYCLES / UNC_P_CLOCKTICKS) * 100.",
63 "PerPkg": "1",
64 "Unit": "PCU"
65 },
66 {
67 "BriefDescription": "Power Strongest Upper Limit Cycles. Derived from unc_p_freq_max_power_cycles",
68 "Counter": "0,1,2,3",
69 "EventCode": "0x5",
70 "EventName": "UNC_P_FREQ_MAX_POWER_CYCLES",
71 "MetricExpr": "(UNC_P_FREQ_MAX_POWER_CYCLES / UNC_P_CLOCKTICKS) * 100.",
72 "PerPkg": "1",
73 "Unit": "PCU"
74 },
75 {
76 "BriefDescription": "Cycles spent changing Frequency. Derived from unc_p_freq_trans_cycles",
77 "Counter": "0,1,2,3",
78 "EventCode": "0x74",
79 "EventName": "UNC_P_FREQ_TRANS_CYCLES",
80 "MetricExpr": "(UNC_P_FREQ_TRANS_CYCLES / UNC_P_CLOCKTICKS) * 100.",
81 "PerPkg": "1",
82 "Unit": "PCU"
83 }
84]
diff --git a/tools/perf/pmu-events/arch/x86/ivytown/uncore-cache.json b/tools/perf/pmu-events/arch/x86/ivytown/uncore-cache.json
new file mode 100644
index 000000000000..2efdc6772e0b
--- /dev/null
+++ b/tools/perf/pmu-events/arch/x86/ivytown/uncore-cache.json
@@ -0,0 +1,322 @@
1[
2 {
3 "BriefDescription": "Uncore cache clock ticks. Derived from unc_c_clockticks",
4 "Counter": "0,1,2,3",
5 "EventName": "UNC_C_CLOCKTICKS",
6 "PerPkg": "1",
7 "Unit": "CBO"
8 },
9 {
10 "BriefDescription": "All LLC Misses (code+ data rd + data wr - including demand and prefetch). Derived from unc_c_llc_lookup.any",
11 "Counter": "0,1",
12 "EventCode": "0x34",
13 "EventName": "UNC_C_LLC_LOOKUP.ANY",
14 "Filter": "filter_state=0x1",
15 "PerPkg": "1",
16 "ScaleUnit": "64Bytes",
17 "UMask": "0x11",
18 "Unit": "CBO"
19 },
20 {
21 "BriefDescription": "M line evictions from LLC (writebacks to memory). Derived from unc_c_llc_victims.m_state",
22 "Counter": "0,1",
23 "EventCode": "0x37",
24 "EventName": "UNC_C_LLC_VICTIMS.M_STATE",
25 "PerPkg": "1",
26 "ScaleUnit": "64Bytes",
27 "UMask": "0x1",
28 "Unit": "CBO"
29 },
30 {
31 "BriefDescription": "LLC misses - demand and prefetch data reads - excludes LLC prefetches. Derived from unc_c_tor_inserts.miss_opcode.demand",
32 "Counter": "0,1",
33 "EventCode": "0x35",
34 "EventName": "LLC_MISSES.DATA_READ",
35 "Filter": "filter_opc=0x182",
36 "PerPkg": "1",
37 "ScaleUnit": "64Bytes",
38 "UMask": "0x3",
39 "Unit": "CBO"
40 },
41 {
42 "BriefDescription": "LLC misses - Uncacheable reads. Derived from unc_c_tor_inserts.miss_opcode.uncacheable",
43 "Counter": "0,1",
44 "EventCode": "0x35",
45 "EventName": "LLC_MISSES.UNCACHEABLE",
46 "Filter": "filter_opc=0x187",
47 "PerPkg": "1",
48 "ScaleUnit": "64Bytes",
49 "UMask": "0x3",
50 "Unit": "CBO"
51 },
52 {
53 "BriefDescription": "LLC prefetch misses for RFO. Derived from unc_c_tor_inserts.miss_opcode.rfo_prefetch",
54 "Counter": "0,1",
55 "EventCode": "0x35",
56 "EventName": "LLC_MISSES.RFO_LLC_PREFETCH",
57 "Filter": "filter_opc=0x190",
58 "PerPkg": "1",
59 "ScaleUnit": "64Bytes",
60 "UMask": "0x3",
61 "Unit": "CBO"
62 },
63 {
64 "BriefDescription": "LLC prefetch misses for code reads. Derived from unc_c_tor_inserts.miss_opcode.code",
65 "Counter": "0,1",
66 "EventCode": "0x35",
67 "EventName": "LLC_MISSES.CODE_LLC_PREFETCH",
68 "Filter": "filter_opc=0x191",
69 "PerPkg": "1",
70 "ScaleUnit": "64Bytes",
71 "UMask": "0x3",
72 "Unit": "CBO"
73 },
74 {
75 "BriefDescription": "LLC prefetch misses for data reads. Derived from unc_c_tor_inserts.miss_opcode.data_read",
76 "Counter": "0,1",
77 "EventCode": "0x35",
78 "EventName": "LLC_MISSES.DATA_LLC_PREFETCH",
79 "Filter": "filter_opc=0x192",
80 "PerPkg": "1",
81 "ScaleUnit": "64Bytes",
82 "UMask": "0x3",
83 "Unit": "CBO"
84 },
85 {
86 "BriefDescription": "PCIe allocating writes that miss LLC - DDIO misses. Derived from unc_c_tor_inserts.miss_opcode.ddio_miss",
87 "Counter": "0,1",
88 "EventCode": "0x35",
89 "EventName": "LLC_MISSES.PCIE_WRITE",
90 "Filter": "filter_opc=0x19c",
91 "PerPkg": "1",
92 "ScaleUnit": "64Bytes",
93 "UMask": "0x3",
94 "Unit": "CBO"
95 },
96 {
97 "BriefDescription": "LLC misses for PCIe read current. Derived from unc_c_tor_inserts.miss_opcode.pcie_read",
98 "Counter": "0,1",
99 "EventCode": "0x35",
100 "EventName": "LLC_MISSES.PCIE_READ",
101 "Filter": "filter_opc=0x19e",
102 "PerPkg": "1",
103 "ScaleUnit": "64Bytes",
104 "UMask": "0x3",
105 "Unit": "CBO"
106 },
107 {
108 "BriefDescription": "LLC misses for ItoM writes (as part of fast string memcpy stores). Derived from unc_c_tor_inserts.miss_opcode.itom_write",
109 "Counter": "0,1",
110 "EventCode": "0x35",
111 "EventName": "LLC_MISSES.ITOM_WRITE",
112 "Filter": "filter_opc=0x1c8",
113 "PerPkg": "1",
114 "ScaleUnit": "64Bytes",
115 "UMask": "0x3",
116 "Unit": "CBO"
117 },
118 {
119 "BriefDescription": "LLC misses for PCIe non-snoop reads. Derived from unc_c_tor_inserts.miss_opcode.pcie_read",
120 "Counter": "0,1",
121 "EventCode": "0x35",
122 "EventName": "LLC_MISSES.PCIE_NON_SNOOP_READ",
123 "Filter": "filter_opc=0x1e4",
124 "PerPkg": "1",
125 "ScaleUnit": "64Bytes",
126 "UMask": "0x3",
127 "Unit": "CBO"
128 },
129 {
130 "BriefDescription": "LLC misses for PCIe non-snoop writes (full line). Derived from unc_c_tor_inserts.miss_opcode.pcie_write",
131 "Counter": "0,1",
132 "EventCode": "0x35",
133 "EventName": "LLC_MISSES.PCIE_NON_SNOOP_WRITE",
134 "Filter": "filter_opc=0x1e6",
135 "PerPkg": "1",
136 "ScaleUnit": "64Bytes",
137 "UMask": "0x3",
138 "Unit": "CBO"
139 },
140 {
141 "BriefDescription": "Streaming stores (full cache line). Derived from unc_c_tor_inserts.opcode.streaming_full",
142 "Counter": "0,1",
143 "EventCode": "0x35",
144 "EventName": "LLC_REFERENCES.STREAMING_FULL",
145 "Filter": "filter_opc=0x18c",
146 "PerPkg": "1",
147 "ScaleUnit": "64Bytes",
148 "UMask": "0x1",
149 "Unit": "CBO"
150 },
151 {
152 "BriefDescription": "Streaming stores (partial cache line). Derived from unc_c_tor_inserts.opcode.streaming_partial",
153 "Counter": "0,1",
154 "EventCode": "0x35",
155 "EventName": "LLC_REFERENCES.STREAMING_PARTIAL",
156 "Filter": "filter_opc=0x18d",
157 "PerPkg": "1",
158 "ScaleUnit": "64Bytes",
159 "UMask": "0x1",
160 "Unit": "CBO"
161 },
162 {
163 "BriefDescription": "Partial PCIe reads. Derived from unc_c_tor_inserts.opcode.pcie_partial",
164 "Counter": "0,1",
165 "EventCode": "0x35",
166 "EventName": "LLC_REFERENCES.PCIE_PARTIAL_READ",
167 "Filter": "filter_opc=0x195",
168 "PerPkg": "1",
169 "ScaleUnit": "64Bytes",
170 "UMask": "0x1",
171 "Unit": "CBO"
172 },
173 {
174 "BriefDescription": "PCIe allocating writes that hit in LLC (DDIO hits). Derived from unc_c_tor_inserts.opcode.ddio_hit",
175 "Counter": "0,1",
176 "EventCode": "0x35",
177 "EventName": "LLC_REFERENCES.PCIE_WRITE",
178 "Filter": "filter_opc=0x19c",
179 "PerPkg": "1",
180 "ScaleUnit": "64Bytes",
181 "UMask": "0x1",
182 "Unit": "CBO"
183 },
184 {
185 "BriefDescription": "PCIe read current. Derived from unc_c_tor_inserts.opcode.pcie_read_current",
186 "Counter": "0,1",
187 "EventCode": "0x35",
188 "EventName": "LLC_REFERENCES.PCIE_READ",
189 "Filter": "filter_opc=0x19e",
190 "PerPkg": "1",
191 "ScaleUnit": "64Bytes",
192 "UMask": "0x1",
193 "Unit": "CBO"
194 },
195 {
196 "BriefDescription": "ItoM write hits (as part of fast string memcpy stores). Derived from unc_c_tor_inserts.opcode.itom_write_hit",
197 "Counter": "0,1",
198 "EventCode": "0x35",
199 "EventName": "LLC_REFERENCES.ITOM_WRITE",
200 "Filter": "filter_opc=0x1c8",
201 "PerPkg": "1",
202 "ScaleUnit": "64Bytes",
203 "UMask": "0x1",
204 "Unit": "CBO"
205 },
206 {
207 "BriefDescription": "PCIe non-snoop reads. Derived from unc_c_tor_inserts.opcode.pcie_read",
208 "Counter": "0,1",
209 "EventCode": "0x35",
210 "EventName": "LLC_REFERENCES.PCIE_NS_READ",
211 "Filter": "filter_opc=0x1e4",
212 "PerPkg": "1",
213 "ScaleUnit": "64Bytes",
214 "UMask": "0x1",
215 "Unit": "CBO"
216 },
217 {
218 "BriefDescription": "PCIe non-snoop writes (partial). Derived from unc_c_tor_inserts.opcode.pcie_partial_write",
219 "Counter": "0,1",
220 "EventCode": "0x35",
221 "EventName": "LLC_REFERENCES.PCIE_NS_PARTIAL_WRITE",
222 "Filter": "filter_opc=0x1e5",
223 "PerPkg": "1",
224 "ScaleUnit": "64Bytes",
225 "UMask": "0x1",
226 "Unit": "CBO"
227 },
228 {
229 "BriefDescription": "PCIe non-snoop writes (full line). Derived from unc_c_tor_inserts.opcode.pcie_full_write",
230 "Counter": "0,1",
231 "EventCode": "0x35",
232 "EventName": "LLC_REFERENCES.PCIE_NS_WRITE",
233 "Filter": "filter_opc=0x1e6",
234 "PerPkg": "1",
235 "ScaleUnit": "64Bytes",
236 "UMask": "0x1",
237 "Unit": "CBO"
238 },
239 {
240 "BriefDescription": "Occupancy for all LLC misses that are addressed to local memory. Derived from unc_c_tor_occupancy.miss_local",
241 "EventCode": "0x36",
242 "EventName": "UNC_C_TOR_OCCUPANCY.MISS_LOCAL",
243 "PerPkg": "1",
244 "UMask": "0x2A",
245 "Unit": "CBO"
246 },
247 {
248 "BriefDescription": "Occupancy counter for LLC data reads (demand and L2 prefetch). Derived from unc_c_tor_occupancy.miss_opcode.llc_data_read",
249 "EventCode": "0x36",
250 "EventName": "UNC_C_TOR_OCCUPANCY.LLC_DATA_READ",
251 "Filter": "filter_opc=0x182",
252 "PerPkg": "1",
253 "UMask": "0x3",
254 "Unit": "CBO"
255 },
256 {
257 "BriefDescription": "Occupancy for all LLC misses that are addressed to remote memory. Derived from unc_c_tor_occupancy.miss_remote",
258 "EventCode": "0x36",
259 "EventName": "UNC_C_TOR_OCCUPANCY.MISS_REMOTE",
260 "PerPkg": "1",
261 "UMask": "0x8A",
262 "Unit": "CBO"
263 },
264 {
265 "BriefDescription": "Read requests to home agent. Derived from unc_h_requests.reads",
266 "Counter": "0,1,2,3",
267 "EventCode": "0x1",
268 "EventName": "UNC_H_REQUESTS.READS",
269 "PerPkg": "1",
270 "UMask": "0x3",
271 "Unit": "HA"
272 },
273 {
274 "BriefDescription": "Write requests to home agent. Derived from unc_h_requests.writes",
275 "Counter": "0,1,2,3",
276 "EventCode": "0x1",
277 "EventName": "UNC_H_REQUESTS.WRITES",
278 "PerPkg": "1",
279 "UMask": "0xC",
280 "Unit": "HA"
281 },
282 {
283 "BriefDescription": "M line forwarded from remote cache along with writeback to memory. Derived from unc_h_snoop_resp.rsp_fwd_wb",
284 "Counter": "0,1,2,3",
285 "EventCode": "0x21",
286 "EventName": "UNC_H_SNOOP_RESP.RSP_FWD_WB",
287 "PerPkg": "1",
288 "ScaleUnit": "64Bytes",
289 "UMask": "0x20",
290 "Unit": "HA"
291 },
292 {
293 "BriefDescription": "M line forwarded from remote cache with no writeback to memory. Derived from unc_h_snoop_resp.rspifwd",
294 "Counter": "0,1,2,3",
295 "EventCode": "0x21",
296 "EventName": "UNC_H_SNOOP_RESP.RSPIFWD",
297 "PerPkg": "1",
298 "ScaleUnit": "64Bytes",
299 "UMask": "0x4",
300 "Unit": "HA"
301 },
302 {
303 "BriefDescription": "Shared line response from remote cache. Derived from unc_h_snoop_resp.rsps",
304 "Counter": "0,1,2,3",
305 "EventCode": "0x21",
306 "EventName": "UNC_H_SNOOP_RESP.RSPS",
307 "PerPkg": "1",
308 "ScaleUnit": "64Bytes",
309 "UMask": "0x2",
310 "Unit": "HA"
311 },
312 {
313 "BriefDescription": "Shared line forwarded from remote cache. Derived from unc_h_snoop_resp.rspsfwd",
314 "Counter": "0,1,2,3",
315 "EventCode": "0x21",
316 "EventName": "UNC_H_SNOOP_RESP.RSPSFWD",
317 "PerPkg": "1",
318 "ScaleUnit": "64Bytes",
319 "UMask": "0x8",
320 "Unit": "HA"
321 }
322]
diff --git a/tools/perf/pmu-events/arch/x86/ivytown/uncore-interconnect.json b/tools/perf/pmu-events/arch/x86/ivytown/uncore-interconnect.json
new file mode 100644
index 000000000000..d7e2fda1d695
--- /dev/null
+++ b/tools/perf/pmu-events/arch/x86/ivytown/uncore-interconnect.json
@@ -0,0 +1,46 @@
1[
2 {
3 "BriefDescription": "QPI clock ticks. Use to get percentages for QPI cycles events. Derived from unc_q_clockticks",
4 "Counter": "0,1,2,3",
5 "EventCode": "0x14",
6 "EventName": "UNC_Q_CLOCKTICKS",
7 "PerPkg": "1",
8 "Unit": "QPI LL"
9 },
10 {
11 "BriefDescription": "Cycles where receiving QPI link is in half-width mode. Derived from unc_q_rxl0p_power_cycles",
12 "Counter": "0,1,2,3",
13 "EventCode": "0x10",
14 "EventName": "UNC_Q_RxL0P_POWER_CYCLES",
15 "MetricExpr": "(UNC_Q_RxL0P_POWER_CYCLES / UNC_Q_CLOCKTICKS) * 100.",
16 "PerPkg": "1",
17 "Unit": "QPI LL"
18 },
19 {
20 "BriefDescription": "Cycles where transmitting QPI link is in half-width mode. Derived from unc_q_txl0p_power_cycles",
21 "Counter": "0,1,2,3",
22 "EventCode": "0xd",
23 "EventName": "UNC_Q_TxL0P_POWER_CYCLES",
24 "MetricExpr": "(UNC_Q_TxL0P_POWER_CYCLES / UNC_Q_CLOCKTICKS) * 100.",
25 "PerPkg": "1",
26 "Unit": "QPI LL"
27 },
28 {
29 "BriefDescription": "Number of data flits transmitted . Derived from unc_q_txl_flits_g0.data",
30 "Counter": "0,1,2,3",
31 "EventName": "UNC_Q_TxL_FLITS_G0.DATA",
32 "PerPkg": "1",
33 "ScaleUnit": "8Bytes",
34 "UMask": "0x2",
35 "Unit": "QPI LL"
36 },
37 {
38 "BriefDescription": "Number of non data (control) flits transmitted . Derived from unc_q_txl_flits_g0.non_data",
39 "Counter": "0,1,2,3",
40 "EventName": "UNC_Q_TxL_FLITS_G0.NON_DATA",
41 "PerPkg": "1",
42 "ScaleUnit": "8Bytes",
43 "UMask": "0x4",
44 "Unit": "QPI LL"
45 }
46]
diff --git a/tools/perf/pmu-events/arch/x86/ivytown/uncore-memory.json b/tools/perf/pmu-events/arch/x86/ivytown/uncore-memory.json
new file mode 100644
index 000000000000..ac4ad4d6357b
--- /dev/null
+++ b/tools/perf/pmu-events/arch/x86/ivytown/uncore-memory.json
@@ -0,0 +1,75 @@
1[
2 {
3 "BriefDescription": "Memory page activates for reads and writes. Derived from unc_m_act_count.rd",
4 "Counter": "0,1,2,3",
5 "EventCode": "0x1",
6 "EventName": "UNC_M_ACT_COUNT.RD",
7 "PerPkg": "1",
8 "UMask": "0x1",
9 "Umask": "0x3",
10 "Unit": "iMC"
11 },
12 {
13 "BriefDescription": "Read requests to memory controller. Derived from unc_m_cas_count.rd",
14 "Counter": "0,1,2,3",
15 "EventCode": "0x4",
16 "EventName": "UNC_M_CAS_COUNT.RD",
17 "PerPkg": "1",
18 "ScaleUnit": "64Bytes",
19 "UMask": "0x3",
20 "Unit": "iMC"
21 },
22 {
23 "BriefDescription": "Write requests to memory controller. Derived from unc_m_cas_count.wr",
24 "Counter": "0,1,2,3",
25 "EventCode": "0x4",
26 "EventName": "UNC_M_CAS_COUNT.WR",
27 "PerPkg": "1",
28 "ScaleUnit": "64Bytes",
29 "UMask": "0xC",
30 "Unit": "iMC"
31 },
32 {
33 "BriefDescription": "Memory controller clock ticks. Use to generate percentages for memory controller CYCLES events. Derived from unc_m_clockticks",
34 "Counter": "0,1,2,3",
35 "EventName": "UNC_M_CLOCKTICKS",
36 "PerPkg": "1",
37 "Unit": "iMC"
38 },
39 {
40 "BriefDescription": "Cycles where DRAM ranks are in power down (CKE) mode. Derived from unc_m_power_channel_ppd",
41 "Counter": "0,1,2,3",
42 "EventCode": "0x85",
43 "EventName": "UNC_M_POWER_CHANNEL_PPD",
44 "MetricExpr": "(UNC_M_POWER_CHANNEL_PPD / UNC_M_CLOCKTICKS) * 100.",
45 "PerPkg": "1",
46 "Unit": "iMC"
47 },
48 {
49 "BriefDescription": "Cycles all ranks are in critical thermal throttle. Derived from unc_m_power_critical_throttle_cycles",
50 "Counter": "0,1,2,3",
51 "EventCode": "0x86",
52 "EventName": "UNC_M_POWER_CRITICAL_THROTTLE_CYCLES",
53 "MetricExpr": "(UNC_M_POWER_CRITICAL_THROTTLE_CYCLES / UNC_M_CLOCKTICKS) * 100.",
54 "PerPkg": "1",
55 "Unit": "iMC"
56 },
57 {
58 "BriefDescription": "Cycles Memory is in self refresh power mode. Derived from unc_m_power_self_refresh",
59 "Counter": "0,1,2,3",
60 "EventCode": "0x43",
61 "EventName": "UNC_M_POWER_SELF_REFRESH",
62 "MetricExpr": "(UNC_M_POWER_SELF_REFRESH / UNC_M_CLOCKTICKS) * 100.",
63 "PerPkg": "1",
64 "Unit": "iMC"
65 },
66 {
67 "BriefDescription": "Memory page conflicts. Derived from unc_m_pre_count.page_miss",
68 "Counter": "0,1,2,3",
69 "EventCode": "0x2",
70 "EventName": "UNC_M_PRE_COUNT.PAGE_MISS",
71 "PerPkg": "1",
72 "UMask": "0x1",
73 "Unit": "iMC"
74 }
75]
diff --git a/tools/perf/pmu-events/arch/x86/ivytown/uncore-power.json b/tools/perf/pmu-events/arch/x86/ivytown/uncore-power.json
new file mode 100644
index 000000000000..dc2586db0dfc
--- /dev/null
+++ b/tools/perf/pmu-events/arch/x86/ivytown/uncore-power.json
@@ -0,0 +1,249 @@
1[
2 {
3 "BriefDescription": "PCU clock ticks. Use to get percentages of PCU cycles events. Derived from unc_p_clockticks",
4 "Counter": "0,1,2,3",
5 "EventName": "UNC_P_CLOCKTICKS",
6 "PerPkg": "1",
7 "Unit": "PCU"
8 },
9 {
10 "BriefDescription": "Counts the number of cycles that the uncore was running at a frequency greater than or equal to the frequency that is configured in the filter. (filter_band0=XXX, with XXX in 100Mhz units). One can also use inversion (filter_inv=1) to track cycles when we were less than the configured frequency. Derived from unc_p_freq_band0_cycles",
11 "Counter": "0,1,2,3",
12 "EventCode": "0xb",
13 "EventName": "UNC_P_FREQ_BAND0_CYCLES",
14 "MetricExpr": "(UNC_P_FREQ_BAND0_CYCLES / UNC_P_CLOCKTICKS) * 100.",
15 "PerPkg": "1",
16 "Unit": "PCU"
17 },
18 {
19 "BriefDescription": "Counts the number of cycles that the uncore was running at a frequency greater than or equal to the frequency that is configured in the filter. (filter_band1=XXX, with XXX in 100Mhz units). One can also use inversion (filter_inv=1) to track cycles when we were less than the configured frequency. Derived from unc_p_freq_band1_cycles",
20 "Counter": "0,1,2,3",
21 "EventCode": "0xc",
22 "EventName": "UNC_P_FREQ_BAND1_CYCLES",
23 "MetricExpr": "(UNC_P_FREQ_BAND1_CYCLES / UNC_P_CLOCKTICKS) * 100.",
24 "PerPkg": "1",
25 "Unit": "PCU"
26 },
27 {
28 "BriefDescription": "Counts the number of cycles that the uncore was running at a frequency greater than or equal to the frequency that is configured in the filter. (filter_band2=XXX, with XXX in 100Mhz units). One can also use inversion (filter_inv=1) to track cycles when we were less than the configured frequency. Derived from unc_p_freq_band2_cycles",
29 "Counter": "0,1,2,3",
30 "EventCode": "0xd",
31 "EventName": "UNC_P_FREQ_BAND2_CYCLES",
32 "MetricExpr": "(UNC_P_FREQ_BAND2_CYCLES / UNC_P_CLOCKTICKS) * 100.",
33 "PerPkg": "1",
34 "Unit": "PCU"
35 },
36 {
37 "BriefDescription": "Counts the number of cycles that the uncore was running at a frequency greater than or equal to the frequency that is configured in the filter. (filter_band3=XXX, with XXX in 100Mhz units). One can also use inversion (filter_inv=1) to track cycles when we were less than the configured frequency. Derived from unc_p_freq_band3_cycles",
38 "Counter": "0,1,2,3",
39 "EventCode": "0xe",
40 "EventName": "UNC_P_FREQ_BAND3_CYCLES",
41 "MetricExpr": "(UNC_P_FREQ_BAND3_CYCLES / UNC_P_CLOCKTICKS) * 100.",
42 "PerPkg": "1",
43 "Unit": "PCU"
44 },
45 {
46 "BriefDescription": "Counts the number of times that the uncore transitioned a frequency greater than or equal to the frequency that is configured in the filter. (filter_band0=XXX, with XXX in 100Mhz units). One can also use inversion (filter_inv=1) to track cycles when we were less than the configured frequency. Derived from unc_p_freq_band0_cycles",
47 "Counter": "0,1,2,3",
48 "EventCode": "0xb",
49 "EventName": "UNC_P_FREQ_BAND0_TRANSITIONS",
50 "Filter": "edge=1",
51 "MetricExpr": "(UNC_P_FREQ_BAND0_CYCLES / UNC_P_CLOCKTICKS) * 100.",
52 "PerPkg": "1",
53 "Unit": "PCU"
54 },
55 {
56 "BriefDescription": "Counts the number of times that the uncore transitioned to a frequency greater than or equal to the frequency that is configured in the filter. (filter_band1=XXX, with XXX in 100Mhz units). One can also use inversion (filter_inv=1) to track cycles when we were less than the configured frequency. Derived from unc_p_freq_band1_cycles",
57 "Counter": "0,1,2,3",
58 "EventCode": "0xc",
59 "EventName": "UNC_P_FREQ_BAND1_TRANSITIONS",
60 "Filter": "edge=1",
61 "MetricExpr": "(UNC_P_FREQ_BAND1_CYCLES / UNC_P_CLOCKTICKS) * 100.",
62 "PerPkg": "1",
63 "Unit": "PCU"
64 },
65 {
66 "BriefDescription": "Counts the number of cycles that the uncore transitioned to a frequency greater than or equal to the frequency that is configured in the filter. (filter_band2=XXX, with XXX in 100Mhz units). One can also use inversion (filter_inv=1) to track cycles when we were less than the configured frequency. Derived from unc_p_freq_band2_cycles",
67 "Counter": "0,1,2,3",
68 "EventCode": "0xd",
69 "EventName": "UNC_P_FREQ_BAND2_TRANSITIONS",
70 "Filter": "edge=1",
71 "MetricExpr": "(UNC_P_FREQ_BAND2_CYCLES / UNC_P_CLOCKTICKS) * 100.",
72 "PerPkg": "1",
73 "Unit": "PCU"
74 },
75 {
76 "BriefDescription": "Counts the number of cycles that the uncore transitioned to a frequency greater than or equal to the frequency that is configured in the filter. (filter_band3=XXX, with XXX in 100Mhz units). One can also use inversion (filter_inv=1) to track cycles when we were less than the configured frequency. Derived from unc_p_freq_band3_cycles",
77 "Counter": "0,1,2,3",
78 "EventCode": "0xe",
79 "EventName": "UNC_P_FREQ_BAND3_TRANSITIONS",
80 "Filter": "edge=1",
81 "MetricExpr": "(UNC_P_FREQ_BAND3_CYCLES / UNC_P_CLOCKTICKS) * 100.",
82 "PerPkg": "1",
83 "Unit": "PCU"
84 },
85 {
86 "BriefDescription": "This is an occupancy event that tracks the number of cores that are in the chosen C-State. It can be used by itself to get the average number of cores in that C-state with threshholding to generate histograms, or with other PCU events and occupancy triggering to capture other details. Derived from unc_p_power_state_occupancy.cores_c0",
87 "Counter": "0,1,2,3",
88 "EventCode": "0x80",
89 "EventName": "UNC_P_POWER_STATE_OCCUPANCY.CORES_C0",
90 "Filter": "occ_sel=1",
91 "MetricExpr": "(UNC_P_POWER_STATE_OCCUPANCY.CORES_C0 / UNC_P_CLOCKTICKS) * 100.",
92 "PerPkg": "1",
93 "Unit": "PCU"
94 },
95 {
96 "BriefDescription": "This is an occupancy event that tracks the number of cores that are in the chosen C-State. It can be used by itself to get the average number of cores in that C-state with threshholding to generate histograms, or with other PCU events and occupancy triggering to capture other details. Derived from unc_p_power_state_occupancy.cores_c3",
97 "Counter": "0,1,2,3",
98 "EventCode": "0x80",
99 "EventName": "UNC_P_POWER_STATE_OCCUPANCY.CORES_C3",
100 "Filter": "occ_sel=2",
101 "MetricExpr": "(UNC_P_POWER_STATE_OCCUPANCY.CORES_C3 / UNC_P_CLOCKTICKS) * 100.",
102 "PerPkg": "1",
103 "Unit": "PCU"
104 },
105 {
106 "BriefDescription": "This is an occupancy event that tracks the number of cores that are in the chosen C-State. It can be used by itself to get the average number of cores in that C-state with threshholding to generate histograms, or with other PCU events and occupancy triggering to capture other details. Derived from unc_p_power_state_occupancy.cores_c6",
107 "Counter": "0,1,2,3",
108 "EventCode": "0x80",
109 "EventName": "UNC_P_POWER_STATE_OCCUPANCY.CORES_C6",
110 "Filter": "occ_sel=3",
111 "MetricExpr": "(UNC_P_POWER_STATE_OCCUPANCY.CORES_C6 / UNC_P_CLOCKTICKS) * 100.",
112 "PerPkg": "1",
113 "Unit": "PCU"
114 },
115 {
116 "BriefDescription": "Counts the number of cycles that we are in external PROCHOT mode. This mode is triggered when a sensor off the die determines that something off-die (like DRAM) is too hot and must throttle to avoid damaging the chip. Derived from unc_p_prochot_external_cycles",
117 "Counter": "0,1,2,3",
118 "EventCode": "0xa",
119 "EventName": "UNC_P_PROCHOT_EXTERNAL_CYCLES",
120 "MetricExpr": "(UNC_P_PROCHOT_EXTERNAL_CYCLES / UNC_P_CLOCKTICKS) * 100.",
121 "PerPkg": "1",
122 "Unit": "PCU"
123 },
124 {
125 "BriefDescription": "Counts the number of cycles when thermal conditions are the upper limit on frequency. This is related to the THERMAL_THROTTLE CYCLES_ABOVE_TEMP event, which always counts cycles when we are above the thermal temperature. This event (STRONGEST_UPPER_LIMIT) is sampled at the output of the algorithm that determines the actual frequency, while THERMAL_THROTTLE looks at the input. Derived from unc_p_freq_max_limit_thermal_cycles",
126 "Counter": "0,1,2,3",
127 "EventCode": "0x4",
128 "EventName": "UNC_P_FREQ_MAX_LIMIT_THERMAL_CYCLES",
129 "MetricExpr": "(UNC_P_FREQ_MAX_LIMIT_THERMAL_CYCLES / UNC_P_CLOCKTICKS) * 100.",
130 "PerPkg": "1",
131 "Unit": "PCU"
132 },
133 {
134 "BriefDescription": "Counts the number of cycles when the OS is the upper limit on frequency. Derived from unc_p_freq_max_os_cycles",
135 "Counter": "0,1,2,3",
136 "EventCode": "0x6",
137 "EventName": "UNC_P_FREQ_MAX_OS_CYCLES",
138 "MetricExpr": "(UNC_P_FREQ_MAX_OS_CYCLES / UNC_P_CLOCKTICKS) * 100.",
139 "PerPkg": "1",
140 "Unit": "PCU"
141 },
142 {
143 "BriefDescription": "Counts the number of cycles when power is the upper limit on frequency. Derived from unc_p_freq_max_power_cycles",
144 "Counter": "0,1,2,3",
145 "EventCode": "0x5",
146 "EventName": "UNC_P_FREQ_MAX_POWER_CYCLES",
147 "MetricExpr": "(UNC_P_FREQ_MAX_POWER_CYCLES / UNC_P_CLOCKTICKS) * 100.",
148 "PerPkg": "1",
149 "Unit": "PCU"
150 },
151 {
152 "BriefDescription": "Counts the number of cycles when current is the upper limit on frequency. Derived from unc_p_freq_max_current_cycles",
153 "Counter": "0,1,2,3",
154 "EventCode": "0x7",
155 "EventName": "UNC_P_FREQ_MAX_CURRENT_CYCLES",
156 "MetricExpr": "(UNC_P_FREQ_MAX_CURRENT_CYCLES / UNC_P_CLOCKTICKS) * 100.",
157 "PerPkg": "1",
158 "Unit": "PCU"
159 },
160 {
161 "BriefDescription": "Counts the number of cycles when the system is changing frequency. This can not be filtered by thread ID. One can also use it with the occupancy counter that monitors number of threads in C0 to estimate the performance impact that frequency transitions had on the system. Derived from unc_p_freq_trans_cycles",
162 "Counter": "0,1,2,3",
163 "EventCode": "0x60",
164 "EventName": "UNC_P_FREQ_TRANS_CYCLES",
165 "MetricExpr": "(UNC_P_FREQ_TRANS_CYCLES / UNC_P_CLOCKTICKS) * 100.",
166 "PerPkg": "1",
167 "Unit": "PCU"
168 },
169 {
170 "BriefDescription": "Counts the number of cycles that the uncore was running at a frequency greater than or equal to 1.2Ghz. Derived from unc_p_freq_band0_cycles",
171 "Counter": "0,1,2,3",
172 "EventCode": "0xb",
173 "EventName": "UNC_P_FREQ_GE_1200MHZ_CYCLES",
174 "Filter": "filter_band0=1200",
175 "MetricExpr": "(UNC_P_FREQ_GE_1200MHZ_CYCLES / UNC_P_CLOCKTICKS) * 100.",
176 "PerPkg": "1",
177 "Unit": "PCU"
178 },
179 {
180 "BriefDescription": "Counts the number of cycles that the uncore was running at a frequency greater than or equal to 2Ghz. Derived from unc_p_freq_band1_cycles",
181 "Counter": "0,1,2,3",
182 "EventCode": "0xc",
183 "EventName": "UNC_P_FREQ_GE_2000MHZ_CYCLES",
184 "Filter": "filter_band1=2000",
185 "MetricExpr": "(UNC_P_FREQ_GE_2000MHZ_CYCLES / UNC_P_CLOCKTICKS) * 100.",
186 "PerPkg": "1",
187 "Unit": "PCU"
188 },
189 {
190 "BriefDescription": "Counts the number of cycles that the uncore was running at a frequency greater than or equal to 3Ghz. Derived from unc_p_freq_band2_cycles",
191 "Counter": "0,1,2,3",
192 "EventCode": "0xd",
193 "EventName": "UNC_P_FREQ_GE_3000MHZ_CYCLES",
194 "Filter": "filter_band2=3000",
195 "MetricExpr": "(UNC_P_FREQ_GE_3000MHZ_CYCLES / UNC_P_CLOCKTICKS) * 100.",
196 "PerPkg": "1",
197 "Unit": "PCU"
198 },
199 {
200 "BriefDescription": "Counts the number of cycles that the uncore was running at a frequency greater than or equal to 4Ghz. Derived from unc_p_freq_band3_cycles",
201 "Counter": "0,1,2,3",
202 "EventCode": "0xe",
203 "EventName": "UNC_P_FREQ_GE_4000MHZ_CYCLES",
204 "Filter": "filter_band3=4000",
205 "MetricExpr": "(UNC_P_FREQ_GE_4000MHZ_CYCLES / UNC_P_CLOCKTICKS) * 100.",
206 "PerPkg": "1",
207 "Unit": "PCU"
208 },
209 {
210 "BriefDescription": "Counts the number of times that the uncore transitioned to a frequency greater than or equal to 1.2Ghz. Derived from unc_p_freq_band0_cycles",
211 "Counter": "0,1,2,3",
212 "EventCode": "0xb",
213 "EventName": "UNC_P_FREQ_GE_1200MHZ_TRANSITIONS",
214 "Filter": "edge=1,filter_band0=1200",
215 "MetricExpr": "(UNC_P_FREQ_GE_1200MHZ_CYCLES / UNC_P_CLOCKTICKS) * 100.",
216 "PerPkg": "1",
217 "Unit": "PCU"
218 },
219 {
220 "BriefDescription": "Counts the number of times that the uncore transitioned to a frequency greater than or equal to 2Ghz. Derived from unc_p_freq_band1_cycles",
221 "Counter": "0,1,2,3",
222 "EventCode": "0xc",
223 "EventName": "UNC_P_FREQ_GE_2000MHZ_TRANSITIONS",
224 "Filter": "edge=1,filter_band1=2000",
225 "MetricExpr": "(UNC_P_FREQ_GE_2000MHZ_CYCLES / UNC_P_CLOCKTICKS) * 100.",
226 "PerPkg": "1",
227 "Unit": "PCU"
228 },
229 {
230 "BriefDescription": "Counts the number of cycles that the uncore transitioned to a frequency greater than or equal to 3Ghz. Derived from unc_p_freq_band2_cycles",
231 "Counter": "0,1,2,3",
232 "EventCode": "0xd",
233 "EventName": "UNC_P_FREQ_GE_3000MHZ_TRANSITIONS",
234 "Filter": "edge=1,filter_band2=4000",
235 "MetricExpr": "(UNC_P_FREQ_GE_3000MHZ_CYCLES / UNC_P_CLOCKTICKS) * 100.",
236 "PerPkg": "1",
237 "Unit": "PCU"
238 },
239 {
240 "BriefDescription": "Counts the number of cycles that the uncore transitioned to a frequency greater than or equal to 4Ghz. Derived from unc_p_freq_band3_cycles",
241 "Counter": "0,1,2,3",
242 "EventCode": "0xe",
243 "EventName": "UNC_P_FREQ_GE_4000MHZ_TRANSITIONS",
244 "Filter": "edge=1,filter_band3=4000",
245 "MetricExpr": "(UNC_P_FREQ_GE_4000MHZ_CYCLES / UNC_P_CLOCKTICKS) * 100.",
246 "PerPkg": "1",
247 "Unit": "PCU"
248 }
249]
diff --git a/tools/perf/pmu-events/arch/x86/jaketown/uncore-cache.json b/tools/perf/pmu-events/arch/x86/jaketown/uncore-cache.json
new file mode 100644
index 000000000000..2f23cf0129e7
--- /dev/null
+++ b/tools/perf/pmu-events/arch/x86/jaketown/uncore-cache.json
@@ -0,0 +1,209 @@
1[
2 {
3 "BriefDescription": "Uncore cache clock ticks. Derived from unc_c_clockticks",
4 "Counter": "0,1,2,3",
5 "EventName": "UNC_C_CLOCKTICKS",
6 "PerPkg": "1",
7 "Unit": "CBO"
8 },
9 {
10 "BriefDescription": "All LLC Misses (code+ data rd + data wr - including demand and prefetch). Derived from unc_c_llc_lookup.any",
11 "Counter": "0,1",
12 "EventCode": "0x34",
13 "EventName": "UNC_C_LLC_LOOKUP.ANY",
14 "Filter": "filter_state=0x1",
15 "PerPkg": "1",
16 "ScaleUnit": "64Bytes",
17 "UMask": "0x11",
18 "Unit": "CBO"
19 },
20 {
21 "BriefDescription": "M line evictions from LLC (writebacks to memory). Derived from unc_c_llc_victims.m_state",
22 "Counter": "0,1",
23 "EventCode": "0x37",
24 "EventName": "UNC_C_LLC_VICTIMS.M_STATE",
25 "PerPkg": "1",
26 "ScaleUnit": "64Bytes",
27 "UMask": "0x1",
28 "Unit": "CBO"
29 },
30 {
31 "BriefDescription": "LLC misses - demand and prefetch data reads - excludes LLC prefetches. Derived from unc_c_tor_inserts.miss_opcode.demand",
32 "Counter": "0,1",
33 "EventCode": "0x35",
34 "EventName": "LLC_MISSES.DATA_READ",
35 "Filter": "filter_opc=0x182",
36 "PerPkg": "1",
37 "ScaleUnit": "64Bytes",
38 "UMask": "0x3",
39 "Unit": "CBO"
40 },
41 {
42 "BriefDescription": "LLC misses - Uncacheable reads. Derived from unc_c_tor_inserts.miss_opcode.uncacheable",
43 "Counter": "0,1",
44 "EventCode": "0x35",
45 "EventName": "LLC_MISSES.UNCACHEABLE",
46 "Filter": "filter_opc=0x187",
47 "PerPkg": "1",
48 "ScaleUnit": "64Bytes",
49 "UMask": "0x3",
50 "Unit": "CBO"
51 },
52 {
53 "BriefDescription": "PCIe allocating writes that miss LLC - DDIO misses. Derived from unc_c_tor_inserts.miss_opcode.ddio_miss",
54 "Counter": "0,1",
55 "EventCode": "0x35",
56 "EventName": "LLC_MISSES.PCIE_WRITE",
57 "Filter": "filter_opc=0x19c",
58 "PerPkg": "1",
59 "ScaleUnit": "64Bytes",
60 "UMask": "0x3",
61 "Unit": "CBO"
62 },
63 {
64 "BriefDescription": "LLC misses for ItoM writes (as part of fast string memcpy stores). Derived from unc_c_tor_inserts.miss_opcode.itom_write",
65 "Counter": "0,1",
66 "EventCode": "0x35",
67 "EventName": "LLC_MISSES.ITOM_WRITE",
68 "Filter": "filter_opc=0x1c8",
69 "PerPkg": "1",
70 "ScaleUnit": "64Bytes",
71 "UMask": "0x3",
72 "Unit": "CBO"
73 },
74 {
75 "BriefDescription": "Streaming stores (full cache line). Derived from unc_c_tor_inserts.opcode.streaming_full",
76 "Counter": "0,1",
77 "EventCode": "0x35",
78 "EventName": "LLC_REFERENCES.STREAMING_FULL",
79 "Filter": "filter_opc=0x18c",
80 "PerPkg": "1",
81 "ScaleUnit": "64Bytes",
82 "UMask": "0x1",
83 "Unit": "CBO"
84 },
85 {
86 "BriefDescription": "Streaming stores (partial cache line). Derived from unc_c_tor_inserts.opcode.streaming_partial",
87 "Counter": "0,1",
88 "EventCode": "0x35",
89 "EventName": "LLC_REFERENCES.STREAMING_PARTIAL",
90 "Filter": "filter_opc=0x18d",
91 "PerPkg": "1",
92 "ScaleUnit": "64Bytes",
93 "UMask": "0x1",
94 "Unit": "CBO"
95 },
96 {
97 "BriefDescription": "Partial PCIe reads. Derived from unc_c_tor_inserts.opcode.pcie_partial",
98 "Counter": "0,1",
99 "EventCode": "0x35",
100 "EventName": "LLC_REFERENCES.PCIE_PARTIAL_READ",
101 "Filter": "filter_opc=0x195",
102 "PerPkg": "1",
103 "ScaleUnit": "64Bytes",
104 "UMask": "0x1",
105 "Unit": "CBO"
106 },
107 {
108 "BriefDescription": "PCIe allocating writes that hit in LLC (DDIO hits). Derived from unc_c_tor_inserts.opcode.ddio_hit",
109 "Counter": "0,1",
110 "EventCode": "0x35",
111 "EventName": "LLC_REFERENCES.PCIE_WRITE",
112 "Filter": "filter_opc=0x19c",
113 "PerPkg": "1",
114 "ScaleUnit": "64Bytes",
115 "UMask": "0x1",
116 "Unit": "CBO"
117 },
118 {
119 "BriefDescription": "PCIe read current. Derived from unc_c_tor_inserts.opcode.pcie_read_current",
120 "Counter": "0,1",
121 "EventCode": "0x35",
122 "EventName": "LLC_REFERENCES.PCIE_READ",
123 "Filter": "filter_opc=0x19e",
124 "PerPkg": "1",
125 "ScaleUnit": "64Bytes",
126 "UMask": "0x1",
127 "Unit": "CBO"
128 },
129 {
130 "BriefDescription": "ItoM write hits (as part of fast string memcpy stores). Derived from unc_c_tor_inserts.opcode.itom_write_hit",
131 "Counter": "0,1",
132 "EventCode": "0x35",
133 "EventName": "LLC_REFERENCES.ITOM_WRITE",
134 "Filter": "filter_opc=0x1c8",
135 "PerPkg": "1",
136 "ScaleUnit": "64Bytes",
137 "UMask": "0x1",
138 "Unit": "CBO"
139 },
140 {
141 "BriefDescription": "PCIe non-snoop reads. Derived from unc_c_tor_inserts.opcode.pcie_read",
142 "Counter": "0,1",
143 "EventCode": "0x35",
144 "EventName": "LLC_REFERENCES.PCIE_NS_READ",
145 "Filter": "filter_opc=0x1e4",
146 "PerPkg": "1",
147 "ScaleUnit": "64Bytes",
148 "UMask": "0x1",
149 "Unit": "CBO"
150 },
151 {
152 "BriefDescription": "PCIe non-snoop writes (partial). Derived from unc_c_tor_inserts.opcode.pcie_partial_write",
153 "Counter": "0,1",
154 "EventCode": "0x35",
155 "EventName": "LLC_REFERENCES.PCIE_NS_PARTIAL_WRITE",
156 "Filter": "filter_opc=0x1e5",
157 "PerPkg": "1",
158 "ScaleUnit": "64Bytes",
159 "UMask": "0x1",
160 "Unit": "CBO"
161 },
162 {
163 "BriefDescription": "PCIe non-snoop writes (full line). Derived from unc_c_tor_inserts.opcode.pcie_full_write",
164 "Counter": "0,1",
165 "EventCode": "0x35",
166 "EventName": "LLC_REFERENCES.PCIE_NS_WRITE",
167 "Filter": "filter_opc=0x1e6",
168 "PerPkg": "1",
169 "ScaleUnit": "64Bytes",
170 "UMask": "0x1",
171 "Unit": "CBO"
172 },
173 {
174 "BriefDescription": "Occupancy counter for all LLC misses; we divide this by UNC_C_CLOCKTICKS to get average Q depth. Derived from unc_c_tor_occupancy.miss_all",
175 "EventCode": "0x36",
176 "EventName": "UNC_C_TOR_OCCUPANCY.MISS_ALL",
177 "Filter": "filter_opc=0x182",
178 "MetricExpr": "(UNC_C_TOR_OCCUPANCY.MISS_ALL / UNC_C_CLOCKTICKS) * 100.",
179 "PerPkg": "1",
180 "UMask": "0xa",
181 "Unit": "CBO"
182 },
183 {
184 "BriefDescription": "Occupancy counter for LLC data reads (demand and L2 prefetch). Derived from unc_c_tor_occupancy.miss_opcode.llc_data_read",
185 "EventCode": "0x36",
186 "EventName": "UNC_C_TOR_OCCUPANCY.LLC_DATA_READ",
187 "PerPkg": "1",
188 "UMask": "0x3",
189 "Unit": "CBO"
190 },
191 {
192 "BriefDescription": "read requests to home agent. Derived from unc_h_requests.reads",
193 "Counter": "0,1,2,3",
194 "EventCode": "0x1",
195 "EventName": "UNC_H_REQUESTS.READS",
196 "PerPkg": "1",
197 "UMask": "0x3",
198 "Unit": "HA"
199 },
200 {
201 "BriefDescription": "write requests to home agent. Derived from unc_h_requests.writes",
202 "Counter": "0,1,2,3",
203 "EventCode": "0x1",
204 "EventName": "UNC_H_REQUESTS.WRITES",
205 "PerPkg": "1",
206 "UMask": "0xc",
207 "Unit": "HA"
208 }
209]
diff --git a/tools/perf/pmu-events/arch/x86/jaketown/uncore-interconnect.json b/tools/perf/pmu-events/arch/x86/jaketown/uncore-interconnect.json
new file mode 100644
index 000000000000..63351876eb57
--- /dev/null
+++ b/tools/perf/pmu-events/arch/x86/jaketown/uncore-interconnect.json
@@ -0,0 +1,46 @@
1[
2 {
3 "BriefDescription": "QPI clock ticks. Used to get percentages of QPI cycles events. Derived from unc_q_clockticks",
4 "Counter": "0,1,2,3",
5 "EventCode": "0x14",
6 "EventName": "UNC_Q_CLOCKTICKS",
7 "PerPkg": "1",
8 "Unit": "QPI LL"
9 },
10 {
11 "BriefDescription": "Cycles where receiving QPI link is in half-width mode. Derived from unc_q_rxl0p_power_cycles",
12 "Counter": "0,1,2,3",
13 "EventCode": "0x10",
14 "EventName": "UNC_Q_RxL0P_POWER_CYCLES",
15 "MetricExpr": "(UNC_Q_RxL0P_POWER_CYCLES / UNC_Q_CLOCKTICKS) * 100.",
16 "PerPkg": "1",
17 "Unit": "QPI LL"
18 },
19 {
20 "BriefDescription": "Cycles where transmitting QPI link is in half-width mode. Derived from unc_q_txl0p_power_cycles",
21 "Counter": "0,1,2,3",
22 "EventCode": "0xd",
23 "EventName": "UNC_Q_TxL0P_POWER_CYCLES",
24 "MetricExpr": "(UNC_Q_TxL0P_POWER_CYCLES / UNC_Q_CLOCKTICKS) * 100.",
25 "PerPkg": "1",
26 "Unit": "QPI LL"
27 },
28 {
29 "BriefDescription": "Number of data flits transmitted . Derived from unc_q_txl_flits_g0.data",
30 "Counter": "0,1,2,3",
31 "EventName": "UNC_Q_TxL_FLITS_G0.DATA",
32 "PerPkg": "1",
33 "ScaleUnit": "8Bytes",
34 "UMask": "0x2",
35 "Unit": "QPI LL"
36 },
37 {
38 "BriefDescription": "Number of non data (control) flits transmitted . Derived from unc_q_txl_flits_g0.non_data",
39 "Counter": "0,1,2,3",
40 "EventName": "UNC_Q_TxL_FLITS_G0.NON_DATA",
41 "PerPkg": "1",
42 "ScaleUnit": "8Bytes",
43 "UMask": "0x4",
44 "Unit": "QPI LL"
45 }
46]
diff --git a/tools/perf/pmu-events/arch/x86/jaketown/uncore-memory.json b/tools/perf/pmu-events/arch/x86/jaketown/uncore-memory.json
new file mode 100644
index 000000000000..e2cf6daa7b37
--- /dev/null
+++ b/tools/perf/pmu-events/arch/x86/jaketown/uncore-memory.json
@@ -0,0 +1,79 @@
1[
2 {
3 "BriefDescription": "Memory page activates. Derived from unc_m_act_count",
4 "Counter": "0,1,2,3",
5 "EventCode": "0x1",
6 "EventName": "UNC_M_ACT_COUNT",
7 "PerPkg": "1",
8 "Unit": "iMC"
9 },
10 {
11 "BriefDescription": "read requests to memory controller. Derived from unc_m_cas_count.rd",
12 "Counter": "0,1,2,3",
13 "EventCode": "0x4",
14 "EventName": "UNC_M_CAS_COUNT.RD",
15 "PerPkg": "1",
16 "UMask": "0x3",
17 "Unit": "iMC"
18 },
19 {
20 "BriefDescription": "write requests to memory controller. Derived from unc_m_cas_count.wr",
21 "Counter": "0,1,2,3",
22 "EventCode": "0x4",
23 "EventName": "UNC_M_CAS_COUNT.WR",
24 "PerPkg": "1",
25 "UMask": "0xc",
26 "Unit": "iMC"
27 },
28 {
29 "BriefDescription": "Memory controller clock ticks. Used to get percentages of memory controller cycles events. Derived from unc_m_clockticks",
30 "Counter": "0,1,2,3",
31 "EventName": "UNC_M_CLOCKTICKS",
32 "PerPkg": "1",
33 "Unit": "iMC"
34 },
35 {
36 "BriefDescription": "Cycles where DRAM ranks are in power down (CKE) mode. Derived from unc_m_power_channel_ppd",
37 "Counter": "0,1,2,3",
38 "EventCode": "0x85",
39 "EventName": "UNC_M_POWER_CHANNEL_PPD",
40 "MetricExpr": "(UNC_M_POWER_CHANNEL_PPD / UNC_M_CLOCKTICKS) * 100.",
41 "PerPkg": "1",
42 "Unit": "iMC"
43 },
44 {
45 "BriefDescription": "Cycles all ranks are in critical thermal throttle. Derived from unc_m_power_critical_throttle_cycles",
46 "Counter": "0,1,2,3",
47 "EventCode": "0x86",
48 "EventName": "UNC_M_POWER_CRITICAL_THROTTLE_CYCLES",
49 "MetricExpr": "(UNC_M_POWER_CRITICAL_THROTTLE_CYCLES / UNC_M_CLOCKTICKS) * 100.",
50 "PerPkg": "1",
51 "Unit": "iMC"
52 },
53 {
54 "BriefDescription": "Cycles Memory is in self refresh power mode. Derived from unc_m_power_self_refresh",
55 "Counter": "0,1,2,3",
56 "EventCode": "0x43",
57 "EventName": "UNC_M_POWER_SELF_REFRESH",
58 "MetricExpr": "(UNC_M_POWER_SELF_REFRESH / UNC_M_CLOCKTICKS) * 100.",
59 "PerPkg": "1",
60 "Unit": "iMC"
61 },
62 {
63 "BriefDescription": "Memory page conflicts. Derived from unc_m_pre_count.page_miss",
64 "Counter": "0,1,2,3",
65 "EventCode": "0x2",
66 "EventName": "UNC_M_PRE_COUNT.PAGE_MISS",
67 "PerPkg": "1",
68 "UMask": "0x1",
69 "Unit": "iMC"
70 },
71 {
72 "BriefDescription": "Occupancy counter for memory read queue. Derived from unc_m_rpq_occupancy",
73 "Counter": "0,1,2,3",
74 "EventCode": "0x80",
75 "EventName": "UNC_M_RPQ_OCCUPANCY",
76 "PerPkg": "1",
77 "Unit": "iMC"
78 }
79]
diff --git a/tools/perf/pmu-events/arch/x86/jaketown/uncore-power.json b/tools/perf/pmu-events/arch/x86/jaketown/uncore-power.json
new file mode 100644
index 000000000000..bbe36d547386
--- /dev/null
+++ b/tools/perf/pmu-events/arch/x86/jaketown/uncore-power.json
@@ -0,0 +1,248 @@
1[
2 {
3 "BriefDescription": "PCU clock ticks. Use to get percentages of PCU cycles events. Derived from unc_p_clockticks",
4 "Counter": "0,1,2,3",
5 "EventName": "UNC_P_CLOCKTICKS",
6 "PerPkg": "1",
7 "Unit": "PCU"
8 },
9 {
10 "BriefDescription": "Counts the number of cycles that the uncore was running at a frequency greater than or equal to the frequency that is configured in the filter. (filter_band0=XXX with XXX in 100Mhz units). One can also use inversion (filter_inv=1) to track cycles when we were less than the configured frequency. Derived from unc_p_freq_band0_cycles",
11 "Counter": "0,1,2,3",
12 "EventCode": "0xb",
13 "EventName": "UNC_P_FREQ_BAND0_CYCLES",
14 "MetricExpr": "(UNC_P_FREQ_BAND0_CYCLES / UNC_P_CLOCKTICKS) * 100.",
15 "PerPkg": "1",
16 "Unit": "PCU"
17 },
18 {
19 "BriefDescription": "Counts the number of cycles that the uncore was running at a frequency greater than or equal to the frequency that is configured in the filter. (filter_band1=XXX with XXX in 100Mhz units). One can also use inversion (filter_inv=1) to track cycles when we were less than the configured frequency. Derived from unc_p_freq_band1_cycles",
20 "Counter": "0,1,2,3",
21 "EventCode": "0xc",
22 "EventName": "UNC_P_FREQ_BAND1_CYCLES",
23 "MetricExpr": "(UNC_P_FREQ_BAND1_CYCLES / UNC_P_CLOCKTICKS) * 100.",
24 "PerPkg": "1",
25 "Unit": "PCU"
26 },
27 {
28 "BriefDescription": "Counts the number of cycles that the uncore was running at a frequency greater than or equal to the frequency that is configured in the filter. (filter_band2=XXX with XXX in 100Mhz units). One can also use inversion (filter_inv=1) to track cycles when we were less than the configured frequency. Derived from unc_p_freq_band2_cycles",
29 "Counter": "0,1,2,3",
30 "EventCode": "0xd",
31 "EventName": "UNC_P_FREQ_BAND2_CYCLES",
32 "MetricExpr": "(UNC_P_FREQ_BAND2_CYCLES / UNC_P_CLOCKTICKS) * 100.",
33 "PerPkg": "1",
34 "Unit": "PCU"
35 },
36 {
37 "BriefDescription": "Counts the number of cycles that the uncore was running at a frequency greater than or equal to the frequency that is configured in the filter. (filter_band3=XXX, with XXX in 100Mhz units). One can also use inversion (filter_inv=1) to track cycles when we were less than the configured frequency. Derived from unc_p_freq_band3_cycles",
38 "Counter": "0,1,2,3",
39 "EventCode": "0xe",
40 "EventName": "UNC_P_FREQ_BAND3_CYCLES",
41 "MetricExpr": "(UNC_P_FREQ_BAND3_CYCLES / UNC_P_CLOCKTICKS) * 100.",
42 "PerPkg": "1",
43 "Unit": "PCU"
44 },
45 {
46 "BriefDescription": "Counts the number of times that the uncore transitioned a frequency greater than or equal to the frequency that is configured in the filter. (filter_band0=XXX with XXX in 100Mhz units). One can also use inversion (filter_inv=1) to track cycles when we were less than the configured frequency. Derived from unc_p_freq_band0_cycles",
47 "Counter": "0,1,2,3",
48 "EventCode": "0xb",
49 "EventName": "UNC_P_FREQ_BAND0_TRANSITIONS",
50 "Filter": "edge=1",
51 "MetricExpr": "(UNC_P_FREQ_BAND0_CYCLES / UNC_P_CLOCKTICKS) * 100.",
52 "PerPkg": "1",
53 "Unit": "PCU"
54 },
55 {
56 "BriefDescription": "Counts the number of times that the uncore transistioned to a frequency greater than or equal to the frequency that is configured in the filter. (filter_band1=XXX with XXX in 100Mhz units). One can also use inversion (filter_inv=1) to track cycles when we were less than the configured frequency. Derived from unc_p_freq_band1_cycles",
57 "Counter": "0,1,2,3",
58 "EventCode": "0xc",
59 "EventName": "UNC_P_FREQ_BAND1_TRANSITIONS",
60 "Filter": "edge=1",
61 "MetricExpr": "(UNC_P_FREQ_BAND1_CYCLES / UNC_P_CLOCKTICKS) * 100.",
62 "PerPkg": "1",
63 "Unit": "PCU"
64 },
65 {
66 "BriefDescription": "Counts the number of cycles that the uncore transitioned to a frequency greater than or equal to the frequency that is configured in the filter. (filter_band2=XXX with XXX in 100Mhz units). One can also use inversion (filter_inv=1) to track cycles when we were less than the configured frequency. Derived from unc_p_freq_band2_cycles",
67 "Counter": "0,1,2,3",
68 "EventCode": "0xd",
69 "EventName": "UNC_P_FREQ_BAND2_TRANSITIONS",
70 "Filter": "edge=1",
71 "MetricExpr": "(UNC_P_FREQ_BAND2_CYCLES / UNC_P_CLOCKTICKS) * 100.",
72 "PerPkg": "1",
73 "Unit": "PCU"
74 },
75 {
76 "BriefDescription": "Counts the number of cycles that the uncore transitioned to a frequency greater than or equal to the frequency that is configured in the filter. (filter_band3=XXX, with XXX in 100Mhz units). One can also use inversion (filter_inv=1) to track cycles when we were less than the configured frequency. Derived from unc_p_freq_band3_cycles",
77 "Counter": "0,1,2,3",
78 "EventCode": "0xe",
79 "EventName": "UNC_P_FREQ_BAND3_TRANSITIONS",
80 "Filter": "edge=1",
81 "MetricExpr": "(UNC_P_FREQ_BAND3_CYCLES / UNC_P_CLOCKTICKS) * 100.",
82 "PerPkg": "1",
83 "Unit": "PCU"
84 },
85 {
86 "BriefDescription": "This is an occupancy event that tracks the number of cores that are in C0. It can be used by itself to get the average number of cores in C0, with threshholding to generate histograms, or with other PCU events and occupancy triggering to capture other details. Derived from unc_p_power_state_occupancy.cores_c0",
87 "Counter": "0,1,2,3",
88 "EventCode": "0x80",
89 "EventName": "UNC_P_POWER_STATE_OCCUPANCY.CORES_C0",
90 "Filter": "occ_sel=1",
91 "MetricExpr": "(UNC_P_POWER_STATE_OCCUPANCY.CORES_C0 / UNC_P_CLOCKTICKS) * 100.",
92 "PerPkg": "1",
93 "Unit": "PCU"
94 },
95 {
96 "BriefDescription": "This is an occupancy event that tracks the number of cores that are in C3. It can be used by itself to get the average number of cores in C0, with threshholding to generate histograms, or with other PCU events and occupancy triggering to capture other details. Derived from unc_p_power_state_occupancy.cores_c3",
97 "Counter": "0,1,2,3",
98 "EventCode": "0x80",
99 "EventName": "UNC_P_POWER_STATE_OCCUPANCY.CORES_C3",
100 "Filter": "occ_sel=2",
101 "MetricExpr": "(UNC_P_POWER_STATE_OCCUPANCY.CORES_C3 / UNC_P_CLOCKTICKS) * 100.",
102 "PerPkg": "1",
103 "Unit": "PCU"
104 },
105 {
106 "BriefDescription": "This is an occupancy event that tracks the number of cores that are in C6. It can be used by itself to get the average number of cores in C0, with threshholding to generate histograms, or with other PCU events . Derived from unc_p_power_state_occupancy.cores_c6",
107 "Counter": "0,1,2,3",
108 "EventCode": "0x80",
109 "EventName": "UNC_P_POWER_STATE_OCCUPANCY.CORES_C6",
110 "Filter": "occ_sel=3",
111 "MetricExpr": "(UNC_P_POWER_STATE_OCCUPANCY.CORES_C6 / UNC_P_CLOCKTICKS) * 100.",
112 "PerPkg": "1",
113 "Unit": "PCU"
114 },
115 {
116 "BriefDescription": "Counts the number of cycles that we are in external PROCHOT mode. This mode is triggered when a sensor off the die determines that something off-die (like DRAM) is too hot and must throttle to avoid damaging the chip. Derived from unc_p_prochot_external_cycles",
117 "Counter": "0,1,2,3",
118 "EventCode": "0xa",
119 "EventName": "UNC_P_PROCHOT_EXTERNAL_CYCLES",
120 "MetricExpr": "(UNC_P_PROCHOT_EXTERNAL_CYCLES / UNC_P_CLOCKTICKS) * 100.",
121 "PerPkg": "1",
122 "Unit": "PCU"
123 },
124 {
125 "BriefDescription": "Counts the number of cycles when temperature is the upper limit on frequency. Derived from unc_p_freq_max_limit_thermal_cycles",
126 "Counter": "0,1,2,3",
127 "EventCode": "0x4",
128 "EventName": "UNC_P_FREQ_MAX_LIMIT_THERMAL_CYCLES",
129 "MetricExpr": "(UNC_P_FREQ_MAX_LIMIT_THERMAL_CYCLES / UNC_P_CLOCKTICKS) * 100.",
130 "PerPkg": "1",
131 "Unit": "PCU"
132 },
133 {
134 "BriefDescription": "Counts the number of cycles when the OS is the upper limit on frequency. Derived from unc_p_freq_max_os_cycles",
135 "Counter": "0,1,2,3",
136 "EventCode": "0x6",
137 "EventName": "UNC_P_FREQ_MAX_OS_CYCLES",
138 "MetricExpr": "(UNC_P_FREQ_MAX_OS_CYCLES / UNC_P_CLOCKTICKS) * 100.",
139 "PerPkg": "1",
140 "Unit": "PCU"
141 },
142 {
143 "BriefDescription": "Counts the number of cycles when power is the upper limit on frequency. Derived from unc_p_freq_max_power_cycles",
144 "Counter": "0,1,2,3",
145 "EventCode": "0x5",
146 "EventName": "UNC_P_FREQ_MAX_POWER_CYCLES",
147 "MetricExpr": "(UNC_P_FREQ_MAX_POWER_CYCLES / UNC_P_CLOCKTICKS) * 100.",
148 "PerPkg": "1",
149 "Unit": "PCU"
150 },
151 {
152 "BriefDescription": "Counts the number of cycles when current is the upper limit on frequency. Derived from unc_p_freq_max_current_cycles",
153 "Counter": "0,1,2,3",
154 "EventCode": "0x7",
155 "EventName": "UNC_P_FREQ_MAX_CURRENT_CYCLES",
156 "MetricExpr": "(UNC_P_FREQ_MAX_CURRENT_CYCLES / UNC_P_CLOCKTICKS) * 100.",
157 "PerPkg": "1",
158 "Unit": "PCU"
159 },
160 {
161 "BriefDescription": "Cycles spent changing Frequency. Derived from unc_p_freq_trans_cycles",
162 "Counter": "0,1,2,3",
163 "EventName": "UNC_P_FREQ_TRANS_CYCLES",
164 "MetricExpr": "(UNC_P_FREQ_TRANS_CYCLES / UNC_P_CLOCKTICKS) * 100.",
165 "PerPkg": "1",
166 "Unit": "PCU"
167 },
168 {
169 "BriefDescription": "Counts the number of cycles that the uncore was running at a frequency greater than or equal to 1.2Ghz. Derived from unc_p_freq_band0_cycles",
170 "Counter": "0,1,2,3",
171 "EventCode": "0xb",
172 "EventName": "UNC_P_FREQ_GE_1200MHZ_CYCLES",
173 "Filter": "filter_band0=1200",
174 "MetricExpr": "(UNC_P_FREQ_GE_1200MHZ_CYCLES / UNC_P_CLOCKTICKS) * 100.",
175 "PerPkg": "1",
176 "Unit": "PCU"
177 },
178 {
179 "BriefDescription": "Counts the number of cycles that the uncore was running at a frequency greater than or equal to 2Ghz. Derived from unc_p_freq_band1_cycles",
180 "Counter": "0,1,2,3",
181 "EventCode": "0xc",
182 "EventName": "UNC_P_FREQ_GE_2000MHZ_CYCLES",
183 "Filter": "filter_band1=2000",
184 "MetricExpr": "(UNC_P_FREQ_GE_2000MHZ_CYCLES / UNC_P_CLOCKTICKS) * 100.",
185 "PerPkg": "1",
186 "Unit": "PCU"
187 },
188 {
189 "BriefDescription": "Counts the number of cycles that the uncore was running at a frequency greater than or equal to 3Ghz. Derived from unc_p_freq_band2_cycles",
190 "Counter": "0,1,2,3",
191 "EventCode": "0xd",
192 "EventName": "UNC_P_FREQ_GE_3000MHZ_CYCLES",
193 "Filter": "filter_band2=3000",
194 "MetricExpr": "(UNC_P_FREQ_GE_3000MHZ_CYCLES / UNC_P_CLOCKTICKS) * 100.",
195 "PerPkg": "1",
196 "Unit": "PCU"
197 },
198 {
199 "BriefDescription": "Counts the number of cycles that the uncore was running at a frequency greater than or equal to 4Ghz. Derived from unc_p_freq_band3_cycles",
200 "Counter": "0,1,2,3",
201 "EventCode": "0xe",
202 "EventName": "UNC_P_FREQ_GE_4000MHZ_CYCLES",
203 "Filter": "filter_band3=4000",
204 "MetricExpr": "(UNC_P_FREQ_GE_4000MHZ_CYCLES / UNC_P_CLOCKTICKS) * 100.",
205 "PerPkg": "1",
206 "Unit": "PCU"
207 },
208 {
209 "BriefDescription": "Counts the number of times that the uncore transitioned to a frequency greater than or equal to 1.2Ghz. Derived from unc_p_freq_band0_cycles",
210 "Counter": "0,1,2,3",
211 "EventCode": "0xb",
212 "EventName": "UNC_P_FREQ_GE_1200MHZ_TRANSITIONS",
213 "Filter": "edge=1,filter_band0=1200",
214 "MetricExpr": "(UNC_P_FREQ_GE_1200MHZ_CYCLES / UNC_P_CLOCKTICKS) * 100.",
215 "PerPkg": "1",
216 "Unit": "PCU"
217 },
218 {
219 "BriefDescription": "Counts the number of times that the uncore transitioned to a frequency greater than or equal to 2Ghz. Derived from unc_p_freq_band1_cycles",
220 "Counter": "0,1,2,3",
221 "EventCode": "0xc",
222 "EventName": "UNC_P_FREQ_GE_2000MHZ_TRANSITIONS",
223 "Filter": "edge=1,filter_band1=2000",
224 "MetricExpr": "(UNC_P_FREQ_GE_2000MHZ_CYCLES / UNC_P_CLOCKTICKS) * 100.",
225 "PerPkg": "1",
226 "Unit": "PCU"
227 },
228 {
229 "BriefDescription": "Counts the number of cycles that the uncore transitioned to a frequency greater than or equal to 3Ghz. Derived from unc_p_freq_band2_cycles",
230 "Counter": "0,1,2,3",
231 "EventCode": "0xd",
232 "EventName": "UNC_P_FREQ_GE_3000MHZ_TRANSITIONS",
233 "Filter": "edge=1,filter_band2=4000",
234 "MetricExpr": "(UNC_P_FREQ_GE_3000MHZ_CYCLES / UNC_P_CLOCKTICKS) * 100.",
235 "PerPkg": "1",
236 "Unit": "PCU"
237 },
238 {
239 "BriefDescription": "Counts the number of cycles that the uncore transitioned to a frequency greater than or equal to 4Ghz. Derived from unc_p_freq_band3_cycles",
240 "Counter": "0,1,2,3",
241 "EventCode": "0xe",
242 "EventName": "UNC_P_FREQ_GE_4000MHZ_TRANSITIONS",
243 "Filter": "edge=1,filter_band3=4000",
244 "MetricExpr": "(UNC_P_FREQ_GE_4000MHZ_CYCLES / UNC_P_CLOCKTICKS) * 100.",
245 "PerPkg": "1",
246 "Unit": "PCU"
247 }
248]
diff --git a/tools/perf/pmu-events/arch/x86/knightslanding/uncore-memory.json b/tools/perf/pmu-events/arch/x86/knightslanding/uncore-memory.json
new file mode 100644
index 000000000000..e3bcd86c4f56
--- /dev/null
+++ b/tools/perf/pmu-events/arch/x86/knightslanding/uncore-memory.json
@@ -0,0 +1,42 @@
1[
2 {
3 "BriefDescription": "ddr bandwidth read (CPU traffic only) (MB/sec). ",
4 "Counter": "0,1,2,3",
5 "EventCode": "0x03",
6 "EventName": "UNC_M_CAS_COUNT.RD",
7 "PerPkg": "1",
8 "ScaleUnit": "6.4e-05MiB",
9 "UMask": "0x01",
10 "Unit": "imc"
11 },
12 {
13 "BriefDescription": "ddr bandwidth write (CPU traffic only) (MB/sec). ",
14 "Counter": "0,1,2,3",
15 "EventCode": "0x03",
16 "EventName": "UNC_M_CAS_COUNT.WR",
17 "PerPkg": "1",
18 "ScaleUnit": "6.4e-05MiB",
19 "UMask": "0x02",
20 "Unit": "imc"
21 },
22 {
23 "BriefDescription": "mcdram bandwidth read (CPU traffic only) (MB/sec). ",
24 "Counter": "0,1,2,3",
25 "EventCode": "0x01",
26 "EventName": "UNC_E_RPQ_INSERTS",
27 "PerPkg": "1",
28 "ScaleUnit": "6.4e-05MiB",
29 "UMask": "0x01",
30 "Unit": "edc_eclk"
31 },
32 {
33 "BriefDescription": "mcdram bandwidth write (CPU traffic only) (MB/sec). ",
34 "Counter": "0,1,2,3",
35 "EventCode": "0x02",
36 "EventName": "UNC_E_WPQ_INSERTS",
37 "PerPkg": "1",
38 "ScaleUnit": "6.4e-05MiB",
39 "UMask": "0x01",
40 "Unit": "edc_eclk"
41 }
42]
diff --git a/tools/perf/pmu-events/jevents.c b/tools/perf/pmu-events/jevents.c
index 41611d7f9873..eed09346a72a 100644
--- a/tools/perf/pmu-events/jevents.c
+++ b/tools/perf/pmu-events/jevents.c
@@ -135,7 +135,6 @@ static struct field {
135 const char *field; 135 const char *field;
136 const char *kernel; 136 const char *kernel;
137} fields[] = { 137} fields[] = {
138 { "EventCode", "event=" },
139 { "UMask", "umask=" }, 138 { "UMask", "umask=" },
140 { "CounterMask", "cmask=" }, 139 { "CounterMask", "cmask=" },
141 { "Invert", "inv=" }, 140 { "Invert", "inv=" },
@@ -189,6 +188,27 @@ static struct msrmap *lookup_msr(char *map, jsmntok_t *val)
189 return NULL; 188 return NULL;
190} 189}
191 190
191static struct map {
192 const char *json;
193 const char *perf;
194} unit_to_pmu[] = {
195 { "CBO", "uncore_cbox" },
196 { "QPI LL", "uncore_qpi" },
197 { "SBO", "uncore_sbox" },
198 {}
199};
200
201static const char *field_to_perf(struct map *table, char *map, jsmntok_t *val)
202{
203 int i;
204
205 for (i = 0; table[i].json; i++) {
206 if (json_streq(map, val, table[i].json))
207 return table[i].perf;
208 }
209 return NULL;
210}
211
192#define EXPECT(e, t, m) do { if (!(e)) { \ 212#define EXPECT(e, t, m) do { if (!(e)) { \
193 jsmntok_t *loc = (t); \ 213 jsmntok_t *loc = (t); \
194 if (!(t)->start && (t) > tokens) \ 214 if (!(t)->start && (t) > tokens) \
@@ -270,7 +290,8 @@ static void print_events_table_prefix(FILE *fp, const char *tblname)
270} 290}
271 291
272static int print_events_table_entry(void *data, char *name, char *event, 292static int print_events_table_entry(void *data, char *name, char *event,
273 char *desc, char *long_desc) 293 char *desc, char *long_desc,
294 char *pmu, char *unit, char *perpkg)
274{ 295{
275 struct perf_entry_data *pd = data; 296 struct perf_entry_data *pd = data;
276 FILE *outfp = pd->outfp; 297 FILE *outfp = pd->outfp;
@@ -288,7 +309,12 @@ static int print_events_table_entry(void *data, char *name, char *event,
288 fprintf(outfp, "\t.topic = \"%s\",\n", topic); 309 fprintf(outfp, "\t.topic = \"%s\",\n", topic);
289 if (long_desc && long_desc[0]) 310 if (long_desc && long_desc[0])
290 fprintf(outfp, "\t.long_desc = \"%s\",\n", long_desc); 311 fprintf(outfp, "\t.long_desc = \"%s\",\n", long_desc);
291 312 if (pmu)
313 fprintf(outfp, "\t.pmu = \"%s\",\n", pmu);
314 if (unit)
315 fprintf(outfp, "\t.unit = \"%s\",\n", unit);
316 if (perpkg)
317 fprintf(outfp, "\t.perpkg = \"%s\",\n", perpkg);
292 fprintf(outfp, "},\n"); 318 fprintf(outfp, "},\n");
293 319
294 return 0; 320 return 0;
@@ -335,7 +361,8 @@ static char *real_event(const char *name, char *event)
335/* Call func with each event in the json file */ 361/* Call func with each event in the json file */
336int json_events(const char *fn, 362int json_events(const char *fn,
337 int (*func)(void *data, char *name, char *event, char *desc, 363 int (*func)(void *data, char *name, char *event, char *desc,
338 char *long_desc), 364 char *long_desc,
365 char *pmu, char *unit, char *perpkg),
339 void *data) 366 void *data)
340{ 367{
341 int err = -EIO; 368 int err = -EIO;
@@ -343,6 +370,7 @@ int json_events(const char *fn,
343 jsmntok_t *tokens, *tok; 370 jsmntok_t *tokens, *tok;
344 int i, j, len; 371 int i, j, len;
345 char *map; 372 char *map;
373 char buf[128];
346 374
347 if (!fn) 375 if (!fn)
348 return -ENOENT; 376 return -ENOENT;
@@ -356,6 +384,11 @@ int json_events(const char *fn,
356 char *event = NULL, *desc = NULL, *name = NULL; 384 char *event = NULL, *desc = NULL, *name = NULL;
357 char *long_desc = NULL; 385 char *long_desc = NULL;
358 char *extra_desc = NULL; 386 char *extra_desc = NULL;
387 char *pmu = NULL;
388 char *filter = NULL;
389 char *perpkg = NULL;
390 char *unit = NULL;
391 unsigned long long eventcode = 0;
359 struct msrmap *msr = NULL; 392 struct msrmap *msr = NULL;
360 jsmntok_t *msrval = NULL; 393 jsmntok_t *msrval = NULL;
361 jsmntok_t *precise = NULL; 394 jsmntok_t *precise = NULL;
@@ -376,6 +409,16 @@ int json_events(const char *fn,
376 nz = !json_streq(map, val, "0"); 409 nz = !json_streq(map, val, "0");
377 if (match_field(map, field, nz, &event, val)) { 410 if (match_field(map, field, nz, &event, val)) {
378 /* ok */ 411 /* ok */
412 } else if (json_streq(map, field, "EventCode")) {
413 char *code = NULL;
414 addfield(map, &code, "", "", val);
415 eventcode |= strtoul(code, NULL, 0);
416 free(code);
417 } else if (json_streq(map, field, "ExtSel")) {
418 char *code = NULL;
419 addfield(map, &code, "", "", val);
420 eventcode |= strtoul(code, NULL, 0) << 21;
421 free(code);
379 } else if (json_streq(map, field, "EventName")) { 422 } else if (json_streq(map, field, "EventName")) {
380 addfield(map, &name, "", "", val); 423 addfield(map, &name, "", "", val);
381 } else if (json_streq(map, field, "BriefDescription")) { 424 } else if (json_streq(map, field, "BriefDescription")) {
@@ -399,6 +442,28 @@ int json_events(const char *fn,
399 addfield(map, &extra_desc, ". ", 442 addfield(map, &extra_desc, ". ",
400 " Supports address when precise", 443 " Supports address when precise",
401 NULL); 444 NULL);
445 } else if (json_streq(map, field, "Unit")) {
446 const char *ppmu;
447 char *s;
448
449 ppmu = field_to_perf(unit_to_pmu, map, val);
450 if (ppmu) {
451 pmu = strdup(ppmu);
452 } else {
453 if (!pmu)
454 pmu = strdup("uncore_");
455 addfield(map, &pmu, "", "", val);
456 for (s = pmu; *s; s++)
457 *s = tolower(*s);
458 }
459 addfield(map, &desc, ". ", "Unit: ", NULL);
460 addfield(map, &desc, "", pmu, NULL);
461 } else if (json_streq(map, field, "Filter")) {
462 addfield(map, &filter, "", "", val);
463 } else if (json_streq(map, field, "ScaleUnit")) {
464 addfield(map, &unit, "", "", val);
465 } else if (json_streq(map, field, "PerPkg")) {
466 addfield(map, &perpkg, "", "", val);
402 } 467 }
403 /* ignore unknown fields */ 468 /* ignore unknown fields */
404 } 469 }
@@ -410,20 +475,29 @@ int json_events(const char *fn,
410 addfield(map, &extra_desc, " ", 475 addfield(map, &extra_desc, " ",
411 "(Precise event)", NULL); 476 "(Precise event)", NULL);
412 } 477 }
478 snprintf(buf, sizeof buf, "event=%#llx", eventcode);
479 addfield(map, &event, ",", buf, NULL);
413 if (desc && extra_desc) 480 if (desc && extra_desc)
414 addfield(map, &desc, " ", extra_desc, NULL); 481 addfield(map, &desc, " ", extra_desc, NULL);
415 if (long_desc && extra_desc) 482 if (long_desc && extra_desc)
416 addfield(map, &long_desc, " ", extra_desc, NULL); 483 addfield(map, &long_desc, " ", extra_desc, NULL);
484 if (filter)
485 addfield(map, &event, ",", filter, NULL);
417 if (msr != NULL) 486 if (msr != NULL)
418 addfield(map, &event, ",", msr->pname, msrval); 487 addfield(map, &event, ",", msr->pname, msrval);
419 fixname(name); 488 fixname(name);
420 489
421 err = func(data, name, real_event(name, event), desc, long_desc); 490 err = func(data, name, real_event(name, event), desc, long_desc,
491 pmu, unit, perpkg);
422 free(event); 492 free(event);
423 free(desc); 493 free(desc);
424 free(name); 494 free(name);
425 free(long_desc); 495 free(long_desc);
426 free(extra_desc); 496 free(extra_desc);
497 free(pmu);
498 free(filter);
499 free(perpkg);
500 free(unit);
427 if (err) 501 if (err)
428 break; 502 break;
429 tok += j; 503 tok += j;
diff --git a/tools/perf/pmu-events/jevents.h b/tools/perf/pmu-events/jevents.h
index b0eb2744b498..71e13de31092 100644
--- a/tools/perf/pmu-events/jevents.h
+++ b/tools/perf/pmu-events/jevents.h
@@ -3,7 +3,9 @@
3 3
4int json_events(const char *fn, 4int json_events(const char *fn,
5 int (*func)(void *data, char *name, char *event, char *desc, 5 int (*func)(void *data, char *name, char *event, char *desc,
6 char *long_desc), 6 char *long_desc,
7 char *pmu,
8 char *unit, char *perpkg),
7 void *data); 9 void *data);
8char *get_cpu_str(void); 10char *get_cpu_str(void);
9 11
diff --git a/tools/perf/pmu-events/json.c b/tools/perf/pmu-events/json.c
index f67bbb0aa36e..0544398d6e2d 100644
--- a/tools/perf/pmu-events/json.c
+++ b/tools/perf/pmu-events/json.c
@@ -49,7 +49,7 @@ static char *mapfile(const char *fn, size_t *size)
49 int err; 49 int err;
50 int fd = open(fn, O_RDONLY); 50 int fd = open(fn, O_RDONLY);
51 51
52 if (fd < 0 && verbose && fn) { 52 if (fd < 0 && verbose > 0 && fn) {
53 pr_err("Error opening events file '%s': %s\n", fn, 53 pr_err("Error opening events file '%s': %s\n", fn,
54 strerror(errno)); 54 strerror(errno));
55 } 55 }
diff --git a/tools/perf/pmu-events/pmu-events.h b/tools/perf/pmu-events/pmu-events.h
index 2eaef595d8a0..c669a3cdb9f0 100644
--- a/tools/perf/pmu-events/pmu-events.h
+++ b/tools/perf/pmu-events/pmu-events.h
@@ -10,6 +10,9 @@ struct pmu_event {
10 const char *desc; 10 const char *desc;
11 const char *topic; 11 const char *topic;
12 const char *long_desc; 12 const char *long_desc;
13 const char *pmu;
14 const char *unit;
15 const char *perpkg;
13}; 16};
14 17
15/* 18/*
diff --git a/tools/perf/tests/Build b/tools/perf/tests/Build
index 6676c2dd6dcb..1cb3d9b540e9 100644
--- a/tools/perf/tests/Build
+++ b/tools/perf/tests/Build
@@ -44,6 +44,7 @@ perf-y += is_printable_array.o
44perf-y += bitmap.o 44perf-y += bitmap.o
45perf-y += perf-hooks.o 45perf-y += perf-hooks.o
46perf-y += clang.o 46perf-y += clang.o
47perf-y += unit_number__scnprintf.o
47 48
48$(OUTPUT)tests/llvm-src-base.c: tests/bpf-script-example.c tests/Build 49$(OUTPUT)tests/llvm-src-base.c: tests/bpf-script-example.c tests/Build
49 $(call rule_mkdir) 50 $(call rule_mkdir)
diff --git a/tools/perf/tests/attr.c b/tools/perf/tests/attr.c
index 28d1605b0338..88dc51f4c27b 100644
--- a/tools/perf/tests/attr.c
+++ b/tools/perf/tests/attr.c
@@ -144,7 +144,7 @@ static int run_dir(const char *d, const char *perf)
144 int vcnt = min(verbose, (int) sizeof(v) - 1); 144 int vcnt = min(verbose, (int) sizeof(v) - 1);
145 char cmd[3*PATH_MAX]; 145 char cmd[3*PATH_MAX];
146 146
147 if (verbose) 147 if (verbose > 0)
148 vcnt++; 148 vcnt++;
149 149
150 snprintf(cmd, 3*PATH_MAX, PYTHON " %s/attr.py -d %s/attr/ -p %s %.*s", 150 snprintf(cmd, 3*PATH_MAX, PYTHON " %s/attr.py -d %s/attr/ -p %s %.*s",
diff --git a/tools/perf/tests/bpf.c b/tools/perf/tests/bpf.c
index 92343f43e44a..1a04fe77487d 100644
--- a/tools/perf/tests/bpf.c
+++ b/tools/perf/tests/bpf.c
@@ -5,11 +5,13 @@
5#include <util/evlist.h> 5#include <util/evlist.h>
6#include <linux/bpf.h> 6#include <linux/bpf.h>
7#include <linux/filter.h> 7#include <linux/filter.h>
8#include <api/fs/fs.h>
8#include <bpf/bpf.h> 9#include <bpf/bpf.h>
9#include "tests.h" 10#include "tests.h"
10#include "llvm.h" 11#include "llvm.h"
11#include "debug.h" 12#include "debug.h"
12#define NR_ITERS 111 13#define NR_ITERS 111
14#define PERF_TEST_BPF_PATH "/sys/fs/bpf/perf_test"
13 15
14#ifdef HAVE_LIBBPF_SUPPORT 16#ifdef HAVE_LIBBPF_SUPPORT
15 17
@@ -54,6 +56,7 @@ static struct {
54 const char *msg_load_fail; 56 const char *msg_load_fail;
55 int (*target_func)(void); 57 int (*target_func)(void);
56 int expect_result; 58 int expect_result;
59 bool pin;
57} bpf_testcase_table[] = { 60} bpf_testcase_table[] = {
58 { 61 {
59 LLVM_TESTCASE_BASE, 62 LLVM_TESTCASE_BASE,
@@ -63,6 +66,17 @@ static struct {
63 "load bpf object failed", 66 "load bpf object failed",
64 &epoll_wait_loop, 67 &epoll_wait_loop,
65 (NR_ITERS + 1) / 2, 68 (NR_ITERS + 1) / 2,
69 false,
70 },
71 {
72 LLVM_TESTCASE_BASE,
73 "BPF pinning",
74 "[bpf_pinning]",
75 "fix kbuild first",
76 "check your vmlinux setting?",
77 &epoll_wait_loop,
78 (NR_ITERS + 1) / 2,
79 true,
66 }, 80 },
67#ifdef HAVE_BPF_PROLOGUE 81#ifdef HAVE_BPF_PROLOGUE
68 { 82 {
@@ -73,6 +87,7 @@ static struct {
73 "check your vmlinux setting?", 87 "check your vmlinux setting?",
74 &llseek_loop, 88 &llseek_loop,
75 (NR_ITERS + 1) / 4, 89 (NR_ITERS + 1) / 4,
90 false,
76 }, 91 },
77#endif 92#endif
78 { 93 {
@@ -83,6 +98,7 @@ static struct {
83 "libbpf error when dealing with relocation", 98 "libbpf error when dealing with relocation",
84 NULL, 99 NULL,
85 0, 100 0,
101 false,
86 }, 102 },
87}; 103};
88 104
@@ -226,10 +242,34 @@ static int __test__bpf(int idx)
226 goto out; 242 goto out;
227 } 243 }
228 244
229 if (obj) 245 if (obj) {
230 ret = do_test(obj, 246 ret = do_test(obj,
231 bpf_testcase_table[idx].target_func, 247 bpf_testcase_table[idx].target_func,
232 bpf_testcase_table[idx].expect_result); 248 bpf_testcase_table[idx].expect_result);
249 if (ret != TEST_OK)
250 goto out;
251 if (bpf_testcase_table[idx].pin) {
252 int err;
253
254 if (!bpf_fs__mount()) {
255 pr_debug("BPF filesystem not mounted\n");
256 ret = TEST_FAIL;
257 goto out;
258 }
259 err = mkdir(PERF_TEST_BPF_PATH, 0777);
260 if (err && errno != EEXIST) {
261 pr_debug("Failed to make perf_test dir: %s\n",
262 strerror(errno));
263 ret = TEST_FAIL;
264 goto out;
265 }
266 if (bpf_object__pin(obj, PERF_TEST_BPF_PATH))
267 ret = TEST_FAIL;
268 if (rm_rf(PERF_TEST_BPF_PATH))
269 ret = TEST_FAIL;
270 }
271 }
272
233out: 273out:
234 bpf__clear(); 274 bpf__clear();
235 return ret; 275 return ret;
diff --git a/tools/perf/tests/builtin-test.c b/tools/perf/tests/builtin-test.c
index a77dcc0d24e3..83c4669cbc5b 100644
--- a/tools/perf/tests/builtin-test.c
+++ b/tools/perf/tests/builtin-test.c
@@ -247,6 +247,10 @@ static struct test generic_tests[] = {
247 } 247 }
248 }, 248 },
249 { 249 {
250 .desc = "unit_number__scnprintf",
251 .func = test__unit_number__scnprint,
252 },
253 {
250 .func = NULL, 254 .func = NULL,
251 }, 255 },
252}; 256};
@@ -295,7 +299,7 @@ static int run_test(struct test *test, int subtest)
295 if (!dont_fork) { 299 if (!dont_fork) {
296 pr_debug("test child forked, pid %d\n", getpid()); 300 pr_debug("test child forked, pid %d\n", getpid());
297 301
298 if (!verbose) { 302 if (verbose <= 0) {
299 int nullfd = open("/dev/null", O_WRONLY); 303 int nullfd = open("/dev/null", O_WRONLY);
300 304
301 if (nullfd >= 0) { 305 if (nullfd >= 0) {
diff --git a/tools/perf/tests/code-reading.c b/tools/perf/tests/code-reading.c
index ff5bc6363a79..d1f693041324 100644
--- a/tools/perf/tests/code-reading.c
+++ b/tools/perf/tests/code-reading.c
@@ -599,7 +599,7 @@ static int do_test_code_reading(bool try_kcore)
599 continue; 599 continue;
600 } 600 }
601 601
602 if (verbose) { 602 if (verbose > 0) {
603 char errbuf[512]; 603 char errbuf[512];
604 perf_evlist__strerror_open(evlist, errno, errbuf, sizeof(errbuf)); 604 perf_evlist__strerror_open(evlist, errno, errbuf, sizeof(errbuf));
605 pr_debug("perf_evlist__open() failed!\n%s\n", errbuf); 605 pr_debug("perf_evlist__open() failed!\n%s\n", errbuf);
diff --git a/tools/perf/tests/fdarray.c b/tools/perf/tests/fdarray.c
index a2b5ff9bf83d..bc5982f42dc3 100644
--- a/tools/perf/tests/fdarray.c
+++ b/tools/perf/tests/fdarray.c
@@ -19,7 +19,7 @@ static int fdarray__fprintf_prefix(struct fdarray *fda, const char *prefix, FILE
19{ 19{
20 int printed = 0; 20 int printed = 0;
21 21
22 if (!verbose) 22 if (verbose <= 0)
23 return 0; 23 return 0;
24 24
25 printed += fprintf(fp, "\n%s: ", prefix); 25 printed += fprintf(fp, "\n%s: ", prefix);
diff --git a/tools/perf/tests/llvm.c b/tools/perf/tests/llvm.c
index 02a33ebcd992..482b5365e68d 100644
--- a/tools/perf/tests/llvm.c
+++ b/tools/perf/tests/llvm.c
@@ -13,7 +13,7 @@ static int test__bpf_parsing(void *obj_buf, size_t obj_buf_sz)
13 struct bpf_object *obj; 13 struct bpf_object *obj;
14 14
15 obj = bpf_object__open_buffer(obj_buf, obj_buf_sz, NULL); 15 obj = bpf_object__open_buffer(obj_buf, obj_buf_sz, NULL);
16 if (IS_ERR(obj)) 16 if (libbpf_get_error(obj))
17 return TEST_FAIL; 17 return TEST_FAIL;
18 bpf_object__close(obj); 18 bpf_object__close(obj);
19 return TEST_OK; 19 return TEST_OK;
@@ -76,7 +76,7 @@ test_llvm__fetch_bpf_obj(void **p_obj_buf,
76 * Skip this test if user's .perfconfig doesn't set [llvm] section 76 * Skip this test if user's .perfconfig doesn't set [llvm] section
77 * and clang is not found in $PATH, and this is not perf test -v 77 * and clang is not found in $PATH, and this is not perf test -v
78 */ 78 */
79 if (!force && (verbose == 0 && 79 if (!force && (verbose <= 0 &&
80 !llvm_param.user_set_param && 80 !llvm_param.user_set_param &&
81 llvm__search_clang())) { 81 llvm__search_clang())) {
82 pr_debug("No clang and no verbosive, skip this test\n"); 82 pr_debug("No clang and no verbosive, skip this test\n");
diff --git a/tools/perf/tests/parse-events.c b/tools/perf/tests/parse-events.c
index 20c2e641c422..1dc838014422 100644
--- a/tools/perf/tests/parse-events.c
+++ b/tools/perf/tests/parse-events.c
@@ -1779,15 +1779,14 @@ static int test_pmu_events(void)
1779 } 1779 }
1780 1780
1781 while (!ret && (ent = readdir(dir))) { 1781 while (!ret && (ent = readdir(dir))) {
1782#define MAX_NAME 100
1783 struct evlist_test e; 1782 struct evlist_test e;
1784 char name[MAX_NAME]; 1783 char name[2 * NAME_MAX + 1 + 12 + 3];
1785 1784
1786 /* Names containing . are special and cannot be used directly */ 1785 /* Names containing . are special and cannot be used directly */
1787 if (strchr(ent->d_name, '.')) 1786 if (strchr(ent->d_name, '.'))
1788 continue; 1787 continue;
1789 1788
1790 snprintf(name, MAX_NAME, "cpu/event=%s/u", ent->d_name); 1789 snprintf(name, sizeof(name), "cpu/event=%s/u", ent->d_name);
1791 1790
1792 e.name = name; 1791 e.name = name;
1793 e.check = test__checkevent_pmu_events; 1792 e.check = test__checkevent_pmu_events;
@@ -1795,11 +1794,10 @@ static int test_pmu_events(void)
1795 ret = test_event(&e); 1794 ret = test_event(&e);
1796 if (ret) 1795 if (ret)
1797 break; 1796 break;
1798 snprintf(name, MAX_NAME, "%s:u,cpu/event=%s/u", ent->d_name, ent->d_name); 1797 snprintf(name, sizeof(name), "%s:u,cpu/event=%s/u", ent->d_name, ent->d_name);
1799 e.name = name; 1798 e.name = name;
1800 e.check = test__checkevent_pmu_events_mix; 1799 e.check = test__checkevent_pmu_events_mix;
1801 ret = test_event(&e); 1800 ret = test_event(&e);
1802#undef MAX_NAME
1803 } 1801 }
1804 1802
1805 closedir(dir); 1803 closedir(dir);
@@ -1810,7 +1808,7 @@ static void debug_warn(const char *warn, va_list params)
1810{ 1808{
1811 char msg[1024]; 1809 char msg[1024];
1812 1810
1813 if (!verbose) 1811 if (verbose <= 0)
1814 return; 1812 return;
1815 1813
1816 vsnprintf(msg, sizeof(msg), warn, params); 1814 vsnprintf(msg, sizeof(msg), warn, params);
diff --git a/tools/perf/tests/parse-no-sample-id-all.c b/tools/perf/tests/parse-no-sample-id-all.c
index 81c6eeaca0f5..65dcf48a92fb 100644
--- a/tools/perf/tests/parse-no-sample-id-all.c
+++ b/tools/perf/tests/parse-no-sample-id-all.c
@@ -50,7 +50,8 @@ static int process_events(union perf_event **events, size_t count)
50} 50}
51 51
52struct test_attr_event { 52struct test_attr_event {
53 struct attr_event attr; 53 struct perf_event_header header;
54 struct perf_event_attr attr;
54 u64 id; 55 u64 id;
55}; 56};
56 57
@@ -71,20 +72,16 @@ int test__parse_no_sample_id_all(int subtest __maybe_unused)
71 int err; 72 int err;
72 73
73 struct test_attr_event event1 = { 74 struct test_attr_event event1 = {
74 .attr = { 75 .header = {
75 .header = { 76 .type = PERF_RECORD_HEADER_ATTR,
76 .type = PERF_RECORD_HEADER_ATTR, 77 .size = sizeof(struct test_attr_event),
77 .size = sizeof(struct test_attr_event),
78 },
79 }, 78 },
80 .id = 1, 79 .id = 1,
81 }; 80 };
82 struct test_attr_event event2 = { 81 struct test_attr_event event2 = {
83 .attr = { 82 .header = {
84 .header = { 83 .type = PERF_RECORD_HEADER_ATTR,
85 .type = PERF_RECORD_HEADER_ATTR, 84 .size = sizeof(struct test_attr_event),
86 .size = sizeof(struct test_attr_event),
87 },
88 }, 85 },
89 .id = 2, 86 .id = 2,
90 }; 87 };
diff --git a/tools/perf/tests/perf-record.c b/tools/perf/tests/perf-record.c
index 8f2e1de6d0ea..87893f3ba5f1 100644
--- a/tools/perf/tests/perf-record.c
+++ b/tools/perf/tests/perf-record.c
@@ -66,7 +66,7 @@ int test__PERF_RECORD(int subtest __maybe_unused)
66 if (evlist == NULL) /* Fallback for kernels lacking PERF_COUNT_SW_DUMMY */ 66 if (evlist == NULL) /* Fallback for kernels lacking PERF_COUNT_SW_DUMMY */
67 evlist = perf_evlist__new_default(); 67 evlist = perf_evlist__new_default();
68 68
69 if (evlist == NULL || argv == NULL) { 69 if (evlist == NULL) {
70 pr_debug("Not enough memory to create evlist\n"); 70 pr_debug("Not enough memory to create evlist\n");
71 goto out; 71 goto out;
72 } 72 }
@@ -172,13 +172,13 @@ int test__PERF_RECORD(int subtest __maybe_unused)
172 172
173 err = perf_evlist__parse_sample(evlist, event, &sample); 173 err = perf_evlist__parse_sample(evlist, event, &sample);
174 if (err < 0) { 174 if (err < 0) {
175 if (verbose) 175 if (verbose > 0)
176 perf_event__fprintf(event, stderr); 176 perf_event__fprintf(event, stderr);
177 pr_debug("Couldn't parse sample\n"); 177 pr_debug("Couldn't parse sample\n");
178 goto out_delete_evlist; 178 goto out_delete_evlist;
179 } 179 }
180 180
181 if (verbose) { 181 if (verbose > 0) {
182 pr_info("%" PRIu64" %d ", sample.time, sample.cpu); 182 pr_info("%" PRIu64" %d ", sample.time, sample.cpu);
183 perf_event__fprintf(event, stderr); 183 perf_event__fprintf(event, stderr);
184 } 184 }
diff --git a/tools/perf/tests/python-use.c b/tools/perf/tests/python-use.c
index 7a52834ee0d0..fa79509da535 100644
--- a/tools/perf/tests/python-use.c
+++ b/tools/perf/tests/python-use.c
@@ -15,7 +15,7 @@ int test__python_use(int subtest __maybe_unused)
15 int ret; 15 int ret;
16 16
17 if (asprintf(&cmd, "echo \"import sys ; sys.path.append('%s'); import perf\" | %s %s", 17 if (asprintf(&cmd, "echo \"import sys ; sys.path.append('%s'); import perf\" | %s %s",
18 PYTHONPATH, PYTHON, verbose ? "" : "2> /dev/null") < 0) 18 PYTHONPATH, PYTHON, verbose > 0 ? "" : "2> /dev/null") < 0)
19 return -1; 19 return -1;
20 20
21 ret = system(cmd) ? -1 : 0; 21 ret = system(cmd) ? -1 : 0;
diff --git a/tools/perf/tests/tests.h b/tools/perf/tests/tests.h
index a512f0c8ff5b..1fa9b9d83aa5 100644
--- a/tools/perf/tests/tests.h
+++ b/tools/perf/tests/tests.h
@@ -96,6 +96,7 @@ int test__perf_hooks(int subtest);
96int test__clang(int subtest); 96int test__clang(int subtest);
97const char *test__clang_subtest_get_desc(int subtest); 97const char *test__clang_subtest_get_desc(int subtest);
98int test__clang_subtest_get_nr(void); 98int test__clang_subtest_get_nr(void);
99int test__unit_number__scnprint(int subtest);
99 100
100#if defined(__arm__) || defined(__aarch64__) 101#if defined(__arm__) || defined(__aarch64__)
101#ifdef HAVE_DWARF_UNWIND_SUPPORT 102#ifdef HAVE_DWARF_UNWIND_SUPPORT
diff --git a/tools/perf/tests/thread-map.c b/tools/perf/tests/thread-map.c
index a4a4b4625ac3..f2d2e542d0ee 100644
--- a/tools/perf/tests/thread-map.c
+++ b/tools/perf/tests/thread-map.c
@@ -109,7 +109,7 @@ int test__thread_map_remove(int subtest __maybe_unused)
109 TEST_ASSERT_VAL("failed to allocate thread_map", 109 TEST_ASSERT_VAL("failed to allocate thread_map",
110 threads); 110 threads);
111 111
112 if (verbose) 112 if (verbose > 0)
113 thread_map__fprintf(threads, stderr); 113 thread_map__fprintf(threads, stderr);
114 114
115 TEST_ASSERT_VAL("failed to remove thread", 115 TEST_ASSERT_VAL("failed to remove thread",
@@ -117,7 +117,7 @@ int test__thread_map_remove(int subtest __maybe_unused)
117 117
118 TEST_ASSERT_VAL("thread_map count != 1", threads->nr == 1); 118 TEST_ASSERT_VAL("thread_map count != 1", threads->nr == 1);
119 119
120 if (verbose) 120 if (verbose > 0)
121 thread_map__fprintf(threads, stderr); 121 thread_map__fprintf(threads, stderr);
122 122
123 TEST_ASSERT_VAL("failed to remove thread", 123 TEST_ASSERT_VAL("failed to remove thread",
@@ -125,7 +125,7 @@ int test__thread_map_remove(int subtest __maybe_unused)
125 125
126 TEST_ASSERT_VAL("thread_map count != 0", threads->nr == 0); 126 TEST_ASSERT_VAL("thread_map count != 0", threads->nr == 0);
127 127
128 if (verbose) 128 if (verbose > 0)
129 thread_map__fprintf(threads, stderr); 129 thread_map__fprintf(threads, stderr);
130 130
131 TEST_ASSERT_VAL("failed to not remove thread", 131 TEST_ASSERT_VAL("failed to not remove thread",
diff --git a/tools/perf/tests/topology.c b/tools/perf/tests/topology.c
index 98fe69ac553c..803f893550d6 100644
--- a/tools/perf/tests/topology.c
+++ b/tools/perf/tests/topology.c
@@ -65,7 +65,9 @@ static int check_cpu_topology(char *path, struct cpu_map *map)
65 session = perf_session__new(&file, false, NULL); 65 session = perf_session__new(&file, false, NULL);
66 TEST_ASSERT_VAL("can't get session", session); 66 TEST_ASSERT_VAL("can't get session", session);
67 67
68 for (i = 0; i < session->header.env.nr_cpus_online; i++) { 68 for (i = 0; i < session->header.env.nr_cpus_avail; i++) {
69 if (!cpu_map__has(map, i))
70 continue;
69 pr_debug("CPU %d, core %d, socket %d\n", i, 71 pr_debug("CPU %d, core %d, socket %d\n", i,
70 session->header.env.cpu[i].core_id, 72 session->header.env.cpu[i].core_id,
71 session->header.env.cpu[i].socket_id); 73 session->header.env.cpu[i].socket_id);
diff --git a/tools/perf/tests/unit_number__scnprintf.c b/tools/perf/tests/unit_number__scnprintf.c
new file mode 100644
index 000000000000..623c2aa53c4a
--- /dev/null
+++ b/tools/perf/tests/unit_number__scnprintf.c
@@ -0,0 +1,37 @@
1#include <linux/compiler.h>
2#include <linux/types.h>
3#include "tests.h"
4#include "util.h"
5#include "debug.h"
6
7int test__unit_number__scnprint(int subtest __maybe_unused)
8{
9 struct {
10 u64 n;
11 const char *str;
12 } test[] = {
13 { 1, "1B" },
14 { 10*1024, "10K" },
15 { 20*1024*1024, "20M" },
16 { 30*1024*1024*1024ULL, "30G" },
17 { 0, "0B" },
18 { 0, NULL },
19 };
20 unsigned i = 0;
21
22 while (test[i].str) {
23 char buf[100];
24
25 unit_number__scnprintf(buf, sizeof(buf), test[i].n);
26
27 pr_debug("n %" PRIu64 ", str '%s', buf '%s'\n",
28 test[i].n, test[i].str, buf);
29
30 if (strcmp(test[i].str, buf))
31 return TEST_FAIL;
32
33 i++;
34 }
35
36 return TEST_OK;
37}
diff --git a/tools/perf/tests/vmlinux-kallsyms.c b/tools/perf/tests/vmlinux-kallsyms.c
index a5082331f246..862b043e5924 100644
--- a/tools/perf/tests/vmlinux-kallsyms.c
+++ b/tools/perf/tests/vmlinux-kallsyms.c
@@ -168,7 +168,7 @@ next_pair:
168 err = -1; 168 err = -1;
169 } 169 }
170 170
171 if (!verbose) 171 if (verbose <= 0)
172 goto out; 172 goto out;
173 173
174 header_printed = false; 174 header_printed = false;
diff --git a/tools/perf/ui/browsers/hists.c b/tools/perf/ui/browsers/hists.c
index 641b40234a9d..fc4fb669ceee 100644
--- a/tools/perf/ui/browsers/hists.c
+++ b/tools/perf/ui/browsers/hists.c
@@ -501,8 +501,8 @@ static int hierarchy_set_folding(struct hist_browser *hb, struct hist_entry *he,
501 return n; 501 return n;
502} 502}
503 503
504static void hist_entry__set_folding(struct hist_entry *he, 504static void __hist_entry__set_folding(struct hist_entry *he,
505 struct hist_browser *hb, bool unfold) 505 struct hist_browser *hb, bool unfold)
506{ 506{
507 hist_entry__init_have_children(he); 507 hist_entry__init_have_children(he);
508 he->unfolded = unfold ? he->has_children : false; 508 he->unfolded = unfold ? he->has_children : false;
@@ -520,12 +520,34 @@ static void hist_entry__set_folding(struct hist_entry *he,
520 he->nr_rows = 0; 520 he->nr_rows = 0;
521} 521}
522 522
523static void hist_entry__set_folding(struct hist_entry *he,
524 struct hist_browser *browser, bool unfold)
525{
526 double percent;
527
528 percent = hist_entry__get_percent_limit(he);
529 if (he->filtered || percent < browser->min_pcnt)
530 return;
531
532 __hist_entry__set_folding(he, browser, unfold);
533
534 if (!he->depth || unfold)
535 browser->nr_hierarchy_entries++;
536 if (he->leaf)
537 browser->nr_callchain_rows += he->nr_rows;
538 else if (unfold && !hist_entry__has_hierarchy_children(he, browser->min_pcnt)) {
539 browser->nr_hierarchy_entries++;
540 he->has_no_entry = true;
541 he->nr_rows = 1;
542 } else
543 he->has_no_entry = false;
544}
545
523static void 546static void
524__hist_browser__set_folding(struct hist_browser *browser, bool unfold) 547__hist_browser__set_folding(struct hist_browser *browser, bool unfold)
525{ 548{
526 struct rb_node *nd; 549 struct rb_node *nd;
527 struct hist_entry *he; 550 struct hist_entry *he;
528 double percent;
529 551
530 nd = rb_first(&browser->hists->entries); 552 nd = rb_first(&browser->hists->entries);
531 while (nd) { 553 while (nd) {
@@ -535,21 +557,6 @@ __hist_browser__set_folding(struct hist_browser *browser, bool unfold)
535 nd = __rb_hierarchy_next(nd, HMD_FORCE_CHILD); 557 nd = __rb_hierarchy_next(nd, HMD_FORCE_CHILD);
536 558
537 hist_entry__set_folding(he, browser, unfold); 559 hist_entry__set_folding(he, browser, unfold);
538
539 percent = hist_entry__get_percent_limit(he);
540 if (he->filtered || percent < browser->min_pcnt)
541 continue;
542
543 if (!he->depth || unfold)
544 browser->nr_hierarchy_entries++;
545 if (he->leaf)
546 browser->nr_callchain_rows += he->nr_rows;
547 else if (unfold && !hist_entry__has_hierarchy_children(he, browser->min_pcnt)) {
548 browser->nr_hierarchy_entries++;
549 he->has_no_entry = true;
550 he->nr_rows = 1;
551 } else
552 he->has_no_entry = false;
553 } 560 }
554} 561}
555 562
@@ -564,6 +571,15 @@ static void hist_browser__set_folding(struct hist_browser *browser, bool unfold)
564 ui_browser__reset_index(&browser->b); 571 ui_browser__reset_index(&browser->b);
565} 572}
566 573
574static void hist_browser__set_folding_selected(struct hist_browser *browser, bool unfold)
575{
576 if (!browser->he_selection)
577 return;
578
579 hist_entry__set_folding(browser->he_selection, browser, unfold);
580 browser->b.nr_entries = hist_browser__nr_entries(browser);
581}
582
567static void ui_browser__warn_lost_events(struct ui_browser *browser) 583static void ui_browser__warn_lost_events(struct ui_browser *browser)
568{ 584{
569 ui_browser__warning(browser, 4, 585 ui_browser__warning(browser, 4,
@@ -637,10 +653,18 @@ int hist_browser__run(struct hist_browser *browser, const char *help)
637 /* Collapse the whole world. */ 653 /* Collapse the whole world. */
638 hist_browser__set_folding(browser, false); 654 hist_browser__set_folding(browser, false);
639 break; 655 break;
656 case 'c':
657 /* Collapse the selected entry. */
658 hist_browser__set_folding_selected(browser, false);
659 break;
640 case 'E': 660 case 'E':
641 /* Expand the whole world. */ 661 /* Expand the whole world. */
642 hist_browser__set_folding(browser, true); 662 hist_browser__set_folding(browser, true);
643 break; 663 break;
664 case 'e':
665 /* Expand the selected entry. */
666 hist_browser__set_folding_selected(browser, true);
667 break;
644 case 'H': 668 case 'H':
645 browser->show_headers = !browser->show_headers; 669 browser->show_headers = !browser->show_headers;
646 hist_browser__update_rows(browser); 670 hist_browser__update_rows(browser);
diff --git a/tools/perf/ui/browsers/map.c b/tools/perf/ui/browsers/map.c
index 98a34664bb7e..9ce142de536d 100644
--- a/tools/perf/ui/browsers/map.c
+++ b/tools/perf/ui/browsers/map.c
@@ -73,7 +73,7 @@ static int map_browser__run(struct map_browser *browser)
73 73
74 if (ui_browser__show(&browser->b, browser->map->dso->long_name, 74 if (ui_browser__show(&browser->b, browser->map->dso->long_name,
75 "Press ESC to exit, %s / to search", 75 "Press ESC to exit, %s / to search",
76 verbose ? "" : "restart with -v to use") < 0) 76 verbose > 0 ? "" : "restart with -v to use") < 0)
77 return -1; 77 return -1;
78 78
79 while (1) { 79 while (1) {
@@ -81,7 +81,7 @@ static int map_browser__run(struct map_browser *browser)
81 81
82 switch (key) { 82 switch (key) {
83 case '/': 83 case '/':
84 if (verbose) 84 if (verbose > 0)
85 map_browser__search(browser); 85 map_browser__search(browser);
86 default: 86 default:
87 break; 87 break;
@@ -117,7 +117,7 @@ int map__browse(struct map *map)
117 117
118 if (maxaddr < pos->end) 118 if (maxaddr < pos->end)
119 maxaddr = pos->end; 119 maxaddr = pos->end;
120 if (verbose) { 120 if (verbose > 0) {
121 u32 *idx = symbol__browser_index(pos); 121 u32 *idx = symbol__browser_index(pos);
122 *idx = mb.b.nr_entries; 122 *idx = mb.b.nr_entries;
123 } 123 }
diff --git a/tools/perf/ui/hist.c b/tools/perf/ui/hist.c
index 18cfcdc90356..5d632dca672a 100644
--- a/tools/perf/ui/hist.c
+++ b/tools/perf/ui/hist.c
@@ -648,7 +648,7 @@ unsigned int hists__sort_list_width(struct hists *hists)
648 ret += fmt->width(fmt, &dummy_hpp, hists); 648 ret += fmt->width(fmt, &dummy_hpp, hists);
649 } 649 }
650 650
651 if (verbose && hists__has(hists, sym)) /* Addr + origin */ 651 if (verbose > 0 && hists__has(hists, sym)) /* Addr + origin */
652 ret += 3 + BITS_PER_LONG / 4; 652 ret += 3 + BITS_PER_LONG / 4;
653 653
654 return ret; 654 return ret;
diff --git a/tools/perf/ui/setup.c b/tools/perf/ui/setup.c
index 1f6b0994f4f4..50d13e58210f 100644
--- a/tools/perf/ui/setup.c
+++ b/tools/perf/ui/setup.c
@@ -7,6 +7,7 @@
7 7
8pthread_mutex_t ui__lock = PTHREAD_MUTEX_INITIALIZER; 8pthread_mutex_t ui__lock = PTHREAD_MUTEX_INITIALIZER;
9void *perf_gtk_handle; 9void *perf_gtk_handle;
10int use_browser = -1;
10 11
11#ifdef HAVE_GTK2_SUPPORT 12#ifdef HAVE_GTK2_SUPPORT
12static int setup_gtk_browser(void) 13static int setup_gtk_browser(void)
diff --git a/tools/perf/util/Build b/tools/perf/util/Build
index 3840e3a87057..5da376bc1afc 100644
--- a/tools/perf/util/Build
+++ b/tools/perf/util/Build
@@ -162,6 +162,7 @@ CFLAGS_rbtree.o += -Wno-unused-parameter -DETC_PERFCONFIG="BUILD_STR($(ET
162CFLAGS_libstring.o += -Wno-unused-parameter -DETC_PERFCONFIG="BUILD_STR($(ETC_PERFCONFIG_SQ))" 162CFLAGS_libstring.o += -Wno-unused-parameter -DETC_PERFCONFIG="BUILD_STR($(ETC_PERFCONFIG_SQ))"
163CFLAGS_hweight.o += -Wno-unused-parameter -DETC_PERFCONFIG="BUILD_STR($(ETC_PERFCONFIG_SQ))" 163CFLAGS_hweight.o += -Wno-unused-parameter -DETC_PERFCONFIG="BUILD_STR($(ETC_PERFCONFIG_SQ))"
164CFLAGS_parse-events.o += -Wno-redundant-decls 164CFLAGS_parse-events.o += -Wno-redundant-decls
165CFLAGS_header.o += -include $(OUTPUT)PERF-VERSION-FILE
165 166
166$(OUTPUT)util/kallsyms.o: ../lib/symbol/kallsyms.c FORCE 167$(OUTPUT)util/kallsyms.o: ../lib/symbol/kallsyms.c FORCE
167 $(call rule_mkdir) 168 $(call rule_mkdir)
diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c
index 06cc04e5806a..273f21fa32b5 100644
--- a/tools/perf/util/annotate.c
+++ b/tools/perf/util/annotate.c
@@ -1768,7 +1768,7 @@ int symbol__annotate_printf(struct symbol *sym, struct map *map,
1768 printf("%-*.*s----\n", 1768 printf("%-*.*s----\n",
1769 graph_dotted_len, graph_dotted_len, graph_dotted_line); 1769 graph_dotted_len, graph_dotted_len, graph_dotted_line);
1770 1770
1771 if (verbose) 1771 if (verbose > 0)
1772 symbol__annotate_hits(sym, evsel); 1772 symbol__annotate_hits(sym, evsel);
1773 1773
1774 list_for_each_entry(pos, &notes->src->source, node) { 1774 list_for_each_entry(pos, &notes->src->source, node) {
diff --git a/tools/perf/util/bpf-loader.c b/tools/perf/util/bpf-loader.c
index 36c861103291..bc6bc7062eb4 100644
--- a/tools/perf/util/bpf-loader.c
+++ b/tools/perf/util/bpf-loader.c
@@ -670,13 +670,13 @@ int bpf__probe(struct bpf_object *obj)
670 670
671 err = convert_perf_probe_events(pev, 1); 671 err = convert_perf_probe_events(pev, 1);
672 if (err < 0) { 672 if (err < 0) {
673 pr_debug("bpf_probe: failed to convert perf probe events"); 673 pr_debug("bpf_probe: failed to convert perf probe events\n");
674 goto out; 674 goto out;
675 } 675 }
676 676
677 err = apply_perf_probe_events(pev, 1); 677 err = apply_perf_probe_events(pev, 1);
678 if (err < 0) { 678 if (err < 0) {
679 pr_debug("bpf_probe: failed to apply perf probe events"); 679 pr_debug("bpf_probe: failed to apply perf probe events\n");
680 goto out; 680 goto out;
681 } 681 }
682 682
diff --git a/tools/perf/util/callchain.c b/tools/perf/util/callchain.c
index 8b610dd9e2f6..aba953421a03 100644
--- a/tools/perf/util/callchain.c
+++ b/tools/perf/util/callchain.c
@@ -48,6 +48,8 @@ static int parse_callchain_mode(const char *value)
48 callchain_param.mode = CHAIN_FOLDED; 48 callchain_param.mode = CHAIN_FOLDED;
49 return 0; 49 return 0;
50 } 50 }
51
52 pr_err("Invalid callchain mode: %s\n", value);
51 return -1; 53 return -1;
52} 54}
53 55
@@ -63,6 +65,8 @@ static int parse_callchain_order(const char *value)
63 callchain_param.order_set = true; 65 callchain_param.order_set = true;
64 return 0; 66 return 0;
65 } 67 }
68
69 pr_err("Invalid callchain order: %s\n", value);
66 return -1; 70 return -1;
67} 71}
68 72
@@ -80,6 +84,8 @@ static int parse_callchain_sort_key(const char *value)
80 callchain_param.branch_callstack = 1; 84 callchain_param.branch_callstack = 1;
81 return 0; 85 return 0;
82 } 86 }
87
88 pr_err("Invalid callchain sort key: %s\n", value);
83 return -1; 89 return -1;
84} 90}
85 91
@@ -97,6 +103,8 @@ static int parse_callchain_value(const char *value)
97 callchain_param.value = CCVAL_COUNT; 103 callchain_param.value = CCVAL_COUNT;
98 return 0; 104 return 0;
99 } 105 }
106
107 pr_err("Invalid callchain config key: %s\n", value);
100 return -1; 108 return -1;
101} 109}
102 110
@@ -210,13 +218,17 @@ int perf_callchain_config(const char *var, const char *value)
210 return parse_callchain_sort_key(value); 218 return parse_callchain_sort_key(value);
211 if (!strcmp(var, "threshold")) { 219 if (!strcmp(var, "threshold")) {
212 callchain_param.min_percent = strtod(value, &endptr); 220 callchain_param.min_percent = strtod(value, &endptr);
213 if (value == endptr) 221 if (value == endptr) {
222 pr_err("Invalid callchain threshold: %s\n", value);
214 return -1; 223 return -1;
224 }
215 } 225 }
216 if (!strcmp(var, "print-limit")) { 226 if (!strcmp(var, "print-limit")) {
217 callchain_param.print_limit = strtod(value, &endptr); 227 callchain_param.print_limit = strtod(value, &endptr);
218 if (value == endptr) 228 if (value == endptr) {
229 pr_err("Invalid callchain print limit: %s\n", value);
219 return -1; 230 return -1;
231 }
220 } 232 }
221 233
222 return 0; 234 return 0;
diff --git a/tools/perf/util/cgroup.c b/tools/perf/util/cgroup.c
index 8fdee24725a7..eafbf11442b2 100644
--- a/tools/perf/util/cgroup.c
+++ b/tools/perf/util/cgroup.c
@@ -12,8 +12,8 @@ cgroupfs_find_mountpoint(char *buf, size_t maxlen)
12{ 12{
13 FILE *fp; 13 FILE *fp;
14 char mountpoint[PATH_MAX + 1], tokens[PATH_MAX + 1], type[PATH_MAX + 1]; 14 char mountpoint[PATH_MAX + 1], tokens[PATH_MAX + 1], type[PATH_MAX + 1];
15 char path_v1[PATH_MAX + 1], path_v2[PATH_MAX + 2], *path;
15 char *token, *saved_ptr = NULL; 16 char *token, *saved_ptr = NULL;
16 int found = 0;
17 17
18 fp = fopen("/proc/mounts", "r"); 18 fp = fopen("/proc/mounts", "r");
19 if (!fp) 19 if (!fp)
@@ -24,31 +24,43 @@ cgroupfs_find_mountpoint(char *buf, size_t maxlen)
24 * and inspect every cgroupfs mount point to find one that has 24 * and inspect every cgroupfs mount point to find one that has
25 * perf_event subsystem 25 * perf_event subsystem
26 */ 26 */
27 path_v1[0] = '\0';
28 path_v2[0] = '\0';
29
27 while (fscanf(fp, "%*s %"STR(PATH_MAX)"s %"STR(PATH_MAX)"s %" 30 while (fscanf(fp, "%*s %"STR(PATH_MAX)"s %"STR(PATH_MAX)"s %"
28 STR(PATH_MAX)"s %*d %*d\n", 31 STR(PATH_MAX)"s %*d %*d\n",
29 mountpoint, type, tokens) == 3) { 32 mountpoint, type, tokens) == 3) {
30 33
31 if (!strcmp(type, "cgroup")) { 34 if (!path_v1[0] && !strcmp(type, "cgroup")) {
32 35
33 token = strtok_r(tokens, ",", &saved_ptr); 36 token = strtok_r(tokens, ",", &saved_ptr);
34 37
35 while (token != NULL) { 38 while (token != NULL) {
36 if (!strcmp(token, "perf_event")) { 39 if (!strcmp(token, "perf_event")) {
37 found = 1; 40 strcpy(path_v1, mountpoint);
38 break; 41 break;
39 } 42 }
40 token = strtok_r(NULL, ",", &saved_ptr); 43 token = strtok_r(NULL, ",", &saved_ptr);
41 } 44 }
42 } 45 }
43 if (found) 46
47 if (!path_v2[0] && !strcmp(type, "cgroup2"))
48 strcpy(path_v2, mountpoint);
49
50 if (path_v1[0] && path_v2[0])
44 break; 51 break;
45 } 52 }
46 fclose(fp); 53 fclose(fp);
47 if (!found) 54
55 if (path_v1[0])
56 path = path_v1;
57 else if (path_v2[0])
58 path = path_v2;
59 else
48 return -1; 60 return -1;
49 61
50 if (strlen(mountpoint) < maxlen) { 62 if (strlen(path) < maxlen) {
51 strcpy(buf, mountpoint); 63 strcpy(buf, path);
52 return 0; 64 return 0;
53 } 65 }
54 return -1; 66 return -1;
diff --git a/tools/perf/util/config.c b/tools/perf/util/config.c
index 3d906dbbef74..0c7d5a4975cd 100644
--- a/tools/perf/util/config.c
+++ b/tools/perf/util/config.c
@@ -386,8 +386,10 @@ static int perf_buildid_config(const char *var, const char *value)
386 if (!strcmp(var, "buildid.dir")) { 386 if (!strcmp(var, "buildid.dir")) {
387 const char *dir = perf_config_dirname(var, value); 387 const char *dir = perf_config_dirname(var, value);
388 388
389 if (!dir) 389 if (!dir) {
390 pr_err("Invalid buildid directory!\n");
390 return -1; 391 return -1;
392 }
391 strncpy(buildid_dir, dir, MAXPATHLEN-1); 393 strncpy(buildid_dir, dir, MAXPATHLEN-1);
392 buildid_dir[MAXPATHLEN-1] = '\0'; 394 buildid_dir[MAXPATHLEN-1] = '\0';
393 } 395 }
@@ -405,10 +407,9 @@ static int perf_default_core_config(const char *var __maybe_unused,
405static int perf_ui_config(const char *var, const char *value) 407static int perf_ui_config(const char *var, const char *value)
406{ 408{
407 /* Add other config variables here. */ 409 /* Add other config variables here. */
408 if (!strcmp(var, "ui.show-headers")) { 410 if (!strcmp(var, "ui.show-headers"))
409 symbol_conf.show_hist_headers = perf_config_bool(var, value); 411 symbol_conf.show_hist_headers = perf_config_bool(var, value);
410 return 0; 412
411 }
412 return 0; 413 return 0;
413} 414}
414 415
@@ -646,8 +647,13 @@ static int perf_config_set__init(struct perf_config_set *set)
646 goto out; 647 goto out;
647 } 648 }
648 649
649 if (stat(user_config, &st) < 0) 650 if (stat(user_config, &st) < 0) {
651 if (errno == ENOENT)
652 ret = 0;
650 goto out_free; 653 goto out_free;
654 }
655
656 ret = 0;
651 657
652 if (st.st_uid && (st.st_uid != geteuid())) { 658 if (st.st_uid && (st.st_uid != geteuid())) {
653 warning("File %s not owned by current user or root, " 659 warning("File %s not owned by current user or root, "
@@ -655,11 +661,8 @@ static int perf_config_set__init(struct perf_config_set *set)
655 goto out_free; 661 goto out_free;
656 } 662 }
657 663
658 if (!st.st_size) 664 if (st.st_size)
659 goto out_free; 665 ret = perf_config_from_file(collect_config, user_config, set);
660
661 ret = perf_config_from_file(collect_config, user_config, set);
662
663out_free: 666out_free:
664 free(user_config); 667 free(user_config);
665 } 668 }
diff --git a/tools/perf/util/cpumap.c b/tools/perf/util/cpumap.c
index 2c0b52264a46..8c7504939113 100644
--- a/tools/perf/util/cpumap.c
+++ b/tools/perf/util/cpumap.c
@@ -9,6 +9,7 @@
9#include "asm/bug.h" 9#include "asm/bug.h"
10 10
11static int max_cpu_num; 11static int max_cpu_num;
12static int max_present_cpu_num;
12static int max_node_num; 13static int max_node_num;
13static int *cpunode_map; 14static int *cpunode_map;
14 15
@@ -442,6 +443,7 @@ static void set_max_cpu_num(void)
442 443
443 /* set up default */ 444 /* set up default */
444 max_cpu_num = 4096; 445 max_cpu_num = 4096;
446 max_present_cpu_num = 4096;
445 447
446 mnt = sysfs__mountpoint(); 448 mnt = sysfs__mountpoint();
447 if (!mnt) 449 if (!mnt)
@@ -455,6 +457,17 @@ static void set_max_cpu_num(void)
455 } 457 }
456 458
457 ret = get_max_num(path, &max_cpu_num); 459 ret = get_max_num(path, &max_cpu_num);
460 if (ret)
461 goto out;
462
463 /* get the highest present cpu number for a sparse allocation */
464 ret = snprintf(path, PATH_MAX, "%s/devices/system/cpu/present", mnt);
465 if (ret == PATH_MAX) {
466 pr_err("sysfs path crossed PATH_MAX(%d) size\n", PATH_MAX);
467 goto out;
468 }
469
470 ret = get_max_num(path, &max_present_cpu_num);
458 471
459out: 472out:
460 if (ret) 473 if (ret)
@@ -505,6 +518,15 @@ int cpu__max_cpu(void)
505 return max_cpu_num; 518 return max_cpu_num;
506} 519}
507 520
521int cpu__max_present_cpu(void)
522{
523 if (unlikely(!max_present_cpu_num))
524 set_max_cpu_num();
525
526 return max_present_cpu_num;
527}
528
529
508int cpu__get_node(int cpu) 530int cpu__get_node(int cpu)
509{ 531{
510 if (unlikely(cpunode_map == NULL)) { 532 if (unlikely(cpunode_map == NULL)) {
diff --git a/tools/perf/util/cpumap.h b/tools/perf/util/cpumap.h
index 06bd689f5989..1a0549af8f5c 100644
--- a/tools/perf/util/cpumap.h
+++ b/tools/perf/util/cpumap.h
@@ -62,6 +62,7 @@ int cpu__setup_cpunode_map(void);
62 62
63int cpu__max_node(void); 63int cpu__max_node(void);
64int cpu__max_cpu(void); 64int cpu__max_cpu(void);
65int cpu__max_present_cpu(void);
65int cpu__get_node(int cpu); 66int cpu__get_node(int cpu);
66 67
67int cpu_map__build_map(struct cpu_map *cpus, struct cpu_map **res, 68int cpu_map__build_map(struct cpu_map *cpus, struct cpu_map **res,
diff --git a/tools/perf/util/data-convert-bt.c b/tools/perf/util/data-convert-bt.c
index 7123f4de32cc..4e6cbc99f08e 100644
--- a/tools/perf/util/data-convert-bt.c
+++ b/tools/perf/util/data-convert-bt.c
@@ -1473,7 +1473,7 @@ int bt_convert__perf2ctf(const char *input, const char *path,
1473 }, 1473 },
1474 }; 1474 };
1475 struct ctf_writer *cw = &c.writer; 1475 struct ctf_writer *cw = &c.writer;
1476 int err = -1; 1476 int err;
1477 1477
1478 if (opts->all) { 1478 if (opts->all) {
1479 c.tool.comm = process_comm_event; 1479 c.tool.comm = process_comm_event;
@@ -1481,12 +1481,15 @@ int bt_convert__perf2ctf(const char *input, const char *path,
1481 c.tool.fork = process_fork_event; 1481 c.tool.fork = process_fork_event;
1482 } 1482 }
1483 1483
1484 perf_config(convert__config, &c); 1484 err = perf_config(convert__config, &c);
1485 if (err)
1486 return err;
1485 1487
1486 /* CTF writer */ 1488 /* CTF writer */
1487 if (ctf_writer__init(cw, path)) 1489 if (ctf_writer__init(cw, path))
1488 return -1; 1490 return -1;
1489 1491
1492 err = -1;
1490 /* perf.data session */ 1493 /* perf.data session */
1491 session = perf_session__new(&file, 0, &c.tool); 1494 session = perf_session__new(&file, 0, &c.tool);
1492 if (!session) 1495 if (!session)
diff --git a/tools/perf/util/debug.c b/tools/perf/util/debug.c
index c1838b643108..03eb81f30d0d 100644
--- a/tools/perf/util/debug.c
+++ b/tools/perf/util/debug.c
@@ -203,11 +203,28 @@ int perf_debug_option(const char *str)
203 v = (v < 0) || (v > 10) ? 0 : v; 203 v = (v < 0) || (v > 10) ? 0 : v;
204 } 204 }
205 205
206 if (quiet)
207 v = -1;
208
206 *var->ptr = v; 209 *var->ptr = v;
207 free(s); 210 free(s);
208 return 0; 211 return 0;
209} 212}
210 213
214int perf_quiet_option(void)
215{
216 struct debug_variable *var = &debug_variables[0];
217
218 /* disable all debug messages */
219 while (var->name) {
220 *var->ptr = -1;
221 var++;
222 }
223
224 quiet = true;
225 return 0;
226}
227
211#define DEBUG_WRAPPER(__n, __l) \ 228#define DEBUG_WRAPPER(__n, __l) \
212static int pr_ ## __n ## _wrapper(const char *fmt, ...) \ 229static int pr_ ## __n ## _wrapper(const char *fmt, ...) \
213{ \ 230{ \
diff --git a/tools/perf/util/debug.h b/tools/perf/util/debug.h
index d242adc3d5a2..98832f5531d3 100644
--- a/tools/perf/util/debug.h
+++ b/tools/perf/util/debug.h
@@ -54,5 +54,6 @@ int veprintf(int level, int var, const char *fmt, va_list args);
54 54
55int perf_debug_option(const char *str); 55int perf_debug_option(const char *str);
56void perf_debug_setup(void); 56void perf_debug_setup(void);
57int perf_quiet_option(void);
57 58
58#endif /* __PERF_DEBUG_H */ 59#endif /* __PERF_DEBUG_H */
diff --git a/tools/perf/util/dso.c b/tools/perf/util/dso.c
index d2c6cdd9d42b..d38b62a700ca 100644
--- a/tools/perf/util/dso.c
+++ b/tools/perf/util/dso.c
@@ -9,6 +9,13 @@
9#include "debug.h" 9#include "debug.h"
10#include "vdso.h" 10#include "vdso.h"
11 11
12static const char * const debuglink_paths[] = {
13 "%.0s%s",
14 "%s/%s",
15 "%s/.debug/%s",
16 "/usr/lib/debug%s/%s"
17};
18
12char dso__symtab_origin(const struct dso *dso) 19char dso__symtab_origin(const struct dso *dso)
13{ 20{
14 static const char origin[] = { 21 static const char origin[] = {
@@ -44,24 +51,43 @@ int dso__read_binary_type_filename(const struct dso *dso,
44 size_t len; 51 size_t len;
45 52
46 switch (type) { 53 switch (type) {
47 case DSO_BINARY_TYPE__DEBUGLINK: { 54 case DSO_BINARY_TYPE__DEBUGLINK:
48 char *debuglink; 55 {
56 const char *last_slash;
57 char dso_dir[PATH_MAX];
58 char symfile[PATH_MAX];
59 unsigned int i;
49 60
50 len = __symbol__join_symfs(filename, size, dso->long_name); 61 len = __symbol__join_symfs(filename, size, dso->long_name);
51 debuglink = filename + len; 62 last_slash = filename + len;
52 while (debuglink != filename && *debuglink != '/') 63 while (last_slash != filename && *last_slash != '/')
53 debuglink--; 64 last_slash--;
54 if (*debuglink == '/')
55 debuglink++;
56 65
57 ret = -1; 66 strncpy(dso_dir, filename, last_slash - filename);
58 if (!is_regular_file(filename)) 67 dso_dir[last_slash-filename] = '\0';
68
69 if (!is_regular_file(filename)) {
70 ret = -1;
71 break;
72 }
73
74 ret = filename__read_debuglink(filename, symfile, PATH_MAX);
75 if (ret)
59 break; 76 break;
60 77
61 ret = filename__read_debuglink(filename, debuglink, 78 /* Check predefined locations where debug file might reside */
62 size - (debuglink - filename)); 79 ret = -1;
80 for (i = 0; i < ARRAY_SIZE(debuglink_paths); i++) {
81 snprintf(filename, size,
82 debuglink_paths[i], dso_dir, symfile);
83 if (is_regular_file(filename)) {
84 ret = 0;
85 break;
86 }
63 } 87 }
88
64 break; 89 break;
90 }
65 case DSO_BINARY_TYPE__BUILD_ID_CACHE: 91 case DSO_BINARY_TYPE__BUILD_ID_CACHE:
66 if (dso__build_id_filename(dso, filename, size) == NULL) 92 if (dso__build_id_filename(dso, filename, size) == NULL)
67 ret = -1; 93 ret = -1;
@@ -925,7 +951,7 @@ static struct dso *__dso__findlink_by_longname(struct rb_root *root,
925 if (rc == 0) { 951 if (rc == 0) {
926 /* 952 /*
927 * In case the new DSO is a duplicate of an existing 953 * In case the new DSO is a duplicate of an existing
928 * one, print an one-time warning & put the new entry 954 * one, print a one-time warning & put the new entry
929 * at the end of the list of duplicates. 955 * at the end of the list of duplicates.
930 */ 956 */
931 if (!dso || (dso == this)) 957 if (!dso || (dso == this))
@@ -1032,7 +1058,7 @@ int dso__name_len(const struct dso *dso)
1032{ 1058{
1033 if (!dso) 1059 if (!dso)
1034 return strlen("[unknown]"); 1060 return strlen("[unknown]");
1035 if (verbose) 1061 if (verbose > 0)
1036 return dso->long_name_len; 1062 return dso->long_name_len;
1037 1063
1038 return dso->short_name_len; 1064 return dso->short_name_len;
diff --git a/tools/perf/util/env.c b/tools/perf/util/env.c
index bb964e86b09d..075fc77286bf 100644
--- a/tools/perf/util/env.c
+++ b/tools/perf/util/env.c
@@ -66,7 +66,7 @@ int perf_env__read_cpu_topology_map(struct perf_env *env)
66 return 0; 66 return 0;
67 67
68 if (env->nr_cpus_avail == 0) 68 if (env->nr_cpus_avail == 0)
69 env->nr_cpus_avail = sysconf(_SC_NPROCESSORS_CONF); 69 env->nr_cpus_avail = cpu__max_present_cpu();
70 70
71 nr_cpus = env->nr_cpus_avail; 71 nr_cpus = env->nr_cpus_avail;
72 if (nr_cpus == -1) 72 if (nr_cpus == -1)
diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c
index 8ab0d7da956b..4ea7ce72ed9c 100644
--- a/tools/perf/util/event.c
+++ b/tools/perf/util/event.c
@@ -1,5 +1,5 @@
1#include <linux/types.h> 1#include <linux/types.h>
2#include <uapi/linux/mman.h> /* To get things like MAP_HUGETLB even on older libc headers */ 2#include <linux/mman.h> /* To get things like MAP_HUGETLB even on older libc headers */
3#include <api/fs/fs.h> 3#include <api/fs/fs.h>
4#include "event.h" 4#include "event.h"
5#include "debug.h" 5#include "debug.h"
diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c
index d92e02006fb8..b601f2814a30 100644
--- a/tools/perf/util/evlist.c
+++ b/tools/perf/util/evlist.c
@@ -1184,7 +1184,7 @@ unsigned long perf_event_mlock_kb_in_pages(void)
1184 return pages; 1184 return pages;
1185} 1185}
1186 1186
1187static size_t perf_evlist__mmap_size(unsigned long pages) 1187size_t perf_evlist__mmap_size(unsigned long pages)
1188{ 1188{
1189 if (pages == UINT_MAX) 1189 if (pages == UINT_MAX)
1190 pages = perf_event_mlock_kb_in_pages(); 1190 pages = perf_event_mlock_kb_in_pages();
@@ -1224,12 +1224,16 @@ static long parse_pages_arg(const char *str, unsigned long min,
1224 if (pages == 0 && min == 0) { 1224 if (pages == 0 && min == 0) {
1225 /* leave number of pages at 0 */ 1225 /* leave number of pages at 0 */
1226 } else if (!is_power_of_2(pages)) { 1226 } else if (!is_power_of_2(pages)) {
1227 char buf[100];
1228
1227 /* round pages up to next power of 2 */ 1229 /* round pages up to next power of 2 */
1228 pages = roundup_pow_of_two(pages); 1230 pages = roundup_pow_of_two(pages);
1229 if (!pages) 1231 if (!pages)
1230 return -EINVAL; 1232 return -EINVAL;
1231 pr_info("rounding mmap pages size to %lu bytes (%lu pages)\n", 1233
1232 pages * page_size, pages); 1234 unit_number__scnprintf(buf, sizeof(buf), pages * page_size);
1235 pr_info("rounding mmap pages size to %s (%lu pages)\n",
1236 buf, pages);
1233 } 1237 }
1234 1238
1235 if (pages > max) 1239 if (pages > max)
@@ -1797,7 +1801,7 @@ int perf_evlist__start_workload(struct perf_evlist *evlist)
1797 */ 1801 */
1798 ret = write(evlist->workload.cork_fd, &bf, 1); 1802 ret = write(evlist->workload.cork_fd, &bf, 1);
1799 if (ret < 0) 1803 if (ret < 0)
1800 perror("enable to write to pipe"); 1804 perror("unable to write to pipe");
1801 1805
1802 close(evlist->workload.cork_fd); 1806 close(evlist->workload.cork_fd);
1803 return ret; 1807 return ret;
diff --git a/tools/perf/util/evlist.h b/tools/perf/util/evlist.h
index 4fd034f22d2f..389b9ccdf8c7 100644
--- a/tools/perf/util/evlist.h
+++ b/tools/perf/util/evlist.h
@@ -218,6 +218,8 @@ int perf_evlist__mmap(struct perf_evlist *evlist, unsigned int pages,
218 bool overwrite); 218 bool overwrite);
219void perf_evlist__munmap(struct perf_evlist *evlist); 219void perf_evlist__munmap(struct perf_evlist *evlist);
220 220
221size_t perf_evlist__mmap_size(unsigned long pages);
222
221void perf_evlist__disable(struct perf_evlist *evlist); 223void perf_evlist__disable(struct perf_evlist *evlist);
222void perf_evlist__enable(struct perf_evlist *evlist); 224void perf_evlist__enable(struct perf_evlist *evlist);
223void perf_evlist__toggle_enable(struct perf_evlist *evlist); 225void perf_evlist__toggle_enable(struct perf_evlist *evlist);
diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c
index 04e536ae4d88..ac59710b79e0 100644
--- a/tools/perf/util/evsel.c
+++ b/tools/perf/util/evsel.c
@@ -1448,8 +1448,8 @@ static bool ignore_missing_thread(struct perf_evsel *evsel,
1448 return true; 1448 return true;
1449} 1449}
1450 1450
1451static int __perf_evsel__open(struct perf_evsel *evsel, struct cpu_map *cpus, 1451int perf_evsel__open(struct perf_evsel *evsel, struct cpu_map *cpus,
1452 struct thread_map *threads) 1452 struct thread_map *threads)
1453{ 1453{
1454 int cpu, thread, nthreads; 1454 int cpu, thread, nthreads;
1455 unsigned long flags = PERF_FLAG_FD_CLOEXEC; 1455 unsigned long flags = PERF_FLAG_FD_CLOEXEC;
@@ -1459,6 +1459,30 @@ static int __perf_evsel__open(struct perf_evsel *evsel, struct cpu_map *cpus,
1459 if (perf_missing_features.write_backward && evsel->attr.write_backward) 1459 if (perf_missing_features.write_backward && evsel->attr.write_backward)
1460 return -EINVAL; 1460 return -EINVAL;
1461 1461
1462 if (cpus == NULL) {
1463 static struct cpu_map *empty_cpu_map;
1464
1465 if (empty_cpu_map == NULL) {
1466 empty_cpu_map = cpu_map__dummy_new();
1467 if (empty_cpu_map == NULL)
1468 return -ENOMEM;
1469 }
1470
1471 cpus = empty_cpu_map;
1472 }
1473
1474 if (threads == NULL) {
1475 static struct thread_map *empty_thread_map;
1476
1477 if (empty_thread_map == NULL) {
1478 empty_thread_map = thread_map__new_by_tid(-1);
1479 if (empty_thread_map == NULL)
1480 return -ENOMEM;
1481 }
1482
1483 threads = empty_thread_map;
1484 }
1485
1462 if (evsel->system_wide) 1486 if (evsel->system_wide)
1463 nthreads = 1; 1487 nthreads = 1;
1464 else 1488 else
@@ -1655,46 +1679,16 @@ void perf_evsel__close(struct perf_evsel *evsel, int ncpus, int nthreads)
1655 perf_evsel__free_fd(evsel); 1679 perf_evsel__free_fd(evsel);
1656} 1680}
1657 1681
1658static struct {
1659 struct cpu_map map;
1660 int cpus[1];
1661} empty_cpu_map = {
1662 .map.nr = 1,
1663 .cpus = { -1, },
1664};
1665
1666static struct {
1667 struct thread_map map;
1668 int threads[1];
1669} empty_thread_map = {
1670 .map.nr = 1,
1671 .threads = { -1, },
1672};
1673
1674int perf_evsel__open(struct perf_evsel *evsel, struct cpu_map *cpus,
1675 struct thread_map *threads)
1676{
1677 if (cpus == NULL) {
1678 /* Work around old compiler warnings about strict aliasing */
1679 cpus = &empty_cpu_map.map;
1680 }
1681
1682 if (threads == NULL)
1683 threads = &empty_thread_map.map;
1684
1685 return __perf_evsel__open(evsel, cpus, threads);
1686}
1687
1688int perf_evsel__open_per_cpu(struct perf_evsel *evsel, 1682int perf_evsel__open_per_cpu(struct perf_evsel *evsel,
1689 struct cpu_map *cpus) 1683 struct cpu_map *cpus)
1690{ 1684{
1691 return __perf_evsel__open(evsel, cpus, &empty_thread_map.map); 1685 return perf_evsel__open(evsel, cpus, NULL);
1692} 1686}
1693 1687
1694int perf_evsel__open_per_thread(struct perf_evsel *evsel, 1688int perf_evsel__open_per_thread(struct perf_evsel *evsel,
1695 struct thread_map *threads) 1689 struct thread_map *threads)
1696{ 1690{
1697 return __perf_evsel__open(evsel, &empty_cpu_map.map, threads); 1691 return perf_evsel__open(evsel, NULL, threads);
1698} 1692}
1699 1693
1700static int perf_evsel__parse_id_sample(const struct perf_evsel *evsel, 1694static int perf_evsel__parse_id_sample(const struct perf_evsel *evsel,
@@ -2469,7 +2463,9 @@ int perf_evsel__open_strerror(struct perf_evsel *evsel, struct target *target,
2469 " -1: Allow use of (almost) all events by all users\n" 2463 " -1: Allow use of (almost) all events by all users\n"
2470 ">= 0: Disallow raw tracepoint access by users without CAP_IOC_LOCK\n" 2464 ">= 0: Disallow raw tracepoint access by users without CAP_IOC_LOCK\n"
2471 ">= 1: Disallow CPU event access by users without CAP_SYS_ADMIN\n" 2465 ">= 1: Disallow CPU event access by users without CAP_SYS_ADMIN\n"
2472 ">= 2: Disallow kernel profiling by users without CAP_SYS_ADMIN", 2466 ">= 2: Disallow kernel profiling by users without CAP_SYS_ADMIN\n\n"
2467 "To make this setting permanent, edit /etc/sysctl.conf too, e.g.:\n\n"
2468 " kernel.perf_event_paranoid = -1\n" ,
2473 target->system_wide ? "system-wide " : "", 2469 target->system_wide ? "system-wide " : "",
2474 perf_event_paranoid()); 2470 perf_event_paranoid());
2475 case ENOENT: 2471 case ENOENT:
diff --git a/tools/perf/util/evsel_fprintf.c b/tools/perf/util/evsel_fprintf.c
index 6b2925542c0a..4ef5184819a0 100644
--- a/tools/perf/util/evsel_fprintf.c
+++ b/tools/perf/util/evsel_fprintf.c
@@ -168,7 +168,6 @@ int sample__fprintf_callchain(struct perf_sample *sample, int left_alignment,
168 168
169 if (symbol_conf.bt_stop_list && 169 if (symbol_conf.bt_stop_list &&
170 node->sym && 170 node->sym &&
171 node->sym->name &&
172 strlist__has_entry(symbol_conf.bt_stop_list, 171 strlist__has_entry(symbol_conf.bt_stop_list,
173 node->sym->name)) { 172 node->sym->name)) {
174 break; 173 break;
diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c
index d89c9c7ef4e5..05714d548584 100644
--- a/tools/perf/util/header.c
+++ b/tools/perf/util/header.c
@@ -41,6 +41,8 @@ static const u64 __perf_magic2_sw = 0x50455246494c4532ULL;
41 41
42#define PERF_MAGIC __perf_magic2 42#define PERF_MAGIC __perf_magic2
43 43
44const char perf_version_string[] = PERF_VERSION;
45
44struct perf_file_attr { 46struct perf_file_attr {
45 struct perf_event_attr attr; 47 struct perf_event_attr attr;
46 struct perf_file_section ids; 48 struct perf_file_section ids;
@@ -293,11 +295,7 @@ static int write_nrcpus(int fd, struct perf_header *h __maybe_unused,
293 u32 nrc, nra; 295 u32 nrc, nra;
294 int ret; 296 int ret;
295 297
296 nr = sysconf(_SC_NPROCESSORS_CONF); 298 nrc = cpu__max_present_cpu();
297 if (nr < 0)
298 return -1;
299
300 nrc = (u32)(nr & UINT_MAX);
301 299
302 nr = sysconf(_SC_NPROCESSORS_ONLN); 300 nr = sysconf(_SC_NPROCESSORS_ONLN);
303 if (nr < 0) 301 if (nr < 0)
@@ -503,24 +501,29 @@ static void free_cpu_topo(struct cpu_topo *tp)
503 501
504static struct cpu_topo *build_cpu_topology(void) 502static struct cpu_topo *build_cpu_topology(void)
505{ 503{
506 struct cpu_topo *tp; 504 struct cpu_topo *tp = NULL;
507 void *addr; 505 void *addr;
508 u32 nr, i; 506 u32 nr, i;
509 size_t sz; 507 size_t sz;
510 long ncpus; 508 long ncpus;
511 int ret = -1; 509 int ret = -1;
510 struct cpu_map *map;
512 511
513 ncpus = sysconf(_SC_NPROCESSORS_CONF); 512 ncpus = cpu__max_present_cpu();
514 if (ncpus < 0) 513
514 /* build online CPU map */
515 map = cpu_map__new(NULL);
516 if (map == NULL) {
517 pr_debug("failed to get system cpumap\n");
515 return NULL; 518 return NULL;
519 }
516 520
517 nr = (u32)(ncpus & UINT_MAX); 521 nr = (u32)(ncpus & UINT_MAX);
518 522
519 sz = nr * sizeof(char *); 523 sz = nr * sizeof(char *);
520
521 addr = calloc(1, sizeof(*tp) + 2 * sz); 524 addr = calloc(1, sizeof(*tp) + 2 * sz);
522 if (!addr) 525 if (!addr)
523 return NULL; 526 goto out_free;
524 527
525 tp = addr; 528 tp = addr;
526 tp->cpu_nr = nr; 529 tp->cpu_nr = nr;
@@ -530,10 +533,16 @@ static struct cpu_topo *build_cpu_topology(void)
530 tp->thread_siblings = addr; 533 tp->thread_siblings = addr;
531 534
532 for (i = 0; i < nr; i++) { 535 for (i = 0; i < nr; i++) {
536 if (!cpu_map__has(map, i))
537 continue;
538
533 ret = build_cpu_topo(tp, i); 539 ret = build_cpu_topo(tp, i);
534 if (ret < 0) 540 if (ret < 0)
535 break; 541 break;
536 } 542 }
543
544out_free:
545 cpu_map__put(map);
537 if (ret) { 546 if (ret) {
538 free_cpu_topo(tp); 547 free_cpu_topo(tp);
539 tp = NULL; 548 tp = NULL;
@@ -1124,7 +1133,7 @@ static void print_cpu_topology(struct perf_header *ph, int fd __maybe_unused,
1124{ 1133{
1125 int nr, i; 1134 int nr, i;
1126 char *str; 1135 char *str;
1127 int cpu_nr = ph->env.nr_cpus_online; 1136 int cpu_nr = ph->env.nr_cpus_avail;
1128 1137
1129 nr = ph->env.nr_sibling_cores; 1138 nr = ph->env.nr_sibling_cores;
1130 str = ph->env.sibling_cores; 1139 str = ph->env.sibling_cores;
@@ -1779,7 +1788,7 @@ static int process_cpu_topology(struct perf_file_section *section,
1779 u32 nr, i; 1788 u32 nr, i;
1780 char *str; 1789 char *str;
1781 struct strbuf sb; 1790 struct strbuf sb;
1782 int cpu_nr = ph->env.nr_cpus_online; 1791 int cpu_nr = ph->env.nr_cpus_avail;
1783 u64 size = 0; 1792 u64 size = 0;
1784 1793
1785 ph->env.cpu = calloc(cpu_nr, sizeof(*ph->env.cpu)); 1794 ph->env.cpu = calloc(cpu_nr, sizeof(*ph->env.cpu));
@@ -1860,7 +1869,7 @@ static int process_cpu_topology(struct perf_file_section *section,
1860 if (ph->needs_swap) 1869 if (ph->needs_swap)
1861 nr = bswap_32(nr); 1870 nr = bswap_32(nr);
1862 1871
1863 if (nr > (u32)cpu_nr) { 1872 if (nr != (u32)-1 && nr > (u32)cpu_nr) {
1864 pr_debug("socket_id number is too big." 1873 pr_debug("socket_id number is too big."
1865 "You may need to upgrade the perf tool.\n"); 1874 "You may need to upgrade the perf tool.\n");
1866 goto free_cpu; 1875 goto free_cpu;
@@ -2801,8 +2810,10 @@ static int perf_evsel__prepare_tracepoint_event(struct perf_evsel *evsel,
2801 } 2810 }
2802 2811
2803 event = pevent_find_event(pevent, evsel->attr.config); 2812 event = pevent_find_event(pevent, evsel->attr.config);
2804 if (event == NULL) 2813 if (event == NULL) {
2814 pr_debug("cannot find event format for %d\n", (int)evsel->attr.config);
2805 return -1; 2815 return -1;
2816 }
2806 2817
2807 if (!evsel->name) { 2818 if (!evsel->name) {
2808 snprintf(bf, sizeof(bf), "%s:%s", event->system, event->name); 2819 snprintf(bf, sizeof(bf), "%s:%s", event->system, event->name);
@@ -3201,6 +3212,7 @@ int perf_event__process_event_update(struct perf_tool *tool __maybe_unused,
3201 case PERF_EVENT_UPDATE__SCALE: 3212 case PERF_EVENT_UPDATE__SCALE:
3202 ev_scale = (struct event_update_event_scale *) ev->data; 3213 ev_scale = (struct event_update_event_scale *) ev->data;
3203 evsel->scale = ev_scale->scale; 3214 evsel->scale = ev_scale->scale;
3215 break;
3204 case PERF_EVENT_UPDATE__CPUS: 3216 case PERF_EVENT_UPDATE__CPUS:
3205 ev_cpus = (struct event_update_event_cpus *) ev->data; 3217 ev_cpus = (struct event_update_event_cpus *) ev->data;
3206 3218
diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c
index 7d1b7d33e644..eaf72a938fb4 100644
--- a/tools/perf/util/hist.c
+++ b/tools/perf/util/hist.c
@@ -69,7 +69,7 @@ void hists__calc_col_len(struct hists *hists, struct hist_entry *h)
69 */ 69 */
70 if (h->ms.sym) { 70 if (h->ms.sym) {
71 symlen = h->ms.sym->namelen + 4; 71 symlen = h->ms.sym->namelen + 4;
72 if (verbose) 72 if (verbose > 0)
73 symlen += BITS_PER_LONG / 4 + 2 + 3; 73 symlen += BITS_PER_LONG / 4 + 2 + 3;
74 hists__new_col_len(hists, HISTC_SYMBOL, symlen); 74 hists__new_col_len(hists, HISTC_SYMBOL, symlen);
75 } else { 75 } else {
@@ -93,7 +93,7 @@ void hists__calc_col_len(struct hists *hists, struct hist_entry *h)
93 if (h->branch_info) { 93 if (h->branch_info) {
94 if (h->branch_info->from.sym) { 94 if (h->branch_info->from.sym) {
95 symlen = (int)h->branch_info->from.sym->namelen + 4; 95 symlen = (int)h->branch_info->from.sym->namelen + 4;
96 if (verbose) 96 if (verbose > 0)
97 symlen += BITS_PER_LONG / 4 + 2 + 3; 97 symlen += BITS_PER_LONG / 4 + 2 + 3;
98 hists__new_col_len(hists, HISTC_SYMBOL_FROM, symlen); 98 hists__new_col_len(hists, HISTC_SYMBOL_FROM, symlen);
99 99
@@ -107,7 +107,7 @@ void hists__calc_col_len(struct hists *hists, struct hist_entry *h)
107 107
108 if (h->branch_info->to.sym) { 108 if (h->branch_info->to.sym) {
109 symlen = (int)h->branch_info->to.sym->namelen + 4; 109 symlen = (int)h->branch_info->to.sym->namelen + 4;
110 if (verbose) 110 if (verbose > 0)
111 symlen += BITS_PER_LONG / 4 + 2 + 3; 111 symlen += BITS_PER_LONG / 4 + 2 + 3;
112 hists__new_col_len(hists, HISTC_SYMBOL_TO, symlen); 112 hists__new_col_len(hists, HISTC_SYMBOL_TO, symlen);
113 113
@@ -2446,8 +2446,10 @@ int parse_filter_percentage(const struct option *opt __maybe_unused,
2446 symbol_conf.filter_relative = true; 2446 symbol_conf.filter_relative = true;
2447 else if (!strcmp(arg, "absolute")) 2447 else if (!strcmp(arg, "absolute"))
2448 symbol_conf.filter_relative = false; 2448 symbol_conf.filter_relative = false;
2449 else 2449 else {
2450 pr_debug("Invalud percentage: %s\n", arg);
2450 return -1; 2451 return -1;
2452 }
2451 2453
2452 return 0; 2454 return 0;
2453} 2455}
diff --git a/tools/perf/util/intel-pt-decoder/Build b/tools/perf/util/intel-pt-decoder/Build
index 9b742ea8bfe8..7aca5d6d7e1f 100644
--- a/tools/perf/util/intel-pt-decoder/Build
+++ b/tools/perf/util/intel-pt-decoder/Build
@@ -23,4 +23,8 @@ $(OUTPUT)util/intel-pt-decoder/intel-pt-insn-decoder.o: util/intel-pt-decoder/in
23 $(call rule_mkdir) 23 $(call rule_mkdir)
24 $(call if_changed_dep,cc_o_c) 24 $(call if_changed_dep,cc_o_c)
25 25
26CFLAGS_intel-pt-insn-decoder.o += -I$(OUTPUT)util/intel-pt-decoder -Wno-override-init 26CFLAGS_intel-pt-insn-decoder.o += -I$(OUTPUT)util/intel-pt-decoder
27
28ifneq ($(CC), clang)
29 CFLAGS_intel-pt-insn-decoder.o += -Wno-override-init
30endif
diff --git a/tools/perf/util/intel-pt-decoder/intel-pt-decoder.c b/tools/perf/util/intel-pt-decoder/intel-pt-decoder.c
index e4e7dc781d21..7cf7f7aca4d2 100644
--- a/tools/perf/util/intel-pt-decoder/intel-pt-decoder.c
+++ b/tools/perf/util/intel-pt-decoder/intel-pt-decoder.c
@@ -22,6 +22,7 @@
22#include <errno.h> 22#include <errno.h>
23#include <stdint.h> 23#include <stdint.h>
24#include <inttypes.h> 24#include <inttypes.h>
25#include <linux/compiler.h>
25 26
26#include "../cache.h" 27#include "../cache.h"
27#include "../util.h" 28#include "../util.h"
@@ -1746,6 +1747,7 @@ static int intel_pt_walk_psb(struct intel_pt_decoder *decoder)
1746 switch (decoder->packet.type) { 1747 switch (decoder->packet.type) {
1747 case INTEL_PT_TIP_PGD: 1748 case INTEL_PT_TIP_PGD:
1748 decoder->continuous_period = false; 1749 decoder->continuous_period = false;
1750 __fallthrough;
1749 case INTEL_PT_TIP_PGE: 1751 case INTEL_PT_TIP_PGE:
1750 case INTEL_PT_TIP: 1752 case INTEL_PT_TIP:
1751 intel_pt_log("ERROR: Unexpected packet\n"); 1753 intel_pt_log("ERROR: Unexpected packet\n");
@@ -1799,6 +1801,8 @@ static int intel_pt_walk_psb(struct intel_pt_decoder *decoder)
1799 decoder->pge = false; 1801 decoder->pge = false;
1800 decoder->continuous_period = false; 1802 decoder->continuous_period = false;
1801 intel_pt_clear_tx_flags(decoder); 1803 intel_pt_clear_tx_flags(decoder);
1804 __fallthrough;
1805
1802 case INTEL_PT_TNT: 1806 case INTEL_PT_TNT:
1803 decoder->have_tma = false; 1807 decoder->have_tma = false;
1804 intel_pt_log("ERROR: Unexpected packet\n"); 1808 intel_pt_log("ERROR: Unexpected packet\n");
@@ -1839,6 +1843,7 @@ static int intel_pt_walk_to_ip(struct intel_pt_decoder *decoder)
1839 switch (decoder->packet.type) { 1843 switch (decoder->packet.type) {
1840 case INTEL_PT_TIP_PGD: 1844 case INTEL_PT_TIP_PGD:
1841 decoder->continuous_period = false; 1845 decoder->continuous_period = false;
1846 __fallthrough;
1842 case INTEL_PT_TIP_PGE: 1847 case INTEL_PT_TIP_PGE:
1843 case INTEL_PT_TIP: 1848 case INTEL_PT_TIP:
1844 decoder->pge = decoder->packet.type != INTEL_PT_TIP_PGD; 1849 decoder->pge = decoder->packet.type != INTEL_PT_TIP_PGD;
diff --git a/tools/perf/util/intel-pt-decoder/intel-pt-pkt-decoder.c b/tools/perf/util/intel-pt-decoder/intel-pt-pkt-decoder.c
index 4f7b32020487..7528ae4f7e28 100644
--- a/tools/perf/util/intel-pt-decoder/intel-pt-pkt-decoder.c
+++ b/tools/perf/util/intel-pt-decoder/intel-pt-pkt-decoder.c
@@ -17,6 +17,7 @@
17#include <string.h> 17#include <string.h>
18#include <endian.h> 18#include <endian.h>
19#include <byteswap.h> 19#include <byteswap.h>
20#include <linux/compiler.h>
20 21
21#include "intel-pt-pkt-decoder.h" 22#include "intel-pt-pkt-decoder.h"
22 23
@@ -498,6 +499,7 @@ int intel_pt_pkt_desc(const struct intel_pt_pkt *packet, char *buf,
498 case INTEL_PT_FUP: 499 case INTEL_PT_FUP:
499 if (!(packet->count)) 500 if (!(packet->count))
500 return snprintf(buf, buf_len, "%s no ip", name); 501 return snprintf(buf, buf_len, "%s no ip", name);
502 __fallthrough;
501 case INTEL_PT_CYC: 503 case INTEL_PT_CYC:
502 case INTEL_PT_VMCS: 504 case INTEL_PT_VMCS:
503 case INTEL_PT_MTC: 505 case INTEL_PT_MTC:
diff --git a/tools/perf/util/intel-pt.c b/tools/perf/util/intel-pt.c
index 85d5eeb66c75..da20cd5612e9 100644
--- a/tools/perf/util/intel-pt.c
+++ b/tools/perf/util/intel-pt.c
@@ -2159,7 +2159,9 @@ int intel_pt_process_auxtrace_info(union perf_event *event,
2159 2159
2160 addr_filters__init(&pt->filts); 2160 addr_filters__init(&pt->filts);
2161 2161
2162 perf_config(intel_pt_perf_config, pt); 2162 err = perf_config(intel_pt_perf_config, pt);
2163 if (err)
2164 goto err_free;
2163 2165
2164 err = auxtrace_queues__init(&pt->queues); 2166 err = auxtrace_queues__init(&pt->queues);
2165 if (err) 2167 if (err)
diff --git a/tools/perf/util/llvm-utils.c b/tools/perf/util/llvm-utils.c
index b23ff44cf214..824356488ce6 100644
--- a/tools/perf/util/llvm-utils.c
+++ b/tools/perf/util/llvm-utils.c
@@ -48,8 +48,10 @@ int perf_llvm_config(const char *var, const char *value)
48 llvm_param.kbuild_opts = strdup(value); 48 llvm_param.kbuild_opts = strdup(value);
49 else if (!strcmp(var, "dump-obj")) 49 else if (!strcmp(var, "dump-obj"))
50 llvm_param.dump_obj = !!perf_config_bool(var, value); 50 llvm_param.dump_obj = !!perf_config_bool(var, value);
51 else 51 else {
52 pr_debug("Invalid LLVM config option: %s\n", value);
52 return -1; 53 return -1;
54 }
53 llvm_param.user_set_param = true; 55 llvm_param.user_set_param = true;
54 return 0; 56 return 0;
55} 57}
diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c
index 9b33bef54581..71c9720d4973 100644
--- a/tools/perf/util/machine.c
+++ b/tools/perf/util/machine.c
@@ -87,6 +87,25 @@ out_delete:
87 return NULL; 87 return NULL;
88} 88}
89 89
90struct machine *machine__new_kallsyms(void)
91{
92 struct machine *machine = machine__new_host();
93 /*
94 * FIXME:
95 * 1) MAP__FUNCTION will go away when we stop loading separate maps for
96 * functions and data objects.
97 * 2) We should switch to machine__load_kallsyms(), i.e. not explicitely
98 * ask for not using the kcore parsing code, once this one is fixed
99 * to create a map per module.
100 */
101 if (machine && __machine__load_kallsyms(machine, "/proc/kallsyms", MAP__FUNCTION, true) <= 0) {
102 machine__delete(machine);
103 machine = NULL;
104 }
105
106 return machine;
107}
108
90static void dsos__purge(struct dsos *dsos) 109static void dsos__purge(struct dsos *dsos)
91{ 110{
92 struct dso *pos, *n; 111 struct dso *pos, *n;
@@ -763,7 +782,7 @@ static u64 machine__get_running_kernel_start(struct machine *machine,
763 782
764int __machine__create_kernel_maps(struct machine *machine, struct dso *kernel) 783int __machine__create_kernel_maps(struct machine *machine, struct dso *kernel)
765{ 784{
766 enum map_type type; 785 int type;
767 u64 start = machine__get_running_kernel_start(machine, NULL); 786 u64 start = machine__get_running_kernel_start(machine, NULL);
768 787
769 /* In case of renewal the kernel map, destroy previous one */ 788 /* In case of renewal the kernel map, destroy previous one */
@@ -794,7 +813,7 @@ int __machine__create_kernel_maps(struct machine *machine, struct dso *kernel)
794 813
795void machine__destroy_kernel_maps(struct machine *machine) 814void machine__destroy_kernel_maps(struct machine *machine)
796{ 815{
797 enum map_type type; 816 int type;
798 817
799 for (type = 0; type < MAP__NR_TYPES; ++type) { 818 for (type = 0; type < MAP__NR_TYPES; ++type) {
800 struct kmap *kmap; 819 struct kmap *kmap;
@@ -1546,7 +1565,7 @@ int machine__process_event(struct machine *machine, union perf_event *event,
1546 1565
1547static bool symbol__match_regex(struct symbol *sym, regex_t *regex) 1566static bool symbol__match_regex(struct symbol *sym, regex_t *regex)
1548{ 1567{
1549 if (sym->name && !regexec(regex, sym->name, 0, NULL, 0)) 1568 if (!regexec(regex, sym->name, 0, NULL, 0))
1550 return 1; 1569 return 1;
1551 return 0; 1570 return 0;
1552} 1571}
diff --git a/tools/perf/util/machine.h b/tools/perf/util/machine.h
index 354de6e56109..a28305029711 100644
--- a/tools/perf/util/machine.h
+++ b/tools/perf/util/machine.h
@@ -129,6 +129,7 @@ char *machine__mmap_name(struct machine *machine, char *bf, size_t size);
129void machines__set_comm_exec(struct machines *machines, bool comm_exec); 129void machines__set_comm_exec(struct machines *machines, bool comm_exec);
130 130
131struct machine *machine__new_host(void); 131struct machine *machine__new_host(void);
132struct machine *machine__new_kallsyms(void);
132int machine__init(struct machine *machine, const char *root_dir, pid_t pid); 133int machine__init(struct machine *machine, const char *root_dir, pid_t pid);
133void machine__exit(struct machine *machine); 134void machine__exit(struct machine *machine);
134void machine__delete_threads(struct machine *machine); 135void machine__delete_threads(struct machine *machine);
diff --git a/tools/perf/util/map.c b/tools/perf/util/map.c
index 4f9a71c63026..0a943e7b1ea7 100644
--- a/tools/perf/util/map.c
+++ b/tools/perf/util/map.c
@@ -387,10 +387,10 @@ size_t map__fprintf_dsoname(struct map *map, FILE *fp)
387{ 387{
388 const char *dsoname = "[unknown]"; 388 const char *dsoname = "[unknown]";
389 389
390 if (map && map->dso && (map->dso->name || map->dso->long_name)) { 390 if (map && map->dso) {
391 if (symbol_conf.show_kernel_path && map->dso->long_name) 391 if (symbol_conf.show_kernel_path && map->dso->long_name)
392 dsoname = map->dso->long_name; 392 dsoname = map->dso->long_name;
393 else if (map->dso->name) 393 else
394 dsoname = map->dso->name; 394 dsoname = map->dso->name;
395 } 395 }
396 396
diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c
index 3c876b8ba4de..67a8aebc67ab 100644
--- a/tools/perf/util/parse-events.c
+++ b/tools/perf/util/parse-events.c
@@ -211,6 +211,8 @@ struct tracepoint_path *tracepoint_id_to_path(u64 config)
211 closedir(evt_dir); 211 closedir(evt_dir);
212 closedir(sys_dir); 212 closedir(sys_dir);
213 path = zalloc(sizeof(*path)); 213 path = zalloc(sizeof(*path));
214 if (!path)
215 return NULL;
214 path->system = malloc(MAX_EVENT_LENGTH); 216 path->system = malloc(MAX_EVENT_LENGTH);
215 if (!path->system) { 217 if (!path->system) {
216 free(path); 218 free(path);
@@ -252,8 +254,7 @@ struct tracepoint_path *tracepoint_name_to_path(const char *name)
252 if (path->system == NULL || path->name == NULL) { 254 if (path->system == NULL || path->name == NULL) {
253 zfree(&path->system); 255 zfree(&path->system);
254 zfree(&path->name); 256 zfree(&path->name);
255 free(path); 257 zfree(&path);
256 path = NULL;
257 } 258 }
258 259
259 return path; 260 return path;
@@ -310,10 +311,11 @@ __add_event(struct list_head *list, int *idx,
310 311
311 event_attr_init(attr); 312 event_attr_init(attr);
312 313
313 evsel = perf_evsel__new_idx(attr, (*idx)++); 314 evsel = perf_evsel__new_idx(attr, *idx);
314 if (!evsel) 315 if (!evsel)
315 return NULL; 316 return NULL;
316 317
318 (*idx)++;
317 evsel->cpus = cpu_map__get(cpus); 319 evsel->cpus = cpu_map__get(cpus);
318 evsel->own_cpus = cpu_map__get(cpus); 320 evsel->own_cpus = cpu_map__get(cpus);
319 321
@@ -1477,10 +1479,9 @@ static void perf_pmu__parse_cleanup(void)
1477 1479
1478 for (i = 0; i < perf_pmu_events_list_num; i++) { 1480 for (i = 0; i < perf_pmu_events_list_num; i++) {
1479 p = perf_pmu_events_list + i; 1481 p = perf_pmu_events_list + i;
1480 free(p->symbol); 1482 zfree(&p->symbol);
1481 } 1483 }
1482 free(perf_pmu_events_list); 1484 zfree(&perf_pmu_events_list);
1483 perf_pmu_events_list = NULL;
1484 perf_pmu_events_list_num = 0; 1485 perf_pmu_events_list_num = 0;
1485 } 1486 }
1486} 1487}
@@ -1504,35 +1505,41 @@ static void perf_pmu__parse_init(void)
1504 struct perf_pmu_alias *alias; 1505 struct perf_pmu_alias *alias;
1505 int len = 0; 1506 int len = 0;
1506 1507
1507 pmu = perf_pmu__find("cpu"); 1508 pmu = NULL;
1508 if ((pmu == NULL) || list_empty(&pmu->aliases)) { 1509 while ((pmu = perf_pmu__scan(pmu)) != NULL) {
1510 list_for_each_entry(alias, &pmu->aliases, list) {
1511 if (strchr(alias->name, '-'))
1512 len++;
1513 len++;
1514 }
1515 }
1516
1517 if (len == 0) {
1509 perf_pmu_events_list_num = -1; 1518 perf_pmu_events_list_num = -1;
1510 return; 1519 return;
1511 } 1520 }
1512 list_for_each_entry(alias, &pmu->aliases, list) {
1513 if (strchr(alias->name, '-'))
1514 len++;
1515 len++;
1516 }
1517 perf_pmu_events_list = malloc(sizeof(struct perf_pmu_event_symbol) * len); 1521 perf_pmu_events_list = malloc(sizeof(struct perf_pmu_event_symbol) * len);
1518 if (!perf_pmu_events_list) 1522 if (!perf_pmu_events_list)
1519 return; 1523 return;
1520 perf_pmu_events_list_num = len; 1524 perf_pmu_events_list_num = len;
1521 1525
1522 len = 0; 1526 len = 0;
1523 list_for_each_entry(alias, &pmu->aliases, list) { 1527 pmu = NULL;
1524 struct perf_pmu_event_symbol *p = perf_pmu_events_list + len; 1528 while ((pmu = perf_pmu__scan(pmu)) != NULL) {
1525 char *tmp = strchr(alias->name, '-'); 1529 list_for_each_entry(alias, &pmu->aliases, list) {
1526 1530 struct perf_pmu_event_symbol *p = perf_pmu_events_list + len;
1527 if (tmp != NULL) { 1531 char *tmp = strchr(alias->name, '-');
1528 SET_SYMBOL(strndup(alias->name, tmp - alias->name), 1532
1529 PMU_EVENT_SYMBOL_PREFIX); 1533 if (tmp != NULL) {
1530 p++; 1534 SET_SYMBOL(strndup(alias->name, tmp - alias->name),
1531 SET_SYMBOL(strdup(++tmp), PMU_EVENT_SYMBOL_SUFFIX); 1535 PMU_EVENT_SYMBOL_PREFIX);
1532 len += 2; 1536 p++;
1533 } else { 1537 SET_SYMBOL(strdup(++tmp), PMU_EVENT_SYMBOL_SUFFIX);
1534 SET_SYMBOL(strdup(alias->name), PMU_EVENT_SYMBOL); 1538 len += 2;
1535 len++; 1539 } else {
1540 SET_SYMBOL(strdup(alias->name), PMU_EVENT_SYMBOL);
1541 len++;
1542 }
1536 } 1543 }
1537 } 1544 }
1538 qsort(perf_pmu_events_list, len, 1545 qsort(perf_pmu_events_list, len,
@@ -1563,7 +1570,7 @@ perf_pmu__parse_check(const char *name)
1563 r = bsearch(&p, perf_pmu_events_list, 1570 r = bsearch(&p, perf_pmu_events_list,
1564 (size_t) perf_pmu_events_list_num, 1571 (size_t) perf_pmu_events_list_num,
1565 sizeof(struct perf_pmu_event_symbol), comp_pmu); 1572 sizeof(struct perf_pmu_event_symbol), comp_pmu);
1566 free(p.symbol); 1573 zfree(&p.symbol);
1567 return r ? r->type : PMU_EVENT_SYMBOL_ERR; 1574 return r ? r->type : PMU_EVENT_SYMBOL_ERR;
1568} 1575}
1569 1576
@@ -1710,8 +1717,8 @@ static void parse_events_print_error(struct parse_events_error *err,
1710 fprintf(stderr, "%*s\\___ %s\n", idx + 1, "", err->str); 1717 fprintf(stderr, "%*s\\___ %s\n", idx + 1, "", err->str);
1711 if (err->help) 1718 if (err->help)
1712 fprintf(stderr, "\n%s\n", err->help); 1719 fprintf(stderr, "\n%s\n", err->help);
1713 free(err->str); 1720 zfree(&err->str);
1714 free(err->help); 1721 zfree(&err->help);
1715 } 1722 }
1716 1723
1717 fprintf(stderr, "Run 'perf list' for a list of valid events\n"); 1724 fprintf(stderr, "Run 'perf list' for a list of valid events\n");
@@ -2013,17 +2020,14 @@ static bool is_event_supported(u8 type, unsigned config)
2013 .config = config, 2020 .config = config,
2014 .disabled = 1, 2021 .disabled = 1,
2015 }; 2022 };
2016 struct { 2023 struct thread_map *tmap = thread_map__new_by_tid(0);
2017 struct thread_map map; 2024
2018 int threads[1]; 2025 if (tmap == NULL)
2019 } tmap = { 2026 return false;
2020 .map.nr = 1,
2021 .threads = { 0 },
2022 };
2023 2027
2024 evsel = perf_evsel__new(&attr); 2028 evsel = perf_evsel__new(&attr);
2025 if (evsel) { 2029 if (evsel) {
2026 open_return = perf_evsel__open(evsel, NULL, &tmap.map); 2030 open_return = perf_evsel__open(evsel, NULL, tmap);
2027 ret = open_return >= 0; 2031 ret = open_return >= 0;
2028 2032
2029 if (open_return == -EACCES) { 2033 if (open_return == -EACCES) {
@@ -2035,7 +2039,7 @@ static bool is_event_supported(u8 type, unsigned config)
2035 * 2039 *
2036 */ 2040 */
2037 evsel->attr.exclude_kernel = 1; 2041 evsel->attr.exclude_kernel = 1;
2038 ret = perf_evsel__open(evsel, NULL, &tmap.map) >= 0; 2042 ret = perf_evsel__open(evsel, NULL, tmap) >= 0;
2039 } 2043 }
2040 perf_evsel__delete(evsel); 2044 perf_evsel__delete(evsel);
2041 } 2045 }
@@ -2314,24 +2318,20 @@ int parse_events__is_hardcoded_term(struct parse_events_term *term)
2314 return term->type_term != PARSE_EVENTS__TERM_TYPE_USER; 2318 return term->type_term != PARSE_EVENTS__TERM_TYPE_USER;
2315} 2319}
2316 2320
2317static int new_term(struct parse_events_term **_term, int type_val, 2321static int new_term(struct parse_events_term **_term,
2318 int type_term, char *config, 2322 struct parse_events_term *temp,
2319 char *str, u64 num, int err_term, int err_val) 2323 char *str, u64 num)
2320{ 2324{
2321 struct parse_events_term *term; 2325 struct parse_events_term *term;
2322 2326
2323 term = zalloc(sizeof(*term)); 2327 term = malloc(sizeof(*term));
2324 if (!term) 2328 if (!term)
2325 return -ENOMEM; 2329 return -ENOMEM;
2326 2330
2331 *term = *temp;
2327 INIT_LIST_HEAD(&term->list); 2332 INIT_LIST_HEAD(&term->list);
2328 term->type_val = type_val;
2329 term->type_term = type_term;
2330 term->config = config;
2331 term->err_term = err_term;
2332 term->err_val = err_val;
2333 2333
2334 switch (type_val) { 2334 switch (term->type_val) {
2335 case PARSE_EVENTS__TERM_TYPE_NUM: 2335 case PARSE_EVENTS__TERM_TYPE_NUM:
2336 term->val.num = num; 2336 term->val.num = num;
2337 break; 2337 break;
@@ -2349,15 +2349,22 @@ static int new_term(struct parse_events_term **_term, int type_val,
2349 2349
2350int parse_events_term__num(struct parse_events_term **term, 2350int parse_events_term__num(struct parse_events_term **term,
2351 int type_term, char *config, u64 num, 2351 int type_term, char *config, u64 num,
2352 bool no_value,
2352 void *loc_term_, void *loc_val_) 2353 void *loc_term_, void *loc_val_)
2353{ 2354{
2354 YYLTYPE *loc_term = loc_term_; 2355 YYLTYPE *loc_term = loc_term_;
2355 YYLTYPE *loc_val = loc_val_; 2356 YYLTYPE *loc_val = loc_val_;
2356 2357
2357 return new_term(term, PARSE_EVENTS__TERM_TYPE_NUM, type_term, 2358 struct parse_events_term temp = {
2358 config, NULL, num, 2359 .type_val = PARSE_EVENTS__TERM_TYPE_NUM,
2359 loc_term ? loc_term->first_column : 0, 2360 .type_term = type_term,
2360 loc_val ? loc_val->first_column : 0); 2361 .config = config,
2362 .no_value = no_value,
2363 .err_term = loc_term ? loc_term->first_column : 0,
2364 .err_val = loc_val ? loc_val->first_column : 0,
2365 };
2366
2367 return new_term(term, &temp, NULL, num);
2361} 2368}
2362 2369
2363int parse_events_term__str(struct parse_events_term **term, 2370int parse_events_term__str(struct parse_events_term **term,
@@ -2367,37 +2374,45 @@ int parse_events_term__str(struct parse_events_term **term,
2367 YYLTYPE *loc_term = loc_term_; 2374 YYLTYPE *loc_term = loc_term_;
2368 YYLTYPE *loc_val = loc_val_; 2375 YYLTYPE *loc_val = loc_val_;
2369 2376
2370 return new_term(term, PARSE_EVENTS__TERM_TYPE_STR, type_term, 2377 struct parse_events_term temp = {
2371 config, str, 0, 2378 .type_val = PARSE_EVENTS__TERM_TYPE_STR,
2372 loc_term ? loc_term->first_column : 0, 2379 .type_term = type_term,
2373 loc_val ? loc_val->first_column : 0); 2380 .config = config,
2381 .err_term = loc_term ? loc_term->first_column : 0,
2382 .err_val = loc_val ? loc_val->first_column : 0,
2383 };
2384
2385 return new_term(term, &temp, str, 0);
2374} 2386}
2375 2387
2376int parse_events_term__sym_hw(struct parse_events_term **term, 2388int parse_events_term__sym_hw(struct parse_events_term **term,
2377 char *config, unsigned idx) 2389 char *config, unsigned idx)
2378{ 2390{
2379 struct event_symbol *sym; 2391 struct event_symbol *sym;
2392 struct parse_events_term temp = {
2393 .type_val = PARSE_EVENTS__TERM_TYPE_STR,
2394 .type_term = PARSE_EVENTS__TERM_TYPE_USER,
2395 .config = config ?: (char *) "event",
2396 };
2380 2397
2381 BUG_ON(idx >= PERF_COUNT_HW_MAX); 2398 BUG_ON(idx >= PERF_COUNT_HW_MAX);
2382 sym = &event_symbols_hw[idx]; 2399 sym = &event_symbols_hw[idx];
2383 2400
2384 if (config) 2401 return new_term(term, &temp, (char *) sym->symbol, 0);
2385 return new_term(term, PARSE_EVENTS__TERM_TYPE_STR,
2386 PARSE_EVENTS__TERM_TYPE_USER, config,
2387 (char *) sym->symbol, 0, 0, 0);
2388 else
2389 return new_term(term, PARSE_EVENTS__TERM_TYPE_STR,
2390 PARSE_EVENTS__TERM_TYPE_USER,
2391 (char *) "event", (char *) sym->symbol,
2392 0, 0, 0);
2393} 2402}
2394 2403
2395int parse_events_term__clone(struct parse_events_term **new, 2404int parse_events_term__clone(struct parse_events_term **new,
2396 struct parse_events_term *term) 2405 struct parse_events_term *term)
2397{ 2406{
2398 return new_term(new, term->type_val, term->type_term, term->config, 2407 struct parse_events_term temp = {
2399 term->val.str, term->val.num, 2408 .type_val = term->type_val,
2400 term->err_term, term->err_val); 2409 .type_term = term->type_term,
2410 .config = term->config,
2411 .err_term = term->err_term,
2412 .err_val = term->err_val,
2413 };
2414
2415 return new_term(new, &temp, term->val.str, term->val.num);
2401} 2416}
2402 2417
2403void parse_events_terms__purge(struct list_head *terms) 2418void parse_events_terms__purge(struct list_head *terms)
@@ -2406,7 +2421,7 @@ void parse_events_terms__purge(struct list_head *terms)
2406 2421
2407 list_for_each_entry_safe(term, h, terms, list) { 2422 list_for_each_entry_safe(term, h, terms, list) {
2408 if (term->array.nr_ranges) 2423 if (term->array.nr_ranges)
2409 free(term->array.ranges); 2424 zfree(&term->array.ranges);
2410 list_del_init(&term->list); 2425 list_del_init(&term->list);
2411 free(term); 2426 free(term);
2412 } 2427 }
@@ -2422,7 +2437,7 @@ void parse_events_terms__delete(struct list_head *terms)
2422 2437
2423void parse_events__clear_array(struct parse_events_array *a) 2438void parse_events__clear_array(struct parse_events_array *a)
2424{ 2439{
2425 free(a->ranges); 2440 zfree(&a->ranges);
2426} 2441}
2427 2442
2428void parse_events_evlist_error(struct parse_events_evlist *data, 2443void parse_events_evlist_error(struct parse_events_evlist *data,
diff --git a/tools/perf/util/parse-events.h b/tools/perf/util/parse-events.h
index da246a3ddb69..1af6a267c21b 100644
--- a/tools/perf/util/parse-events.h
+++ b/tools/perf/util/parse-events.h
@@ -94,6 +94,7 @@ struct parse_events_term {
94 int type_term; 94 int type_term;
95 struct list_head list; 95 struct list_head list;
96 bool used; 96 bool used;
97 bool no_value;
97 98
98 /* error string indexes for within parsed string */ 99 /* error string indexes for within parsed string */
99 int err_term; 100 int err_term;
@@ -122,6 +123,7 @@ void parse_events__shrink_config_terms(void);
122int parse_events__is_hardcoded_term(struct parse_events_term *term); 123int parse_events__is_hardcoded_term(struct parse_events_term *term);
123int parse_events_term__num(struct parse_events_term **term, 124int parse_events_term__num(struct parse_events_term **term,
124 int type_term, char *config, u64 num, 125 int type_term, char *config, u64 num,
126 bool novalue,
125 void *loc_term, void *loc_val); 127 void *loc_term, void *loc_val);
126int parse_events_term__str(struct parse_events_term **term, 128int parse_events_term__str(struct parse_events_term **term,
127 int type_term, char *config, char *str, 129 int type_term, char *config, char *str,
diff --git a/tools/perf/util/parse-events.y b/tools/perf/util/parse-events.y
index 879115f93edc..30f018ea1370 100644
--- a/tools/perf/util/parse-events.y
+++ b/tools/perf/util/parse-events.y
@@ -12,9 +12,13 @@
12#include <linux/list.h> 12#include <linux/list.h>
13#include <linux/types.h> 13#include <linux/types.h>
14#include "util.h" 14#include "util.h"
15#include "pmu.h"
16#include "debug.h"
15#include "parse-events.h" 17#include "parse-events.h"
16#include "parse-events-bison.h" 18#include "parse-events-bison.h"
17 19
20void parse_events_error(YYLTYPE *loc, void *data, void *scanner, char const *msg);
21
18#define ABORT_ON(val) \ 22#define ABORT_ON(val) \
19do { \ 23do { \
20 if (val) \ 24 if (val) \
@@ -236,15 +240,34 @@ PE_KERNEL_PMU_EVENT sep_dc
236 struct list_head *head; 240 struct list_head *head;
237 struct parse_events_term *term; 241 struct parse_events_term *term;
238 struct list_head *list; 242 struct list_head *list;
243 struct perf_pmu *pmu = NULL;
244 int ok = 0;
239 245
240 ALLOC_LIST(head); 246 /* Add it for all PMUs that support the alias */
241 ABORT_ON(parse_events_term__num(&term, PARSE_EVENTS__TERM_TYPE_USER,
242 $1, 1, &@1, NULL));
243 list_add_tail(&term->list, head);
244
245 ALLOC_LIST(list); 247 ALLOC_LIST(list);
246 ABORT_ON(parse_events_add_pmu(data, list, "cpu", head)); 248 while ((pmu = perf_pmu__scan(pmu)) != NULL) {
247 parse_events_terms__delete(head); 249 struct perf_pmu_alias *alias;
250
251 list_for_each_entry(alias, &pmu->aliases, list) {
252 if (!strcasecmp(alias->name, $1)) {
253 ALLOC_LIST(head);
254 ABORT_ON(parse_events_term__num(&term, PARSE_EVENTS__TERM_TYPE_USER,
255 $1, 1, false, &@1, NULL));
256 list_add_tail(&term->list, head);
257
258 if (!parse_events_add_pmu(data, list,
259 pmu->name, head)) {
260 pr_debug("%s -> %s/%s/\n", $1,
261 pmu->name, alias->str);
262 ok++;
263 }
264
265 parse_events_terms__delete(head);
266 }
267 }
268 }
269 if (!ok)
270 YYABORT;
248 $$ = list; 271 $$ = list;
249} 272}
250| 273|
@@ -259,7 +282,7 @@ PE_PMU_EVENT_PRE '-' PE_PMU_EVENT_SUF sep_dc
259 282
260 ALLOC_LIST(head); 283 ALLOC_LIST(head);
261 ABORT_ON(parse_events_term__num(&term, PARSE_EVENTS__TERM_TYPE_USER, 284 ABORT_ON(parse_events_term__num(&term, PARSE_EVENTS__TERM_TYPE_USER,
262 &pmu_name, 1, &@1, NULL)); 285 &pmu_name, 1, false, &@1, NULL));
263 list_add_tail(&term->list, head); 286 list_add_tail(&term->list, head);
264 287
265 ALLOC_LIST(list); 288 ALLOC_LIST(list);
@@ -525,7 +548,7 @@ PE_NAME '=' PE_VALUE
525 struct parse_events_term *term; 548 struct parse_events_term *term;
526 549
527 ABORT_ON(parse_events_term__num(&term, PARSE_EVENTS__TERM_TYPE_USER, 550 ABORT_ON(parse_events_term__num(&term, PARSE_EVENTS__TERM_TYPE_USER,
528 $1, $3, &@1, &@3)); 551 $1, $3, false, &@1, &@3));
529 $$ = term; 552 $$ = term;
530} 553}
531| 554|
@@ -543,7 +566,7 @@ PE_NAME
543 struct parse_events_term *term; 566 struct parse_events_term *term;
544 567
545 ABORT_ON(parse_events_term__num(&term, PARSE_EVENTS__TERM_TYPE_USER, 568 ABORT_ON(parse_events_term__num(&term, PARSE_EVENTS__TERM_TYPE_USER,
546 $1, 1, &@1, NULL)); 569 $1, 1, true, &@1, NULL));
547 $$ = term; 570 $$ = term;
548} 571}
549| 572|
@@ -568,7 +591,7 @@ PE_TERM '=' PE_VALUE
568{ 591{
569 struct parse_events_term *term; 592 struct parse_events_term *term;
570 593
571 ABORT_ON(parse_events_term__num(&term, (int)$1, NULL, $3, &@1, &@3)); 594 ABORT_ON(parse_events_term__num(&term, (int)$1, NULL, $3, false, &@1, &@3));
572 $$ = term; 595 $$ = term;
573} 596}
574| 597|
@@ -576,7 +599,7 @@ PE_TERM
576{ 599{
577 struct parse_events_term *term; 600 struct parse_events_term *term;
578 601
579 ABORT_ON(parse_events_term__num(&term, (int)$1, NULL, 1, &@1, NULL)); 602 ABORT_ON(parse_events_term__num(&term, (int)$1, NULL, 1, true, &@1, NULL));
580 $$ = term; 603 $$ = term;
581} 604}
582| 605|
@@ -597,7 +620,7 @@ PE_NAME array '=' PE_VALUE
597 struct parse_events_term *term; 620 struct parse_events_term *term;
598 621
599 ABORT_ON(parse_events_term__num(&term, PARSE_EVENTS__TERM_TYPE_USER, 622 ABORT_ON(parse_events_term__num(&term, PARSE_EVENTS__TERM_TYPE_USER,
600 $1, $4, &@1, &@4)); 623 $1, $4, false, &@1, &@4));
601 term->array = $2; 624 term->array = $2;
602 $$ = term; 625 $$ = term;
603} 626}
diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c
index dc6ccaa4e927..12f84dd2ac5d 100644
--- a/tools/perf/util/pmu.c
+++ b/tools/perf/util/pmu.c
@@ -94,32 +94,10 @@ static int pmu_format(const char *name, struct list_head *format)
94 return 0; 94 return 0;
95} 95}
96 96
97static int perf_pmu__parse_scale(struct perf_pmu_alias *alias, char *dir, char *name) 97static int convert_scale(const char *scale, char **end, double *sval)
98{ 98{
99 struct stat st;
100 ssize_t sret;
101 char scale[128];
102 int fd, ret = -1;
103 char path[PATH_MAX];
104 char *lc; 99 char *lc;
105 100 int ret = 0;
106 snprintf(path, PATH_MAX, "%s/%s.scale", dir, name);
107
108 fd = open(path, O_RDONLY);
109 if (fd == -1)
110 return -1;
111
112 if (fstat(fd, &st) < 0)
113 goto error;
114
115 sret = read(fd, scale, sizeof(scale)-1);
116 if (sret < 0)
117 goto error;
118
119 if (scale[sret - 1] == '\n')
120 scale[sret - 1] = '\0';
121 else
122 scale[sret] = '\0';
123 101
124 /* 102 /*
125 * save current locale 103 * save current locale
@@ -134,7 +112,7 @@ static int perf_pmu__parse_scale(struct perf_pmu_alias *alias, char *dir, char *
134 lc = strdup(lc); 112 lc = strdup(lc);
135 if (!lc) { 113 if (!lc) {
136 ret = -ENOMEM; 114 ret = -ENOMEM;
137 goto error; 115 goto out;
138 } 116 }
139 117
140 /* 118 /*
@@ -144,14 +122,42 @@ static int perf_pmu__parse_scale(struct perf_pmu_alias *alias, char *dir, char *
144 */ 122 */
145 setlocale(LC_NUMERIC, "C"); 123 setlocale(LC_NUMERIC, "C");
146 124
147 alias->scale = strtod(scale, NULL); 125 *sval = strtod(scale, end);
148 126
127out:
149 /* restore locale */ 128 /* restore locale */
150 setlocale(LC_NUMERIC, lc); 129 setlocale(LC_NUMERIC, lc);
151
152 free(lc); 130 free(lc);
131 return ret;
132}
133
134static int perf_pmu__parse_scale(struct perf_pmu_alias *alias, char *dir, char *name)
135{
136 struct stat st;
137 ssize_t sret;
138 char scale[128];
139 int fd, ret = -1;
140 char path[PATH_MAX];
153 141
154 ret = 0; 142 snprintf(path, PATH_MAX, "%s/%s.scale", dir, name);
143
144 fd = open(path, O_RDONLY);
145 if (fd == -1)
146 return -1;
147
148 if (fstat(fd, &st) < 0)
149 goto error;
150
151 sret = read(fd, scale, sizeof(scale)-1);
152 if (sret < 0)
153 goto error;
154
155 if (scale[sret - 1] == '\n')
156 scale[sret - 1] = '\0';
157 else
158 scale[sret] = '\0';
159
160 ret = convert_scale(scale, NULL, &alias->scale);
155error: 161error:
156 close(fd); 162 close(fd);
157 return ret; 163 return ret;
@@ -223,11 +229,13 @@ static int perf_pmu__parse_snapshot(struct perf_pmu_alias *alias,
223} 229}
224 230
225static int __perf_pmu__new_alias(struct list_head *list, char *dir, char *name, 231static int __perf_pmu__new_alias(struct list_head *list, char *dir, char *name,
226 char *desc, char *val, char *long_desc, 232 char *desc, char *val,
227 char *topic) 233 char *long_desc, char *topic,
234 char *unit, char *perpkg)
228{ 235{
229 struct perf_pmu_alias *alias; 236 struct perf_pmu_alias *alias;
230 int ret; 237 int ret;
238 int num;
231 239
232 alias = malloc(sizeof(*alias)); 240 alias = malloc(sizeof(*alias));
233 if (!alias) 241 if (!alias)
@@ -261,6 +269,13 @@ static int __perf_pmu__new_alias(struct list_head *list, char *dir, char *name,
261 alias->long_desc = long_desc ? strdup(long_desc) : 269 alias->long_desc = long_desc ? strdup(long_desc) :
262 desc ? strdup(desc) : NULL; 270 desc ? strdup(desc) : NULL;
263 alias->topic = topic ? strdup(topic) : NULL; 271 alias->topic = topic ? strdup(topic) : NULL;
272 if (unit) {
273 if (convert_scale(unit, &unit, &alias->scale) < 0)
274 return -1;
275 snprintf(alias->unit, sizeof(alias->unit), "%s", unit);
276 }
277 alias->per_pkg = perpkg && sscanf(perpkg, "%d", &num) == 1 && num == 1;
278 alias->str = strdup(val);
264 279
265 list_add_tail(&alias->list, list); 280 list_add_tail(&alias->list, list);
266 281
@@ -278,7 +293,8 @@ static int perf_pmu__new_alias(struct list_head *list, char *dir, char *name, FI
278 293
279 buf[ret] = 0; 294 buf[ret] = 0;
280 295
281 return __perf_pmu__new_alias(list, dir, name, NULL, buf, NULL, NULL); 296 return __perf_pmu__new_alias(list, dir, name, NULL, buf, NULL, NULL, NULL,
297 NULL);
282} 298}
283 299
284static inline bool pmu_alias_info_file(char *name) 300static inline bool pmu_alias_info_file(char *name)
@@ -498,7 +514,7 @@ char * __weak get_cpuid_str(void)
498 * to the current running CPU. Then, add all PMU events from that table 514 * to the current running CPU. Then, add all PMU events from that table
499 * as aliases. 515 * as aliases.
500 */ 516 */
501static void pmu_add_cpu_aliases(struct list_head *head) 517static void pmu_add_cpu_aliases(struct list_head *head, const char *name)
502{ 518{
503 int i; 519 int i;
504 struct pmu_events_map *map; 520 struct pmu_events_map *map;
@@ -534,14 +550,21 @@ static void pmu_add_cpu_aliases(struct list_head *head)
534 */ 550 */
535 i = 0; 551 i = 0;
536 while (1) { 552 while (1) {
553 const char *pname;
554
537 pe = &map->table[i++]; 555 pe = &map->table[i++];
538 if (!pe->name) 556 if (!pe->name)
539 break; 557 break;
540 558
559 pname = pe->pmu ? pe->pmu : "cpu";
560 if (strncmp(pname, name, strlen(pname)))
561 continue;
562
541 /* need type casts to override 'const' */ 563 /* need type casts to override 'const' */
542 __perf_pmu__new_alias(head, NULL, (char *)pe->name, 564 __perf_pmu__new_alias(head, NULL, (char *)pe->name,
543 (char *)pe->desc, (char *)pe->event, 565 (char *)pe->desc, (char *)pe->event,
544 (char *)pe->long_desc, (char *)pe->topic); 566 (char *)pe->long_desc, (char *)pe->topic,
567 (char *)pe->unit, (char *)pe->perpkg);
545 } 568 }
546 569
547out: 570out:
@@ -569,15 +592,16 @@ static struct perf_pmu *pmu_lookup(const char *name)
569 if (pmu_format(name, &format)) 592 if (pmu_format(name, &format))
570 return NULL; 593 return NULL;
571 594
572 if (pmu_aliases(name, &aliases)) 595 /*
596 * Check the type first to avoid unnecessary work.
597 */
598 if (pmu_type(name, &type))
573 return NULL; 599 return NULL;
574 600
575 if (!strcmp(name, "cpu")) 601 if (pmu_aliases(name, &aliases))
576 pmu_add_cpu_aliases(&aliases);
577
578 if (pmu_type(name, &type))
579 return NULL; 602 return NULL;
580 603
604 pmu_add_cpu_aliases(&aliases, name);
581 pmu = zalloc(sizeof(*pmu)); 605 pmu = zalloc(sizeof(*pmu));
582 if (!pmu) 606 if (!pmu)
583 return NULL; 607 return NULL;
@@ -721,7 +745,7 @@ static int pmu_resolve_param_term(struct parse_events_term *term,
721 } 745 }
722 } 746 }
723 747
724 if (verbose) 748 if (verbose > 0)
725 printf("Required parameter '%s' not specified\n", term->config); 749 printf("Required parameter '%s' not specified\n", term->config);
726 750
727 return -1; 751 return -1;
@@ -779,7 +803,7 @@ static int pmu_config_term(struct list_head *formats,
779 803
780 format = pmu_find_format(formats, term->config); 804 format = pmu_find_format(formats, term->config);
781 if (!format) { 805 if (!format) {
782 if (verbose) 806 if (verbose > 0)
783 printf("Invalid event/parameter '%s'\n", term->config); 807 printf("Invalid event/parameter '%s'\n", term->config);
784 if (err) { 808 if (err) {
785 char *pmu_term = pmu_formats_string(formats); 809 char *pmu_term = pmu_formats_string(formats);
@@ -810,11 +834,20 @@ static int pmu_config_term(struct list_head *formats,
810 * Either directly use a numeric term, or try to translate string terms 834 * Either directly use a numeric term, or try to translate string terms
811 * using event parameters. 835 * using event parameters.
812 */ 836 */
813 if (term->type_val == PARSE_EVENTS__TERM_TYPE_NUM) 837 if (term->type_val == PARSE_EVENTS__TERM_TYPE_NUM) {
838 if (term->no_value &&
839 bitmap_weight(format->bits, PERF_PMU_FORMAT_BITS) > 1) {
840 if (err) {
841 err->idx = term->err_val;
842 err->str = strdup("no value assigned for term");
843 }
844 return -EINVAL;
845 }
846
814 val = term->val.num; 847 val = term->val.num;
815 else if (term->type_val == PARSE_EVENTS__TERM_TYPE_STR) { 848 } else if (term->type_val == PARSE_EVENTS__TERM_TYPE_STR) {
816 if (strcmp(term->val.str, "?")) { 849 if (strcmp(term->val.str, "?")) {
817 if (verbose) { 850 if (verbose > 0) {
818 pr_info("Invalid sysfs entry %s=%s\n", 851 pr_info("Invalid sysfs entry %s=%s\n",
819 term->config, term->val.str); 852 term->config, term->val.str);
820 } 853 }
@@ -921,12 +954,12 @@ static int check_info_data(struct perf_pmu_alias *alias,
921 * define unit, scale and snapshot, fail 954 * define unit, scale and snapshot, fail
922 * if there's more than one. 955 * if there's more than one.
923 */ 956 */
924 if ((info->unit && alias->unit) || 957 if ((info->unit && alias->unit[0]) ||
925 (info->scale && alias->scale) || 958 (info->scale && alias->scale) ||
926 (info->snapshot && alias->snapshot)) 959 (info->snapshot && alias->snapshot))
927 return -EINVAL; 960 return -EINVAL;
928 961
929 if (alias->unit) 962 if (alias->unit[0])
930 info->unit = alias->unit; 963 info->unit = alias->unit;
931 964
932 if (alias->scale) 965 if (alias->scale)
@@ -1065,6 +1098,8 @@ struct sevent {
1065 char *name; 1098 char *name;
1066 char *desc; 1099 char *desc;
1067 char *topic; 1100 char *topic;
1101 char *str;
1102 char *pmu;
1068}; 1103};
1069 1104
1070static int cmp_sevent(const void *a, const void *b) 1105static int cmp_sevent(const void *a, const void *b)
@@ -1161,6 +1196,8 @@ void print_pmu_events(const char *event_glob, bool name_only, bool quiet_flag,
1161 aliases[j].desc = long_desc ? alias->long_desc : 1196 aliases[j].desc = long_desc ? alias->long_desc :
1162 alias->desc; 1197 alias->desc;
1163 aliases[j].topic = alias->topic; 1198 aliases[j].topic = alias->topic;
1199 aliases[j].str = alias->str;
1200 aliases[j].pmu = pmu->name;
1164 j++; 1201 j++;
1165 } 1202 }
1166 if (pmu->selectable && 1203 if (pmu->selectable &&
@@ -1175,6 +1212,9 @@ void print_pmu_events(const char *event_glob, bool name_only, bool quiet_flag,
1175 len = j; 1212 len = j;
1176 qsort(aliases, len, sizeof(struct sevent), cmp_sevent); 1213 qsort(aliases, len, sizeof(struct sevent), cmp_sevent);
1177 for (j = 0; j < len; j++) { 1214 for (j = 0; j < len; j++) {
1215 /* Skip duplicates */
1216 if (j > 0 && !strcmp(aliases[j].name, aliases[j - 1].name))
1217 continue;
1178 if (name_only) { 1218 if (name_only) {
1179 printf("%s ", aliases[j].name); 1219 printf("%s ", aliases[j].name);
1180 continue; 1220 continue;
@@ -1192,6 +1232,8 @@ void print_pmu_events(const char *event_glob, bool name_only, bool quiet_flag,
1192 printf("%*s", 8, "["); 1232 printf("%*s", 8, "[");
1193 wordwrap(aliases[j].desc, 8, columns, 0); 1233 wordwrap(aliases[j].desc, 8, columns, 0);
1194 printf("]\n"); 1234 printf("]\n");
1235 if (verbose > 0)
1236 printf("%*s%s/%s/\n", 8, "", aliases[j].pmu, aliases[j].str);
1195 } else 1237 } else
1196 printf(" %-50s [Kernel PMU event]\n", aliases[j].name); 1238 printf(" %-50s [Kernel PMU event]\n", aliases[j].name);
1197 printed++; 1239 printed++;
diff --git a/tools/perf/util/pmu.h b/tools/perf/util/pmu.h
index 25712034c815..00852ddc7741 100644
--- a/tools/perf/util/pmu.h
+++ b/tools/perf/util/pmu.h
@@ -43,6 +43,7 @@ struct perf_pmu_alias {
43 char *desc; 43 char *desc;
44 char *long_desc; 44 char *long_desc;
45 char *topic; 45 char *topic;
46 char *str;
46 struct list_head terms; /* HEAD struct parse_events_term -> list */ 47 struct list_head terms; /* HEAD struct parse_events_term -> list */
47 struct list_head list; /* ELEM */ 48 struct list_head list; /* ELEM */
48 char unit[UNIT_MAX_LEN+1]; 49 char unit[UNIT_MAX_LEN+1];
diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c
index 6a6f44dd594b..28fb62c32678 100644
--- a/tools/perf/util/probe-event.c
+++ b/tools/perf/util/probe-event.c
@@ -594,7 +594,7 @@ static int find_perf_probe_point_from_dwarf(struct probe_trace_point *tp,
594 pr_debug("try to find information at %" PRIx64 " in %s\n", addr, 594 pr_debug("try to find information at %" PRIx64 " in %s\n", addr,
595 tp->module ? : "kernel"); 595 tp->module ? : "kernel");
596 596
597 dinfo = debuginfo_cache__open(tp->module, verbose == 0); 597 dinfo = debuginfo_cache__open(tp->module, verbose <= 0);
598 if (dinfo) 598 if (dinfo)
599 ret = debuginfo__find_probe_point(dinfo, 599 ret = debuginfo__find_probe_point(dinfo,
600 (unsigned long)addr, pp); 600 (unsigned long)addr, pp);
@@ -2061,7 +2061,7 @@ static int find_perf_probe_point_from_map(struct probe_trace_point *tp,
2061 bool is_kprobe) 2061 bool is_kprobe)
2062{ 2062{
2063 struct symbol *sym = NULL; 2063 struct symbol *sym = NULL;
2064 struct map *map; 2064 struct map *map = NULL;
2065 u64 addr = tp->address; 2065 u64 addr = tp->address;
2066 int ret = -ENOENT; 2066 int ret = -ENOENT;
2067 2067
@@ -3023,20 +3023,17 @@ static int try_to_find_absolute_address(struct perf_probe_event *pev,
3023 3023
3024 tev->nargs = pev->nargs; 3024 tev->nargs = pev->nargs;
3025 tev->args = zalloc(sizeof(struct probe_trace_arg) * tev->nargs); 3025 tev->args = zalloc(sizeof(struct probe_trace_arg) * tev->nargs);
3026 if (!tev->args) { 3026 if (!tev->args)
3027 err = -ENOMEM;
3028 goto errout; 3027 goto errout;
3029 } 3028
3030 for (i = 0; i < tev->nargs; i++) 3029 for (i = 0; i < tev->nargs; i++)
3031 copy_to_probe_trace_arg(&tev->args[i], &pev->args[i]); 3030 copy_to_probe_trace_arg(&tev->args[i], &pev->args[i]);
3032 3031
3033 return 1; 3032 return 1;
3034 3033
3035errout: 3034errout:
3036 if (*tevs) { 3035 clear_probe_trace_events(*tevs, 1);
3037 clear_probe_trace_events(*tevs, 1); 3036 *tevs = NULL;
3038 *tevs = NULL;
3039 }
3040 return err; 3037 return err;
3041} 3038}
3042 3039
diff --git a/tools/perf/util/probe-finder.c b/tools/perf/util/probe-finder.c
index 0d9d6e0803b8..57cd268d4275 100644
--- a/tools/perf/util/probe-finder.c
+++ b/tools/perf/util/probe-finder.c
@@ -464,7 +464,7 @@ static int convert_variable_fields(Dwarf_Die *vr_die, const char *varname,
464 /* Verify it is a data structure */ 464 /* Verify it is a data structure */
465 tag = dwarf_tag(&type); 465 tag = dwarf_tag(&type);
466 if (tag != DW_TAG_structure_type && tag != DW_TAG_union_type) { 466 if (tag != DW_TAG_structure_type && tag != DW_TAG_union_type) {
467 pr_warning("%s is not a data structure nor an union.\n", 467 pr_warning("%s is not a data structure nor a union.\n",
468 varname); 468 varname);
469 return -EINVAL; 469 return -EINVAL;
470 } 470 }
@@ -479,7 +479,7 @@ static int convert_variable_fields(Dwarf_Die *vr_die, const char *varname,
479 } else { 479 } else {
480 /* Verify it is a data structure */ 480 /* Verify it is a data structure */
481 if (tag != DW_TAG_structure_type && tag != DW_TAG_union_type) { 481 if (tag != DW_TAG_structure_type && tag != DW_TAG_union_type) {
482 pr_warning("%s is not a data structure nor an union.\n", 482 pr_warning("%s is not a data structure nor a union.\n",
483 varname); 483 varname);
484 return -EINVAL; 484 return -EINVAL;
485 } 485 }
diff --git a/tools/perf/util/scripting-engines/Build b/tools/perf/util/scripting-engines/Build
index 6516e220c247..82d28c67e0f3 100644
--- a/tools/perf/util/scripting-engines/Build
+++ b/tools/perf/util/scripting-engines/Build
@@ -1,6 +1,6 @@
1libperf-$(CONFIG_LIBPERL) += trace-event-perl.o 1libperf-$(CONFIG_LIBPERL) += trace-event-perl.o
2libperf-$(CONFIG_LIBPYTHON) += trace-event-python.o 2libperf-$(CONFIG_LIBPYTHON) += trace-event-python.o
3 3
4CFLAGS_trace-event-perl.o += $(PERL_EMBED_CCOPTS) -Wno-redundant-decls -Wno-strict-prototypes -Wno-unused-parameter -Wno-shadow -Wno-undef -Wno-switch-default 4CFLAGS_trace-event-perl.o += $(PERL_EMBED_CCOPTS) -Wno-redundant-decls -Wno-strict-prototypes -Wno-unused-parameter -Wno-shadow -Wno-nested-externs -Wno-undef -Wno-switch-default
5 5
6CFLAGS_trace-event-python.o += $(PYTHON_EMBED_CCOPTS) -Wno-redundant-decls -Wno-strict-prototypes -Wno-unused-parameter -Wno-shadow 6CFLAGS_trace-event-python.o += $(PYTHON_EMBED_CCOPTS) -Wno-redundant-decls -Wno-strict-prototypes -Wno-unused-parameter -Wno-shadow
diff --git a/tools/perf/util/scripting-engines/trace-event-perl.c b/tools/perf/util/scripting-engines/trace-event-perl.c
index e55a132f69b7..dff043a29589 100644
--- a/tools/perf/util/scripting-engines/trace-event-perl.c
+++ b/tools/perf/util/scripting-engines/trace-event-perl.c
@@ -217,6 +217,7 @@ static void define_event_symbols(struct event_format *event,
217 cur_field_name); 217 cur_field_name);
218 break; 218 break;
219 case PRINT_HEX: 219 case PRINT_HEX:
220 case PRINT_HEX_STR:
220 define_event_symbols(event, ev_name, args->hex.field); 221 define_event_symbols(event, ev_name, args->hex.field);
221 define_event_symbols(event, ev_name, args->hex.size); 222 define_event_symbols(event, ev_name, args->hex.size);
222 break; 223 break;
@@ -309,10 +310,10 @@ static SV *perl_process_callchain(struct perf_sample *sample,
309 if (node->map) { 310 if (node->map) {
310 struct map *map = node->map; 311 struct map *map = node->map;
311 const char *dsoname = "[unknown]"; 312 const char *dsoname = "[unknown]";
312 if (map && map->dso && (map->dso->name || map->dso->long_name)) { 313 if (map && map->dso) {
313 if (symbol_conf.show_kernel_path && map->dso->long_name) 314 if (symbol_conf.show_kernel_path && map->dso->long_name)
314 dsoname = map->dso->long_name; 315 dsoname = map->dso->long_name;
315 else if (map->dso->name) 316 else
316 dsoname = map->dso->name; 317 dsoname = map->dso->name;
317 } 318 }
318 if (!hv_stores(elem, "dso", newSVpv(dsoname,0))) { 319 if (!hv_stores(elem, "dso", newSVpv(dsoname,0))) {
@@ -350,8 +351,10 @@ static void perl_process_tracepoint(struct perf_sample *sample,
350 if (evsel->attr.type != PERF_TYPE_TRACEPOINT) 351 if (evsel->attr.type != PERF_TYPE_TRACEPOINT)
351 return; 352 return;
352 353
353 if (!event) 354 if (!event) {
354 die("ug! no event found for type %" PRIu64, (u64)evsel->attr.config); 355 pr_debug("ug! no event found for type %" PRIu64, (u64)evsel->attr.config);
356 return;
357 }
355 358
356 pid = raw_field_value(event, "common_pid", data); 359 pid = raw_field_value(event, "common_pid", data);
357 360
diff --git a/tools/perf/util/scripting-engines/trace-event-python.c b/tools/perf/util/scripting-engines/trace-event-python.c
index 089438da1f7f..783326cfbaa6 100644
--- a/tools/perf/util/scripting-engines/trace-event-python.c
+++ b/tools/perf/util/scripting-engines/trace-event-python.c
@@ -236,6 +236,7 @@ static void define_event_symbols(struct event_format *event,
236 cur_field_name); 236 cur_field_name);
237 break; 237 break;
238 case PRINT_HEX: 238 case PRINT_HEX:
239 case PRINT_HEX_STR:
239 define_event_symbols(event, ev_name, args->hex.field); 240 define_event_symbols(event, ev_name, args->hex.field);
240 define_event_symbols(event, ev_name, args->hex.size); 241 define_event_symbols(event, ev_name, args->hex.size);
241 break; 242 break;
@@ -368,10 +369,10 @@ static PyObject *python_process_callchain(struct perf_sample *sample,
368 if (node->map) { 369 if (node->map) {
369 struct map *map = node->map; 370 struct map *map = node->map;
370 const char *dsoname = "[unknown]"; 371 const char *dsoname = "[unknown]";
371 if (map && map->dso && (map->dso->name || map->dso->long_name)) { 372 if (map && map->dso) {
372 if (symbol_conf.show_kernel_path && map->dso->long_name) 373 if (symbol_conf.show_kernel_path && map->dso->long_name)
373 dsoname = map->dso->long_name; 374 dsoname = map->dso->long_name;
374 else if (map->dso->name) 375 else
375 dsoname = map->dso->name; 376 dsoname = map->dso->name;
376 } 377 }
377 pydict_set_item_string_decref(pyelem, "dso", 378 pydict_set_item_string_decref(pyelem, "dso",
diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c
index f268201048a0..1dd617d116b5 100644
--- a/tools/perf/util/session.c
+++ b/tools/perf/util/session.c
@@ -932,7 +932,7 @@ static void branch_stack__printf(struct perf_sample *sample)
932 932
933 printf("..... %2"PRIu64": %016" PRIx64 " -> %016" PRIx64 " %hu cycles %s%s%s%s %x\n", 933 printf("..... %2"PRIu64": %016" PRIx64 " -> %016" PRIx64 " %hu cycles %s%s%s%s %x\n",
934 i, e->from, e->to, 934 i, e->from, e->to,
935 e->flags.cycles, 935 (unsigned short)e->flags.cycles,
936 e->flags.mispred ? "M" : " ", 936 e->flags.mispred ? "M" : " ",
937 e->flags.predicted ? "P" : " ", 937 e->flags.predicted ? "P" : " ",
938 e->flags.abort ? "A" : " ", 938 e->flags.abort ? "A" : " ",
@@ -1191,7 +1191,7 @@ static int
1191 u64 sample_type = evsel->attr.sample_type; 1191 u64 sample_type = evsel->attr.sample_type;
1192 u64 read_format = evsel->attr.read_format; 1192 u64 read_format = evsel->attr.read_format;
1193 1193
1194 /* Standard sample delievery. */ 1194 /* Standard sample delivery. */
1195 if (!(sample_type & PERF_SAMPLE_READ)) 1195 if (!(sample_type & PERF_SAMPLE_READ))
1196 return tool->sample(tool, event, sample, evsel, machine); 1196 return tool->sample(tool, event, sample, evsel, machine);
1197 1197
@@ -1901,7 +1901,7 @@ int maps__set_kallsyms_ref_reloc_sym(struct map **maps,
1901 const char *symbol_name, u64 addr) 1901 const char *symbol_name, u64 addr)
1902{ 1902{
1903 char *bracket; 1903 char *bracket;
1904 enum map_type i; 1904 int i;
1905 struct ref_reloc_sym *ref; 1905 struct ref_reloc_sym *ref;
1906 1906
1907 ref = zalloc(sizeof(struct ref_reloc_sym)); 1907 ref = zalloc(sizeof(struct ref_reloc_sym));
diff --git a/tools/perf/util/setup.py b/tools/perf/util/setup.py
index c8680984d2d6..af415febbc46 100644
--- a/tools/perf/util/setup.py
+++ b/tools/perf/util/setup.py
@@ -1,8 +1,15 @@
1#!/usr/bin/python2 1#!/usr/bin/python2
2 2
3from distutils.core import setup, Extension
4from os import getenv 3from os import getenv
5 4
5cc = getenv("CC")
6if cc == "clang":
7 from _sysconfigdata import build_time_vars
8 from re import sub
9 build_time_vars["CFLAGS"] = sub("-specs=[^ ]+", "", build_time_vars["CFLAGS"])
10
11from distutils.core import setup, Extension
12
6from distutils.command.build_ext import build_ext as _build_ext 13from distutils.command.build_ext import build_ext as _build_ext
7from distutils.command.install_lib import install_lib as _install_lib 14from distutils.command.install_lib import install_lib as _install_lib
8 15
diff --git a/tools/perf/util/sort.c b/tools/perf/util/sort.c
index df622f4e301e..0ff622288d24 100644
--- a/tools/perf/util/sort.c
+++ b/tools/perf/util/sort.c
@@ -151,7 +151,7 @@ static int64_t _sort__dso_cmp(struct map *map_l, struct map *map_r)
151 if (!dso_l || !dso_r) 151 if (!dso_l || !dso_r)
152 return cmp_null(dso_r, dso_l); 152 return cmp_null(dso_r, dso_l);
153 153
154 if (verbose) { 154 if (verbose > 0) {
155 dso_name_l = dso_l->long_name; 155 dso_name_l = dso_l->long_name;
156 dso_name_r = dso_r->long_name; 156 dso_name_r = dso_r->long_name;
157 } else { 157 } else {
@@ -172,8 +172,8 @@ static int _hist_entry__dso_snprintf(struct map *map, char *bf,
172 size_t size, unsigned int width) 172 size_t size, unsigned int width)
173{ 173{
174 if (map && map->dso) { 174 if (map && map->dso) {
175 const char *dso_name = !verbose ? map->dso->short_name : 175 const char *dso_name = verbose > 0 ? map->dso->long_name :
176 map->dso->long_name; 176 map->dso->short_name;
177 return repsep_snprintf(bf, size, "%-*.*s", width, width, dso_name); 177 return repsep_snprintf(bf, size, "%-*.*s", width, width, dso_name);
178 } 178 }
179 179
@@ -261,7 +261,7 @@ static int _hist_entry__sym_snprintf(struct map *map, struct symbol *sym,
261{ 261{
262 size_t ret = 0; 262 size_t ret = 0;
263 263
264 if (verbose) { 264 if (verbose > 0) {
265 char o = map ? dso__symtab_origin(map->dso) : '!'; 265 char o = map ? dso__symtab_origin(map->dso) : '!';
266 ret += repsep_snprintf(bf, size, "%-#*llx %c ", 266 ret += repsep_snprintf(bf, size, "%-#*llx %c ",
267 BITS_PER_LONG / 4 + 2, ip, o); 267 BITS_PER_LONG / 4 + 2, ip, o);
diff --git a/tools/perf/util/sort.h b/tools/perf/util/sort.h
index 7aff317fc7c4..796c847e2f00 100644
--- a/tools/perf/util/sort.h
+++ b/tools/perf/util/sort.h
@@ -108,7 +108,7 @@ struct hist_entry {
108 /* 108 /*
109 * Since perf diff only supports the stdio output, TUI 109 * Since perf diff only supports the stdio output, TUI
110 * fields are only accessed from perf report (or perf 110 * fields are only accessed from perf report (or perf
111 * top). So make it an union to reduce memory usage. 111 * top). So make it a union to reduce memory usage.
112 */ 112 */
113 struct hist_entry_diff diff; 113 struct hist_entry_diff diff;
114 struct /* for TUI */ { 114 struct /* for TUI */ {
diff --git a/tools/perf/util/stat.c b/tools/perf/util/stat.c
index 39345c2ddfc2..0d51334a9b46 100644
--- a/tools/perf/util/stat.c
+++ b/tools/perf/util/stat.c
@@ -344,7 +344,7 @@ int perf_stat_process_counter(struct perf_stat_config *config,
344 for (i = 0; i < 3; i++) 344 for (i = 0; i < 3; i++)
345 update_stats(&ps->res_stats[i], count[i]); 345 update_stats(&ps->res_stats[i], count[i]);
346 346
347 if (verbose) { 347 if (verbose > 0) {
348 fprintf(config->output, "%s: %" PRIu64 " %" PRIu64 " %" PRIu64 "\n", 348 fprintf(config->output, "%s: %" PRIu64 " %" PRIu64 " %" PRIu64 "\n",
349 perf_evsel__name(counter), count[0], count[1], count[2]); 349 perf_evsel__name(counter), count[0], count[1], count[2]);
350 } 350 }
diff --git a/tools/perf/util/strfilter.c b/tools/perf/util/strfilter.c
index bcae659b6546..efb53772e0ec 100644
--- a/tools/perf/util/strfilter.c
+++ b/tools/perf/util/strfilter.c
@@ -269,6 +269,7 @@ static int strfilter_node__sprint(struct strfilter_node *node, char *buf)
269 len = strfilter_node__sprint_pt(node->l, buf); 269 len = strfilter_node__sprint_pt(node->l, buf);
270 if (len < 0) 270 if (len < 0)
271 return len; 271 return len;
272 __fallthrough;
272 case '!': 273 case '!':
273 if (buf) { 274 if (buf) {
274 *(buf + len++) = *node->p; 275 *(buf + len++) = *node->p;
diff --git a/tools/perf/util/string.c b/tools/perf/util/string.c
index d8dfaf64b32e..bddca519dd58 100644
--- a/tools/perf/util/string.c
+++ b/tools/perf/util/string.c
@@ -21,6 +21,8 @@ s64 perf_atoll(const char *str)
21 case 'b': case 'B': 21 case 'b': case 'B':
22 if (*p) 22 if (*p)
23 goto out_err; 23 goto out_err;
24
25 __fallthrough;
24 case '\0': 26 case '\0':
25 return length; 27 return length;
26 default: 28 default:
diff --git a/tools/perf/util/symbol-elf.c b/tools/perf/util/symbol-elf.c
index adbc6c02c3aa..4e59ddeb4eda 100644
--- a/tools/perf/util/symbol-elf.c
+++ b/tools/perf/util/symbol-elf.c
@@ -213,7 +213,7 @@ static bool want_demangle(bool is_kernel_sym)
213 213
214static char *demangle_sym(struct dso *dso, int kmodule, const char *elf_name) 214static char *demangle_sym(struct dso *dso, int kmodule, const char *elf_name)
215{ 215{
216 int demangle_flags = verbose ? (DMGL_PARAMS | DMGL_ANSI) : DMGL_NO_OPTS; 216 int demangle_flags = verbose > 0 ? (DMGL_PARAMS | DMGL_ANSI) : DMGL_NO_OPTS;
217 char *demangled = NULL; 217 char *demangled = NULL;
218 218
219 /* 219 /*
diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c
index dc93940de351..70e389bc4af7 100644
--- a/tools/perf/util/symbol.c
+++ b/tools/perf/util/symbol.c
@@ -1460,9 +1460,11 @@ int dso__load(struct dso *dso, struct map *map)
1460 * DSO_BINARY_TYPE__BUILDID_DEBUGINFO to work 1460 * DSO_BINARY_TYPE__BUILDID_DEBUGINFO to work
1461 */ 1461 */
1462 if (!dso->has_build_id && 1462 if (!dso->has_build_id &&
1463 is_regular_file(dso->long_name) && 1463 is_regular_file(dso->long_name)) {
1464 filename__read_build_id(dso->long_name, build_id, BUILD_ID_SIZE) > 0) 1464 __symbol__join_symfs(name, PATH_MAX, dso->long_name);
1465 if (filename__read_build_id(name, build_id, BUILD_ID_SIZE) > 0)
1465 dso__set_build_id(dso, build_id); 1466 dso__set_build_id(dso, build_id);
1467 }
1466 1468
1467 /* 1469 /*
1468 * Iterate over candidate debug images. 1470 * Iterate over candidate debug images.
diff --git a/tools/perf/util/symbol_fprintf.c b/tools/perf/util/symbol_fprintf.c
index 7c6b33e8e2d2..63694e174e5c 100644
--- a/tools/perf/util/symbol_fprintf.c
+++ b/tools/perf/util/symbol_fprintf.c
@@ -21,7 +21,7 @@ size_t __symbol__fprintf_symname_offs(const struct symbol *sym,
21 unsigned long offset; 21 unsigned long offset;
22 size_t length; 22 size_t length;
23 23
24 if (sym && sym->name) { 24 if (sym) {
25 length = fprintf(fp, "%s", sym->name); 25 length = fprintf(fp, "%s", sym->name);
26 if (al && print_offsets) { 26 if (al && print_offsets) {
27 if (al->addr < sym->end) 27 if (al->addr < sym->end)
diff --git a/tools/perf/util/thread_map.c b/tools/perf/util/thread_map.c
index f9eab200fd75..7c3fcc538a70 100644
--- a/tools/perf/util/thread_map.c
+++ b/tools/perf/util/thread_map.c
@@ -93,7 +93,7 @@ struct thread_map *thread_map__new_by_uid(uid_t uid)
93{ 93{
94 DIR *proc; 94 DIR *proc;
95 int max_threads = 32, items, i; 95 int max_threads = 32, items, i;
96 char path[256]; 96 char path[NAME_MAX + 1 + 6];
97 struct dirent *dirent, **namelist = NULL; 97 struct dirent *dirent, **namelist = NULL;
98 struct thread_map *threads = thread_map__alloc(max_threads); 98 struct thread_map *threads = thread_map__alloc(max_threads);
99 99
diff --git a/tools/perf/util/trace-event-info.c b/tools/perf/util/trace-event-info.c
index d995743cb673..e7d60d05596d 100644
--- a/tools/perf/util/trace-event-info.c
+++ b/tools/perf/util/trace-event-info.c
@@ -42,7 +42,7 @@
42#include "evsel.h" 42#include "evsel.h"
43#include "debug.h" 43#include "debug.h"
44 44
45#define VERSION "0.5" 45#define VERSION "0.6"
46 46
47static int output_fd; 47static int output_fd;
48 48
@@ -170,6 +170,12 @@ static bool name_in_tp_list(char *sys, struct tracepoint_path *tps)
170 return false; 170 return false;
171} 171}
172 172
173#define for_each_event(dir, dent, tps) \
174 while ((dent = readdir(dir))) \
175 if (dent->d_type == DT_DIR && \
176 (strcmp(dent->d_name, ".")) && \
177 (strcmp(dent->d_name, ".."))) \
178
173static int copy_event_system(const char *sys, struct tracepoint_path *tps) 179static int copy_event_system(const char *sys, struct tracepoint_path *tps)
174{ 180{
175 struct dirent *dent; 181 struct dirent *dent;
@@ -186,12 +192,10 @@ static int copy_event_system(const char *sys, struct tracepoint_path *tps)
186 return -errno; 192 return -errno;
187 } 193 }
188 194
189 while ((dent = readdir(dir))) { 195 for_each_event(dir, dent, tps) {
190 if (dent->d_type != DT_DIR || 196 if (!name_in_tp_list(dent->d_name, tps))
191 strcmp(dent->d_name, ".") == 0 ||
192 strcmp(dent->d_name, "..") == 0 ||
193 !name_in_tp_list(dent->d_name, tps))
194 continue; 197 continue;
198
195 if (asprintf(&format, "%s/%s/format", sys, dent->d_name) < 0) { 199 if (asprintf(&format, "%s/%s/format", sys, dent->d_name) < 0) {
196 err = -ENOMEM; 200 err = -ENOMEM;
197 goto out; 201 goto out;
@@ -210,12 +214,10 @@ static int copy_event_system(const char *sys, struct tracepoint_path *tps)
210 } 214 }
211 215
212 rewinddir(dir); 216 rewinddir(dir);
213 while ((dent = readdir(dir))) { 217 for_each_event(dir, dent, tps) {
214 if (dent->d_type != DT_DIR || 218 if (!name_in_tp_list(dent->d_name, tps))
215 strcmp(dent->d_name, ".") == 0 ||
216 strcmp(dent->d_name, "..") == 0 ||
217 !name_in_tp_list(dent->d_name, tps))
218 continue; 219 continue;
220
219 if (asprintf(&format, "%s/%s/format", sys, dent->d_name) < 0) { 221 if (asprintf(&format, "%s/%s/format", sys, dent->d_name) < 0) {
220 err = -ENOMEM; 222 err = -ENOMEM;
221 goto out; 223 goto out;
@@ -290,13 +292,11 @@ static int record_event_files(struct tracepoint_path *tps)
290 goto out; 292 goto out;
291 } 293 }
292 294
293 while ((dent = readdir(dir))) { 295 for_each_event(dir, dent, tps) {
294 if (dent->d_type != DT_DIR || 296 if (strcmp(dent->d_name, "ftrace") == 0 ||
295 strcmp(dent->d_name, ".") == 0 ||
296 strcmp(dent->d_name, "..") == 0 ||
297 strcmp(dent->d_name, "ftrace") == 0 ||
298 !system_in_tp_list(dent->d_name, tps)) 297 !system_in_tp_list(dent->d_name, tps))
299 continue; 298 continue;
299
300 count++; 300 count++;
301 } 301 }
302 302
@@ -307,13 +307,11 @@ static int record_event_files(struct tracepoint_path *tps)
307 } 307 }
308 308
309 rewinddir(dir); 309 rewinddir(dir);
310 while ((dent = readdir(dir))) { 310 for_each_event(dir, dent, tps) {
311 if (dent->d_type != DT_DIR || 311 if (strcmp(dent->d_name, "ftrace") == 0 ||
312 strcmp(dent->d_name, ".") == 0 ||
313 strcmp(dent->d_name, "..") == 0 ||
314 strcmp(dent->d_name, "ftrace") == 0 ||
315 !system_in_tp_list(dent->d_name, tps)) 312 !system_in_tp_list(dent->d_name, tps))
316 continue; 313 continue;
314
317 if (asprintf(&sys, "%s/%s", path, dent->d_name) < 0) { 315 if (asprintf(&sys, "%s/%s", path, dent->d_name) < 0) {
318 err = -ENOMEM; 316 err = -ENOMEM;
319 goto out; 317 goto out;
@@ -379,6 +377,34 @@ out:
379 return err; 377 return err;
380} 378}
381 379
380static int record_saved_cmdline(void)
381{
382 unsigned int size;
383 char *path;
384 struct stat st;
385 int ret, err = 0;
386
387 path = get_tracing_file("saved_cmdlines");
388 if (!path) {
389 pr_debug("can't get tracing/saved_cmdline");
390 return -ENOMEM;
391 }
392
393 ret = stat(path, &st);
394 if (ret < 0) {
395 /* not found */
396 size = 0;
397 if (write(output_fd, &size, 8) != 8)
398 err = -EIO;
399 goto out;
400 }
401 err = record_file(path, 8);
402
403out:
404 put_tracing_file(path);
405 return err;
406}
407
382static void 408static void
383put_tracepoints_path(struct tracepoint_path *tps) 409put_tracepoints_path(struct tracepoint_path *tps)
384{ 410{
@@ -539,6 +565,9 @@ struct tracing_data *tracing_data_get(struct list_head *pattrs,
539 if (err) 565 if (err)
540 goto out; 566 goto out;
541 err = record_ftrace_printk(); 567 err = record_ftrace_printk();
568 if (err)
569 goto out;
570 err = record_saved_cmdline();
542 571
543out: 572out:
544 /* 573 /*
diff --git a/tools/perf/util/trace-event-parse.c b/tools/perf/util/trace-event-parse.c
index 33b52eaa39db..de0078e21408 100644
--- a/tools/perf/util/trace-event-parse.c
+++ b/tools/perf/util/trace-event-parse.c
@@ -160,6 +160,23 @@ void parse_ftrace_printk(struct pevent *pevent,
160 } 160 }
161} 161}
162 162
163void parse_saved_cmdline(struct pevent *pevent,
164 char *file, unsigned int size __maybe_unused)
165{
166 char *comm;
167 char *line;
168 char *next = NULL;
169 int pid;
170
171 line = strtok_r(file, "\n", &next);
172 while (line) {
173 sscanf(line, "%d %ms", &pid, &comm);
174 pevent_register_comm(pevent, comm, pid);
175 free(comm);
176 line = strtok_r(NULL, "\n", &next);
177 }
178}
179
163int parse_ftrace_file(struct pevent *pevent, char *buf, unsigned long size) 180int parse_ftrace_file(struct pevent *pevent, char *buf, unsigned long size)
164{ 181{
165 return pevent_parse_event(pevent, buf, size, "ftrace"); 182 return pevent_parse_event(pevent, buf, size, "ftrace");
diff --git a/tools/perf/util/trace-event-read.c b/tools/perf/util/trace-event-read.c
index b67a0ccf5ab9..27420159bf69 100644
--- a/tools/perf/util/trace-event-read.c
+++ b/tools/perf/util/trace-event-read.c
@@ -260,39 +260,53 @@ static int read_header_files(struct pevent *pevent)
260 260
261static int read_ftrace_file(struct pevent *pevent, unsigned long long size) 261static int read_ftrace_file(struct pevent *pevent, unsigned long long size)
262{ 262{
263 int ret;
263 char *buf; 264 char *buf;
264 265
265 buf = malloc(size); 266 buf = malloc(size);
266 if (buf == NULL) 267 if (buf == NULL) {
268 pr_debug("memory allocation failure\n");
267 return -1; 269 return -1;
270 }
268 271
269 if (do_read(buf, size) < 0) { 272 ret = do_read(buf, size);
270 free(buf); 273 if (ret < 0) {
271 return -1; 274 pr_debug("error reading ftrace file.\n");
275 goto out;
272 } 276 }
273 277
274 parse_ftrace_file(pevent, buf, size); 278 ret = parse_ftrace_file(pevent, buf, size);
279 if (ret < 0)
280 pr_debug("error parsing ftrace file.\n");
281out:
275 free(buf); 282 free(buf);
276 return 0; 283 return ret;
277} 284}
278 285
279static int read_event_file(struct pevent *pevent, char *sys, 286static int read_event_file(struct pevent *pevent, char *sys,
280 unsigned long long size) 287 unsigned long long size)
281{ 288{
289 int ret;
282 char *buf; 290 char *buf;
283 291
284 buf = malloc(size); 292 buf = malloc(size);
285 if (buf == NULL) 293 if (buf == NULL) {
294 pr_debug("memory allocation failure\n");
286 return -1; 295 return -1;
296 }
287 297
288 if (do_read(buf, size) < 0) { 298 ret = do_read(buf, size);
299 if (ret < 0) {
289 free(buf); 300 free(buf);
290 return -1; 301 goto out;
291 } 302 }
292 303
293 parse_event_file(pevent, buf, size, sys); 304 ret = parse_event_file(pevent, buf, size, sys);
305 if (ret < 0)
306 pr_debug("error parsing event file.\n");
307out:
294 free(buf); 308 free(buf);
295 return 0; 309 return ret;
296} 310}
297 311
298static int read_ftrace_files(struct pevent *pevent) 312static int read_ftrace_files(struct pevent *pevent)
@@ -341,6 +355,36 @@ static int read_event_files(struct pevent *pevent)
341 return 0; 355 return 0;
342} 356}
343 357
358static int read_saved_cmdline(struct pevent *pevent)
359{
360 unsigned long long size;
361 char *buf;
362 int ret;
363
364 /* it can have 0 size */
365 size = read8(pevent);
366 if (!size)
367 return 0;
368
369 buf = malloc(size + 1);
370 if (buf == NULL) {
371 pr_debug("memory allocation failure\n");
372 return -1;
373 }
374
375 ret = do_read(buf, size);
376 if (ret < 0) {
377 pr_debug("error reading saved cmdlines\n");
378 goto out;
379 }
380
381 parse_saved_cmdline(pevent, buf, size);
382 ret = 0;
383out:
384 free(buf);
385 return ret;
386}
387
344ssize_t trace_report(int fd, struct trace_event *tevent, bool __repipe) 388ssize_t trace_report(int fd, struct trace_event *tevent, bool __repipe)
345{ 389{
346 char buf[BUFSIZ]; 390 char buf[BUFSIZ];
@@ -379,10 +423,11 @@ ssize_t trace_report(int fd, struct trace_event *tevent, bool __repipe)
379 return -1; 423 return -1;
380 if (show_version) 424 if (show_version)
381 printf("version = %s\n", version); 425 printf("version = %s\n", version);
382 free(version);
383 426
384 if (do_read(buf, 1) < 0) 427 if (do_read(buf, 1) < 0) {
428 free(version);
385 return -1; 429 return -1;
430 }
386 file_bigendian = buf[0]; 431 file_bigendian = buf[0];
387 host_bigendian = bigendian(); 432 host_bigendian = bigendian();
388 433
@@ -423,6 +468,11 @@ ssize_t trace_report(int fd, struct trace_event *tevent, bool __repipe)
423 err = read_ftrace_printk(pevent); 468 err = read_ftrace_printk(pevent);
424 if (err) 469 if (err)
425 goto out; 470 goto out;
471 if (atof(version) >= 0.6) {
472 err = read_saved_cmdline(pevent);
473 if (err)
474 goto out;
475 }
426 476
427 size = trace_data_size; 477 size = trace_data_size;
428 repipe = false; 478 repipe = false;
@@ -438,5 +488,6 @@ ssize_t trace_report(int fd, struct trace_event *tevent, bool __repipe)
438out: 488out:
439 if (pevent) 489 if (pevent)
440 trace_event__cleanup(tevent); 490 trace_event__cleanup(tevent);
491 free(version);
441 return size; 492 return size;
442} 493}
diff --git a/tools/perf/util/trace-event.h b/tools/perf/util/trace-event.h
index b0af9c81bb0d..1fbc044f9eb0 100644
--- a/tools/perf/util/trace-event.h
+++ b/tools/perf/util/trace-event.h
@@ -42,6 +42,7 @@ raw_field_value(struct event_format *event, const char *name, void *data);
42 42
43void parse_proc_kallsyms(struct pevent *pevent, char *file, unsigned int size); 43void parse_proc_kallsyms(struct pevent *pevent, char *file, unsigned int size);
44void parse_ftrace_printk(struct pevent *pevent, char *file, unsigned int size); 44void parse_ftrace_printk(struct pevent *pevent, char *file, unsigned int size);
45void parse_saved_cmdline(struct pevent *pevent, char *file, unsigned int size);
45 46
46ssize_t trace_report(int fd, struct trace_event *tevent, bool repipe); 47ssize_t trace_report(int fd, struct trace_event *tevent, bool repipe);
47 48
diff --git a/tools/perf/util/unwind-libunwind-local.c b/tools/perf/util/unwind-libunwind-local.c
index 6fec84dff3f7..bfb9b7987692 100644
--- a/tools/perf/util/unwind-libunwind-local.c
+++ b/tools/perf/util/unwind-libunwind-local.c
@@ -35,6 +35,7 @@
35#include "util.h" 35#include "util.h"
36#include "debug.h" 36#include "debug.h"
37#include "asm/bug.h" 37#include "asm/bug.h"
38#include "dso.h"
38 39
39extern int 40extern int
40UNW_OBJ(dwarf_search_unwind_table) (unw_addr_space_t as, 41UNW_OBJ(dwarf_search_unwind_table) (unw_addr_space_t as,
@@ -297,15 +298,58 @@ static int read_unwind_spec_debug_frame(struct dso *dso,
297 int fd; 298 int fd;
298 u64 ofs = dso->data.debug_frame_offset; 299 u64 ofs = dso->data.debug_frame_offset;
299 300
301 /* debug_frame can reside in:
302 * - dso
303 * - debug pointed by symsrc_filename
304 * - gnu_debuglink, which doesn't necessary
305 * has to be pointed by symsrc_filename
306 */
300 if (ofs == 0) { 307 if (ofs == 0) {
301 fd = dso__data_get_fd(dso, machine); 308 fd = dso__data_get_fd(dso, machine);
302 if (fd < 0) 309 if (fd >= 0) {
303 return -EINVAL; 310 ofs = elf_section_offset(fd, ".debug_frame");
311 dso__data_put_fd(dso);
312 }
313
314 if (ofs <= 0) {
315 fd = open(dso->symsrc_filename, O_RDONLY);
316 if (fd >= 0) {
317 ofs = elf_section_offset(fd, ".debug_frame");
318 close(fd);
319 }
320 }
321
322 if (ofs <= 0) {
323 char *debuglink = malloc(PATH_MAX);
324 int ret = 0;
325
326 ret = dso__read_binary_type_filename(
327 dso, DSO_BINARY_TYPE__DEBUGLINK,
328 machine->root_dir, debuglink, PATH_MAX);
329 if (!ret) {
330 fd = open(debuglink, O_RDONLY);
331 if (fd >= 0) {
332 ofs = elf_section_offset(fd,
333 ".debug_frame");
334 close(fd);
335 }
336 }
337 if (ofs > 0) {
338 if (dso->symsrc_filename != NULL) {
339 pr_warning(
340 "%s: overwrite symsrc(%s,%s)\n",
341 __func__,
342 dso->symsrc_filename,
343 debuglink);
344 free(dso->symsrc_filename);
345 }
346 dso->symsrc_filename = debuglink;
347 } else {
348 free(debuglink);
349 }
350 }
304 351
305 /* Check the .debug_frame section for unwinding info */
306 ofs = elf_section_offset(fd, ".debug_frame");
307 dso->data.debug_frame_offset = ofs; 352 dso->data.debug_frame_offset = ofs;
308 dso__data_put_fd(dso);
309 } 353 }
310 354
311 *offset = ofs; 355 *offset = ofs;
diff --git a/tools/perf/util/util.c b/tools/perf/util/util.c
index 9ddd98827d12..d8b45cea54d0 100644
--- a/tools/perf/util/util.c
+++ b/tools/perf/util/util.c
@@ -85,7 +85,7 @@ int mkdir_p(char *path, mode_t mode)
85 return (stat(path, &st) && mkdir(path, mode)) ? -1 : 0; 85 return (stat(path, &st) && mkdir(path, mode)) ? -1 : 0;
86} 86}
87 87
88int rm_rf(char *path) 88int rm_rf(const char *path)
89{ 89{
90 DIR *dir; 90 DIR *dir;
91 int ret = 0; 91 int ret = 0;
@@ -789,3 +789,16 @@ int is_printable_array(char *p, unsigned int len)
789 } 789 }
790 return 1; 790 return 1;
791} 791}
792
793int unit_number__scnprintf(char *buf, size_t size, u64 n)
794{
795 char unit[4] = "BKMG";
796 int i = 0;
797
798 while (((n / 1024) > 1) && (i < 3)) {
799 n /= 1024;
800 i++;
801 }
802
803 return scnprintf(buf, size, "%" PRIu64 "%c", n, unit[i]);
804}
diff --git a/tools/perf/util/util.h b/tools/perf/util/util.h
index 1d639e38aa82..c74708da8571 100644
--- a/tools/perf/util/util.h
+++ b/tools/perf/util/util.h
@@ -209,7 +209,7 @@ static inline int sane_case(int x, int high)
209} 209}
210 210
211int mkdir_p(char *path, mode_t mode); 211int mkdir_p(char *path, mode_t mode);
212int rm_rf(char *path); 212int rm_rf(const char *path);
213struct strlist *lsdir(const char *name, bool (*filter)(const char *, struct dirent *)); 213struct strlist *lsdir(const char *name, bool (*filter)(const char *, struct dirent *));
214bool lsdir_no_dot_filter(const char *name, struct dirent *d); 214bool lsdir_no_dot_filter(const char *name, struct dirent *d);
215int copyfile(const char *from, const char *to); 215int copyfile(const char *from, const char *to);
@@ -363,4 +363,5 @@ int is_printable_array(char *p, unsigned int len);
363 363
364int timestamp__scnprintf_usec(u64 timestamp, char *buf, size_t sz); 364int timestamp__scnprintf_usec(u64 timestamp, char *buf, size_t sz);
365 365
366int unit_number__scnprintf(char *buf, size_t size, u64 n);
366#endif /* GIT_COMPAT_UTIL_H */ 367#endif /* GIT_COMPAT_UTIL_H */