aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf
diff options
context:
space:
mode:
authorIngo Molnar <mingo@kernel.org>2017-07-01 04:39:25 -0400
committerIngo Molnar <mingo@kernel.org>2017-07-01 04:39:25 -0400
commit23acd3e1a0a377cf3730ccb753aa1fdc50378396 (patch)
treea80d7cfd2be43d77af659d5f309a5032be5e0662 /tools/perf
parente91c8d97eac74e603481840d950536bcb62b471b (diff)
parent644e0840ad4615e032d67adec6ee60f821b669fe (diff)
Merge tag 'perf-core-for-mingo-4.13-20170630' of git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux into perf/core
Pull perf/core improvements and fixes from Arnaldo Carvalho de Melo: Intel PT enhancements: - Support "ptwrite" instruction, a way to stuff 32 or 64 bit values into the Intel PT trace (Adrian Hunter) - Support power events in Intel PT to report changes to C-state (Adrian Hunter) - Synthesize Intel PT events as PERF_RECORD_SAMPLE records with a perf_event_attr.type (PERF_TYPE_SYNTH) just after the range used by the kernel, i.e. right after what is allocated for PMUs, at INT_MAX + 1U, attr.config will have the identification for the synthesized event and the PERF_SAMPLE_RAW payload will have its fields (Adrian Hunter) Infrastructure changes: - Remove warning() and error(), using instead pr_warning() and pr_error(), consolidating error reporting (Arnaldo Carvalho de Melo) - Add platform dependency to 'perf test 15' (Thomas Richter) Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> Signed-off-by: Ingo Molnar <mingo@kernel.org>
Diffstat (limited to 'tools/perf')
-rw-r--r--tools/perf/Documentation/intel-pt.txt42
-rw-r--r--tools/perf/Documentation/itrace.txt8
-rw-r--r--tools/perf/Documentation/perf-script.txt6
-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/builtin-c2c.c4
-rw-r--r--tools/perf/builtin-diff.c5
-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.c205
-rw-r--r--tools/perf/builtin-stat.c4
-rw-r--r--tools/perf/builtin-top.c2
-rw-r--r--tools/perf/jvmti/jvmti_agent.c2
-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/attr.c10
-rw-r--r--tools/perf/tests/attr.py48
-rw-r--r--tools/perf/tests/parse-events.c13
-rw-r--r--tools/perf/util/auxtrace.c18
-rw-r--r--tools/perf/util/auxtrace.h6
-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/event.h121
-rw-r--r--tools/perf/util/help-unknown-cmd.c2
-rw-r--r--tools/perf/util/intel-pt-decoder/intel-pt-decoder.c14
-rw-r--r--tools/perf/util/intel-pt-decoder/x86-opcode-map.txt2
-rw-r--r--tools/perf/util/intel-pt.c623
-rw-r--r--tools/perf/util/sort.c22
-rw-r--r--tools/perf/util/trace-event-parse.c4
-rw-r--r--tools/perf/util/usage.c58
-rw-r--r--tools/perf/util/util.h4
37 files changed, 1197 insertions, 361 deletions
diff --git a/tools/perf/Documentation/intel-pt.txt b/tools/perf/Documentation/intel-pt.txt
index d157dee7a4ec..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.
@@ -710,13 +713,15 @@ Having no option is the same as
710 713
711which, in turn, is the same as 714which, in turn, is the same as
712 715
713 --itrace=ibxe 716 --itrace=ibxwpe
714 717
715The letters are: 718The letters are:
716 719
717 i synthesize "instructions" events 720 i synthesize "instructions" events
718 b synthesize "branches" events 721 b synthesize "branches" events
719 x synthesize "transactions" events 722 x synthesize "transactions" events
723 w synthesize "ptwrite" events
724 p synthesize "power" events
720 c synthesize branches events (calls only) 725 c synthesize branches events (calls only)
721 r synthesize branches events (returns only) 726 r synthesize branches events (returns only)
722 e synthesize tracing error events 727 e synthesize tracing error events
@@ -735,7 +740,40 @@ and "r" can be combined to get calls and returns.
735'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
736tranasaction start, commit or abort. 741tranasaction start, commit or abort.
737 742
738Error 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
739are 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
740picture or not. 778picture or not.
741 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-script.txt b/tools/perf/Documentation/perf-script.txt
index e2468ed6a307..5ee8796be96e 100644
--- a/tools/perf/Documentation/perf-script.txt
+++ b/tools/perf/Documentation/perf-script.txt
@@ -117,7 +117,8 @@ OPTIONS
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, brstackoff, 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
@@ -193,6 +194,9 @@ OPTIONS
193 instruction bytes and the instruction length of the current 194 instruction bytes and the instruction length of the current
194 instruction. 195 instruction.
195 196
197 The synth field is used by synthesized events which may be created when
198 Instruction Trace decoding.
199
196 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.
197 i.e., -F "" is not allowed. 201 i.e., -F "" is not allowed.
198 202
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/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-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-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 4bce7d8679cb..83cdc0a61fd6 100644
--- a/tools/perf/builtin-script.c
+++ b/tools/perf/builtin-script.c
@@ -86,6 +86,7 @@ enum perf_output_field {
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, 88 PERF_OUTPUT_BRSTACKOFF = 1U << 24,
89 PERF_OUTPUT_SYNTH = 1U << 25,
89}; 90};
90 91
91struct output_option { 92struct output_option {
@@ -117,6 +118,12 @@ struct output_option {
117 {.str = "insnlen", .field = PERF_OUTPUT_INSNLEN}, 118 {.str = "insnlen", .field = PERF_OUTPUT_INSNLEN},
118 {.str = "brstackinsn", .field = PERF_OUTPUT_BRSTACKINSN}, 119 {.str = "brstackinsn", .field = PERF_OUTPUT_BRSTACKINSN},
119 {.str = "brstackoff", .field = PERF_OUTPUT_BRSTACKOFF}, 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
120}; 127};
121 128
122/* default set to maintain compatibility with current format */ 129/* default set to maintain compatibility with current format */
@@ -126,7 +133,7 @@ static struct {
126 unsigned int print_ip_opts; 133 unsigned int print_ip_opts;
127 u64 fields; 134 u64 fields;
128 u64 invalid_fields; 135 u64 invalid_fields;
129} output[PERF_TYPE_MAX] = { 136} output[OUTPUT_TYPE_MAX] = {
130 137
131 [PERF_TYPE_HARDWARE] = { 138 [PERF_TYPE_HARDWARE] = {
132 .user_set = false, 139 .user_set = false,
@@ -184,12 +191,44 @@ static struct {
184 191
185 .invalid_fields = PERF_OUTPUT_TRACE | PERF_OUTPUT_BPF_OUTPUT, 192 .invalid_fields = PERF_OUTPUT_TRACE | PERF_OUTPUT_BPF_OUTPUT,
186 }, 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 },
187}; 206};
188 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
189static bool output_set_by_user(void) 228static bool output_set_by_user(void)
190{ 229{
191 int j; 230 int j;
192 for (j = 0; j < PERF_TYPE_MAX; ++j) { 231 for (j = 0; j < OUTPUT_TYPE_MAX; ++j) {
193 if (output[j].user_set) 232 if (output[j].user_set)
194 return true; 233 return true;
195 } 234 }
@@ -210,7 +249,7 @@ static const char *output_field2str(enum perf_output_field field)
210 return str; 249 return str;
211} 250}
212 251
213#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)
214 253
215static int perf_evsel__do_check_stype(struct perf_evsel *evsel, 254static int perf_evsel__do_check_stype(struct perf_evsel *evsel,
216 u64 sample_type, const char *sample_msg, 255 u64 sample_type, const char *sample_msg,
@@ -218,7 +257,7 @@ static int perf_evsel__do_check_stype(struct perf_evsel *evsel,
218 bool allow_user_set) 257 bool allow_user_set)
219{ 258{
220 struct perf_event_attr *attr = &evsel->attr; 259 struct perf_event_attr *attr = &evsel->attr;
221 int type = attr->type; 260 int type = output_type(attr->type);
222 const char *evname; 261 const char *evname;
223 262
224 if (attr->sample_type & sample_type) 263 if (attr->sample_type & sample_type)
@@ -348,7 +387,7 @@ static int perf_evsel__check_attr(struct perf_evsel *evsel,
348 387
349static void set_print_ip_opts(struct perf_event_attr *attr) 388static void set_print_ip_opts(struct perf_event_attr *attr)
350{ 389{
351 unsigned int type = attr->type; 390 unsigned int type = output_type(attr->type);
352 391
353 output[type].print_ip_opts = 0; 392 output[type].print_ip_opts = 0;
354 if (PRINT_FIELD(IP)) 393 if (PRINT_FIELD(IP))
@@ -376,14 +415,15 @@ static int perf_session__check_output_opt(struct perf_session *session)
376 unsigned int j; 415 unsigned int j;
377 struct perf_evsel *evsel; 416 struct perf_evsel *evsel;
378 417
379 for (j = 0; j < PERF_TYPE_MAX; ++j) { 418 for (j = 0; j < OUTPUT_TYPE_MAX; ++j) {
380 evsel = perf_session__find_first_evtype(session, j); 419 evsel = perf_session__find_first_evtype(session, attr_type(j));
381 420
382 /* 421 /*
383 * 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
384 * exist if user explicitly includes it on the command line 423 * exist if user explicitly includes it on the command line
385 */ 424 */
386 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) {
387 pr_err("%s events do not exist. " 427 pr_err("%s events do not exist. "
388 "Remove corresponding -F option to proceed.\n", 428 "Remove corresponding -F option to proceed.\n",
389 event_type(j)); 429 event_type(j));
@@ -989,6 +1029,7 @@ static void print_sample_bts(struct perf_sample *sample,
989 struct machine *machine) 1029 struct machine *machine)
990{ 1030{
991 struct perf_event_attr *attr = &evsel->attr; 1031 struct perf_event_attr *attr = &evsel->attr;
1032 unsigned int type = output_type(attr->type);
992 bool print_srcline_last = false; 1033 bool print_srcline_last = false;
993 1034
994 if (PRINT_FIELD(CALLINDENT)) 1035 if (PRINT_FIELD(CALLINDENT))
@@ -996,7 +1037,7 @@ static void print_sample_bts(struct perf_sample *sample,
996 1037
997 /* print branch_from information */ 1038 /* print branch_from information */
998 if (PRINT_FIELD(IP)) { 1039 if (PRINT_FIELD(IP)) {
999 unsigned int print_opts = output[attr->type].print_ip_opts; 1040 unsigned int print_opts = output[type].print_ip_opts;
1000 struct callchain_cursor *cursor = NULL; 1041 struct callchain_cursor *cursor = NULL;
1001 1042
1002 if (symbol_conf.use_callchain && sample->callchain && 1043 if (symbol_conf.use_callchain && sample->callchain &&
@@ -1019,7 +1060,7 @@ static void print_sample_bts(struct perf_sample *sample,
1019 /* print branch_to information */ 1060 /* print branch_to information */
1020 if (PRINT_FIELD(ADDR) || 1061 if (PRINT_FIELD(ADDR) ||
1021 ((evsel->attr.sample_type & PERF_SAMPLE_ADDR) && 1062 ((evsel->attr.sample_type & PERF_SAMPLE_ADDR) &&
1022 !output[attr->type].user_set)) { 1063 !output[type].user_set)) {
1023 printf(" => "); 1064 printf(" => ");
1024 print_sample_addr(sample, thread, attr); 1065 print_sample_addr(sample, thread, attr);
1025 } 1066 }
@@ -1162,6 +1203,127 @@ static void print_sample_bpf_output(struct perf_sample *sample)
1162 (char *)(sample->raw_data)); 1203 (char *)(sample->raw_data));
1163} 1204}
1164 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
1165struct perf_script { 1327struct perf_script {
1166 struct perf_tool tool; 1328 struct perf_tool tool;
1167 struct perf_session *session; 1329 struct perf_session *session;
@@ -1215,8 +1377,9 @@ static void process_event(struct perf_script *script,
1215{ 1377{
1216 struct thread *thread = al->thread; 1378 struct thread *thread = al->thread;
1217 struct perf_event_attr *attr = &evsel->attr; 1379 struct perf_event_attr *attr = &evsel->attr;
1380 unsigned int type = output_type(attr->type);
1218 1381
1219 if (output[attr->type].fields == 0) 1382 if (output[type].fields == 0)
1220 return; 1383 return;
1221 1384
1222 print_sample_start(sample, thread, evsel); 1385 print_sample_start(sample, thread, evsel);
@@ -1245,6 +1408,10 @@ static void process_event(struct perf_script *script,
1245 if (PRINT_FIELD(TRACE)) 1408 if (PRINT_FIELD(TRACE))
1246 event_format__print(evsel->tp_format, sample->cpu, 1409 event_format__print(evsel->tp_format, sample->cpu,
1247 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
1248 if (PRINT_FIELD(ADDR)) 1415 if (PRINT_FIELD(ADDR))
1249 print_sample_addr(sample, thread, attr); 1416 print_sample_addr(sample, thread, attr);
1250 1417
@@ -1263,7 +1430,7 @@ static void process_event(struct perf_script *script,
1263 cursor = &callchain_cursor; 1430 cursor = &callchain_cursor;
1264 1431
1265 putchar(cursor ? '\n' : ' '); 1432 putchar(cursor ? '\n' : ' ');
1266 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);
1267 } 1434 }
1268 1435
1269 if (PRINT_FIELD(IREGS)) 1436 if (PRINT_FIELD(IREGS))
@@ -1410,7 +1577,8 @@ static int process_attr(struct perf_tool *tool, union perf_event *event,
1410 evlist = *pevlist; 1577 evlist = *pevlist;
1411 evsel = perf_evlist__last(*pevlist); 1578 evsel = perf_evlist__last(*pevlist);
1412 1579
1413 if (evsel->attr.type >= PERF_TYPE_MAX) 1580 if (evsel->attr.type >= PERF_TYPE_MAX &&
1581 evsel->attr.type != PERF_TYPE_SYNTH)
1414 return 0; 1582 return 0;
1415 1583
1416 evlist__for_each_entry(evlist, pos) { 1584 evlist__for_each_entry(evlist, pos) {
@@ -1835,6 +2003,8 @@ static int parse_output_fields(const struct option *opt __maybe_unused,
1835 type = PERF_TYPE_RAW; 2003 type = PERF_TYPE_RAW;
1836 else if (!strcmp(str, "break")) 2004 else if (!strcmp(str, "break"))
1837 type = PERF_TYPE_BREAKPOINT; 2005 type = PERF_TYPE_BREAKPOINT;
2006 else if (!strcmp(str, "synth"))
2007 type = OUTPUT_TYPE_SYNTH;
1838 else { 2008 else {
1839 fprintf(stderr, "Invalid event type in field string.\n"); 2009 fprintf(stderr, "Invalid event type in field string.\n");
1840 rc = -EINVAL; 2010 rc = -EINVAL;
@@ -1865,7 +2035,7 @@ static int parse_output_fields(const struct option *opt __maybe_unused,
1865 if (output_set_by_user()) 2035 if (output_set_by_user())
1866 pr_warning("Overriding previous field request for all events.\n"); 2036 pr_warning("Overriding previous field request for all events.\n");
1867 2037
1868 for (j = 0; j < PERF_TYPE_MAX; ++j) { 2038 for (j = 0; j < OUTPUT_TYPE_MAX; ++j) {
1869 output[j].fields = 0; 2039 output[j].fields = 0;
1870 output[j].user_set = true; 2040 output[j].user_set = true;
1871 output[j].wildcard_set = true; 2041 output[j].wildcard_set = true;
@@ -1908,7 +2078,7 @@ parse:
1908 /* add user option to all events types for 2078 /* add user option to all events types for
1909 * which it is valid 2079 * which it is valid
1910 */ 2080 */
1911 for (j = 0; j < PERF_TYPE_MAX; ++j) { 2081 for (j = 0; j < OUTPUT_TYPE_MAX; ++j) {
1912 if (output[j].invalid_fields & all_output_options[i].field) { 2082 if (output[j].invalid_fields & all_output_options[i].field) {
1913 pr_warning("\'%s\' not valid for %s events. Ignoring.\n", 2083 pr_warning("\'%s\' not valid for %s events. Ignoring.\n",
1914 all_output_options[i].str, event_type(j)); 2084 all_output_options[i].str, event_type(j));
@@ -2560,10 +2730,10 @@ int cmd_script(int argc, const char **argv)
2560 OPT_CALLBACK('F', "fields", NULL, "str", 2730 OPT_CALLBACK('F', "fields", NULL, "str",
2561 "comma separated output fields prepend with 'type:'. " 2731 "comma separated output fields prepend with 'type:'. "
2562 "+field to add and -field to remove." 2732 "+field to add and -field to remove."
2563 "Valid types: hw,sw,trace,raw. " 2733 "Valid types: hw,sw,trace,raw,synth. "
2564 "Fields: comm,tid,pid,time,cpu,event,trace,ip,sym,dso," 2734 "Fields: comm,tid,pid,time,cpu,event,trace,ip,sym,dso,"
2565 "addr,symoff,period,iregs,brstack,brstacksym,flags," 2735 "addr,symoff,period,iregs,brstack,brstacksym,flags,"
2566 "bpf-output,callindent,insn,insnlen,brstackinsn", 2736 "bpf-output,callindent,insn,insnlen,brstackinsn,synth",
2567 parse_output_fields), 2737 parse_output_fields),
2568 OPT_BOOLEAN('a', "all-cpus", &system_wide, 2738 OPT_BOOLEAN('a', "all-cpus", &system_wide,
2569 "system-wide collection from all CPUs"), 2739 "system-wide collection from all CPUs"),
@@ -2822,6 +2992,7 @@ int cmd_script(int argc, const char **argv)
2822 err = perf_session__cpu_bitmap(session, cpu_list, cpu_bitmap); 2992 err = perf_session__cpu_bitmap(session, cpu_list, cpu_bitmap);
2823 if (err < 0) 2993 if (err < 0)
2824 goto out_delete; 2994 goto out_delete;
2995 itrace_synth_opts.cpu_bitmap = cpu_bitmap;
2825 } 2996 }
2826 2997
2827 if (!no_callchain) 2998 if (!no_callchain)
diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c
index 324363054c3f..48ac53b199fc 100644
--- a/tools/perf/builtin-stat.c
+++ b/tools/perf/builtin-stat.c
@@ -636,14 +636,14 @@ try_again:
636 } 636 }
637 637
638 if (perf_evlist__apply_filters(evsel_list, &counter)) { 638 if (perf_evlist__apply_filters(evsel_list, &counter)) {
639 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",
640 counter->filter, perf_evsel__name(counter), errno, 640 counter->filter, perf_evsel__name(counter), errno,
641 str_error_r(errno, msg, sizeof(msg))); 641 str_error_r(errno, msg, sizeof(msg)));
642 return -1; 642 return -1;
643 } 643 }
644 644
645 if (perf_evlist__apply_drv_configs(evsel_list, &counter, &err_term)) { 645 if (perf_evlist__apply_drv_configs(evsel_list, &counter, &err_term)) {
646 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",
647 err_term->val.drv_cfg, perf_evsel__name(counter), errno, 647 err_term->val.drv_cfg, perf_evsel__name(counter), errno,
648 str_error_r(errno, msg, sizeof(msg))); 648 str_error_r(errno, msg, sizeof(msg)));
649 return -1; 649 return -1;
diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c
index 2bcfa46913c8..6052376634c0 100644
--- a/tools/perf/builtin-top.c
+++ b/tools/perf/builtin-top.c
@@ -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/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/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/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/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/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/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/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/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-pt-decoder/intel-pt-decoder.c b/tools/perf/util/intel-pt-decoder/intel-pt-decoder.c
index 5dea06289db5..aa1593ce551d 100644
--- a/tools/perf/util/intel-pt-decoder/intel-pt-decoder.c
+++ b/tools/perf/util/intel-pt-decoder/intel-pt-decoder.c
@@ -711,6 +711,12 @@ static int intel_pt_calc_cyc_cb(struct intel_pt_pkt_info *pkt_info)
711 break; 711 break;
712 712
713 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;
714 timestamp = pkt_info->packet.payload | 720 timestamp = pkt_info->packet.payload |
715 (data->timestamp & (0xffULL << 56)); 721 (data->timestamp & (0xffULL << 56));
716 if (data->from_mtc && timestamp < data->timestamp && 722 if (data->from_mtc && timestamp < data->timestamp &&
@@ -828,6 +834,14 @@ static void intel_pt_calc_cyc_to_tsc(struct intel_pt_decoder *decoder,
828 .cbr_cyc_to_tsc = 0, 834 .cbr_cyc_to_tsc = 0,
829 }; 835 };
830 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
831 intel_pt_pkt_lookahead(decoder, intel_pt_calc_cyc_cb, &data); 845 intel_pt_pkt_lookahead(decoder, intel_pt_calc_cyc_cb, &data);
832} 846}
833 847
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 6df836469f2b..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
@@ -1058,6 +1070,36 @@ static void intel_pt_update_last_branch_rb(struct intel_pt_queue *ptq)
1058 bs->nr += 1; 1070 bs->nr += 1;
1059} 1071}
1060 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
1061static int intel_pt_inject_event(union perf_event *event, 1103static int intel_pt_inject_event(union perf_event *event,
1062 struct perf_sample *sample, u64 type, 1104 struct perf_sample *sample, u64 type,
1063 bool swapped) 1105 bool swapped)
@@ -1066,9 +1108,35 @@ static int intel_pt_inject_event(union perf_event *event,
1066 return perf_event__synthesize_sample(event, type, 0, sample, swapped); 1108 return perf_event__synthesize_sample(event, type, 0, sample, swapped);
1067} 1109}
1068 1110
1069static 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)
1070{ 1124{
1071 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{
1072 struct intel_pt *pt = ptq->pt; 1140 struct intel_pt *pt = ptq->pt;
1073 union perf_event *event = ptq->event_buf; 1141 union perf_event *event = ptq->event_buf;
1074 struct perf_sample sample = { .ip = 0, }; 1142 struct perf_sample sample = { .ip = 0, };
@@ -1080,29 +1148,13 @@ static int intel_pt_synth_branch_sample(struct intel_pt_queue *ptq)
1080 if (pt->branches_filter && !(pt->branches_filter & ptq->flags)) 1148 if (pt->branches_filter && !(pt->branches_filter & ptq->flags))
1081 return 0; 1149 return 0;
1082 1150
1083 if (pt->synth_opts.initial_skip && 1151 if (intel_pt_skip_event(pt))
1084 pt->num_events++ < pt->synth_opts.initial_skip)
1085 return 0; 1152 return 0;
1086 1153
1087 event->sample.header.type = PERF_RECORD_SAMPLE; 1154 intel_pt_prep_b_sample(pt, ptq, event, &sample);
1088 event->sample.header.misc = PERF_RECORD_MISC_USER;
1089 event->sample.header.size = sizeof(struct perf_event_header);
1090 1155
1091 if (!pt->timeless_decoding)
1092 sample.time = tsc_to_perf_time(ptq->timestamp, &pt->tc);
1093
1094 sample.cpumode = PERF_RECORD_MISC_USER;
1095 sample.ip = ptq->state->from_ip;
1096 sample.pid = ptq->pid;
1097 sample.tid = ptq->tid;
1098 sample.addr = ptq->state->to_ip;
1099 sample.id = ptq->pt->branches_id; 1156 sample.id = ptq->pt->branches_id;
1100 sample.stream_id = ptq->pt->branches_id; 1157 sample.stream_id = ptq->pt->branches_id;
1101 sample.period = 1;
1102 sample.cpu = ptq->cpu;
1103 sample.flags = ptq->flags;
1104 sample.insn_len = ptq->insn_len;
1105 memcpy(sample.insn, ptq->insn, INTEL_PT_INSN_BUF_SZ);
1106 1158
1107 /* 1159 /*
1108 * perf report cannot handle events without a branch stack when using 1160 * perf report cannot handle events without a branch stack when using
@@ -1119,144 +1171,251 @@ static int intel_pt_synth_branch_sample(struct intel_pt_queue *ptq)
1119 sample.branch_stack = (struct branch_stack *)&dummy_bs; 1171 sample.branch_stack = (struct branch_stack *)&dummy_bs;
1120 } 1172 }
1121 1173
1122 if (pt->synth_opts.inject) { 1174 return intel_pt_deliver_synth_b_event(pt, event, &sample,
1123 ret = intel_pt_inject_event(event, &sample, 1175 pt->branches_sample_type);
1124 pt->branches_sample_type, 1176}
1125 pt->synth_needs_swap); 1177
1126 if (ret) 1178static void intel_pt_prep_sample(struct intel_pt *pt,
1127 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;
1128 } 1189 }
1129 1190
1130 ret = perf_session__deliver_synth_event(pt->session, event, &sample); 1191 if (pt->synth_opts.last_branch) {
1131 if (ret) 1192 intel_pt_copy_last_branch_rb(ptq);
1132 pr_err("Intel Processor Trace: failed to deliver branch event, error %d\n", 1193 sample->branch_stack = ptq->last_branch;
1133 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);
1134 1209
1135 return ret; 1210 return ret;
1136} 1211}
1137 1212
1138static int intel_pt_synth_instruction_sample(struct intel_pt_queue *ptq) 1213static int intel_pt_synth_instruction_sample(struct intel_pt_queue *ptq)
1139{ 1214{
1140 int ret;
1141 struct intel_pt *pt = ptq->pt; 1215 struct intel_pt *pt = ptq->pt;
1142 union perf_event *event = ptq->event_buf; 1216 union perf_event *event = ptq->event_buf;
1143 struct perf_sample sample = { .ip = 0, }; 1217 struct perf_sample sample = { .ip = 0, };
1144 1218
1145 if (pt->synth_opts.initial_skip && 1219 if (intel_pt_skip_event(pt))
1146 pt->num_events++ < pt->synth_opts.initial_skip)
1147 return 0; 1220 return 0;
1148 1221
1149 event->sample.header.type = PERF_RECORD_SAMPLE; 1222 intel_pt_prep_sample(pt, ptq, event, &sample);
1150 event->sample.header.misc = PERF_RECORD_MISC_USER;
1151 event->sample.header.size = sizeof(struct perf_event_header);
1152
1153 if (!pt->timeless_decoding)
1154 sample.time = tsc_to_perf_time(ptq->timestamp, &pt->tc);
1155 1223
1156 sample.cpumode = PERF_RECORD_MISC_USER;
1157 sample.ip = ptq->state->from_ip;
1158 sample.pid = ptq->pid;
1159 sample.tid = ptq->tid;
1160 sample.addr = ptq->state->to_ip;
1161 sample.id = ptq->pt->instructions_id; 1224 sample.id = ptq->pt->instructions_id;
1162 sample.stream_id = ptq->pt->instructions_id; 1225 sample.stream_id = ptq->pt->instructions_id;
1163 sample.period = ptq->state->tot_insn_cnt - ptq->last_insn_cnt; 1226 sample.period = ptq->state->tot_insn_cnt - ptq->last_insn_cnt;
1164 sample.cpu = ptq->cpu;
1165 sample.flags = ptq->flags;
1166 sample.insn_len = ptq->insn_len;
1167 memcpy(sample.insn, ptq->insn, INTEL_PT_INSN_BUF_SZ);
1168 1227
1169 ptq->last_insn_cnt = ptq->state->tot_insn_cnt; 1228 ptq->last_insn_cnt = ptq->state->tot_insn_cnt;
1170 1229
1171 if (pt->synth_opts.callchain) { 1230 return intel_pt_deliver_synth_event(pt, ptq, event, &sample,
1172 thread_stack__sample(ptq->thread, ptq->chain, 1231 pt->instructions_sample_type);
1173 pt->synth_opts.callchain_sz, sample.ip); 1232}
1174 sample.callchain = ptq->chain;
1175 }
1176 1233
1177 if (pt->synth_opts.last_branch) { 1234static int intel_pt_synth_transaction_sample(struct intel_pt_queue *ptq)
1178 intel_pt_copy_last_branch_rb(ptq); 1235{
1179 sample.branch_stack = ptq->last_branch; 1236 struct intel_pt *pt = ptq->pt;
1180 } 1237 union perf_event *event = ptq->event_buf;
1238 struct perf_sample sample = { .ip = 0, };
1181 1239
1182 if (pt->synth_opts.inject) { 1240 if (intel_pt_skip_event(pt))
1183 ret = intel_pt_inject_event(event, &sample, 1241 return 0;
1184 pt->instructions_sample_type,
1185 pt->synth_needs_swap);
1186 if (ret)
1187 return ret;
1188 }
1189 1242
1190 ret = perf_session__deliver_synth_event(pt->session, event, &sample); 1243 intel_pt_prep_sample(pt, ptq, event, &sample);
1191 if (ret)
1192 pr_err("Intel Processor Trace: failed to deliver instruction event, error %d\n",
1193 ret);
1194 1244
1195 if (pt->synth_opts.last_branch) 1245 sample.id = ptq->pt->transactions_id;
1196 intel_pt_reset_last_branch_rb(ptq); 1246 sample.stream_id = ptq->pt->transactions_id;
1197 1247
1198 return ret; 1248 return intel_pt_deliver_synth_event(pt, ptq, event, &sample,
1249 pt->transactions_sample_type);
1199} 1250}
1200 1251
1201static 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)
1202{ 1268{
1203 int ret;
1204 struct intel_pt *pt = ptq->pt; 1269 struct intel_pt *pt = ptq->pt;
1205 union perf_event *event = ptq->event_buf; 1270 union perf_event *event = ptq->event_buf;
1206 struct perf_sample sample = { .ip = 0, }; 1271 struct perf_sample sample = { .ip = 0, };
1272 struct perf_synth_intel_ptwrite raw;
1207 1273
1208 if (pt->synth_opts.initial_skip && 1274 if (intel_pt_skip_event(pt))
1209 pt->num_events++ < pt->synth_opts.initial_skip)
1210 return 0; 1275 return 0;
1211 1276
1212 event->sample.header.type = PERF_RECORD_SAMPLE; 1277 intel_pt_prep_p_sample(pt, ptq, event, &sample);
1213 event->sample.header.misc = PERF_RECORD_MISC_USER;
1214 event->sample.header.size = sizeof(struct perf_event_header);
1215 1278
1216 if (!pt->timeless_decoding) 1279 sample.id = ptq->pt->ptwrites_id;
1217 sample.time = tsc_to_perf_time(ptq->timestamp, &pt->tc); 1280 sample.stream_id = ptq->pt->ptwrites_id;
1218 1281
1219 sample.cpumode = PERF_RECORD_MISC_USER; 1282 raw.flags = 0;
1220 sample.ip = ptq->state->from_ip; 1283 raw.ip = !!(ptq->state->flags & INTEL_PT_FUP_IP);
1221 sample.pid = ptq->pid; 1284 raw.payload = cpu_to_le64(ptq->state->ptw_payload);
1222 sample.tid = ptq->tid;
1223 sample.addr = ptq->state->to_ip;
1224 sample.id = ptq->pt->transactions_id;
1225 sample.stream_id = ptq->pt->transactions_id;
1226 sample.period = 1;
1227 sample.cpu = ptq->cpu;
1228 sample.flags = ptq->flags;
1229 sample.insn_len = ptq->insn_len;
1230 memcpy(sample.insn, ptq->insn, INTEL_PT_INSN_BUF_SZ);
1231 1285
1232 if (pt->synth_opts.callchain) { 1286 sample.raw_size = perf_synth__raw_size(raw);
1233 thread_stack__sample(ptq->thread, ptq->chain, 1287 sample.raw_data = perf_synth__raw_data(&raw);
1234 pt->synth_opts.callchain_sz, sample.ip);
1235 sample.callchain = ptq->chain;
1236 }
1237 1288
1238 if (pt->synth_opts.last_branch) { 1289 return intel_pt_deliver_synth_event(pt, ptq, event, &sample,
1239 intel_pt_copy_last_branch_rb(ptq); 1290 pt->ptwrites_sample_type);
1240 sample.branch_stack = ptq->last_branch; 1291}
1241 }
1242 1292
1243 if (pt->synth_opts.inject) { 1293static int intel_pt_synth_cbr_sample(struct intel_pt_queue *ptq)
1244 ret = intel_pt_inject_event(event, &sample, 1294{
1245 pt->transactions_sample_type, 1295 struct intel_pt *pt = ptq->pt;
1246 pt->synth_needs_swap); 1296 union perf_event *event = ptq->event_buf;
1247 if (ret) 1297 struct perf_sample sample = { .ip = 0, };
1248 return ret; 1298 struct perf_synth_intel_cbr raw;
1249 } 1299 u32 flags;
1250 1300
1251 ret = perf_session__deliver_synth_event(pt->session, event, &sample); 1301 if (intel_pt_skip_event(pt))
1252 if (ret) 1302 return 0;
1253 pr_err("Intel Processor Trace: failed to deliver transaction event, error %d\n",
1254 ret);
1255 1303
1256 if (pt->synth_opts.last_branch) 1304 intel_pt_prep_p_sample(pt, ptq, event, &sample);
1257 intel_pt_reset_last_branch_rb(ptq);
1258 1305
1259 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);
1260} 1419}
1261 1420
1262static 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,
@@ -1310,6 +1469,10 @@ static inline bool intel_pt_is_switch_ip(struct intel_pt_queue *ptq, u64 ip)
1310 PERF_IP_FLAG_INTERRUPT | PERF_IP_FLAG_TX_ABORT)); 1469 PERF_IP_FLAG_INTERRUPT | PERF_IP_FLAG_TX_ABORT));
1311} 1470}
1312 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
1313static int intel_pt_sample(struct intel_pt_queue *ptq) 1476static int intel_pt_sample(struct intel_pt_queue *ptq)
1314{ 1477{
1315 const struct intel_pt_state *state = ptq->state; 1478 const struct intel_pt_state *state = ptq->state;
@@ -1321,20 +1484,52 @@ static int intel_pt_sample(struct intel_pt_queue *ptq)
1321 1484
1322 ptq->have_sample = false; 1485 ptq->have_sample = false;
1323 1486
1324 if (pt->sample_instructions && 1487 if (pt->sample_pwr_events && (state->type & INTEL_PT_PWR_EVT)) {
1325 (state->type & INTEL_PT_INSTRUCTION)) { 1488 if (state->type & INTEL_PT_CBR_CHG) {
1489 err = intel_pt_synth_cbr_sample(ptq);
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)) {
1326 err = intel_pt_synth_instruction_sample(ptq); 1516 err = intel_pt_synth_instruction_sample(ptq);
1327 if (err) 1517 if (err)
1328 return err; 1518 return err;
1329 } 1519 }
1330 1520
1331 if (pt->sample_transactions && 1521 if (pt->sample_transactions && (state->type & INTEL_PT_TRANSACTION)) {
1332 (state->type & INTEL_PT_TRANSACTION)) {
1333 err = intel_pt_synth_transaction_sample(ptq); 1522 err = intel_pt_synth_transaction_sample(ptq);
1334 if (err) 1523 if (err)
1335 return err; 1524 return err;
1336 } 1525 }
1337 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
1338 if (!(state->type & INTEL_PT_BRANCH)) 1533 if (!(state->type & INTEL_PT_BRANCH))
1339 return 0; 1534 return 0;
1340 1535
@@ -1935,36 +2130,65 @@ static int intel_pt_event_synth(struct perf_tool *tool,
1935 NULL); 2130 NULL);
1936} 2131}
1937 2132
1938static int intel_pt_synth_event(struct perf_session *session, 2133static int intel_pt_synth_event(struct perf_session *session, const char *name,
1939 struct perf_event_attr *attr, u64 id) 2134 struct perf_event_attr *attr, u64 id)
1940{ 2135{
1941 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);
1942 2141
1943 memset(&intel_pt_synth, 0, sizeof(struct intel_pt_synth)); 2142 memset(&intel_pt_synth, 0, sizeof(struct intel_pt_synth));
1944 intel_pt_synth.session = session; 2143 intel_pt_synth.session = session;
1945 2144
1946 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,
1947 &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;
1948} 2152}
1949 2153
1950static int intel_pt_synth_events(struct intel_pt *pt, 2154static void intel_pt_set_event_name(struct perf_evlist *evlist, u64 id,
1951 struct perf_session *session) 2155 const char *name)
1952{ 2156{
1953 struct perf_evlist *evlist = session->evlist;
1954 struct perf_evsel *evsel; 2157 struct perf_evsel *evsel;
1955 struct perf_event_attr attr;
1956 bool found = false;
1957 u64 id;
1958 int err;
1959 2158
1960 evlist__for_each_entry(evlist, evsel) { 2159 evlist__for_each_entry(evlist, evsel) {
1961 if (evsel->attr.type == pt->pmu_type && evsel->ids) { 2160 if (evsel->id && evsel->id[0] == id) {
1962 found = true; 2161 if (evsel->name)
2162 zfree(&evsel->name);
2163 evsel->name = strdup(name);
1963 break; 2164 break;
1964 } 2165 }
1965 } 2166 }
2167}
2168
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;
1966 2190
1967 if (!found) { 2191 if (!evsel) {
1968 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");
1969 return 0; 2193 return 0;
1970 } 2194 }
@@ -1993,6 +2217,25 @@ static int intel_pt_synth_events(struct intel_pt *pt,
1993 if (!id) 2217 if (!id)
1994 id = 1; 2218 id = 1;
1995 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
1996 if (pt->synth_opts.instructions) { 2239 if (pt->synth_opts.instructions) {
1997 attr.config = PERF_COUNT_HW_INSTRUCTIONS; 2240 attr.config = PERF_COUNT_HW_INSTRUCTIONS;
1998 if (pt->synth_opts.period_type == PERF_ITRACE_PERIOD_NANOSECS) 2241 if (pt->synth_opts.period_type == PERF_ITRACE_PERIOD_NANOSECS)
@@ -2000,71 +2243,90 @@ static int intel_pt_synth_events(struct intel_pt *pt,
2000 intel_pt_ns_to_ticks(pt, pt->synth_opts.period); 2243 intel_pt_ns_to_ticks(pt, pt->synth_opts.period);
2001 else 2244 else
2002 attr.sample_period = pt->synth_opts.period; 2245 attr.sample_period = pt->synth_opts.period;
2003 pt->instructions_sample_period = attr.sample_period; 2246 err = intel_pt_synth_event(session, "instructions", &attr, id);
2004 if (pt->synth_opts.callchain) 2247 if (err)
2005 attr.sample_type |= PERF_SAMPLE_CALLCHAIN;
2006 if (pt->synth_opts.last_branch)
2007 attr.sample_type |= PERF_SAMPLE_BRANCH_STACK;
2008 pr_debug("Synthesizing 'instructions' event with id %" PRIu64 " sample type %#" PRIx64 "\n",
2009 id, (u64)attr.sample_type);
2010 err = intel_pt_synth_event(session, &attr, id);
2011 if (err) {
2012 pr_err("%s: failed to synthesize 'instructions' event type\n",
2013 __func__);
2014 return err; 2248 return err;
2015 }
2016 pt->sample_instructions = true; 2249 pt->sample_instructions = true;
2017 pt->instructions_sample_type = attr.sample_type; 2250 pt->instructions_sample_type = attr.sample_type;
2018 pt->instructions_id = id; 2251 pt->instructions_id = id;
2019 id += 1; 2252 id += 1;
2020 } 2253 }
2021 2254
2255 attr.sample_type &= ~(u64)PERF_SAMPLE_PERIOD;
2256 attr.sample_period = 1;
2257
2022 if (pt->synth_opts.transactions) { 2258 if (pt->synth_opts.transactions) {
2023 attr.config = PERF_COUNT_HW_INSTRUCTIONS; 2259 attr.config = PERF_COUNT_HW_INSTRUCTIONS;
2024 attr.sample_period = 1; 2260 err = intel_pt_synth_event(session, "transactions", &attr, id);
2025 if (pt->synth_opts.callchain) 2261 if (err)
2026 attr.sample_type |= PERF_SAMPLE_CALLCHAIN;
2027 if (pt->synth_opts.last_branch)
2028 attr.sample_type |= PERF_SAMPLE_BRANCH_STACK;
2029 pr_debug("Synthesizing 'transactions' event with id %" PRIu64 " sample type %#" PRIx64 "\n",
2030 id, (u64)attr.sample_type);
2031 err = intel_pt_synth_event(session, &attr, id);
2032 if (err) {
2033 pr_err("%s: failed to synthesize 'transactions' event type\n",
2034 __func__);
2035 return err; 2262 return err;
2036 }
2037 pt->sample_transactions = true; 2263 pt->sample_transactions = true;
2038 pt->transactions_sample_type = attr.sample_type; 2264 pt->transactions_sample_type = attr.sample_type;
2039 pt->transactions_id = id; 2265 pt->transactions_id = id;
2266 intel_pt_set_event_name(evlist, id, "transactions");
2040 id += 1; 2267 id += 1;
2041 evlist__for_each_entry(evlist, evsel) {
2042 if (evsel->id && evsel->id[0] == pt->transactions_id) {
2043 if (evsel->name)
2044 zfree(&evsel->name);
2045 evsel->name = strdup("transactions");
2046 break;
2047 }
2048 }
2049 } 2268 }
2050 2269
2051 if (pt->synth_opts.branches) { 2270 attr.type = PERF_TYPE_SYNTH;
2052 attr.config = PERF_COUNT_HW_BRANCH_INSTRUCTIONS; 2271 attr.sample_type |= PERF_SAMPLE_RAW;
2053 attr.sample_period = 1; 2272
2054 attr.sample_type |= PERF_SAMPLE_ADDR; 2273 if (pt->synth_opts.ptwrites) {
2055 attr.sample_type &= ~(u64)PERF_SAMPLE_CALLCHAIN; 2274 attr.config = PERF_SYNTH_INTEL_PTWRITE;
2056 attr.sample_type &= ~(u64)PERF_SAMPLE_BRANCH_STACK; 2275 err = intel_pt_synth_event(session, "ptwrite", &attr, id);
2057 pr_debug("Synthesizing 'branches' event with id %" PRIu64 " sample type %#" PRIx64 "\n", 2276 if (err)
2058 id, (u64)attr.sample_type);
2059 err = intel_pt_synth_event(session, &attr, id);
2060 if (err) {
2061 pr_err("%s: failed to synthesize 'branches' event type\n",
2062 __func__);
2063 return err; 2277 return err;
2064 } 2278 pt->sample_ptwrites = true;
2065 pt->sample_branches = true; 2279 pt->ptwrites_sample_type = attr.sample_type;
2066 pt->branches_sample_type = attr.sample_type; 2280 pt->ptwrites_id = id;
2067 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;
2068 } 2330 }
2069 2331
2070 pt->synth_needs_swap = evsel->needs_swap; 2332 pt->synth_needs_swap = evsel->needs_swap;
@@ -2333,6 +2595,7 @@ int intel_pt_process_auxtrace_info(union perf_event *event,
2333 intel_pt_log("TSC frequency %"PRIu64"\n", tsc_freq); 2595 intel_pt_log("TSC frequency %"PRIu64"\n", tsc_freq);
2334 intel_pt_log("Maximum non-turbo ratio %u\n", 2596 intel_pt_log("Maximum non-turbo ratio %u\n",
2335 pt->max_non_turbo_ratio); 2597 pt->max_non_turbo_ratio);
2598 pt->cbr2khz = tsc_freq / pt->max_non_turbo_ratio / 1000;
2336 } 2599 }
2337 2600
2338 if (pt->synth_opts.calls) 2601 if (pt->synth_opts.calls)
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/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/usage.c b/tools/perf/util/usage.c
index aacb65e079aa..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)
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) 12static __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.h b/tools/perf/util/util.h
index 978572dfeb14..2c9e58a45310 100644
--- a/tools/perf/util/util.h
+++ b/tools/perf/util/util.h
@@ -16,10 +16,6 @@
16/* General helper functions */ 16/* General helper functions */
17void usage(const char *err) __noreturn; 17void usage(const char *err) __noreturn;
18void die(const char *err, ...) __noreturn __printf(1, 2); 18void die(const char *err, ...) __noreturn __printf(1, 2);
19int error(const char *err, ...) __printf(1, 2);
20void warning(const char *err, ...) __printf(1, 2);
21
22void set_warning_routine(void (*routine)(const char *err, va_list params));
23 19
24static inline void *zalloc(size_t size) 20static inline void *zalloc(size_t size)
25{ 21{