aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf
diff options
context:
space:
mode:
Diffstat (limited to 'tools/perf')
-rw-r--r--tools/perf/Documentation/intel-pt.txt78
-rw-r--r--tools/perf/Documentation/itrace.txt8
-rw-r--r--tools/perf/Documentation/perf-ftrace.txt33
-rw-r--r--tools/perf/Documentation/perf-probe.txt8
-rw-r--r--tools/perf/Documentation/perf-script-perl.txt2
-rw-r--r--tools/perf/Documentation/perf-script-python.txt23
-rw-r--r--tools/perf/Documentation/perf-script.txt22
-rw-r--r--tools/perf/Documentation/perf-stat.txt14
-rw-r--r--tools/perf/Makefile.config38
-rw-r--r--tools/perf/Makefile.perf2
-rw-r--r--tools/perf/arch/Build2
-rw-r--r--tools/perf/arch/arm/util/cs-etm.c29
-rw-r--r--tools/perf/arch/common.c1
-rw-r--r--tools/perf/arch/powerpc/util/Build2
-rw-r--r--tools/perf/arch/powerpc/util/unwind-libdw.c73
-rw-r--r--tools/perf/arch/x86/tests/insn-x86-dat-32.c12
-rw-r--r--tools/perf/arch/x86/tests/insn-x86-dat-64.c30
-rw-r--r--tools/perf/arch/x86/tests/insn-x86-dat-src.c30
-rw-r--r--tools/perf/arch/x86/util/intel-bts.c4
-rw-r--r--tools/perf/arch/x86/util/intel-pt.c9
-rw-r--r--tools/perf/bench/numa.c2
-rw-r--r--tools/perf/builtin-c2c.c4
-rw-r--r--tools/perf/builtin-config.c67
-rw-r--r--tools/perf/builtin-diff.c5
-rw-r--r--tools/perf/builtin-ftrace.c159
-rw-r--r--tools/perf/builtin-help.c48
-rw-r--r--tools/perf/builtin-kmem.c4
-rw-r--r--tools/perf/builtin-record.c4
-rw-r--r--tools/perf/builtin-report.c8
-rw-r--r--tools/perf/builtin-sched.c2
-rw-r--r--tools/perf/builtin-script.c355
-rw-r--r--tools/perf/builtin-stat.c58
-rw-r--r--tools/perf/builtin-top.c4
-rw-r--r--tools/perf/builtin-trace.c4
-rw-r--r--tools/perf/jvmti/jvmti_agent.c2
-rw-r--r--tools/perf/jvmti/jvmti_agent.h2
-rw-r--r--tools/perf/jvmti/libjvmti.c5
-rw-r--r--tools/perf/pmu-events/Build4
-rw-r--r--tools/perf/pmu-events/jevents.c4
-rw-r--r--tools/perf/scripts/python/bin/intel-pt-events-record13
-rw-r--r--tools/perf/scripts/python/bin/intel-pt-events-report3
-rw-r--r--tools/perf/scripts/python/intel-pt-events.py128
-rw-r--r--tools/perf/tests/Build2
-rw-r--r--tools/perf/tests/attr.c10
-rw-r--r--tools/perf/tests/attr.py48
-rw-r--r--tools/perf/tests/bp_signal.c17
-rw-r--r--tools/perf/tests/bp_signal_overflow.c3
-rw-r--r--tools/perf/tests/bpf-script-test-prologue.c9
-rw-r--r--tools/perf/tests/builtin-test.c7
-rw-r--r--tools/perf/tests/code-reading.c20
-rw-r--r--tools/perf/tests/dwarf-unwind.c15
-rw-r--r--tools/perf/tests/parse-events.c13
-rw-r--r--tools/perf/tests/task-exit.c2
-rw-r--r--tools/perf/tests/tests.h3
-rw-r--r--tools/perf/ui/browsers/annotate.c54
-rw-r--r--tools/perf/ui/gtk/annotate.c3
-rw-r--r--tools/perf/ui/hist.c2
-rw-r--r--tools/perf/util/annotate.c82
-rw-r--r--tools/perf/util/annotate.h4
-rw-r--r--tools/perf/util/auxtrace.c18
-rw-r--r--tools/perf/util/auxtrace.h6
-rw-r--r--tools/perf/util/build-id.c45
-rw-r--r--tools/perf/util/build-id.h1
-rw-r--r--tools/perf/util/cache.h3
-rw-r--r--tools/perf/util/callchain.c13
-rw-r--r--tools/perf/util/config.c43
-rw-r--r--tools/perf/util/config.h4
-rw-r--r--tools/perf/util/data-convert-bt.c6
-rw-r--r--tools/perf/util/debug.h11
-rw-r--r--tools/perf/util/dso.c100
-rw-r--r--tools/perf/util/dso.h9
-rw-r--r--tools/perf/util/event.h121
-rw-r--r--tools/perf/util/evlist.h3
-rw-r--r--tools/perf/util/evsel.c54
-rw-r--r--tools/perf/util/evsel_fprintf.c33
-rw-r--r--tools/perf/util/genelf_debug.c5
-rw-r--r--tools/perf/util/header.c17
-rw-r--r--tools/perf/util/help-unknown-cmd.c2
-rw-r--r--tools/perf/util/intel-bts.c2
-rw-r--r--tools/perf/util/intel-pt-decoder/intel-pt-decoder.c304
-rw-r--r--tools/perf/util/intel-pt-decoder/intel-pt-decoder.h13
-rw-r--r--tools/perf/util/intel-pt-decoder/intel-pt-log.h4
-rw-r--r--tools/perf/util/intel-pt-decoder/intel-pt-pkt-decoder.c110
-rw-r--r--tools/perf/util/intel-pt-decoder/intel-pt-pkt-decoder.h7
-rw-r--r--tools/perf/util/intel-pt-decoder/x86-opcode-map.txt2
-rw-r--r--tools/perf/util/intel-pt.c642
-rw-r--r--tools/perf/util/machine.c21
-rw-r--r--tools/perf/util/pmu.h4
-rw-r--r--tools/perf/util/probe-event.c2
-rw-r--r--tools/perf/util/probe-event.h4
-rw-r--r--tools/perf/util/scripting-engines/trace-event-python.c5
-rw-r--r--tools/perf/util/session.c2
-rw-r--r--tools/perf/util/sort.c22
-rw-r--r--tools/perf/util/srcline.c49
-rw-r--r--tools/perf/util/stat-shadow.c33
-rw-r--r--tools/perf/util/stat.c2
-rw-r--r--tools/perf/util/stat.h2
-rw-r--r--tools/perf/util/strbuf.h4
-rw-r--r--tools/perf/util/symbol-elf.c41
-rw-r--r--tools/perf/util/symbol.c4
-rw-r--r--tools/perf/util/trace-event-parse.c4
-rw-r--r--tools/perf/util/unwind-libdw.c22
-rw-r--r--tools/perf/util/unwind-libunwind-local.c11
-rw-r--r--tools/perf/util/usage.c62
-rw-r--r--tools/perf/util/util.c52
-rw-r--r--tools/perf/util/util.h21
106 files changed, 2731 insertions, 813 deletions
diff --git a/tools/perf/Documentation/intel-pt.txt b/tools/perf/Documentation/intel-pt.txt
index b0b3007d3c9c..4b6cdbf8f935 100644
--- a/tools/perf/Documentation/intel-pt.txt
+++ b/tools/perf/Documentation/intel-pt.txt
@@ -108,6 +108,9 @@ approach is available to export the data to a postgresql database. Refer to
108script export-to-postgresql.py for more details, and to script 108script export-to-postgresql.py for more details, and to script
109call-graph-from-postgresql.py for an example of using the database. 109call-graph-from-postgresql.py for an example of using the database.
110 110
111There is also script intel-pt-events.py which provides an example of how to
112unpack the raw data for power events and PTWRITE.
113
111As mentioned above, it is easy to capture too much data. One way to limit the 114As mentioned above, it is easy to capture too much data. One way to limit the
112data captured is to use 'snapshot' mode which is explained further below. 115data captured is to use 'snapshot' mode which is explained further below.
113Refer to 'new snapshot option' and 'Intel PT modes of operation' further below. 116Refer to 'new snapshot option' and 'Intel PT modes of operation' further below.
@@ -364,6 +367,42 @@ cyc_thresh Specifies how frequently CYC packets are produced - see cyc
364 367
365 CYC packets are not requested by default. 368 CYC packets are not requested by default.
366 369
370pt Specifies pass-through which enables the 'branch' config term.
371
372 The default config selects 'pt' if it is available, so a user will
373 never need to specify this term.
374
375branch Enable branch tracing. Branch tracing is enabled by default so to
376 disable branch tracing use 'branch=0'.
377
378 The default config selects 'branch' if it is available.
379
380ptw Enable PTWRITE packets which are produced when a ptwrite instruction
381 is executed.
382
383 Support for this feature is indicated by:
384
385 /sys/bus/event_source/devices/intel_pt/caps/ptwrite
386
387 which contains "1" if the feature is supported and
388 "0" otherwise.
389
390fup_on_ptw Enable a FUP packet to follow the PTWRITE packet. The FUP packet
391 provides the address of the ptwrite instruction. In the absence of
392 fup_on_ptw, the decoder will use the address of the previous branch
393 if branch tracing is enabled, otherwise the address will be zero.
394 Note that fup_on_ptw will work even when branch tracing is disabled.
395
396pwr_evt Enable power events. The power events provide information about
397 changes to the CPU C-state.
398
399 Support for this feature is indicated by:
400
401 /sys/bus/event_source/devices/intel_pt/caps/power_event_trace
402
403 which contains "1" if the feature is supported and
404 "0" otherwise.
405
367 406
368new snapshot option 407new snapshot option
369------------------- 408-------------------
@@ -674,13 +713,15 @@ Having no option is the same as
674 713
675which, in turn, is the same as 714which, in turn, is the same as
676 715
677 --itrace=ibxe 716 --itrace=ibxwpe
678 717
679The letters are: 718The letters are:
680 719
681 i synthesize "instructions" events 720 i synthesize "instructions" events
682 b synthesize "branches" events 721 b synthesize "branches" events
683 x synthesize "transactions" events 722 x synthesize "transactions" events
723 w synthesize "ptwrite" events
724 p synthesize "power" events
684 c synthesize branches events (calls only) 725 c synthesize branches events (calls only)
685 r synthesize branches events (returns only) 726 r synthesize branches events (returns only)
686 e synthesize tracing error events 727 e synthesize tracing error events
@@ -699,7 +740,40 @@ and "r" can be combined to get calls and returns.
699'flags' field can be used in perf script to determine whether the event is a 740'flags' field can be used in perf script to determine whether the event is a
700tranasaction start, commit or abort. 741tranasaction start, commit or abort.
701 742
702Error events are new. They show where the decoder lost the trace. Error events 743Note that "instructions", "branches" and "transactions" events depend on code
744flow packets which can be disabled by using the config term "branch=0". Refer
745to the config terms section above.
746
747"ptwrite" events record the payload of the ptwrite instruction and whether
748"fup_on_ptw" was used. "ptwrite" events depend on PTWRITE packets which are
749recorded only if the "ptw" config term was used. Refer to the config terms
750section above. perf script "synth" field displays "ptwrite" information like
751this: "ip: 0 payload: 0x123456789abcdef0" where "ip" is 1 if "fup_on_ptw" was
752used.
753
754"Power" events correspond to power event packets and CBR (core-to-bus ratio)
755packets. While CBR packets are always recorded when tracing is enabled, power
756event packets are recorded only if the "pwr_evt" config term was used. Refer to
757the config terms section above. The power events record information about
758C-state changes, whereas CBR is indicative of CPU frequency. perf script
759"event,synth" fields display information like this:
760 cbr: cbr: 22 freq: 2189 MHz (200%)
761 mwait: hints: 0x60 extensions: 0x1
762 pwre: hw: 0 cstate: 2 sub-cstate: 0
763 exstop: ip: 1
764 pwrx: deepest cstate: 2 last cstate: 2 wake reason: 0x4
765Where:
766 "cbr" includes the frequency and the percentage of maximum non-turbo
767 "mwait" shows mwait hints and extensions
768 "pwre" shows C-state transitions (to a C-state deeper than C0) and
769 whether initiated by hardware
770 "exstop" indicates execution stopped and whether the IP was recorded
771 exactly,
772 "pwrx" indicates return to C0
773For more details refer to the Intel 64 and IA-32 Architectures Software
774Developer Manuals.
775
776Error events show where the decoder lost the trace. Error events
703are quite important. Users must know if what they are seeing is a complete 777are quite important. Users must know if what they are seeing is a complete
704picture or not. 778picture or not.
705 779
diff --git a/tools/perf/Documentation/itrace.txt b/tools/perf/Documentation/itrace.txt
index e2a4c5e0dbe5..a3abe04c779d 100644
--- a/tools/perf/Documentation/itrace.txt
+++ b/tools/perf/Documentation/itrace.txt
@@ -3,13 +3,15 @@
3 c synthesize branches events (calls only) 3 c synthesize branches events (calls only)
4 r synthesize branches events (returns only) 4 r synthesize branches events (returns only)
5 x synthesize transactions events 5 x synthesize transactions events
6 w synthesize ptwrite events
7 p synthesize power events
6 e synthesize error events 8 e synthesize error events
7 d create a debug log 9 d create a debug log
8 g synthesize a call chain (use with i or x) 10 g synthesize a call chain (use with i or x)
9 l synthesize last branch entries (use with i or x) 11 l synthesize last branch entries (use with i or x)
10 s skip initial number of events 12 s skip initial number of events
11 13
12 The default is all events i.e. the same as --itrace=ibxe 14 The default is all events i.e. the same as --itrace=ibxwpe
13 15
14 In addition, the period (default 100000) for instructions events 16 In addition, the period (default 100000) for instructions events
15 can be specified in units of: 17 can be specified in units of:
@@ -26,8 +28,8 @@
26 Also the number of last branch entries (default 64, max. 1024) for 28 Also the number of last branch entries (default 64, max. 1024) for
27 instructions or transactions events can be specified. 29 instructions or transactions events can be specified.
28 30
29 It is also possible to skip events generated (instructions, branches, transactions) 31 It is also possible to skip events generated (instructions, branches, transactions,
30 at the beginning. This is useful to ignore initialization code. 32 ptwrite, power) at the beginning. This is useful to ignore initialization code.
31 33
32 --itrace=i0nss1000000 34 --itrace=i0nss1000000
33 35
diff --git a/tools/perf/Documentation/perf-ftrace.txt b/tools/perf/Documentation/perf-ftrace.txt
index 6e6a8b22c859..721a447f046e 100644
--- a/tools/perf/Documentation/perf-ftrace.txt
+++ b/tools/perf/Documentation/perf-ftrace.txt
@@ -48,6 +48,39 @@ OPTIONS
48 Ranges of CPUs are specified with -: 0-2. 48 Ranges of CPUs are specified with -: 0-2.
49 Default is to trace on all online CPUs. 49 Default is to trace on all online CPUs.
50 50
51-T::
52--trace-funcs=::
53 Only trace functions given by the argument. Multiple functions
54 can be given by using this option more than once. The function
55 argument also can be a glob pattern. It will be passed to
56 'set_ftrace_filter' in tracefs.
57
58-N::
59--notrace-funcs=::
60 Do not trace functions given by the argument. Like -T option,
61 this can be used more than once to specify multiple functions
62 (or glob patterns). It will be passed to 'set_ftrace_notrace'
63 in tracefs.
64
65-G::
66--graph-funcs=::
67 Set graph filter on the given function (or a glob pattern).
68 This is useful for the function_graph tracer only and enables
69 tracing for functions executed from the given function.
70 This can be used more than once to specify multiple functions.
71 It will be passed to 'set_graph_function' in tracefs.
72
73-g::
74--nograph-funcs=::
75 Set graph notrace filter on the given function (or a glob pattern).
76 Like -G option, this is useful for the function_graph tracer only
77 and disables tracing for function executed from the given function.
78 This can be used more than once to specify multiple functions.
79 It will be passed to 'set_graph_notrace' in tracefs.
80
81-D::
82--graph-depth=::
83 Set max depth for function graph tracer to follow
51 84
52SEE ALSO 85SEE ALSO
53-------- 86--------
diff --git a/tools/perf/Documentation/perf-probe.txt b/tools/perf/Documentation/perf-probe.txt
index e6c9902c6d82..165c2b1d4317 100644
--- a/tools/perf/Documentation/perf-probe.txt
+++ b/tools/perf/Documentation/perf-probe.txt
@@ -240,9 +240,13 @@ Add a probe on schedule() function 12th line with recording cpu local variable:
240 or 240 or
241 ./perf probe --add='schedule:12 cpu' 241 ./perf probe --add='schedule:12 cpu'
242 242
243 this will add one or more probes which has the name start with "schedule". 243Add one or more probes which has the name start with "schedule".
244 244
245 Add probes on lines in schedule() function which calls update_rq_clock(). 245 ./perf probe schedule*
246 or
247 ./perf probe --add='schedule*'
248
249Add probes on lines in schedule() function which calls update_rq_clock().
246 250
247 ./perf probe 'schedule;update_rq_clock*' 251 ./perf probe 'schedule;update_rq_clock*'
248 or 252 or
diff --git a/tools/perf/Documentation/perf-script-perl.txt b/tools/perf/Documentation/perf-script-perl.txt
index dfbb506d2c34..142606c0ec9c 100644
--- a/tools/perf/Documentation/perf-script-perl.txt
+++ b/tools/perf/Documentation/perf-script-perl.txt
@@ -39,7 +39,7 @@ EVENT HANDLERS
39When perf script is invoked using a trace script, a user-defined 39When perf script is invoked using a trace script, a user-defined
40'handler function' is called for each event in the trace. If there's 40'handler function' is called for each event in the trace. If there's
41no handler function defined for a given event type, the event is 41no handler function defined for a given event type, the event is
42ignored (or passed to a 'trace_handled' function, see below) and the 42ignored (or passed to a 'trace_unhandled' function, see below) and the
43next event is processed. 43next event is processed.
44 44
45Most of the event's field values are passed as arguments to the 45Most of the event's field values are passed as arguments to the
diff --git a/tools/perf/Documentation/perf-script-python.txt b/tools/perf/Documentation/perf-script-python.txt
index 54acba221558..51ec2d20068a 100644
--- a/tools/perf/Documentation/perf-script-python.txt
+++ b/tools/perf/Documentation/perf-script-python.txt
@@ -149,10 +149,8 @@ def raw_syscalls__sys_enter(event_name, context, common_cpu,
149 print "id=%d, args=%s\n" % \ 149 print "id=%d, args=%s\n" % \
150 (id, args), 150 (id, args),
151 151
152def trace_unhandled(event_name, context, common_cpu, common_secs, common_nsecs, 152def trace_unhandled(event_name, context, event_fields_dict):
153 common_pid, common_comm): 153 print ' '.join(['%s=%s'%(k,str(v))for k,v in sorted(event_fields_dict.items())])
154 print_header(event_name, common_cpu, common_secs, common_nsecs,
155 common_pid, common_comm)
156 154
157def print_header(event_name, cpu, secs, nsecs, pid, comm): 155def print_header(event_name, cpu, secs, nsecs, pid, comm):
158 print "%-20s %5u %05u.%09u %8u %-20s " % \ 156 print "%-20s %5u %05u.%09u %8u %-20s " % \
@@ -321,7 +319,7 @@ So those are the essential steps in writing and running a script. The
321process can be generalized to any tracepoint or set of tracepoints 319process can be generalized to any tracepoint or set of tracepoints
322you're interested in - basically find the tracepoint(s) you're 320you're interested in - basically find the tracepoint(s) you're
323interested in by looking at the list of available events shown by 321interested in by looking at the list of available events shown by
324'perf list' and/or look in /sys/kernel/debug/tracing events for 322'perf list' and/or look in /sys/kernel/debug/tracing/events/ for
325detailed event and field info, record the corresponding trace data 323detailed event and field info, record the corresponding trace data
326using 'perf record', passing it the list of interesting events, 324using 'perf record', passing it the list of interesting events,
327generate a skeleton script using 'perf script -g python' and modify the 325generate a skeleton script using 'perf script -g python' and modify the
@@ -334,7 +332,7 @@ right place, you can have your script listed alongside the other
334scripts listed by the 'perf script -l' command e.g.: 332scripts listed by the 'perf script -l' command e.g.:
335 333
336---- 334----
337root@tropicana:~# perf script -l 335# perf script -l
338List of available trace scripts: 336List of available trace scripts:
339 wakeup-latency system-wide min/max/avg wakeup latency 337 wakeup-latency system-wide min/max/avg wakeup latency
340 rw-by-file <comm> r/w activity for a program, by file 338 rw-by-file <comm> r/w activity for a program, by file
@@ -383,8 +381,6 @@ source tree:
383 381
384---- 382----
385# ls -al kernel-source/tools/perf/scripts/python 383# ls -al kernel-source/tools/perf/scripts/python
386
387root@tropicana:/home/trz/src/tip# ls -al tools/perf/scripts/python
388total 32 384total 32
389drwxr-xr-x 4 trz trz 4096 2010-01-26 22:30 . 385drwxr-xr-x 4 trz trz 4096 2010-01-26 22:30 .
390drwxr-xr-x 4 trz trz 4096 2010-01-26 22:29 .. 386drwxr-xr-x 4 trz trz 4096 2010-01-26 22:29 ..
@@ -399,7 +395,7 @@ otherwise your script won't show up at run-time), 'perf script -l'
399should show a new entry for your script: 395should show a new entry for your script:
400 396
401---- 397----
402root@tropicana:~# perf script -l 398# perf script -l
403List of available trace scripts: 399List of available trace scripts:
404 wakeup-latency system-wide min/max/avg wakeup latency 400 wakeup-latency system-wide min/max/avg wakeup latency
405 rw-by-file <comm> r/w activity for a program, by file 401 rw-by-file <comm> r/w activity for a program, by file
@@ -437,7 +433,7 @@ EVENT HANDLERS
437When perf script is invoked using a trace script, a user-defined 433When perf script is invoked using a trace script, a user-defined
438'handler function' is called for each event in the trace. If there's 434'handler function' is called for each event in the trace. If there's
439no handler function defined for a given event type, the event is 435no handler function defined for a given event type, the event is
440ignored (or passed to a 'trace_handled' function, see below) and the 436ignored (or passed to a 'trace_unhandled' function, see below) and the
441next event is processed. 437next event is processed.
442 438
443Most of the event's field values are passed as arguments to the 439Most of the event's field values are passed as arguments to the
@@ -532,7 +528,7 @@ can implement a set of optional functions:
532gives scripts a chance to do setup tasks: 528gives scripts a chance to do setup tasks:
533 529
534---- 530----
535def trace_begin: 531def trace_begin():
536 pass 532 pass
537---- 533----
538 534
@@ -541,7 +537,7 @@ def trace_begin:
541 as display results: 537 as display results:
542 538
543---- 539----
544def trace_end: 540def trace_end():
545 pass 541 pass
546---- 542----
547 543
@@ -550,8 +546,7 @@ def trace_end:
550 of common arguments are passed into it: 546 of common arguments are passed into it:
551 547
552---- 548----
553def trace_unhandled(event_name, context, common_cpu, common_secs, 549def trace_unhandled(event_name, context, event_fields_dict):
554 common_nsecs, common_pid, common_comm):
555 pass 550 pass
556---- 551----
557 552
diff --git a/tools/perf/Documentation/perf-script.txt b/tools/perf/Documentation/perf-script.txt
index cb0eda3925e6..5ee8796be96e 100644
--- a/tools/perf/Documentation/perf-script.txt
+++ b/tools/perf/Documentation/perf-script.txt
@@ -116,8 +116,9 @@ OPTIONS
116--fields:: 116--fields::
117 Comma separated list of fields to print. Options are: 117 Comma separated list of fields to print. Options are:
118 comm, tid, pid, time, cpu, event, trace, ip, sym, dso, addr, symoff, 118 comm, tid, pid, time, cpu, event, trace, ip, sym, dso, addr, symoff,
119 srcline, period, iregs, brstack, brstacksym, flags, bpf-output, brstackinsn, 119 srcline, period, iregs, brstack, brstacksym, flags, bpf-output, brstackinsn, brstackoff,
120 callindent, insn, insnlen. Field list can be prepended with the type, trace, sw or hw, 120 callindent, insn, insnlen, synth.
121 Field list can be prepended with the type, trace, sw or hw,
121 to indicate to which event type the field list applies. 122 to indicate to which event type the field list applies.
122 e.g., -F sw:comm,tid,time,ip,sym and -F trace:time,cpu,trace 123 e.g., -F sw:comm,tid,time,ip,sym and -F trace:time,cpu,trace
123 124
@@ -130,6 +131,14 @@ OPTIONS
130 i.e., the specified fields apply to all event types if the type string 131 i.e., the specified fields apply to all event types if the type string
131 is not given. 132 is not given.
132 133
134 In addition to overriding fields, it is also possible to add or remove
135 fields from the defaults. For example
136
137 -F -cpu,+insn
138
139 removes the cpu field and adds the insn field. Adding/removing fields
140 cannot be mixed with normal overriding.
141
133 The arguments are processed in the order received. A later usage can 142 The arguments are processed in the order received. A later usage can
134 reset a prior request. e.g.: 143 reset a prior request. e.g.:
135 144
@@ -185,6 +194,9 @@ OPTIONS
185 instruction bytes and the instruction length of the current 194 instruction bytes and the instruction length of the current
186 instruction. 195 instruction.
187 196
197 The synth field is used by synthesized events which may be created when
198 Instruction Trace decoding.
199
188 Finally, a user may not set fields to none for all event types. 200 Finally, a user may not set fields to none for all event types.
189 i.e., -F "" is not allowed. 201 i.e., -F "" is not allowed.
190 202
@@ -203,6 +215,8 @@ OPTIONS
203 is printed. This is the full execution path leading to the sample. This is only supported when the 215 is printed. This is the full execution path leading to the sample. This is only supported when the
204 sample was recorded with perf record -b or -j any. 216 sample was recorded with perf record -b or -j any.
205 217
218 The brstackoff field will print an offset into a specific dso/binary.
219
206-k:: 220-k::
207--vmlinux=<file>:: 221--vmlinux=<file>::
208 vmlinux pathname 222 vmlinux pathname
@@ -311,6 +325,10 @@ include::itrace.txt[]
311 Set the maximum number of program blocks to print with brstackasm for 325 Set the maximum number of program blocks to print with brstackasm for
312 each sample. 326 each sample.
313 327
328--inline::
329 If a callgraph address belongs to an inlined function, the inline stack
330 will be printed. Each entry has function name and file/line.
331
314SEE ALSO 332SEE ALSO
315-------- 333--------
316linkperf:perf-record[1], linkperf:perf-script-perl[1], 334linkperf:perf-record[1], linkperf:perf-script-perl[1],
diff --git a/tools/perf/Documentation/perf-stat.txt b/tools/perf/Documentation/perf-stat.txt
index bd0e4417f2be..698076313606 100644
--- a/tools/perf/Documentation/perf-stat.txt
+++ b/tools/perf/Documentation/perf-stat.txt
@@ -239,6 +239,20 @@ taskset.
239--no-merge:: 239--no-merge::
240Do not merge results from same PMUs. 240Do not merge results from same PMUs.
241 241
242--smi-cost::
243Measure SMI cost if msr/aperf/ and msr/smi/ events are supported.
244
245During the measurement, the /sys/device/cpu/freeze_on_smi will be set to
246freeze core counters on SMI.
247The aperf counter will not be effected by the setting.
248The cost of SMI can be measured by (aperf - unhalted core cycles).
249
250In practice, the percentages of SMI cycles is very useful for performance
251oriented analysis. --metric_only will be applied by default.
252The output is SMI cycles%, equals to (aperf - unhalted core cycles) / aperf
253
254Users who wants to get the actual value can apply --no-metric-only.
255
242EXAMPLES 256EXAMPLES
243-------- 257--------
244 258
diff --git a/tools/perf/Makefile.config b/tools/perf/Makefile.config
index 8354d04b392f..bdf0e87f9b29 100644
--- a/tools/perf/Makefile.config
+++ b/tools/perf/Makefile.config
@@ -19,18 +19,18 @@ CFLAGS := $(EXTRA_CFLAGS) $(EXTRA_WARNINGS)
19 19
20include $(srctree)/tools/scripts/Makefile.arch 20include $(srctree)/tools/scripts/Makefile.arch
21 21
22$(call detected_var,ARCH) 22$(call detected_var,SRCARCH)
23 23
24NO_PERF_REGS := 1 24NO_PERF_REGS := 1
25 25
26# Additional ARCH settings for ppc 26# Additional ARCH settings for ppc
27ifeq ($(ARCH),powerpc) 27ifeq ($(SRCARCH),powerpc)
28 NO_PERF_REGS := 0 28 NO_PERF_REGS := 0
29 LIBUNWIND_LIBS := -lunwind -lunwind-ppc64 29 LIBUNWIND_LIBS := -lunwind -lunwind-ppc64
30endif 30endif
31 31
32# Additional ARCH settings for x86 32# Additional ARCH settings for x86
33ifeq ($(ARCH),x86) 33ifeq ($(SRCARCH),x86)
34 $(call detected,CONFIG_X86) 34 $(call detected,CONFIG_X86)
35 ifeq (${IS_64_BIT}, 1) 35 ifeq (${IS_64_BIT}, 1)
36 CFLAGS += -DHAVE_ARCH_X86_64_SUPPORT -DHAVE_SYSCALL_TABLE -I$(OUTPUT)arch/x86/include/generated 36 CFLAGS += -DHAVE_ARCH_X86_64_SUPPORT -DHAVE_SYSCALL_TABLE -I$(OUTPUT)arch/x86/include/generated
@@ -43,12 +43,12 @@ ifeq ($(ARCH),x86)
43 NO_PERF_REGS := 0 43 NO_PERF_REGS := 0
44endif 44endif
45 45
46ifeq ($(ARCH),arm) 46ifeq ($(SRCARCH),arm)
47 NO_PERF_REGS := 0 47 NO_PERF_REGS := 0
48 LIBUNWIND_LIBS = -lunwind -lunwind-arm 48 LIBUNWIND_LIBS = -lunwind -lunwind-arm
49endif 49endif
50 50
51ifeq ($(ARCH),arm64) 51ifeq ($(SRCARCH),arm64)
52 NO_PERF_REGS := 0 52 NO_PERF_REGS := 0
53 LIBUNWIND_LIBS = -lunwind -lunwind-aarch64 53 LIBUNWIND_LIBS = -lunwind -lunwind-aarch64
54endif 54endif
@@ -61,7 +61,7 @@ endif
61# Disable it on all other architectures in case libdw unwind 61# Disable it on all other architectures in case libdw unwind
62# support is detected in system. Add supported architectures 62# support is detected in system. Add supported architectures
63# to the check. 63# to the check.
64ifneq ($(ARCH),$(filter $(ARCH),x86 arm)) 64ifneq ($(SRCARCH),$(filter $(SRCARCH),x86 arm powerpc))
65 NO_LIBDW_DWARF_UNWIND := 1 65 NO_LIBDW_DWARF_UNWIND := 1
66endif 66endif
67 67
@@ -115,9 +115,9 @@ endif
115FEATURE_CHECK_CFLAGS-libbabeltrace := $(LIBBABELTRACE_CFLAGS) 115FEATURE_CHECK_CFLAGS-libbabeltrace := $(LIBBABELTRACE_CFLAGS)
116FEATURE_CHECK_LDFLAGS-libbabeltrace := $(LIBBABELTRACE_LDFLAGS) -lbabeltrace-ctf 116FEATURE_CHECK_LDFLAGS-libbabeltrace := $(LIBBABELTRACE_LDFLAGS) -lbabeltrace-ctf
117 117
118FEATURE_CHECK_CFLAGS-bpf = -I. -I$(srctree)/tools/include -I$(srctree)/tools/arch/$(ARCH)/include/uapi -I$(srctree)/tools/include/uapi 118FEATURE_CHECK_CFLAGS-bpf = -I. -I$(srctree)/tools/include -I$(srctree)/tools/arch/$(SRCARCH)/include/uapi -I$(srctree)/tools/include/uapi
119# include ARCH specific config 119# include ARCH specific config
120-include $(src-perf)/arch/$(ARCH)/Makefile 120-include $(src-perf)/arch/$(SRCARCH)/Makefile
121 121
122ifdef PERF_HAVE_ARCH_REGS_QUERY_REGISTER_OFFSET 122ifdef PERF_HAVE_ARCH_REGS_QUERY_REGISTER_OFFSET
123 CFLAGS += -DHAVE_ARCH_REGS_QUERY_REGISTER_OFFSET 123 CFLAGS += -DHAVE_ARCH_REGS_QUERY_REGISTER_OFFSET
@@ -228,12 +228,12 @@ ifeq ($(DEBUG),0)
228endif 228endif
229 229
230INC_FLAGS += -I$(src-perf)/util/include 230INC_FLAGS += -I$(src-perf)/util/include
231INC_FLAGS += -I$(src-perf)/arch/$(ARCH)/include 231INC_FLAGS += -I$(src-perf)/arch/$(SRCARCH)/include
232INC_FLAGS += -I$(srctree)/tools/include/uapi 232INC_FLAGS += -I$(srctree)/tools/include/uapi
233INC_FLAGS += -I$(srctree)/tools/include/ 233INC_FLAGS += -I$(srctree)/tools/include/
234INC_FLAGS += -I$(srctree)/tools/arch/$(ARCH)/include/uapi 234INC_FLAGS += -I$(srctree)/tools/arch/$(SRCARCH)/include/uapi
235INC_FLAGS += -I$(srctree)/tools/arch/$(ARCH)/include/ 235INC_FLAGS += -I$(srctree)/tools/arch/$(SRCARCH)/include/
236INC_FLAGS += -I$(srctree)/tools/arch/$(ARCH)/ 236INC_FLAGS += -I$(srctree)/tools/arch/$(SRCARCH)/
237 237
238# $(obj-perf) for generated common-cmds.h 238# $(obj-perf) for generated common-cmds.h
239# $(obj-perf)/util for generated bison/flex headers 239# $(obj-perf)/util for generated bison/flex headers
@@ -355,7 +355,7 @@ ifndef NO_LIBELF
355 355
356 ifndef NO_DWARF 356 ifndef NO_DWARF
357 ifeq ($(origin PERF_HAVE_DWARF_REGS), undefined) 357 ifeq ($(origin PERF_HAVE_DWARF_REGS), undefined)
358 msg := $(warning DWARF register mappings have not been defined for architecture $(ARCH), DWARF support disabled); 358 msg := $(warning DWARF register mappings have not been defined for architecture $(SRCARCH), DWARF support disabled);
359 NO_DWARF := 1 359 NO_DWARF := 1
360 else 360 else
361 CFLAGS += -DHAVE_DWARF_SUPPORT $(LIBDW_CFLAGS) 361 CFLAGS += -DHAVE_DWARF_SUPPORT $(LIBDW_CFLAGS)
@@ -380,7 +380,7 @@ ifndef NO_LIBELF
380 CFLAGS += -DHAVE_BPF_PROLOGUE 380 CFLAGS += -DHAVE_BPF_PROLOGUE
381 $(call detected,CONFIG_BPF_PROLOGUE) 381 $(call detected,CONFIG_BPF_PROLOGUE)
382 else 382 else
383 msg := $(warning BPF prologue is not supported by architecture $(ARCH), missing regs_query_register_offset()); 383 msg := $(warning BPF prologue is not supported by architecture $(SRCARCH), missing regs_query_register_offset());
384 endif 384 endif
385 else 385 else
386 msg := $(warning DWARF support is off, BPF prologue is disabled); 386 msg := $(warning DWARF support is off, BPF prologue is disabled);
@@ -406,7 +406,7 @@ ifdef PERF_HAVE_JITDUMP
406 endif 406 endif
407endif 407endif
408 408
409ifeq ($(ARCH),powerpc) 409ifeq ($(SRCARCH),powerpc)
410 ifndef NO_DWARF 410 ifndef NO_DWARF
411 CFLAGS += -DHAVE_SKIP_CALLCHAIN_IDX 411 CFLAGS += -DHAVE_SKIP_CALLCHAIN_IDX
412 endif 412 endif
@@ -487,7 +487,7 @@ else
487endif 487endif
488 488
489ifndef NO_LOCAL_LIBUNWIND 489ifndef NO_LOCAL_LIBUNWIND
490 ifeq ($(ARCH),$(filter $(ARCH),arm arm64)) 490 ifeq ($(SRCARCH),$(filter $(SRCARCH),arm arm64))
491 $(call feature_check,libunwind-debug-frame) 491 $(call feature_check,libunwind-debug-frame)
492 ifneq ($(feature-libunwind-debug-frame), 1) 492 ifneq ($(feature-libunwind-debug-frame), 1)
493 msg := $(warning No debug_frame support found in libunwind); 493 msg := $(warning No debug_frame support found in libunwind);
@@ -740,7 +740,7 @@ ifeq (${IS_64_BIT}, 1)
740 NO_PERF_READ_VDSO32 := 1 740 NO_PERF_READ_VDSO32 := 1
741 endif 741 endif
742 endif 742 endif
743 ifneq ($(ARCH), x86) 743 ifneq ($(SRCARCH), x86)
744 NO_PERF_READ_VDSOX32 := 1 744 NO_PERF_READ_VDSOX32 := 1
745 endif 745 endif
746 ifndef NO_PERF_READ_VDSOX32 746 ifndef NO_PERF_READ_VDSOX32
@@ -769,7 +769,7 @@ ifdef LIBBABELTRACE
769endif 769endif
770 770
771ifndef NO_AUXTRACE 771ifndef NO_AUXTRACE
772 ifeq ($(ARCH),x86) 772 ifeq ($(SRCARCH),x86)
773 ifeq ($(feature-get_cpuid), 0) 773 ifeq ($(feature-get_cpuid), 0)
774 msg := $(warning Your gcc lacks the __get_cpuid() builtin, disables support for auxtrace/Intel PT, please install a newer gcc); 774 msg := $(warning Your gcc lacks the __get_cpuid() builtin, disables support for auxtrace/Intel PT, please install a newer gcc);
775 NO_AUXTRACE := 1 775 NO_AUXTRACE := 1
@@ -872,7 +872,7 @@ sysconfdir = $(prefix)/etc
872ETC_PERFCONFIG = etc/perfconfig 872ETC_PERFCONFIG = etc/perfconfig
873endif 873endif
874ifndef lib 874ifndef lib
875ifeq ($(ARCH)$(IS_64_BIT), x861) 875ifeq ($(SRCARCH)$(IS_64_BIT), x861)
876lib = lib64 876lib = lib64
877else 877else
878lib = lib 878lib = lib
diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf
index 79fe31f20a17..5008f51a08a2 100644
--- a/tools/perf/Makefile.perf
+++ b/tools/perf/Makefile.perf
@@ -226,7 +226,7 @@ endif
226 226
227ifeq ($(config),0) 227ifeq ($(config),0)
228include $(srctree)/tools/scripts/Makefile.arch 228include $(srctree)/tools/scripts/Makefile.arch
229-include arch/$(ARCH)/Makefile 229-include arch/$(SRCARCH)/Makefile
230endif 230endif
231 231
232# The FEATURE_DUMP_EXPORT holds location of the actual 232# The FEATURE_DUMP_EXPORT holds location of the actual
diff --git a/tools/perf/arch/Build b/tools/perf/arch/Build
index 109eb75cf7de..d9b6af837c7d 100644
--- a/tools/perf/arch/Build
+++ b/tools/perf/arch/Build
@@ -1,2 +1,2 @@
1libperf-y += common.o 1libperf-y += common.o
2libperf-y += $(ARCH)/ 2libperf-y += $(SRCARCH)/
diff --git a/tools/perf/arch/arm/util/cs-etm.c b/tools/perf/arch/arm/util/cs-etm.c
index 29361d9b635a..7ce3d1a25133 100644
--- a/tools/perf/arch/arm/util/cs-etm.c
+++ b/tools/perf/arch/arm/util/cs-etm.c
@@ -17,6 +17,7 @@
17 17
18#include <api/fs/fs.h> 18#include <api/fs/fs.h>
19#include <linux/bitops.h> 19#include <linux/bitops.h>
20#include <linux/compiler.h>
20#include <linux/coresight-pmu.h> 21#include <linux/coresight-pmu.h>
21#include <linux/kernel.h> 22#include <linux/kernel.h>
22#include <linux/log2.h> 23#include <linux/log2.h>
@@ -202,19 +203,18 @@ static int cs_etm_recording_options(struct auxtrace_record *itr,
202 pr_debug2("%s snapshot size: %zu\n", CORESIGHT_ETM_PMU_NAME, 203 pr_debug2("%s snapshot size: %zu\n", CORESIGHT_ETM_PMU_NAME,
203 opts->auxtrace_snapshot_size); 204 opts->auxtrace_snapshot_size);
204 205
205 if (cs_etm_evsel) { 206 /*
206 /* 207 * To obtain the auxtrace buffer file descriptor, the auxtrace
207 * To obtain the auxtrace buffer file descriptor, the auxtrace 208 * event must come first.
208 * event must come first. 209 */
209 */ 210 perf_evlist__to_front(evlist, cs_etm_evsel);
210 perf_evlist__to_front(evlist, cs_etm_evsel); 211
211 /* 212 /*
212 * In the case of per-cpu mmaps, we need the CPU on the 213 * In the case of per-cpu mmaps, we need the CPU on the
213 * AUX event. 214 * AUX event.
214 */ 215 */
215 if (!cpu_map__empty(cpus)) 216 if (!cpu_map__empty(cpus))
216 perf_evsel__set_sample_bit(cs_etm_evsel, CPU); 217 perf_evsel__set_sample_bit(cs_etm_evsel, CPU);
217 }
218 218
219 /* Add dummy event to keep tracking */ 219 /* Add dummy event to keep tracking */
220 if (opts->full_auxtrace) { 220 if (opts->full_auxtrace) {
@@ -583,8 +583,7 @@ static FILE *cs_device__open_file(const char *name)
583 583
584} 584}
585 585
586static __attribute__((format(printf, 2, 3))) 586static int __printf(2, 3) cs_device__print_file(const char *name, const char *fmt, ...)
587int cs_device__print_file(const char *name, const char *fmt, ...)
588{ 587{
589 va_list args; 588 va_list args;
590 FILE *file; 589 FILE *file;
diff --git a/tools/perf/arch/common.c b/tools/perf/arch/common.c
index 837067f48a4c..6b40e9f01740 100644
--- a/tools/perf/arch/common.c
+++ b/tools/perf/arch/common.c
@@ -26,6 +26,7 @@ const char *const arm64_triplets[] = {
26 26
27const char *const powerpc_triplets[] = { 27const char *const powerpc_triplets[] = {
28 "powerpc-unknown-linux-gnu-", 28 "powerpc-unknown-linux-gnu-",
29 "powerpc-linux-gnu-",
29 "powerpc64-unknown-linux-gnu-", 30 "powerpc64-unknown-linux-gnu-",
30 "powerpc64-linux-gnu-", 31 "powerpc64-linux-gnu-",
31 "powerpc64le-linux-gnu-", 32 "powerpc64le-linux-gnu-",
diff --git a/tools/perf/arch/powerpc/util/Build b/tools/perf/arch/powerpc/util/Build
index 90ad64b231cd..2e6595310420 100644
--- a/tools/perf/arch/powerpc/util/Build
+++ b/tools/perf/arch/powerpc/util/Build
@@ -5,4 +5,6 @@ libperf-y += perf_regs.o
5 5
6libperf-$(CONFIG_DWARF) += dwarf-regs.o 6libperf-$(CONFIG_DWARF) += dwarf-regs.o
7libperf-$(CONFIG_DWARF) += skip-callchain-idx.o 7libperf-$(CONFIG_DWARF) += skip-callchain-idx.o
8
8libperf-$(CONFIG_LIBUNWIND) += unwind-libunwind.o 9libperf-$(CONFIG_LIBUNWIND) += unwind-libunwind.o
10libperf-$(CONFIG_LIBDW_DWARF_UNWIND) += unwind-libdw.o
diff --git a/tools/perf/arch/powerpc/util/unwind-libdw.c b/tools/perf/arch/powerpc/util/unwind-libdw.c
new file mode 100644
index 000000000000..3a24b3c43273
--- /dev/null
+++ b/tools/perf/arch/powerpc/util/unwind-libdw.c
@@ -0,0 +1,73 @@
1#include <elfutils/libdwfl.h>
2#include "../../util/unwind-libdw.h"
3#include "../../util/perf_regs.h"
4#include "../../util/event.h"
5
6/* See backends/ppc_initreg.c and backends/ppc_regs.c in elfutils. */
7static const int special_regs[3][2] = {
8 { 65, PERF_REG_POWERPC_LINK },
9 { 101, PERF_REG_POWERPC_XER },
10 { 109, PERF_REG_POWERPC_CTR },
11};
12
13bool libdw__arch_set_initial_registers(Dwfl_Thread *thread, void *arg)
14{
15 struct unwind_info *ui = arg;
16 struct regs_dump *user_regs = &ui->sample->user_regs;
17 Dwarf_Word dwarf_regs[32], dwarf_nip;
18 size_t i;
19
20#define REG(r) ({ \
21 Dwarf_Word val = 0; \
22 perf_reg_value(&val, user_regs, PERF_REG_POWERPC_##r); \
23 val; \
24})
25
26 dwarf_regs[0] = REG(R0);
27 dwarf_regs[1] = REG(R1);
28 dwarf_regs[2] = REG(R2);
29 dwarf_regs[3] = REG(R3);
30 dwarf_regs[4] = REG(R4);
31 dwarf_regs[5] = REG(R5);
32 dwarf_regs[6] = REG(R6);
33 dwarf_regs[7] = REG(R7);
34 dwarf_regs[8] = REG(R8);
35 dwarf_regs[9] = REG(R9);
36 dwarf_regs[10] = REG(R10);
37 dwarf_regs[11] = REG(R11);
38 dwarf_regs[12] = REG(R12);
39 dwarf_regs[13] = REG(R13);
40 dwarf_regs[14] = REG(R14);
41 dwarf_regs[15] = REG(R15);
42 dwarf_regs[16] = REG(R16);
43 dwarf_regs[17] = REG(R17);
44 dwarf_regs[18] = REG(R18);
45 dwarf_regs[19] = REG(R19);
46 dwarf_regs[20] = REG(R20);
47 dwarf_regs[21] = REG(R21);
48 dwarf_regs[22] = REG(R22);
49 dwarf_regs[23] = REG(R23);
50 dwarf_regs[24] = REG(R24);
51 dwarf_regs[25] = REG(R25);
52 dwarf_regs[26] = REG(R26);
53 dwarf_regs[27] = REG(R27);
54 dwarf_regs[28] = REG(R28);
55 dwarf_regs[29] = REG(R29);
56 dwarf_regs[30] = REG(R30);
57 dwarf_regs[31] = REG(R31);
58 if (!dwfl_thread_state_registers(thread, 0, 32, dwarf_regs))
59 return false;
60
61 dwarf_nip = REG(NIP);
62 dwfl_thread_state_register_pc(thread, dwarf_nip);
63 for (i = 0; i < ARRAY_SIZE(special_regs); i++) {
64 Dwarf_Word val = 0;
65 perf_reg_value(&val, user_regs, special_regs[i][1]);
66 if (!dwfl_thread_state_registers(thread,
67 special_regs[i][0], 1,
68 &val))
69 return false;
70 }
71
72 return true;
73}
diff --git a/tools/perf/arch/x86/tests/insn-x86-dat-32.c b/tools/perf/arch/x86/tests/insn-x86-dat-32.c
index 0f196eec9f48..3cbf6fad169f 100644
--- a/tools/perf/arch/x86/tests/insn-x86-dat-32.c
+++ b/tools/perf/arch/x86/tests/insn-x86-dat-32.c
@@ -1664,3 +1664,15 @@
1664"0f c7 1d 78 56 34 12 \txrstors 0x12345678",}, 1664"0f c7 1d 78 56 34 12 \txrstors 0x12345678",},
1665{{0x0f, 0xc7, 0x9c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 8, 0, "", "", 1665{{0x0f, 0xc7, 0x9c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 8, 0, "", "",
1666"0f c7 9c c8 78 56 34 12 \txrstors 0x12345678(%eax,%ecx,8)",}, 1666"0f c7 9c c8 78 56 34 12 \txrstors 0x12345678(%eax,%ecx,8)",},
1667{{0xf3, 0x0f, 0xae, 0x20, }, 4, 0, "", "",
1668"f3 0f ae 20 \tptwritel (%eax)",},
1669{{0xf3, 0x0f, 0xae, 0x25, 0x78, 0x56, 0x34, 0x12, }, 8, 0, "", "",
1670"f3 0f ae 25 78 56 34 12 \tptwritel 0x12345678",},
1671{{0xf3, 0x0f, 0xae, 0xa4, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
1672"f3 0f ae a4 c8 78 56 34 12 \tptwritel 0x12345678(%eax,%ecx,8)",},
1673{{0xf3, 0x0f, 0xae, 0x20, }, 4, 0, "", "",
1674"f3 0f ae 20 \tptwritel (%eax)",},
1675{{0xf3, 0x0f, 0xae, 0x25, 0x78, 0x56, 0x34, 0x12, }, 8, 0, "", "",
1676"f3 0f ae 25 78 56 34 12 \tptwritel 0x12345678",},
1677{{0xf3, 0x0f, 0xae, 0xa4, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
1678"f3 0f ae a4 c8 78 56 34 12 \tptwritel 0x12345678(%eax,%ecx,8)",},
diff --git a/tools/perf/arch/x86/tests/insn-x86-dat-64.c b/tools/perf/arch/x86/tests/insn-x86-dat-64.c
index af25bc8240d0..aa512fa944dd 100644
--- a/tools/perf/arch/x86/tests/insn-x86-dat-64.c
+++ b/tools/perf/arch/x86/tests/insn-x86-dat-64.c
@@ -1696,3 +1696,33 @@
1696"0f c7 9c c8 78 56 34 12 \txrstors 0x12345678(%rax,%rcx,8)",}, 1696"0f c7 9c c8 78 56 34 12 \txrstors 0x12345678(%rax,%rcx,8)",},
1697{{0x41, 0x0f, 0xc7, 0x9c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "", 1697{{0x41, 0x0f, 0xc7, 0x9c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
1698"41 0f c7 9c c8 78 56 34 12 \txrstors 0x12345678(%r8,%rcx,8)",}, 1698"41 0f c7 9c c8 78 56 34 12 \txrstors 0x12345678(%r8,%rcx,8)",},
1699{{0xf3, 0x0f, 0xae, 0x20, }, 4, 0, "", "",
1700"f3 0f ae 20 \tptwritel (%rax)",},
1701{{0xf3, 0x41, 0x0f, 0xae, 0x20, }, 5, 0, "", "",
1702"f3 41 0f ae 20 \tptwritel (%r8)",},
1703{{0xf3, 0x0f, 0xae, 0x24, 0x25, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
1704"f3 0f ae 24 25 78 56 34 12 \tptwritel 0x12345678",},
1705{{0xf3, 0x0f, 0xae, 0xa4, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
1706"f3 0f ae a4 c8 78 56 34 12 \tptwritel 0x12345678(%rax,%rcx,8)",},
1707{{0xf3, 0x41, 0x0f, 0xae, 0xa4, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 10, 0, "", "",
1708"f3 41 0f ae a4 c8 78 56 34 12 \tptwritel 0x12345678(%r8,%rcx,8)",},
1709{{0xf3, 0x0f, 0xae, 0x20, }, 4, 0, "", "",
1710"f3 0f ae 20 \tptwritel (%rax)",},
1711{{0xf3, 0x41, 0x0f, 0xae, 0x20, }, 5, 0, "", "",
1712"f3 41 0f ae 20 \tptwritel (%r8)",},
1713{{0xf3, 0x0f, 0xae, 0x24, 0x25, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
1714"f3 0f ae 24 25 78 56 34 12 \tptwritel 0x12345678",},
1715{{0xf3, 0x0f, 0xae, 0xa4, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
1716"f3 0f ae a4 c8 78 56 34 12 \tptwritel 0x12345678(%rax,%rcx,8)",},
1717{{0xf3, 0x41, 0x0f, 0xae, 0xa4, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 10, 0, "", "",
1718"f3 41 0f ae a4 c8 78 56 34 12 \tptwritel 0x12345678(%r8,%rcx,8)",},
1719{{0xf3, 0x48, 0x0f, 0xae, 0x20, }, 5, 0, "", "",
1720"f3 48 0f ae 20 \tptwriteq (%rax)",},
1721{{0xf3, 0x49, 0x0f, 0xae, 0x20, }, 5, 0, "", "",
1722"f3 49 0f ae 20 \tptwriteq (%r8)",},
1723{{0xf3, 0x48, 0x0f, 0xae, 0x24, 0x25, 0x78, 0x56, 0x34, 0x12, }, 10, 0, "", "",
1724"f3 48 0f ae 24 25 78 56 34 12 \tptwriteq 0x12345678",},
1725{{0xf3, 0x48, 0x0f, 0xae, 0xa4, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 10, 0, "", "",
1726"f3 48 0f ae a4 c8 78 56 34 12 \tptwriteq 0x12345678(%rax,%rcx,8)",},
1727{{0xf3, 0x49, 0x0f, 0xae, 0xa4, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 10, 0, "", "",
1728"f3 49 0f ae a4 c8 78 56 34 12 \tptwriteq 0x12345678(%r8,%rcx,8)",},
diff --git a/tools/perf/arch/x86/tests/insn-x86-dat-src.c b/tools/perf/arch/x86/tests/insn-x86-dat-src.c
index 979487dae8d4..6cdb65d25b79 100644
--- a/tools/perf/arch/x86/tests/insn-x86-dat-src.c
+++ b/tools/perf/arch/x86/tests/insn-x86-dat-src.c
@@ -1343,6 +1343,26 @@ int main(void)
1343 asm volatile("xrstors 0x12345678(%rax,%rcx,8)"); 1343 asm volatile("xrstors 0x12345678(%rax,%rcx,8)");
1344 asm volatile("xrstors 0x12345678(%r8,%rcx,8)"); 1344 asm volatile("xrstors 0x12345678(%r8,%rcx,8)");
1345 1345
1346 /* ptwrite */
1347
1348 asm volatile("ptwrite (%rax)");
1349 asm volatile("ptwrite (%r8)");
1350 asm volatile("ptwrite (0x12345678)");
1351 asm volatile("ptwrite 0x12345678(%rax,%rcx,8)");
1352 asm volatile("ptwrite 0x12345678(%r8,%rcx,8)");
1353
1354 asm volatile("ptwritel (%rax)");
1355 asm volatile("ptwritel (%r8)");
1356 asm volatile("ptwritel (0x12345678)");
1357 asm volatile("ptwritel 0x12345678(%rax,%rcx,8)");
1358 asm volatile("ptwritel 0x12345678(%r8,%rcx,8)");
1359
1360 asm volatile("ptwriteq (%rax)");
1361 asm volatile("ptwriteq (%r8)");
1362 asm volatile("ptwriteq (0x12345678)");
1363 asm volatile("ptwriteq 0x12345678(%rax,%rcx,8)");
1364 asm volatile("ptwriteq 0x12345678(%r8,%rcx,8)");
1365
1346#else /* #ifdef __x86_64__ */ 1366#else /* #ifdef __x86_64__ */
1347 1367
1348 /* bound r32, mem (same op code as EVEX prefix) */ 1368 /* bound r32, mem (same op code as EVEX prefix) */
@@ -2653,6 +2673,16 @@ int main(void)
2653 asm volatile("xrstors (0x12345678)"); 2673 asm volatile("xrstors (0x12345678)");
2654 asm volatile("xrstors 0x12345678(%eax,%ecx,8)"); 2674 asm volatile("xrstors 0x12345678(%eax,%ecx,8)");
2655 2675
2676 /* ptwrite */
2677
2678 asm volatile("ptwrite (%eax)");
2679 asm volatile("ptwrite (0x12345678)");
2680 asm volatile("ptwrite 0x12345678(%eax,%ecx,8)");
2681
2682 asm volatile("ptwritel (%eax)");
2683 asm volatile("ptwritel (0x12345678)");
2684 asm volatile("ptwritel 0x12345678(%eax,%ecx,8)");
2685
2656#endif /* #ifndef __x86_64__ */ 2686#endif /* #ifndef __x86_64__ */
2657 2687
2658 /* Following line is a marker for the awk script - do not change */ 2688 /* Following line is a marker for the awk script - do not change */
diff --git a/tools/perf/arch/x86/util/intel-bts.c b/tools/perf/arch/x86/util/intel-bts.c
index af2bce7a2cd6..781df40b2966 100644
--- a/tools/perf/arch/x86/util/intel-bts.c
+++ b/tools/perf/arch/x86/util/intel-bts.c
@@ -35,10 +35,6 @@
35#define KiB_MASK(x) (KiB(x) - 1) 35#define KiB_MASK(x) (KiB(x) - 1)
36#define MiB_MASK(x) (MiB(x) - 1) 36#define MiB_MASK(x) (MiB(x) - 1)
37 37
38#define INTEL_BTS_DFLT_SAMPLE_SIZE KiB(4)
39
40#define INTEL_BTS_MAX_SAMPLE_SIZE KiB(60)
41
42struct intel_bts_snapshot_ref { 38struct intel_bts_snapshot_ref {
43 void *ref_buf; 39 void *ref_buf;
44 size_t ref_offset; 40 size_t ref_offset;
diff --git a/tools/perf/arch/x86/util/intel-pt.c b/tools/perf/arch/x86/util/intel-pt.c
index f630de0206a1..9535be57033f 100644
--- a/tools/perf/arch/x86/util/intel-pt.c
+++ b/tools/perf/arch/x86/util/intel-pt.c
@@ -40,10 +40,6 @@
40#define KiB_MASK(x) (KiB(x) - 1) 40#define KiB_MASK(x) (KiB(x) - 1)
41#define MiB_MASK(x) (MiB(x) - 1) 41#define MiB_MASK(x) (MiB(x) - 1)
42 42
43#define INTEL_PT_DEFAULT_SAMPLE_SIZE KiB(4)
44
45#define INTEL_PT_MAX_SAMPLE_SIZE KiB(60)
46
47#define INTEL_PT_PSB_PERIOD_NEAR 256 43#define INTEL_PT_PSB_PERIOD_NEAR 256
48 44
49struct intel_pt_snapshot_ref { 45struct intel_pt_snapshot_ref {
@@ -196,6 +192,7 @@ static u64 intel_pt_default_config(struct perf_pmu *intel_pt_pmu)
196 int psb_cyc, psb_periods, psb_period; 192 int psb_cyc, psb_periods, psb_period;
197 int pos = 0; 193 int pos = 0;
198 u64 config; 194 u64 config;
195 char c;
199 196
200 pos += scnprintf(buf + pos, sizeof(buf) - pos, "tsc"); 197 pos += scnprintf(buf + pos, sizeof(buf) - pos, "tsc");
201 198
@@ -229,6 +226,10 @@ static u64 intel_pt_default_config(struct perf_pmu *intel_pt_pmu)
229 } 226 }
230 } 227 }
231 228
229 if (perf_pmu__scan_file(intel_pt_pmu, "format/pt", "%c", &c) == 1 &&
230 perf_pmu__scan_file(intel_pt_pmu, "format/branch", "%c", &c) == 1)
231 pos += scnprintf(buf + pos, sizeof(buf) - pos, ",pt,branch");
232
232 pr_debug2("%s default config: %s\n", intel_pt_pmu->name, buf); 233 pr_debug2("%s default config: %s\n", intel_pt_pmu->name, buf);
233 234
234 intel_pt_parse_terms(&intel_pt_pmu->format, buf, &config); 235 intel_pt_parse_terms(&intel_pt_pmu->format, buf, &config);
diff --git a/tools/perf/bench/numa.c b/tools/perf/bench/numa.c
index 27de0c8c5c19..469d65b21122 100644
--- a/tools/perf/bench/numa.c
+++ b/tools/perf/bench/numa.c
@@ -700,7 +700,7 @@ static inline uint32_t lfsr_32(uint32_t lfsr)
700 * kernel (KSM, zero page, etc.) cannot optimize away RAM 700 * kernel (KSM, zero page, etc.) cannot optimize away RAM
701 * accesses: 701 * accesses:
702 */ 702 */
703static inline u64 access_data(u64 *data __attribute__((unused)), u64 val) 703static inline u64 access_data(u64 *data, u64 val)
704{ 704{
705 if (g->p.data_reads) 705 if (g->p.data_reads)
706 val += *data; 706 val += *data;
diff --git a/tools/perf/builtin-c2c.c b/tools/perf/builtin-c2c.c
index 620a467ee304..475999e48f66 100644
--- a/tools/perf/builtin-c2c.c
+++ b/tools/perf/builtin-c2c.c
@@ -1725,10 +1725,10 @@ static int c2c_hists__init_sort(struct perf_hpp_list *hpp_list, char *name)
1725 tok; tok = strtok_r(NULL, ", ", &tmp)) { \ 1725 tok; tok = strtok_r(NULL, ", ", &tmp)) { \
1726 ret = _fn(hpp_list, tok); \ 1726 ret = _fn(hpp_list, tok); \
1727 if (ret == -EINVAL) { \ 1727 if (ret == -EINVAL) { \
1728 error("Invalid --fields key: `%s'", tok); \ 1728 pr_err("Invalid --fields key: `%s'", tok); \
1729 break; \ 1729 break; \
1730 } else if (ret == -ESRCH) { \ 1730 } else if (ret == -ESRCH) { \
1731 error("Unknown --fields key: `%s'", tok); \ 1731 pr_err("Unknown --fields key: `%s'", tok); \
1732 break; \ 1732 break; \
1733 } \ 1733 } \
1734 } \ 1734 } \
diff --git a/tools/perf/builtin-config.c b/tools/perf/builtin-config.c
index 80668fa7556e..ece45582a48d 100644
--- a/tools/perf/builtin-config.c
+++ b/tools/perf/builtin-config.c
@@ -156,7 +156,7 @@ static int parse_config_arg(char *arg, char **var, char **value)
156 156
157int cmd_config(int argc, const char **argv) 157int cmd_config(int argc, const char **argv)
158{ 158{
159 int i, ret = 0; 159 int i, ret = -1;
160 struct perf_config_set *set; 160 struct perf_config_set *set;
161 char *user_config = mkpath("%s/.perfconfig", getenv("HOME")); 161 char *user_config = mkpath("%s/.perfconfig", getenv("HOME"));
162 const char *config_filename; 162 const char *config_filename;
@@ -186,10 +186,8 @@ int cmd_config(int argc, const char **argv)
186 * because of reinitializing with options config file location. 186 * because of reinitializing with options config file location.
187 */ 187 */
188 set = perf_config_set__new(); 188 set = perf_config_set__new();
189 if (!set) { 189 if (!set)
190 ret = -1;
191 goto out_err; 190 goto out_err;
192 }
193 191
194 switch (actions) { 192 switch (actions) {
195 case ACTION_LIST: 193 case ACTION_LIST:
@@ -197,41 +195,54 @@ int cmd_config(int argc, const char **argv)
197 pr_err("Error: takes no arguments\n"); 195 pr_err("Error: takes no arguments\n");
198 parse_options_usage(config_usage, config_options, "l", 1); 196 parse_options_usage(config_usage, config_options, "l", 1);
199 } else { 197 } else {
200 ret = show_config(set); 198 if (show_config(set) < 0) {
201 if (ret < 0)
202 pr_err("Nothing configured, " 199 pr_err("Nothing configured, "
203 "please check your %s \n", config_filename); 200 "please check your %s \n", config_filename);
201 goto out_err;
202 }
204 } 203 }
205 break; 204 break;
206 default: 205 default:
207 if (argc) { 206 if (!argc) {
208 for (i = 0; argv[i]; i++) { 207 usage_with_options(config_usage, config_options);
209 char *var, *value; 208 break;
210 char *arg = strdup(argv[i]); 209 }
211
212 if (!arg) {
213 pr_err("%s: strdup failed\n", __func__);
214 ret = -1;
215 break;
216 }
217 210
218 if (parse_config_arg(arg, &var, &value) < 0) { 211 for (i = 0; argv[i]; i++) {
219 free(arg); 212 char *var, *value;
220 ret = -1; 213 char *arg = strdup(argv[i]);
221 break; 214
222 } 215 if (!arg) {
216 pr_err("%s: strdup failed\n", __func__);
217 goto out_err;
218 }
223 219
224 if (value == NULL) 220 if (parse_config_arg(arg, &var, &value) < 0) {
225 ret = show_spec_config(set, var);
226 else
227 ret = set_config(set, config_filename, var, value);
228 free(arg); 221 free(arg);
222 goto out_err;
229 } 223 }
230 } else 224
231 usage_with_options(config_usage, config_options); 225 if (value == NULL) {
226 if (show_spec_config(set, var) < 0) {
227 pr_err("%s is not configured: %s\n",
228 var, config_filename);
229 free(arg);
230 goto out_err;
231 }
232 } else {
233 if (set_config(set, config_filename, var, value) < 0) {
234 pr_err("Failed to set '%s=%s' on %s\n",
235 var, value, config_filename);
236 free(arg);
237 goto out_err;
238 }
239 }
240 free(arg);
241 }
232 } 242 }
233 243
234 perf_config_set__delete(set); 244 ret = 0;
235out_err: 245out_err:
246 perf_config_set__delete(set);
236 return ret; 247 return ret;
237} 248}
diff --git a/tools/perf/builtin-diff.c b/tools/perf/builtin-diff.c
index eec5df80f5a3..0cd4cf6a344b 100644
--- a/tools/perf/builtin-diff.c
+++ b/tools/perf/builtin-diff.c
@@ -1302,7 +1302,10 @@ static int diff__config(const char *var, const char *value,
1302 void *cb __maybe_unused) 1302 void *cb __maybe_unused)
1303{ 1303{
1304 if (!strcmp(var, "diff.order")) { 1304 if (!strcmp(var, "diff.order")) {
1305 sort_compute = perf_config_int(var, value); 1305 int ret;
1306 if (perf_config_int(&ret, var, value) < 0)
1307 return -1;
1308 sort_compute = ret;
1306 return 0; 1309 return 0;
1307 } 1310 }
1308 if (!strcmp(var, "diff.compute")) { 1311 if (!strcmp(var, "diff.compute")) {
diff --git a/tools/perf/builtin-ftrace.c b/tools/perf/builtin-ftrace.c
index 9e0b35cd0eea..dd26c62c9893 100644
--- a/tools/perf/builtin-ftrace.c
+++ b/tools/perf/builtin-ftrace.c
@@ -28,9 +28,19 @@
28#define DEFAULT_TRACER "function_graph" 28#define DEFAULT_TRACER "function_graph"
29 29
30struct perf_ftrace { 30struct perf_ftrace {
31 struct perf_evlist *evlist; 31 struct perf_evlist *evlist;
32 struct target target; 32 struct target target;
33 const char *tracer; 33 const char *tracer;
34 struct list_head filters;
35 struct list_head notrace;
36 struct list_head graph_funcs;
37 struct list_head nograph_funcs;
38 int graph_depth;
39};
40
41struct filter_entry {
42 struct list_head list;
43 char name[];
34}; 44};
35 45
36static bool done; 46static bool done;
@@ -61,6 +71,7 @@ static int __write_tracing_file(const char *name, const char *val, bool append)
61 int fd, ret = -1; 71 int fd, ret = -1;
62 ssize_t size = strlen(val); 72 ssize_t size = strlen(val);
63 int flags = O_WRONLY; 73 int flags = O_WRONLY;
74 char errbuf[512];
64 75
65 file = get_tracing_file(name); 76 file = get_tracing_file(name);
66 if (!file) { 77 if (!file) {
@@ -75,14 +86,16 @@ static int __write_tracing_file(const char *name, const char *val, bool append)
75 86
76 fd = open(file, flags); 87 fd = open(file, flags);
77 if (fd < 0) { 88 if (fd < 0) {
78 pr_debug("cannot open tracing file: %s\n", name); 89 pr_debug("cannot open tracing file: %s: %s\n",
90 name, str_error_r(errno, errbuf, sizeof(errbuf)));
79 goto out; 91 goto out;
80 } 92 }
81 93
82 if (write(fd, val, size) == size) 94 if (write(fd, val, size) == size)
83 ret = 0; 95 ret = 0;
84 else 96 else
85 pr_debug("write '%s' to tracing/%s failed\n", val, name); 97 pr_debug("write '%s' to tracing/%s failed: %s\n",
98 val, name, str_error_r(errno, errbuf, sizeof(errbuf)));
86 99
87 close(fd); 100 close(fd);
88out: 101out:
@@ -101,6 +114,7 @@ static int append_tracing_file(const char *name, const char *val)
101} 114}
102 115
103static int reset_tracing_cpu(void); 116static int reset_tracing_cpu(void);
117static void reset_tracing_filters(void);
104 118
105static int reset_tracing_files(struct perf_ftrace *ftrace __maybe_unused) 119static int reset_tracing_files(struct perf_ftrace *ftrace __maybe_unused)
106{ 120{
@@ -116,6 +130,10 @@ static int reset_tracing_files(struct perf_ftrace *ftrace __maybe_unused)
116 if (reset_tracing_cpu() < 0) 130 if (reset_tracing_cpu() < 0)
117 return -1; 131 return -1;
118 132
133 if (write_tracing_file("max_graph_depth", "0") < 0)
134 return -1;
135
136 reset_tracing_filters();
119 return 0; 137 return 0;
120} 138}
121 139
@@ -181,6 +199,68 @@ static int reset_tracing_cpu(void)
181 return ret; 199 return ret;
182} 200}
183 201
202static int __set_tracing_filter(const char *filter_file, struct list_head *funcs)
203{
204 struct filter_entry *pos;
205
206 list_for_each_entry(pos, funcs, list) {
207 if (append_tracing_file(filter_file, pos->name) < 0)
208 return -1;
209 }
210
211 return 0;
212}
213
214static int set_tracing_filters(struct perf_ftrace *ftrace)
215{
216 int ret;
217
218 ret = __set_tracing_filter("set_ftrace_filter", &ftrace->filters);
219 if (ret < 0)
220 return ret;
221
222 ret = __set_tracing_filter("set_ftrace_notrace", &ftrace->notrace);
223 if (ret < 0)
224 return ret;
225
226 ret = __set_tracing_filter("set_graph_function", &ftrace->graph_funcs);
227 if (ret < 0)
228 return ret;
229
230 /* old kernels do not have this filter */
231 __set_tracing_filter("set_graph_notrace", &ftrace->nograph_funcs);
232
233 return ret;
234}
235
236static void reset_tracing_filters(void)
237{
238 write_tracing_file("set_ftrace_filter", " ");
239 write_tracing_file("set_ftrace_notrace", " ");
240 write_tracing_file("set_graph_function", " ");
241 write_tracing_file("set_graph_notrace", " ");
242}
243
244static int set_tracing_depth(struct perf_ftrace *ftrace)
245{
246 char buf[16];
247
248 if (ftrace->graph_depth == 0)
249 return 0;
250
251 if (ftrace->graph_depth < 0) {
252 pr_err("invalid graph depth: %d\n", ftrace->graph_depth);
253 return -1;
254 }
255
256 snprintf(buf, sizeof(buf), "%d", ftrace->graph_depth);
257
258 if (write_tracing_file("max_graph_depth", buf) < 0)
259 return -1;
260
261 return 0;
262}
263
184static int __cmd_ftrace(struct perf_ftrace *ftrace, int argc, const char **argv) 264static int __cmd_ftrace(struct perf_ftrace *ftrace, int argc, const char **argv)
185{ 265{
186 char *trace_file; 266 char *trace_file;
@@ -223,11 +303,23 @@ static int __cmd_ftrace(struct perf_ftrace *ftrace, int argc, const char **argv)
223 goto out_reset; 303 goto out_reset;
224 } 304 }
225 305
306 if (set_tracing_filters(ftrace) < 0) {
307 pr_err("failed to set tracing filters\n");
308 goto out_reset;
309 }
310
311 if (set_tracing_depth(ftrace) < 0) {
312 pr_err("failed to set graph depth\n");
313 goto out_reset;
314 }
315
226 if (write_tracing_file("current_tracer", ftrace->tracer) < 0) { 316 if (write_tracing_file("current_tracer", ftrace->tracer) < 0) {
227 pr_err("failed to set current_tracer to %s\n", ftrace->tracer); 317 pr_err("failed to set current_tracer to %s\n", ftrace->tracer);
228 goto out_reset; 318 goto out_reset;
229 } 319 }
230 320
321 setup_pager();
322
231 trace_file = get_tracing_file("trace_pipe"); 323 trace_file = get_tracing_file("trace_pipe");
232 if (!trace_file) { 324 if (!trace_file) {
233 pr_err("failed to open trace_pipe\n"); 325 pr_err("failed to open trace_pipe\n");
@@ -251,8 +343,6 @@ static int __cmd_ftrace(struct perf_ftrace *ftrace, int argc, const char **argv)
251 goto out_close_fd; 343 goto out_close_fd;
252 } 344 }
253 345
254 setup_pager();
255
256 perf_evlist__start_workload(ftrace->evlist); 346 perf_evlist__start_workload(ftrace->evlist);
257 347
258 while (!done) { 348 while (!done) {
@@ -307,6 +397,32 @@ static int perf_ftrace_config(const char *var, const char *value, void *cb)
307 return -1; 397 return -1;
308} 398}
309 399
400static int parse_filter_func(const struct option *opt, const char *str,
401 int unset __maybe_unused)
402{
403 struct list_head *head = opt->value;
404 struct filter_entry *entry;
405
406 entry = malloc(sizeof(*entry) + strlen(str) + 1);
407 if (entry == NULL)
408 return -ENOMEM;
409
410 strcpy(entry->name, str);
411 list_add_tail(&entry->list, head);
412
413 return 0;
414}
415
416static void delete_filter_func(struct list_head *head)
417{
418 struct filter_entry *pos, *tmp;
419
420 list_for_each_entry_safe(pos, tmp, head, list) {
421 list_del(&pos->list);
422 free(pos);
423 }
424}
425
310int cmd_ftrace(int argc, const char **argv) 426int cmd_ftrace(int argc, const char **argv)
311{ 427{
312 int ret; 428 int ret;
@@ -330,9 +446,24 @@ int cmd_ftrace(int argc, const char **argv)
330 "system-wide collection from all CPUs"), 446 "system-wide collection from all CPUs"),
331 OPT_STRING('C', "cpu", &ftrace.target.cpu_list, "cpu", 447 OPT_STRING('C', "cpu", &ftrace.target.cpu_list, "cpu",
332 "list of cpus to monitor"), 448 "list of cpus to monitor"),
449 OPT_CALLBACK('T', "trace-funcs", &ftrace.filters, "func",
450 "trace given functions only", parse_filter_func),
451 OPT_CALLBACK('N', "notrace-funcs", &ftrace.notrace, "func",
452 "do not trace given functions", parse_filter_func),
453 OPT_CALLBACK('G', "graph-funcs", &ftrace.graph_funcs, "func",
454 "Set graph filter on given functions", parse_filter_func),
455 OPT_CALLBACK('g', "nograph-funcs", &ftrace.nograph_funcs, "func",
456 "Set nograph filter on given functions", parse_filter_func),
457 OPT_INTEGER('D', "graph-depth", &ftrace.graph_depth,
458 "Max depth for function graph tracer"),
333 OPT_END() 459 OPT_END()
334 }; 460 };
335 461
462 INIT_LIST_HEAD(&ftrace.filters);
463 INIT_LIST_HEAD(&ftrace.notrace);
464 INIT_LIST_HEAD(&ftrace.graph_funcs);
465 INIT_LIST_HEAD(&ftrace.nograph_funcs);
466
336 ret = perf_config(perf_ftrace_config, &ftrace); 467 ret = perf_config(perf_ftrace_config, &ftrace);
337 if (ret < 0) 468 if (ret < 0)
338 return -1; 469 return -1;
@@ -348,12 +479,14 @@ int cmd_ftrace(int argc, const char **argv)
348 479
349 target__strerror(&ftrace.target, ret, errbuf, 512); 480 target__strerror(&ftrace.target, ret, errbuf, 512);
350 pr_err("%s\n", errbuf); 481 pr_err("%s\n", errbuf);
351 return -EINVAL; 482 goto out_delete_filters;
352 } 483 }
353 484
354 ftrace.evlist = perf_evlist__new(); 485 ftrace.evlist = perf_evlist__new();
355 if (ftrace.evlist == NULL) 486 if (ftrace.evlist == NULL) {
356 return -ENOMEM; 487 ret = -ENOMEM;
488 goto out_delete_filters;
489 }
357 490
358 ret = perf_evlist__create_maps(ftrace.evlist, &ftrace.target); 491 ret = perf_evlist__create_maps(ftrace.evlist, &ftrace.target);
359 if (ret < 0) 492 if (ret < 0)
@@ -364,5 +497,11 @@ int cmd_ftrace(int argc, const char **argv)
364out_delete_evlist: 497out_delete_evlist:
365 perf_evlist__delete(ftrace.evlist); 498 perf_evlist__delete(ftrace.evlist);
366 499
500out_delete_filters:
501 delete_filter_func(&ftrace.filters);
502 delete_filter_func(&ftrace.notrace);
503 delete_filter_func(&ftrace.graph_funcs);
504 delete_filter_func(&ftrace.nograph_funcs);
505
367 return ret; 506 return ret;
368} 507}
diff --git a/tools/perf/builtin-help.c b/tools/perf/builtin-help.c
index 492f8e14ab09..530a7f2fa0f3 100644
--- a/tools/perf/builtin-help.c
+++ b/tools/perf/builtin-help.c
@@ -108,10 +108,14 @@ out:
108 return ret; 108 return ret;
109} 109}
110 110
111static void exec_woman_emacs(const char *path, const char *page) 111static void exec_failed(const char *cmd)
112{ 112{
113 char sbuf[STRERR_BUFSIZE]; 113 char sbuf[STRERR_BUFSIZE];
114 pr_warning("failed to exec '%s': %s", cmd, str_error_r(errno, sbuf, sizeof(sbuf)));
115}
114 116
117static void exec_woman_emacs(const char *path, const char *page)
118{
115 if (!check_emacsclient_version()) { 119 if (!check_emacsclient_version()) {
116 /* This works only with emacsclient version >= 22. */ 120 /* This works only with emacsclient version >= 22. */
117 char *man_page; 121 char *man_page;
@@ -122,8 +126,7 @@ static void exec_woman_emacs(const char *path, const char *page)
122 execlp(path, "emacsclient", "-e", man_page, NULL); 126 execlp(path, "emacsclient", "-e", man_page, NULL);
123 free(man_page); 127 free(man_page);
124 } 128 }
125 warning("failed to exec '%s': %s", path, 129 exec_failed(path);
126 str_error_r(errno, sbuf, sizeof(sbuf)));
127 } 130 }
128} 131}
129 132
@@ -134,7 +137,6 @@ static void exec_man_konqueror(const char *path, const char *page)
134 if (display && *display) { 137 if (display && *display) {
135 char *man_page; 138 char *man_page;
136 const char *filename = "kfmclient"; 139 const char *filename = "kfmclient";
137 char sbuf[STRERR_BUFSIZE];
138 140
139 /* It's simpler to launch konqueror using kfmclient. */ 141 /* It's simpler to launch konqueror using kfmclient. */
140 if (path) { 142 if (path) {
@@ -155,33 +157,27 @@ static void exec_man_konqueror(const char *path, const char *page)
155 execlp(path, filename, "newTab", man_page, NULL); 157 execlp(path, filename, "newTab", man_page, NULL);
156 free(man_page); 158 free(man_page);
157 } 159 }
158 warning("failed to exec '%s': %s", path, 160 exec_failed(path);
159 str_error_r(errno, sbuf, sizeof(sbuf)));
160 } 161 }
161} 162}
162 163
163static void exec_man_man(const char *path, const char *page) 164static void exec_man_man(const char *path, const char *page)
164{ 165{
165 char sbuf[STRERR_BUFSIZE];
166
167 if (!path) 166 if (!path)
168 path = "man"; 167 path = "man";
169 execlp(path, "man", page, NULL); 168 execlp(path, "man", page, NULL);
170 warning("failed to exec '%s': %s", path, 169 exec_failed(path);
171 str_error_r(errno, sbuf, sizeof(sbuf)));
172} 170}
173 171
174static void exec_man_cmd(const char *cmd, const char *page) 172static void exec_man_cmd(const char *cmd, const char *page)
175{ 173{
176 char sbuf[STRERR_BUFSIZE];
177 char *shell_cmd; 174 char *shell_cmd;
178 175
179 if (asprintf(&shell_cmd, "%s %s", cmd, page) > 0) { 176 if (asprintf(&shell_cmd, "%s %s", cmd, page) > 0) {
180 execl("/bin/sh", "sh", "-c", shell_cmd, NULL); 177 execl("/bin/sh", "sh", "-c", shell_cmd, NULL);
181 free(shell_cmd); 178 free(shell_cmd);
182 } 179 }
183 warning("failed to exec '%s': %s", cmd, 180 exec_failed(cmd);
184 str_error_r(errno, sbuf, sizeof(sbuf)));
185} 181}
186 182
187static void add_man_viewer(const char *name) 183static void add_man_viewer(const char *name)
@@ -214,6 +210,12 @@ static void do_add_man_viewer_info(const char *name,
214 man_viewer_info_list = new; 210 man_viewer_info_list = new;
215} 211}
216 212
213static void unsupported_man_viewer(const char *name, const char *var)
214{
215 pr_warning("'%s': path for unsupported man viewer.\n"
216 "Please consider using 'man.<tool>.%s' instead.", name, var);
217}
218
217static int add_man_viewer_path(const char *name, 219static int add_man_viewer_path(const char *name,
218 size_t len, 220 size_t len,
219 const char *value) 221 const char *value)
@@ -221,9 +223,7 @@ static int add_man_viewer_path(const char *name,
221 if (supported_man_viewer(name, len)) 223 if (supported_man_viewer(name, len))
222 do_add_man_viewer_info(name, len, value); 224 do_add_man_viewer_info(name, len, value);
223 else 225 else
224 warning("'%s': path for unsupported man viewer.\n" 226 unsupported_man_viewer(name, "cmd");
225 "Please consider using 'man.<tool>.cmd' instead.",
226 name);
227 227
228 return 0; 228 return 0;
229} 229}
@@ -233,9 +233,7 @@ static int add_man_viewer_cmd(const char *name,
233 const char *value) 233 const char *value)
234{ 234{
235 if (supported_man_viewer(name, len)) 235 if (supported_man_viewer(name, len))
236 warning("'%s': cmd for supported man viewer.\n" 236 unsupported_man_viewer(name, "path");
237 "Please consider using 'man.<tool>.path' instead.",
238 name);
239 else 237 else
240 do_add_man_viewer_info(name, len, value); 238 do_add_man_viewer_info(name, len, value);
241 239
@@ -247,8 +245,10 @@ static int add_man_viewer_info(const char *var, const char *value)
247 const char *name = var + 4; 245 const char *name = var + 4;
248 const char *subkey = strrchr(name, '.'); 246 const char *subkey = strrchr(name, '.');
249 247
250 if (!subkey) 248 if (!subkey) {
251 return error("Config with no key for man viewer: %s", name); 249 pr_err("Config with no key for man viewer: %s", name);
250 return -1;
251 }
252 252
253 if (!strcmp(subkey, ".path")) { 253 if (!strcmp(subkey, ".path")) {
254 if (!value) 254 if (!value)
@@ -261,7 +261,7 @@ static int add_man_viewer_info(const char *var, const char *value)
261 return add_man_viewer_cmd(name, subkey - name, value); 261 return add_man_viewer_cmd(name, subkey - name, value);
262 } 262 }
263 263
264 warning("'%s': unsupported man viewer sub key.", subkey); 264 pr_warning("'%s': unsupported man viewer sub key.", subkey);
265 return 0; 265 return 0;
266} 266}
267 267
@@ -332,7 +332,7 @@ static void setup_man_path(void)
332 setenv("MANPATH", new_path, 1); 332 setenv("MANPATH", new_path, 1);
333 free(new_path); 333 free(new_path);
334 } else { 334 } else {
335 error("Unable to setup man path"); 335 pr_err("Unable to setup man path");
336 } 336 }
337} 337}
338 338
@@ -349,7 +349,7 @@ static void exec_viewer(const char *name, const char *page)
349 else if (info) 349 else if (info)
350 exec_man_cmd(info, page); 350 exec_man_cmd(info, page);
351 else 351 else
352 warning("'%s': unknown man viewer.", name); 352 pr_warning("'%s': unknown man viewer.", name);
353} 353}
354 354
355static int show_man_page(const char *perf_cmd) 355static int show_man_page(const char *perf_cmd)
diff --git a/tools/perf/builtin-kmem.c b/tools/perf/builtin-kmem.c
index 9409c9464667..0a8a1c45af87 100644
--- a/tools/perf/builtin-kmem.c
+++ b/tools/perf/builtin-kmem.c
@@ -1715,7 +1715,7 @@ static int setup_slab_sorting(struct list_head *sort_list, const char *arg)
1715 if (!tok) 1715 if (!tok)
1716 break; 1716 break;
1717 if (slab_sort_dimension__add(tok, sort_list) < 0) { 1717 if (slab_sort_dimension__add(tok, sort_list) < 0) {
1718 error("Unknown slab --sort key: '%s'", tok); 1718 pr_err("Unknown slab --sort key: '%s'", tok);
1719 free(str); 1719 free(str);
1720 return -1; 1720 return -1;
1721 } 1721 }
@@ -1741,7 +1741,7 @@ static int setup_page_sorting(struct list_head *sort_list, const char *arg)
1741 if (!tok) 1741 if (!tok)
1742 break; 1742 break;
1743 if (page_sort_dimension__add(tok, sort_list) < 0) { 1743 if (page_sort_dimension__add(tok, sort_list) < 0) {
1744 error("Unknown page --sort key: '%s'", tok); 1744 pr_err("Unknown page --sort key: '%s'", tok);
1745 free(str); 1745 free(str);
1746 return -1; 1746 return -1;
1747 } 1747 }
diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c
index ee7d0a82ccd0..17a14bcce34a 100644
--- a/tools/perf/builtin-record.c
+++ b/tools/perf/builtin-record.c
@@ -453,7 +453,7 @@ try_again:
453 } 453 }
454 454
455 if (perf_evlist__apply_filters(evlist, &pos)) { 455 if (perf_evlist__apply_filters(evlist, &pos)) {
456 error("failed to set filter \"%s\" on event %s with %d (%s)\n", 456 pr_err("failed to set filter \"%s\" on event %s with %d (%s)\n",
457 pos->filter, perf_evsel__name(pos), errno, 457 pos->filter, perf_evsel__name(pos), errno,
458 str_error_r(errno, msg, sizeof(msg))); 458 str_error_r(errno, msg, sizeof(msg)));
459 rc = -1; 459 rc = -1;
@@ -461,7 +461,7 @@ try_again:
461 } 461 }
462 462
463 if (perf_evlist__apply_drv_configs(evlist, &pos, &err_term)) { 463 if (perf_evlist__apply_drv_configs(evlist, &pos, &err_term)) {
464 error("failed to set config \"%s\" on event %s with %d (%s)\n", 464 pr_err("failed to set config \"%s\" on event %s with %d (%s)\n",
465 err_term->val.drv_cfg, perf_evsel__name(pos), errno, 465 err_term->val.drv_cfg, perf_evsel__name(pos), errno,
466 str_error_r(errno, msg, sizeof(msg))); 466 str_error_r(errno, msg, sizeof(msg)));
467 rc = -1; 467 rc = -1;
diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c
index 22478ff2b706..79a33eb1a10d 100644
--- a/tools/perf/builtin-report.c
+++ b/tools/perf/builtin-report.c
@@ -94,10 +94,9 @@ static int report__config(const char *var, const char *value, void *cb)
94 symbol_conf.cumulate_callchain = perf_config_bool(var, value); 94 symbol_conf.cumulate_callchain = perf_config_bool(var, value);
95 return 0; 95 return 0;
96 } 96 }
97 if (!strcmp(var, "report.queue-size")) { 97 if (!strcmp(var, "report.queue-size"))
98 rep->queue_size = perf_config_u64(var, value); 98 return perf_config_u64(&rep->queue_size, var, value);
99 return 0; 99
100 }
101 if (!strcmp(var, "report.sort_order")) { 100 if (!strcmp(var, "report.sort_order")) {
102 default_sort_order = strdup(value); 101 default_sort_order = strdup(value);
103 return 0; 102 return 0;
@@ -558,6 +557,7 @@ static int __cmd_report(struct report *rep)
558 ui__error("failed to set cpu bitmap\n"); 557 ui__error("failed to set cpu bitmap\n");
559 return ret; 558 return ret;
560 } 559 }
560 session->itrace_synth_opts->cpu_bitmap = rep->cpu_bitmap;
561 } 561 }
562 562
563 if (rep->show_threads) { 563 if (rep->show_threads) {
diff --git a/tools/perf/builtin-sched.c b/tools/perf/builtin-sched.c
index 39996c53995a..322b4def8411 100644
--- a/tools/perf/builtin-sched.c
+++ b/tools/perf/builtin-sched.c
@@ -2066,7 +2066,7 @@ static void save_task_callchain(struct perf_sched *sched,
2066 if (thread__resolve_callchain(thread, cursor, evsel, sample, 2066 if (thread__resolve_callchain(thread, cursor, evsel, sample,
2067 NULL, NULL, sched->max_stack + 2) != 0) { 2067 NULL, NULL, sched->max_stack + 2) != 0) {
2068 if (verbose > 0) 2068 if (verbose > 0)
2069 error("Failed to resolve callchain. Skipping\n"); 2069 pr_err("Failed to resolve callchain. Skipping\n");
2070 2070
2071 return; 2071 return;
2072 } 2072 }
diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c
index d05aec491cff..83cdc0a61fd6 100644
--- a/tools/perf/builtin-script.c
+++ b/tools/perf/builtin-script.c
@@ -85,6 +85,8 @@ enum perf_output_field {
85 PERF_OUTPUT_INSN = 1U << 21, 85 PERF_OUTPUT_INSN = 1U << 21,
86 PERF_OUTPUT_INSNLEN = 1U << 22, 86 PERF_OUTPUT_INSNLEN = 1U << 22,
87 PERF_OUTPUT_BRSTACKINSN = 1U << 23, 87 PERF_OUTPUT_BRSTACKINSN = 1U << 23,
88 PERF_OUTPUT_BRSTACKOFF = 1U << 24,
89 PERF_OUTPUT_SYNTH = 1U << 25,
88}; 90};
89 91
90struct output_option { 92struct output_option {
@@ -115,6 +117,13 @@ struct output_option {
115 {.str = "insn", .field = PERF_OUTPUT_INSN}, 117 {.str = "insn", .field = PERF_OUTPUT_INSN},
116 {.str = "insnlen", .field = PERF_OUTPUT_INSNLEN}, 118 {.str = "insnlen", .field = PERF_OUTPUT_INSNLEN},
117 {.str = "brstackinsn", .field = PERF_OUTPUT_BRSTACKINSN}, 119 {.str = "brstackinsn", .field = PERF_OUTPUT_BRSTACKINSN},
120 {.str = "brstackoff", .field = PERF_OUTPUT_BRSTACKOFF},
121 {.str = "synth", .field = PERF_OUTPUT_SYNTH},
122};
123
124enum {
125 OUTPUT_TYPE_SYNTH = PERF_TYPE_MAX,
126 OUTPUT_TYPE_MAX
118}; 127};
119 128
120/* default set to maintain compatibility with current format */ 129/* default set to maintain compatibility with current format */
@@ -124,7 +133,7 @@ static struct {
124 unsigned int print_ip_opts; 133 unsigned int print_ip_opts;
125 u64 fields; 134 u64 fields;
126 u64 invalid_fields; 135 u64 invalid_fields;
127} output[PERF_TYPE_MAX] = { 136} output[OUTPUT_TYPE_MAX] = {
128 137
129 [PERF_TYPE_HARDWARE] = { 138 [PERF_TYPE_HARDWARE] = {
130 .user_set = false, 139 .user_set = false,
@@ -182,12 +191,44 @@ static struct {
182 191
183 .invalid_fields = PERF_OUTPUT_TRACE | PERF_OUTPUT_BPF_OUTPUT, 192 .invalid_fields = PERF_OUTPUT_TRACE | PERF_OUTPUT_BPF_OUTPUT,
184 }, 193 },
194
195 [OUTPUT_TYPE_SYNTH] = {
196 .user_set = false,
197
198 .fields = PERF_OUTPUT_COMM | PERF_OUTPUT_TID |
199 PERF_OUTPUT_CPU | PERF_OUTPUT_TIME |
200 PERF_OUTPUT_EVNAME | PERF_OUTPUT_IP |
201 PERF_OUTPUT_SYM | PERF_OUTPUT_DSO |
202 PERF_OUTPUT_SYNTH,
203
204 .invalid_fields = PERF_OUTPUT_TRACE | PERF_OUTPUT_BPF_OUTPUT,
205 },
185}; 206};
186 207
208static inline int output_type(unsigned int type)
209{
210 switch (type) {
211 case PERF_TYPE_SYNTH:
212 return OUTPUT_TYPE_SYNTH;
213 default:
214 return type;
215 }
216}
217
218static inline unsigned int attr_type(unsigned int type)
219{
220 switch (type) {
221 case OUTPUT_TYPE_SYNTH:
222 return PERF_TYPE_SYNTH;
223 default:
224 return type;
225 }
226}
227
187static bool output_set_by_user(void) 228static bool output_set_by_user(void)
188{ 229{
189 int j; 230 int j;
190 for (j = 0; j < PERF_TYPE_MAX; ++j) { 231 for (j = 0; j < OUTPUT_TYPE_MAX; ++j) {
191 if (output[j].user_set) 232 if (output[j].user_set)
192 return true; 233 return true;
193 } 234 }
@@ -208,7 +249,7 @@ static const char *output_field2str(enum perf_output_field field)
208 return str; 249 return str;
209} 250}
210 251
211#define PRINT_FIELD(x) (output[attr->type].fields & PERF_OUTPUT_##x) 252#define PRINT_FIELD(x) (output[output_type(attr->type)].fields & PERF_OUTPUT_##x)
212 253
213static int perf_evsel__do_check_stype(struct perf_evsel *evsel, 254static int perf_evsel__do_check_stype(struct perf_evsel *evsel,
214 u64 sample_type, const char *sample_msg, 255 u64 sample_type, const char *sample_msg,
@@ -216,7 +257,7 @@ static int perf_evsel__do_check_stype(struct perf_evsel *evsel,
216 bool allow_user_set) 257 bool allow_user_set)
217{ 258{
218 struct perf_event_attr *attr = &evsel->attr; 259 struct perf_event_attr *attr = &evsel->attr;
219 int type = attr->type; 260 int type = output_type(attr->type);
220 const char *evname; 261 const char *evname;
221 262
222 if (attr->sample_type & sample_type) 263 if (attr->sample_type & sample_type)
@@ -298,10 +339,10 @@ static int perf_evsel__check_attr(struct perf_evsel *evsel,
298 "selected.\n"); 339 "selected.\n");
299 return -EINVAL; 340 return -EINVAL;
300 } 341 }
301 if (PRINT_FIELD(DSO) && !PRINT_FIELD(IP) && !PRINT_FIELD(ADDR)) { 342 if (PRINT_FIELD(DSO) && !PRINT_FIELD(IP) && !PRINT_FIELD(ADDR) &&
302 pr_err("Display of DSO requested but neither sample IP nor " 343 !PRINT_FIELD(BRSTACK) && !PRINT_FIELD(BRSTACKSYM) && !PRINT_FIELD(BRSTACKOFF)) {
303 "sample address\nis selected. Hence, no addresses to convert " 344 pr_err("Display of DSO requested but no address to convert. Select\n"
304 "to DSO.\n"); 345 "sample IP, sample address, brstack, brstacksym, or brstackoff.\n");
305 return -EINVAL; 346 return -EINVAL;
306 } 347 }
307 if (PRINT_FIELD(SRCLINE) && !PRINT_FIELD(IP)) { 348 if (PRINT_FIELD(SRCLINE) && !PRINT_FIELD(IP)) {
@@ -346,7 +387,7 @@ static int perf_evsel__check_attr(struct perf_evsel *evsel,
346 387
347static void set_print_ip_opts(struct perf_event_attr *attr) 388static void set_print_ip_opts(struct perf_event_attr *attr)
348{ 389{
349 unsigned int type = attr->type; 390 unsigned int type = output_type(attr->type);
350 391
351 output[type].print_ip_opts = 0; 392 output[type].print_ip_opts = 0;
352 if (PRINT_FIELD(IP)) 393 if (PRINT_FIELD(IP))
@@ -374,16 +415,17 @@ static int perf_session__check_output_opt(struct perf_session *session)
374 unsigned int j; 415 unsigned int j;
375 struct perf_evsel *evsel; 416 struct perf_evsel *evsel;
376 417
377 for (j = 0; j < PERF_TYPE_MAX; ++j) { 418 for (j = 0; j < OUTPUT_TYPE_MAX; ++j) {
378 evsel = perf_session__find_first_evtype(session, j); 419 evsel = perf_session__find_first_evtype(session, attr_type(j));
379 420
380 /* 421 /*
381 * even if fields is set to 0 (ie., show nothing) event must 422 * even if fields is set to 0 (ie., show nothing) event must
382 * exist if user explicitly includes it on the command line 423 * exist if user explicitly includes it on the command line
383 */ 424 */
384 if (!evsel && output[j].user_set && !output[j].wildcard_set) { 425 if (!evsel && output[j].user_set && !output[j].wildcard_set &&
426 j != OUTPUT_TYPE_SYNTH) {
385 pr_err("%s events do not exist. " 427 pr_err("%s events do not exist. "
386 "Remove corresponding -f option to proceed.\n", 428 "Remove corresponding -F option to proceed.\n",
387 event_type(j)); 429 event_type(j));
388 return -1; 430 return -1;
389 } 431 }
@@ -514,18 +556,43 @@ mispred_str(struct branch_entry *br)
514 return br->flags.predicted ? 'P' : 'M'; 556 return br->flags.predicted ? 'P' : 'M';
515} 557}
516 558
517static void print_sample_brstack(struct perf_sample *sample) 559static void print_sample_brstack(struct perf_sample *sample,
560 struct thread *thread,
561 struct perf_event_attr *attr)
518{ 562{
519 struct branch_stack *br = sample->branch_stack; 563 struct branch_stack *br = sample->branch_stack;
520 u64 i; 564 struct addr_location alf, alt;
565 u64 i, from, to;
521 566
522 if (!(br && br->nr)) 567 if (!(br && br->nr))
523 return; 568 return;
524 569
525 for (i = 0; i < br->nr; i++) { 570 for (i = 0; i < br->nr; i++) {
526 printf(" 0x%"PRIx64"/0x%"PRIx64"/%c/%c/%c/%d ", 571 from = br->entries[i].from;
527 br->entries[i].from, 572 to = br->entries[i].to;
528 br->entries[i].to, 573
574 if (PRINT_FIELD(DSO)) {
575 memset(&alf, 0, sizeof(alf));
576 memset(&alt, 0, sizeof(alt));
577 thread__find_addr_map(thread, sample->cpumode, MAP__FUNCTION, from, &alf);
578 thread__find_addr_map(thread, sample->cpumode, MAP__FUNCTION, to, &alt);
579 }
580
581 printf("0x%"PRIx64, from);
582 if (PRINT_FIELD(DSO)) {
583 printf("(");
584 map__fprintf_dsoname(alf.map, stdout);
585 printf(")");
586 }
587
588 printf("/0x%"PRIx64, to);
589 if (PRINT_FIELD(DSO)) {
590 printf("(");
591 map__fprintf_dsoname(alt.map, stdout);
592 printf(")");
593 }
594
595 printf("/%c/%c/%c/%d ",
529 mispred_str( br->entries + i), 596 mispred_str( br->entries + i),
530 br->entries[i].flags.in_tx? 'X' : '-', 597 br->entries[i].flags.in_tx? 'X' : '-',
531 br->entries[i].flags.abort? 'A' : '-', 598 br->entries[i].flags.abort? 'A' : '-',
@@ -534,7 +601,8 @@ static void print_sample_brstack(struct perf_sample *sample)
534} 601}
535 602
536static void print_sample_brstacksym(struct perf_sample *sample, 603static void print_sample_brstacksym(struct perf_sample *sample,
537 struct thread *thread) 604 struct thread *thread,
605 struct perf_event_attr *attr)
538{ 606{
539 struct branch_stack *br = sample->branch_stack; 607 struct branch_stack *br = sample->branch_stack;
540 struct addr_location alf, alt; 608 struct addr_location alf, alt;
@@ -559,8 +627,18 @@ static void print_sample_brstacksym(struct perf_sample *sample,
559 alt.sym = map__find_symbol(alt.map, alt.addr); 627 alt.sym = map__find_symbol(alt.map, alt.addr);
560 628
561 symbol__fprintf_symname_offs(alf.sym, &alf, stdout); 629 symbol__fprintf_symname_offs(alf.sym, &alf, stdout);
630 if (PRINT_FIELD(DSO)) {
631 printf("(");
632 map__fprintf_dsoname(alf.map, stdout);
633 printf(")");
634 }
562 putchar('/'); 635 putchar('/');
563 symbol__fprintf_symname_offs(alt.sym, &alt, stdout); 636 symbol__fprintf_symname_offs(alt.sym, &alt, stdout);
637 if (PRINT_FIELD(DSO)) {
638 printf("(");
639 map__fprintf_dsoname(alt.map, stdout);
640 printf(")");
641 }
564 printf("/%c/%c/%c/%d ", 642 printf("/%c/%c/%c/%d ",
565 mispred_str( br->entries + i), 643 mispred_str( br->entries + i),
566 br->entries[i].flags.in_tx? 'X' : '-', 644 br->entries[i].flags.in_tx? 'X' : '-',
@@ -569,6 +647,51 @@ static void print_sample_brstacksym(struct perf_sample *sample,
569 } 647 }
570} 648}
571 649
650static void print_sample_brstackoff(struct perf_sample *sample,
651 struct thread *thread,
652 struct perf_event_attr *attr)
653{
654 struct branch_stack *br = sample->branch_stack;
655 struct addr_location alf, alt;
656 u64 i, from, to;
657
658 if (!(br && br->nr))
659 return;
660
661 for (i = 0; i < br->nr; i++) {
662
663 memset(&alf, 0, sizeof(alf));
664 memset(&alt, 0, sizeof(alt));
665 from = br->entries[i].from;
666 to = br->entries[i].to;
667
668 thread__find_addr_map(thread, sample->cpumode, MAP__FUNCTION, from, &alf);
669 if (alf.map && !alf.map->dso->adjust_symbols)
670 from = map__map_ip(alf.map, from);
671
672 thread__find_addr_map(thread, sample->cpumode, MAP__FUNCTION, to, &alt);
673 if (alt.map && !alt.map->dso->adjust_symbols)
674 to = map__map_ip(alt.map, to);
675
676 printf("0x%"PRIx64, from);
677 if (PRINT_FIELD(DSO)) {
678 printf("(");
679 map__fprintf_dsoname(alf.map, stdout);
680 printf(")");
681 }
682 printf("/0x%"PRIx64, to);
683 if (PRINT_FIELD(DSO)) {
684 printf("(");
685 map__fprintf_dsoname(alt.map, stdout);
686 printf(")");
687 }
688 printf("/%c/%c/%c/%d ",
689 mispred_str(br->entries + i),
690 br->entries[i].flags.in_tx ? 'X' : '-',
691 br->entries[i].flags.abort ? 'A' : '-',
692 br->entries[i].flags.cycles);
693 }
694}
572#define MAXBB 16384UL 695#define MAXBB 16384UL
573 696
574static int grab_bb(u8 *buffer, u64 start, u64 end, 697static int grab_bb(u8 *buffer, u64 start, u64 end,
@@ -906,6 +1029,7 @@ static void print_sample_bts(struct perf_sample *sample,
906 struct machine *machine) 1029 struct machine *machine)
907{ 1030{
908 struct perf_event_attr *attr = &evsel->attr; 1031 struct perf_event_attr *attr = &evsel->attr;
1032 unsigned int type = output_type(attr->type);
909 bool print_srcline_last = false; 1033 bool print_srcline_last = false;
910 1034
911 if (PRINT_FIELD(CALLINDENT)) 1035 if (PRINT_FIELD(CALLINDENT))
@@ -913,7 +1037,7 @@ static void print_sample_bts(struct perf_sample *sample,
913 1037
914 /* print branch_from information */ 1038 /* print branch_from information */
915 if (PRINT_FIELD(IP)) { 1039 if (PRINT_FIELD(IP)) {
916 unsigned int print_opts = output[attr->type].print_ip_opts; 1040 unsigned int print_opts = output[type].print_ip_opts;
917 struct callchain_cursor *cursor = NULL; 1041 struct callchain_cursor *cursor = NULL;
918 1042
919 if (symbol_conf.use_callchain && sample->callchain && 1043 if (symbol_conf.use_callchain && sample->callchain &&
@@ -936,7 +1060,7 @@ static void print_sample_bts(struct perf_sample *sample,
936 /* print branch_to information */ 1060 /* print branch_to information */
937 if (PRINT_FIELD(ADDR) || 1061 if (PRINT_FIELD(ADDR) ||
938 ((evsel->attr.sample_type & PERF_SAMPLE_ADDR) && 1062 ((evsel->attr.sample_type & PERF_SAMPLE_ADDR) &&
939 !output[attr->type].user_set)) { 1063 !output[type].user_set)) {
940 printf(" => "); 1064 printf(" => ");
941 print_sample_addr(sample, thread, attr); 1065 print_sample_addr(sample, thread, attr);
942 } 1066 }
@@ -1079,6 +1203,127 @@ static void print_sample_bpf_output(struct perf_sample *sample)
1079 (char *)(sample->raw_data)); 1203 (char *)(sample->raw_data));
1080} 1204}
1081 1205
1206static void print_sample_spacing(int len, int spacing)
1207{
1208 if (len > 0 && len < spacing)
1209 printf("%*s", spacing - len, "");
1210}
1211
1212static void print_sample_pt_spacing(int len)
1213{
1214 print_sample_spacing(len, 34);
1215}
1216
1217static void print_sample_synth_ptwrite(struct perf_sample *sample)
1218{
1219 struct perf_synth_intel_ptwrite *data = perf_sample__synth_ptr(sample);
1220 int len;
1221
1222 if (perf_sample__bad_synth_size(sample, *data))
1223 return;
1224
1225 len = printf(" IP: %u payload: %#" PRIx64 " ",
1226 data->ip, le64_to_cpu(data->payload));
1227 print_sample_pt_spacing(len);
1228}
1229
1230static void print_sample_synth_mwait(struct perf_sample *sample)
1231{
1232 struct perf_synth_intel_mwait *data = perf_sample__synth_ptr(sample);
1233 int len;
1234
1235 if (perf_sample__bad_synth_size(sample, *data))
1236 return;
1237
1238 len = printf(" hints: %#x extensions: %#x ",
1239 data->hints, data->extensions);
1240 print_sample_pt_spacing(len);
1241}
1242
1243static void print_sample_synth_pwre(struct perf_sample *sample)
1244{
1245 struct perf_synth_intel_pwre *data = perf_sample__synth_ptr(sample);
1246 int len;
1247
1248 if (perf_sample__bad_synth_size(sample, *data))
1249 return;
1250
1251 len = printf(" hw: %u cstate: %u sub-cstate: %u ",
1252 data->hw, data->cstate, data->subcstate);
1253 print_sample_pt_spacing(len);
1254}
1255
1256static void print_sample_synth_exstop(struct perf_sample *sample)
1257{
1258 struct perf_synth_intel_exstop *data = perf_sample__synth_ptr(sample);
1259 int len;
1260
1261 if (perf_sample__bad_synth_size(sample, *data))
1262 return;
1263
1264 len = printf(" IP: %u ", data->ip);
1265 print_sample_pt_spacing(len);
1266}
1267
1268static void print_sample_synth_pwrx(struct perf_sample *sample)
1269{
1270 struct perf_synth_intel_pwrx *data = perf_sample__synth_ptr(sample);
1271 int len;
1272
1273 if (perf_sample__bad_synth_size(sample, *data))
1274 return;
1275
1276 len = printf(" deepest cstate: %u last cstate: %u wake reason: %#x ",
1277 data->deepest_cstate, data->last_cstate,
1278 data->wake_reason);
1279 print_sample_pt_spacing(len);
1280}
1281
1282static void print_sample_synth_cbr(struct perf_sample *sample)
1283{
1284 struct perf_synth_intel_cbr *data = perf_sample__synth_ptr(sample);
1285 unsigned int percent, freq;
1286 int len;
1287
1288 if (perf_sample__bad_synth_size(sample, *data))
1289 return;
1290
1291 freq = (le32_to_cpu(data->freq) + 500) / 1000;
1292 len = printf(" cbr: %2u freq: %4u MHz ", data->cbr, freq);
1293 if (data->max_nonturbo) {
1294 percent = (5 + (1000 * data->cbr) / data->max_nonturbo) / 10;
1295 len += printf("(%3u%%) ", percent);
1296 }
1297 print_sample_pt_spacing(len);
1298}
1299
1300static void print_sample_synth(struct perf_sample *sample,
1301 struct perf_evsel *evsel)
1302{
1303 switch (evsel->attr.config) {
1304 case PERF_SYNTH_INTEL_PTWRITE:
1305 print_sample_synth_ptwrite(sample);
1306 break;
1307 case PERF_SYNTH_INTEL_MWAIT:
1308 print_sample_synth_mwait(sample);
1309 break;
1310 case PERF_SYNTH_INTEL_PWRE:
1311 print_sample_synth_pwre(sample);
1312 break;
1313 case PERF_SYNTH_INTEL_EXSTOP:
1314 print_sample_synth_exstop(sample);
1315 break;
1316 case PERF_SYNTH_INTEL_PWRX:
1317 print_sample_synth_pwrx(sample);
1318 break;
1319 case PERF_SYNTH_INTEL_CBR:
1320 print_sample_synth_cbr(sample);
1321 break;
1322 default:
1323 break;
1324 }
1325}
1326
1082struct perf_script { 1327struct perf_script {
1083 struct perf_tool tool; 1328 struct perf_tool tool;
1084 struct perf_session *session; 1329 struct perf_session *session;
@@ -1132,8 +1377,9 @@ static void process_event(struct perf_script *script,
1132{ 1377{
1133 struct thread *thread = al->thread; 1378 struct thread *thread = al->thread;
1134 struct perf_event_attr *attr = &evsel->attr; 1379 struct perf_event_attr *attr = &evsel->attr;
1380 unsigned int type = output_type(attr->type);
1135 1381
1136 if (output[attr->type].fields == 0) 1382 if (output[type].fields == 0)
1137 return; 1383 return;
1138 1384
1139 print_sample_start(sample, thread, evsel); 1385 print_sample_start(sample, thread, evsel);
@@ -1162,6 +1408,10 @@ static void process_event(struct perf_script *script,
1162 if (PRINT_FIELD(TRACE)) 1408 if (PRINT_FIELD(TRACE))
1163 event_format__print(evsel->tp_format, sample->cpu, 1409 event_format__print(evsel->tp_format, sample->cpu,
1164 sample->raw_data, sample->raw_size); 1410 sample->raw_data, sample->raw_size);
1411
1412 if (attr->type == PERF_TYPE_SYNTH && PRINT_FIELD(SYNTH))
1413 print_sample_synth(sample, evsel);
1414
1165 if (PRINT_FIELD(ADDR)) 1415 if (PRINT_FIELD(ADDR))
1166 print_sample_addr(sample, thread, attr); 1416 print_sample_addr(sample, thread, attr);
1167 1417
@@ -1180,16 +1430,18 @@ static void process_event(struct perf_script *script,
1180 cursor = &callchain_cursor; 1430 cursor = &callchain_cursor;
1181 1431
1182 putchar(cursor ? '\n' : ' '); 1432 putchar(cursor ? '\n' : ' ');
1183 sample__fprintf_sym(sample, al, 0, output[attr->type].print_ip_opts, cursor, stdout); 1433 sample__fprintf_sym(sample, al, 0, output[type].print_ip_opts, cursor, stdout);
1184 } 1434 }
1185 1435
1186 if (PRINT_FIELD(IREGS)) 1436 if (PRINT_FIELD(IREGS))
1187 print_sample_iregs(sample, attr); 1437 print_sample_iregs(sample, attr);
1188 1438
1189 if (PRINT_FIELD(BRSTACK)) 1439 if (PRINT_FIELD(BRSTACK))
1190 print_sample_brstack(sample); 1440 print_sample_brstack(sample, thread, attr);
1191 else if (PRINT_FIELD(BRSTACKSYM)) 1441 else if (PRINT_FIELD(BRSTACKSYM))
1192 print_sample_brstacksym(sample, thread); 1442 print_sample_brstacksym(sample, thread, attr);
1443 else if (PRINT_FIELD(BRSTACKOFF))
1444 print_sample_brstackoff(sample, thread, attr);
1193 1445
1194 if (perf_evsel__is_bpf_output(evsel) && PRINT_FIELD(BPF_OUTPUT)) 1446 if (perf_evsel__is_bpf_output(evsel) && PRINT_FIELD(BPF_OUTPUT))
1195 print_sample_bpf_output(sample); 1447 print_sample_bpf_output(sample);
@@ -1325,7 +1577,8 @@ static int process_attr(struct perf_tool *tool, union perf_event *event,
1325 evlist = *pevlist; 1577 evlist = *pevlist;
1326 evsel = perf_evlist__last(*pevlist); 1578 evsel = perf_evlist__last(*pevlist);
1327 1579
1328 if (evsel->attr.type >= PERF_TYPE_MAX) 1580 if (evsel->attr.type >= PERF_TYPE_MAX &&
1581 evsel->attr.type != PERF_TYPE_SYNTH)
1329 return 0; 1582 return 0;
1330 1583
1331 evlist__for_each_entry(evlist, pos) { 1584 evlist__for_each_entry(evlist, pos) {
@@ -1727,6 +1980,7 @@ static int parse_output_fields(const struct option *opt __maybe_unused,
1727 int rc = 0; 1980 int rc = 0;
1728 char *str = strdup(arg); 1981 char *str = strdup(arg);
1729 int type = -1; 1982 int type = -1;
1983 enum { DEFAULT, SET, ADD, REMOVE } change = DEFAULT;
1730 1984
1731 if (!str) 1985 if (!str)
1732 return -ENOMEM; 1986 return -ENOMEM;
@@ -1749,6 +2003,8 @@ static int parse_output_fields(const struct option *opt __maybe_unused,
1749 type = PERF_TYPE_RAW; 2003 type = PERF_TYPE_RAW;
1750 else if (!strcmp(str, "break")) 2004 else if (!strcmp(str, "break"))
1751 type = PERF_TYPE_BREAKPOINT; 2005 type = PERF_TYPE_BREAKPOINT;
2006 else if (!strcmp(str, "synth"))
2007 type = OUTPUT_TYPE_SYNTH;
1752 else { 2008 else {
1753 fprintf(stderr, "Invalid event type in field string.\n"); 2009 fprintf(stderr, "Invalid event type in field string.\n");
1754 rc = -EINVAL; 2010 rc = -EINVAL;
@@ -1772,23 +2028,44 @@ static int parse_output_fields(const struct option *opt __maybe_unused,
1772 goto out; 2028 goto out;
1773 } 2029 }
1774 2030
2031 /* Don't override defaults for +- */
2032 if (strchr(str, '+') || strchr(str, '-'))
2033 goto parse;
2034
1775 if (output_set_by_user()) 2035 if (output_set_by_user())
1776 pr_warning("Overriding previous field request for all events.\n"); 2036 pr_warning("Overriding previous field request for all events.\n");
1777 2037
1778 for (j = 0; j < PERF_TYPE_MAX; ++j) { 2038 for (j = 0; j < OUTPUT_TYPE_MAX; ++j) {
1779 output[j].fields = 0; 2039 output[j].fields = 0;
1780 output[j].user_set = true; 2040 output[j].user_set = true;
1781 output[j].wildcard_set = true; 2041 output[j].wildcard_set = true;
1782 } 2042 }
1783 } 2043 }
1784 2044
2045parse:
1785 for (tok = strtok_r(tok, ",", &strtok_saveptr); tok; tok = strtok_r(NULL, ",", &strtok_saveptr)) { 2046 for (tok = strtok_r(tok, ",", &strtok_saveptr); tok; tok = strtok_r(NULL, ",", &strtok_saveptr)) {
2047 if (*tok == '+') {
2048 if (change == SET)
2049 goto out_badmix;
2050 change = ADD;
2051 tok++;
2052 } else if (*tok == '-') {
2053 if (change == SET)
2054 goto out_badmix;
2055 change = REMOVE;
2056 tok++;
2057 } else {
2058 if (change != SET && change != DEFAULT)
2059 goto out_badmix;
2060 change = SET;
2061 }
2062
1786 for (i = 0; i < imax; ++i) { 2063 for (i = 0; i < imax; ++i) {
1787 if (strcmp(tok, all_output_options[i].str) == 0) 2064 if (strcmp(tok, all_output_options[i].str) == 0)
1788 break; 2065 break;
1789 } 2066 }
1790 if (i == imax && strcmp(tok, "flags") == 0) { 2067 if (i == imax && strcmp(tok, "flags") == 0) {
1791 print_flags = true; 2068 print_flags = change == REMOVE ? false : true;
1792 continue; 2069 continue;
1793 } 2070 }
1794 if (i == imax) { 2071 if (i == imax) {
@@ -1801,12 +2078,16 @@ static int parse_output_fields(const struct option *opt __maybe_unused,
1801 /* add user option to all events types for 2078 /* add user option to all events types for
1802 * which it is valid 2079 * which it is valid
1803 */ 2080 */
1804 for (j = 0; j < PERF_TYPE_MAX; ++j) { 2081 for (j = 0; j < OUTPUT_TYPE_MAX; ++j) {
1805 if (output[j].invalid_fields & all_output_options[i].field) { 2082 if (output[j].invalid_fields & all_output_options[i].field) {
1806 pr_warning("\'%s\' not valid for %s events. Ignoring.\n", 2083 pr_warning("\'%s\' not valid for %s events. Ignoring.\n",
1807 all_output_options[i].str, event_type(j)); 2084 all_output_options[i].str, event_type(j));
1808 } else 2085 } else {
1809 output[j].fields |= all_output_options[i].field; 2086 if (change == REMOVE)
2087 output[j].fields &= ~all_output_options[i].field;
2088 else
2089 output[j].fields |= all_output_options[i].field;
2090 }
1810 } 2091 }
1811 } else { 2092 } else {
1812 if (output[type].invalid_fields & all_output_options[i].field) { 2093 if (output[type].invalid_fields & all_output_options[i].field) {
@@ -1826,7 +2107,11 @@ static int parse_output_fields(const struct option *opt __maybe_unused,
1826 "Events will not be displayed.\n", event_type(type)); 2107 "Events will not be displayed.\n", event_type(type));
1827 } 2108 }
1828 } 2109 }
2110 goto out;
1829 2111
2112out_badmix:
2113 fprintf(stderr, "Cannot mix +-field with overridden fields\n");
2114 rc = -EINVAL;
1830out: 2115out:
1831 free(str); 2116 free(str);
1832 return rc; 2117 return rc;
@@ -2444,10 +2729,11 @@ int cmd_script(int argc, const char **argv)
2444 symbol__config_symfs), 2729 symbol__config_symfs),
2445 OPT_CALLBACK('F', "fields", NULL, "str", 2730 OPT_CALLBACK('F', "fields", NULL, "str",
2446 "comma separated output fields prepend with 'type:'. " 2731 "comma separated output fields prepend with 'type:'. "
2447 "Valid types: hw,sw,trace,raw. " 2732 "+field to add and -field to remove."
2733 "Valid types: hw,sw,trace,raw,synth. "
2448 "Fields: comm,tid,pid,time,cpu,event,trace,ip,sym,dso," 2734 "Fields: comm,tid,pid,time,cpu,event,trace,ip,sym,dso,"
2449 "addr,symoff,period,iregs,brstack,brstacksym,flags," 2735 "addr,symoff,period,iregs,brstack,brstacksym,flags,"
2450 "bpf-output,callindent,insn,insnlen,brstackinsn", 2736 "bpf-output,callindent,insn,insnlen,brstackinsn,synth",
2451 parse_output_fields), 2737 parse_output_fields),
2452 OPT_BOOLEAN('a', "all-cpus", &system_wide, 2738 OPT_BOOLEAN('a', "all-cpus", &system_wide,
2453 "system-wide collection from all CPUs"), 2739 "system-wide collection from all CPUs"),
@@ -2494,6 +2780,8 @@ int cmd_script(int argc, const char **argv)
2494 "Enable kernel symbol demangling"), 2780 "Enable kernel symbol demangling"),
2495 OPT_STRING(0, "time", &script.time_str, "str", 2781 OPT_STRING(0, "time", &script.time_str, "str",
2496 "Time span of interest (start,stop)"), 2782 "Time span of interest (start,stop)"),
2783 OPT_BOOLEAN(0, "inline", &symbol_conf.inline_name,
2784 "Show inline function"),
2497 OPT_END() 2785 OPT_END()
2498 }; 2786 };
2499 const char * const script_subcommands[] = { "record", "report", NULL }; 2787 const char * const script_subcommands[] = { "record", "report", NULL };
@@ -2704,6 +2992,7 @@ int cmd_script(int argc, const char **argv)
2704 err = perf_session__cpu_bitmap(session, cpu_list, cpu_bitmap); 2992 err = perf_session__cpu_bitmap(session, cpu_list, cpu_bitmap);
2705 if (err < 0) 2993 if (err < 0)
2706 goto out_delete; 2994 goto out_delete;
2995 itrace_synth_opts.cpu_bitmap = cpu_bitmap;
2707 } 2996 }
2708 2997
2709 if (!no_callchain) 2998 if (!no_callchain)
diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c
index a935b5023732..48ac53b199fc 100644
--- a/tools/perf/builtin-stat.c
+++ b/tools/perf/builtin-stat.c
@@ -86,6 +86,7 @@
86#define DEFAULT_SEPARATOR " " 86#define DEFAULT_SEPARATOR " "
87#define CNTR_NOT_SUPPORTED "<not supported>" 87#define CNTR_NOT_SUPPORTED "<not supported>"
88#define CNTR_NOT_COUNTED "<not counted>" 88#define CNTR_NOT_COUNTED "<not counted>"
89#define FREEZE_ON_SMI_PATH "devices/cpu/freeze_on_smi"
89 90
90static void print_counters(struct timespec *ts, int argc, const char **argv); 91static void print_counters(struct timespec *ts, int argc, const char **argv);
91 92
@@ -122,6 +123,14 @@ static const char * topdown_attrs[] = {
122 NULL, 123 NULL,
123}; 124};
124 125
126static const char *smi_cost_attrs = {
127 "{"
128 "msr/aperf/,"
129 "msr/smi/,"
130 "cycles"
131 "}"
132};
133
125static struct perf_evlist *evsel_list; 134static struct perf_evlist *evsel_list;
126 135
127static struct target target = { 136static struct target target = {
@@ -137,6 +146,8 @@ static bool null_run = false;
137static int detailed_run = 0; 146static int detailed_run = 0;
138static bool transaction_run; 147static bool transaction_run;
139static bool topdown_run = false; 148static bool topdown_run = false;
149static bool smi_cost = false;
150static bool smi_reset = false;
140static bool big_num = true; 151static bool big_num = true;
141static int big_num_opt = -1; 152static int big_num_opt = -1;
142static const char *csv_sep = NULL; 153static const char *csv_sep = NULL;
@@ -625,14 +636,14 @@ try_again:
625 } 636 }
626 637
627 if (perf_evlist__apply_filters(evsel_list, &counter)) { 638 if (perf_evlist__apply_filters(evsel_list, &counter)) {
628 error("failed to set filter \"%s\" on event %s with %d (%s)\n", 639 pr_err("failed to set filter \"%s\" on event %s with %d (%s)\n",
629 counter->filter, perf_evsel__name(counter), errno, 640 counter->filter, perf_evsel__name(counter), errno,
630 str_error_r(errno, msg, sizeof(msg))); 641 str_error_r(errno, msg, sizeof(msg)));
631 return -1; 642 return -1;
632 } 643 }
633 644
634 if (perf_evlist__apply_drv_configs(evsel_list, &counter, &err_term)) { 645 if (perf_evlist__apply_drv_configs(evsel_list, &counter, &err_term)) {
635 error("failed to set config \"%s\" on event %s with %d (%s)\n", 646 pr_err("failed to set config \"%s\" on event %s with %d (%s)\n",
636 err_term->val.drv_cfg, perf_evsel__name(counter), errno, 647 err_term->val.drv_cfg, perf_evsel__name(counter), errno,
637 str_error_r(errno, msg, sizeof(msg))); 648 str_error_r(errno, msg, sizeof(msg)));
638 return -1; 649 return -1;
@@ -1578,6 +1589,7 @@ static void print_header(int argc, const char **argv)
1578static void print_footer(void) 1589static void print_footer(void)
1579{ 1590{
1580 FILE *output = stat_config.output; 1591 FILE *output = stat_config.output;
1592 int n;
1581 1593
1582 if (!null_run) 1594 if (!null_run)
1583 fprintf(output, "\n"); 1595 fprintf(output, "\n");
@@ -1590,7 +1602,9 @@ static void print_footer(void)
1590 } 1602 }
1591 fprintf(output, "\n\n"); 1603 fprintf(output, "\n\n");
1592 1604
1593 if (print_free_counters_hint) 1605 if (print_free_counters_hint &&
1606 sysctl__read_int("kernel/nmi_watchdog", &n) >= 0 &&
1607 n > 0)
1594 fprintf(output, 1608 fprintf(output,
1595"Some events weren't counted. Try disabling the NMI watchdog:\n" 1609"Some events weren't counted. Try disabling the NMI watchdog:\n"
1596" echo 0 > /proc/sys/kernel/nmi_watchdog\n" 1610" echo 0 > /proc/sys/kernel/nmi_watchdog\n"
@@ -1779,6 +1793,8 @@ static const struct option stat_options[] = {
1779 "Only print computed metrics. No raw values", enable_metric_only), 1793 "Only print computed metrics. No raw values", enable_metric_only),
1780 OPT_BOOLEAN(0, "topdown", &topdown_run, 1794 OPT_BOOLEAN(0, "topdown", &topdown_run,
1781 "measure topdown level 1 statistics"), 1795 "measure topdown level 1 statistics"),
1796 OPT_BOOLEAN(0, "smi-cost", &smi_cost,
1797 "measure SMI cost"),
1782 OPT_END() 1798 OPT_END()
1783}; 1799};
1784 1800
@@ -2157,6 +2173,39 @@ static int add_default_attributes(void)
2157 return 0; 2173 return 0;
2158 } 2174 }
2159 2175
2176 if (smi_cost) {
2177 int smi;
2178
2179 if (sysfs__read_int(FREEZE_ON_SMI_PATH, &smi) < 0) {
2180 fprintf(stderr, "freeze_on_smi is not supported.\n");
2181 return -1;
2182 }
2183
2184 if (!smi) {
2185 if (sysfs__write_int(FREEZE_ON_SMI_PATH, 1) < 0) {
2186 fprintf(stderr, "Failed to set freeze_on_smi.\n");
2187 return -1;
2188 }
2189 smi_reset = true;
2190 }
2191
2192 if (pmu_have_event("msr", "aperf") &&
2193 pmu_have_event("msr", "smi")) {
2194 if (!force_metric_only)
2195 metric_only = true;
2196 err = parse_events(evsel_list, smi_cost_attrs, NULL);
2197 } else {
2198 fprintf(stderr, "To measure SMI cost, it needs "
2199 "msr/aperf/, msr/smi/ and cpu/cycles/ support\n");
2200 return -1;
2201 }
2202 if (err) {
2203 fprintf(stderr, "Cannot set up SMI cost events\n");
2204 return -1;
2205 }
2206 return 0;
2207 }
2208
2160 if (topdown_run) { 2209 if (topdown_run) {
2161 char *str = NULL; 2210 char *str = NULL;
2162 bool warn = false; 2211 bool warn = false;
@@ -2739,6 +2788,9 @@ int cmd_stat(int argc, const char **argv)
2739 perf_stat__exit_aggr_mode(); 2788 perf_stat__exit_aggr_mode();
2740 perf_evlist__free_stats(evsel_list); 2789 perf_evlist__free_stats(evsel_list);
2741out: 2790out:
2791 if (smi_cost && smi_reset)
2792 sysfs__write_int(FREEZE_ON_SMI_PATH, 0);
2793
2742 perf_evlist__delete(evsel_list); 2794 perf_evlist__delete(evsel_list);
2743 return status; 2795 return status;
2744} 2796}
diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c
index 10b6362ca0bf..6052376634c0 100644
--- a/tools/perf/builtin-top.c
+++ b/tools/perf/builtin-top.c
@@ -134,7 +134,7 @@ static int perf_top__parse_source(struct perf_top *top, struct hist_entry *he)
134 return err; 134 return err;
135 } 135 }
136 136
137 err = symbol__disassemble(sym, map, NULL, 0); 137 err = symbol__disassemble(sym, map, NULL, 0, NULL);
138 if (err == 0) { 138 if (err == 0) {
139out_assign: 139out_assign:
140 top->sym_filter_entry = he; 140 top->sym_filter_entry = he;
@@ -958,7 +958,7 @@ static int __cmd_top(struct perf_top *top)
958 958
959 ret = perf_evlist__apply_drv_configs(evlist, &pos, &err_term); 959 ret = perf_evlist__apply_drv_configs(evlist, &pos, &err_term);
960 if (ret) { 960 if (ret) {
961 error("failed to set config \"%s\" on event %s with %d (%s)\n", 961 pr_err("failed to set config \"%s\" on event %s with %d (%s)\n",
962 err_term->val.drv_cfg, perf_evsel__name(pos), errno, 962 err_term->val.drv_cfg, perf_evsel__name(pos), errno,
963 str_error_r(errno, msg, sizeof(msg))); 963 str_error_r(errno, msg, sizeof(msg)));
964 goto out_delete; 964 goto out_delete;
diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c
index d014350adc52..4b2a5d298197 100644
--- a/tools/perf/builtin-trace.c
+++ b/tools/perf/builtin-trace.c
@@ -681,6 +681,10 @@ static struct syscall_fmt {
681 { .name = "mlockall", .errmsg = true, 681 { .name = "mlockall", .errmsg = true,
682 .arg_scnprintf = { [0] = SCA_HEX, /* addr */ }, }, 682 .arg_scnprintf = { [0] = SCA_HEX, /* addr */ }, },
683 { .name = "mmap", .hexret = true, 683 { .name = "mmap", .hexret = true,
684/* The standard mmap maps to old_mmap on s390x */
685#if defined(__s390x__)
686 .alias = "old_mmap",
687#endif
684 .arg_scnprintf = { [0] = SCA_HEX, /* addr */ 688 .arg_scnprintf = { [0] = SCA_HEX, /* addr */
685 [2] = SCA_MMAP_PROT, /* prot */ 689 [2] = SCA_MMAP_PROT, /* prot */
686 [3] = SCA_MMAP_FLAGS, /* flags */ }, }, 690 [3] = SCA_MMAP_FLAGS, /* flags */ }, },
diff --git a/tools/perf/jvmti/jvmti_agent.c b/tools/perf/jvmti/jvmti_agent.c
index e9651a9d670e..cf36de7ea255 100644
--- a/tools/perf/jvmti/jvmti_agent.c
+++ b/tools/perf/jvmti/jvmti_agent.c
@@ -304,7 +304,7 @@ jvmti_close(void *agent)
304 FILE *fp = agent; 304 FILE *fp = agent;
305 305
306 if (!fp) { 306 if (!fp) {
307 warnx("jvmti: incalid fd in close_agent"); 307 warnx("jvmti: invalid fd in close_agent");
308 return -1; 308 return -1;
309 } 309 }
310 310
diff --git a/tools/perf/jvmti/jvmti_agent.h b/tools/perf/jvmti/jvmti_agent.h
index bedf5d0ba9ff..c53a41f48b63 100644
--- a/tools/perf/jvmti/jvmti_agent.h
+++ b/tools/perf/jvmti/jvmti_agent.h
@@ -5,8 +5,6 @@
5#include <stdint.h> 5#include <stdint.h>
6#include <jvmti.h> 6#include <jvmti.h>
7 7
8#define __unused __attribute__((unused))
9
10#if defined(__cplusplus) 8#if defined(__cplusplus)
11extern "C" { 9extern "C" {
12#endif 10#endif
diff --git a/tools/perf/jvmti/libjvmti.c b/tools/perf/jvmti/libjvmti.c
index 5612641c69b4..6d710904c837 100644
--- a/tools/perf/jvmti/libjvmti.c
+++ b/tools/perf/jvmti/libjvmti.c
@@ -1,3 +1,4 @@
1#include <linux/compiler.h>
1#include <sys/types.h> 2#include <sys/types.h>
2#include <stdio.h> 3#include <stdio.h>
3#include <string.h> 4#include <string.h>
@@ -238,7 +239,7 @@ code_generated_cb(jvmtiEnv *jvmti,
238} 239}
239 240
240JNIEXPORT jint JNICALL 241JNIEXPORT jint JNICALL
241Agent_OnLoad(JavaVM *jvm, char *options, void *reserved __unused) 242Agent_OnLoad(JavaVM *jvm, char *options, void *reserved __maybe_unused)
242{ 243{
243 jvmtiEventCallbacks cb; 244 jvmtiEventCallbacks cb;
244 jvmtiCapabilities caps1; 245 jvmtiCapabilities caps1;
@@ -313,7 +314,7 @@ Agent_OnLoad(JavaVM *jvm, char *options, void *reserved __unused)
313} 314}
314 315
315JNIEXPORT void JNICALL 316JNIEXPORT void JNICALL
316Agent_OnUnload(JavaVM *jvm __unused) 317Agent_OnUnload(JavaVM *jvm __maybe_unused)
317{ 318{
318 int ret; 319 int ret;
319 320
diff --git a/tools/perf/pmu-events/Build b/tools/perf/pmu-events/Build
index 9213a1273697..999a4e878162 100644
--- a/tools/perf/pmu-events/Build
+++ b/tools/perf/pmu-events/Build
@@ -2,7 +2,7 @@ hostprogs := jevents
2 2
3jevents-y += json.o jsmn.o jevents.o 3jevents-y += json.o jsmn.o jevents.o
4pmu-events-y += pmu-events.o 4pmu-events-y += pmu-events.o
5JDIR = pmu-events/arch/$(ARCH) 5JDIR = pmu-events/arch/$(SRCARCH)
6JSON = $(shell [ -d $(JDIR) ] && \ 6JSON = $(shell [ -d $(JDIR) ] && \
7 find $(JDIR) -name '*.json' -o -name 'mapfile.csv') 7 find $(JDIR) -name '*.json' -o -name 'mapfile.csv')
8# 8#
@@ -10,4 +10,4 @@ JSON = $(shell [ -d $(JDIR) ] && \
10# directory and create tables in pmu-events.c. 10# directory and create tables in pmu-events.c.
11# 11#
12$(OUTPUT)pmu-events/pmu-events.c: $(JSON) $(JEVENTS) 12$(OUTPUT)pmu-events/pmu-events.c: $(JSON) $(JEVENTS)
13 $(Q)$(call echo-cmd,gen)$(JEVENTS) $(ARCH) pmu-events/arch $(OUTPUT)pmu-events/pmu-events.c $(V) 13 $(Q)$(call echo-cmd,gen)$(JEVENTS) $(SRCARCH) pmu-events/arch $(OUTPUT)pmu-events/pmu-events.c $(V)
diff --git a/tools/perf/pmu-events/jevents.c b/tools/perf/pmu-events/jevents.c
index baa073f38334..bd0aabb2bd0f 100644
--- a/tools/perf/pmu-events/jevents.c
+++ b/tools/perf/pmu-events/jevents.c
@@ -48,10 +48,6 @@
48#include "json.h" 48#include "json.h"
49#include "jevents.h" 49#include "jevents.h"
50 50
51#ifndef __maybe_unused
52#define __maybe_unused __attribute__((unused))
53#endif
54
55int verbose; 51int verbose;
56char *prog; 52char *prog;
57 53
diff --git a/tools/perf/scripts/python/bin/intel-pt-events-record b/tools/perf/scripts/python/bin/intel-pt-events-record
new file mode 100644
index 000000000000..10fe2b6977d4
--- /dev/null
+++ b/tools/perf/scripts/python/bin/intel-pt-events-record
@@ -0,0 +1,13 @@
1#!/bin/bash
2
3#
4# print Intel PT Power Events and PTWRITE. The intel_pt PMU event needs
5# to be specified with appropriate config terms.
6#
7if ! echo "$@" | grep -q intel_pt ; then
8 echo "Options must include the Intel PT event e.g. -e intel_pt/pwr_evt,ptw/"
9 echo "and for power events it probably needs to be system wide i.e. -a option"
10 echo "For example: -a -e intel_pt/pwr_evt,branch=0/ sleep 1"
11 exit 1
12fi
13perf record $@
diff --git a/tools/perf/scripts/python/bin/intel-pt-events-report b/tools/perf/scripts/python/bin/intel-pt-events-report
new file mode 100644
index 000000000000..9a9c92fcd026
--- /dev/null
+++ b/tools/perf/scripts/python/bin/intel-pt-events-report
@@ -0,0 +1,3 @@
1#!/bin/bash
2# description: print Intel PT Power Events and PTWRITE
3perf script $@ -s "$PERF_EXEC_PATH"/scripts/python/intel-pt-events.py \ No newline at end of file
diff --git a/tools/perf/scripts/python/intel-pt-events.py b/tools/perf/scripts/python/intel-pt-events.py
new file mode 100644
index 000000000000..b19172d673af
--- /dev/null
+++ b/tools/perf/scripts/python/intel-pt-events.py
@@ -0,0 +1,128 @@
1# intel-pt-events.py: Print Intel PT Power Events and PTWRITE
2# Copyright (c) 2017, Intel Corporation.
3#
4# This program is free software; you can redistribute it and/or modify it
5# under the terms and conditions of the GNU General Public License,
6# version 2, as published by the Free Software Foundation.
7#
8# This program is distributed in the hope it will be useful, but WITHOUT
9# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
11# more details.
12
13import os
14import sys
15import struct
16
17sys.path.append(os.environ['PERF_EXEC_PATH'] + \
18 '/scripts/python/Perf-Trace-Util/lib/Perf/Trace')
19
20# These perf imports are not used at present
21#from perf_trace_context import *
22#from Core import *
23
24def trace_begin():
25 print "Intel PT Power Events and PTWRITE"
26
27def trace_end():
28 print "End"
29
30def trace_unhandled(event_name, context, event_fields_dict):
31 print ' '.join(['%s=%s'%(k,str(v))for k,v in sorted(event_fields_dict.items())])
32
33def print_ptwrite(raw_buf):
34 data = struct.unpack_from("<IQ", raw_buf)
35 flags = data[0]
36 payload = data[1]
37 exact_ip = flags & 1
38 print "IP: %u payload: %#x" % (exact_ip, payload),
39
40def print_cbr(raw_buf):
41 data = struct.unpack_from("<BBBBII", raw_buf)
42 cbr = data[0]
43 f = (data[4] + 500) / 1000
44 p = ((cbr * 1000 / data[2]) + 5) / 10
45 print "%3u freq: %4u MHz (%3u%%)" % (cbr, f, p),
46
47def print_mwait(raw_buf):
48 data = struct.unpack_from("<IQ", raw_buf)
49 payload = data[1]
50 hints = payload & 0xff
51 extensions = (payload >> 32) & 0x3
52 print "hints: %#x extensions: %#x" % (hints, extensions),
53
54def print_pwre(raw_buf):
55 data = struct.unpack_from("<IQ", raw_buf)
56 payload = data[1]
57 hw = (payload >> 7) & 1
58 cstate = (payload >> 12) & 0xf
59 subcstate = (payload >> 8) & 0xf
60 print "hw: %u cstate: %u sub-cstate: %u" % (hw, cstate, subcstate),
61
62def print_exstop(raw_buf):
63 data = struct.unpack_from("<I", raw_buf)
64 flags = data[0]
65 exact_ip = flags & 1
66 print "IP: %u" % (exact_ip),
67
68def print_pwrx(raw_buf):
69 data = struct.unpack_from("<IQ", raw_buf)
70 payload = data[1]
71 deepest_cstate = payload & 0xf
72 last_cstate = (payload >> 4) & 0xf
73 wake_reason = (payload >> 8) & 0xf
74 print "deepest cstate: %u last cstate: %u wake reason: %#x" % (deepest_cstate, last_cstate, wake_reason),
75
76def print_common_start(comm, sample, name):
77 ts = sample["time"]
78 cpu = sample["cpu"]
79 pid = sample["pid"]
80 tid = sample["tid"]
81 print "%16s %5u/%-5u [%03u] %9u.%09u %7s:" % (comm, pid, tid, cpu, ts / 1000000000, ts %1000000000, name),
82
83def print_common_ip(sample, symbol, dso):
84 ip = sample["ip"]
85 print "%16x %s (%s)" % (ip, symbol, dso)
86
87def process_event(param_dict):
88 event_attr = param_dict["attr"]
89 sample = param_dict["sample"]
90 raw_buf = param_dict["raw_buf"]
91 comm = param_dict["comm"]
92 name = param_dict["ev_name"]
93
94 # Symbol and dso info are not always resolved
95 if (param_dict.has_key("dso")):
96 dso = param_dict["dso"]
97 else:
98 dso = "[unknown]"
99
100 if (param_dict.has_key("symbol")):
101 symbol = param_dict["symbol"]
102 else:
103 symbol = "[unknown]"
104
105 if name == "ptwrite":
106 print_common_start(comm, sample, name)
107 print_ptwrite(raw_buf)
108 print_common_ip(sample, symbol, dso)
109 elif name == "cbr":
110 print_common_start(comm, sample, name)
111 print_cbr(raw_buf)
112 print_common_ip(sample, symbol, dso)
113 elif name == "mwait":
114 print_common_start(comm, sample, name)
115 print_mwait(raw_buf)
116 print_common_ip(sample, symbol, dso)
117 elif name == "pwre":
118 print_common_start(comm, sample, name)
119 print_pwre(raw_buf)
120 print_common_ip(sample, symbol, dso)
121 elif name == "exstop":
122 print_common_start(comm, sample, name)
123 print_exstop(raw_buf)
124 print_common_ip(sample, symbol, dso)
125 elif name == "pwrx":
126 print_common_start(comm, sample, name)
127 print_pwrx(raw_buf)
128 print_common_ip(sample, symbol, dso)
diff --git a/tools/perf/tests/Build b/tools/perf/tests/Build
index af58ebc243ef..84222bdb8689 100644
--- a/tools/perf/tests/Build
+++ b/tools/perf/tests/Build
@@ -75,7 +75,7 @@ $(OUTPUT)tests/llvm-src-relocation.c: tests/bpf-script-test-relocation.c tests/B
75 $(Q)sed -e 's/"/\\"/g' -e 's/\(.*\)/"\1\\n"/g' $< >> $@ 75 $(Q)sed -e 's/"/\\"/g' -e 's/\(.*\)/"\1\\n"/g' $< >> $@
76 $(Q)echo ';' >> $@ 76 $(Q)echo ';' >> $@
77 77
78ifeq ($(ARCH),$(filter $(ARCH),x86 arm arm64 powerpc)) 78ifeq ($(SRCARCH),$(filter $(SRCARCH),x86 arm arm64 powerpc))
79perf-$(CONFIG_DWARF_UNWIND) += dwarf-unwind.o 79perf-$(CONFIG_DWARF_UNWIND) += dwarf-unwind.o
80endif 80endif
81 81
diff --git a/tools/perf/tests/attr.c b/tools/perf/tests/attr.c
index 0dd77494bb58..0e77b2cf61ec 100644
--- a/tools/perf/tests/attr.c
+++ b/tools/perf/tests/attr.c
@@ -18,6 +18,7 @@
18 * permissions. All the event text files are stored there. 18 * permissions. All the event text files are stored there.
19 */ 19 */
20 20
21#include <debug.h>
21#include <errno.h> 22#include <errno.h>
22#include <inttypes.h> 23#include <inttypes.h>
23#include <stdlib.h> 24#include <stdlib.h>
@@ -29,14 +30,11 @@
29#include <sys/stat.h> 30#include <sys/stat.h>
30#include <unistd.h> 31#include <unistd.h>
31#include "../perf.h" 32#include "../perf.h"
32#include "util.h"
33#include <subcmd/exec-cmd.h> 33#include <subcmd/exec-cmd.h>
34#include "tests.h" 34#include "tests.h"
35 35
36#define ENV "PERF_TEST_ATTR" 36#define ENV "PERF_TEST_ATTR"
37 37
38extern int verbose;
39
40static char *dir; 38static char *dir;
41 39
42void test_attr__init(void) 40void test_attr__init(void)
@@ -138,8 +136,10 @@ void test_attr__open(struct perf_event_attr *attr, pid_t pid, int cpu,
138{ 136{
139 int errno_saved = errno; 137 int errno_saved = errno;
140 138
141 if (store_event(attr, pid, cpu, fd, group_fd, flags)) 139 if (store_event(attr, pid, cpu, fd, group_fd, flags)) {
142 die("test attr FAILED"); 140 pr_err("test attr FAILED");
141 exit(128);
142 }
143 143
144 errno = errno_saved; 144 errno = errno_saved;
145} 145}
diff --git a/tools/perf/tests/attr.py b/tools/perf/tests/attr.py
index 1091bd47adfd..cdf21a9d0c35 100644
--- a/tools/perf/tests/attr.py
+++ b/tools/perf/tests/attr.py
@@ -16,6 +16,13 @@ class Fail(Exception):
16 def getMsg(self): 16 def getMsg(self):
17 return '\'%s\' - %s' % (self.test.path, self.msg) 17 return '\'%s\' - %s' % (self.test.path, self.msg)
18 18
19class Notest(Exception):
20 def __init__(self, test, arch):
21 self.arch = arch
22 self.test = test
23 def getMsg(self):
24 return '[%s] \'%s\'' % (self.arch, self.test.path)
25
19class Unsup(Exception): 26class Unsup(Exception):
20 def __init__(self, test): 27 def __init__(self, test):
21 self.test = test 28 self.test = test
@@ -112,6 +119,9 @@ class Event(dict):
112# 'command' - perf command name 119# 'command' - perf command name
113# 'args' - special command arguments 120# 'args' - special command arguments
114# 'ret' - expected command return value (0 by default) 121# 'ret' - expected command return value (0 by default)
122# 'arch' - architecture specific test (optional)
123# comma separated list, ! at the beginning
124# negates it.
115# 125#
116# [eventX:base] 126# [eventX:base]
117# - one or multiple instances in file 127# - one or multiple instances in file
@@ -134,6 +144,12 @@ class Test(object):
134 except: 144 except:
135 self.ret = 0 145 self.ret = 0
136 146
147 try:
148 self.arch = parser.get('config', 'arch')
149 log.warning("test limitation '%s'" % self.arch)
150 except:
151 self.arch = ''
152
137 self.expect = {} 153 self.expect = {}
138 self.result = {} 154 self.result = {}
139 log.debug(" loading expected events"); 155 log.debug(" loading expected events");
@@ -145,6 +161,31 @@ class Test(object):
145 else: 161 else:
146 return True 162 return True
147 163
164 def skip_test(self, myarch):
165 # If architecture not set always run test
166 if self.arch == '':
167 # log.warning("test for arch %s is ok" % myarch)
168 return False
169
170 # Allow multiple values in assignment separated by ','
171 arch_list = self.arch.split(',')
172
173 # Handle negated list such as !s390x,ppc
174 if arch_list[0][0] == '!':
175 arch_list[0] = arch_list[0][1:]
176 log.warning("excluded architecture list %s" % arch_list)
177 for arch_item in arch_list:
178 # log.warning("test for %s arch is %s" % (arch_item, myarch))
179 if arch_item == myarch:
180 return True
181 return False
182
183 for arch_item in arch_list:
184 # log.warning("test for architecture '%s' current '%s'" % (arch_item, myarch))
185 if arch_item == myarch:
186 return False
187 return True
188
148 def load_events(self, path, events): 189 def load_events(self, path, events):
149 parser_event = ConfigParser.SafeConfigParser() 190 parser_event = ConfigParser.SafeConfigParser()
150 parser_event.read(path) 191 parser_event.read(path)
@@ -168,6 +209,11 @@ class Test(object):
168 events[section] = e 209 events[section] = e
169 210
170 def run_cmd(self, tempdir): 211 def run_cmd(self, tempdir):
212 junk1, junk2, junk3, junk4, myarch = (os.uname())
213
214 if self.skip_test(myarch):
215 raise Notest(self, myarch)
216
171 cmd = "PERF_TEST_ATTR=%s %s %s -o %s/perf.data %s" % (tempdir, 217 cmd = "PERF_TEST_ATTR=%s %s %s -o %s/perf.data %s" % (tempdir,
172 self.perf, self.command, tempdir, self.args) 218 self.perf, self.command, tempdir, self.args)
173 ret = os.WEXITSTATUS(os.system(cmd)) 219 ret = os.WEXITSTATUS(os.system(cmd))
@@ -265,6 +311,8 @@ def run_tests(options):
265 Test(f, options).run() 311 Test(f, options).run()
266 except Unsup, obj: 312 except Unsup, obj:
267 log.warning("unsupp %s" % obj.getMsg()) 313 log.warning("unsupp %s" % obj.getMsg())
314 except Notest, obj:
315 log.warning("skipped %s" % obj.getMsg())
268 316
269def setup_log(verbose): 317def setup_log(verbose):
270 global log 318 global log
diff --git a/tools/perf/tests/bp_signal.c b/tools/perf/tests/bp_signal.c
index e7664fe3bd33..39bbb97cd30a 100644
--- a/tools/perf/tests/bp_signal.c
+++ b/tools/perf/tests/bp_signal.c
@@ -62,8 +62,7 @@ static void __test_function(volatile long *ptr)
62} 62}
63#endif 63#endif
64 64
65__attribute__ ((noinline)) 65static noinline int test_function(void)
66static int test_function(void)
67{ 66{
68 __test_function(&the_var); 67 __test_function(&the_var);
69 the_var++; 68 the_var++;
@@ -288,3 +287,17 @@ int test__bp_signal(int subtest __maybe_unused)
288 return count1 == 1 && overflows == 3 && count2 == 3 && overflows_2 == 3 && count3 == 2 ? 287 return count1 == 1 && overflows == 3 && count2 == 3 && overflows_2 == 3 && count3 == 2 ?
289 TEST_OK : TEST_FAIL; 288 TEST_OK : TEST_FAIL;
290} 289}
290
291bool test__bp_signal_is_supported(void)
292{
293/*
294 * The powerpc so far does not have support to even create
295 * instruction breakpoint using the perf event interface.
296 * Once it's there we can release this.
297 */
298#ifdef __powerpc__
299 return false;
300#else
301 return true;
302#endif
303}
diff --git a/tools/perf/tests/bp_signal_overflow.c b/tools/perf/tests/bp_signal_overflow.c
index 89f92fa67cc4..3b1ac6f31b15 100644
--- a/tools/perf/tests/bp_signal_overflow.c
+++ b/tools/perf/tests/bp_signal_overflow.c
@@ -28,8 +28,7 @@
28 28
29static int overflows; 29static int overflows;
30 30
31__attribute__ ((noinline)) 31static noinline int test_function(void)
32static int test_function(void)
33{ 32{
34 return time(NULL); 33 return time(NULL);
35} 34}
diff --git a/tools/perf/tests/bpf-script-test-prologue.c b/tools/perf/tests/bpf-script-test-prologue.c
index 7230e62c70fc..b4ebc75e25ae 100644
--- a/tools/perf/tests/bpf-script-test-prologue.c
+++ b/tools/perf/tests/bpf-script-test-prologue.c
@@ -10,6 +10,15 @@
10 10
11#include <uapi/linux/fs.h> 11#include <uapi/linux/fs.h>
12 12
13/*
14 * If CONFIG_PROFILE_ALL_BRANCHES is selected,
15 * 'if' is redefined after include kernel header.
16 * Recover 'if' for BPF object code.
17 */
18#ifdef if
19# undef if
20#endif
21
13#define FMODE_READ 0x1 22#define FMODE_READ 0x1
14#define FMODE_WRITE 0x2 23#define FMODE_WRITE 0x2
15 24
diff --git a/tools/perf/tests/builtin-test.c b/tools/perf/tests/builtin-test.c
index 9e08d297f1a9..3ccfd58a8c3c 100644
--- a/tools/perf/tests/builtin-test.c
+++ b/tools/perf/tests/builtin-test.c
@@ -97,10 +97,12 @@ static struct test generic_tests[] = {
97 { 97 {
98 .desc = "Breakpoint overflow signal handler", 98 .desc = "Breakpoint overflow signal handler",
99 .func = test__bp_signal, 99 .func = test__bp_signal,
100 .is_supported = test__bp_signal_is_supported,
100 }, 101 },
101 { 102 {
102 .desc = "Breakpoint overflow sampling", 103 .desc = "Breakpoint overflow sampling",
103 .func = test__bp_signal_overflow, 104 .func = test__bp_signal_overflow,
105 .is_supported = test__bp_signal_is_supported,
104 }, 106 },
105 { 107 {
106 .desc = "Number of exit events of a simple workload", 108 .desc = "Number of exit events of a simple workload",
@@ -401,6 +403,11 @@ static int __cmd_test(int argc, const char *argv[], struct intlist *skiplist)
401 if (!perf_test__matches(t, curr, argc, argv)) 403 if (!perf_test__matches(t, curr, argc, argv))
402 continue; 404 continue;
403 405
406 if (t->is_supported && !t->is_supported()) {
407 pr_debug("%2d: %-*s: Disabled\n", i, width, t->desc);
408 continue;
409 }
410
404 pr_info("%2d: %-*s:", i, width, t->desc); 411 pr_info("%2d: %-*s:", i, width, t->desc);
405 412
406 if (intlist__find(skiplist, i)) { 413 if (intlist__find(skiplist, i)) {
diff --git a/tools/perf/tests/code-reading.c b/tools/perf/tests/code-reading.c
index 1f14e7612cbb..94b7c7b02bde 100644
--- a/tools/perf/tests/code-reading.c
+++ b/tools/perf/tests/code-reading.c
@@ -229,6 +229,8 @@ static int read_object_code(u64 addr, size_t len, u8 cpumode,
229 unsigned char buf2[BUFSZ]; 229 unsigned char buf2[BUFSZ];
230 size_t ret_len; 230 size_t ret_len;
231 u64 objdump_addr; 231 u64 objdump_addr;
232 const char *objdump_name;
233 char decomp_name[KMOD_DECOMP_LEN];
232 int ret; 234 int ret;
233 235
234 pr_debug("Reading object code for memory address: %#"PRIx64"\n", addr); 236 pr_debug("Reading object code for memory address: %#"PRIx64"\n", addr);
@@ -289,9 +291,25 @@ static int read_object_code(u64 addr, size_t len, u8 cpumode,
289 state->done[state->done_cnt++] = al.map->start; 291 state->done[state->done_cnt++] = al.map->start;
290 } 292 }
291 293
294 objdump_name = al.map->dso->long_name;
295 if (dso__needs_decompress(al.map->dso)) {
296 if (dso__decompress_kmodule_path(al.map->dso, objdump_name,
297 decomp_name,
298 sizeof(decomp_name)) < 0) {
299 pr_debug("decompression failed\n");
300 return -1;
301 }
302
303 objdump_name = decomp_name;
304 }
305
292 /* Read the object code using objdump */ 306 /* Read the object code using objdump */
293 objdump_addr = map__rip_2objdump(al.map, al.addr); 307 objdump_addr = map__rip_2objdump(al.map, al.addr);
294 ret = read_via_objdump(al.map->dso->long_name, objdump_addr, buf2, len); 308 ret = read_via_objdump(objdump_name, objdump_addr, buf2, len);
309
310 if (dso__needs_decompress(al.map->dso))
311 unlink(objdump_name);
312
295 if (ret > 0) { 313 if (ret > 0) {
296 /* 314 /*
297 * The kernel maps are inaccurate - assume objdump is right in 315 * The kernel maps are inaccurate - assume objdump is right in
diff --git a/tools/perf/tests/dwarf-unwind.c b/tools/perf/tests/dwarf-unwind.c
index dfe5c89e2049..3e56d08f7995 100644
--- a/tools/perf/tests/dwarf-unwind.c
+++ b/tools/perf/tests/dwarf-unwind.c
@@ -76,8 +76,7 @@ static int unwind_entry(struct unwind_entry *entry, void *arg)
76 return strcmp((const char *) symbol, funcs[idx]); 76 return strcmp((const char *) symbol, funcs[idx]);
77} 77}
78 78
79__attribute__ ((noinline)) 79static noinline int unwind_thread(struct thread *thread)
80static int unwind_thread(struct thread *thread)
81{ 80{
82 struct perf_sample sample; 81 struct perf_sample sample;
83 unsigned long cnt = 0; 82 unsigned long cnt = 0;
@@ -108,8 +107,7 @@ static int unwind_thread(struct thread *thread)
108 107
109static int global_unwind_retval = -INT_MAX; 108static int global_unwind_retval = -INT_MAX;
110 109
111__attribute__ ((noinline)) 110static noinline int compare(void *p1, void *p2)
112static int compare(void *p1, void *p2)
113{ 111{
114 /* Any possible value should be 'thread' */ 112 /* Any possible value should be 'thread' */
115 struct thread *thread = *(struct thread **)p1; 113 struct thread *thread = *(struct thread **)p1;
@@ -128,8 +126,7 @@ static int compare(void *p1, void *p2)
128 return p1 - p2; 126 return p1 - p2;
129} 127}
130 128
131__attribute__ ((noinline)) 129static noinline int krava_3(struct thread *thread)
132static int krava_3(struct thread *thread)
133{ 130{
134 struct thread *array[2] = {thread, thread}; 131 struct thread *array[2] = {thread, thread};
135 void *fp = &bsearch; 132 void *fp = &bsearch;
@@ -147,14 +144,12 @@ static int krava_3(struct thread *thread)
147 return global_unwind_retval; 144 return global_unwind_retval;
148} 145}
149 146
150__attribute__ ((noinline)) 147static noinline int krava_2(struct thread *thread)
151static int krava_2(struct thread *thread)
152{ 148{
153 return krava_3(thread); 149 return krava_3(thread);
154} 150}
155 151
156__attribute__ ((noinline)) 152static noinline int krava_1(struct thread *thread)
157static int krava_1(struct thread *thread)
158{ 153{
159 return krava_2(thread); 154 return krava_2(thread);
160} 155}
diff --git a/tools/perf/tests/parse-events.c b/tools/perf/tests/parse-events.c
index 7fad885491c5..812a053d1941 100644
--- a/tools/perf/tests/parse-events.c
+++ b/tools/perf/tests/parse-events.c
@@ -1810,17 +1810,6 @@ static int test_pmu_events(void)
1810 return ret; 1810 return ret;
1811} 1811}
1812 1812
1813static void debug_warn(const char *warn, va_list params)
1814{
1815 char msg[1024];
1816
1817 if (verbose <= 0)
1818 return;
1819
1820 vsnprintf(msg, sizeof(msg), warn, params);
1821 fprintf(stderr, " Warning: %s\n", msg);
1822}
1823
1824int test__parse_events(int subtest __maybe_unused) 1813int test__parse_events(int subtest __maybe_unused)
1825{ 1814{
1826 int ret1, ret2 = 0; 1815 int ret1, ret2 = 0;
@@ -1832,8 +1821,6 @@ do { \
1832 ret2 = ret1; \ 1821 ret2 = ret1; \
1833} while (0) 1822} while (0)
1834 1823
1835 set_warning_routine(debug_warn);
1836
1837 TEST_EVENTS(test__events); 1824 TEST_EVENTS(test__events);
1838 1825
1839 if (test_pmu()) 1826 if (test_pmu())
diff --git a/tools/perf/tests/task-exit.c b/tools/perf/tests/task-exit.c
index 32873ec91a4e..cf00ebad2ef5 100644
--- a/tools/perf/tests/task-exit.c
+++ b/tools/perf/tests/task-exit.c
@@ -83,7 +83,7 @@ int test__task_exit(int subtest __maybe_unused)
83 83
84 evsel = perf_evlist__first(evlist); 84 evsel = perf_evlist__first(evlist);
85 evsel->attr.task = 1; 85 evsel->attr.task = 1;
86 evsel->attr.sample_freq = 0; 86 evsel->attr.sample_freq = 1;
87 evsel->attr.inherit = 0; 87 evsel->attr.inherit = 0;
88 evsel->attr.watermark = 0; 88 evsel->attr.watermark = 0;
89 evsel->attr.wakeup_events = 1; 89 evsel->attr.wakeup_events = 1;
diff --git a/tools/perf/tests/tests.h b/tools/perf/tests/tests.h
index 631859629403..577363809c9b 100644
--- a/tools/perf/tests/tests.h
+++ b/tools/perf/tests/tests.h
@@ -34,6 +34,7 @@ struct test {
34 int (*get_nr)(void); 34 int (*get_nr)(void);
35 const char *(*get_desc)(int subtest); 35 const char *(*get_desc)(int subtest);
36 } subtest; 36 } subtest;
37 bool (*is_supported)(void);
37}; 38};
38 39
39/* Tests */ 40/* Tests */
@@ -99,6 +100,8 @@ const char *test__clang_subtest_get_desc(int subtest);
99int test__clang_subtest_get_nr(void); 100int test__clang_subtest_get_nr(void);
100int test__unit_number__scnprint(int subtest); 101int test__unit_number__scnprint(int subtest);
101 102
103bool test__bp_signal_is_supported(void);
104
102#if defined(__arm__) || defined(__aarch64__) 105#if defined(__arm__) || defined(__aarch64__)
103#ifdef HAVE_DWARF_UNWIND_SUPPORT 106#ifdef HAVE_DWARF_UNWIND_SUPPORT
104struct thread; 107struct thread;
diff --git a/tools/perf/ui/browsers/annotate.c b/tools/perf/ui/browsers/annotate.c
index d990ad08a3c6..27f41f28dcb4 100644
--- a/tools/perf/ui/browsers/annotate.c
+++ b/tools/perf/ui/browsers/annotate.c
@@ -46,12 +46,15 @@ static struct annotate_browser_opt {
46 .jump_arrows = true, 46 .jump_arrows = true,
47}; 47};
48 48
49struct arch;
50
49struct annotate_browser { 51struct annotate_browser {
50 struct ui_browser b; 52 struct ui_browser b;
51 struct rb_root entries; 53 struct rb_root entries;
52 struct rb_node *curr_hot; 54 struct rb_node *curr_hot;
53 struct disasm_line *selection; 55 struct disasm_line *selection;
54 struct disasm_line **offsets; 56 struct disasm_line **offsets;
57 struct arch *arch;
55 int nr_events; 58 int nr_events;
56 u64 start; 59 u64 start;
57 int nr_asm_entries; 60 int nr_asm_entries;
@@ -125,43 +128,57 @@ static void annotate_browser__write(struct ui_browser *browser, void *entry, int
125 int i, pcnt_width = annotate_browser__pcnt_width(ab); 128 int i, pcnt_width = annotate_browser__pcnt_width(ab);
126 double percent_max = 0.0; 129 double percent_max = 0.0;
127 char bf[256]; 130 char bf[256];
131 bool show_title = false;
128 132
129 for (i = 0; i < ab->nr_events; i++) { 133 for (i = 0; i < ab->nr_events; i++) {
130 if (bdl->samples[i].percent > percent_max) 134 if (bdl->samples[i].percent > percent_max)
131 percent_max = bdl->samples[i].percent; 135 percent_max = bdl->samples[i].percent;
132 } 136 }
133 137
138 if ((row == 0) && (dl->offset == -1 || percent_max == 0.0)) {
139 if (ab->have_cycles) {
140 if (dl->ipc == 0.0 && dl->cycles == 0)
141 show_title = true;
142 } else
143 show_title = true;
144 }
145
134 if (dl->offset != -1 && percent_max != 0.0) { 146 if (dl->offset != -1 && percent_max != 0.0) {
135 if (percent_max != 0.0) { 147 for (i = 0; i < ab->nr_events; i++) {
136 for (i = 0; i < ab->nr_events; i++) { 148 ui_browser__set_percent_color(browser,
137 ui_browser__set_percent_color(browser, 149 bdl->samples[i].percent,
138 bdl->samples[i].percent, 150 current_entry);
139 current_entry); 151 if (annotate_browser__opts.show_total_period) {
140 if (annotate_browser__opts.show_total_period) { 152 ui_browser__printf(browser, "%6" PRIu64 " ",
141 ui_browser__printf(browser, "%6" PRIu64 " ", 153 bdl->samples[i].nr);
142 bdl->samples[i].nr); 154 } else {
143 } else { 155 ui_browser__printf(browser, "%6.2f ",
144 ui_browser__printf(browser, "%6.2f ", 156 bdl->samples[i].percent);
145 bdl->samples[i].percent);
146 }
147 } 157 }
148 } else {
149 ui_browser__write_nstring(browser, " ", 7 * ab->nr_events);
150 } 158 }
151 } else { 159 } else {
152 ui_browser__set_percent_color(browser, 0, current_entry); 160 ui_browser__set_percent_color(browser, 0, current_entry);
153 ui_browser__write_nstring(browser, " ", 7 * ab->nr_events); 161
162 if (!show_title)
163 ui_browser__write_nstring(browser, " ", 7 * ab->nr_events);
164 else
165 ui_browser__printf(browser, "%*s", 7, "Percent");
154 } 166 }
155 if (ab->have_cycles) { 167 if (ab->have_cycles) {
156 if (dl->ipc) 168 if (dl->ipc)
157 ui_browser__printf(browser, "%*.2f ", IPC_WIDTH - 1, dl->ipc); 169 ui_browser__printf(browser, "%*.2f ", IPC_WIDTH - 1, dl->ipc);
158 else 170 else if (!show_title)
159 ui_browser__write_nstring(browser, " ", IPC_WIDTH); 171 ui_browser__write_nstring(browser, " ", IPC_WIDTH);
172 else
173 ui_browser__printf(browser, "%*s ", IPC_WIDTH - 1, "IPC");
174
160 if (dl->cycles) 175 if (dl->cycles)
161 ui_browser__printf(browser, "%*" PRIu64 " ", 176 ui_browser__printf(browser, "%*" PRIu64 " ",
162 CYCLES_WIDTH - 1, dl->cycles); 177 CYCLES_WIDTH - 1, dl->cycles);
163 else 178 else if (!show_title)
164 ui_browser__write_nstring(browser, " ", CYCLES_WIDTH); 179 ui_browser__write_nstring(browser, " ", CYCLES_WIDTH);
180 else
181 ui_browser__printf(browser, "%*s ", CYCLES_WIDTH - 1, "Cycle");
165 } 182 }
166 183
167 SLsmg_write_char(' '); 184 SLsmg_write_char(' ');
@@ -1056,7 +1073,8 @@ int symbol__tui_annotate(struct symbol *sym, struct map *map,
1056 (nr_pcnt - 1); 1073 (nr_pcnt - 1);
1057 } 1074 }
1058 1075
1059 err = symbol__disassemble(sym, map, perf_evsel__env_arch(evsel), sizeof_bdl); 1076 err = symbol__disassemble(sym, map, perf_evsel__env_arch(evsel),
1077 sizeof_bdl, &browser.arch);
1060 if (err) { 1078 if (err) {
1061 char msg[BUFSIZ]; 1079 char msg[BUFSIZ];
1062 symbol__strerror_disassemble(sym, map, err, msg, sizeof(msg)); 1080 symbol__strerror_disassemble(sym, map, err, msg, sizeof(msg));
diff --git a/tools/perf/ui/gtk/annotate.c b/tools/perf/ui/gtk/annotate.c
index e99ba86158d2..d903fd493416 100644
--- a/tools/perf/ui/gtk/annotate.c
+++ b/tools/perf/ui/gtk/annotate.c
@@ -168,7 +168,8 @@ static int symbol__gtk_annotate(struct symbol *sym, struct map *map,
168 if (map->dso->annotate_warned) 168 if (map->dso->annotate_warned)
169 return -1; 169 return -1;
170 170
171 err = symbol__disassemble(sym, map, perf_evsel__env_arch(evsel), 0); 171 err = symbol__disassemble(sym, map, perf_evsel__env_arch(evsel),
172 0, NULL);
172 if (err) { 173 if (err) {
173 char msg[BUFSIZ]; 174 char msg[BUFSIZ];
174 symbol__strerror_disassemble(sym, map, err, msg, sizeof(msg)); 175 symbol__strerror_disassemble(sym, map, err, msg, sizeof(msg));
diff --git a/tools/perf/ui/hist.c b/tools/perf/ui/hist.c
index 59addd52d9cd..ddb2c6fbdf91 100644
--- a/tools/perf/ui/hist.c
+++ b/tools/perf/ui/hist.c
@@ -210,6 +210,8 @@ static int __hpp__sort_acc(struct hist_entry *a, struct hist_entry *b,
210 return 0; 210 return 0;
211 211
212 ret = b->callchain->max_depth - a->callchain->max_depth; 212 ret = b->callchain->max_depth - a->callchain->max_depth;
213 if (callchain_param.order == ORDER_CALLER)
214 ret = -ret;
213 } 215 }
214 return ret; 216 return ret;
215} 217}
diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c
index 683f8340460c..be1caabb9290 100644
--- a/tools/perf/util/annotate.c
+++ b/tools/perf/util/annotate.c
@@ -239,10 +239,20 @@ static int jump__parse(struct arch *arch __maybe_unused, struct ins_operands *op
239 const char *s = strchr(ops->raw, '+'); 239 const char *s = strchr(ops->raw, '+');
240 const char *c = strchr(ops->raw, ','); 240 const char *c = strchr(ops->raw, ',');
241 241
242 if (c++ != NULL) 242 /*
243 * skip over possible up to 2 operands to get to address, e.g.:
244 * tbnz w0, #26, ffff0000083cd190 <security_file_permission+0xd0>
245 */
246 if (c++ != NULL) {
243 ops->target.addr = strtoull(c, NULL, 16); 247 ops->target.addr = strtoull(c, NULL, 16);
244 else 248 if (!ops->target.addr) {
249 c = strchr(c, ',');
250 if (c++ != NULL)
251 ops->target.addr = strtoull(c, NULL, 16);
252 }
253 } else {
245 ops->target.addr = strtoull(ops->raw, NULL, 16); 254 ops->target.addr = strtoull(ops->raw, NULL, 16);
255 }
246 256
247 if (s++ != NULL) { 257 if (s++ != NULL) {
248 ops->target.offset = strtoull(s, NULL, 16); 258 ops->target.offset = strtoull(s, NULL, 16);
@@ -257,10 +267,27 @@ static int jump__parse(struct arch *arch __maybe_unused, struct ins_operands *op
257static int jump__scnprintf(struct ins *ins, char *bf, size_t size, 267static int jump__scnprintf(struct ins *ins, char *bf, size_t size,
258 struct ins_operands *ops) 268 struct ins_operands *ops)
259{ 269{
270 const char *c = strchr(ops->raw, ',');
271
260 if (!ops->target.addr || ops->target.offset < 0) 272 if (!ops->target.addr || ops->target.offset < 0)
261 return ins__raw_scnprintf(ins, bf, size, ops); 273 return ins__raw_scnprintf(ins, bf, size, ops);
262 274
263 return scnprintf(bf, size, "%-6.6s %" PRIx64, ins->name, ops->target.offset); 275 if (c != NULL) {
276 const char *c2 = strchr(c + 1, ',');
277
278 /* check for 3-op insn */
279 if (c2 != NULL)
280 c = c2;
281 c++;
282
283 /* mirror arch objdump's space-after-comma style */
284 if (*c == ' ')
285 c++;
286 }
287
288 return scnprintf(bf, size, "%-6.6s %.*s%" PRIx64,
289 ins->name, c ? c - ops->raw : 0, ops->raw,
290 ops->target.offset);
264} 291}
265 292
266static struct ins_ops jump_ops = { 293static struct ins_ops jump_ops = {
@@ -1294,6 +1321,7 @@ static int dso__disassemble_filename(struct dso *dso, char *filename, size_t fil
1294 char linkname[PATH_MAX]; 1321 char linkname[PATH_MAX];
1295 char *build_id_filename; 1322 char *build_id_filename;
1296 char *build_id_path = NULL; 1323 char *build_id_path = NULL;
1324 char *pos;
1297 1325
1298 if (dso->symtab_type == DSO_BINARY_TYPE__KALLSYMS && 1326 if (dso->symtab_type == DSO_BINARY_TYPE__KALLSYMS &&
1299 !dso__is_kcore(dso)) 1327 !dso__is_kcore(dso))
@@ -1313,7 +1341,14 @@ static int dso__disassemble_filename(struct dso *dso, char *filename, size_t fil
1313 if (!build_id_path) 1341 if (!build_id_path)
1314 return -1; 1342 return -1;
1315 1343
1316 dirname(build_id_path); 1344 /*
1345 * old style build-id cache has name of XX/XXXXXXX.. while
1346 * new style has XX/XXXXXXX../{elf,kallsyms,vdso}.
1347 * extract the build-id part of dirname in the new style only.
1348 */
1349 pos = strrchr(build_id_path, '/');
1350 if (pos && strlen(pos) < SBUILD_ID_SIZE - 2)
1351 dirname(build_id_path);
1317 1352
1318 if (dso__is_kcore(dso) || 1353 if (dso__is_kcore(dso) ||
1319 readlink(build_id_path, linkname, sizeof(linkname)) < 0 || 1354 readlink(build_id_path, linkname, sizeof(linkname)) < 0 ||
@@ -1344,7 +1379,9 @@ static const char *annotate__norm_arch(const char *arch_name)
1344 return normalize_arch((char *)arch_name); 1379 return normalize_arch((char *)arch_name);
1345} 1380}
1346 1381
1347int symbol__disassemble(struct symbol *sym, struct map *map, const char *arch_name, size_t privsize) 1382int symbol__disassemble(struct symbol *sym, struct map *map,
1383 const char *arch_name, size_t privsize,
1384 struct arch **parch)
1348{ 1385{
1349 struct dso *dso = map->dso; 1386 struct dso *dso = map->dso;
1350 char command[PATH_MAX * 2]; 1387 char command[PATH_MAX * 2];
@@ -1370,6 +1407,9 @@ int symbol__disassemble(struct symbol *sym, struct map *map, const char *arch_na
1370 if (arch == NULL) 1407 if (arch == NULL)
1371 return -ENOTSUP; 1408 return -ENOTSUP;
1372 1409
1410 if (parch)
1411 *parch = arch;
1412
1373 if (arch->init) { 1413 if (arch->init) {
1374 err = arch->init(arch); 1414 err = arch->init(arch);
1375 if (err) { 1415 if (err) {
@@ -1396,31 +1436,10 @@ int symbol__disassemble(struct symbol *sym, struct map *map, const char *arch_na
1396 sizeof(symfs_filename)); 1436 sizeof(symfs_filename));
1397 } 1437 }
1398 } else if (dso__needs_decompress(dso)) { 1438 } else if (dso__needs_decompress(dso)) {
1399 char tmp[PATH_MAX]; 1439 char tmp[KMOD_DECOMP_LEN];
1400 struct kmod_path m;
1401 int fd;
1402 bool ret;
1403
1404 if (kmod_path__parse_ext(&m, symfs_filename))
1405 goto out;
1406
1407 snprintf(tmp, PATH_MAX, "/tmp/perf-kmod-XXXXXX");
1408
1409 fd = mkstemp(tmp);
1410 if (fd < 0) {
1411 free(m.ext);
1412 goto out;
1413 }
1414
1415 ret = decompress_to_file(m.ext, symfs_filename, fd);
1416
1417 if (ret)
1418 pr_err("Cannot decompress %s %s\n", m.ext, symfs_filename);
1419
1420 free(m.ext);
1421 close(fd);
1422 1440
1423 if (!ret) 1441 if (dso__decompress_kmodule_path(dso, symfs_filename,
1442 tmp, sizeof(tmp)) < 0)
1424 goto out; 1443 goto out;
1425 1444
1426 strcpy(symfs_filename, tmp); 1445 strcpy(symfs_filename, tmp);
@@ -1429,7 +1448,7 @@ int symbol__disassemble(struct symbol *sym, struct map *map, const char *arch_na
1429 snprintf(command, sizeof(command), 1448 snprintf(command, sizeof(command),
1430 "%s %s%s --start-address=0x%016" PRIx64 1449 "%s %s%s --start-address=0x%016" PRIx64
1431 " --stop-address=0x%016" PRIx64 1450 " --stop-address=0x%016" PRIx64
1432 " -l -d %s %s -C %s 2>/dev/null|grep -v %s:|expand", 1451 " -l -d %s %s -C \"%s\" 2>/dev/null|grep -v \"%s:\"|expand",
1433 objdump_path ? objdump_path : "objdump", 1452 objdump_path ? objdump_path : "objdump",
1434 disassembler_style ? "-M " : "", 1453 disassembler_style ? "-M " : "",
1435 disassembler_style ? disassembler_style : "", 1454 disassembler_style ? disassembler_style : "",
@@ -1887,7 +1906,8 @@ int symbol__tty_annotate(struct symbol *sym, struct map *map,
1887 struct rb_root source_line = RB_ROOT; 1906 struct rb_root source_line = RB_ROOT;
1888 u64 len; 1907 u64 len;
1889 1908
1890 if (symbol__disassemble(sym, map, perf_evsel__env_arch(evsel), 0) < 0) 1909 if (symbol__disassemble(sym, map, perf_evsel__env_arch(evsel),
1910 0, NULL) < 0)
1891 return -1; 1911 return -1;
1892 1912
1893 len = symbol__size(sym); 1913 len = symbol__size(sym);
diff --git a/tools/perf/util/annotate.h b/tools/perf/util/annotate.h
index 948aa8e6fd39..21055034aedd 100644
--- a/tools/perf/util/annotate.h
+++ b/tools/perf/util/annotate.h
@@ -158,7 +158,9 @@ int hist_entry__inc_addr_samples(struct hist_entry *he, int evidx, u64 addr);
158int symbol__alloc_hist(struct symbol *sym); 158int symbol__alloc_hist(struct symbol *sym);
159void symbol__annotate_zero_histograms(struct symbol *sym); 159void symbol__annotate_zero_histograms(struct symbol *sym);
160 160
161int symbol__disassemble(struct symbol *sym, struct map *map, const char *arch_name, size_t privsize); 161int symbol__disassemble(struct symbol *sym, struct map *map,
162 const char *arch_name, size_t privsize,
163 struct arch **parch);
162 164
163enum symbol_disassemble_errno { 165enum symbol_disassemble_errno {
164 SYMBOL_ANNOTATE_ERRNO__SUCCESS = 0, 166 SYMBOL_ANNOTATE_ERRNO__SUCCESS = 0,
diff --git a/tools/perf/util/auxtrace.c b/tools/perf/util/auxtrace.c
index 0daf63b9ee3e..5547457566a7 100644
--- a/tools/perf/util/auxtrace.c
+++ b/tools/perf/util/auxtrace.c
@@ -322,6 +322,13 @@ static int auxtrace_queues__add_event_buffer(struct auxtrace_queues *queues,
322 return auxtrace_queues__add_buffer(queues, idx, buffer); 322 return auxtrace_queues__add_buffer(queues, idx, buffer);
323} 323}
324 324
325static bool filter_cpu(struct perf_session *session, int cpu)
326{
327 unsigned long *cpu_bitmap = session->itrace_synth_opts->cpu_bitmap;
328
329 return cpu_bitmap && cpu != -1 && !test_bit(cpu, cpu_bitmap);
330}
331
325int auxtrace_queues__add_event(struct auxtrace_queues *queues, 332int auxtrace_queues__add_event(struct auxtrace_queues *queues,
326 struct perf_session *session, 333 struct perf_session *session,
327 union perf_event *event, off_t data_offset, 334 union perf_event *event, off_t data_offset,
@@ -331,6 +338,9 @@ int auxtrace_queues__add_event(struct auxtrace_queues *queues,
331 unsigned int idx; 338 unsigned int idx;
332 int err; 339 int err;
333 340
341 if (filter_cpu(session, event->auxtrace.cpu))
342 return 0;
343
334 buffer = zalloc(sizeof(struct auxtrace_buffer)); 344 buffer = zalloc(sizeof(struct auxtrace_buffer));
335 if (!buffer) 345 if (!buffer)
336 return -ENOMEM; 346 return -ENOMEM;
@@ -947,6 +957,8 @@ void itrace_synth_opts__set_default(struct itrace_synth_opts *synth_opts)
947 synth_opts->instructions = true; 957 synth_opts->instructions = true;
948 synth_opts->branches = true; 958 synth_opts->branches = true;
949 synth_opts->transactions = true; 959 synth_opts->transactions = true;
960 synth_opts->ptwrites = true;
961 synth_opts->pwr_events = true;
950 synth_opts->errors = true; 962 synth_opts->errors = true;
951 synth_opts->period_type = PERF_ITRACE_DEFAULT_PERIOD_TYPE; 963 synth_opts->period_type = PERF_ITRACE_DEFAULT_PERIOD_TYPE;
952 synth_opts->period = PERF_ITRACE_DEFAULT_PERIOD; 964 synth_opts->period = PERF_ITRACE_DEFAULT_PERIOD;
@@ -1030,6 +1042,12 @@ int itrace_parse_synth_opts(const struct option *opt, const char *str,
1030 case 'x': 1042 case 'x':
1031 synth_opts->transactions = true; 1043 synth_opts->transactions = true;
1032 break; 1044 break;
1045 case 'w':
1046 synth_opts->ptwrites = true;
1047 break;
1048 case 'p':
1049 synth_opts->pwr_events = true;
1050 break;
1033 case 'e': 1051 case 'e':
1034 synth_opts->errors = true; 1052 synth_opts->errors = true;
1035 break; 1053 break;
diff --git a/tools/perf/util/auxtrace.h b/tools/perf/util/auxtrace.h
index 9f0de72d58e2..33b5e6cdf38c 100644
--- a/tools/perf/util/auxtrace.h
+++ b/tools/perf/util/auxtrace.h
@@ -59,6 +59,8 @@ enum itrace_period_type {
59 * @instructions: whether to synthesize 'instructions' events 59 * @instructions: whether to synthesize 'instructions' events
60 * @branches: whether to synthesize 'branches' events 60 * @branches: whether to synthesize 'branches' events
61 * @transactions: whether to synthesize events for transactions 61 * @transactions: whether to synthesize events for transactions
62 * @ptwrites: whether to synthesize events for ptwrites
63 * @pwr_events: whether to synthesize power events
62 * @errors: whether to synthesize decoder error events 64 * @errors: whether to synthesize decoder error events
63 * @dont_decode: whether to skip decoding entirely 65 * @dont_decode: whether to skip decoding entirely
64 * @log: write a decoding log 66 * @log: write a decoding log
@@ -72,6 +74,7 @@ enum itrace_period_type {
72 * @period: 'instructions' events period 74 * @period: 'instructions' events period
73 * @period_type: 'instructions' events period type 75 * @period_type: 'instructions' events period type
74 * @initial_skip: skip N events at the beginning. 76 * @initial_skip: skip N events at the beginning.
77 * @cpu_bitmap: CPUs for which to synthesize events, or NULL for all
75 */ 78 */
76struct itrace_synth_opts { 79struct itrace_synth_opts {
77 bool set; 80 bool set;
@@ -79,6 +82,8 @@ struct itrace_synth_opts {
79 bool instructions; 82 bool instructions;
80 bool branches; 83 bool branches;
81 bool transactions; 84 bool transactions;
85 bool ptwrites;
86 bool pwr_events;
82 bool errors; 87 bool errors;
83 bool dont_decode; 88 bool dont_decode;
84 bool log; 89 bool log;
@@ -92,6 +97,7 @@ struct itrace_synth_opts {
92 unsigned long long period; 97 unsigned long long period;
93 enum itrace_period_type period_type; 98 enum itrace_period_type period_type;
94 unsigned long initial_skip; 99 unsigned long initial_skip;
100 unsigned long *cpu_bitmap;
95}; 101};
96 102
97/** 103/**
diff --git a/tools/perf/util/build-id.c b/tools/perf/util/build-id.c
index 168cc49654e7..e0148b081bdf 100644
--- a/tools/perf/util/build-id.c
+++ b/tools/perf/util/build-id.c
@@ -278,51 +278,6 @@ char *dso__build_id_filename(const struct dso *dso, char *bf, size_t size)
278 return bf; 278 return bf;
279} 279}
280 280
281bool dso__build_id_is_kmod(const struct dso *dso, char *bf, size_t size)
282{
283 char *id_name = NULL, *ch;
284 struct stat sb;
285 char sbuild_id[SBUILD_ID_SIZE];
286
287 if (!dso->has_build_id)
288 goto err;
289
290 build_id__sprintf(dso->build_id, sizeof(dso->build_id), sbuild_id);
291 id_name = build_id_cache__linkname(sbuild_id, NULL, 0);
292 if (!id_name)
293 goto err;
294 if (access(id_name, F_OK))
295 goto err;
296 if (lstat(id_name, &sb) == -1)
297 goto err;
298 if ((size_t)sb.st_size > size - 1)
299 goto err;
300 if (readlink(id_name, bf, size - 1) < 0)
301 goto err;
302
303 bf[sb.st_size] = '\0';
304
305 /*
306 * link should be:
307 * ../../lib/modules/4.4.0-rc4/kernel/net/ipv4/netfilter/nf_nat_ipv4.ko/a09fe3eb3147dafa4e3b31dbd6257e4d696bdc92
308 */
309 ch = strrchr(bf, '/');
310 if (!ch)
311 goto err;
312 if (ch - 3 < bf)
313 goto err;
314
315 free(id_name);
316 return strncmp(".ko", ch - 3, 3) == 0;
317err:
318 pr_err("Invalid build id: %s\n", id_name ? :
319 dso->long_name ? :
320 dso->short_name ? :
321 "[unknown]");
322 free(id_name);
323 return false;
324}
325
326#define dsos__for_each_with_build_id(pos, head) \ 281#define dsos__for_each_with_build_id(pos, head) \
327 list_for_each_entry(pos, head, node) \ 282 list_for_each_entry(pos, head, node) \
328 if (!pos->has_build_id) \ 283 if (!pos->has_build_id) \
diff --git a/tools/perf/util/build-id.h b/tools/perf/util/build-id.h
index 8a89b195c1fc..96690a55c62c 100644
--- a/tools/perf/util/build-id.h
+++ b/tools/perf/util/build-id.h
@@ -17,7 +17,6 @@ char *build_id_cache__kallsyms_path(const char *sbuild_id, char *bf,
17 size_t size); 17 size_t size);
18 18
19char *dso__build_id_filename(const struct dso *dso, char *bf, size_t size); 19char *dso__build_id_filename(const struct dso *dso, char *bf, size_t size);
20bool dso__build_id_is_kmod(const struct dso *dso, char *bf, size_t size);
21 20
22int build_id__mark_dso_hit(struct perf_tool *tool, union perf_event *event, 21int build_id__mark_dso_hit(struct perf_tool *tool, union perf_event *event,
23 struct perf_sample *sample, struct perf_evsel *evsel, 22 struct perf_sample *sample, struct perf_evsel *evsel,
diff --git a/tools/perf/util/cache.h b/tools/perf/util/cache.h
index 0328f297a748..0175765c05b9 100644
--- a/tools/perf/util/cache.h
+++ b/tools/perf/util/cache.h
@@ -5,6 +5,7 @@
5#include <subcmd/pager.h> 5#include <subcmd/pager.h>
6#include "../ui/ui.h" 6#include "../ui/ui.h"
7 7
8#include <linux/compiler.h>
8#include <linux/string.h> 9#include <linux/string.h>
9 10
10#define CMD_EXEC_PATH "--exec-path" 11#define CMD_EXEC_PATH "--exec-path"
@@ -24,6 +25,6 @@ static inline int is_absolute_path(const char *path)
24 return path[0] == '/'; 25 return path[0] == '/';
25} 26}
26 27
27char *mkpath(const char *fmt, ...) __attribute__((format (printf, 1, 2))); 28char *mkpath(const char *fmt, ...) __printf(1, 2);
28 29
29#endif /* __PERF_CACHE_H */ 30#endif /* __PERF_CACHE_H */
diff --git a/tools/perf/util/callchain.c b/tools/perf/util/callchain.c
index 81fc29ac798f..b4204b43ed58 100644
--- a/tools/perf/util/callchain.c
+++ b/tools/perf/util/callchain.c
@@ -621,14 +621,19 @@ enum match_result {
621static enum match_result match_chain_srcline(struct callchain_cursor_node *node, 621static enum match_result match_chain_srcline(struct callchain_cursor_node *node,
622 struct callchain_list *cnode) 622 struct callchain_list *cnode)
623{ 623{
624 char *left = get_srcline(cnode->ms.map->dso, 624 char *left = NULL;
625 char *right = NULL;
626 enum match_result ret = MATCH_EQ;
627 int cmp;
628
629 if (cnode->ms.map)
630 left = get_srcline(cnode->ms.map->dso,
625 map__rip_2objdump(cnode->ms.map, cnode->ip), 631 map__rip_2objdump(cnode->ms.map, cnode->ip),
626 cnode->ms.sym, true, false); 632 cnode->ms.sym, true, false);
627 char *right = get_srcline(node->map->dso, 633 if (node->map)
634 right = get_srcline(node->map->dso,
628 map__rip_2objdump(node->map, node->ip), 635 map__rip_2objdump(node->map, node->ip),
629 node->sym, true, false); 636 node->sym, true, false);
630 enum match_result ret = MATCH_EQ;
631 int cmp;
632 637
633 if (left && right) 638 if (left && right)
634 cmp = strcmp(left, right); 639 cmp = strcmp(left, right);
diff --git a/tools/perf/util/config.c b/tools/perf/util/config.c
index 8d724f0fa5a8..31a7dea248d0 100644
--- a/tools/perf/util/config.c
+++ b/tools/perf/util/config.c
@@ -335,32 +335,42 @@ static int perf_parse_long(const char *value, long *ret)
335 return 0; 335 return 0;
336} 336}
337 337
338static void die_bad_config(const char *name) 338static void bad_config(const char *name)
339{ 339{
340 if (config_file_name) 340 if (config_file_name)
341 die("bad config value for '%s' in %s", name, config_file_name); 341 pr_warning("bad config value for '%s' in %s, ignoring...\n", name, config_file_name);
342 die("bad config value for '%s'", name); 342 else
343 pr_warning("bad config value for '%s', ignoring...\n", name);
343} 344}
344 345
345u64 perf_config_u64(const char *name, const char *value) 346int perf_config_u64(u64 *dest, const char *name, const char *value)
346{ 347{
347 long long ret = 0; 348 long long ret = 0;
348 349
349 if (!perf_parse_llong(value, &ret)) 350 if (!perf_parse_llong(value, &ret)) {
350 die_bad_config(name); 351 bad_config(name);
351 return (u64) ret; 352 return -1;
353 }
354
355 *dest = ret;
356 return 0;
352} 357}
353 358
354int perf_config_int(const char *name, const char *value) 359int perf_config_int(int *dest, const char *name, const char *value)
355{ 360{
356 long ret = 0; 361 long ret = 0;
357 if (!perf_parse_long(value, &ret)) 362 if (!perf_parse_long(value, &ret)) {
358 die_bad_config(name); 363 bad_config(name);
359 return ret; 364 return -1;
365 }
366 *dest = ret;
367 return 0;
360} 368}
361 369
362static int perf_config_bool_or_int(const char *name, const char *value, int *is_bool) 370static int perf_config_bool_or_int(const char *name, const char *value, int *is_bool)
363{ 371{
372 int ret;
373
364 *is_bool = 1; 374 *is_bool = 1;
365 if (!value) 375 if (!value)
366 return 1; 376 return 1;
@@ -371,7 +381,7 @@ static int perf_config_bool_or_int(const char *name, const char *value, int *is_
371 if (!strcasecmp(value, "false") || !strcasecmp(value, "no") || !strcasecmp(value, "off")) 381 if (!strcasecmp(value, "false") || !strcasecmp(value, "no") || !strcasecmp(value, "off"))
372 return 0; 382 return 0;
373 *is_bool = 0; 383 *is_bool = 0;
374 return perf_config_int(name, value); 384 return perf_config_int(&ret, name, value) < 0 ? -1 : ret;
375} 385}
376 386
377int perf_config_bool(const char *name, const char *value) 387int perf_config_bool(const char *name, const char *value)
@@ -657,8 +667,7 @@ static int perf_config_set__init(struct perf_config_set *set)
657 667
658 user_config = strdup(mkpath("%s/.perfconfig", home)); 668 user_config = strdup(mkpath("%s/.perfconfig", home));
659 if (user_config == NULL) { 669 if (user_config == NULL) {
660 warning("Not enough memory to process %s/.perfconfig, " 670 pr_warning("Not enough memory to process %s/.perfconfig, ignoring it.", home);
661 "ignoring it.", home);
662 goto out; 671 goto out;
663 } 672 }
664 673
@@ -671,8 +680,7 @@ static int perf_config_set__init(struct perf_config_set *set)
671 ret = 0; 680 ret = 0;
672 681
673 if (st.st_uid && (st.st_uid != geteuid())) { 682 if (st.st_uid && (st.st_uid != geteuid())) {
674 warning("File %s not owned by current user or root, " 683 pr_warning("File %s not owned by current user or root, ignoring it.", user_config);
675 "ignoring it.", user_config);
676 goto out_free; 684 goto out_free;
677 } 685 }
678 686
@@ -795,7 +803,8 @@ void perf_config_set__delete(struct perf_config_set *set)
795 */ 803 */
796int config_error_nonbool(const char *var) 804int config_error_nonbool(const char *var)
797{ 805{
798 return error("Missing value for '%s'", var); 806 pr_err("Missing value for '%s'", var);
807 return -1;
799} 808}
800 809
801void set_buildid_dir(const char *dir) 810void set_buildid_dir(const char *dir)
diff --git a/tools/perf/util/config.h b/tools/perf/util/config.h
index 1a59a6b43f8b..b6bb11f3f165 100644
--- a/tools/perf/util/config.h
+++ b/tools/perf/util/config.h
@@ -27,8 +27,8 @@ extern const char *config_exclusive_filename;
27typedef int (*config_fn_t)(const char *, const char *, void *); 27typedef int (*config_fn_t)(const char *, const char *, void *);
28int perf_default_config(const char *, const char *, void *); 28int perf_default_config(const char *, const char *, void *);
29int perf_config(config_fn_t fn, void *); 29int perf_config(config_fn_t fn, void *);
30int perf_config_int(const char *, const char *); 30int perf_config_int(int *dest, const char *, const char *);
31u64 perf_config_u64(const char *, const char *); 31int perf_config_u64(u64 *dest, const char *, const char *);
32int perf_config_bool(const char *, const char *); 32int perf_config_bool(const char *, const char *);
33int config_error_nonbool(const char *); 33int config_error_nonbool(const char *);
34const char *perf_etc_perfconfig(void); 34const char *perf_etc_perfconfig(void);
diff --git a/tools/perf/util/data-convert-bt.c b/tools/perf/util/data-convert-bt.c
index 89d50318833d..3149b70799fd 100644
--- a/tools/perf/util/data-convert-bt.c
+++ b/tools/perf/util/data-convert-bt.c
@@ -1444,10 +1444,8 @@ static int convert__config(const char *var, const char *value, void *cb)
1444{ 1444{
1445 struct convert *c = cb; 1445 struct convert *c = cb;
1446 1446
1447 if (!strcmp(var, "convert.queue-size")) { 1447 if (!strcmp(var, "convert.queue-size"))
1448 c->queue_size = perf_config_u64(var, value); 1448 return perf_config_u64(&c->queue_size, var, value);
1449 return 0;
1450 }
1451 1449
1452 return 0; 1450 return 0;
1453} 1451}
diff --git a/tools/perf/util/debug.h b/tools/perf/util/debug.h
index 8a23ea1a71c7..c818bdb1c1ab 100644
--- a/tools/perf/util/debug.h
+++ b/tools/perf/util/debug.h
@@ -4,6 +4,7 @@
4 4
5#include <stdbool.h> 5#include <stdbool.h>
6#include <string.h> 6#include <string.h>
7#include <linux/compiler.h>
7#include "event.h" 8#include "event.h"
8#include "../ui/helpline.h" 9#include "../ui/helpline.h"
9#include "../ui/progress.h" 10#include "../ui/progress.h"
@@ -40,16 +41,16 @@ extern int debug_data_convert;
40 41
41#define STRERR_BUFSIZE 128 /* For the buffer size of str_error_r */ 42#define STRERR_BUFSIZE 128 /* For the buffer size of str_error_r */
42 43
43int dump_printf(const char *fmt, ...) __attribute__((format(printf, 1, 2))); 44int dump_printf(const char *fmt, ...) __printf(1, 2);
44void trace_event(union perf_event *event); 45void trace_event(union perf_event *event);
45 46
46int ui__error(const char *format, ...) __attribute__((format(printf, 1, 2))); 47int ui__error(const char *format, ...) __printf(1, 2);
47int ui__warning(const char *format, ...) __attribute__((format(printf, 1, 2))); 48int ui__warning(const char *format, ...) __printf(1, 2);
48 49
49void pr_stat(const char *fmt, ...); 50void pr_stat(const char *fmt, ...);
50 51
51int eprintf(int level, int var, const char *fmt, ...) __attribute__((format(printf, 3, 4))); 52int eprintf(int level, int var, const char *fmt, ...) __printf(3, 4);
52int eprintf_time(int level, int var, u64 t, const char *fmt, ...) __attribute__((format(printf, 4, 5))); 53int eprintf_time(int level, int var, u64 t, const char *fmt, ...) __printf(4, 5);
53int veprintf(int level, int var, const char *fmt, va_list args); 54int veprintf(int level, int var, const char *fmt, va_list args);
54 55
55int perf_debug_option(const char *str); 56int perf_debug_option(const char *str);
diff --git a/tools/perf/util/dso.c b/tools/perf/util/dso.c
index a96a99d2369f..4e7ab611377a 100644
--- a/tools/perf/util/dso.c
+++ b/tools/perf/util/dso.c
@@ -248,6 +248,64 @@ bool dso__needs_decompress(struct dso *dso)
248 dso->symtab_type == DSO_BINARY_TYPE__GUEST_KMODULE_COMP; 248 dso->symtab_type == DSO_BINARY_TYPE__GUEST_KMODULE_COMP;
249} 249}
250 250
251static int decompress_kmodule(struct dso *dso, const char *name, char *tmpbuf)
252{
253 int fd = -1;
254 struct kmod_path m;
255
256 if (!dso__needs_decompress(dso))
257 return -1;
258
259 if (kmod_path__parse_ext(&m, dso->long_name))
260 return -1;
261
262 if (!m.comp)
263 goto out;
264
265 fd = mkstemp(tmpbuf);
266 if (fd < 0) {
267 dso->load_errno = errno;
268 goto out;
269 }
270
271 if (!decompress_to_file(m.ext, name, fd)) {
272 dso->load_errno = DSO_LOAD_ERRNO__DECOMPRESSION_FAILURE;
273 close(fd);
274 fd = -1;
275 }
276
277out:
278 free(m.ext);
279 return fd;
280}
281
282int dso__decompress_kmodule_fd(struct dso *dso, const char *name)
283{
284 char tmpbuf[] = KMOD_DECOMP_NAME;
285 int fd;
286
287 fd = decompress_kmodule(dso, name, tmpbuf);
288 unlink(tmpbuf);
289 return fd;
290}
291
292int dso__decompress_kmodule_path(struct dso *dso, const char *name,
293 char *pathname, size_t len)
294{
295 char tmpbuf[] = KMOD_DECOMP_NAME;
296 int fd;
297
298 fd = decompress_kmodule(dso, name, tmpbuf);
299 if (fd < 0) {
300 unlink(tmpbuf);
301 return -1;
302 }
303
304 strncpy(pathname, tmpbuf, len);
305 close(fd);
306 return 0;
307}
308
251/* 309/*
252 * Parses kernel module specified in @path and updates 310 * Parses kernel module specified in @path and updates
253 * @m argument like: 311 * @m argument like:
@@ -335,6 +393,21 @@ int __kmod_path__parse(struct kmod_path *m, const char *path,
335 return 0; 393 return 0;
336} 394}
337 395
396void dso__set_module_info(struct dso *dso, struct kmod_path *m,
397 struct machine *machine)
398{
399 if (machine__is_host(machine))
400 dso->symtab_type = DSO_BINARY_TYPE__SYSTEM_PATH_KMODULE;
401 else
402 dso->symtab_type = DSO_BINARY_TYPE__GUEST_KMODULE;
403
404 /* _KMODULE_COMP should be next to _KMODULE */
405 if (m->kmod && m->comp)
406 dso->symtab_type++;
407
408 dso__set_short_name(dso, strdup(m->name), true);
409}
410
338/* 411/*
339 * Global list of open DSOs and the counter. 412 * Global list of open DSOs and the counter.
340 */ 413 */
@@ -381,7 +454,7 @@ static int do_open(char *name)
381 454
382static int __open_dso(struct dso *dso, struct machine *machine) 455static int __open_dso(struct dso *dso, struct machine *machine)
383{ 456{
384 int fd; 457 int fd = -EINVAL;
385 char *root_dir = (char *)""; 458 char *root_dir = (char *)"";
386 char *name = malloc(PATH_MAX); 459 char *name = malloc(PATH_MAX);
387 460
@@ -392,15 +465,30 @@ static int __open_dso(struct dso *dso, struct machine *machine)
392 root_dir = machine->root_dir; 465 root_dir = machine->root_dir;
393 466
394 if (dso__read_binary_type_filename(dso, dso->binary_type, 467 if (dso__read_binary_type_filename(dso, dso->binary_type,
395 root_dir, name, PATH_MAX)) { 468 root_dir, name, PATH_MAX))
396 free(name); 469 goto out;
397 return -EINVAL;
398 }
399 470
400 if (!is_regular_file(name)) 471 if (!is_regular_file(name))
401 return -EINVAL; 472 goto out;
473
474 if (dso__needs_decompress(dso)) {
475 char newpath[KMOD_DECOMP_LEN];
476 size_t len = sizeof(newpath);
477
478 if (dso__decompress_kmodule_path(dso, name, newpath, len) < 0) {
479 fd = -dso->load_errno;
480 goto out;
481 }
482
483 strcpy(name, newpath);
484 }
402 485
403 fd = do_open(name); 486 fd = do_open(name);
487
488 if (dso__needs_decompress(dso))
489 unlink(name);
490
491out:
404 free(name); 492 free(name);
405 return fd; 493 return fd;
406} 494}
diff --git a/tools/perf/util/dso.h b/tools/perf/util/dso.h
index 12350b171727..bd061ba7b47c 100644
--- a/tools/perf/util/dso.h
+++ b/tools/perf/util/dso.h
@@ -244,6 +244,12 @@ bool is_supported_compression(const char *ext);
244bool is_kernel_module(const char *pathname, int cpumode); 244bool is_kernel_module(const char *pathname, int cpumode);
245bool decompress_to_file(const char *ext, const char *filename, int output_fd); 245bool decompress_to_file(const char *ext, const char *filename, int output_fd);
246bool dso__needs_decompress(struct dso *dso); 246bool dso__needs_decompress(struct dso *dso);
247int dso__decompress_kmodule_fd(struct dso *dso, const char *name);
248int dso__decompress_kmodule_path(struct dso *dso, const char *name,
249 char *pathname, size_t len);
250
251#define KMOD_DECOMP_NAME "/tmp/perf-kmod-XXXXXX"
252#define KMOD_DECOMP_LEN sizeof(KMOD_DECOMP_NAME)
247 253
248struct kmod_path { 254struct kmod_path {
249 char *name; 255 char *name;
@@ -259,6 +265,9 @@ int __kmod_path__parse(struct kmod_path *m, const char *path,
259#define kmod_path__parse_name(__m, __p) __kmod_path__parse(__m, __p, true , false) 265#define kmod_path__parse_name(__m, __p) __kmod_path__parse(__m, __p, true , false)
260#define kmod_path__parse_ext(__m, __p) __kmod_path__parse(__m, __p, false, true) 266#define kmod_path__parse_ext(__m, __p) __kmod_path__parse(__m, __p, false, true)
261 267
268void dso__set_module_info(struct dso *dso, struct kmod_path *m,
269 struct machine *machine);
270
262/* 271/*
263 * The dso__data_* external interface provides following functions: 272 * The dso__data_* external interface provides following functions:
264 * dso__data_get_fd 273 * dso__data_get_fd
diff --git a/tools/perf/util/event.h b/tools/perf/util/event.h
index 7c3fa1c8cbcd..9967c87af7a6 100644
--- a/tools/perf/util/event.h
+++ b/tools/perf/util/event.h
@@ -252,6 +252,127 @@ enum auxtrace_error_type {
252 PERF_AUXTRACE_ERROR_MAX 252 PERF_AUXTRACE_ERROR_MAX
253}; 253};
254 254
255/* Attribute type for custom synthesized events */
256#define PERF_TYPE_SYNTH (INT_MAX + 1U)
257
258/* Attribute config for custom synthesized events */
259enum perf_synth_id {
260 PERF_SYNTH_INTEL_PTWRITE,
261 PERF_SYNTH_INTEL_MWAIT,
262 PERF_SYNTH_INTEL_PWRE,
263 PERF_SYNTH_INTEL_EXSTOP,
264 PERF_SYNTH_INTEL_PWRX,
265 PERF_SYNTH_INTEL_CBR,
266};
267
268/*
269 * Raw data formats for synthesized events. Note that 4 bytes of padding are
270 * present to match the 'size' member of PERF_SAMPLE_RAW data which is always
271 * 8-byte aligned. That means we must dereference raw_data with an offset of 4.
272 * Refer perf_sample__synth_ptr() and perf_synth__raw_data(). It also means the
273 * structure sizes are 4 bytes bigger than the raw_size, refer
274 * perf_synth__raw_size().
275 */
276
277struct perf_synth_intel_ptwrite {
278 u32 padding;
279 union {
280 struct {
281 u32 ip : 1,
282 reserved : 31;
283 };
284 u32 flags;
285 };
286 u64 payload;
287};
288
289struct perf_synth_intel_mwait {
290 u32 padding;
291 u32 reserved;
292 union {
293 struct {
294 u64 hints : 8,
295 reserved1 : 24,
296 extensions : 2,
297 reserved2 : 30;
298 };
299 u64 payload;
300 };
301};
302
303struct perf_synth_intel_pwre {
304 u32 padding;
305 u32 reserved;
306 union {
307 struct {
308 u64 reserved1 : 7,
309 hw : 1,
310 subcstate : 4,
311 cstate : 4,
312 reserved2 : 48;
313 };
314 u64 payload;
315 };
316};
317
318struct perf_synth_intel_exstop {
319 u32 padding;
320 union {
321 struct {
322 u32 ip : 1,
323 reserved : 31;
324 };
325 u32 flags;
326 };
327};
328
329struct perf_synth_intel_pwrx {
330 u32 padding;
331 u32 reserved;
332 union {
333 struct {
334 u64 deepest_cstate : 4,
335 last_cstate : 4,
336 wake_reason : 4,
337 reserved1 : 52;
338 };
339 u64 payload;
340 };
341};
342
343struct perf_synth_intel_cbr {
344 u32 padding;
345 union {
346 struct {
347 u32 cbr : 8,
348 reserved1 : 8,
349 max_nonturbo : 8,
350 reserved2 : 8;
351 };
352 u32 flags;
353 };
354 u32 freq;
355 u32 reserved3;
356};
357
358/*
359 * raw_data is always 4 bytes from an 8-byte boundary, so subtract 4 to get
360 * 8-byte alignment.
361 */
362static inline void *perf_sample__synth_ptr(struct perf_sample *sample)
363{
364 return sample->raw_data - 4;
365}
366
367static inline void *perf_synth__raw_data(void *p)
368{
369 return p + 4;
370}
371
372#define perf_synth__raw_size(d) (sizeof(d) - 4)
373
374#define perf_sample__bad_synth_size(s, d) ((s)->raw_size < sizeof(d) - 4)
375
255/* 376/*
256 * The kernel collects the number of events it couldn't send in a stretch and 377 * The kernel collects the number of events it couldn't send in a stretch and
257 * when possible sends this number in a PERF_RECORD_LOST event. The number of 378 * when possible sends this number in a PERF_RECORD_LOST event. The number of
diff --git a/tools/perf/util/evlist.h b/tools/perf/util/evlist.h
index 94cea4398a13..8d601fbdd8d6 100644
--- a/tools/perf/util/evlist.h
+++ b/tools/perf/util/evlist.h
@@ -1,6 +1,7 @@
1#ifndef __PERF_EVLIST_H 1#ifndef __PERF_EVLIST_H
2#define __PERF_EVLIST_H 1 2#define __PERF_EVLIST_H 1
3 3
4#include <linux/compiler.h>
4#include <linux/kernel.h> 5#include <linux/kernel.h>
5#include <linux/refcount.h> 6#include <linux/refcount.h>
6#include <linux/list.h> 7#include <linux/list.h>
@@ -34,7 +35,7 @@ struct perf_mmap {
34 refcount_t refcnt; 35 refcount_t refcnt;
35 u64 prev; 36 u64 prev;
36 struct auxtrace_mmap auxtrace_mmap; 37 struct auxtrace_mmap auxtrace_mmap;
37 char event_copy[PERF_SAMPLE_MAX_SIZE] __attribute__((aligned(8))); 38 char event_copy[PERF_SAMPLE_MAX_SIZE] __aligned(8);
38}; 39};
39 40
40static inline size_t 41static inline size_t
diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c
index e4f7902d5afa..6f4882f8d61f 100644
--- a/tools/perf/util/evsel.c
+++ b/tools/perf/util/evsel.c
@@ -11,13 +11,17 @@
11#include <errno.h> 11#include <errno.h>
12#include <inttypes.h> 12#include <inttypes.h>
13#include <linux/bitops.h> 13#include <linux/bitops.h>
14#include <api/fs/fs.h>
14#include <api/fs/tracing_path.h> 15#include <api/fs/tracing_path.h>
15#include <traceevent/event-parse.h> 16#include <traceevent/event-parse.h>
16#include <linux/hw_breakpoint.h> 17#include <linux/hw_breakpoint.h>
17#include <linux/perf_event.h> 18#include <linux/perf_event.h>
19#include <linux/compiler.h>
18#include <linux/err.h> 20#include <linux/err.h>
19#include <sys/ioctl.h> 21#include <sys/ioctl.h>
20#include <sys/resource.h> 22#include <sys/resource.h>
23#include <sys/types.h>
24#include <dirent.h>
21#include "asm/bug.h" 25#include "asm/bug.h"
22#include "callchain.h" 26#include "callchain.h"
23#include "cgroup.h" 27#include "cgroup.h"
@@ -273,8 +277,20 @@ struct perf_evsel *perf_evsel__new_cycles(void)
273 struct perf_evsel *evsel; 277 struct perf_evsel *evsel;
274 278
275 event_attr_init(&attr); 279 event_attr_init(&attr);
280 /*
281 * Unnamed union member, not supported as struct member named
282 * initializer in older compilers such as gcc 4.4.7
283 *
284 * Just for probing the precise_ip:
285 */
286 attr.sample_period = 1;
276 287
277 perf_event_attr__set_max_precise_ip(&attr); 288 perf_event_attr__set_max_precise_ip(&attr);
289 /*
290 * Now let the usual logic to set up the perf_event_attr defaults
291 * to kick in when we return and before perf_evsel__open() is called.
292 */
293 attr.sample_period = 0;
278 294
279 evsel = perf_evsel__new(&attr); 295 evsel = perf_evsel__new(&attr);
280 if (evsel == NULL) 296 if (evsel == NULL)
@@ -1429,7 +1445,7 @@ int perf_event_attr__fprintf(FILE *fp, struct perf_event_attr *attr,
1429} 1445}
1430 1446
1431static int __open_attr__fprintf(FILE *fp, const char *name, const char *val, 1447static int __open_attr__fprintf(FILE *fp, const char *name, const char *val,
1432 void *priv __attribute__((unused))) 1448 void *priv __maybe_unused)
1433{ 1449{
1434 return fprintf(fp, " %-32s %s\n", name, val); 1450 return fprintf(fp, " %-32s %s\n", name, val);
1435} 1451}
@@ -2459,6 +2475,42 @@ bool perf_evsel__fallback(struct perf_evsel *evsel, int err,
2459 return false; 2475 return false;
2460} 2476}
2461 2477
2478static bool find_process(const char *name)
2479{
2480 size_t len = strlen(name);
2481 DIR *dir;
2482 struct dirent *d;
2483 int ret = -1;
2484
2485 dir = opendir(procfs__mountpoint());
2486 if (!dir)
2487 return false;
2488
2489 /* Walk through the directory. */
2490 while (ret && (d = readdir(dir)) != NULL) {
2491 char path[PATH_MAX];
2492 char *data;
2493 size_t size;
2494
2495 if ((d->d_type != DT_DIR) ||
2496 !strcmp(".", d->d_name) ||
2497 !strcmp("..", d->d_name))
2498 continue;
2499
2500 scnprintf(path, sizeof(path), "%s/%s/comm",
2501 procfs__mountpoint(), d->d_name);
2502
2503 if (filename__read_str(path, &data, &size))
2504 continue;
2505
2506 ret = strncmp(name, data, len);
2507 free(data);
2508 }
2509
2510 closedir(dir);
2511 return ret ? false : true;
2512}
2513
2462int perf_evsel__open_strerror(struct perf_evsel *evsel, struct target *target, 2514int perf_evsel__open_strerror(struct perf_evsel *evsel, struct target *target,
2463 int err, char *msg, size_t size) 2515 int err, char *msg, size_t size)
2464{ 2516{
diff --git a/tools/perf/util/evsel_fprintf.c b/tools/perf/util/evsel_fprintf.c
index e415aee6a245..583f3a602506 100644
--- a/tools/perf/util/evsel_fprintf.c
+++ b/tools/perf/util/evsel_fprintf.c
@@ -7,6 +7,7 @@
7#include "map.h" 7#include "map.h"
8#include "strlist.h" 8#include "strlist.h"
9#include "symbol.h" 9#include "symbol.h"
10#include "srcline.h"
10 11
11static int comma_fprintf(FILE *fp, bool *first, const char *fmt, ...) 12static int comma_fprintf(FILE *fp, bool *first, const char *fmt, ...)
12{ 13{
@@ -168,6 +169,38 @@ int sample__fprintf_callchain(struct perf_sample *sample, int left_alignment,
168 if (!print_oneline) 169 if (!print_oneline)
169 printed += fprintf(fp, "\n"); 170 printed += fprintf(fp, "\n");
170 171
172 if (symbol_conf.inline_name && node->map) {
173 struct inline_node *inode;
174
175 addr = map__rip_2objdump(node->map, node->ip),
176 inode = dso__parse_addr_inlines(node->map->dso, addr);
177
178 if (inode) {
179 struct inline_list *ilist;
180
181 list_for_each_entry(ilist, &inode->val, list) {
182 if (print_arrow)
183 printed += fprintf(fp, " <-");
184
185 /* IP is same, just skip it */
186 if (print_ip)
187 printed += fprintf(fp, "%c%16s",
188 s, "");
189 if (print_sym)
190 printed += fprintf(fp, " %s",
191 ilist->funcname);
192 if (print_srcline)
193 printed += fprintf(fp, "\n %s:%d",
194 ilist->filename,
195 ilist->line_nr);
196 if (!print_oneline)
197 printed += fprintf(fp, "\n");
198 }
199
200 inline_node__delete(inode);
201 }
202 }
203
171 if (symbol_conf.bt_stop_list && 204 if (symbol_conf.bt_stop_list &&
172 node->sym && 205 node->sym &&
173 strlist__has_entry(symbol_conf.bt_stop_list, 206 strlist__has_entry(symbol_conf.bt_stop_list,
diff --git a/tools/perf/util/genelf_debug.c b/tools/perf/util/genelf_debug.c
index 5980f7d256b1..40789d8603d0 100644
--- a/tools/perf/util/genelf_debug.c
+++ b/tools/perf/util/genelf_debug.c
@@ -11,6 +11,7 @@
11 * @remark Copyright 2007 OProfile authors 11 * @remark Copyright 2007 OProfile authors
12 * @author Philippe Elie 12 * @author Philippe Elie
13 */ 13 */
14#include <linux/compiler.h>
14#include <sys/types.h> 15#include <sys/types.h>
15#include <stdio.h> 16#include <stdio.h>
16#include <getopt.h> 17#include <getopt.h>
@@ -125,7 +126,7 @@ struct debug_line_header {
125 * and filesize, last entry is followed by en empty string. 126 * and filesize, last entry is followed by en empty string.
126 */ 127 */
127 /* follow the first program statement */ 128 /* follow the first program statement */
128} __attribute__((packed)); 129} __packed;
129 130
130/* DWARF 2 spec talk only about one possible compilation unit header while 131/* DWARF 2 spec talk only about one possible compilation unit header while
131 * binutils can handle two flavours of dwarf 2, 32 and 64 bits, this is not 132 * binutils can handle two flavours of dwarf 2, 32 and 64 bits, this is not
@@ -138,7 +139,7 @@ struct compilation_unit_header {
138 uhalf version; 139 uhalf version;
139 uword debug_abbrev_offset; 140 uword debug_abbrev_offset;
140 ubyte pointer_size; 141 ubyte pointer_size;
141} __attribute__((packed)); 142} __packed;
142 143
143#define DW_LNS_num_opcode (DW_LNS_set_isa + 1) 144#define DW_LNS_num_opcode (DW_LNS_set_isa + 1)
144 145
diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c
index 314a07151fb7..76ed7d03e500 100644
--- a/tools/perf/util/header.c
+++ b/tools/perf/util/header.c
@@ -8,6 +8,7 @@
8#include <unistd.h> 8#include <unistd.h>
9#include <stdio.h> 9#include <stdio.h>
10#include <stdlib.h> 10#include <stdlib.h>
11#include <linux/compiler.h>
11#include <linux/list.h> 12#include <linux/list.h>
12#include <linux/kernel.h> 13#include <linux/kernel.h>
13#include <linux/bitops.h> 14#include <linux/bitops.h>
@@ -841,7 +842,7 @@ static int write_group_desc(int fd, struct perf_header *h __maybe_unused,
841 842
842/* 843/*
843 * default get_cpuid(): nothing gets recorded 844 * default get_cpuid(): nothing gets recorded
844 * actual implementation must be in arch/$(ARCH)/util/header.c 845 * actual implementation must be in arch/$(SRCARCH)/util/header.c
845 */ 846 */
846int __weak get_cpuid(char *buffer __maybe_unused, size_t sz __maybe_unused) 847int __weak get_cpuid(char *buffer __maybe_unused, size_t sz __maybe_unused)
847{ 848{
@@ -1274,7 +1275,7 @@ error:
1274} 1275}
1275 1276
1276static int __desc_attr__fprintf(FILE *fp, const char *name, const char *val, 1277static int __desc_attr__fprintf(FILE *fp, const char *name, const char *val,
1277 void *priv __attribute__((unused))) 1278 void *priv __maybe_unused)
1278{ 1279{
1279 return fprintf(fp, ", %s = %s", name, val); 1280 return fprintf(fp, ", %s = %s", name, val);
1280} 1281}
@@ -1469,8 +1470,16 @@ static int __event_process_build_id(struct build_id_event *bev,
1469 1470
1470 dso__set_build_id(dso, &bev->build_id); 1471 dso__set_build_id(dso, &bev->build_id);
1471 1472
1472 if (!is_kernel_module(filename, cpumode)) 1473 if (dso_type != DSO_TYPE_USER) {
1473 dso->kernel = dso_type; 1474 struct kmod_path m = { .name = NULL, };
1475
1476 if (!kmod_path__parse_name(&m, filename) && m.kmod)
1477 dso__set_module_info(dso, &m, machine);
1478 else
1479 dso->kernel = dso_type;
1480
1481 free(m.name);
1482 }
1474 1483
1475 build_id__sprintf(dso->build_id, sizeof(dso->build_id), 1484 build_id__sprintf(dso->build_id, sizeof(dso->build_id),
1476 sbuild_id); 1485 sbuild_id);
diff --git a/tools/perf/util/help-unknown-cmd.c b/tools/perf/util/help-unknown-cmd.c
index 1c88ad6425b8..15b95300d7f3 100644
--- a/tools/perf/util/help-unknown-cmd.c
+++ b/tools/perf/util/help-unknown-cmd.c
@@ -12,7 +12,7 @@ static int perf_unknown_cmd_config(const char *var, const char *value,
12 void *cb __maybe_unused) 12 void *cb __maybe_unused)
13{ 13{
14 if (!strcmp(var, "help.autocorrect")) 14 if (!strcmp(var, "help.autocorrect"))
15 autocorrect = perf_config_int(var,value); 15 return perf_config_int(&autocorrect, var,value);
16 16
17 return 0; 17 return 0;
18} 18}
diff --git a/tools/perf/util/intel-bts.c b/tools/perf/util/intel-bts.c
index b2834ac7b1f5..218ee2bac9a5 100644
--- a/tools/perf/util/intel-bts.c
+++ b/tools/perf/util/intel-bts.c
@@ -866,8 +866,6 @@ static void intel_bts_print_info(u64 *arr, int start, int finish)
866 fprintf(stdout, intel_bts_info_fmts[i], arr[i]); 866 fprintf(stdout, intel_bts_info_fmts[i], arr[i]);
867} 867}
868 868
869u64 intel_bts_auxtrace_info_priv[INTEL_BTS_AUXTRACE_PRIV_SIZE];
870
871int intel_bts_process_auxtrace_info(union perf_event *event, 869int intel_bts_process_auxtrace_info(union perf_event *event,
872 struct perf_session *session) 870 struct perf_session *session)
873{ 871{
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 7cf7f7aca4d2..aa1593ce551d 100644
--- a/tools/perf/util/intel-pt-decoder/intel-pt-decoder.c
+++ b/tools/perf/util/intel-pt-decoder/intel-pt-decoder.c
@@ -64,6 +64,25 @@ enum intel_pt_pkt_state {
64 INTEL_PT_STATE_FUP_NO_TIP, 64 INTEL_PT_STATE_FUP_NO_TIP,
65}; 65};
66 66
67static inline bool intel_pt_sample_time(enum intel_pt_pkt_state pkt_state)
68{
69 switch (pkt_state) {
70 case INTEL_PT_STATE_NO_PSB:
71 case INTEL_PT_STATE_NO_IP:
72 case INTEL_PT_STATE_ERR_RESYNC:
73 case INTEL_PT_STATE_IN_SYNC:
74 case INTEL_PT_STATE_TNT:
75 return true;
76 case INTEL_PT_STATE_TIP:
77 case INTEL_PT_STATE_TIP_PGD:
78 case INTEL_PT_STATE_FUP:
79 case INTEL_PT_STATE_FUP_NO_TIP:
80 return false;
81 default:
82 return true;
83 };
84}
85
67#ifdef INTEL_PT_STRICT 86#ifdef INTEL_PT_STRICT
68#define INTEL_PT_STATE_ERR1 INTEL_PT_STATE_NO_PSB 87#define INTEL_PT_STATE_ERR1 INTEL_PT_STATE_NO_PSB
69#define INTEL_PT_STATE_ERR2 INTEL_PT_STATE_NO_PSB 88#define INTEL_PT_STATE_ERR2 INTEL_PT_STATE_NO_PSB
@@ -87,11 +106,13 @@ struct intel_pt_decoder {
87 const unsigned char *buf; 106 const unsigned char *buf;
88 size_t len; 107 size_t len;
89 bool return_compression; 108 bool return_compression;
109 bool branch_enable;
90 bool mtc_insn; 110 bool mtc_insn;
91 bool pge; 111 bool pge;
92 bool have_tma; 112 bool have_tma;
93 bool have_cyc; 113 bool have_cyc;
94 bool fixup_last_mtc; 114 bool fixup_last_mtc;
115 bool have_last_ip;
95 uint64_t pos; 116 uint64_t pos;
96 uint64_t last_ip; 117 uint64_t last_ip;
97 uint64_t ip; 118 uint64_t ip;
@@ -99,6 +120,7 @@ struct intel_pt_decoder {
99 uint64_t timestamp; 120 uint64_t timestamp;
100 uint64_t tsc_timestamp; 121 uint64_t tsc_timestamp;
101 uint64_t ref_timestamp; 122 uint64_t ref_timestamp;
123 uint64_t sample_timestamp;
102 uint64_t ret_addr; 124 uint64_t ret_addr;
103 uint64_t ctc_timestamp; 125 uint64_t ctc_timestamp;
104 uint64_t ctc_delta; 126 uint64_t ctc_delta;
@@ -119,6 +141,7 @@ struct intel_pt_decoder {
119 int pkt_len; 141 int pkt_len;
120 int last_packet_type; 142 int last_packet_type;
121 unsigned int cbr; 143 unsigned int cbr;
144 unsigned int cbr_seen;
122 unsigned int max_non_turbo_ratio; 145 unsigned int max_non_turbo_ratio;
123 double max_non_turbo_ratio_fp; 146 double max_non_turbo_ratio_fp;
124 double cbr_cyc_to_tsc; 147 double cbr_cyc_to_tsc;
@@ -136,9 +159,18 @@ struct intel_pt_decoder {
136 bool continuous_period; 159 bool continuous_period;
137 bool overflow; 160 bool overflow;
138 bool set_fup_tx_flags; 161 bool set_fup_tx_flags;
162 bool set_fup_ptw;
163 bool set_fup_mwait;
164 bool set_fup_pwre;
165 bool set_fup_exstop;
139 unsigned int fup_tx_flags; 166 unsigned int fup_tx_flags;
140 unsigned int tx_flags; 167 unsigned int tx_flags;
168 uint64_t fup_ptw_payload;
169 uint64_t fup_mwait_payload;
170 uint64_t fup_pwre_payload;
171 uint64_t cbr_payload;
141 uint64_t timestamp_insn_cnt; 172 uint64_t timestamp_insn_cnt;
173 uint64_t sample_insn_cnt;
142 uint64_t stuck_ip; 174 uint64_t stuck_ip;
143 int no_progress; 175 int no_progress;
144 int stuck_ip_prd; 176 int stuck_ip_prd;
@@ -192,6 +224,7 @@ struct intel_pt_decoder *intel_pt_decoder_new(struct intel_pt_params *params)
192 decoder->pgd_ip = params->pgd_ip; 224 decoder->pgd_ip = params->pgd_ip;
193 decoder->data = params->data; 225 decoder->data = params->data;
194 decoder->return_compression = params->return_compression; 226 decoder->return_compression = params->return_compression;
227 decoder->branch_enable = params->branch_enable;
195 228
196 decoder->period = params->period; 229 decoder->period = params->period;
197 decoder->period_type = params->period_type; 230 decoder->period_type = params->period_type;
@@ -398,6 +431,7 @@ static uint64_t intel_pt_calc_ip(const struct intel_pt_pkt *packet,
398static inline void intel_pt_set_last_ip(struct intel_pt_decoder *decoder) 431static inline void intel_pt_set_last_ip(struct intel_pt_decoder *decoder)
399{ 432{
400 decoder->last_ip = intel_pt_calc_ip(&decoder->packet, decoder->last_ip); 433 decoder->last_ip = intel_pt_calc_ip(&decoder->packet, decoder->last_ip);
434 decoder->have_last_ip = true;
401} 435}
402 436
403static inline void intel_pt_set_ip(struct intel_pt_decoder *decoder) 437static inline void intel_pt_set_ip(struct intel_pt_decoder *decoder)
@@ -635,6 +669,8 @@ static int intel_pt_calc_cyc_cb(struct intel_pt_pkt_info *pkt_info)
635 case INTEL_PT_PAD: 669 case INTEL_PT_PAD:
636 case INTEL_PT_VMCS: 670 case INTEL_PT_VMCS:
637 case INTEL_PT_MNT: 671 case INTEL_PT_MNT:
672 case INTEL_PT_PTWRITE:
673 case INTEL_PT_PTWRITE_IP:
638 return 0; 674 return 0;
639 675
640 case INTEL_PT_MTC: 676 case INTEL_PT_MTC:
@@ -675,6 +711,12 @@ static int intel_pt_calc_cyc_cb(struct intel_pt_pkt_info *pkt_info)
675 break; 711 break;
676 712
677 case INTEL_PT_TSC: 713 case INTEL_PT_TSC:
714 /*
715 * For now, do not support using TSC packets - refer
716 * intel_pt_calc_cyc_to_tsc().
717 */
718 if (data->from_mtc)
719 return 1;
678 timestamp = pkt_info->packet.payload | 720 timestamp = pkt_info->packet.payload |
679 (data->timestamp & (0xffULL << 56)); 721 (data->timestamp & (0xffULL << 56));
680 if (data->from_mtc && timestamp < data->timestamp && 722 if (data->from_mtc && timestamp < data->timestamp &&
@@ -733,6 +775,11 @@ static int intel_pt_calc_cyc_cb(struct intel_pt_pkt_info *pkt_info)
733 775
734 case INTEL_PT_TIP_PGD: 776 case INTEL_PT_TIP_PGD:
735 case INTEL_PT_TRACESTOP: 777 case INTEL_PT_TRACESTOP:
778 case INTEL_PT_EXSTOP:
779 case INTEL_PT_EXSTOP_IP:
780 case INTEL_PT_MWAIT:
781 case INTEL_PT_PWRE:
782 case INTEL_PT_PWRX:
736 case INTEL_PT_OVF: 783 case INTEL_PT_OVF:
737 case INTEL_PT_BAD: /* Does not happen */ 784 case INTEL_PT_BAD: /* Does not happen */
738 default: 785 default:
@@ -787,6 +834,14 @@ static void intel_pt_calc_cyc_to_tsc(struct intel_pt_decoder *decoder,
787 .cbr_cyc_to_tsc = 0, 834 .cbr_cyc_to_tsc = 0,
788 }; 835 };
789 836
837 /*
838 * For now, do not support using TSC packets for at least the reasons:
839 * 1) timing might have stopped
840 * 2) TSC packets within PSB+ can slip against CYC packets
841 */
842 if (!from_mtc)
843 return;
844
790 intel_pt_pkt_lookahead(decoder, intel_pt_calc_cyc_cb, &data); 845 intel_pt_pkt_lookahead(decoder, intel_pt_calc_cyc_cb, &data);
791} 846}
792 847
@@ -898,6 +953,7 @@ static int intel_pt_walk_insn(struct intel_pt_decoder *decoder,
898 953
899 decoder->tot_insn_cnt += insn_cnt; 954 decoder->tot_insn_cnt += insn_cnt;
900 decoder->timestamp_insn_cnt += insn_cnt; 955 decoder->timestamp_insn_cnt += insn_cnt;
956 decoder->sample_insn_cnt += insn_cnt;
901 decoder->period_insn_cnt += insn_cnt; 957 decoder->period_insn_cnt += insn_cnt;
902 958
903 if (err) { 959 if (err) {
@@ -990,6 +1046,57 @@ out_no_progress:
990 return err; 1046 return err;
991} 1047}
992 1048
1049static bool intel_pt_fup_event(struct intel_pt_decoder *decoder)
1050{
1051 bool ret = false;
1052
1053 if (decoder->set_fup_tx_flags) {
1054 decoder->set_fup_tx_flags = false;
1055 decoder->tx_flags = decoder->fup_tx_flags;
1056 decoder->state.type = INTEL_PT_TRANSACTION;
1057 decoder->state.from_ip = decoder->ip;
1058 decoder->state.to_ip = 0;
1059 decoder->state.flags = decoder->fup_tx_flags;
1060 return true;
1061 }
1062 if (decoder->set_fup_ptw) {
1063 decoder->set_fup_ptw = false;
1064 decoder->state.type = INTEL_PT_PTW;
1065 decoder->state.flags |= INTEL_PT_FUP_IP;
1066 decoder->state.from_ip = decoder->ip;
1067 decoder->state.to_ip = 0;
1068 decoder->state.ptw_payload = decoder->fup_ptw_payload;
1069 return true;
1070 }
1071 if (decoder->set_fup_mwait) {
1072 decoder->set_fup_mwait = false;
1073 decoder->state.type = INTEL_PT_MWAIT_OP;
1074 decoder->state.from_ip = decoder->ip;
1075 decoder->state.to_ip = 0;
1076 decoder->state.mwait_payload = decoder->fup_mwait_payload;
1077 ret = true;
1078 }
1079 if (decoder->set_fup_pwre) {
1080 decoder->set_fup_pwre = false;
1081 decoder->state.type |= INTEL_PT_PWR_ENTRY;
1082 decoder->state.type &= ~INTEL_PT_BRANCH;
1083 decoder->state.from_ip = decoder->ip;
1084 decoder->state.to_ip = 0;
1085 decoder->state.pwre_payload = decoder->fup_pwre_payload;
1086 ret = true;
1087 }
1088 if (decoder->set_fup_exstop) {
1089 decoder->set_fup_exstop = false;
1090 decoder->state.type |= INTEL_PT_EX_STOP;
1091 decoder->state.type &= ~INTEL_PT_BRANCH;
1092 decoder->state.flags |= INTEL_PT_FUP_IP;
1093 decoder->state.from_ip = decoder->ip;
1094 decoder->state.to_ip = 0;
1095 ret = true;
1096 }
1097 return ret;
1098}
1099
993static int intel_pt_walk_fup(struct intel_pt_decoder *decoder) 1100static int intel_pt_walk_fup(struct intel_pt_decoder *decoder)
994{ 1101{
995 struct intel_pt_insn intel_pt_insn; 1102 struct intel_pt_insn intel_pt_insn;
@@ -1003,15 +1110,8 @@ static int intel_pt_walk_fup(struct intel_pt_decoder *decoder)
1003 if (err == INTEL_PT_RETURN) 1110 if (err == INTEL_PT_RETURN)
1004 return 0; 1111 return 0;
1005 if (err == -EAGAIN) { 1112 if (err == -EAGAIN) {
1006 if (decoder->set_fup_tx_flags) { 1113 if (intel_pt_fup_event(decoder))
1007 decoder->set_fup_tx_flags = false;
1008 decoder->tx_flags = decoder->fup_tx_flags;
1009 decoder->state.type = INTEL_PT_TRANSACTION;
1010 decoder->state.from_ip = decoder->ip;
1011 decoder->state.to_ip = 0;
1012 decoder->state.flags = decoder->fup_tx_flags;
1013 return 0; 1114 return 0;
1014 }
1015 return err; 1115 return err;
1016 } 1116 }
1017 decoder->set_fup_tx_flags = false; 1117 decoder->set_fup_tx_flags = false;
@@ -1360,7 +1460,9 @@ static void intel_pt_calc_mtc_timestamp(struct intel_pt_decoder *decoder)
1360 1460
1361static void intel_pt_calc_cbr(struct intel_pt_decoder *decoder) 1461static void intel_pt_calc_cbr(struct intel_pt_decoder *decoder)
1362{ 1462{
1363 unsigned int cbr = decoder->packet.payload; 1463 unsigned int cbr = decoder->packet.payload & 0xff;
1464
1465 decoder->cbr_payload = decoder->packet.payload;
1364 1466
1365 if (decoder->cbr == cbr) 1467 if (decoder->cbr == cbr)
1366 return; 1468 return;
@@ -1417,6 +1519,13 @@ static int intel_pt_walk_psbend(struct intel_pt_decoder *decoder)
1417 case INTEL_PT_TRACESTOP: 1519 case INTEL_PT_TRACESTOP:
1418 case INTEL_PT_BAD: 1520 case INTEL_PT_BAD:
1419 case INTEL_PT_PSB: 1521 case INTEL_PT_PSB:
1522 case INTEL_PT_PTWRITE:
1523 case INTEL_PT_PTWRITE_IP:
1524 case INTEL_PT_EXSTOP:
1525 case INTEL_PT_EXSTOP_IP:
1526 case INTEL_PT_MWAIT:
1527 case INTEL_PT_PWRE:
1528 case INTEL_PT_PWRX:
1420 decoder->have_tma = false; 1529 decoder->have_tma = false;
1421 intel_pt_log("ERROR: Unexpected packet\n"); 1530 intel_pt_log("ERROR: Unexpected packet\n");
1422 return -EAGAIN; 1531 return -EAGAIN;
@@ -1446,7 +1555,8 @@ static int intel_pt_walk_psbend(struct intel_pt_decoder *decoder)
1446 1555
1447 case INTEL_PT_FUP: 1556 case INTEL_PT_FUP:
1448 decoder->pge = true; 1557 decoder->pge = true;
1449 intel_pt_set_last_ip(decoder); 1558 if (decoder->packet.count)
1559 intel_pt_set_last_ip(decoder);
1450 break; 1560 break;
1451 1561
1452 case INTEL_PT_MODE_TSX: 1562 case INTEL_PT_MODE_TSX:
@@ -1497,6 +1607,13 @@ static int intel_pt_walk_fup_tip(struct intel_pt_decoder *decoder)
1497 case INTEL_PT_MODE_TSX: 1607 case INTEL_PT_MODE_TSX:
1498 case INTEL_PT_BAD: 1608 case INTEL_PT_BAD:
1499 case INTEL_PT_PSBEND: 1609 case INTEL_PT_PSBEND:
1610 case INTEL_PT_PTWRITE:
1611 case INTEL_PT_PTWRITE_IP:
1612 case INTEL_PT_EXSTOP:
1613 case INTEL_PT_EXSTOP_IP:
1614 case INTEL_PT_MWAIT:
1615 case INTEL_PT_PWRE:
1616 case INTEL_PT_PWRX:
1500 intel_pt_log("ERROR: Missing TIP after FUP\n"); 1617 intel_pt_log("ERROR: Missing TIP after FUP\n");
1501 decoder->pkt_state = INTEL_PT_STATE_ERR3; 1618 decoder->pkt_state = INTEL_PT_STATE_ERR3;
1502 return -ENOENT; 1619 return -ENOENT;
@@ -1625,6 +1742,15 @@ next:
1625 break; 1742 break;
1626 } 1743 }
1627 intel_pt_set_last_ip(decoder); 1744 intel_pt_set_last_ip(decoder);
1745 if (!decoder->branch_enable) {
1746 decoder->ip = decoder->last_ip;
1747 if (intel_pt_fup_event(decoder))
1748 return 0;
1749 no_tip = false;
1750 break;
1751 }
1752 if (decoder->set_fup_mwait)
1753 no_tip = true;
1628 err = intel_pt_walk_fup(decoder); 1754 err = intel_pt_walk_fup(decoder);
1629 if (err != -EAGAIN) { 1755 if (err != -EAGAIN) {
1630 if (err) 1756 if (err)
@@ -1650,6 +1776,8 @@ next:
1650 break; 1776 break;
1651 1777
1652 case INTEL_PT_PSB: 1778 case INTEL_PT_PSB:
1779 decoder->last_ip = 0;
1780 decoder->have_last_ip = true;
1653 intel_pt_clear_stack(&decoder->stack); 1781 intel_pt_clear_stack(&decoder->stack);
1654 err = intel_pt_walk_psbend(decoder); 1782 err = intel_pt_walk_psbend(decoder);
1655 if (err == -EAGAIN) 1783 if (err == -EAGAIN)
@@ -1696,6 +1824,16 @@ next:
1696 1824
1697 case INTEL_PT_CBR: 1825 case INTEL_PT_CBR:
1698 intel_pt_calc_cbr(decoder); 1826 intel_pt_calc_cbr(decoder);
1827 if (!decoder->branch_enable &&
1828 decoder->cbr != decoder->cbr_seen) {
1829 decoder->cbr_seen = decoder->cbr;
1830 decoder->state.type = INTEL_PT_CBR_CHG;
1831 decoder->state.from_ip = decoder->ip;
1832 decoder->state.to_ip = 0;
1833 decoder->state.cbr_payload =
1834 decoder->packet.payload;
1835 return 0;
1836 }
1699 break; 1837 break;
1700 1838
1701 case INTEL_PT_MODE_EXEC: 1839 case INTEL_PT_MODE_EXEC:
@@ -1722,6 +1860,71 @@ next:
1722 case INTEL_PT_PAD: 1860 case INTEL_PT_PAD:
1723 break; 1861 break;
1724 1862
1863 case INTEL_PT_PTWRITE_IP:
1864 decoder->fup_ptw_payload = decoder->packet.payload;
1865 err = intel_pt_get_next_packet(decoder);
1866 if (err)
1867 return err;
1868 if (decoder->packet.type == INTEL_PT_FUP) {
1869 decoder->set_fup_ptw = true;
1870 no_tip = true;
1871 } else {
1872 intel_pt_log_at("ERROR: Missing FUP after PTWRITE",
1873 decoder->pos);
1874 }
1875 goto next;
1876
1877 case INTEL_PT_PTWRITE:
1878 decoder->state.type = INTEL_PT_PTW;
1879 decoder->state.from_ip = decoder->ip;
1880 decoder->state.to_ip = 0;
1881 decoder->state.ptw_payload = decoder->packet.payload;
1882 return 0;
1883
1884 case INTEL_PT_MWAIT:
1885 decoder->fup_mwait_payload = decoder->packet.payload;
1886 decoder->set_fup_mwait = true;
1887 break;
1888
1889 case INTEL_PT_PWRE:
1890 if (decoder->set_fup_mwait) {
1891 decoder->fup_pwre_payload =
1892 decoder->packet.payload;
1893 decoder->set_fup_pwre = true;
1894 break;
1895 }
1896 decoder->state.type = INTEL_PT_PWR_ENTRY;
1897 decoder->state.from_ip = decoder->ip;
1898 decoder->state.to_ip = 0;
1899 decoder->state.pwrx_payload = decoder->packet.payload;
1900 return 0;
1901
1902 case INTEL_PT_EXSTOP_IP:
1903 err = intel_pt_get_next_packet(decoder);
1904 if (err)
1905 return err;
1906 if (decoder->packet.type == INTEL_PT_FUP) {
1907 decoder->set_fup_exstop = true;
1908 no_tip = true;
1909 } else {
1910 intel_pt_log_at("ERROR: Missing FUP after EXSTOP",
1911 decoder->pos);
1912 }
1913 goto next;
1914
1915 case INTEL_PT_EXSTOP:
1916 decoder->state.type = INTEL_PT_EX_STOP;
1917 decoder->state.from_ip = decoder->ip;
1918 decoder->state.to_ip = 0;
1919 return 0;
1920
1921 case INTEL_PT_PWRX:
1922 decoder->state.type = INTEL_PT_PWR_EXIT;
1923 decoder->state.from_ip = decoder->ip;
1924 decoder->state.to_ip = 0;
1925 decoder->state.pwrx_payload = decoder->packet.payload;
1926 return 0;
1927
1725 default: 1928 default:
1726 return intel_pt_bug(decoder); 1929 return intel_pt_bug(decoder);
1727 } 1930 }
@@ -1730,8 +1933,9 @@ next:
1730 1933
1731static inline bool intel_pt_have_ip(struct intel_pt_decoder *decoder) 1934static inline bool intel_pt_have_ip(struct intel_pt_decoder *decoder)
1732{ 1935{
1733 return decoder->last_ip || decoder->packet.count == 0 || 1936 return decoder->packet.count &&
1734 decoder->packet.count == 3 || decoder->packet.count == 6; 1937 (decoder->have_last_ip || decoder->packet.count == 3 ||
1938 decoder->packet.count == 6);
1735} 1939}
1736 1940
1737/* Walk PSB+ packets to get in sync. */ 1941/* Walk PSB+ packets to get in sync. */
@@ -1750,6 +1954,13 @@ static int intel_pt_walk_psb(struct intel_pt_decoder *decoder)
1750 __fallthrough; 1954 __fallthrough;
1751 case INTEL_PT_TIP_PGE: 1955 case INTEL_PT_TIP_PGE:
1752 case INTEL_PT_TIP: 1956 case INTEL_PT_TIP:
1957 case INTEL_PT_PTWRITE:
1958 case INTEL_PT_PTWRITE_IP:
1959 case INTEL_PT_EXSTOP:
1960 case INTEL_PT_EXSTOP_IP:
1961 case INTEL_PT_MWAIT:
1962 case INTEL_PT_PWRE:
1963 case INTEL_PT_PWRX:
1753 intel_pt_log("ERROR: Unexpected packet\n"); 1964 intel_pt_log("ERROR: Unexpected packet\n");
1754 return -ENOENT; 1965 return -ENOENT;
1755 1966
@@ -1854,14 +2065,10 @@ static int intel_pt_walk_to_ip(struct intel_pt_decoder *decoder)
1854 break; 2065 break;
1855 2066
1856 case INTEL_PT_FUP: 2067 case INTEL_PT_FUP:
1857 if (decoder->overflow) { 2068 if (intel_pt_have_ip(decoder))
1858 if (intel_pt_have_ip(decoder)) 2069 intel_pt_set_ip(decoder);
1859 intel_pt_set_ip(decoder); 2070 if (decoder->ip)
1860 if (decoder->ip) 2071 return 0;
1861 return 0;
1862 }
1863 if (decoder->packet.count)
1864 intel_pt_set_last_ip(decoder);
1865 break; 2072 break;
1866 2073
1867 case INTEL_PT_MTC: 2074 case INTEL_PT_MTC:
@@ -1910,6 +2117,9 @@ static int intel_pt_walk_to_ip(struct intel_pt_decoder *decoder)
1910 break; 2117 break;
1911 2118
1912 case INTEL_PT_PSB: 2119 case INTEL_PT_PSB:
2120 decoder->last_ip = 0;
2121 decoder->have_last_ip = true;
2122 intel_pt_clear_stack(&decoder->stack);
1913 err = intel_pt_walk_psb(decoder); 2123 err = intel_pt_walk_psb(decoder);
1914 if (err) 2124 if (err)
1915 return err; 2125 return err;
@@ -1925,6 +2135,13 @@ static int intel_pt_walk_to_ip(struct intel_pt_decoder *decoder)
1925 case INTEL_PT_VMCS: 2135 case INTEL_PT_VMCS:
1926 case INTEL_PT_MNT: 2136 case INTEL_PT_MNT:
1927 case INTEL_PT_PAD: 2137 case INTEL_PT_PAD:
2138 case INTEL_PT_PTWRITE:
2139 case INTEL_PT_PTWRITE_IP:
2140 case INTEL_PT_EXSTOP:
2141 case INTEL_PT_EXSTOP_IP:
2142 case INTEL_PT_MWAIT:
2143 case INTEL_PT_PWRE:
2144 case INTEL_PT_PWRX:
1928 default: 2145 default:
1929 break; 2146 break;
1930 } 2147 }
@@ -1935,6 +2152,19 @@ static int intel_pt_sync_ip(struct intel_pt_decoder *decoder)
1935{ 2152{
1936 int err; 2153 int err;
1937 2154
2155 decoder->set_fup_tx_flags = false;
2156 decoder->set_fup_ptw = false;
2157 decoder->set_fup_mwait = false;
2158 decoder->set_fup_pwre = false;
2159 decoder->set_fup_exstop = false;
2160
2161 if (!decoder->branch_enable) {
2162 decoder->pkt_state = INTEL_PT_STATE_IN_SYNC;
2163 decoder->overflow = false;
2164 decoder->state.type = 0; /* Do not have a sample */
2165 return 0;
2166 }
2167
1938 intel_pt_log("Scanning for full IP\n"); 2168 intel_pt_log("Scanning for full IP\n");
1939 err = intel_pt_walk_to_ip(decoder); 2169 err = intel_pt_walk_to_ip(decoder);
1940 if (err) 2170 if (err)
@@ -2043,6 +2273,7 @@ static int intel_pt_sync(struct intel_pt_decoder *decoder)
2043 2273
2044 decoder->pge = false; 2274 decoder->pge = false;
2045 decoder->continuous_period = false; 2275 decoder->continuous_period = false;
2276 decoder->have_last_ip = false;
2046 decoder->last_ip = 0; 2277 decoder->last_ip = 0;
2047 decoder->ip = 0; 2278 decoder->ip = 0;
2048 intel_pt_clear_stack(&decoder->stack); 2279 intel_pt_clear_stack(&decoder->stack);
@@ -2051,6 +2282,7 @@ static int intel_pt_sync(struct intel_pt_decoder *decoder)
2051 if (err) 2282 if (err)
2052 return err; 2283 return err;
2053 2284
2285 decoder->have_last_ip = true;
2054 decoder->pkt_state = INTEL_PT_STATE_NO_IP; 2286 decoder->pkt_state = INTEL_PT_STATE_NO_IP;
2055 2287
2056 err = intel_pt_walk_psb(decoder); 2288 err = intel_pt_walk_psb(decoder);
@@ -2069,7 +2301,7 @@ static int intel_pt_sync(struct intel_pt_decoder *decoder)
2069 2301
2070static uint64_t intel_pt_est_timestamp(struct intel_pt_decoder *decoder) 2302static uint64_t intel_pt_est_timestamp(struct intel_pt_decoder *decoder)
2071{ 2303{
2072 uint64_t est = decoder->timestamp_insn_cnt << 1; 2304 uint64_t est = decoder->sample_insn_cnt << 1;
2073 2305
2074 if (!decoder->cbr || !decoder->max_non_turbo_ratio) 2306 if (!decoder->cbr || !decoder->max_non_turbo_ratio)
2075 goto out; 2307 goto out;
@@ -2077,7 +2309,7 @@ static uint64_t intel_pt_est_timestamp(struct intel_pt_decoder *decoder)
2077 est *= decoder->max_non_turbo_ratio; 2309 est *= decoder->max_non_turbo_ratio;
2078 est /= decoder->cbr; 2310 est /= decoder->cbr;
2079out: 2311out:
2080 return decoder->timestamp + est; 2312 return decoder->sample_timestamp + est;
2081} 2313}
2082 2314
2083const struct intel_pt_state *intel_pt_decode(struct intel_pt_decoder *decoder) 2315const struct intel_pt_state *intel_pt_decode(struct intel_pt_decoder *decoder)
@@ -2093,8 +2325,10 @@ const struct intel_pt_state *intel_pt_decode(struct intel_pt_decoder *decoder)
2093 err = intel_pt_sync(decoder); 2325 err = intel_pt_sync(decoder);
2094 break; 2326 break;
2095 case INTEL_PT_STATE_NO_IP: 2327 case INTEL_PT_STATE_NO_IP:
2328 decoder->have_last_ip = false;
2096 decoder->last_ip = 0; 2329 decoder->last_ip = 0;
2097 /* Fall through */ 2330 decoder->ip = 0;
2331 __fallthrough;
2098 case INTEL_PT_STATE_ERR_RESYNC: 2332 case INTEL_PT_STATE_ERR_RESYNC:
2099 err = intel_pt_sync_ip(decoder); 2333 err = intel_pt_sync_ip(decoder);
2100 break; 2334 break;
@@ -2130,15 +2364,29 @@ const struct intel_pt_state *intel_pt_decode(struct intel_pt_decoder *decoder)
2130 } 2364 }
2131 } while (err == -ENOLINK); 2365 } while (err == -ENOLINK);
2132 2366
2133 decoder->state.err = err ? intel_pt_ext_err(err) : 0; 2367 if (err) {
2134 decoder->state.timestamp = decoder->timestamp; 2368 decoder->state.err = intel_pt_ext_err(err);
2369 decoder->state.from_ip = decoder->ip;
2370 decoder->sample_timestamp = decoder->timestamp;
2371 decoder->sample_insn_cnt = decoder->timestamp_insn_cnt;
2372 } else {
2373 decoder->state.err = 0;
2374 if (decoder->cbr != decoder->cbr_seen && decoder->state.type) {
2375 decoder->cbr_seen = decoder->cbr;
2376 decoder->state.type |= INTEL_PT_CBR_CHG;
2377 decoder->state.cbr_payload = decoder->cbr_payload;
2378 }
2379 if (intel_pt_sample_time(decoder->pkt_state)) {
2380 decoder->sample_timestamp = decoder->timestamp;
2381 decoder->sample_insn_cnt = decoder->timestamp_insn_cnt;
2382 }
2383 }
2384
2385 decoder->state.timestamp = decoder->sample_timestamp;
2135 decoder->state.est_timestamp = intel_pt_est_timestamp(decoder); 2386 decoder->state.est_timestamp = intel_pt_est_timestamp(decoder);
2136 decoder->state.cr3 = decoder->cr3; 2387 decoder->state.cr3 = decoder->cr3;
2137 decoder->state.tot_insn_cnt = decoder->tot_insn_cnt; 2388 decoder->state.tot_insn_cnt = decoder->tot_insn_cnt;
2138 2389
2139 if (err)
2140 decoder->state.from_ip = decoder->ip;
2141
2142 return &decoder->state; 2390 return &decoder->state;
2143} 2391}
2144 2392
diff --git a/tools/perf/util/intel-pt-decoder/intel-pt-decoder.h b/tools/perf/util/intel-pt-decoder/intel-pt-decoder.h
index e90619a43c0c..921b22e8ca0e 100644
--- a/tools/perf/util/intel-pt-decoder/intel-pt-decoder.h
+++ b/tools/perf/util/intel-pt-decoder/intel-pt-decoder.h
@@ -25,11 +25,18 @@
25#define INTEL_PT_IN_TX (1 << 0) 25#define INTEL_PT_IN_TX (1 << 0)
26#define INTEL_PT_ABORT_TX (1 << 1) 26#define INTEL_PT_ABORT_TX (1 << 1)
27#define INTEL_PT_ASYNC (1 << 2) 27#define INTEL_PT_ASYNC (1 << 2)
28#define INTEL_PT_FUP_IP (1 << 3)
28 29
29enum intel_pt_sample_type { 30enum intel_pt_sample_type {
30 INTEL_PT_BRANCH = 1 << 0, 31 INTEL_PT_BRANCH = 1 << 0,
31 INTEL_PT_INSTRUCTION = 1 << 1, 32 INTEL_PT_INSTRUCTION = 1 << 1,
32 INTEL_PT_TRANSACTION = 1 << 2, 33 INTEL_PT_TRANSACTION = 1 << 2,
34 INTEL_PT_PTW = 1 << 3,
35 INTEL_PT_MWAIT_OP = 1 << 4,
36 INTEL_PT_PWR_ENTRY = 1 << 5,
37 INTEL_PT_EX_STOP = 1 << 6,
38 INTEL_PT_PWR_EXIT = 1 << 7,
39 INTEL_PT_CBR_CHG = 1 << 8,
33}; 40};
34 41
35enum intel_pt_period_type { 42enum intel_pt_period_type {
@@ -63,6 +70,11 @@ struct intel_pt_state {
63 uint64_t timestamp; 70 uint64_t timestamp;
64 uint64_t est_timestamp; 71 uint64_t est_timestamp;
65 uint64_t trace_nr; 72 uint64_t trace_nr;
73 uint64_t ptw_payload;
74 uint64_t mwait_payload;
75 uint64_t pwre_payload;
76 uint64_t pwrx_payload;
77 uint64_t cbr_payload;
66 uint32_t flags; 78 uint32_t flags;
67 enum intel_pt_insn_op insn_op; 79 enum intel_pt_insn_op insn_op;
68 int insn_len; 80 int insn_len;
@@ -87,6 +99,7 @@ struct intel_pt_params {
87 bool (*pgd_ip)(uint64_t ip, void *data); 99 bool (*pgd_ip)(uint64_t ip, void *data);
88 void *data; 100 void *data;
89 bool return_compression; 101 bool return_compression;
102 bool branch_enable;
90 uint64_t period; 103 uint64_t period;
91 enum intel_pt_period_type period_type; 104 enum intel_pt_period_type period_type;
92 unsigned max_non_turbo_ratio; 105 unsigned max_non_turbo_ratio;
diff --git a/tools/perf/util/intel-pt-decoder/intel-pt-log.h b/tools/perf/util/intel-pt-decoder/intel-pt-log.h
index debe751dc3d6..45b64f93f358 100644
--- a/tools/perf/util/intel-pt-decoder/intel-pt-log.h
+++ b/tools/perf/util/intel-pt-decoder/intel-pt-log.h
@@ -16,6 +16,7 @@
16#ifndef INCLUDE__INTEL_PT_LOG_H__ 16#ifndef INCLUDE__INTEL_PT_LOG_H__
17#define INCLUDE__INTEL_PT_LOG_H__ 17#define INCLUDE__INTEL_PT_LOG_H__
18 18
19#include <linux/compiler.h>
19#include <stdint.h> 20#include <stdint.h>
20#include <inttypes.h> 21#include <inttypes.h>
21 22
@@ -34,8 +35,7 @@ void __intel_pt_log_insn(struct intel_pt_insn *intel_pt_insn, uint64_t ip);
34void __intel_pt_log_insn_no_data(struct intel_pt_insn *intel_pt_insn, 35void __intel_pt_log_insn_no_data(struct intel_pt_insn *intel_pt_insn,
35 uint64_t ip); 36 uint64_t ip);
36 37
37__attribute__((format(printf, 1, 2))) 38void __intel_pt_log(const char *fmt, ...) __printf(1, 2);
38void __intel_pt_log(const char *fmt, ...);
39 39
40#define intel_pt_log(fmt, ...) \ 40#define intel_pt_log(fmt, ...) \
41 do { \ 41 do { \
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 7528ae4f7e28..ba4c9dd18643 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
@@ -64,6 +64,13 @@ static const char * const packet_name[] = {
64 [INTEL_PT_PIP] = "PIP", 64 [INTEL_PT_PIP] = "PIP",
65 [INTEL_PT_OVF] = "OVF", 65 [INTEL_PT_OVF] = "OVF",
66 [INTEL_PT_MNT] = "MNT", 66 [INTEL_PT_MNT] = "MNT",
67 [INTEL_PT_PTWRITE] = "PTWRITE",
68 [INTEL_PT_PTWRITE_IP] = "PTWRITE",
69 [INTEL_PT_EXSTOP] = "EXSTOP",
70 [INTEL_PT_EXSTOP_IP] = "EXSTOP",
71 [INTEL_PT_MWAIT] = "MWAIT",
72 [INTEL_PT_PWRE] = "PWRE",
73 [INTEL_PT_PWRX] = "PWRX",
67}; 74};
68 75
69const char *intel_pt_pkt_name(enum intel_pt_pkt_type type) 76const char *intel_pt_pkt_name(enum intel_pt_pkt_type type)
@@ -123,7 +130,7 @@ static int intel_pt_get_cbr(const unsigned char *buf, size_t len,
123 if (len < 4) 130 if (len < 4)
124 return INTEL_PT_NEED_MORE_BYTES; 131 return INTEL_PT_NEED_MORE_BYTES;
125 packet->type = INTEL_PT_CBR; 132 packet->type = INTEL_PT_CBR;
126 packet->payload = buf[2]; 133 packet->payload = le16_to_cpu(*(uint16_t *)(buf + 2));
127 return 4; 134 return 4;
128} 135}
129 136
@@ -217,12 +224,80 @@ static int intel_pt_get_3byte(const unsigned char *buf, size_t len,
217 } 224 }
218} 225}
219 226
227static int intel_pt_get_ptwrite(const unsigned char *buf, size_t len,
228 struct intel_pt_pkt *packet)
229{
230 packet->count = (buf[1] >> 5) & 0x3;
231 packet->type = buf[1] & BIT(7) ? INTEL_PT_PTWRITE_IP :
232 INTEL_PT_PTWRITE;
233
234 switch (packet->count) {
235 case 0:
236 if (len < 6)
237 return INTEL_PT_NEED_MORE_BYTES;
238 packet->payload = le32_to_cpu(*(uint32_t *)(buf + 2));
239 return 6;
240 case 1:
241 if (len < 10)
242 return INTEL_PT_NEED_MORE_BYTES;
243 packet->payload = le64_to_cpu(*(uint64_t *)(buf + 2));
244 return 10;
245 default:
246 return INTEL_PT_BAD_PACKET;
247 }
248}
249
250static int intel_pt_get_exstop(struct intel_pt_pkt *packet)
251{
252 packet->type = INTEL_PT_EXSTOP;
253 return 2;
254}
255
256static int intel_pt_get_exstop_ip(struct intel_pt_pkt *packet)
257{
258 packet->type = INTEL_PT_EXSTOP_IP;
259 return 2;
260}
261
262static int intel_pt_get_mwait(const unsigned char *buf, size_t len,
263 struct intel_pt_pkt *packet)
264{
265 if (len < 10)
266 return INTEL_PT_NEED_MORE_BYTES;
267 packet->type = INTEL_PT_MWAIT;
268 packet->payload = le64_to_cpu(*(uint64_t *)(buf + 2));
269 return 10;
270}
271
272static int intel_pt_get_pwre(const unsigned char *buf, size_t len,
273 struct intel_pt_pkt *packet)
274{
275 if (len < 4)
276 return INTEL_PT_NEED_MORE_BYTES;
277 packet->type = INTEL_PT_PWRE;
278 memcpy_le64(&packet->payload, buf + 2, 2);
279 return 4;
280}
281
282static int intel_pt_get_pwrx(const unsigned char *buf, size_t len,
283 struct intel_pt_pkt *packet)
284{
285 if (len < 7)
286 return INTEL_PT_NEED_MORE_BYTES;
287 packet->type = INTEL_PT_PWRX;
288 memcpy_le64(&packet->payload, buf + 2, 5);
289 return 7;
290}
291
220static int intel_pt_get_ext(const unsigned char *buf, size_t len, 292static int intel_pt_get_ext(const unsigned char *buf, size_t len,
221 struct intel_pt_pkt *packet) 293 struct intel_pt_pkt *packet)
222{ 294{
223 if (len < 2) 295 if (len < 2)
224 return INTEL_PT_NEED_MORE_BYTES; 296 return INTEL_PT_NEED_MORE_BYTES;
225 297
298 if ((buf[1] & 0x1f) == 0x12)
299 return intel_pt_get_ptwrite(buf, len, packet);
300
226 switch (buf[1]) { 301 switch (buf[1]) {
227 case 0xa3: /* Long TNT */ 302 case 0xa3: /* Long TNT */
228 return intel_pt_get_long_tnt(buf, len, packet); 303 return intel_pt_get_long_tnt(buf, len, packet);
@@ -244,6 +319,16 @@ static int intel_pt_get_ext(const unsigned char *buf, size_t len,
244 return intel_pt_get_tma(buf, len, packet); 319 return intel_pt_get_tma(buf, len, packet);
245 case 0xC3: /* 3-byte header */ 320 case 0xC3: /* 3-byte header */
246 return intel_pt_get_3byte(buf, len, packet); 321 return intel_pt_get_3byte(buf, len, packet);
322 case 0x62: /* EXSTOP no IP */
323 return intel_pt_get_exstop(packet);
324 case 0xE2: /* EXSTOP with IP */
325 return intel_pt_get_exstop_ip(packet);
326 case 0xC2: /* MWAIT */
327 return intel_pt_get_mwait(buf, len, packet);
328 case 0x22: /* PWRE */
329 return intel_pt_get_pwre(buf, len, packet);
330 case 0xA2: /* PWRX */
331 return intel_pt_get_pwrx(buf, len, packet);
247 default: 332 default:
248 return INTEL_PT_BAD_PACKET; 333 return INTEL_PT_BAD_PACKET;
249 } 334 }
@@ -522,6 +607,29 @@ int intel_pt_pkt_desc(const struct intel_pt_pkt *packet, char *buf,
522 ret = snprintf(buf, buf_len, "%s 0x%llx (NR=%d)", 607 ret = snprintf(buf, buf_len, "%s 0x%llx (NR=%d)",
523 name, payload, nr); 608 name, payload, nr);
524 return ret; 609 return ret;
610 case INTEL_PT_PTWRITE:
611 return snprintf(buf, buf_len, "%s 0x%llx IP:0", name, payload);
612 case INTEL_PT_PTWRITE_IP:
613 return snprintf(buf, buf_len, "%s 0x%llx IP:1", name, payload);
614 case INTEL_PT_EXSTOP:
615 return snprintf(buf, buf_len, "%s IP:0", name);
616 case INTEL_PT_EXSTOP_IP:
617 return snprintf(buf, buf_len, "%s IP:1", name);
618 case INTEL_PT_MWAIT:
619 return snprintf(buf, buf_len, "%s 0x%llx Hints 0x%x Extensions 0x%x",
620 name, payload, (unsigned int)(payload & 0xff),
621 (unsigned int)((payload >> 32) & 0x3));
622 case INTEL_PT_PWRE:
623 return snprintf(buf, buf_len, "%s 0x%llx HW:%u CState:%u Sub-CState:%u",
624 name, payload, !!(payload & 0x80),
625 (unsigned int)((payload >> 12) & 0xf),
626 (unsigned int)((payload >> 8) & 0xf));
627 case INTEL_PT_PWRX:
628 return snprintf(buf, buf_len, "%s 0x%llx Last CState:%u Deepest CState:%u Wake Reason 0x%x",
629 name, payload,
630 (unsigned int)((payload >> 4) & 0xf),
631 (unsigned int)(payload & 0xf),
632 (unsigned int)((payload >> 8) & 0xf));
525 default: 633 default:
526 break; 634 break;
527 } 635 }
diff --git a/tools/perf/util/intel-pt-decoder/intel-pt-pkt-decoder.h b/tools/perf/util/intel-pt-decoder/intel-pt-pkt-decoder.h
index 781bb79883bd..73ddc3a88d07 100644
--- a/tools/perf/util/intel-pt-decoder/intel-pt-pkt-decoder.h
+++ b/tools/perf/util/intel-pt-decoder/intel-pt-pkt-decoder.h
@@ -52,6 +52,13 @@ enum intel_pt_pkt_type {
52 INTEL_PT_PIP, 52 INTEL_PT_PIP,
53 INTEL_PT_OVF, 53 INTEL_PT_OVF,
54 INTEL_PT_MNT, 54 INTEL_PT_MNT,
55 INTEL_PT_PTWRITE,
56 INTEL_PT_PTWRITE_IP,
57 INTEL_PT_EXSTOP,
58 INTEL_PT_EXSTOP_IP,
59 INTEL_PT_MWAIT,
60 INTEL_PT_PWRE,
61 INTEL_PT_PWRX,
55}; 62};
56 63
57struct intel_pt_pkt { 64struct intel_pt_pkt {
diff --git a/tools/perf/util/intel-pt-decoder/x86-opcode-map.txt b/tools/perf/util/intel-pt-decoder/x86-opcode-map.txt
index 767be7c76034..12e377184ee4 100644
--- a/tools/perf/util/intel-pt-decoder/x86-opcode-map.txt
+++ b/tools/perf/util/intel-pt-decoder/x86-opcode-map.txt
@@ -1009,7 +1009,7 @@ GrpTable: Grp15
10091: fxstor | RDGSBASE Ry (F3),(11B) 10091: fxstor | RDGSBASE Ry (F3),(11B)
10102: vldmxcsr Md (v1) | WRFSBASE Ry (F3),(11B) 10102: vldmxcsr Md (v1) | WRFSBASE Ry (F3),(11B)
10113: vstmxcsr Md (v1) | WRGSBASE Ry (F3),(11B) 10113: vstmxcsr Md (v1) | WRGSBASE Ry (F3),(11B)
10124: XSAVE 10124: XSAVE | ptwrite Ey (F3),(11B)
10135: XRSTOR | lfence (11B) 10135: XRSTOR | lfence (11B)
10146: XSAVEOPT | clwb (66) | mfence (11B) 10146: XSAVEOPT | clwb (66) | mfence (11B)
10157: clflush | clflushopt (66) | sfence (11B) 10157: clflush | clflushopt (66) | sfence (11B)
diff --git a/tools/perf/util/intel-pt.c b/tools/perf/util/intel-pt.c
index 4c7718f87a08..b58f9fd1e2ee 100644
--- a/tools/perf/util/intel-pt.c
+++ b/tools/perf/util/intel-pt.c
@@ -81,7 +81,6 @@ struct intel_pt {
81 81
82 bool sample_instructions; 82 bool sample_instructions;
83 u64 instructions_sample_type; 83 u64 instructions_sample_type;
84 u64 instructions_sample_period;
85 u64 instructions_id; 84 u64 instructions_id;
86 85
87 bool sample_branches; 86 bool sample_branches;
@@ -93,6 +92,18 @@ struct intel_pt {
93 u64 transactions_sample_type; 92 u64 transactions_sample_type;
94 u64 transactions_id; 93 u64 transactions_id;
95 94
95 bool sample_ptwrites;
96 u64 ptwrites_sample_type;
97 u64 ptwrites_id;
98
99 bool sample_pwr_events;
100 u64 pwr_events_sample_type;
101 u64 mwait_id;
102 u64 pwre_id;
103 u64 exstop_id;
104 u64 pwrx_id;
105 u64 cbr_id;
106
96 bool synth_needs_swap; 107 bool synth_needs_swap;
97 108
98 u64 tsc_bit; 109 u64 tsc_bit;
@@ -103,6 +114,7 @@ struct intel_pt {
103 u64 cyc_bit; 114 u64 cyc_bit;
104 u64 noretcomp_bit; 115 u64 noretcomp_bit;
105 unsigned max_non_turbo_ratio; 116 unsigned max_non_turbo_ratio;
117 unsigned cbr2khz;
106 118
107 unsigned long num_events; 119 unsigned long num_events;
108 120
@@ -668,6 +680,19 @@ static bool intel_pt_return_compression(struct intel_pt *pt)
668 return true; 680 return true;
669} 681}
670 682
683static bool intel_pt_branch_enable(struct intel_pt *pt)
684{
685 struct perf_evsel *evsel;
686 u64 config;
687
688 evlist__for_each_entry(pt->session->evlist, evsel) {
689 if (intel_pt_get_config(pt, &evsel->attr, &config) &&
690 (config & 1) && !(config & 0x2000))
691 return false;
692 }
693 return true;
694}
695
671static unsigned int intel_pt_mtc_period(struct intel_pt *pt) 696static unsigned int intel_pt_mtc_period(struct intel_pt *pt)
672{ 697{
673 struct perf_evsel *evsel; 698 struct perf_evsel *evsel;
@@ -799,6 +824,7 @@ static struct intel_pt_queue *intel_pt_alloc_queue(struct intel_pt *pt,
799 params.walk_insn = intel_pt_walk_next_insn; 824 params.walk_insn = intel_pt_walk_next_insn;
800 params.data = ptq; 825 params.data = ptq;
801 params.return_compression = intel_pt_return_compression(pt); 826 params.return_compression = intel_pt_return_compression(pt);
827 params.branch_enable = intel_pt_branch_enable(pt);
802 params.max_non_turbo_ratio = pt->max_non_turbo_ratio; 828 params.max_non_turbo_ratio = pt->max_non_turbo_ratio;
803 params.mtc_period = intel_pt_mtc_period(pt); 829 params.mtc_period = intel_pt_mtc_period(pt);
804 params.tsc_ctc_ratio_n = pt->tsc_ctc_ratio_n; 830 params.tsc_ctc_ratio_n = pt->tsc_ctc_ratio_n;
@@ -1044,6 +1070,36 @@ static void intel_pt_update_last_branch_rb(struct intel_pt_queue *ptq)
1044 bs->nr += 1; 1070 bs->nr += 1;
1045} 1071}
1046 1072
1073static inline bool intel_pt_skip_event(struct intel_pt *pt)
1074{
1075 return pt->synth_opts.initial_skip &&
1076 pt->num_events++ < pt->synth_opts.initial_skip;
1077}
1078
1079static void intel_pt_prep_b_sample(struct intel_pt *pt,
1080 struct intel_pt_queue *ptq,
1081 union perf_event *event,
1082 struct perf_sample *sample)
1083{
1084 event->sample.header.type = PERF_RECORD_SAMPLE;
1085 event->sample.header.misc = PERF_RECORD_MISC_USER;
1086 event->sample.header.size = sizeof(struct perf_event_header);
1087
1088 if (!pt->timeless_decoding)
1089 sample->time = tsc_to_perf_time(ptq->timestamp, &pt->tc);
1090
1091 sample->cpumode = PERF_RECORD_MISC_USER;
1092 sample->ip = ptq->state->from_ip;
1093 sample->pid = ptq->pid;
1094 sample->tid = ptq->tid;
1095 sample->addr = ptq->state->to_ip;
1096 sample->period = 1;
1097 sample->cpu = ptq->cpu;
1098 sample->flags = ptq->flags;
1099 sample->insn_len = ptq->insn_len;
1100 memcpy(sample->insn, ptq->insn, INTEL_PT_INSN_BUF_SZ);
1101}
1102
1047static int intel_pt_inject_event(union perf_event *event, 1103static int intel_pt_inject_event(union perf_event *event,
1048 struct perf_sample *sample, u64 type, 1104 struct perf_sample *sample, u64 type,
1049 bool swapped) 1105 bool swapped)
@@ -1052,9 +1108,35 @@ static int intel_pt_inject_event(union perf_event *event,
1052 return perf_event__synthesize_sample(event, type, 0, sample, swapped); 1108 return perf_event__synthesize_sample(event, type, 0, sample, swapped);
1053} 1109}
1054 1110
1055static int intel_pt_synth_branch_sample(struct intel_pt_queue *ptq) 1111static inline int intel_pt_opt_inject(struct intel_pt *pt,
1112 union perf_event *event,
1113 struct perf_sample *sample, u64 type)
1114{
1115 if (!pt->synth_opts.inject)
1116 return 0;
1117
1118 return intel_pt_inject_event(event, sample, type, pt->synth_needs_swap);
1119}
1120
1121static int intel_pt_deliver_synth_b_event(struct intel_pt *pt,
1122 union perf_event *event,
1123 struct perf_sample *sample, u64 type)
1056{ 1124{
1057 int ret; 1125 int ret;
1126
1127 ret = intel_pt_opt_inject(pt, event, sample, type);
1128 if (ret)
1129 return ret;
1130
1131 ret = perf_session__deliver_synth_event(pt->session, event, sample);
1132 if (ret)
1133 pr_err("Intel PT: failed to deliver event, error %d\n", ret);
1134
1135 return ret;
1136}
1137
1138static int intel_pt_synth_branch_sample(struct intel_pt_queue *ptq)
1139{
1058 struct intel_pt *pt = ptq->pt; 1140 struct intel_pt *pt = ptq->pt;
1059 union perf_event *event = ptq->event_buf; 1141 union perf_event *event = ptq->event_buf;
1060 struct perf_sample sample = { .ip = 0, }; 1142 struct perf_sample sample = { .ip = 0, };
@@ -1066,29 +1148,13 @@ static int intel_pt_synth_branch_sample(struct intel_pt_queue *ptq)
1066 if (pt->branches_filter && !(pt->branches_filter & ptq->flags)) 1148 if (pt->branches_filter && !(pt->branches_filter & ptq->flags))
1067 return 0; 1149 return 0;
1068 1150
1069 if (pt->synth_opts.initial_skip && 1151 if (intel_pt_skip_event(pt))
1070 pt->num_events++ < pt->synth_opts.initial_skip)
1071 return 0; 1152 return 0;
1072 1153
1073 event->sample.header.type = PERF_RECORD_SAMPLE; 1154 intel_pt_prep_b_sample(pt, ptq, event, &sample);
1074 event->sample.header.misc = PERF_RECORD_MISC_USER;
1075 event->sample.header.size = sizeof(struct perf_event_header);
1076 1155
1077 if (!pt->timeless_decoding)
1078 sample.time = tsc_to_perf_time(ptq->timestamp, &pt->tc);
1079
1080 sample.cpumode = PERF_RECORD_MISC_USER;
1081 sample.ip = ptq->state->from_ip;
1082 sample.pid = ptq->pid;
1083 sample.tid = ptq->tid;
1084 sample.addr = ptq->state->to_ip;
1085 sample.id = ptq->pt->branches_id; 1156 sample.id = ptq->pt->branches_id;
1086 sample.stream_id = ptq->pt->branches_id; 1157 sample.stream_id = ptq->pt->branches_id;
1087 sample.period = 1;
1088 sample.cpu = ptq->cpu;
1089 sample.flags = ptq->flags;
1090 sample.insn_len = ptq->insn_len;
1091 memcpy(sample.insn, ptq->insn, INTEL_PT_INSN_BUF_SZ);
1092 1158
1093 /* 1159 /*
1094 * perf report cannot handle events without a branch stack when using 1160 * perf report cannot handle events without a branch stack when using
@@ -1105,144 +1171,251 @@ static int intel_pt_synth_branch_sample(struct intel_pt_queue *ptq)
1105 sample.branch_stack = (struct branch_stack *)&dummy_bs; 1171 sample.branch_stack = (struct branch_stack *)&dummy_bs;
1106 } 1172 }
1107 1173
1108 if (pt->synth_opts.inject) { 1174 return intel_pt_deliver_synth_b_event(pt, event, &sample,
1109 ret = intel_pt_inject_event(event, &sample, 1175 pt->branches_sample_type);
1110 pt->branches_sample_type, 1176}
1111 pt->synth_needs_swap); 1177
1112 if (ret) 1178static void intel_pt_prep_sample(struct intel_pt *pt,
1113 return ret; 1179 struct intel_pt_queue *ptq,
1180 union perf_event *event,
1181 struct perf_sample *sample)
1182{
1183 intel_pt_prep_b_sample(pt, ptq, event, sample);
1184
1185 if (pt->synth_opts.callchain) {
1186 thread_stack__sample(ptq->thread, ptq->chain,
1187 pt->synth_opts.callchain_sz, sample->ip);
1188 sample->callchain = ptq->chain;
1114 } 1189 }
1115 1190
1116 ret = perf_session__deliver_synth_event(pt->session, event, &sample); 1191 if (pt->synth_opts.last_branch) {
1117 if (ret) 1192 intel_pt_copy_last_branch_rb(ptq);
1118 pr_err("Intel Processor Trace: failed to deliver branch event, error %d\n", 1193 sample->branch_stack = ptq->last_branch;
1119 ret); 1194 }
1195}
1196
1197static inline int intel_pt_deliver_synth_event(struct intel_pt *pt,
1198 struct intel_pt_queue *ptq,
1199 union perf_event *event,
1200 struct perf_sample *sample,
1201 u64 type)
1202{
1203 int ret;
1204
1205 ret = intel_pt_deliver_synth_b_event(pt, event, sample, type);
1206
1207 if (pt->synth_opts.last_branch)
1208 intel_pt_reset_last_branch_rb(ptq);
1120 1209
1121 return ret; 1210 return ret;
1122} 1211}
1123 1212
1124static int intel_pt_synth_instruction_sample(struct intel_pt_queue *ptq) 1213static int intel_pt_synth_instruction_sample(struct intel_pt_queue *ptq)
1125{ 1214{
1126 int ret;
1127 struct intel_pt *pt = ptq->pt; 1215 struct intel_pt *pt = ptq->pt;
1128 union perf_event *event = ptq->event_buf; 1216 union perf_event *event = ptq->event_buf;
1129 struct perf_sample sample = { .ip = 0, }; 1217 struct perf_sample sample = { .ip = 0, };
1130 1218
1131 if (pt->synth_opts.initial_skip && 1219 if (intel_pt_skip_event(pt))
1132 pt->num_events++ < pt->synth_opts.initial_skip)
1133 return 0; 1220 return 0;
1134 1221
1135 event->sample.header.type = PERF_RECORD_SAMPLE; 1222 intel_pt_prep_sample(pt, ptq, event, &sample);
1136 event->sample.header.misc = PERF_RECORD_MISC_USER;
1137 event->sample.header.size = sizeof(struct perf_event_header);
1138
1139 if (!pt->timeless_decoding)
1140 sample.time = tsc_to_perf_time(ptq->timestamp, &pt->tc);
1141 1223
1142 sample.cpumode = PERF_RECORD_MISC_USER;
1143 sample.ip = ptq->state->from_ip;
1144 sample.pid = ptq->pid;
1145 sample.tid = ptq->tid;
1146 sample.addr = ptq->state->to_ip;
1147 sample.id = ptq->pt->instructions_id; 1224 sample.id = ptq->pt->instructions_id;
1148 sample.stream_id = ptq->pt->instructions_id; 1225 sample.stream_id = ptq->pt->instructions_id;
1149 sample.period = ptq->state->tot_insn_cnt - ptq->last_insn_cnt; 1226 sample.period = ptq->state->tot_insn_cnt - ptq->last_insn_cnt;
1150 sample.cpu = ptq->cpu;
1151 sample.flags = ptq->flags;
1152 sample.insn_len = ptq->insn_len;
1153 memcpy(sample.insn, ptq->insn, INTEL_PT_INSN_BUF_SZ);
1154 1227
1155 ptq->last_insn_cnt = ptq->state->tot_insn_cnt; 1228 ptq->last_insn_cnt = ptq->state->tot_insn_cnt;
1156 1229
1157 if (pt->synth_opts.callchain) { 1230 return intel_pt_deliver_synth_event(pt, ptq, event, &sample,
1158 thread_stack__sample(ptq->thread, ptq->chain, 1231 pt->instructions_sample_type);
1159 pt->synth_opts.callchain_sz, sample.ip); 1232}
1160 sample.callchain = ptq->chain;
1161 }
1162 1233
1163 if (pt->synth_opts.last_branch) { 1234static int intel_pt_synth_transaction_sample(struct intel_pt_queue *ptq)
1164 intel_pt_copy_last_branch_rb(ptq); 1235{
1165 sample.branch_stack = ptq->last_branch; 1236 struct intel_pt *pt = ptq->pt;
1166 } 1237 union perf_event *event = ptq->event_buf;
1238 struct perf_sample sample = { .ip = 0, };
1167 1239
1168 if (pt->synth_opts.inject) { 1240 if (intel_pt_skip_event(pt))
1169 ret = intel_pt_inject_event(event, &sample, 1241 return 0;
1170 pt->instructions_sample_type,
1171 pt->synth_needs_swap);
1172 if (ret)
1173 return ret;
1174 }
1175 1242
1176 ret = perf_session__deliver_synth_event(pt->session, event, &sample); 1243 intel_pt_prep_sample(pt, ptq, event, &sample);
1177 if (ret)
1178 pr_err("Intel Processor Trace: failed to deliver instruction event, error %d\n",
1179 ret);
1180 1244
1181 if (pt->synth_opts.last_branch) 1245 sample.id = ptq->pt->transactions_id;
1182 intel_pt_reset_last_branch_rb(ptq); 1246 sample.stream_id = ptq->pt->transactions_id;
1183 1247
1184 return ret; 1248 return intel_pt_deliver_synth_event(pt, ptq, event, &sample,
1249 pt->transactions_sample_type);
1185} 1250}
1186 1251
1187static int intel_pt_synth_transaction_sample(struct intel_pt_queue *ptq) 1252static void intel_pt_prep_p_sample(struct intel_pt *pt,
1253 struct intel_pt_queue *ptq,
1254 union perf_event *event,
1255 struct perf_sample *sample)
1256{
1257 intel_pt_prep_sample(pt, ptq, event, sample);
1258
1259 /*
1260 * Zero IP is used to mean "trace start" but that is not the case for
1261 * power or PTWRITE events with no IP, so clear the flags.
1262 */
1263 if (!sample->ip)
1264 sample->flags = 0;
1265}
1266
1267static int intel_pt_synth_ptwrite_sample(struct intel_pt_queue *ptq)
1188{ 1268{
1189 int ret;
1190 struct intel_pt *pt = ptq->pt; 1269 struct intel_pt *pt = ptq->pt;
1191 union perf_event *event = ptq->event_buf; 1270 union perf_event *event = ptq->event_buf;
1192 struct perf_sample sample = { .ip = 0, }; 1271 struct perf_sample sample = { .ip = 0, };
1272 struct perf_synth_intel_ptwrite raw;
1193 1273
1194 if (pt->synth_opts.initial_skip && 1274 if (intel_pt_skip_event(pt))
1195 pt->num_events++ < pt->synth_opts.initial_skip)
1196 return 0; 1275 return 0;
1197 1276
1198 event->sample.header.type = PERF_RECORD_SAMPLE; 1277 intel_pt_prep_p_sample(pt, ptq, event, &sample);
1199 event->sample.header.misc = PERF_RECORD_MISC_USER;
1200 event->sample.header.size = sizeof(struct perf_event_header);
1201 1278
1202 if (!pt->timeless_decoding) 1279 sample.id = ptq->pt->ptwrites_id;
1203 sample.time = tsc_to_perf_time(ptq->timestamp, &pt->tc); 1280 sample.stream_id = ptq->pt->ptwrites_id;
1204 1281
1205 sample.cpumode = PERF_RECORD_MISC_USER; 1282 raw.flags = 0;
1206 sample.ip = ptq->state->from_ip; 1283 raw.ip = !!(ptq->state->flags & INTEL_PT_FUP_IP);
1207 sample.pid = ptq->pid; 1284 raw.payload = cpu_to_le64(ptq->state->ptw_payload);
1208 sample.tid = ptq->tid;
1209 sample.addr = ptq->state->to_ip;
1210 sample.id = ptq->pt->transactions_id;
1211 sample.stream_id = ptq->pt->transactions_id;
1212 sample.period = 1;
1213 sample.cpu = ptq->cpu;
1214 sample.flags = ptq->flags;
1215 sample.insn_len = ptq->insn_len;
1216 memcpy(sample.insn, ptq->insn, INTEL_PT_INSN_BUF_SZ);
1217 1285
1218 if (pt->synth_opts.callchain) { 1286 sample.raw_size = perf_synth__raw_size(raw);
1219 thread_stack__sample(ptq->thread, ptq->chain, 1287 sample.raw_data = perf_synth__raw_data(&raw);
1220 pt->synth_opts.callchain_sz, sample.ip);
1221 sample.callchain = ptq->chain;
1222 }
1223 1288
1224 if (pt->synth_opts.last_branch) { 1289 return intel_pt_deliver_synth_event(pt, ptq, event, &sample,
1225 intel_pt_copy_last_branch_rb(ptq); 1290 pt->ptwrites_sample_type);
1226 sample.branch_stack = ptq->last_branch; 1291}
1227 }
1228 1292
1229 if (pt->synth_opts.inject) { 1293static int intel_pt_synth_cbr_sample(struct intel_pt_queue *ptq)
1230 ret = intel_pt_inject_event(event, &sample, 1294{
1231 pt->transactions_sample_type, 1295 struct intel_pt *pt = ptq->pt;
1232 pt->synth_needs_swap); 1296 union perf_event *event = ptq->event_buf;
1233 if (ret) 1297 struct perf_sample sample = { .ip = 0, };
1234 return ret; 1298 struct perf_synth_intel_cbr raw;
1235 } 1299 u32 flags;
1236 1300
1237 ret = perf_session__deliver_synth_event(pt->session, event, &sample); 1301 if (intel_pt_skip_event(pt))
1238 if (ret) 1302 return 0;
1239 pr_err("Intel Processor Trace: failed to deliver transaction event, error %d\n",
1240 ret);
1241 1303
1242 if (pt->synth_opts.last_branch) 1304 intel_pt_prep_p_sample(pt, ptq, event, &sample);
1243 intel_pt_reset_last_branch_rb(ptq);
1244 1305
1245 return ret; 1306 sample.id = ptq->pt->cbr_id;
1307 sample.stream_id = ptq->pt->cbr_id;
1308
1309 flags = (u16)ptq->state->cbr_payload | (pt->max_non_turbo_ratio << 16);
1310 raw.flags = cpu_to_le32(flags);
1311 raw.freq = cpu_to_le32(raw.cbr * pt->cbr2khz);
1312 raw.reserved3 = 0;
1313
1314 sample.raw_size = perf_synth__raw_size(raw);
1315 sample.raw_data = perf_synth__raw_data(&raw);
1316
1317 return intel_pt_deliver_synth_event(pt, ptq, event, &sample,
1318 pt->pwr_events_sample_type);
1319}
1320
1321static int intel_pt_synth_mwait_sample(struct intel_pt_queue *ptq)
1322{
1323 struct intel_pt *pt = ptq->pt;
1324 union perf_event *event = ptq->event_buf;
1325 struct perf_sample sample = { .ip = 0, };
1326 struct perf_synth_intel_mwait raw;
1327
1328 if (intel_pt_skip_event(pt))
1329 return 0;
1330
1331 intel_pt_prep_p_sample(pt, ptq, event, &sample);
1332
1333 sample.id = ptq->pt->mwait_id;
1334 sample.stream_id = ptq->pt->mwait_id;
1335
1336 raw.reserved = 0;
1337 raw.payload = cpu_to_le64(ptq->state->mwait_payload);
1338
1339 sample.raw_size = perf_synth__raw_size(raw);
1340 sample.raw_data = perf_synth__raw_data(&raw);
1341
1342 return intel_pt_deliver_synth_event(pt, ptq, event, &sample,
1343 pt->pwr_events_sample_type);
1344}
1345
1346static int intel_pt_synth_pwre_sample(struct intel_pt_queue *ptq)
1347{
1348 struct intel_pt *pt = ptq->pt;
1349 union perf_event *event = ptq->event_buf;
1350 struct perf_sample sample = { .ip = 0, };
1351 struct perf_synth_intel_pwre raw;
1352
1353 if (intel_pt_skip_event(pt))
1354 return 0;
1355
1356 intel_pt_prep_p_sample(pt, ptq, event, &sample);
1357
1358 sample.id = ptq->pt->pwre_id;
1359 sample.stream_id = ptq->pt->pwre_id;
1360
1361 raw.reserved = 0;
1362 raw.payload = cpu_to_le64(ptq->state->pwre_payload);
1363
1364 sample.raw_size = perf_synth__raw_size(raw);
1365 sample.raw_data = perf_synth__raw_data(&raw);
1366
1367 return intel_pt_deliver_synth_event(pt, ptq, event, &sample,
1368 pt->pwr_events_sample_type);
1369}
1370
1371static int intel_pt_synth_exstop_sample(struct intel_pt_queue *ptq)
1372{
1373 struct intel_pt *pt = ptq->pt;
1374 union perf_event *event = ptq->event_buf;
1375 struct perf_sample sample = { .ip = 0, };
1376 struct perf_synth_intel_exstop raw;
1377
1378 if (intel_pt_skip_event(pt))
1379 return 0;
1380
1381 intel_pt_prep_p_sample(pt, ptq, event, &sample);
1382
1383 sample.id = ptq->pt->exstop_id;
1384 sample.stream_id = ptq->pt->exstop_id;
1385
1386 raw.flags = 0;
1387 raw.ip = !!(ptq->state->flags & INTEL_PT_FUP_IP);
1388
1389 sample.raw_size = perf_synth__raw_size(raw);
1390 sample.raw_data = perf_synth__raw_data(&raw);
1391
1392 return intel_pt_deliver_synth_event(pt, ptq, event, &sample,
1393 pt->pwr_events_sample_type);
1394}
1395
1396static int intel_pt_synth_pwrx_sample(struct intel_pt_queue *ptq)
1397{
1398 struct intel_pt *pt = ptq->pt;
1399 union perf_event *event = ptq->event_buf;
1400 struct perf_sample sample = { .ip = 0, };
1401 struct perf_synth_intel_pwrx raw;
1402
1403 if (intel_pt_skip_event(pt))
1404 return 0;
1405
1406 intel_pt_prep_p_sample(pt, ptq, event, &sample);
1407
1408 sample.id = ptq->pt->pwrx_id;
1409 sample.stream_id = ptq->pt->pwrx_id;
1410
1411 raw.reserved = 0;
1412 raw.payload = cpu_to_le64(ptq->state->pwrx_payload);
1413
1414 sample.raw_size = perf_synth__raw_size(raw);
1415 sample.raw_data = perf_synth__raw_data(&raw);
1416
1417 return intel_pt_deliver_synth_event(pt, ptq, event, &sample,
1418 pt->pwr_events_sample_type);
1246} 1419}
1247 1420
1248static int intel_pt_synth_error(struct intel_pt *pt, int code, int cpu, 1421static int intel_pt_synth_error(struct intel_pt *pt, int code, int cpu,
@@ -1296,6 +1469,10 @@ static inline bool intel_pt_is_switch_ip(struct intel_pt_queue *ptq, u64 ip)
1296 PERF_IP_FLAG_INTERRUPT | PERF_IP_FLAG_TX_ABORT)); 1469 PERF_IP_FLAG_INTERRUPT | PERF_IP_FLAG_TX_ABORT));
1297} 1470}
1298 1471
1472#define INTEL_PT_PWR_EVT (INTEL_PT_MWAIT_OP | INTEL_PT_PWR_ENTRY | \
1473 INTEL_PT_EX_STOP | INTEL_PT_PWR_EXIT | \
1474 INTEL_PT_CBR_CHG)
1475
1299static int intel_pt_sample(struct intel_pt_queue *ptq) 1476static int intel_pt_sample(struct intel_pt_queue *ptq)
1300{ 1477{
1301 const struct intel_pt_state *state = ptq->state; 1478 const struct intel_pt_state *state = ptq->state;
@@ -1307,24 +1484,52 @@ static int intel_pt_sample(struct intel_pt_queue *ptq)
1307 1484
1308 ptq->have_sample = false; 1485 ptq->have_sample = false;
1309 1486
1310 if (pt->sample_instructions && 1487 if (pt->sample_pwr_events && (state->type & INTEL_PT_PWR_EVT)) {
1311 (state->type & INTEL_PT_INSTRUCTION) && 1488 if (state->type & INTEL_PT_CBR_CHG) {
1312 (!pt->synth_opts.initial_skip || 1489 err = intel_pt_synth_cbr_sample(ptq);
1313 pt->num_events++ >= pt->synth_opts.initial_skip)) { 1490 if (err)
1491 return err;
1492 }
1493 if (state->type & INTEL_PT_MWAIT_OP) {
1494 err = intel_pt_synth_mwait_sample(ptq);
1495 if (err)
1496 return err;
1497 }
1498 if (state->type & INTEL_PT_PWR_ENTRY) {
1499 err = intel_pt_synth_pwre_sample(ptq);
1500 if (err)
1501 return err;
1502 }
1503 if (state->type & INTEL_PT_EX_STOP) {
1504 err = intel_pt_synth_exstop_sample(ptq);
1505 if (err)
1506 return err;
1507 }
1508 if (state->type & INTEL_PT_PWR_EXIT) {
1509 err = intel_pt_synth_pwrx_sample(ptq);
1510 if (err)
1511 return err;
1512 }
1513 }
1514
1515 if (pt->sample_instructions && (state->type & INTEL_PT_INSTRUCTION)) {
1314 err = intel_pt_synth_instruction_sample(ptq); 1516 err = intel_pt_synth_instruction_sample(ptq);
1315 if (err) 1517 if (err)
1316 return err; 1518 return err;
1317 } 1519 }
1318 1520
1319 if (pt->sample_transactions && 1521 if (pt->sample_transactions && (state->type & INTEL_PT_TRANSACTION)) {
1320 (state->type & INTEL_PT_TRANSACTION) &&
1321 (!pt->synth_opts.initial_skip ||
1322 pt->num_events++ >= pt->synth_opts.initial_skip)) {
1323 err = intel_pt_synth_transaction_sample(ptq); 1522 err = intel_pt_synth_transaction_sample(ptq);
1324 if (err) 1523 if (err)
1325 return err; 1524 return err;
1326 } 1525 }
1327 1526
1527 if (pt->sample_ptwrites && (state->type & INTEL_PT_PTW)) {
1528 err = intel_pt_synth_ptwrite_sample(ptq);
1529 if (err)
1530 return err;
1531 }
1532
1328 if (!(state->type & INTEL_PT_BRANCH)) 1533 if (!(state->type & INTEL_PT_BRANCH))
1329 return 0; 1534 return 0;
1330 1535
@@ -1925,36 +2130,65 @@ static int intel_pt_event_synth(struct perf_tool *tool,
1925 NULL); 2130 NULL);
1926} 2131}
1927 2132
1928static int intel_pt_synth_event(struct perf_session *session, 2133static int intel_pt_synth_event(struct perf_session *session, const char *name,
1929 struct perf_event_attr *attr, u64 id) 2134 struct perf_event_attr *attr, u64 id)
1930{ 2135{
1931 struct intel_pt_synth intel_pt_synth; 2136 struct intel_pt_synth intel_pt_synth;
2137 int err;
2138
2139 pr_debug("Synthesizing '%s' event with id %" PRIu64 " sample type %#" PRIx64 "\n",
2140 name, id, (u64)attr->sample_type);
1932 2141
1933 memset(&intel_pt_synth, 0, sizeof(struct intel_pt_synth)); 2142 memset(&intel_pt_synth, 0, sizeof(struct intel_pt_synth));
1934 intel_pt_synth.session = session; 2143 intel_pt_synth.session = session;
1935 2144
1936 return perf_event__synthesize_attr(&intel_pt_synth.dummy_tool, attr, 1, 2145 err = perf_event__synthesize_attr(&intel_pt_synth.dummy_tool, attr, 1,
1937 &id, intel_pt_event_synth); 2146 &id, intel_pt_event_synth);
2147 if (err)
2148 pr_err("%s: failed to synthesize '%s' event type\n",
2149 __func__, name);
2150
2151 return err;
1938} 2152}
1939 2153
1940static int intel_pt_synth_events(struct intel_pt *pt, 2154static void intel_pt_set_event_name(struct perf_evlist *evlist, u64 id,
1941 struct perf_session *session) 2155 const char *name)
1942{ 2156{
1943 struct perf_evlist *evlist = session->evlist;
1944 struct perf_evsel *evsel; 2157 struct perf_evsel *evsel;
1945 struct perf_event_attr attr;
1946 bool found = false;
1947 u64 id;
1948 int err;
1949 2158
1950 evlist__for_each_entry(evlist, evsel) { 2159 evlist__for_each_entry(evlist, evsel) {
1951 if (evsel->attr.type == pt->pmu_type && evsel->ids) { 2160 if (evsel->id && evsel->id[0] == id) {
1952 found = true; 2161 if (evsel->name)
2162 zfree(&evsel->name);
2163 evsel->name = strdup(name);
1953 break; 2164 break;
1954 } 2165 }
1955 } 2166 }
2167}
1956 2168
1957 if (!found) { 2169static struct perf_evsel *intel_pt_evsel(struct intel_pt *pt,
2170 struct perf_evlist *evlist)
2171{
2172 struct perf_evsel *evsel;
2173
2174 evlist__for_each_entry(evlist, evsel) {
2175 if (evsel->attr.type == pt->pmu_type && evsel->ids)
2176 return evsel;
2177 }
2178
2179 return NULL;
2180}
2181
2182static int intel_pt_synth_events(struct intel_pt *pt,
2183 struct perf_session *session)
2184{
2185 struct perf_evlist *evlist = session->evlist;
2186 struct perf_evsel *evsel = intel_pt_evsel(pt, evlist);
2187 struct perf_event_attr attr;
2188 u64 id;
2189 int err;
2190
2191 if (!evsel) {
1958 pr_debug("There are no selected events with Intel Processor Trace data\n"); 2192 pr_debug("There are no selected events with Intel Processor Trace data\n");
1959 return 0; 2193 return 0;
1960 } 2194 }
@@ -1983,6 +2217,25 @@ static int intel_pt_synth_events(struct intel_pt *pt,
1983 if (!id) 2217 if (!id)
1984 id = 1; 2218 id = 1;
1985 2219
2220 if (pt->synth_opts.branches) {
2221 attr.config = PERF_COUNT_HW_BRANCH_INSTRUCTIONS;
2222 attr.sample_period = 1;
2223 attr.sample_type |= PERF_SAMPLE_ADDR;
2224 err = intel_pt_synth_event(session, "branches", &attr, id);
2225 if (err)
2226 return err;
2227 pt->sample_branches = true;
2228 pt->branches_sample_type = attr.sample_type;
2229 pt->branches_id = id;
2230 id += 1;
2231 attr.sample_type &= ~(u64)PERF_SAMPLE_ADDR;
2232 }
2233
2234 if (pt->synth_opts.callchain)
2235 attr.sample_type |= PERF_SAMPLE_CALLCHAIN;
2236 if (pt->synth_opts.last_branch)
2237 attr.sample_type |= PERF_SAMPLE_BRANCH_STACK;
2238
1986 if (pt->synth_opts.instructions) { 2239 if (pt->synth_opts.instructions) {
1987 attr.config = PERF_COUNT_HW_INSTRUCTIONS; 2240 attr.config = PERF_COUNT_HW_INSTRUCTIONS;
1988 if (pt->synth_opts.period_type == PERF_ITRACE_PERIOD_NANOSECS) 2241 if (pt->synth_opts.period_type == PERF_ITRACE_PERIOD_NANOSECS)
@@ -1990,70 +2243,90 @@ static int intel_pt_synth_events(struct intel_pt *pt,
1990 intel_pt_ns_to_ticks(pt, pt->synth_opts.period); 2243 intel_pt_ns_to_ticks(pt, pt->synth_opts.period);
1991 else 2244 else
1992 attr.sample_period = pt->synth_opts.period; 2245 attr.sample_period = pt->synth_opts.period;
1993 pt->instructions_sample_period = attr.sample_period; 2246 err = intel_pt_synth_event(session, "instructions", &attr, id);
1994 if (pt->synth_opts.callchain) 2247 if (err)
1995 attr.sample_type |= PERF_SAMPLE_CALLCHAIN;
1996 if (pt->synth_opts.last_branch)
1997 attr.sample_type |= PERF_SAMPLE_BRANCH_STACK;
1998 pr_debug("Synthesizing 'instructions' event with id %" PRIu64 " sample type %#" PRIx64 "\n",
1999 id, (u64)attr.sample_type);
2000 err = intel_pt_synth_event(session, &attr, id);
2001 if (err) {
2002 pr_err("%s: failed to synthesize 'instructions' event type\n",
2003 __func__);
2004 return err; 2248 return err;
2005 }
2006 pt->sample_instructions = true; 2249 pt->sample_instructions = true;
2007 pt->instructions_sample_type = attr.sample_type; 2250 pt->instructions_sample_type = attr.sample_type;
2008 pt->instructions_id = id; 2251 pt->instructions_id = id;
2009 id += 1; 2252 id += 1;
2010 } 2253 }
2011 2254
2255 attr.sample_type &= ~(u64)PERF_SAMPLE_PERIOD;
2256 attr.sample_period = 1;
2257
2012 if (pt->synth_opts.transactions) { 2258 if (pt->synth_opts.transactions) {
2013 attr.config = PERF_COUNT_HW_INSTRUCTIONS; 2259 attr.config = PERF_COUNT_HW_INSTRUCTIONS;
2014 attr.sample_period = 1; 2260 err = intel_pt_synth_event(session, "transactions", &attr, id);
2015 if (pt->synth_opts.callchain) 2261 if (err)
2016 attr.sample_type |= PERF_SAMPLE_CALLCHAIN;
2017 if (pt->synth_opts.last_branch)
2018 attr.sample_type |= PERF_SAMPLE_BRANCH_STACK;
2019 pr_debug("Synthesizing 'transactions' event with id %" PRIu64 " sample type %#" PRIx64 "\n",
2020 id, (u64)attr.sample_type);
2021 err = intel_pt_synth_event(session, &attr, id);
2022 if (err) {
2023 pr_err("%s: failed to synthesize 'transactions' event type\n",
2024 __func__);
2025 return err; 2262 return err;
2026 }
2027 pt->sample_transactions = true; 2263 pt->sample_transactions = true;
2264 pt->transactions_sample_type = attr.sample_type;
2028 pt->transactions_id = id; 2265 pt->transactions_id = id;
2266 intel_pt_set_event_name(evlist, id, "transactions");
2029 id += 1; 2267 id += 1;
2030 evlist__for_each_entry(evlist, evsel) {
2031 if (evsel->id && evsel->id[0] == pt->transactions_id) {
2032 if (evsel->name)
2033 zfree(&evsel->name);
2034 evsel->name = strdup("transactions");
2035 break;
2036 }
2037 }
2038 } 2268 }
2039 2269
2040 if (pt->synth_opts.branches) { 2270 attr.type = PERF_TYPE_SYNTH;
2041 attr.config = PERF_COUNT_HW_BRANCH_INSTRUCTIONS; 2271 attr.sample_type |= PERF_SAMPLE_RAW;
2042 attr.sample_period = 1; 2272
2043 attr.sample_type |= PERF_SAMPLE_ADDR; 2273 if (pt->synth_opts.ptwrites) {
2044 attr.sample_type &= ~(u64)PERF_SAMPLE_CALLCHAIN; 2274 attr.config = PERF_SYNTH_INTEL_PTWRITE;
2045 attr.sample_type &= ~(u64)PERF_SAMPLE_BRANCH_STACK; 2275 err = intel_pt_synth_event(session, "ptwrite", &attr, id);
2046 pr_debug("Synthesizing 'branches' event with id %" PRIu64 " sample type %#" PRIx64 "\n", 2276 if (err)
2047 id, (u64)attr.sample_type);
2048 err = intel_pt_synth_event(session, &attr, id);
2049 if (err) {
2050 pr_err("%s: failed to synthesize 'branches' event type\n",
2051 __func__);
2052 return err; 2277 return err;
2053 } 2278 pt->sample_ptwrites = true;
2054 pt->sample_branches = true; 2279 pt->ptwrites_sample_type = attr.sample_type;
2055 pt->branches_sample_type = attr.sample_type; 2280 pt->ptwrites_id = id;
2056 pt->branches_id = id; 2281 intel_pt_set_event_name(evlist, id, "ptwrite");
2282 id += 1;
2283 }
2284
2285 if (pt->synth_opts.pwr_events) {
2286 pt->sample_pwr_events = true;
2287 pt->pwr_events_sample_type = attr.sample_type;
2288
2289 attr.config = PERF_SYNTH_INTEL_CBR;
2290 err = intel_pt_synth_event(session, "cbr", &attr, id);
2291 if (err)
2292 return err;
2293 pt->cbr_id = id;
2294 intel_pt_set_event_name(evlist, id, "cbr");
2295 id += 1;
2296 }
2297
2298 if (pt->synth_opts.pwr_events && (evsel->attr.config & 0x10)) {
2299 attr.config = PERF_SYNTH_INTEL_MWAIT;
2300 err = intel_pt_synth_event(session, "mwait", &attr, id);
2301 if (err)
2302 return err;
2303 pt->mwait_id = id;
2304 intel_pt_set_event_name(evlist, id, "mwait");
2305 id += 1;
2306
2307 attr.config = PERF_SYNTH_INTEL_PWRE;
2308 err = intel_pt_synth_event(session, "pwre", &attr, id);
2309 if (err)
2310 return err;
2311 pt->pwre_id = id;
2312 intel_pt_set_event_name(evlist, id, "pwre");
2313 id += 1;
2314
2315 attr.config = PERF_SYNTH_INTEL_EXSTOP;
2316 err = intel_pt_synth_event(session, "exstop", &attr, id);
2317 if (err)
2318 return err;
2319 pt->exstop_id = id;
2320 intel_pt_set_event_name(evlist, id, "exstop");
2321 id += 1;
2322
2323 attr.config = PERF_SYNTH_INTEL_PWRX;
2324 err = intel_pt_synth_event(session, "pwrx", &attr, id);
2325 if (err)
2326 return err;
2327 pt->pwrx_id = id;
2328 intel_pt_set_event_name(evlist, id, "pwrx");
2329 id += 1;
2057 } 2330 }
2058 2331
2059 pt->synth_needs_swap = evsel->needs_swap; 2332 pt->synth_needs_swap = evsel->needs_swap;
@@ -2322,6 +2595,7 @@ int intel_pt_process_auxtrace_info(union perf_event *event,
2322 intel_pt_log("TSC frequency %"PRIu64"\n", tsc_freq); 2595 intel_pt_log("TSC frequency %"PRIu64"\n", tsc_freq);
2323 intel_pt_log("Maximum non-turbo ratio %u\n", 2596 intel_pt_log("Maximum non-turbo ratio %u\n",
2324 pt->max_non_turbo_ratio); 2597 pt->max_non_turbo_ratio);
2598 pt->cbr2khz = tsc_freq / pt->max_non_turbo_ratio / 1000;
2325 } 2599 }
2326 2600
2327 if (pt->synth_opts.calls) 2601 if (pt->synth_opts.calls)
diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c
index d97e014c3df3..5de2b86b9880 100644
--- a/tools/perf/util/machine.c
+++ b/tools/perf/util/machine.c
@@ -572,16 +572,7 @@ static struct dso *machine__findnew_module_dso(struct machine *machine,
572 if (dso == NULL) 572 if (dso == NULL)
573 goto out_unlock; 573 goto out_unlock;
574 574
575 if (machine__is_host(machine)) 575 dso__set_module_info(dso, m, machine);
576 dso->symtab_type = DSO_BINARY_TYPE__SYSTEM_PATH_KMODULE;
577 else
578 dso->symtab_type = DSO_BINARY_TYPE__GUEST_KMODULE;
579
580 /* _KMODULE_COMP should be next to _KMODULE */
581 if (m->kmod && m->comp)
582 dso->symtab_type++;
583
584 dso__set_short_name(dso, strdup(m->name), true);
585 dso__set_long_name(dso, strdup(filename), true); 576 dso__set_long_name(dso, strdup(filename), true);
586 } 577 }
587 578
@@ -1218,10 +1209,12 @@ int machine__create_kernel_maps(struct machine *machine)
1218 */ 1209 */
1219 map_groups__fixup_end(&machine->kmaps); 1210 map_groups__fixup_end(&machine->kmaps);
1220 1211
1221 if (machine__get_running_kernel_start(machine, &name, &addr)) { 1212 if (!machine__get_running_kernel_start(machine, &name, &addr)) {
1222 } else if (maps__set_kallsyms_ref_reloc_sym(machine->vmlinux_maps, name, addr)) { 1213 if (name &&
1223 machine__destroy_kernel_maps(machine); 1214 maps__set_kallsyms_ref_reloc_sym(machine->vmlinux_maps, name, addr)) {
1224 return -1; 1215 machine__destroy_kernel_maps(machine);
1216 return -1;
1217 }
1225 } 1218 }
1226 1219
1227 return 0; 1220 return 0;
diff --git a/tools/perf/util/pmu.h b/tools/perf/util/pmu.h
index ea7f450dc609..389e9729331f 100644
--- a/tools/perf/util/pmu.h
+++ b/tools/perf/util/pmu.h
@@ -2,6 +2,7 @@
2#define __PMU_H 2#define __PMU_H
3 3
4#include <linux/bitmap.h> 4#include <linux/bitmap.h>
5#include <linux/compiler.h>
5#include <linux/perf_event.h> 6#include <linux/perf_event.h>
6#include <stdbool.h> 7#include <stdbool.h>
7#include "evsel.h" 8#include "evsel.h"
@@ -83,8 +84,7 @@ void print_pmu_events(const char *event_glob, bool name_only, bool quiet,
83 bool long_desc, bool details_flag); 84 bool long_desc, bool details_flag);
84bool pmu_have_event(const char *pname, const char *name); 85bool pmu_have_event(const char *pname, const char *name);
85 86
86int perf_pmu__scan_file(struct perf_pmu *pmu, const char *name, const char *fmt, 87int perf_pmu__scan_file(struct perf_pmu *pmu, const char *name, const char *fmt, ...) __scanf(3, 4);
87 ...) __attribute__((format(scanf, 3, 4)));
88 88
89int perf_pmu__test(void); 89int perf_pmu__test(void);
90 90
diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c
index 84e7e698411e..a2670e9d652d 100644
--- a/tools/perf/util/probe-event.c
+++ b/tools/perf/util/probe-event.c
@@ -619,7 +619,7 @@ static int post_process_probe_trace_point(struct probe_trace_point *tp,
619 struct map *map, unsigned long offs) 619 struct map *map, unsigned long offs)
620{ 620{
621 struct symbol *sym; 621 struct symbol *sym;
622 u64 addr = tp->address + tp->offset - offs; 622 u64 addr = tp->address - offs;
623 623
624 sym = map__find_symbol(map, addr); 624 sym = map__find_symbol(map, addr);
625 if (!sym) 625 if (!sym)
diff --git a/tools/perf/util/probe-event.h b/tools/perf/util/probe-event.h
index 373842656fb6..5812947418dd 100644
--- a/tools/perf/util/probe-event.h
+++ b/tools/perf/util/probe-event.h
@@ -1,6 +1,7 @@
1#ifndef _PROBE_EVENT_H 1#ifndef _PROBE_EVENT_H
2#define _PROBE_EVENT_H 2#define _PROBE_EVENT_H
3 3
4#include <linux/compiler.h>
4#include <stdbool.h> 5#include <stdbool.h>
5#include "intlist.h" 6#include "intlist.h"
6 7
@@ -171,8 +172,7 @@ void arch__fix_tev_from_maps(struct perf_probe_event *pev,
171 struct symbol *sym); 172 struct symbol *sym);
172 173
173/* If there is no space to write, returns -E2BIG. */ 174/* If there is no space to write, returns -E2BIG. */
174int e_snprintf(char *str, size_t size, const char *format, ...) 175int e_snprintf(char *str, size_t size, const char *format, ...) __printf(3, 4);
175 __attribute__((format(printf, 3, 4)));
176 176
177/* Maximum index number of event-name postfix */ 177/* Maximum index number of event-name postfix */
178#define MAX_EVENT_INDEX 1024 178#define MAX_EVENT_INDEX 1024
diff --git a/tools/perf/util/scripting-engines/trace-event-python.c b/tools/perf/util/scripting-engines/trace-event-python.c
index 9d92af7d0718..57b7a00e6f16 100644
--- a/tools/perf/util/scripting-engines/trace-event-python.c
+++ b/tools/perf/util/scripting-engines/trace-event-python.c
@@ -28,6 +28,7 @@
28#include <stdbool.h> 28#include <stdbool.h>
29#include <errno.h> 29#include <errno.h>
30#include <linux/bitmap.h> 30#include <linux/bitmap.h>
31#include <linux/compiler.h>
31#include <linux/time64.h> 32#include <linux/time64.h>
32 33
33#include "../../perf.h" 34#include "../../perf.h"
@@ -84,7 +85,7 @@ struct tables {
84 85
85static struct tables tables_global; 86static struct tables tables_global;
86 87
87static void handler_call_die(const char *handler_name) NORETURN; 88static void handler_call_die(const char *handler_name) __noreturn;
88static void handler_call_die(const char *handler_name) 89static void handler_call_die(const char *handler_name)
89{ 90{
90 PyErr_Print(); 91 PyErr_Print();
@@ -1219,7 +1220,7 @@ static int python_generate_script(struct pevent *pevent, const char *outfile)
1219 fprintf(ofp, "# be retrieved using Python functions of the form " 1220 fprintf(ofp, "# be retrieved using Python functions of the form "
1220 "common_*(context).\n"); 1221 "common_*(context).\n");
1221 1222
1222 fprintf(ofp, "# See the perf-trace-python Documentation for the list " 1223 fprintf(ofp, "# See the perf-script-python Documentation for the list "
1223 "of available functions.\n\n"); 1224 "of available functions.\n\n");
1224 1225
1225 fprintf(ofp, "import os\n"); 1226 fprintf(ofp, "import os\n");
diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c
index 7dc1096264c5..d19c40a81040 100644
--- a/tools/perf/util/session.c
+++ b/tools/perf/util/session.c
@@ -2035,7 +2035,7 @@ int perf_session__cpu_bitmap(struct perf_session *session,
2035 2035
2036 if (!(evsel->attr.sample_type & PERF_SAMPLE_CPU)) { 2036 if (!(evsel->attr.sample_type & PERF_SAMPLE_CPU)) {
2037 pr_err("File does not contain CPU events. " 2037 pr_err("File does not contain CPU events. "
2038 "Remove -c option to proceed.\n"); 2038 "Remove -C option to proceed.\n");
2039 return -1; 2039 return -1;
2040 } 2040 }
2041 } 2041 }
diff --git a/tools/perf/util/sort.c b/tools/perf/util/sort.c
index 5762ae4e9e91..8b327c955a4f 100644
--- a/tools/perf/util/sort.c
+++ b/tools/perf/util/sort.c
@@ -2532,12 +2532,12 @@ static int setup_sort_list(struct perf_hpp_list *list, char *str,
2532 ret = sort_dimension__add(list, tok, evlist, level); 2532 ret = sort_dimension__add(list, tok, evlist, level);
2533 if (ret == -EINVAL) { 2533 if (ret == -EINVAL) {
2534 if (!cacheline_size && !strncasecmp(tok, "dcacheline", strlen(tok))) 2534 if (!cacheline_size && !strncasecmp(tok, "dcacheline", strlen(tok)))
2535 error("The \"dcacheline\" --sort key needs to know the cacheline size and it couldn't be determined on this system"); 2535 pr_err("The \"dcacheline\" --sort key needs to know the cacheline size and it couldn't be determined on this system");
2536 else 2536 else
2537 error("Invalid --sort key: `%s'", tok); 2537 pr_err("Invalid --sort key: `%s'", tok);
2538 break; 2538 break;
2539 } else if (ret == -ESRCH) { 2539 } else if (ret == -ESRCH) {
2540 error("Unknown --sort key: `%s'", tok); 2540 pr_err("Unknown --sort key: `%s'", tok);
2541 break; 2541 break;
2542 } 2542 }
2543 } 2543 }
@@ -2594,7 +2594,7 @@ static int setup_sort_order(struct perf_evlist *evlist)
2594 return 0; 2594 return 0;
2595 2595
2596 if (sort_order[1] == '\0') { 2596 if (sort_order[1] == '\0') {
2597 error("Invalid --sort key: `+'"); 2597 pr_err("Invalid --sort key: `+'");
2598 return -EINVAL; 2598 return -EINVAL;
2599 } 2599 }
2600 2600
@@ -2604,7 +2604,7 @@ static int setup_sort_order(struct perf_evlist *evlist)
2604 */ 2604 */
2605 if (asprintf(&new_sort_order, "%s,%s", 2605 if (asprintf(&new_sort_order, "%s,%s",
2606 get_default_sort_order(evlist), sort_order + 1) < 0) { 2606 get_default_sort_order(evlist), sort_order + 1) < 0) {
2607 error("Not enough memory to set up --sort"); 2607 pr_err("Not enough memory to set up --sort");
2608 return -ENOMEM; 2608 return -ENOMEM;
2609 } 2609 }
2610 2610
@@ -2668,7 +2668,7 @@ static int __setup_sorting(struct perf_evlist *evlist)
2668 2668
2669 str = strdup(sort_keys); 2669 str = strdup(sort_keys);
2670 if (str == NULL) { 2670 if (str == NULL) {
2671 error("Not enough memory to setup sort keys"); 2671 pr_err("Not enough memory to setup sort keys");
2672 return -ENOMEM; 2672 return -ENOMEM;
2673 } 2673 }
2674 2674
@@ -2678,7 +2678,7 @@ static int __setup_sorting(struct perf_evlist *evlist)
2678 if (!is_strict_order(field_order)) { 2678 if (!is_strict_order(field_order)) {
2679 str = setup_overhead(str); 2679 str = setup_overhead(str);
2680 if (str == NULL) { 2680 if (str == NULL) {
2681 error("Not enough memory to setup overhead keys"); 2681 pr_err("Not enough memory to setup overhead keys");
2682 return -ENOMEM; 2682 return -ENOMEM;
2683 } 2683 }
2684 } 2684 }
@@ -2834,10 +2834,10 @@ static int setup_output_list(struct perf_hpp_list *list, char *str)
2834 tok; tok = strtok_r(NULL, ", ", &tmp)) { 2834 tok; tok = strtok_r(NULL, ", ", &tmp)) {
2835 ret = output_field_add(list, tok); 2835 ret = output_field_add(list, tok);
2836 if (ret == -EINVAL) { 2836 if (ret == -EINVAL) {
2837 error("Invalid --fields key: `%s'", tok); 2837 pr_err("Invalid --fields key: `%s'", tok);
2838 break; 2838 break;
2839 } else if (ret == -ESRCH) { 2839 } else if (ret == -ESRCH) {
2840 error("Unknown --fields key: `%s'", tok); 2840 pr_err("Unknown --fields key: `%s'", tok);
2841 break; 2841 break;
2842 } 2842 }
2843 } 2843 }
@@ -2877,7 +2877,7 @@ static int __setup_output_field(void)
2877 2877
2878 strp = str = strdup(field_order); 2878 strp = str = strdup(field_order);
2879 if (str == NULL) { 2879 if (str == NULL) {
2880 error("Not enough memory to setup output fields"); 2880 pr_err("Not enough memory to setup output fields");
2881 return -ENOMEM; 2881 return -ENOMEM;
2882 } 2882 }
2883 2883
@@ -2885,7 +2885,7 @@ static int __setup_output_field(void)
2885 strp++; 2885 strp++;
2886 2886
2887 if (!strlen(strp)) { 2887 if (!strlen(strp)) {
2888 error("Invalid --fields key: `+'"); 2888 pr_err("Invalid --fields key: `+'");
2889 goto out; 2889 goto out;
2890 } 2890 }
2891 2891
diff --git a/tools/perf/util/srcline.c b/tools/perf/util/srcline.c
index df051a52393c..ebc88a74e67b 100644
--- a/tools/perf/util/srcline.c
+++ b/tools/perf/util/srcline.c
@@ -56,7 +56,10 @@ static int inline_list__append(char *filename, char *funcname, int line_nr,
56 } 56 }
57 } 57 }
58 58
59 list_add_tail(&ilist->list, &node->val); 59 if (callchain_param.order == ORDER_CALLEE)
60 list_add_tail(&ilist->list, &node->val);
61 else
62 list_add(&ilist->list, &node->val);
60 63
61 return 0; 64 return 0;
62} 65}
@@ -200,12 +203,14 @@ static void addr2line_cleanup(struct a2l_data *a2l)
200 203
201#define MAX_INLINE_NEST 1024 204#define MAX_INLINE_NEST 1024
202 205
203static void inline_list__reverse(struct inline_node *node) 206static int inline_list__append_dso_a2l(struct dso *dso,
207 struct inline_node *node)
204{ 208{
205 struct inline_list *ilist, *n; 209 struct a2l_data *a2l = dso->a2l;
210 char *funcname = a2l->funcname ? strdup(a2l->funcname) : NULL;
211 char *filename = a2l->filename ? strdup(a2l->filename) : NULL;
206 212
207 list_for_each_entry_safe_reverse(ilist, n, &node->val, list) 213 return inline_list__append(filename, funcname, a2l->line, node, dso);
208 list_move_tail(&ilist->list, &node->val);
209} 214}
210 215
211static int addr2line(const char *dso_name, u64 addr, 216static int addr2line(const char *dso_name, u64 addr,
@@ -230,36 +235,36 @@ static int addr2line(const char *dso_name, u64 addr,
230 235
231 bfd_map_over_sections(a2l->abfd, find_address_in_section, a2l); 236 bfd_map_over_sections(a2l->abfd, find_address_in_section, a2l);
232 237
233 if (a2l->found && unwind_inlines) { 238 if (!a2l->found)
239 return 0;
240
241 if (unwind_inlines) {
234 int cnt = 0; 242 int cnt = 0;
235 243
244 if (node && inline_list__append_dso_a2l(dso, node))
245 return 0;
246
236 while (bfd_find_inliner_info(a2l->abfd, &a2l->filename, 247 while (bfd_find_inliner_info(a2l->abfd, &a2l->filename,
237 &a2l->funcname, &a2l->line) && 248 &a2l->funcname, &a2l->line) &&
238 cnt++ < MAX_INLINE_NEST) { 249 cnt++ < MAX_INLINE_NEST) {
239 250
240 if (node != NULL) { 251 if (node != NULL) {
241 if (inline_list__append(strdup(a2l->filename), 252 if (inline_list__append_dso_a2l(dso, node))
242 strdup(a2l->funcname),
243 a2l->line, node,
244 dso) != 0)
245 return 0; 253 return 0;
254 // found at least one inline frame
255 ret = 1;
246 } 256 }
247 } 257 }
258 }
248 259
249 if ((node != NULL) && 260 if (file) {
250 (callchain_param.order != ORDER_CALLEE)) { 261 *file = a2l->filename ? strdup(a2l->filename) : NULL;
251 inline_list__reverse(node); 262 ret = *file ? 1 : 0;
252 }
253 } 263 }
254 264
255 if (a2l->found && a2l->filename) { 265 if (line)
256 *file = strdup(a2l->filename);
257 *line = a2l->line; 266 *line = a2l->line;
258 267
259 if (*file)
260 ret = 1;
261 }
262
263 return ret; 268 return ret;
264} 269}
265 270
@@ -278,8 +283,6 @@ void dso__free_a2l(struct dso *dso)
278static struct inline_node *addr2inlines(const char *dso_name, u64 addr, 283static struct inline_node *addr2inlines(const char *dso_name, u64 addr,
279 struct dso *dso) 284 struct dso *dso)
280{ 285{
281 char *file = NULL;
282 unsigned int line = 0;
283 struct inline_node *node; 286 struct inline_node *node;
284 287
285 node = zalloc(sizeof(*node)); 288 node = zalloc(sizeof(*node));
@@ -291,7 +294,7 @@ static struct inline_node *addr2inlines(const char *dso_name, u64 addr,
291 INIT_LIST_HEAD(&node->val); 294 INIT_LIST_HEAD(&node->val);
292 node->addr = addr; 295 node->addr = addr;
293 296
294 if (!addr2line(dso_name, addr, &file, &line, dso, TRUE, node)) 297 if (!addr2line(dso_name, addr, NULL, NULL, dso, TRUE, node))
295 goto out_free_inline_node; 298 goto out_free_inline_node;
296 299
297 if (list_empty(&node->val)) 300 if (list_empty(&node->val))
diff --git a/tools/perf/util/stat-shadow.c b/tools/perf/util/stat-shadow.c
index ac10cc675d39..719d6cb86952 100644
--- a/tools/perf/util/stat-shadow.c
+++ b/tools/perf/util/stat-shadow.c
@@ -44,6 +44,8 @@ static struct stats runtime_topdown_slots_issued[NUM_CTX][MAX_NR_CPUS];
44static struct stats runtime_topdown_slots_retired[NUM_CTX][MAX_NR_CPUS]; 44static struct stats runtime_topdown_slots_retired[NUM_CTX][MAX_NR_CPUS];
45static struct stats runtime_topdown_fetch_bubbles[NUM_CTX][MAX_NR_CPUS]; 45static struct stats runtime_topdown_fetch_bubbles[NUM_CTX][MAX_NR_CPUS];
46static struct stats runtime_topdown_recovery_bubbles[NUM_CTX][MAX_NR_CPUS]; 46static struct stats runtime_topdown_recovery_bubbles[NUM_CTX][MAX_NR_CPUS];
47static struct stats runtime_smi_num_stats[NUM_CTX][MAX_NR_CPUS];
48static struct stats runtime_aperf_stats[NUM_CTX][MAX_NR_CPUS];
47static struct rblist runtime_saved_values; 49static struct rblist runtime_saved_values;
48static bool have_frontend_stalled; 50static bool have_frontend_stalled;
49 51
@@ -157,6 +159,8 @@ void perf_stat__reset_shadow_stats(void)
157 memset(runtime_topdown_slots_issued, 0, sizeof(runtime_topdown_slots_issued)); 159 memset(runtime_topdown_slots_issued, 0, sizeof(runtime_topdown_slots_issued));
158 memset(runtime_topdown_fetch_bubbles, 0, sizeof(runtime_topdown_fetch_bubbles)); 160 memset(runtime_topdown_fetch_bubbles, 0, sizeof(runtime_topdown_fetch_bubbles));
159 memset(runtime_topdown_recovery_bubbles, 0, sizeof(runtime_topdown_recovery_bubbles)); 161 memset(runtime_topdown_recovery_bubbles, 0, sizeof(runtime_topdown_recovery_bubbles));
162 memset(runtime_smi_num_stats, 0, sizeof(runtime_smi_num_stats));
163 memset(runtime_aperf_stats, 0, sizeof(runtime_aperf_stats));
160 164
161 next = rb_first(&runtime_saved_values.entries); 165 next = rb_first(&runtime_saved_values.entries);
162 while (next) { 166 while (next) {
@@ -217,6 +221,10 @@ void perf_stat__update_shadow_stats(struct perf_evsel *counter, u64 *count,
217 update_stats(&runtime_dtlb_cache_stats[ctx][cpu], count[0]); 221 update_stats(&runtime_dtlb_cache_stats[ctx][cpu], count[0]);
218 else if (perf_evsel__match(counter, HW_CACHE, HW_CACHE_ITLB)) 222 else if (perf_evsel__match(counter, HW_CACHE, HW_CACHE_ITLB))
219 update_stats(&runtime_itlb_cache_stats[ctx][cpu], count[0]); 223 update_stats(&runtime_itlb_cache_stats[ctx][cpu], count[0]);
224 else if (perf_stat_evsel__is(counter, SMI_NUM))
225 update_stats(&runtime_smi_num_stats[ctx][cpu], count[0]);
226 else if (perf_stat_evsel__is(counter, APERF))
227 update_stats(&runtime_aperf_stats[ctx][cpu], count[0]);
220 228
221 if (counter->collect_stat) { 229 if (counter->collect_stat) {
222 struct saved_value *v = saved_value_lookup(counter, cpu, ctx, 230 struct saved_value *v = saved_value_lookup(counter, cpu, ctx,
@@ -592,6 +600,29 @@ static double td_be_bound(int ctx, int cpu)
592 return sanitize_val(1.0 - sum); 600 return sanitize_val(1.0 - sum);
593} 601}
594 602
603static void print_smi_cost(int cpu, struct perf_evsel *evsel,
604 struct perf_stat_output_ctx *out)
605{
606 double smi_num, aperf, cycles, cost = 0.0;
607 int ctx = evsel_context(evsel);
608 const char *color = NULL;
609
610 smi_num = avg_stats(&runtime_smi_num_stats[ctx][cpu]);
611 aperf = avg_stats(&runtime_aperf_stats[ctx][cpu]);
612 cycles = avg_stats(&runtime_cycles_stats[ctx][cpu]);
613
614 if ((cycles == 0) || (aperf == 0))
615 return;
616
617 if (smi_num)
618 cost = (aperf - cycles) / aperf * 100.00;
619
620 if (cost > 10)
621 color = PERF_COLOR_RED;
622 out->print_metric(out->ctx, color, "%8.1f%%", "SMI cycles%", cost);
623 out->print_metric(out->ctx, NULL, "%4.0f", "SMI#", smi_num);
624}
625
595void perf_stat__print_shadow_stats(struct perf_evsel *evsel, 626void perf_stat__print_shadow_stats(struct perf_evsel *evsel,
596 double avg, int cpu, 627 double avg, int cpu,
597 struct perf_stat_output_ctx *out) 628 struct perf_stat_output_ctx *out)
@@ -825,6 +856,8 @@ void perf_stat__print_shadow_stats(struct perf_evsel *evsel,
825 } 856 }
826 snprintf(unit_buf, sizeof(unit_buf), "%c/sec", unit); 857 snprintf(unit_buf, sizeof(unit_buf), "%c/sec", unit);
827 print_metric(ctxp, NULL, "%8.3f", unit_buf, ratio); 858 print_metric(ctxp, NULL, "%8.3f", unit_buf, ratio);
859 } else if (perf_stat_evsel__is(evsel, SMI_NUM)) {
860 print_smi_cost(cpu, evsel, out);
828 } else { 861 } else {
829 print_metric(ctxp, NULL, NULL, NULL, 0); 862 print_metric(ctxp, NULL, NULL, NULL, 0);
830 } 863 }
diff --git a/tools/perf/util/stat.c b/tools/perf/util/stat.c
index c58174443dc1..53b9a994a3dc 100644
--- a/tools/perf/util/stat.c
+++ b/tools/perf/util/stat.c
@@ -86,6 +86,8 @@ static const char *id_str[PERF_STAT_EVSEL_ID__MAX] = {
86 ID(TOPDOWN_SLOTS_RETIRED, topdown-slots-retired), 86 ID(TOPDOWN_SLOTS_RETIRED, topdown-slots-retired),
87 ID(TOPDOWN_FETCH_BUBBLES, topdown-fetch-bubbles), 87 ID(TOPDOWN_FETCH_BUBBLES, topdown-fetch-bubbles),
88 ID(TOPDOWN_RECOVERY_BUBBLES, topdown-recovery-bubbles), 88 ID(TOPDOWN_RECOVERY_BUBBLES, topdown-recovery-bubbles),
89 ID(SMI_NUM, msr/smi/),
90 ID(APERF, msr/aperf/),
89}; 91};
90#undef ID 92#undef ID
91 93
diff --git a/tools/perf/util/stat.h b/tools/perf/util/stat.h
index 0a65ae23f495..7522bf10b03e 100644
--- a/tools/perf/util/stat.h
+++ b/tools/perf/util/stat.h
@@ -22,6 +22,8 @@ enum perf_stat_evsel_id {
22 PERF_STAT_EVSEL_ID__TOPDOWN_SLOTS_RETIRED, 22 PERF_STAT_EVSEL_ID__TOPDOWN_SLOTS_RETIRED,
23 PERF_STAT_EVSEL_ID__TOPDOWN_FETCH_BUBBLES, 23 PERF_STAT_EVSEL_ID__TOPDOWN_FETCH_BUBBLES,
24 PERF_STAT_EVSEL_ID__TOPDOWN_RECOVERY_BUBBLES, 24 PERF_STAT_EVSEL_ID__TOPDOWN_RECOVERY_BUBBLES,
25 PERF_STAT_EVSEL_ID__SMI_NUM,
26 PERF_STAT_EVSEL_ID__APERF,
25 PERF_STAT_EVSEL_ID__MAX, 27 PERF_STAT_EVSEL_ID__MAX,
26}; 28};
27 29
diff --git a/tools/perf/util/strbuf.h b/tools/perf/util/strbuf.h
index 318424ea561d..802d743378af 100644
--- a/tools/perf/util/strbuf.h
+++ b/tools/perf/util/strbuf.h
@@ -42,6 +42,7 @@
42#include <stdarg.h> 42#include <stdarg.h>
43#include <stddef.h> 43#include <stddef.h>
44#include <string.h> 44#include <string.h>
45#include <linux/compiler.h>
45#include <sys/types.h> 46#include <sys/types.h>
46 47
47extern char strbuf_slopbuf[]; 48extern char strbuf_slopbuf[];
@@ -85,8 +86,7 @@ static inline int strbuf_addstr(struct strbuf *sb, const char *s) {
85 return strbuf_add(sb, s, strlen(s)); 86 return strbuf_add(sb, s, strlen(s));
86} 87}
87 88
88__attribute__((format(printf,2,3))) 89int strbuf_addf(struct strbuf *sb, const char *fmt, ...) __printf(2, 3);
89int strbuf_addf(struct strbuf *sb, const char *fmt, ...);
90 90
91/* XXX: if read fails, any partial read is undone */ 91/* XXX: if read fails, any partial read is undone */
92ssize_t strbuf_read(struct strbuf *, int fd, ssize_t hint); 92ssize_t strbuf_read(struct strbuf *, int fd, ssize_t hint);
diff --git a/tools/perf/util/symbol-elf.c b/tools/perf/util/symbol-elf.c
index e7ee47f7377a..502505cf236a 100644
--- a/tools/perf/util/symbol-elf.c
+++ b/tools/perf/util/symbol-elf.c
@@ -637,43 +637,6 @@ static int dso__swap_init(struct dso *dso, unsigned char eidata)
637 return 0; 637 return 0;
638} 638}
639 639
640static int decompress_kmodule(struct dso *dso, const char *name,
641 enum dso_binary_type type)
642{
643 int fd = -1;
644 char tmpbuf[] = "/tmp/perf-kmod-XXXXXX";
645 struct kmod_path m;
646
647 if (type != DSO_BINARY_TYPE__SYSTEM_PATH_KMODULE_COMP &&
648 type != DSO_BINARY_TYPE__GUEST_KMODULE_COMP &&
649 type != DSO_BINARY_TYPE__BUILD_ID_CACHE)
650 return -1;
651
652 if (type == DSO_BINARY_TYPE__BUILD_ID_CACHE)
653 name = dso->long_name;
654
655 if (kmod_path__parse_ext(&m, name) || !m.comp)
656 return -1;
657
658 fd = mkstemp(tmpbuf);
659 if (fd < 0) {
660 dso->load_errno = errno;
661 goto out;
662 }
663
664 if (!decompress_to_file(m.ext, name, fd)) {
665 dso->load_errno = DSO_LOAD_ERRNO__DECOMPRESSION_FAILURE;
666 close(fd);
667 fd = -1;
668 }
669
670 unlink(tmpbuf);
671
672out:
673 free(m.ext);
674 return fd;
675}
676
677bool symsrc__possibly_runtime(struct symsrc *ss) 640bool symsrc__possibly_runtime(struct symsrc *ss)
678{ 641{
679 return ss->dynsym || ss->opdsec; 642 return ss->dynsym || ss->opdsec;
@@ -705,9 +668,11 @@ int symsrc__init(struct symsrc *ss, struct dso *dso, const char *name,
705 int fd; 668 int fd;
706 669
707 if (dso__needs_decompress(dso)) { 670 if (dso__needs_decompress(dso)) {
708 fd = decompress_kmodule(dso, name, type); 671 fd = dso__decompress_kmodule_fd(dso, name);
709 if (fd < 0) 672 if (fd < 0)
710 return -1; 673 return -1;
674
675 type = dso->symtab_type;
711 } else { 676 } else {
712 fd = open(name, O_RDONLY); 677 fd = open(name, O_RDONLY);
713 if (fd < 0) { 678 if (fd < 0) {
diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c
index 8f2b068ff756..e7a98dbd2aed 100644
--- a/tools/perf/util/symbol.c
+++ b/tools/perf/util/symbol.c
@@ -1562,10 +1562,6 @@ int dso__load(struct dso *dso, struct map *map)
1562 if (!runtime_ss && syms_ss) 1562 if (!runtime_ss && syms_ss)
1563 runtime_ss = syms_ss; 1563 runtime_ss = syms_ss;
1564 1564
1565 if (syms_ss && syms_ss->type == DSO_BINARY_TYPE__BUILD_ID_CACHE)
1566 if (dso__build_id_is_kmod(dso, name, PATH_MAX))
1567 kmod = true;
1568
1569 if (syms_ss) 1565 if (syms_ss)
1570 ret = dso__load_sym(dso, map, syms_ss, runtime_ss, kmod); 1566 ret = dso__load_sym(dso, map, syms_ss, runtime_ss, kmod);
1571 else 1567 else
diff --git a/tools/perf/util/trace-event-parse.c b/tools/perf/util/trace-event-parse.c
index 746bbee645d9..e0a6e9a6a053 100644
--- a/tools/perf/util/trace-event-parse.c
+++ b/tools/perf/util/trace-event-parse.c
@@ -24,7 +24,7 @@
24#include <errno.h> 24#include <errno.h>
25 25
26#include "../perf.h" 26#include "../perf.h"
27#include "util.h" 27#include "debug.h"
28#include "trace-event.h" 28#include "trace-event.h"
29 29
30#include "sane_ctype.h" 30#include "sane_ctype.h"
@@ -150,7 +150,7 @@ void parse_ftrace_printk(struct pevent *pevent,
150 while (line) { 150 while (line) {
151 addr_str = strtok_r(line, ":", &fmt); 151 addr_str = strtok_r(line, ":", &fmt);
152 if (!addr_str) { 152 if (!addr_str) {
153 warning("printk format with empty entry"); 153 pr_warning("printk format with empty entry");
154 break; 154 break;
155 } 155 }
156 addr = strtoull(addr_str, NULL, 16); 156 addr = strtoull(addr_str, NULL, 16);
diff --git a/tools/perf/util/unwind-libdw.c b/tools/perf/util/unwind-libdw.c
index f90e11a555b2..7755a5e0fe5e 100644
--- a/tools/perf/util/unwind-libdw.c
+++ b/tools/perf/util/unwind-libdw.c
@@ -39,6 +39,14 @@ static int __report_module(struct addr_location *al, u64 ip,
39 return 0; 39 return 0;
40 40
41 mod = dwfl_addrmodule(ui->dwfl, ip); 41 mod = dwfl_addrmodule(ui->dwfl, ip);
42 if (mod) {
43 Dwarf_Addr s;
44
45 dwfl_module_info(mod, NULL, &s, NULL, NULL, NULL, NULL, NULL);
46 if (s != al->map->start)
47 mod = 0;
48 }
49
42 if (!mod) 50 if (!mod)
43 mod = dwfl_report_elf(ui->dwfl, dso->short_name, 51 mod = dwfl_report_elf(ui->dwfl, dso->short_name,
44 dso->long_name, -1, al->map->start, 52 dso->long_name, -1, al->map->start,
@@ -168,12 +176,24 @@ frame_callback(Dwfl_Frame *state, void *arg)
168{ 176{
169 struct unwind_info *ui = arg; 177 struct unwind_info *ui = arg;
170 Dwarf_Addr pc; 178 Dwarf_Addr pc;
179 bool isactivation;
171 180
172 if (!dwfl_frame_pc(state, &pc, NULL)) { 181 if (!dwfl_frame_pc(state, &pc, NULL)) {
173 pr_err("%s", dwfl_errmsg(-1)); 182 pr_err("%s", dwfl_errmsg(-1));
174 return DWARF_CB_ABORT; 183 return DWARF_CB_ABORT;
175 } 184 }
176 185
186 // report the module before we query for isactivation
187 report_module(pc, ui);
188
189 if (!dwfl_frame_pc(state, &pc, &isactivation)) {
190 pr_err("%s", dwfl_errmsg(-1));
191 return DWARF_CB_ABORT;
192 }
193
194 if (!isactivation)
195 --pc;
196
177 return entry(pc, ui) || !(--ui->max_stack) ? 197 return entry(pc, ui) || !(--ui->max_stack) ?
178 DWARF_CB_ABORT : DWARF_CB_OK; 198 DWARF_CB_ABORT : DWARF_CB_OK;
179} 199}
@@ -220,7 +240,7 @@ int unwind__get_entries(unwind_entry_cb_t cb, void *arg,
220 240
221 err = dwfl_getthread_frames(ui->dwfl, thread->tid, frame_callback, ui); 241 err = dwfl_getthread_frames(ui->dwfl, thread->tid, frame_callback, ui);
222 242
223 if (err && !ui->max_stack) 243 if (err && ui->max_stack != max_stack)
224 err = 0; 244 err = 0;
225 245
226 /* 246 /*
diff --git a/tools/perf/util/unwind-libunwind-local.c b/tools/perf/util/unwind-libunwind-local.c
index f8455bed6e65..672c2ada9357 100644
--- a/tools/perf/util/unwind-libunwind-local.c
+++ b/tools/perf/util/unwind-libunwind-local.c
@@ -692,6 +692,17 @@ static int get_entries(struct unwind_info *ui, unwind_entry_cb_t cb,
692 692
693 while (!ret && (unw_step(&c) > 0) && i < max_stack) { 693 while (!ret && (unw_step(&c) > 0) && i < max_stack) {
694 unw_get_reg(&c, UNW_REG_IP, &ips[i]); 694 unw_get_reg(&c, UNW_REG_IP, &ips[i]);
695
696 /*
697 * Decrement the IP for any non-activation frames.
698 * this is required to properly find the srcline
699 * for caller frames.
700 * See also the documentation for dwfl_frame_pc(),
701 * which this code tries to replicate.
702 */
703 if (unw_is_signal_frame(&c) <= 0)
704 --ips[i];
705
695 ++i; 706 ++i;
696 } 707 }
697 708
diff --git a/tools/perf/util/usage.c b/tools/perf/util/usage.c
index 996046a66fe5..6cc9d9888ce0 100644
--- a/tools/perf/util/usage.c
+++ b/tools/perf/util/usage.c
@@ -9,75 +9,17 @@
9#include "util.h" 9#include "util.h"
10#include "debug.h" 10#include "debug.h"
11 11
12static void report(const char *prefix, const char *err, va_list params) 12static __noreturn void usage_builtin(const char *err)
13{
14 char msg[1024];
15 vsnprintf(msg, sizeof(msg), err, params);
16 fprintf(stderr, " %s%s\n", prefix, msg);
17}
18
19static NORETURN void usage_builtin(const char *err)
20{ 13{
21 fprintf(stderr, "\n Usage: %s\n", err); 14 fprintf(stderr, "\n Usage: %s\n", err);
22 exit(129); 15 exit(129);
23} 16}
24 17
25static NORETURN void die_builtin(const char *err, va_list params)
26{
27 report(" Fatal: ", err, params);
28 exit(128);
29}
30
31static void error_builtin(const char *err, va_list params)
32{
33 report(" Error: ", err, params);
34}
35
36static void warn_builtin(const char *warn, va_list params)
37{
38 report(" Warning: ", warn, params);
39}
40
41/* If we are in a dlopen()ed .so write to a global variable would segfault 18/* If we are in a dlopen()ed .so write to a global variable would segfault
42 * (ugh), so keep things static. */ 19 * (ugh), so keep things static. */
43static void (*usage_routine)(const char *err) NORETURN = usage_builtin; 20static void (*usage_routine)(const char *err) __noreturn = usage_builtin;
44static void (*error_routine)(const char *err, va_list params) = error_builtin;
45static void (*warn_routine)(const char *err, va_list params) = warn_builtin;
46
47void set_warning_routine(void (*routine)(const char *err, va_list params))
48{
49 warn_routine = routine;
50}
51 21
52void usage(const char *err) 22void usage(const char *err)
53{ 23{
54 usage_routine(err); 24 usage_routine(err);
55} 25}
56
57void die(const char *err, ...)
58{
59 va_list params;
60
61 va_start(params, err);
62 die_builtin(err, params);
63 va_end(params);
64}
65
66int error(const char *err, ...)
67{
68 va_list params;
69
70 va_start(params, err);
71 error_routine(err, params);
72 va_end(params);
73 return -1;
74}
75
76void warning(const char *warn, ...)
77{
78 va_list params;
79
80 va_start(params, warn);
81 warn_routine(warn, params);
82 va_end(params);
83}
diff --git a/tools/perf/util/util.c b/tools/perf/util/util.c
index 28c9f335006c..988111e0bab5 100644
--- a/tools/perf/util/util.c
+++ b/tools/perf/util/util.c
@@ -343,43 +343,6 @@ int perf_event_paranoid(void)
343 343
344 return value; 344 return value;
345} 345}
346
347bool find_process(const char *name)
348{
349 size_t len = strlen(name);
350 DIR *dir;
351 struct dirent *d;
352 int ret = -1;
353
354 dir = opendir(procfs__mountpoint());
355 if (!dir)
356 return false;
357
358 /* Walk through the directory. */
359 while (ret && (d = readdir(dir)) != NULL) {
360 char path[PATH_MAX];
361 char *data;
362 size_t size;
363
364 if ((d->d_type != DT_DIR) ||
365 !strcmp(".", d->d_name) ||
366 !strcmp("..", d->d_name))
367 continue;
368
369 scnprintf(path, sizeof(path), "%s/%s/comm",
370 procfs__mountpoint(), d->d_name);
371
372 if (filename__read_str(path, &data, &size))
373 continue;
374
375 ret = strncmp(name, data, len);
376 free(data);
377 }
378
379 closedir(dir);
380 return ret ? false : true;
381}
382
383static int 346static int
384fetch_ubuntu_kernel_version(unsigned int *puint) 347fetch_ubuntu_kernel_version(unsigned int *puint)
385{ 348{
@@ -387,8 +350,12 @@ fetch_ubuntu_kernel_version(unsigned int *puint)
387 size_t line_len = 0; 350 size_t line_len = 0;
388 char *ptr, *line = NULL; 351 char *ptr, *line = NULL;
389 int version, patchlevel, sublevel, err; 352 int version, patchlevel, sublevel, err;
390 FILE *vsig = fopen("/proc/version_signature", "r"); 353 FILE *vsig;
354
355 if (!puint)
356 return 0;
391 357
358 vsig = fopen("/proc/version_signature", "r");
392 if (!vsig) { 359 if (!vsig) {
393 pr_debug("Open /proc/version_signature failed: %s\n", 360 pr_debug("Open /proc/version_signature failed: %s\n",
394 strerror(errno)); 361 strerror(errno));
@@ -418,8 +385,7 @@ fetch_ubuntu_kernel_version(unsigned int *puint)
418 goto errout; 385 goto errout;
419 } 386 }
420 387
421 if (puint) 388 *puint = (version << 16) + (patchlevel << 8) + sublevel;
422 *puint = (version << 16) + (patchlevel << 8) + sublevel;
423 err = 0; 389 err = 0;
424errout: 390errout:
425 free(line); 391 free(line);
@@ -446,6 +412,9 @@ fetch_kernel_version(unsigned int *puint, char *str,
446 str[str_size - 1] = '\0'; 412 str[str_size - 1] = '\0';
447 } 413 }
448 414
415 if (!puint || int_ver_ready)
416 return 0;
417
449 err = sscanf(utsname.release, "%d.%d.%d", 418 err = sscanf(utsname.release, "%d.%d.%d",
450 &version, &patchlevel, &sublevel); 419 &version, &patchlevel, &sublevel);
451 420
@@ -455,8 +424,7 @@ fetch_kernel_version(unsigned int *puint, char *str,
455 return -1; 424 return -1;
456 } 425 }
457 426
458 if (puint && !int_ver_ready) 427 *puint = (version << 16) + (patchlevel << 8) + sublevel;
459 *puint = (version << 16) + (patchlevel << 8) + sublevel;
460 return 0; 428 return 0;
461} 429}
462 430
diff --git a/tools/perf/util/util.h b/tools/perf/util/util.h
index 5dfb9bb6482d..2c9e58a45310 100644
--- a/tools/perf/util/util.h
+++ b/tools/perf/util/util.h
@@ -1,7 +1,6 @@
1#ifndef GIT_COMPAT_UTIL_H 1#ifndef GIT_COMPAT_UTIL_H
2#define GIT_COMPAT_UTIL_H 2#define GIT_COMPAT_UTIL_H
3 3
4#define _ALL_SOURCE 1
5#define _BSD_SOURCE 1 4#define _BSD_SOURCE 1
6/* glibc 2.20 deprecates _BSD_SOURCE in favour of _DEFAULT_SOURCE */ 5/* glibc 2.20 deprecates _BSD_SOURCE in favour of _DEFAULT_SOURCE */
7#define _DEFAULT_SOURCE 1 6#define _DEFAULT_SOURCE 1
@@ -11,24 +10,12 @@
11#include <stddef.h> 10#include <stddef.h>
12#include <stdlib.h> 11#include <stdlib.h>
13#include <stdarg.h> 12#include <stdarg.h>
13#include <linux/compiler.h>
14#include <linux/types.h> 14#include <linux/types.h>
15 15
16#ifdef __GNUC__
17#define NORETURN __attribute__((__noreturn__))
18#else
19#define NORETURN
20#ifndef __attribute__
21#define __attribute__(x)
22#endif
23#endif
24
25/* General helper functions */ 16/* General helper functions */
26void usage(const char *err) NORETURN; 17void usage(const char *err) __noreturn;
27void die(const char *err, ...) NORETURN __attribute__((format (printf, 1, 2))); 18void die(const char *err, ...) __noreturn __printf(1, 2);
28int error(const char *err, ...) __attribute__((format (printf, 1, 2)));
29void warning(const char *err, ...) __attribute__((format (printf, 1, 2)));
30
31void set_warning_routine(void (*routine)(const char *err, va_list params));
32 19
33static inline void *zalloc(size_t size) 20static inline void *zalloc(size_t size)
34{ 21{
@@ -57,8 +44,6 @@ int hex2u64(const char *ptr, u64 *val);
57extern unsigned int page_size; 44extern unsigned int page_size;
58extern int cacheline_size; 45extern int cacheline_size;
59 46
60bool find_process(const char *name);
61
62int fetch_kernel_version(unsigned int *puint, 47int fetch_kernel_version(unsigned int *puint,
63 char *str, size_t str_sz); 48 char *str, size_t str_sz);
64#define KVER_VERSION(x) (((x) >> 16) & 0xff) 49#define KVER_VERSION(x) (((x) >> 16) & 0xff)