aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIngo Molnar <mingo@kernel.org>2012-09-24 14:55:26 -0400
committerIngo Molnar <mingo@kernel.org>2012-09-24 14:55:26 -0400
commitf74eb728687afbf239abe2ea66921583db4eaa4b (patch)
tree47705ee82ead642e9a4b71edb39988c4b991a4ec
parent50a011f6409e888d5f41343024d24885281f048c (diff)
parentb1ac754b67b5a875d63bee880f60ccb0c6bd8899 (diff)
Merge tag 'perf-core-for-mingo' 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: * Convert the trace builtins to use the growing evsel/evlist tracepoint infrastructure, removing several open coded constructs like switch like series of strcmp to dispatch events, etc. Basically what had already been showcased in 'perf sched'. * Add evsel constructor for tracepoints, that uses libtraceevent just to parse the /format events file, use it in a new 'perf test' to make sure the libtraceevent format parsing regressions can be more readily caught. * Some strange errors were happening in some builds, but not on the next, reported by several people, problem was some parser related files, generated during the build, didn't had proper make deps, fix from Eric Sandeen. * Fix some compiling errors on 32-bit, from Feng Tang. * Don't use sscanf extension %as, not available on bionic, reimplementation by Irina Tirdea. * Fix bfd.h/libbfd detection with recent binutils, from Markus Trippelsdorf. * Introduce struct and cache information about the environment where a perf.data file was captured, from Namhyung Kim. * Fix several error paths in libtraceevent, from Namhyung Kim. Print event causing perf_event_open() to fail in 'perf record', from Stephane Eranian. * New 'kvm' analysis tool, from Xiao Guangrong. Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
-rw-r--r--arch/x86/include/asm/kvm.h16
-rw-r--r--arch/x86/include/asm/kvm_host.h16
-rw-r--r--arch/x86/include/asm/svm.h205
-rw-r--r--arch/x86/include/asm/vmx.h127
-rw-r--r--arch/x86/kvm/trace.h89
-rw-r--r--tools/lib/traceevent/event-parse.c570
-rw-r--r--tools/lib/traceevent/event-parse.h3
-rw-r--r--tools/perf/Documentation/perf-kvm.txt30
-rw-r--r--tools/perf/MANIFEST3
-rw-r--r--tools/perf/Makefile6
-rw-r--r--tools/perf/builtin-kmem.c90
-rw-r--r--tools/perf/builtin-kvm.c836
-rw-r--r--tools/perf/builtin-lock.c233
-rw-r--r--tools/perf/builtin-record.c6
-rw-r--r--tools/perf/builtin-test.c86
-rw-r--r--tools/perf/builtin-timechart.c40
-rw-r--r--tools/perf/util/evsel.c88
-rw-r--r--tools/perf/util/evsel.h5
-rw-r--r--tools/perf/util/header.c547
-rw-r--r--tools/perf/util/header.h24
-rw-r--r--tools/perf/util/map.c5
-rw-r--r--tools/perf/util/probe-event.c36
-rw-r--r--tools/perf/util/scripting-engines/trace-event-perl.c2
-rw-r--r--tools/perf/util/symbol.h1
-rw-r--r--tools/perf/util/thread.h2
-rw-r--r--tools/perf/util/trace-event-parse.c18
26 files changed, 2278 insertions, 806 deletions
diff --git a/arch/x86/include/asm/kvm.h b/arch/x86/include/asm/kvm.h
index 246617efd67f..41e08cb6a092 100644
--- a/arch/x86/include/asm/kvm.h
+++ b/arch/x86/include/asm/kvm.h
@@ -9,6 +9,22 @@
9#include <linux/types.h> 9#include <linux/types.h>
10#include <linux/ioctl.h> 10#include <linux/ioctl.h>
11 11
12#define DE_VECTOR 0
13#define DB_VECTOR 1
14#define BP_VECTOR 3
15#define OF_VECTOR 4
16#define BR_VECTOR 5
17#define UD_VECTOR 6
18#define NM_VECTOR 7
19#define DF_VECTOR 8
20#define TS_VECTOR 10
21#define NP_VECTOR 11
22#define SS_VECTOR 12
23#define GP_VECTOR 13
24#define PF_VECTOR 14
25#define MF_VECTOR 16
26#define MC_VECTOR 18
27
12/* Select x86 specific features in <linux/kvm.h> */ 28/* Select x86 specific features in <linux/kvm.h> */
13#define __KVM_HAVE_PIT 29#define __KVM_HAVE_PIT
14#define __KVM_HAVE_IOAPIC 30#define __KVM_HAVE_IOAPIC
diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h
index 09155d64cf7e..1eaa6b056670 100644
--- a/arch/x86/include/asm/kvm_host.h
+++ b/arch/x86/include/asm/kvm_host.h
@@ -75,22 +75,6 @@
75#define KVM_HPAGE_MASK(x) (~(KVM_HPAGE_SIZE(x) - 1)) 75#define KVM_HPAGE_MASK(x) (~(KVM_HPAGE_SIZE(x) - 1))
76#define KVM_PAGES_PER_HPAGE(x) (KVM_HPAGE_SIZE(x) / PAGE_SIZE) 76#define KVM_PAGES_PER_HPAGE(x) (KVM_HPAGE_SIZE(x) / PAGE_SIZE)
77 77
78#define DE_VECTOR 0
79#define DB_VECTOR 1
80#define BP_VECTOR 3
81#define OF_VECTOR 4
82#define BR_VECTOR 5
83#define UD_VECTOR 6
84#define NM_VECTOR 7
85#define DF_VECTOR 8
86#define TS_VECTOR 10
87#define NP_VECTOR 11
88#define SS_VECTOR 12
89#define GP_VECTOR 13
90#define PF_VECTOR 14
91#define MF_VECTOR 16
92#define MC_VECTOR 18
93
94#define SELECTOR_TI_MASK (1 << 2) 78#define SELECTOR_TI_MASK (1 << 2)
95#define SELECTOR_RPL_MASK 0x03 79#define SELECTOR_RPL_MASK 0x03
96 80
diff --git a/arch/x86/include/asm/svm.h b/arch/x86/include/asm/svm.h
index f2b83bc7d784..cdf5674dd23a 100644
--- a/arch/x86/include/asm/svm.h
+++ b/arch/x86/include/asm/svm.h
@@ -1,6 +1,135 @@
1#ifndef __SVM_H 1#ifndef __SVM_H
2#define __SVM_H 2#define __SVM_H
3 3
4#define SVM_EXIT_READ_CR0 0x000
5#define SVM_EXIT_READ_CR3 0x003
6#define SVM_EXIT_READ_CR4 0x004
7#define SVM_EXIT_READ_CR8 0x008
8#define SVM_EXIT_WRITE_CR0 0x010
9#define SVM_EXIT_WRITE_CR3 0x013
10#define SVM_EXIT_WRITE_CR4 0x014
11#define SVM_EXIT_WRITE_CR8 0x018
12#define SVM_EXIT_READ_DR0 0x020
13#define SVM_EXIT_READ_DR1 0x021
14#define SVM_EXIT_READ_DR2 0x022
15#define SVM_EXIT_READ_DR3 0x023
16#define SVM_EXIT_READ_DR4 0x024
17#define SVM_EXIT_READ_DR5 0x025
18#define SVM_EXIT_READ_DR6 0x026
19#define SVM_EXIT_READ_DR7 0x027
20#define SVM_EXIT_WRITE_DR0 0x030
21#define SVM_EXIT_WRITE_DR1 0x031
22#define SVM_EXIT_WRITE_DR2 0x032
23#define SVM_EXIT_WRITE_DR3 0x033
24#define SVM_EXIT_WRITE_DR4 0x034
25#define SVM_EXIT_WRITE_DR5 0x035
26#define SVM_EXIT_WRITE_DR6 0x036
27#define SVM_EXIT_WRITE_DR7 0x037
28#define SVM_EXIT_EXCP_BASE 0x040
29#define SVM_EXIT_INTR 0x060
30#define SVM_EXIT_NMI 0x061
31#define SVM_EXIT_SMI 0x062
32#define SVM_EXIT_INIT 0x063
33#define SVM_EXIT_VINTR 0x064
34#define SVM_EXIT_CR0_SEL_WRITE 0x065
35#define SVM_EXIT_IDTR_READ 0x066
36#define SVM_EXIT_GDTR_READ 0x067
37#define SVM_EXIT_LDTR_READ 0x068
38#define SVM_EXIT_TR_READ 0x069
39#define SVM_EXIT_IDTR_WRITE 0x06a
40#define SVM_EXIT_GDTR_WRITE 0x06b
41#define SVM_EXIT_LDTR_WRITE 0x06c
42#define SVM_EXIT_TR_WRITE 0x06d
43#define SVM_EXIT_RDTSC 0x06e
44#define SVM_EXIT_RDPMC 0x06f
45#define SVM_EXIT_PUSHF 0x070
46#define SVM_EXIT_POPF 0x071
47#define SVM_EXIT_CPUID 0x072
48#define SVM_EXIT_RSM 0x073
49#define SVM_EXIT_IRET 0x074
50#define SVM_EXIT_SWINT 0x075
51#define SVM_EXIT_INVD 0x076
52#define SVM_EXIT_PAUSE 0x077
53#define SVM_EXIT_HLT 0x078
54#define SVM_EXIT_INVLPG 0x079
55#define SVM_EXIT_INVLPGA 0x07a
56#define SVM_EXIT_IOIO 0x07b
57#define SVM_EXIT_MSR 0x07c
58#define SVM_EXIT_TASK_SWITCH 0x07d
59#define SVM_EXIT_FERR_FREEZE 0x07e
60#define SVM_EXIT_SHUTDOWN 0x07f
61#define SVM_EXIT_VMRUN 0x080
62#define SVM_EXIT_VMMCALL 0x081
63#define SVM_EXIT_VMLOAD 0x082
64#define SVM_EXIT_VMSAVE 0x083
65#define SVM_EXIT_STGI 0x084
66#define SVM_EXIT_CLGI 0x085
67#define SVM_EXIT_SKINIT 0x086
68#define SVM_EXIT_RDTSCP 0x087
69#define SVM_EXIT_ICEBP 0x088
70#define SVM_EXIT_WBINVD 0x089
71#define SVM_EXIT_MONITOR 0x08a
72#define SVM_EXIT_MWAIT 0x08b
73#define SVM_EXIT_MWAIT_COND 0x08c
74#define SVM_EXIT_XSETBV 0x08d
75#define SVM_EXIT_NPF 0x400
76
77#define SVM_EXIT_ERR -1
78
79#define SVM_EXIT_REASONS \
80 { SVM_EXIT_READ_CR0, "read_cr0" }, \
81 { SVM_EXIT_READ_CR3, "read_cr3" }, \
82 { SVM_EXIT_READ_CR4, "read_cr4" }, \
83 { SVM_EXIT_READ_CR8, "read_cr8" }, \
84 { SVM_EXIT_WRITE_CR0, "write_cr0" }, \
85 { SVM_EXIT_WRITE_CR3, "write_cr3" }, \
86 { SVM_EXIT_WRITE_CR4, "write_cr4" }, \
87 { SVM_EXIT_WRITE_CR8, "write_cr8" }, \
88 { SVM_EXIT_READ_DR0, "read_dr0" }, \
89 { SVM_EXIT_READ_DR1, "read_dr1" }, \
90 { SVM_EXIT_READ_DR2, "read_dr2" }, \
91 { SVM_EXIT_READ_DR3, "read_dr3" }, \
92 { SVM_EXIT_WRITE_DR0, "write_dr0" }, \
93 { SVM_EXIT_WRITE_DR1, "write_dr1" }, \
94 { SVM_EXIT_WRITE_DR2, "write_dr2" }, \
95 { SVM_EXIT_WRITE_DR3, "write_dr3" }, \
96 { SVM_EXIT_WRITE_DR5, "write_dr5" }, \
97 { SVM_EXIT_WRITE_DR7, "write_dr7" }, \
98 { SVM_EXIT_EXCP_BASE + DB_VECTOR, "DB excp" }, \
99 { SVM_EXIT_EXCP_BASE + BP_VECTOR, "BP excp" }, \
100 { SVM_EXIT_EXCP_BASE + UD_VECTOR, "UD excp" }, \
101 { SVM_EXIT_EXCP_BASE + PF_VECTOR, "PF excp" }, \
102 { SVM_EXIT_EXCP_BASE + NM_VECTOR, "NM excp" }, \
103 { SVM_EXIT_EXCP_BASE + MC_VECTOR, "MC excp" }, \
104 { SVM_EXIT_INTR, "interrupt" }, \
105 { SVM_EXIT_NMI, "nmi" }, \
106 { SVM_EXIT_SMI, "smi" }, \
107 { SVM_EXIT_INIT, "init" }, \
108 { SVM_EXIT_VINTR, "vintr" }, \
109 { SVM_EXIT_CPUID, "cpuid" }, \
110 { SVM_EXIT_INVD, "invd" }, \
111 { SVM_EXIT_HLT, "hlt" }, \
112 { SVM_EXIT_INVLPG, "invlpg" }, \
113 { SVM_EXIT_INVLPGA, "invlpga" }, \
114 { SVM_EXIT_IOIO, "io" }, \
115 { SVM_EXIT_MSR, "msr" }, \
116 { SVM_EXIT_TASK_SWITCH, "task_switch" }, \
117 { SVM_EXIT_SHUTDOWN, "shutdown" }, \
118 { SVM_EXIT_VMRUN, "vmrun" }, \
119 { SVM_EXIT_VMMCALL, "hypercall" }, \
120 { SVM_EXIT_VMLOAD, "vmload" }, \
121 { SVM_EXIT_VMSAVE, "vmsave" }, \
122 { SVM_EXIT_STGI, "stgi" }, \
123 { SVM_EXIT_CLGI, "clgi" }, \
124 { SVM_EXIT_SKINIT, "skinit" }, \
125 { SVM_EXIT_WBINVD, "wbinvd" }, \
126 { SVM_EXIT_MONITOR, "monitor" }, \
127 { SVM_EXIT_MWAIT, "mwait" }, \
128 { SVM_EXIT_XSETBV, "xsetbv" }, \
129 { SVM_EXIT_NPF, "npf" }
130
131#ifdef __KERNEL__
132
4enum { 133enum {
5 INTERCEPT_INTR, 134 INTERCEPT_INTR,
6 INTERCEPT_NMI, 135 INTERCEPT_NMI,
@@ -264,81 +393,6 @@ struct __attribute__ ((__packed__)) vmcb {
264 393
265#define SVM_EXITINFO_REG_MASK 0x0F 394#define SVM_EXITINFO_REG_MASK 0x0F
266 395
267#define SVM_EXIT_READ_CR0 0x000
268#define SVM_EXIT_READ_CR3 0x003
269#define SVM_EXIT_READ_CR4 0x004
270#define SVM_EXIT_READ_CR8 0x008
271#define SVM_EXIT_WRITE_CR0 0x010
272#define SVM_EXIT_WRITE_CR3 0x013
273#define SVM_EXIT_WRITE_CR4 0x014
274#define SVM_EXIT_WRITE_CR8 0x018
275#define SVM_EXIT_READ_DR0 0x020
276#define SVM_EXIT_READ_DR1 0x021
277#define SVM_EXIT_READ_DR2 0x022
278#define SVM_EXIT_READ_DR3 0x023
279#define SVM_EXIT_READ_DR4 0x024
280#define SVM_EXIT_READ_DR5 0x025
281#define SVM_EXIT_READ_DR6 0x026
282#define SVM_EXIT_READ_DR7 0x027
283#define SVM_EXIT_WRITE_DR0 0x030
284#define SVM_EXIT_WRITE_DR1 0x031
285#define SVM_EXIT_WRITE_DR2 0x032
286#define SVM_EXIT_WRITE_DR3 0x033
287#define SVM_EXIT_WRITE_DR4 0x034
288#define SVM_EXIT_WRITE_DR5 0x035
289#define SVM_EXIT_WRITE_DR6 0x036
290#define SVM_EXIT_WRITE_DR7 0x037
291#define SVM_EXIT_EXCP_BASE 0x040
292#define SVM_EXIT_INTR 0x060
293#define SVM_EXIT_NMI 0x061
294#define SVM_EXIT_SMI 0x062
295#define SVM_EXIT_INIT 0x063
296#define SVM_EXIT_VINTR 0x064
297#define SVM_EXIT_CR0_SEL_WRITE 0x065
298#define SVM_EXIT_IDTR_READ 0x066
299#define SVM_EXIT_GDTR_READ 0x067
300#define SVM_EXIT_LDTR_READ 0x068
301#define SVM_EXIT_TR_READ 0x069
302#define SVM_EXIT_IDTR_WRITE 0x06a
303#define SVM_EXIT_GDTR_WRITE 0x06b
304#define SVM_EXIT_LDTR_WRITE 0x06c
305#define SVM_EXIT_TR_WRITE 0x06d
306#define SVM_EXIT_RDTSC 0x06e
307#define SVM_EXIT_RDPMC 0x06f
308#define SVM_EXIT_PUSHF 0x070
309#define SVM_EXIT_POPF 0x071
310#define SVM_EXIT_CPUID 0x072
311#define SVM_EXIT_RSM 0x073
312#define SVM_EXIT_IRET 0x074
313#define SVM_EXIT_SWINT 0x075
314#define SVM_EXIT_INVD 0x076
315#define SVM_EXIT_PAUSE 0x077
316#define SVM_EXIT_HLT 0x078
317#define SVM_EXIT_INVLPG 0x079
318#define SVM_EXIT_INVLPGA 0x07a
319#define SVM_EXIT_IOIO 0x07b
320#define SVM_EXIT_MSR 0x07c
321#define SVM_EXIT_TASK_SWITCH 0x07d
322#define SVM_EXIT_FERR_FREEZE 0x07e
323#define SVM_EXIT_SHUTDOWN 0x07f
324#define SVM_EXIT_VMRUN 0x080
325#define SVM_EXIT_VMMCALL 0x081
326#define SVM_EXIT_VMLOAD 0x082
327#define SVM_EXIT_VMSAVE 0x083
328#define SVM_EXIT_STGI 0x084
329#define SVM_EXIT_CLGI 0x085
330#define SVM_EXIT_SKINIT 0x086
331#define SVM_EXIT_RDTSCP 0x087
332#define SVM_EXIT_ICEBP 0x088
333#define SVM_EXIT_WBINVD 0x089
334#define SVM_EXIT_MONITOR 0x08a
335#define SVM_EXIT_MWAIT 0x08b
336#define SVM_EXIT_MWAIT_COND 0x08c
337#define SVM_EXIT_XSETBV 0x08d
338#define SVM_EXIT_NPF 0x400
339
340#define SVM_EXIT_ERR -1
341
342#define SVM_CR0_SELECTIVE_MASK (X86_CR0_TS | X86_CR0_MP) 396#define SVM_CR0_SELECTIVE_MASK (X86_CR0_TS | X86_CR0_MP)
343 397
344#define SVM_VMLOAD ".byte 0x0f, 0x01, 0xda" 398#define SVM_VMLOAD ".byte 0x0f, 0x01, 0xda"
@@ -350,3 +404,4 @@ struct __attribute__ ((__packed__)) vmcb {
350 404
351#endif 405#endif
352 406
407#endif
diff --git a/arch/x86/include/asm/vmx.h b/arch/x86/include/asm/vmx.h
index 74fcb963595b..36ec21c36d68 100644
--- a/arch/x86/include/asm/vmx.h
+++ b/arch/x86/include/asm/vmx.h
@@ -25,6 +25,88 @@
25 * 25 *
26 */ 26 */
27 27
28#define VMX_EXIT_REASONS_FAILED_VMENTRY 0x80000000
29
30#define EXIT_REASON_EXCEPTION_NMI 0
31#define EXIT_REASON_EXTERNAL_INTERRUPT 1
32#define EXIT_REASON_TRIPLE_FAULT 2
33
34#define EXIT_REASON_PENDING_INTERRUPT 7
35#define EXIT_REASON_NMI_WINDOW 8
36#define EXIT_REASON_TASK_SWITCH 9
37#define EXIT_REASON_CPUID 10
38#define EXIT_REASON_HLT 12
39#define EXIT_REASON_INVD 13
40#define EXIT_REASON_INVLPG 14
41#define EXIT_REASON_RDPMC 15
42#define EXIT_REASON_RDTSC 16
43#define EXIT_REASON_VMCALL 18
44#define EXIT_REASON_VMCLEAR 19
45#define EXIT_REASON_VMLAUNCH 20
46#define EXIT_REASON_VMPTRLD 21
47#define EXIT_REASON_VMPTRST 22
48#define EXIT_REASON_VMREAD 23
49#define EXIT_REASON_VMRESUME 24
50#define EXIT_REASON_VMWRITE 25
51#define EXIT_REASON_VMOFF 26
52#define EXIT_REASON_VMON 27
53#define EXIT_REASON_CR_ACCESS 28
54#define EXIT_REASON_DR_ACCESS 29
55#define EXIT_REASON_IO_INSTRUCTION 30
56#define EXIT_REASON_MSR_READ 31
57#define EXIT_REASON_MSR_WRITE 32
58#define EXIT_REASON_INVALID_STATE 33
59#define EXIT_REASON_MWAIT_INSTRUCTION 36
60#define EXIT_REASON_MONITOR_INSTRUCTION 39
61#define EXIT_REASON_PAUSE_INSTRUCTION 40
62#define EXIT_REASON_MCE_DURING_VMENTRY 41
63#define EXIT_REASON_TPR_BELOW_THRESHOLD 43
64#define EXIT_REASON_APIC_ACCESS 44
65#define EXIT_REASON_EPT_VIOLATION 48
66#define EXIT_REASON_EPT_MISCONFIG 49
67#define EXIT_REASON_WBINVD 54
68#define EXIT_REASON_XSETBV 55
69#define EXIT_REASON_INVPCID 58
70
71#define VMX_EXIT_REASONS \
72 { EXIT_REASON_EXCEPTION_NMI, "EXCEPTION_NMI" }, \
73 { EXIT_REASON_EXTERNAL_INTERRUPT, "EXTERNAL_INTERRUPT" }, \
74 { EXIT_REASON_TRIPLE_FAULT, "TRIPLE_FAULT" }, \
75 { EXIT_REASON_PENDING_INTERRUPT, "PENDING_INTERRUPT" }, \
76 { EXIT_REASON_NMI_WINDOW, "NMI_WINDOW" }, \
77 { EXIT_REASON_TASK_SWITCH, "TASK_SWITCH" }, \
78 { EXIT_REASON_CPUID, "CPUID" }, \
79 { EXIT_REASON_HLT, "HLT" }, \
80 { EXIT_REASON_INVLPG, "INVLPG" }, \
81 { EXIT_REASON_RDPMC, "RDPMC" }, \
82 { EXIT_REASON_RDTSC, "RDTSC" }, \
83 { EXIT_REASON_VMCALL, "VMCALL" }, \
84 { EXIT_REASON_VMCLEAR, "VMCLEAR" }, \
85 { EXIT_REASON_VMLAUNCH, "VMLAUNCH" }, \
86 { EXIT_REASON_VMPTRLD, "VMPTRLD" }, \
87 { EXIT_REASON_VMPTRST, "VMPTRST" }, \
88 { EXIT_REASON_VMREAD, "VMREAD" }, \
89 { EXIT_REASON_VMRESUME, "VMRESUME" }, \
90 { EXIT_REASON_VMWRITE, "VMWRITE" }, \
91 { EXIT_REASON_VMOFF, "VMOFF" }, \
92 { EXIT_REASON_VMON, "VMON" }, \
93 { EXIT_REASON_CR_ACCESS, "CR_ACCESS" }, \
94 { EXIT_REASON_DR_ACCESS, "DR_ACCESS" }, \
95 { EXIT_REASON_IO_INSTRUCTION, "IO_INSTRUCTION" }, \
96 { EXIT_REASON_MSR_READ, "MSR_READ" }, \
97 { EXIT_REASON_MSR_WRITE, "MSR_WRITE" }, \
98 { EXIT_REASON_MWAIT_INSTRUCTION, "MWAIT_INSTRUCTION" }, \
99 { EXIT_REASON_MONITOR_INSTRUCTION, "MONITOR_INSTRUCTION" }, \
100 { EXIT_REASON_PAUSE_INSTRUCTION, "PAUSE_INSTRUCTION" }, \
101 { EXIT_REASON_MCE_DURING_VMENTRY, "MCE_DURING_VMENTRY" }, \
102 { EXIT_REASON_TPR_BELOW_THRESHOLD, "TPR_BELOW_THRESHOLD" }, \
103 { EXIT_REASON_APIC_ACCESS, "APIC_ACCESS" }, \
104 { EXIT_REASON_EPT_VIOLATION, "EPT_VIOLATION" }, \
105 { EXIT_REASON_EPT_MISCONFIG, "EPT_MISCONFIG" }, \
106 { EXIT_REASON_WBINVD, "WBINVD" }
107
108#ifdef __KERNEL__
109
28#include <linux/types.h> 110#include <linux/types.h>
29 111
30/* 112/*
@@ -241,49 +323,6 @@ enum vmcs_field {
241 HOST_RIP = 0x00006c16, 323 HOST_RIP = 0x00006c16,
242}; 324};
243 325
244#define VMX_EXIT_REASONS_FAILED_VMENTRY 0x80000000
245
246#define EXIT_REASON_EXCEPTION_NMI 0
247#define EXIT_REASON_EXTERNAL_INTERRUPT 1
248#define EXIT_REASON_TRIPLE_FAULT 2
249
250#define EXIT_REASON_PENDING_INTERRUPT 7
251#define EXIT_REASON_NMI_WINDOW 8
252#define EXIT_REASON_TASK_SWITCH 9
253#define EXIT_REASON_CPUID 10
254#define EXIT_REASON_HLT 12
255#define EXIT_REASON_INVD 13
256#define EXIT_REASON_INVLPG 14
257#define EXIT_REASON_RDPMC 15
258#define EXIT_REASON_RDTSC 16
259#define EXIT_REASON_VMCALL 18
260#define EXIT_REASON_VMCLEAR 19
261#define EXIT_REASON_VMLAUNCH 20
262#define EXIT_REASON_VMPTRLD 21
263#define EXIT_REASON_VMPTRST 22
264#define EXIT_REASON_VMREAD 23
265#define EXIT_REASON_VMRESUME 24
266#define EXIT_REASON_VMWRITE 25
267#define EXIT_REASON_VMOFF 26
268#define EXIT_REASON_VMON 27
269#define EXIT_REASON_CR_ACCESS 28
270#define EXIT_REASON_DR_ACCESS 29
271#define EXIT_REASON_IO_INSTRUCTION 30
272#define EXIT_REASON_MSR_READ 31
273#define EXIT_REASON_MSR_WRITE 32
274#define EXIT_REASON_INVALID_STATE 33
275#define EXIT_REASON_MWAIT_INSTRUCTION 36
276#define EXIT_REASON_MONITOR_INSTRUCTION 39
277#define EXIT_REASON_PAUSE_INSTRUCTION 40
278#define EXIT_REASON_MCE_DURING_VMENTRY 41
279#define EXIT_REASON_TPR_BELOW_THRESHOLD 43
280#define EXIT_REASON_APIC_ACCESS 44
281#define EXIT_REASON_EPT_VIOLATION 48
282#define EXIT_REASON_EPT_MISCONFIG 49
283#define EXIT_REASON_WBINVD 54
284#define EXIT_REASON_XSETBV 55
285#define EXIT_REASON_INVPCID 58
286
287/* 326/*
288 * Interruption-information format 327 * Interruption-information format
289 */ 328 */
@@ -488,3 +527,5 @@ enum vm_instruction_error_number {
488}; 527};
489 528
490#endif 529#endif
530
531#endif
diff --git a/arch/x86/kvm/trace.h b/arch/x86/kvm/trace.h
index a71faf727ff3..bca63f04dccb 100644
--- a/arch/x86/kvm/trace.h
+++ b/arch/x86/kvm/trace.h
@@ -183,95 +183,6 @@ TRACE_EVENT(kvm_apic,
183#define KVM_ISA_VMX 1 183#define KVM_ISA_VMX 1
184#define KVM_ISA_SVM 2 184#define KVM_ISA_SVM 2
185 185
186#define VMX_EXIT_REASONS \
187 { EXIT_REASON_EXCEPTION_NMI, "EXCEPTION_NMI" }, \
188 { EXIT_REASON_EXTERNAL_INTERRUPT, "EXTERNAL_INTERRUPT" }, \
189 { EXIT_REASON_TRIPLE_FAULT, "TRIPLE_FAULT" }, \
190 { EXIT_REASON_PENDING_INTERRUPT, "PENDING_INTERRUPT" }, \
191 { EXIT_REASON_NMI_WINDOW, "NMI_WINDOW" }, \
192 { EXIT_REASON_TASK_SWITCH, "TASK_SWITCH" }, \
193 { EXIT_REASON_CPUID, "CPUID" }, \
194 { EXIT_REASON_HLT, "HLT" }, \
195 { EXIT_REASON_INVLPG, "INVLPG" }, \
196 { EXIT_REASON_RDPMC, "RDPMC" }, \
197 { EXIT_REASON_RDTSC, "RDTSC" }, \
198 { EXIT_REASON_VMCALL, "VMCALL" }, \
199 { EXIT_REASON_VMCLEAR, "VMCLEAR" }, \
200 { EXIT_REASON_VMLAUNCH, "VMLAUNCH" }, \
201 { EXIT_REASON_VMPTRLD, "VMPTRLD" }, \
202 { EXIT_REASON_VMPTRST, "VMPTRST" }, \
203 { EXIT_REASON_VMREAD, "VMREAD" }, \
204 { EXIT_REASON_VMRESUME, "VMRESUME" }, \
205 { EXIT_REASON_VMWRITE, "VMWRITE" }, \
206 { EXIT_REASON_VMOFF, "VMOFF" }, \
207 { EXIT_REASON_VMON, "VMON" }, \
208 { EXIT_REASON_CR_ACCESS, "CR_ACCESS" }, \
209 { EXIT_REASON_DR_ACCESS, "DR_ACCESS" }, \
210 { EXIT_REASON_IO_INSTRUCTION, "IO_INSTRUCTION" }, \
211 { EXIT_REASON_MSR_READ, "MSR_READ" }, \
212 { EXIT_REASON_MSR_WRITE, "MSR_WRITE" }, \
213 { EXIT_REASON_MWAIT_INSTRUCTION, "MWAIT_INSTRUCTION" }, \
214 { EXIT_REASON_MONITOR_INSTRUCTION, "MONITOR_INSTRUCTION" }, \
215 { EXIT_REASON_PAUSE_INSTRUCTION, "PAUSE_INSTRUCTION" }, \
216 { EXIT_REASON_MCE_DURING_VMENTRY, "MCE_DURING_VMENTRY" }, \
217 { EXIT_REASON_TPR_BELOW_THRESHOLD, "TPR_BELOW_THRESHOLD" }, \
218 { EXIT_REASON_APIC_ACCESS, "APIC_ACCESS" }, \
219 { EXIT_REASON_EPT_VIOLATION, "EPT_VIOLATION" }, \
220 { EXIT_REASON_EPT_MISCONFIG, "EPT_MISCONFIG" }, \
221 { EXIT_REASON_WBINVD, "WBINVD" }
222
223#define SVM_EXIT_REASONS \
224 { SVM_EXIT_READ_CR0, "read_cr0" }, \
225 { SVM_EXIT_READ_CR3, "read_cr3" }, \
226 { SVM_EXIT_READ_CR4, "read_cr4" }, \
227 { SVM_EXIT_READ_CR8, "read_cr8" }, \
228 { SVM_EXIT_WRITE_CR0, "write_cr0" }, \
229 { SVM_EXIT_WRITE_CR3, "write_cr3" }, \
230 { SVM_EXIT_WRITE_CR4, "write_cr4" }, \
231 { SVM_EXIT_WRITE_CR8, "write_cr8" }, \
232 { SVM_EXIT_READ_DR0, "read_dr0" }, \
233 { SVM_EXIT_READ_DR1, "read_dr1" }, \
234 { SVM_EXIT_READ_DR2, "read_dr2" }, \
235 { SVM_EXIT_READ_DR3, "read_dr3" }, \
236 { SVM_EXIT_WRITE_DR0, "write_dr0" }, \
237 { SVM_EXIT_WRITE_DR1, "write_dr1" }, \
238 { SVM_EXIT_WRITE_DR2, "write_dr2" }, \
239 { SVM_EXIT_WRITE_DR3, "write_dr3" }, \
240 { SVM_EXIT_WRITE_DR5, "write_dr5" }, \
241 { SVM_EXIT_WRITE_DR7, "write_dr7" }, \
242 { SVM_EXIT_EXCP_BASE + DB_VECTOR, "DB excp" }, \
243 { SVM_EXIT_EXCP_BASE + BP_VECTOR, "BP excp" }, \
244 { SVM_EXIT_EXCP_BASE + UD_VECTOR, "UD excp" }, \
245 { SVM_EXIT_EXCP_BASE + PF_VECTOR, "PF excp" }, \
246 { SVM_EXIT_EXCP_BASE + NM_VECTOR, "NM excp" }, \
247 { SVM_EXIT_EXCP_BASE + MC_VECTOR, "MC excp" }, \
248 { SVM_EXIT_INTR, "interrupt" }, \
249 { SVM_EXIT_NMI, "nmi" }, \
250 { SVM_EXIT_SMI, "smi" }, \
251 { SVM_EXIT_INIT, "init" }, \
252 { SVM_EXIT_VINTR, "vintr" }, \
253 { SVM_EXIT_CPUID, "cpuid" }, \
254 { SVM_EXIT_INVD, "invd" }, \
255 { SVM_EXIT_HLT, "hlt" }, \
256 { SVM_EXIT_INVLPG, "invlpg" }, \
257 { SVM_EXIT_INVLPGA, "invlpga" }, \
258 { SVM_EXIT_IOIO, "io" }, \
259 { SVM_EXIT_MSR, "msr" }, \
260 { SVM_EXIT_TASK_SWITCH, "task_switch" }, \
261 { SVM_EXIT_SHUTDOWN, "shutdown" }, \
262 { SVM_EXIT_VMRUN, "vmrun" }, \
263 { SVM_EXIT_VMMCALL, "hypercall" }, \
264 { SVM_EXIT_VMLOAD, "vmload" }, \
265 { SVM_EXIT_VMSAVE, "vmsave" }, \
266 { SVM_EXIT_STGI, "stgi" }, \
267 { SVM_EXIT_CLGI, "clgi" }, \
268 { SVM_EXIT_SKINIT, "skinit" }, \
269 { SVM_EXIT_WBINVD, "wbinvd" }, \
270 { SVM_EXIT_MONITOR, "monitor" }, \
271 { SVM_EXIT_MWAIT, "mwait" }, \
272 { SVM_EXIT_XSETBV, "xsetbv" }, \
273 { SVM_EXIT_NPF, "npf" }
274
275/* 186/*
276 * Tracepoint for kvm guest exit: 187 * Tracepoint for kvm guest exit:
277 */ 188 */
diff --git a/tools/lib/traceevent/event-parse.c b/tools/lib/traceevent/event-parse.c
index 77ebeb8266f4..17c922145e88 100644
--- a/tools/lib/traceevent/event-parse.c
+++ b/tools/lib/traceevent/event-parse.c
@@ -31,6 +31,7 @@
31#include <ctype.h> 31#include <ctype.h>
32#include <errno.h> 32#include <errno.h>
33#include <stdint.h> 33#include <stdint.h>
34#include <limits.h>
34 35
35#include "event-parse.h" 36#include "event-parse.h"
36#include "event-utils.h" 37#include "event-utils.h"
@@ -117,14 +118,7 @@ void breakpoint(void)
117 118
118struct print_arg *alloc_arg(void) 119struct print_arg *alloc_arg(void)
119{ 120{
120 struct print_arg *arg; 121 return calloc(1, sizeof(struct print_arg));
121
122 arg = malloc_or_die(sizeof(*arg));
123 if (!arg)
124 return NULL;
125 memset(arg, 0, sizeof(*arg));
126
127 return arg;
128} 122}
129 123
130struct cmdline { 124struct cmdline {
@@ -158,7 +152,9 @@ static int cmdline_init(struct pevent *pevent)
158 struct cmdline *cmdlines; 152 struct cmdline *cmdlines;
159 int i; 153 int i;
160 154
161 cmdlines = malloc_or_die(sizeof(*cmdlines) * pevent->cmdline_count); 155 cmdlines = malloc(sizeof(*cmdlines) * pevent->cmdline_count);
156 if (!cmdlines)
157 return -1;
162 158
163 i = 0; 159 i = 0;
164 while (cmdlist) { 160 while (cmdlist) {
@@ -186,8 +182,8 @@ static char *find_cmdline(struct pevent *pevent, int pid)
186 if (!pid) 182 if (!pid)
187 return "<idle>"; 183 return "<idle>";
188 184
189 if (!pevent->cmdlines) 185 if (!pevent->cmdlines && cmdline_init(pevent))
190 cmdline_init(pevent); 186 return "<not enough memory for cmdlines!>";
191 187
192 key.pid = pid; 188 key.pid = pid;
193 189
@@ -215,8 +211,8 @@ int pevent_pid_is_registered(struct pevent *pevent, int pid)
215 if (!pid) 211 if (!pid)
216 return 1; 212 return 1;
217 213
218 if (!pevent->cmdlines) 214 if (!pevent->cmdlines && cmdline_init(pevent))
219 cmdline_init(pevent); 215 return 0;
220 216
221 key.pid = pid; 217 key.pid = pid;
222 218
@@ -258,10 +254,14 @@ static int add_new_comm(struct pevent *pevent, const char *comm, int pid)
258 return -1; 254 return -1;
259 } 255 }
260 256
261 cmdlines[pevent->cmdline_count].pid = pid;
262 cmdlines[pevent->cmdline_count].comm = strdup(comm); 257 cmdlines[pevent->cmdline_count].comm = strdup(comm);
263 if (!cmdlines[pevent->cmdline_count].comm) 258 if (!cmdlines[pevent->cmdline_count].comm) {
264 die("malloc comm"); 259 free(cmdlines);
260 errno = ENOMEM;
261 return -1;
262 }
263
264 cmdlines[pevent->cmdline_count].pid = pid;
265 265
266 if (cmdlines[pevent->cmdline_count].comm) 266 if (cmdlines[pevent->cmdline_count].comm)
267 pevent->cmdline_count++; 267 pevent->cmdline_count++;
@@ -288,10 +288,15 @@ int pevent_register_comm(struct pevent *pevent, const char *comm, int pid)
288 if (pevent->cmdlines) 288 if (pevent->cmdlines)
289 return add_new_comm(pevent, comm, pid); 289 return add_new_comm(pevent, comm, pid);
290 290
291 item = malloc_or_die(sizeof(*item)); 291 item = malloc(sizeof(*item));
292 if (!item)
293 return -1;
294
292 item->comm = strdup(comm); 295 item->comm = strdup(comm);
293 if (!item->comm) 296 if (!item->comm) {
294 die("malloc comm"); 297 free(item);
298 return -1;
299 }
295 item->pid = pid; 300 item->pid = pid;
296 item->next = pevent->cmdlist; 301 item->next = pevent->cmdlist;
297 302
@@ -355,7 +360,10 @@ static int func_map_init(struct pevent *pevent)
355 struct func_map *func_map; 360 struct func_map *func_map;
356 int i; 361 int i;
357 362
358 func_map = malloc_or_die(sizeof(*func_map) * (pevent->func_count + 1)); 363 func_map = malloc(sizeof(*func_map) * (pevent->func_count + 1));
364 if (!func_map)
365 return -1;
366
359 funclist = pevent->funclist; 367 funclist = pevent->funclist;
360 368
361 i = 0; 369 i = 0;
@@ -455,25 +463,36 @@ pevent_find_function_address(struct pevent *pevent, unsigned long long addr)
455int pevent_register_function(struct pevent *pevent, char *func, 463int pevent_register_function(struct pevent *pevent, char *func,
456 unsigned long long addr, char *mod) 464 unsigned long long addr, char *mod)
457{ 465{
458 struct func_list *item; 466 struct func_list *item = malloc(sizeof(*item));
459 467
460 item = malloc_or_die(sizeof(*item)); 468 if (!item)
469 return -1;
461 470
462 item->next = pevent->funclist; 471 item->next = pevent->funclist;
463 item->func = strdup(func); 472 item->func = strdup(func);
464 if (mod) 473 if (!item->func)
474 goto out_free;
475
476 if (mod) {
465 item->mod = strdup(mod); 477 item->mod = strdup(mod);
466 else 478 if (!item->mod)
479 goto out_free_func;
480 } else
467 item->mod = NULL; 481 item->mod = NULL;
468 item->addr = addr; 482 item->addr = addr;
469 483
470 if (!item->func || (mod && !item->mod))
471 die("malloc func");
472
473 pevent->funclist = item; 484 pevent->funclist = item;
474 pevent->func_count++; 485 pevent->func_count++;
475 486
476 return 0; 487 return 0;
488
489out_free_func:
490 free(item->func);
491 item->func = NULL;
492out_free:
493 free(item);
494 errno = ENOMEM;
495 return -1;
477} 496}
478 497
479/** 498/**
@@ -524,14 +543,16 @@ static int printk_cmp(const void *a, const void *b)
524 return 0; 543 return 0;
525} 544}
526 545
527static void printk_map_init(struct pevent *pevent) 546static int printk_map_init(struct pevent *pevent)
528{ 547{
529 struct printk_list *printklist; 548 struct printk_list *printklist;
530 struct printk_list *item; 549 struct printk_list *item;
531 struct printk_map *printk_map; 550 struct printk_map *printk_map;
532 int i; 551 int i;
533 552
534 printk_map = malloc_or_die(sizeof(*printk_map) * (pevent->printk_count + 1)); 553 printk_map = malloc(sizeof(*printk_map) * (pevent->printk_count + 1));
554 if (!printk_map)
555 return -1;
535 556
536 printklist = pevent->printklist; 557 printklist = pevent->printklist;
537 558
@@ -549,6 +570,8 @@ static void printk_map_init(struct pevent *pevent)
549 570
550 pevent->printk_map = printk_map; 571 pevent->printk_map = printk_map;
551 pevent->printklist = NULL; 572 pevent->printklist = NULL;
573
574 return 0;
552} 575}
553 576
554static struct printk_map * 577static struct printk_map *
@@ -557,8 +580,8 @@ find_printk(struct pevent *pevent, unsigned long long addr)
557 struct printk_map *printk; 580 struct printk_map *printk;
558 struct printk_map key; 581 struct printk_map key;
559 582
560 if (!pevent->printk_map) 583 if (!pevent->printk_map && printk_map_init(pevent))
561 printk_map_init(pevent); 584 return NULL;
562 585
563 key.addr = addr; 586 key.addr = addr;
564 587
@@ -580,21 +603,27 @@ find_printk(struct pevent *pevent, unsigned long long addr)
580int pevent_register_print_string(struct pevent *pevent, char *fmt, 603int pevent_register_print_string(struct pevent *pevent, char *fmt,
581 unsigned long long addr) 604 unsigned long long addr)
582{ 605{
583 struct printk_list *item; 606 struct printk_list *item = malloc(sizeof(*item));
584 607
585 item = malloc_or_die(sizeof(*item)); 608 if (!item)
609 return -1;
586 610
587 item->next = pevent->printklist; 611 item->next = pevent->printklist;
588 item->printk = strdup(fmt);
589 item->addr = addr; 612 item->addr = addr;
590 613
614 item->printk = strdup(fmt);
591 if (!item->printk) 615 if (!item->printk)
592 die("malloc fmt"); 616 goto out_free;
593 617
594 pevent->printklist = item; 618 pevent->printklist = item;
595 pevent->printk_count++; 619 pevent->printk_count++;
596 620
597 return 0; 621 return 0;
622
623out_free:
624 free(item);
625 errno = ENOMEM;
626 return -1;
598} 627}
599 628
600/** 629/**
@@ -619,24 +648,18 @@ void pevent_print_printk(struct pevent *pevent)
619 648
620static struct event_format *alloc_event(void) 649static struct event_format *alloc_event(void)
621{ 650{
622 struct event_format *event; 651 return calloc(1, sizeof(struct event_format));
623
624 event = malloc(sizeof(*event));
625 if (!event)
626 return NULL;
627 memset(event, 0, sizeof(*event));
628
629 return event;
630} 652}
631 653
632static void add_event(struct pevent *pevent, struct event_format *event) 654static int add_event(struct pevent *pevent, struct event_format *event)
633{ 655{
634 int i; 656 int i;
657 struct event_format **events = realloc(pevent->events, sizeof(event) *
658 (pevent->nr_events + 1));
659 if (!events)
660 return -1;
635 661
636 pevent->events = realloc(pevent->events, sizeof(event) * 662 pevent->events = events;
637 (pevent->nr_events + 1));
638 if (!pevent->events)
639 die("Can not allocate events");
640 663
641 for (i = 0; i < pevent->nr_events; i++) { 664 for (i = 0; i < pevent->nr_events; i++) {
642 if (pevent->events[i]->id > event->id) 665 if (pevent->events[i]->id > event->id)
@@ -651,6 +674,8 @@ static void add_event(struct pevent *pevent, struct event_format *event)
651 pevent->nr_events++; 674 pevent->nr_events++;
652 675
653 event->pevent = pevent; 676 event->pevent = pevent;
677
678 return 0;
654} 679}
655 680
656static int event_item_type(enum event_type type) 681static int event_item_type(enum event_type type)
@@ -827,9 +852,9 @@ static enum event_type __read_token(char **tok)
827 switch (type) { 852 switch (type) {
828 case EVENT_NEWLINE: 853 case EVENT_NEWLINE:
829 case EVENT_DELIM: 854 case EVENT_DELIM:
830 *tok = malloc_or_die(2); 855 if (asprintf(tok, "%c", ch) < 0)
831 (*tok)[0] = ch; 856 return EVENT_ERROR;
832 (*tok)[1] = 0; 857
833 return type; 858 return type;
834 859
835 case EVENT_OP: 860 case EVENT_OP:
@@ -1240,8 +1265,10 @@ static int event_read_fields(struct event_format *event, struct format_field **f
1240 1265
1241 last_token = token; 1266 last_token = token;
1242 1267
1243 field = malloc_or_die(sizeof(*field)); 1268 field = calloc(1, sizeof(*field));
1244 memset(field, 0, sizeof(*field)); 1269 if (!field)
1270 goto fail;
1271
1245 field->event = event; 1272 field->event = event;
1246 1273
1247 /* read the rest of the type */ 1274 /* read the rest of the type */
@@ -1282,7 +1309,7 @@ static int event_read_fields(struct event_format *event, struct format_field **f
1282 } 1309 }
1283 1310
1284 if (!field->type) { 1311 if (!field->type) {
1285 die("no type found"); 1312 do_warning("%s: no type found", __func__);
1286 goto fail; 1313 goto fail;
1287 } 1314 }
1288 field->name = last_token; 1315 field->name = last_token;
@@ -1329,7 +1356,7 @@ static int event_read_fields(struct event_format *event, struct format_field **f
1329 free_token(token); 1356 free_token(token);
1330 type = read_token(&token); 1357 type = read_token(&token);
1331 if (type == EVENT_NONE) { 1358 if (type == EVENT_NONE) {
1332 die("failed to find token"); 1359 do_warning("failed to find token");
1333 goto fail; 1360 goto fail;
1334 } 1361 }
1335 } 1362 }
@@ -1538,6 +1565,14 @@ process_cond(struct event_format *event, struct print_arg *top, char **tok)
1538 left = alloc_arg(); 1565 left = alloc_arg();
1539 right = alloc_arg(); 1566 right = alloc_arg();
1540 1567
1568 if (!arg || !left || !right) {
1569 do_warning("%s: not enough memory!", __func__);
1570 /* arg will be freed at out_free */
1571 free_arg(left);
1572 free_arg(right);
1573 goto out_free;
1574 }
1575
1541 arg->type = PRINT_OP; 1576 arg->type = PRINT_OP;
1542 arg->op.left = left; 1577 arg->op.left = left;
1543 arg->op.right = right; 1578 arg->op.right = right;
@@ -1580,6 +1615,12 @@ process_array(struct event_format *event, struct print_arg *top, char **tok)
1580 char *token = NULL; 1615 char *token = NULL;
1581 1616
1582 arg = alloc_arg(); 1617 arg = alloc_arg();
1618 if (!arg) {
1619 do_warning("%s: not enough memory!", __func__);
1620 /* '*tok' is set to top->op.op. No need to free. */
1621 *tok = NULL;
1622 return EVENT_ERROR;
1623 }
1583 1624
1584 *tok = NULL; 1625 *tok = NULL;
1585 type = process_arg(event, arg, &token); 1626 type = process_arg(event, arg, &token);
@@ -1595,8 +1636,7 @@ process_array(struct event_format *event, struct print_arg *top, char **tok)
1595 return type; 1636 return type;
1596 1637
1597out_free: 1638out_free:
1598 free_token(*tok); 1639 free_token(token);
1599 *tok = NULL;
1600 free_arg(arg); 1640 free_arg(arg);
1601 return EVENT_ERROR; 1641 return EVENT_ERROR;
1602} 1642}
@@ -1682,7 +1722,7 @@ process_op(struct event_format *event, struct print_arg *arg, char **tok)
1682 if (arg->type == PRINT_OP && !arg->op.left) { 1722 if (arg->type == PRINT_OP && !arg->op.left) {
1683 /* handle single op */ 1723 /* handle single op */
1684 if (token[1]) { 1724 if (token[1]) {
1685 die("bad op token %s", token); 1725 do_warning("bad op token %s", token);
1686 goto out_free; 1726 goto out_free;
1687 } 1727 }
1688 switch (token[0]) { 1728 switch (token[0]) {
@@ -1699,10 +1739,16 @@ process_op(struct event_format *event, struct print_arg *arg, char **tok)
1699 1739
1700 /* make an empty left */ 1740 /* make an empty left */
1701 left = alloc_arg(); 1741 left = alloc_arg();
1742 if (!left)
1743 goto out_warn_free;
1744
1702 left->type = PRINT_NULL; 1745 left->type = PRINT_NULL;
1703 arg->op.left = left; 1746 arg->op.left = left;
1704 1747
1705 right = alloc_arg(); 1748 right = alloc_arg();
1749 if (!right)
1750 goto out_warn_free;
1751
1706 arg->op.right = right; 1752 arg->op.right = right;
1707 1753
1708 /* do not free the token, it belongs to an op */ 1754 /* do not free the token, it belongs to an op */
@@ -1712,6 +1758,9 @@ process_op(struct event_format *event, struct print_arg *arg, char **tok)
1712 } else if (strcmp(token, "?") == 0) { 1758 } else if (strcmp(token, "?") == 0) {
1713 1759
1714 left = alloc_arg(); 1760 left = alloc_arg();
1761 if (!left)
1762 goto out_warn_free;
1763
1715 /* copy the top arg to the left */ 1764 /* copy the top arg to the left */
1716 *left = *arg; 1765 *left = *arg;
1717 1766
@@ -1720,6 +1769,7 @@ process_op(struct event_format *event, struct print_arg *arg, char **tok)
1720 arg->op.left = left; 1769 arg->op.left = left;
1721 arg->op.prio = 0; 1770 arg->op.prio = 0;
1722 1771
1772 /* it will set arg->op.right */
1723 type = process_cond(event, arg, tok); 1773 type = process_cond(event, arg, tok);
1724 1774
1725 } else if (strcmp(token, ">>") == 0 || 1775 } else if (strcmp(token, ">>") == 0 ||
@@ -1739,6 +1789,8 @@ process_op(struct event_format *event, struct print_arg *arg, char **tok)
1739 strcmp(token, "!=") == 0) { 1789 strcmp(token, "!=") == 0) {
1740 1790
1741 left = alloc_arg(); 1791 left = alloc_arg();
1792 if (!left)
1793 goto out_warn_free;
1742 1794
1743 /* copy the top arg to the left */ 1795 /* copy the top arg to the left */
1744 *left = *arg; 1796 *left = *arg;
@@ -1746,6 +1798,7 @@ process_op(struct event_format *event, struct print_arg *arg, char **tok)
1746 arg->type = PRINT_OP; 1798 arg->type = PRINT_OP;
1747 arg->op.op = token; 1799 arg->op.op = token;
1748 arg->op.left = left; 1800 arg->op.left = left;
1801 arg->op.right = NULL;
1749 1802
1750 if (set_op_prio(arg) == -1) { 1803 if (set_op_prio(arg) == -1) {
1751 event->flags |= EVENT_FL_FAILED; 1804 event->flags |= EVENT_FL_FAILED;
@@ -1762,12 +1815,14 @@ process_op(struct event_format *event, struct print_arg *arg, char **tok)
1762 type == EVENT_DELIM && (strcmp(token, ")") == 0)) { 1815 type == EVENT_DELIM && (strcmp(token, ")") == 0)) {
1763 char *new_atom; 1816 char *new_atom;
1764 1817
1765 if (left->type != PRINT_ATOM) 1818 if (left->type != PRINT_ATOM) {
1766 die("bad pointer type"); 1819 do_warning("bad pointer type");
1820 goto out_free;
1821 }
1767 new_atom = realloc(left->atom.atom, 1822 new_atom = realloc(left->atom.atom,
1768 strlen(left->atom.atom) + 3); 1823 strlen(left->atom.atom) + 3);
1769 if (!new_atom) 1824 if (!new_atom)
1770 goto out_free; 1825 goto out_warn_free;
1771 1826
1772 left->atom.atom = new_atom; 1827 left->atom.atom = new_atom;
1773 strcat(left->atom.atom, " *"); 1828 strcat(left->atom.atom, " *");
@@ -1779,12 +1834,18 @@ process_op(struct event_format *event, struct print_arg *arg, char **tok)
1779 } 1834 }
1780 1835
1781 right = alloc_arg(); 1836 right = alloc_arg();
1837 if (!right)
1838 goto out_warn_free;
1839
1782 type = process_arg_token(event, right, tok, type); 1840 type = process_arg_token(event, right, tok, type);
1783 arg->op.right = right; 1841 arg->op.right = right;
1784 1842
1785 } else if (strcmp(token, "[") == 0) { 1843 } else if (strcmp(token, "[") == 0) {
1786 1844
1787 left = alloc_arg(); 1845 left = alloc_arg();
1846 if (!left)
1847 goto out_warn_free;
1848
1788 *left = *arg; 1849 *left = *arg;
1789 1850
1790 arg->type = PRINT_OP; 1851 arg->type = PRINT_OP;
@@ -1793,6 +1854,7 @@ process_op(struct event_format *event, struct print_arg *arg, char **tok)
1793 1854
1794 arg->op.prio = 0; 1855 arg->op.prio = 0;
1795 1856
1857 /* it will set arg->op.right */
1796 type = process_array(event, arg, tok); 1858 type = process_array(event, arg, tok);
1797 1859
1798 } else { 1860 } else {
@@ -1816,7 +1878,9 @@ process_op(struct event_format *event, struct print_arg *arg, char **tok)
1816 1878
1817 return type; 1879 return type;
1818 1880
1819 out_free: 1881out_warn_free:
1882 do_warning("%s: not enough memory!", __func__);
1883out_free:
1820 free_token(token); 1884 free_token(token);
1821 *tok = NULL; 1885 *tok = NULL;
1822 return EVENT_ERROR; 1886 return EVENT_ERROR;
@@ -1880,7 +1944,11 @@ eval_type_str(unsigned long long val, const char *type, int pointer)
1880 return val; 1944 return val;
1881 } 1945 }
1882 1946
1883 ref = malloc_or_die(len); 1947 ref = malloc(len);
1948 if (!ref) {
1949 do_warning("%s: not enough memory!", __func__);
1950 return val;
1951 }
1884 memcpy(ref, type, len); 1952 memcpy(ref, type, len);
1885 1953
1886 /* chop off the " *" */ 1954 /* chop off the " *" */
@@ -1957,8 +2025,10 @@ eval_type_str(unsigned long long val, const char *type, int pointer)
1957static unsigned long long 2025static unsigned long long
1958eval_type(unsigned long long val, struct print_arg *arg, int pointer) 2026eval_type(unsigned long long val, struct print_arg *arg, int pointer)
1959{ 2027{
1960 if (arg->type != PRINT_TYPE) 2028 if (arg->type != PRINT_TYPE) {
1961 die("expected type argument"); 2029 do_warning("expected type argument");
2030 return 0;
2031 }
1962 2032
1963 return eval_type_str(val, arg->typecast.type, pointer); 2033 return eval_type_str(val, arg->typecast.type, pointer);
1964} 2034}
@@ -2143,7 +2213,7 @@ static char *arg_eval (struct print_arg *arg)
2143 case PRINT_STRING: 2213 case PRINT_STRING:
2144 case PRINT_BSTRING: 2214 case PRINT_BSTRING:
2145 default: 2215 default:
2146 die("invalid eval type %d", arg->type); 2216 do_warning("invalid eval type %d", arg->type);
2147 break; 2217 break;
2148 } 2218 }
2149 2219
@@ -2166,6 +2236,8 @@ process_fields(struct event_format *event, struct print_flag_sym **list, char **
2166 break; 2236 break;
2167 2237
2168 arg = alloc_arg(); 2238 arg = alloc_arg();
2239 if (!arg)
2240 goto out_free;
2169 2241
2170 free_token(token); 2242 free_token(token);
2171 type = process_arg(event, arg, &token); 2243 type = process_arg(event, arg, &token);
@@ -2179,30 +2251,33 @@ process_fields(struct event_format *event, struct print_flag_sym **list, char **
2179 if (test_type_token(type, token, EVENT_DELIM, ",")) 2251 if (test_type_token(type, token, EVENT_DELIM, ","))
2180 goto out_free; 2252 goto out_free;
2181 2253
2182 field = malloc_or_die(sizeof(*field)); 2254 field = calloc(1, sizeof(*field));
2183 memset(field, 0, sizeof(*field)); 2255 if (!field)
2256 goto out_free;
2184 2257
2185 value = arg_eval(arg); 2258 value = arg_eval(arg);
2186 if (value == NULL) 2259 if (value == NULL)
2187 goto out_free; 2260 goto out_free_field;
2188 field->value = strdup(value); 2261 field->value = strdup(value);
2189 if (field->value == NULL) 2262 if (field->value == NULL)
2190 goto out_free; 2263 goto out_free_field;
2191 2264
2192 free_arg(arg); 2265 free_arg(arg);
2193 arg = alloc_arg(); 2266 arg = alloc_arg();
2267 if (!arg)
2268 goto out_free;
2194 2269
2195 free_token(token); 2270 free_token(token);
2196 type = process_arg(event, arg, &token); 2271 type = process_arg(event, arg, &token);
2197 if (test_type_token(type, token, EVENT_OP, "}")) 2272 if (test_type_token(type, token, EVENT_OP, "}"))
2198 goto out_free; 2273 goto out_free_field;
2199 2274
2200 value = arg_eval(arg); 2275 value = arg_eval(arg);
2201 if (value == NULL) 2276 if (value == NULL)
2202 goto out_free; 2277 goto out_free_field;
2203 field->str = strdup(value); 2278 field->str = strdup(value);
2204 if (field->str == NULL) 2279 if (field->str == NULL)
2205 goto out_free; 2280 goto out_free_field;
2206 free_arg(arg); 2281 free_arg(arg);
2207 arg = NULL; 2282 arg = NULL;
2208 2283
@@ -2216,6 +2291,8 @@ process_fields(struct event_format *event, struct print_flag_sym **list, char **
2216 *tok = token; 2291 *tok = token;
2217 return type; 2292 return type;
2218 2293
2294out_free_field:
2295 free_flag_sym(field);
2219out_free: 2296out_free:
2220 free_arg(arg); 2297 free_arg(arg);
2221 free_token(token); 2298 free_token(token);
@@ -2235,6 +2312,10 @@ process_flags(struct event_format *event, struct print_arg *arg, char **tok)
2235 arg->type = PRINT_FLAGS; 2312 arg->type = PRINT_FLAGS;
2236 2313
2237 field = alloc_arg(); 2314 field = alloc_arg();
2315 if (!field) {
2316 do_warning("%s: not enough memory!", __func__);
2317 goto out_free;
2318 }
2238 2319
2239 type = process_arg(event, field, &token); 2320 type = process_arg(event, field, &token);
2240 2321
@@ -2243,7 +2324,7 @@ process_flags(struct event_format *event, struct print_arg *arg, char **tok)
2243 type = process_op(event, field, &token); 2324 type = process_op(event, field, &token);
2244 2325
2245 if (test_type_token(type, token, EVENT_DELIM, ",")) 2326 if (test_type_token(type, token, EVENT_DELIM, ","))
2246 goto out_free; 2327 goto out_free_field;
2247 free_token(token); 2328 free_token(token);
2248 2329
2249 arg->flags.field = field; 2330 arg->flags.field = field;
@@ -2265,7 +2346,9 @@ process_flags(struct event_format *event, struct print_arg *arg, char **tok)
2265 type = read_token_item(tok); 2346 type = read_token_item(tok);
2266 return type; 2347 return type;
2267 2348
2268 out_free: 2349out_free_field:
2350 free_arg(field);
2351out_free:
2269 free_token(token); 2352 free_token(token);
2270 *tok = NULL; 2353 *tok = NULL;
2271 return EVENT_ERROR; 2354 return EVENT_ERROR;
@@ -2282,10 +2365,14 @@ process_symbols(struct event_format *event, struct print_arg *arg, char **tok)
2282 arg->type = PRINT_SYMBOL; 2365 arg->type = PRINT_SYMBOL;
2283 2366
2284 field = alloc_arg(); 2367 field = alloc_arg();
2368 if (!field) {
2369 do_warning("%s: not enough memory!", __func__);
2370 goto out_free;
2371 }
2285 2372
2286 type = process_arg(event, field, &token); 2373 type = process_arg(event, field, &token);
2287 if (test_type_token(type, token, EVENT_DELIM, ",")) 2374 if (test_type_token(type, token, EVENT_DELIM, ","))
2288 goto out_free; 2375 goto out_free_field;
2289 2376
2290 arg->symbol.field = field; 2377 arg->symbol.field = field;
2291 2378
@@ -2297,7 +2384,9 @@ process_symbols(struct event_format *event, struct print_arg *arg, char **tok)
2297 type = read_token_item(tok); 2384 type = read_token_item(tok);
2298 return type; 2385 return type;
2299 2386
2300 out_free: 2387out_free_field:
2388 free_arg(field);
2389out_free:
2301 free_token(token); 2390 free_token(token);
2302 *tok = NULL; 2391 *tok = NULL;
2303 return EVENT_ERROR; 2392 return EVENT_ERROR;
@@ -2314,6 +2403,11 @@ process_hex(struct event_format *event, struct print_arg *arg, char **tok)
2314 arg->type = PRINT_HEX; 2403 arg->type = PRINT_HEX;
2315 2404
2316 field = alloc_arg(); 2405 field = alloc_arg();
2406 if (!field) {
2407 do_warning("%s: not enough memory!", __func__);
2408 goto out_free;
2409 }
2410
2317 type = process_arg(event, field, &token); 2411 type = process_arg(event, field, &token);
2318 2412
2319 if (test_type_token(type, token, EVENT_DELIM, ",")) 2413 if (test_type_token(type, token, EVENT_DELIM, ","))
@@ -2324,6 +2418,12 @@ process_hex(struct event_format *event, struct print_arg *arg, char **tok)
2324 free_token(token); 2418 free_token(token);
2325 2419
2326 field = alloc_arg(); 2420 field = alloc_arg();
2421 if (!field) {
2422 do_warning("%s: not enough memory!", __func__);
2423 *tok = NULL;
2424 return EVENT_ERROR;
2425 }
2426
2327 type = process_arg(event, field, &token); 2427 type = process_arg(event, field, &token);
2328 2428
2329 if (test_type_token(type, token, EVENT_DELIM, ")")) 2429 if (test_type_token(type, token, EVENT_DELIM, ")"))
@@ -2381,6 +2481,12 @@ process_dynamic_array(struct event_format *event, struct print_arg *arg, char **
2381 2481
2382 free_token(token); 2482 free_token(token);
2383 arg = alloc_arg(); 2483 arg = alloc_arg();
2484 if (!field) {
2485 do_warning("%s: not enough memory!", __func__);
2486 *tok = NULL;
2487 return EVENT_ERROR;
2488 }
2489
2384 type = process_arg(event, arg, &token); 2490 type = process_arg(event, arg, &token);
2385 if (type == EVENT_ERROR) 2491 if (type == EVENT_ERROR)
2386 goto out_free_arg; 2492 goto out_free_arg;
@@ -2434,10 +2540,16 @@ process_paren(struct event_format *event, struct print_arg *arg, char **tok)
2434 /* make this a typecast and contine */ 2540 /* make this a typecast and contine */
2435 2541
2436 /* prevous must be an atom */ 2542 /* prevous must be an atom */
2437 if (arg->type != PRINT_ATOM) 2543 if (arg->type != PRINT_ATOM) {
2438 die("previous needed to be PRINT_ATOM"); 2544 do_warning("previous needed to be PRINT_ATOM");
2545 goto out_free;
2546 }
2439 2547
2440 item_arg = alloc_arg(); 2548 item_arg = alloc_arg();
2549 if (!item_arg) {
2550 do_warning("%s: not enough memory!", __func__);
2551 goto out_free;
2552 }
2441 2553
2442 arg->type = PRINT_TYPE; 2554 arg->type = PRINT_TYPE;
2443 arg->typecast.type = arg->atom.atom; 2555 arg->typecast.type = arg->atom.atom;
@@ -2533,6 +2645,11 @@ process_func_handler(struct event_format *event, struct pevent_function_handler
2533 next_arg = &(arg->func.args); 2645 next_arg = &(arg->func.args);
2534 for (i = 0; i < func->nr_args; i++) { 2646 for (i = 0; i < func->nr_args; i++) {
2535 farg = alloc_arg(); 2647 farg = alloc_arg();
2648 if (!farg) {
2649 do_warning("%s: not enough memory!", __func__);
2650 return EVENT_ERROR;
2651 }
2652
2536 type = process_arg(event, farg, &token); 2653 type = process_arg(event, farg, &token);
2537 if (i < (func->nr_args - 1)) 2654 if (i < (func->nr_args - 1))
2538 test = ","; 2655 test = ",";
@@ -2677,7 +2794,8 @@ process_arg_token(struct event_format *event, struct print_arg *arg,
2677 2794
2678 case EVENT_ERROR ... EVENT_NEWLINE: 2795 case EVENT_ERROR ... EVENT_NEWLINE:
2679 default: 2796 default:
2680 die("unexpected type %d", type); 2797 do_warning("unexpected type %d", type);
2798 return EVENT_ERROR;
2681 } 2799 }
2682 *tok = token; 2800 *tok = token;
2683 2801
@@ -2698,6 +2816,10 @@ static int event_read_print_args(struct event_format *event, struct print_arg **
2698 } 2816 }
2699 2817
2700 arg = alloc_arg(); 2818 arg = alloc_arg();
2819 if (!arg) {
2820 do_warning("%s: not enough memory!", __func__);
2821 return -1;
2822 }
2701 2823
2702 type = process_arg(event, arg, &token); 2824 type = process_arg(event, arg, &token);
2703 2825
@@ -2769,10 +2891,8 @@ static int event_read_print(struct event_format *event)
2769 if (type == EVENT_DQUOTE) { 2891 if (type == EVENT_DQUOTE) {
2770 char *cat; 2892 char *cat;
2771 2893
2772 cat = malloc_or_die(strlen(event->print_fmt.format) + 2894 if (asprintf(&cat, "%s%s", event->print_fmt.format, token) < 0)
2773 strlen(token) + 1); 2895 goto fail;
2774 strcpy(cat, event->print_fmt.format);
2775 strcat(cat, token);
2776 free_token(token); 2896 free_token(token);
2777 free_token(event->print_fmt.format); 2897 free_token(event->print_fmt.format);
2778 event->print_fmt.format = NULL; 2898 event->print_fmt.format = NULL;
@@ -2926,8 +3046,10 @@ static int get_common_info(struct pevent *pevent,
2926 * All events should have the same common elements. 3046 * All events should have the same common elements.
2927 * Pick any event to find where the type is; 3047 * Pick any event to find where the type is;
2928 */ 3048 */
2929 if (!pevent->events) 3049 if (!pevent->events) {
2930 die("no event_list!"); 3050 do_warning("no event_list!");
3051 return -1;
3052 }
2931 3053
2932 event = pevent->events[0]; 3054 event = pevent->events[0];
2933 field = pevent_find_common_field(event, type); 3055 field = pevent_find_common_field(event, type);
@@ -3085,7 +3207,8 @@ eval_num_arg(void *data, int size, struct event_format *event, struct print_arg
3085 if (!arg->field.field) { 3207 if (!arg->field.field) {
3086 arg->field.field = pevent_find_any_field(event, arg->field.name); 3208 arg->field.field = pevent_find_any_field(event, arg->field.name);
3087 if (!arg->field.field) 3209 if (!arg->field.field)
3088 die("field %s not found", arg->field.name); 3210 goto out_warning_field;
3211
3089 } 3212 }
3090 /* must be a number */ 3213 /* must be a number */
3091 val = pevent_read_number(pevent, data + arg->field.field->offset, 3214 val = pevent_read_number(pevent, data + arg->field.field->offset,
@@ -3146,8 +3269,10 @@ eval_num_arg(void *data, int size, struct event_format *event, struct print_arg
3146 if (!larg->field.field) { 3269 if (!larg->field.field) {
3147 larg->field.field = 3270 larg->field.field =
3148 pevent_find_any_field(event, larg->field.name); 3271 pevent_find_any_field(event, larg->field.name);
3149 if (!larg->field.field) 3272 if (!larg->field.field) {
3150 die("field %s not found", larg->field.name); 3273 arg = larg;
3274 goto out_warning_field;
3275 }
3151 } 3276 }
3152 field_size = larg->field.field->elementsize; 3277 field_size = larg->field.field->elementsize;
3153 offset = larg->field.field->offset + 3278 offset = larg->field.field->offset +
@@ -3183,7 +3308,7 @@ eval_num_arg(void *data, int size, struct event_format *event, struct print_arg
3183 val = left != right; 3308 val = left != right;
3184 break; 3309 break;
3185 default: 3310 default:
3186 die("unknown op '%s'", arg->op.op); 3311 goto out_warning_op;
3187 } 3312 }
3188 break; 3313 break;
3189 case '~': 3314 case '~':
@@ -3213,7 +3338,7 @@ eval_num_arg(void *data, int size, struct event_format *event, struct print_arg
3213 val = left <= right; 3338 val = left <= right;
3214 break; 3339 break;
3215 default: 3340 default:
3216 die("unknown op '%s'", arg->op.op); 3341 goto out_warning_op;
3217 } 3342 }
3218 break; 3343 break;
3219 case '>': 3344 case '>':
@@ -3228,12 +3353,13 @@ eval_num_arg(void *data, int size, struct event_format *event, struct print_arg
3228 val = left >= right; 3353 val = left >= right;
3229 break; 3354 break;
3230 default: 3355 default:
3231 die("unknown op '%s'", arg->op.op); 3356 goto out_warning_op;
3232 } 3357 }
3233 break; 3358 break;
3234 case '=': 3359 case '=':
3235 if (arg->op.op[1] != '=') 3360 if (arg->op.op[1] != '=')
3236 die("unknown op '%s'", arg->op.op); 3361 goto out_warning_op;
3362
3237 val = left == right; 3363 val = left == right;
3238 break; 3364 break;
3239 case '-': 3365 case '-':
@@ -3249,13 +3375,21 @@ eval_num_arg(void *data, int size, struct event_format *event, struct print_arg
3249 val = left * right; 3375 val = left * right;
3250 break; 3376 break;
3251 default: 3377 default:
3252 die("unknown op '%s'", arg->op.op); 3378 goto out_warning_op;
3253 } 3379 }
3254 break; 3380 break;
3255 default: /* not sure what to do there */ 3381 default: /* not sure what to do there */
3256 return 0; 3382 return 0;
3257 } 3383 }
3258 return val; 3384 return val;
3385
3386out_warning_op:
3387 do_warning("%s: unknown op '%s'", __func__, arg->op.op);
3388 return 0;
3389
3390out_warning_field:
3391 do_warning("%s: field %s not found", __func__, arg->field.name);
3392 return 0;
3259} 3393}
3260 3394
3261struct flag { 3395struct flag {
@@ -3332,8 +3466,10 @@ static void print_str_arg(struct trace_seq *s, void *data, int size,
3332 field = arg->field.field; 3466 field = arg->field.field;
3333 if (!field) { 3467 if (!field) {
3334 field = pevent_find_any_field(event, arg->field.name); 3468 field = pevent_find_any_field(event, arg->field.name);
3335 if (!field) 3469 if (!field) {
3336 die("field %s not found", arg->field.name); 3470 str = arg->field.name;
3471 goto out_warning_field;
3472 }
3337 arg->field.field = field; 3473 arg->field.field = field;
3338 } 3474 }
3339 /* Zero sized fields, mean the rest of the data */ 3475 /* Zero sized fields, mean the rest of the data */
@@ -3350,7 +3486,11 @@ static void print_str_arg(struct trace_seq *s, void *data, int size,
3350 trace_seq_printf(s, "%lx", addr); 3486 trace_seq_printf(s, "%lx", addr);
3351 break; 3487 break;
3352 } 3488 }
3353 str = malloc_or_die(len + 1); 3489 str = malloc(len + 1);
3490 if (!str) {
3491 do_warning("%s: not enough memory!", __func__);
3492 return;
3493 }
3354 memcpy(str, data + field->offset, len); 3494 memcpy(str, data + field->offset, len);
3355 str[len] = 0; 3495 str[len] = 0;
3356 print_str_to_seq(s, format, len_arg, str); 3496 print_str_to_seq(s, format, len_arg, str);
@@ -3390,7 +3530,7 @@ static void print_str_arg(struct trace_seq *s, void *data, int size,
3390 str = arg->hex.field->field.name; 3530 str = arg->hex.field->field.name;
3391 field = pevent_find_any_field(event, str); 3531 field = pevent_find_any_field(event, str);
3392 if (!field) 3532 if (!field)
3393 die("field %s not found", str); 3533 goto out_warning_field;
3394 arg->hex.field->field.field = field; 3534 arg->hex.field->field.field = field;
3395 } 3535 }
3396 hex = data + field->offset; 3536 hex = data + field->offset;
@@ -3442,6 +3582,11 @@ static void print_str_arg(struct trace_seq *s, void *data, int size,
3442 /* well... */ 3582 /* well... */
3443 break; 3583 break;
3444 } 3584 }
3585
3586 return;
3587
3588out_warning_field:
3589 do_warning("%s: field %s not found", __func__, arg->field.name);
3445} 3590}
3446 3591
3447static unsigned long long 3592static unsigned long long
@@ -3468,7 +3613,11 @@ process_defined_func(struct trace_seq *s, void *data, int size,
3468 farg = arg->func.args; 3613 farg = arg->func.args;
3469 param = func_handle->params; 3614 param = func_handle->params;
3470 3615
3471 args = malloc_or_die(sizeof(*args) * func_handle->nr_args); 3616 ret = ULLONG_MAX;
3617 args = malloc(sizeof(*args) * func_handle->nr_args);
3618 if (!args)
3619 goto out;
3620
3472 for (i = 0; i < func_handle->nr_args; i++) { 3621 for (i = 0; i < func_handle->nr_args; i++) {
3473 switch (param->type) { 3622 switch (param->type) {
3474 case PEVENT_FUNC_ARG_INT: 3623 case PEVENT_FUNC_ARG_INT:
@@ -3480,12 +3629,18 @@ process_defined_func(struct trace_seq *s, void *data, int size,
3480 trace_seq_init(&str); 3629 trace_seq_init(&str);
3481 print_str_arg(&str, data, size, event, "%s", -1, farg); 3630 print_str_arg(&str, data, size, event, "%s", -1, farg);
3482 trace_seq_terminate(&str); 3631 trace_seq_terminate(&str);
3483 string = malloc_or_die(sizeof(*string)); 3632 string = malloc(sizeof(*string));
3633 if (!string) {
3634 do_warning("%s(%d): malloc str", __func__, __LINE__);
3635 goto out_free;
3636 }
3484 string->next = strings; 3637 string->next = strings;
3485 string->str = strdup(str.buffer); 3638 string->str = strdup(str.buffer);
3486 if (!string->str) 3639 if (!string->str) {
3487 die("malloc str"); 3640 free(string);
3488 3641 do_warning("%s(%d): malloc str", __func__, __LINE__);
3642 goto out_free;
3643 }
3489 args[i] = (uintptr_t)string->str; 3644 args[i] = (uintptr_t)string->str;
3490 strings = string; 3645 strings = string;
3491 trace_seq_destroy(&str); 3646 trace_seq_destroy(&str);
@@ -3495,14 +3650,15 @@ process_defined_func(struct trace_seq *s, void *data, int size,
3495 * Something went totally wrong, this is not 3650 * Something went totally wrong, this is not
3496 * an input error, something in this code broke. 3651 * an input error, something in this code broke.
3497 */ 3652 */
3498 die("Unexpected end of arguments\n"); 3653 do_warning("Unexpected end of arguments\n");
3499 break; 3654 goto out_free;
3500 } 3655 }
3501 farg = farg->next; 3656 farg = farg->next;
3502 param = param->next; 3657 param = param->next;
3503 } 3658 }
3504 3659
3505 ret = (*func_handle->func)(s, args); 3660 ret = (*func_handle->func)(s, args);
3661out_free:
3506 free(args); 3662 free(args);
3507 while (strings) { 3663 while (strings) {
3508 string = strings; 3664 string = strings;
@@ -3516,6 +3672,18 @@ process_defined_func(struct trace_seq *s, void *data, int size,
3516 return ret; 3672 return ret;
3517} 3673}
3518 3674
3675static void free_args(struct print_arg *args)
3676{
3677 struct print_arg *next;
3678
3679 while (args) {
3680 next = args->next;
3681
3682 free_arg(args);
3683 args = next;
3684 }
3685}
3686
3519static struct print_arg *make_bprint_args(char *fmt, void *data, int size, struct event_format *event) 3687static struct print_arg *make_bprint_args(char *fmt, void *data, int size, struct event_format *event)
3520{ 3688{
3521 struct pevent *pevent = event->pevent; 3689 struct pevent *pevent = event->pevent;
@@ -3531,11 +3699,15 @@ static struct print_arg *make_bprint_args(char *fmt, void *data, int size, struc
3531 3699
3532 if (!field) { 3700 if (!field) {
3533 field = pevent_find_field(event, "buf"); 3701 field = pevent_find_field(event, "buf");
3534 if (!field) 3702 if (!field) {
3535 die("can't find buffer field for binary printk"); 3703 do_warning("can't find buffer field for binary printk");
3704 return NULL;
3705 }
3536 ip_field = pevent_find_field(event, "ip"); 3706 ip_field = pevent_find_field(event, "ip");
3537 if (!ip_field) 3707 if (!ip_field) {
3538 die("can't find ip field for binary printk"); 3708 do_warning("can't find ip field for binary printk");
3709 return NULL;
3710 }
3539 pevent->bprint_buf_field = field; 3711 pevent->bprint_buf_field = field;
3540 pevent->bprint_ip_field = ip_field; 3712 pevent->bprint_ip_field = ip_field;
3541 } 3713 }
@@ -3546,13 +3718,18 @@ static struct print_arg *make_bprint_args(char *fmt, void *data, int size, struc
3546 * The first arg is the IP pointer. 3718 * The first arg is the IP pointer.
3547 */ 3719 */
3548 args = alloc_arg(); 3720 args = alloc_arg();
3721 if (!args) {
3722 do_warning("%s(%d): not enough memory!", __func__, __LINE__);
3723 return NULL;
3724 }
3549 arg = args; 3725 arg = args;
3550 arg->next = NULL; 3726 arg->next = NULL;
3551 next = &arg->next; 3727 next = &arg->next;
3552 3728
3553 arg->type = PRINT_ATOM; 3729 arg->type = PRINT_ATOM;
3554 arg->atom.atom = malloc_or_die(32); 3730
3555 sprintf(arg->atom.atom, "%lld", ip); 3731 if (asprintf(&arg->atom.atom, "%lld", ip) < 0)
3732 goto out_free;
3556 3733
3557 /* skip the first "%pf : " */ 3734 /* skip the first "%pf : " */
3558 for (ptr = fmt + 6, bptr = data + field->offset; 3735 for (ptr = fmt + 6, bptr = data + field->offset;
@@ -3607,10 +3784,17 @@ static struct print_arg *make_bprint_args(char *fmt, void *data, int size, struc
3607 val = pevent_read_number(pevent, bptr, vsize); 3784 val = pevent_read_number(pevent, bptr, vsize);
3608 bptr += vsize; 3785 bptr += vsize;
3609 arg = alloc_arg(); 3786 arg = alloc_arg();
3787 if (!arg) {
3788 do_warning("%s(%d): not enough memory!",
3789 __func__, __LINE__);
3790 goto out_free;
3791 }
3610 arg->next = NULL; 3792 arg->next = NULL;
3611 arg->type = PRINT_ATOM; 3793 arg->type = PRINT_ATOM;
3612 arg->atom.atom = malloc_or_die(32); 3794 if (asprintf(&arg->atom.atom, "%lld", val) < 0) {
3613 sprintf(arg->atom.atom, "%lld", val); 3795 free(arg);
3796 goto out_free;
3797 }
3614 *next = arg; 3798 *next = arg;
3615 next = &arg->next; 3799 next = &arg->next;
3616 /* 3800 /*
@@ -3623,11 +3807,16 @@ static struct print_arg *make_bprint_args(char *fmt, void *data, int size, struc
3623 break; 3807 break;
3624 case 's': 3808 case 's':
3625 arg = alloc_arg(); 3809 arg = alloc_arg();
3810 if (!arg) {
3811 do_warning("%s(%d): not enough memory!",
3812 __func__, __LINE__);
3813 goto out_free;
3814 }
3626 arg->next = NULL; 3815 arg->next = NULL;
3627 arg->type = PRINT_BSTRING; 3816 arg->type = PRINT_BSTRING;
3628 arg->string.string = strdup(bptr); 3817 arg->string.string = strdup(bptr);
3629 if (!arg->string.string) 3818 if (!arg->string.string)
3630 break; 3819 goto out_free;
3631 bptr += strlen(bptr) + 1; 3820 bptr += strlen(bptr) + 1;
3632 *next = arg; 3821 *next = arg;
3633 next = &arg->next; 3822 next = &arg->next;
@@ -3638,18 +3827,10 @@ static struct print_arg *make_bprint_args(char *fmt, void *data, int size, struc
3638 } 3827 }
3639 3828
3640 return args; 3829 return args;
3641}
3642 3830
3643static void free_args(struct print_arg *args) 3831out_free:
3644{ 3832 free_args(args);
3645 struct print_arg *next; 3833 return NULL;
3646
3647 while (args) {
3648 next = args->next;
3649
3650 free_arg(args);
3651 args = next;
3652 }
3653} 3834}
3654 3835
3655static char * 3836static char *
@@ -3667,8 +3848,10 @@ get_bprint_format(void *data, int size __maybe_unused,
3667 3848
3668 if (!field) { 3849 if (!field) {
3669 field = pevent_find_field(event, "fmt"); 3850 field = pevent_find_field(event, "fmt");
3670 if (!field) 3851 if (!field) {
3671 die("can't find format field for binary printk"); 3852 do_warning("can't find format field for binary printk");
3853 return NULL;
3854 }
3672 pevent->bprint_fmt_field = field; 3855 pevent->bprint_fmt_field = field;
3673 } 3856 }
3674 3857
@@ -3676,9 +3859,8 @@ get_bprint_format(void *data, int size __maybe_unused,
3676 3859
3677 printk = find_printk(pevent, addr); 3860 printk = find_printk(pevent, addr);
3678 if (!printk) { 3861 if (!printk) {
3679 format = malloc_or_die(45); 3862 if (asprintf(&format, "%%pf : (NO FORMAT FOUND at %llx)\n", addr) < 0)
3680 sprintf(format, "%%pf : (NO FORMAT FOUND at %llx)\n", 3863 return NULL;
3681 addr);
3682 return format; 3864 return format;
3683 } 3865 }
3684 3866
@@ -3686,8 +3868,8 @@ get_bprint_format(void *data, int size __maybe_unused,
3686 /* Remove any quotes. */ 3868 /* Remove any quotes. */
3687 if (*p == '"') 3869 if (*p == '"')
3688 p++; 3870 p++;
3689 format = malloc_or_die(strlen(p) + 10); 3871 if (asprintf(&format, "%s : %s", "%pf", p) < 0)
3690 sprintf(format, "%s : %s", "%pf", p); 3872 return NULL;
3691 /* remove ending quotes and new line since we will add one too */ 3873 /* remove ending quotes and new line since we will add one too */
3692 p = format + strlen(format) - 1; 3874 p = format + strlen(format) - 1;
3693 if (*p == '"') 3875 if (*p == '"')
@@ -3722,8 +3904,11 @@ static void print_mac_arg(struct trace_seq *s, int mac, void *data, int size,
3722 if (!arg->field.field) { 3904 if (!arg->field.field) {
3723 arg->field.field = 3905 arg->field.field =
3724 pevent_find_any_field(event, arg->field.name); 3906 pevent_find_any_field(event, arg->field.name);
3725 if (!arg->field.field) 3907 if (!arg->field.field) {
3726 die("field %s not found", arg->field.name); 3908 do_warning("%s: field %s not found",
3909 __func__, arg->field.name);
3910 return;
3911 }
3727 } 3912 }
3728 if (arg->field.field->size != 6) { 3913 if (arg->field.field->size != 6) {
3729 trace_seq_printf(s, "INVALIDMAC"); 3914 trace_seq_printf(s, "INVALIDMAC");
@@ -4379,7 +4564,10 @@ get_event_fields(const char *type, const char *name,
4379 struct format_field *field; 4564 struct format_field *field;
4380 int i = 0; 4565 int i = 0;
4381 4566
4382 fields = malloc_or_die(sizeof(*fields) * (count + 1)); 4567 fields = malloc(sizeof(*fields) * (count + 1));
4568 if (!fields)
4569 return NULL;
4570
4383 for (field = list; field; field = field->next) { 4571 for (field = list; field; field = field->next) {
4384 fields[i++] = field; 4572 fields[i++] = field;
4385 if (i == count + 1) { 4573 if (i == count + 1) {
@@ -4695,8 +4883,7 @@ static int find_event_handle(struct pevent *pevent, struct event_format *event)
4695} 4883}
4696 4884
4697/** 4885/**
4698 * pevent_parse_event - parse the event format 4886 * __pevent_parse_format - parse the event format
4699 * @pevent: the handle to the pevent
4700 * @buf: the buffer storing the event format string 4887 * @buf: the buffer storing the event format string
4701 * @size: the size of @buf 4888 * @size: the size of @buf
4702 * @sys: the system the event belongs to 4889 * @sys: the system the event belongs to
@@ -4708,15 +4895,16 @@ static int find_event_handle(struct pevent *pevent, struct event_format *event)
4708 * 4895 *
4709 * /sys/kernel/debug/tracing/events/.../.../format 4896 * /sys/kernel/debug/tracing/events/.../.../format
4710 */ 4897 */
4711enum pevent_errno pevent_parse_event(struct pevent *pevent, const char *buf, 4898enum pevent_errno __pevent_parse_format(struct event_format **eventp,
4712 unsigned long size, const char *sys) 4899 struct pevent *pevent, const char *buf,
4900 unsigned long size, const char *sys)
4713{ 4901{
4714 struct event_format *event; 4902 struct event_format *event;
4715 int ret; 4903 int ret;
4716 4904
4717 init_input_buf(buf, size); 4905 init_input_buf(buf, size);
4718 4906
4719 event = alloc_event(); 4907 *eventp = event = alloc_event();
4720 if (!event) 4908 if (!event)
4721 return PEVENT_ERRNO__MEM_ALLOC_FAILED; 4909 return PEVENT_ERRNO__MEM_ALLOC_FAILED;
4722 4910
@@ -4750,9 +4938,6 @@ enum pevent_errno pevent_parse_event(struct pevent *pevent, const char *buf,
4750 goto event_alloc_failed; 4938 goto event_alloc_failed;
4751 } 4939 }
4752 4940
4753 /* Add pevent to event so that it can be referenced */
4754 event->pevent = pevent;
4755
4756 ret = event_read_format(event); 4941 ret = event_read_format(event);
4757 if (ret < 0) { 4942 if (ret < 0) {
4758 ret = PEVENT_ERRNO__READ_FORMAT_FAILED; 4943 ret = PEVENT_ERRNO__READ_FORMAT_FAILED;
@@ -4763,18 +4948,16 @@ enum pevent_errno pevent_parse_event(struct pevent *pevent, const char *buf,
4763 * If the event has an override, don't print warnings if the event 4948 * If the event has an override, don't print warnings if the event
4764 * print format fails to parse. 4949 * print format fails to parse.
4765 */ 4950 */
4766 if (find_event_handle(pevent, event)) 4951 if (pevent && find_event_handle(pevent, event))
4767 show_warning = 0; 4952 show_warning = 0;
4768 4953
4769 ret = event_read_print(event); 4954 ret = event_read_print(event);
4955 show_warning = 1;
4956
4770 if (ret < 0) { 4957 if (ret < 0) {
4771 show_warning = 1;
4772 ret = PEVENT_ERRNO__READ_PRINT_FAILED; 4958 ret = PEVENT_ERRNO__READ_PRINT_FAILED;
4773 goto event_parse_failed; 4959 goto event_parse_failed;
4774 } 4960 }
4775 show_warning = 1;
4776
4777 add_event(pevent, event);
4778 4961
4779 if (!ret && (event->flags & EVENT_FL_ISFTRACE)) { 4962 if (!ret && (event->flags & EVENT_FL_ISFTRACE)) {
4780 struct format_field *field; 4963 struct format_field *field;
@@ -4784,6 +4967,10 @@ enum pevent_errno pevent_parse_event(struct pevent *pevent, const char *buf,
4784 list = &event->print_fmt.args; 4967 list = &event->print_fmt.args;
4785 for (field = event->format.fields; field; field = field->next) { 4968 for (field = event->format.fields; field; field = field->next) {
4786 arg = alloc_arg(); 4969 arg = alloc_arg();
4970 if (!arg) {
4971 event->flags |= EVENT_FL_FAILED;
4972 return PEVENT_ERRNO__OLD_FTRACE_ARG_FAILED;
4973 }
4787 arg->type = PRINT_FIELD; 4974 arg->type = PRINT_FIELD;
4788 arg->field.name = strdup(field->name); 4975 arg->field.name = strdup(field->name);
4789 if (!arg->field.name) { 4976 if (!arg->field.name) {
@@ -4798,22 +4985,78 @@ enum pevent_errno pevent_parse_event(struct pevent *pevent, const char *buf,
4798 return 0; 4985 return 0;
4799 } 4986 }
4800 4987
4801#define PRINT_ARGS 0
4802 if (PRINT_ARGS && event->print_fmt.args)
4803 print_args(event->print_fmt.args);
4804
4805 return 0; 4988 return 0;
4806 4989
4807 event_parse_failed: 4990 event_parse_failed:
4808 event->flags |= EVENT_FL_FAILED; 4991 event->flags |= EVENT_FL_FAILED;
4809 /* still add it even if it failed */
4810 add_event(pevent, event);
4811 return ret; 4992 return ret;
4812 4993
4813 event_alloc_failed: 4994 event_alloc_failed:
4814 free(event->system); 4995 free(event->system);
4815 free(event->name); 4996 free(event->name);
4816 free(event); 4997 free(event);
4998 *eventp = NULL;
4999 return ret;
5000}
5001
5002/**
5003 * pevent_parse_format - parse the event format
5004 * @buf: the buffer storing the event format string
5005 * @size: the size of @buf
5006 * @sys: the system the event belongs to
5007 *
5008 * This parses the event format and creates an event structure
5009 * to quickly parse raw data for a given event.
5010 *
5011 * These files currently come from:
5012 *
5013 * /sys/kernel/debug/tracing/events/.../.../format
5014 */
5015enum pevent_errno pevent_parse_format(struct event_format **eventp, const char *buf,
5016 unsigned long size, const char *sys)
5017{
5018 return __pevent_parse_format(eventp, NULL, buf, size, sys);
5019}
5020
5021/**
5022 * pevent_parse_event - parse the event format
5023 * @pevent: the handle to the pevent
5024 * @buf: the buffer storing the event format string
5025 * @size: the size of @buf
5026 * @sys: the system the event belongs to
5027 *
5028 * This parses the event format and creates an event structure
5029 * to quickly parse raw data for a given event.
5030 *
5031 * These files currently come from:
5032 *
5033 * /sys/kernel/debug/tracing/events/.../.../format
5034 */
5035enum pevent_errno pevent_parse_event(struct pevent *pevent, const char *buf,
5036 unsigned long size, const char *sys)
5037{
5038 struct event_format *event = NULL;
5039 int ret = __pevent_parse_format(&event, pevent, buf, size, sys);
5040
5041 if (event == NULL)
5042 return ret;
5043
5044 /* Add pevent to event so that it can be referenced */
5045 event->pevent = pevent;
5046
5047 if (add_event(pevent, event))
5048 goto event_add_failed;
5049
5050#define PRINT_ARGS 0
5051 if (PRINT_ARGS && event->print_fmt.args)
5052 print_args(event->print_fmt.args);
5053
5054 return 0;
5055
5056event_add_failed:
5057 free(event->system);
5058 free(event->name);
5059 free(event);
4817 return ret; 5060 return ret;
4818} 5061}
4819 5062
@@ -5094,12 +5337,11 @@ int pevent_register_print_function(struct pevent *pevent,
5094 remove_func_handler(pevent, name); 5337 remove_func_handler(pevent, name);
5095 } 5338 }
5096 5339
5097 func_handle = malloc(sizeof(*func_handle)); 5340 func_handle = calloc(1, sizeof(*func_handle));
5098 if (!func_handle) { 5341 if (!func_handle) {
5099 do_warning("Failed to allocate function handler"); 5342 do_warning("Failed to allocate function handler");
5100 return PEVENT_ERRNO__MEM_ALLOC_FAILED; 5343 return PEVENT_ERRNO__MEM_ALLOC_FAILED;
5101 } 5344 }
5102 memset(func_handle, 0, sizeof(*func_handle));
5103 5345
5104 func_handle->ret_type = ret_type; 5346 func_handle->ret_type = ret_type;
5105 func_handle->name = strdup(name); 5347 func_handle->name = strdup(name);
@@ -5198,13 +5440,12 @@ int pevent_register_event_handler(struct pevent *pevent,
5198 5440
5199 not_found: 5441 not_found:
5200 /* Save for later use. */ 5442 /* Save for later use. */
5201 handle = malloc(sizeof(*handle)); 5443 handle = calloc(1, sizeof(*handle));
5202 if (!handle) { 5444 if (!handle) {
5203 do_warning("Failed to allocate event handler"); 5445 do_warning("Failed to allocate event handler");
5204 return PEVENT_ERRNO__MEM_ALLOC_FAILED; 5446 return PEVENT_ERRNO__MEM_ALLOC_FAILED;
5205 } 5447 }
5206 5448
5207 memset(handle, 0, sizeof(*handle));
5208 handle->id = id; 5449 handle->id = id;
5209 if (event_name) 5450 if (event_name)
5210 handle->event_name = strdup(event_name); 5451 handle->event_name = strdup(event_name);
@@ -5233,13 +5474,10 @@ int pevent_register_event_handler(struct pevent *pevent,
5233 */ 5474 */
5234struct pevent *pevent_alloc(void) 5475struct pevent *pevent_alloc(void)
5235{ 5476{
5236 struct pevent *pevent; 5477 struct pevent *pevent = calloc(1, sizeof(*pevent));
5237 5478
5238 pevent = malloc(sizeof(*pevent)); 5479 if (pevent)
5239 if (!pevent) 5480 pevent->ref_count = 1;
5240 return NULL;
5241 memset(pevent, 0, sizeof(*pevent));
5242 pevent->ref_count = 1;
5243 5481
5244 return pevent; 5482 return pevent;
5245} 5483}
@@ -5268,7 +5506,7 @@ static void free_formats(struct format *format)
5268 free_format_fields(format->fields); 5506 free_format_fields(format->fields);
5269} 5507}
5270 5508
5271static void free_event(struct event_format *event) 5509void pevent_free_format(struct event_format *event)
5272{ 5510{
5273 free(event->name); 5511 free(event->name);
5274 free(event->system); 5512 free(event->system);
@@ -5354,7 +5592,7 @@ void pevent_free(struct pevent *pevent)
5354 } 5592 }
5355 5593
5356 for (i = 0; i < pevent->nr_events; i++) 5594 for (i = 0; i < pevent->nr_events; i++)
5357 free_event(pevent->events[i]); 5595 pevent_free_format(pevent->events[i]);
5358 5596
5359 while (pevent->handlers) { 5597 while (pevent->handlers) {
5360 handle = pevent->handlers; 5598 handle = pevent->handlers;
diff --git a/tools/lib/traceevent/event-parse.h b/tools/lib/traceevent/event-parse.h
index a4bbe2437925..24a4bbabc5d5 100644
--- a/tools/lib/traceevent/event-parse.h
+++ b/tools/lib/traceevent/event-parse.h
@@ -540,6 +540,9 @@ int pevent_parse_header_page(struct pevent *pevent, char *buf, unsigned long siz
540 540
541enum pevent_errno pevent_parse_event(struct pevent *pevent, const char *buf, 541enum pevent_errno pevent_parse_event(struct pevent *pevent, const char *buf,
542 unsigned long size, const char *sys); 542 unsigned long size, const char *sys);
543enum pevent_errno pevent_parse_format(struct event_format **eventp, const char *buf,
544 unsigned long size, const char *sys);
545void pevent_free_format(struct event_format *event);
543 546
544void *pevent_get_field_raw(struct trace_seq *s, struct event_format *event, 547void *pevent_get_field_raw(struct trace_seq *s, struct event_format *event,
545 const char *name, struct pevent_record *record, 548 const char *name, struct pevent_record *record,
diff --git a/tools/perf/Documentation/perf-kvm.txt b/tools/perf/Documentation/perf-kvm.txt
index dd84cb2f0a88..326f2cb333cb 100644
--- a/tools/perf/Documentation/perf-kvm.txt
+++ b/tools/perf/Documentation/perf-kvm.txt
@@ -12,7 +12,7 @@ SYNOPSIS
12 [--guestkallsyms=<path> --guestmodules=<path> | --guestvmlinux=<path>]] 12 [--guestkallsyms=<path> --guestmodules=<path> | --guestvmlinux=<path>]]
13 {top|record|report|diff|buildid-list} 13 {top|record|report|diff|buildid-list}
14'perf kvm' [--host] [--guest] [--guestkallsyms=<path> --guestmodules=<path> 14'perf kvm' [--host] [--guest] [--guestkallsyms=<path> --guestmodules=<path>
15 | --guestvmlinux=<path>] {top|record|report|diff|buildid-list} 15 | --guestvmlinux=<path>] {top|record|report|diff|buildid-list|stat}
16 16
17DESCRIPTION 17DESCRIPTION
18----------- 18-----------
@@ -38,6 +38,18 @@ There are a couple of variants of perf kvm:
38 so that other tools can be used to fetch packages with matching symbol tables 38 so that other tools can be used to fetch packages with matching symbol tables
39 for use by perf report. 39 for use by perf report.
40 40
41 'perf kvm stat <command>' to run a command and gather performance counter
42 statistics.
43 Especially, perf 'kvm stat record/report' generates a statistical analysis
44 of KVM events. Currently, vmexit, mmio and ioport events are supported.
45 'perf kvm stat record <command>' records kvm events and the events between
46 start and end <command>.
47 And this command produces a file which contains tracing results of kvm
48 events.
49
50 'perf kvm stat report' reports statistical data which includes events
51 handled time, samples, and so on.
52
41OPTIONS 53OPTIONS
42------- 54-------
43-i:: 55-i::
@@ -68,7 +80,21 @@ OPTIONS
68--guestvmlinux=<path>:: 80--guestvmlinux=<path>::
69 Guest os kernel vmlinux. 81 Guest os kernel vmlinux.
70 82
83STAT REPORT OPTIONS
84-------------------
85--vcpu=<value>::
86 analyze events which occures on this vcpu. (default: all vcpus)
87
88--events=<value>::
89 events to be analyzed. Possible values: vmexit, mmio, ioport.
90 (default: vmexit)
91-k::
92--key=<value>::
93 Sorting key. Possible values: sample (default, sort by samples
94 number), time (sort by average time).
95
71SEE ALSO 96SEE ALSO
72-------- 97--------
73linkperf:perf-top[1], linkperf:perf-record[1], linkperf:perf-report[1], 98linkperf:perf-top[1], linkperf:perf-record[1], linkperf:perf-report[1],
74linkperf:perf-diff[1], linkperf:perf-buildid-list[1] 99linkperf:perf-diff[1], linkperf:perf-buildid-list[1],
100linkperf:perf-stat[1]
diff --git a/tools/perf/MANIFEST b/tools/perf/MANIFEST
index 051807990938..80db3f4bcf7a 100644
--- a/tools/perf/MANIFEST
+++ b/tools/perf/MANIFEST
@@ -16,3 +16,6 @@ arch/*/lib/memset*.S
16include/linux/poison.h 16include/linux/poison.h
17include/linux/magic.h 17include/linux/magic.h
18include/linux/hw_breakpoint.h 18include/linux/hw_breakpoint.h
19arch/x86/include/asm/svm.h
20arch/x86/include/asm/vmx.h
21arch/x86/include/asm/kvm_host.h
diff --git a/tools/perf/Makefile b/tools/perf/Makefile
index 5077f8e2ef72..251dcd7fb5ac 100644
--- a/tools/perf/Makefile
+++ b/tools/perf/Makefile
@@ -233,13 +233,13 @@ export PERL_PATH
233FLEX = flex 233FLEX = flex
234BISON= bison 234BISON= bison
235 235
236$(OUTPUT)util/parse-events-flex.c: util/parse-events.l 236$(OUTPUT)util/parse-events-flex.c: util/parse-events.l $(OUTPUT)util/parse-events-bison.c
237 $(QUIET_FLEX)$(FLEX) --header-file=$(OUTPUT)util/parse-events-flex.h $(PARSER_DEBUG_FLEX) -t util/parse-events.l > $(OUTPUT)util/parse-events-flex.c 237 $(QUIET_FLEX)$(FLEX) --header-file=$(OUTPUT)util/parse-events-flex.h $(PARSER_DEBUG_FLEX) -t util/parse-events.l > $(OUTPUT)util/parse-events-flex.c
238 238
239$(OUTPUT)util/parse-events-bison.c: util/parse-events.y 239$(OUTPUT)util/parse-events-bison.c: util/parse-events.y
240 $(QUIET_BISON)$(BISON) -v util/parse-events.y -d $(PARSER_DEBUG_BISON) -o $(OUTPUT)util/parse-events-bison.c 240 $(QUIET_BISON)$(BISON) -v util/parse-events.y -d $(PARSER_DEBUG_BISON) -o $(OUTPUT)util/parse-events-bison.c
241 241
242$(OUTPUT)util/pmu-flex.c: util/pmu.l 242$(OUTPUT)util/pmu-flex.c: util/pmu.l $(OUTPUT)util/pmu-bison.c
243 $(QUIET_FLEX)$(FLEX) --header-file=$(OUTPUT)util/pmu-flex.h -t util/pmu.l > $(OUTPUT)util/pmu-flex.c 243 $(QUIET_FLEX)$(FLEX) --header-file=$(OUTPUT)util/pmu-flex.h -t util/pmu.l > $(OUTPUT)util/pmu-flex.c
244 244
245$(OUTPUT)util/pmu-bison.c: util/pmu.y 245$(OUTPUT)util/pmu-bison.c: util/pmu.y
@@ -715,7 +715,7 @@ else
715 EXTLIBS += -liberty 715 EXTLIBS += -liberty
716 BASIC_CFLAGS += -DHAVE_CPLUS_DEMANGLE 716 BASIC_CFLAGS += -DHAVE_CPLUS_DEMANGLE
717 else 717 else
718 FLAGS_BFD=$(ALL_CFLAGS) $(ALL_LDFLAGS) $(EXTLIBS) -lbfd 718 FLAGS_BFD=$(ALL_CFLAGS) $(ALL_LDFLAGS) $(EXTLIBS) -DPACKAGE='perf' -lbfd
719 has_bfd := $(call try-cc,$(SOURCE_BFD),$(FLAGS_BFD)) 719 has_bfd := $(call try-cc,$(SOURCE_BFD),$(FLAGS_BFD))
720 ifeq ($(has_bfd),y) 720 ifeq ($(has_bfd),y)
721 EXTLIBS += -lbfd 721 EXTLIBS += -lbfd
diff --git a/tools/perf/builtin-kmem.c b/tools/perf/builtin-kmem.c
index f5f8a6b745a3..bc912c68f49a 100644
--- a/tools/perf/builtin-kmem.c
+++ b/tools/perf/builtin-kmem.c
@@ -1,6 +1,7 @@
1#include "builtin.h" 1#include "builtin.h"
2#include "perf.h" 2#include "perf.h"
3 3
4#include "util/evlist.h"
4#include "util/evsel.h" 5#include "util/evsel.h"
5#include "util/util.h" 6#include "util/util.h"
6#include "util/cache.h" 7#include "util/cache.h"
@@ -212,36 +213,38 @@ static int insert_caller_stat(unsigned long call_site,
212} 213}
213 214
214static int perf_evsel__process_alloc_event(struct perf_evsel *evsel, 215static int perf_evsel__process_alloc_event(struct perf_evsel *evsel,
215 struct perf_sample *sample, int node) 216 struct perf_sample *sample)
216{ 217{
217 struct event_format *event = evsel->tp_format; 218 unsigned long ptr = perf_evsel__intval(evsel, sample, "ptr"),
218 void *data = sample->raw_data; 219 call_site = perf_evsel__intval(evsel, sample, "call_site");
219 unsigned long call_site; 220 int bytes_req = perf_evsel__intval(evsel, sample, "bytes_req"),
220 unsigned long ptr; 221 bytes_alloc = perf_evsel__intval(evsel, sample, "bytes_alloc");
221 int bytes_req, cpu = sample->cpu; 222
222 int bytes_alloc; 223 if (insert_alloc_stat(call_site, ptr, bytes_req, bytes_alloc, sample->cpu) ||
223 int node1, node2;
224
225 ptr = raw_field_value(event, "ptr", data);
226 call_site = raw_field_value(event, "call_site", data);
227 bytes_req = raw_field_value(event, "bytes_req", data);
228 bytes_alloc = raw_field_value(event, "bytes_alloc", data);
229
230 if (insert_alloc_stat(call_site, ptr, bytes_req, bytes_alloc, cpu) ||
231 insert_caller_stat(call_site, bytes_req, bytes_alloc)) 224 insert_caller_stat(call_site, bytes_req, bytes_alloc))
232 return -1; 225 return -1;
233 226
234 total_requested += bytes_req; 227 total_requested += bytes_req;
235 total_allocated += bytes_alloc; 228 total_allocated += bytes_alloc;
236 229
237 if (node) { 230 nr_allocs++;
238 node1 = cpunode_map[cpu]; 231 return 0;
239 node2 = raw_field_value(event, "node", data); 232}
233
234static int perf_evsel__process_alloc_node_event(struct perf_evsel *evsel,
235 struct perf_sample *sample)
236{
237 int ret = perf_evsel__process_alloc_event(evsel, sample);
238
239 if (!ret) {
240 int node1 = cpunode_map[sample->cpu],
241 node2 = perf_evsel__intval(evsel, sample, "node");
242
240 if (node1 != node2) 243 if (node1 != node2)
241 nr_cross_allocs++; 244 nr_cross_allocs++;
242 } 245 }
243 nr_allocs++; 246
244 return 0; 247 return ret;
245} 248}
246 249
247static int ptr_cmp(struct alloc_stat *, struct alloc_stat *); 250static int ptr_cmp(struct alloc_stat *, struct alloc_stat *);
@@ -275,8 +278,7 @@ static struct alloc_stat *search_alloc_stat(unsigned long ptr,
275static int perf_evsel__process_free_event(struct perf_evsel *evsel, 278static int perf_evsel__process_free_event(struct perf_evsel *evsel,
276 struct perf_sample *sample) 279 struct perf_sample *sample)
277{ 280{
278 unsigned long ptr = raw_field_value(evsel->tp_format, "ptr", 281 unsigned long ptr = perf_evsel__intval(evsel, sample, "ptr");
279 sample->raw_data);
280 struct alloc_stat *s_alloc, *s_caller; 282 struct alloc_stat *s_alloc, *s_caller;
281 283
282 s_alloc = search_alloc_stat(ptr, 0, &root_alloc_stat, ptr_cmp); 284 s_alloc = search_alloc_stat(ptr, 0, &root_alloc_stat, ptr_cmp);
@@ -297,28 +299,8 @@ static int perf_evsel__process_free_event(struct perf_evsel *evsel,
297 return 0; 299 return 0;
298} 300}
299 301
300static int perf_evsel__process_kmem_event(struct perf_evsel *evsel, 302typedef int (*tracepoint_handler)(struct perf_evsel *evsel,
301 struct perf_sample *sample) 303 struct perf_sample *sample);
302{
303 struct event_format *event = evsel->tp_format;
304
305 if (!strcmp(event->name, "kmalloc") ||
306 !strcmp(event->name, "kmem_cache_alloc")) {
307 return perf_evsel__process_alloc_event(evsel, sample, 0);
308 }
309
310 if (!strcmp(event->name, "kmalloc_node") ||
311 !strcmp(event->name, "kmem_cache_alloc_node")) {
312 return perf_evsel__process_alloc_event(evsel, sample, 1);
313 }
314
315 if (!strcmp(event->name, "kfree") ||
316 !strcmp(event->name, "kmem_cache_free")) {
317 return perf_evsel__process_free_event(evsel, sample);
318 }
319
320 return 0;
321}
322 304
323static int process_sample_event(struct perf_tool *tool __maybe_unused, 305static int process_sample_event(struct perf_tool *tool __maybe_unused,
324 union perf_event *event, 306 union perf_event *event,
@@ -336,7 +318,12 @@ static int process_sample_event(struct perf_tool *tool __maybe_unused,
336 318
337 dump_printf(" ... thread: %s:%d\n", thread->comm, thread->pid); 319 dump_printf(" ... thread: %s:%d\n", thread->comm, thread->pid);
338 320
339 return perf_evsel__process_kmem_event(evsel, sample); 321 if (evsel->handler.func != NULL) {
322 tracepoint_handler f = evsel->handler.func;
323 return f(evsel, sample);
324 }
325
326 return 0;
340} 327}
341 328
342static struct perf_tool perf_kmem = { 329static struct perf_tool perf_kmem = {
@@ -498,6 +485,14 @@ static int __cmd_kmem(void)
498{ 485{
499 int err = -EINVAL; 486 int err = -EINVAL;
500 struct perf_session *session; 487 struct perf_session *session;
488 const struct perf_evsel_str_handler kmem_tracepoints[] = {
489 { "kmem:kmalloc", perf_evsel__process_alloc_event, },
490 { "kmem:kmem_cache_alloc", perf_evsel__process_alloc_event, },
491 { "kmem:kmalloc_node", perf_evsel__process_alloc_node_event, },
492 { "kmem:kmem_cache_alloc_node", perf_evsel__process_alloc_node_event, },
493 { "kmem:kfree", perf_evsel__process_free_event, },
494 { "kmem:kmem_cache_free", perf_evsel__process_free_event, },
495 };
501 496
502 session = perf_session__new(input_name, O_RDONLY, 0, false, &perf_kmem); 497 session = perf_session__new(input_name, O_RDONLY, 0, false, &perf_kmem);
503 if (session == NULL) 498 if (session == NULL)
@@ -509,6 +504,11 @@ static int __cmd_kmem(void)
509 if (!perf_session__has_traces(session, "kmem record")) 504 if (!perf_session__has_traces(session, "kmem record"))
510 goto out_delete; 505 goto out_delete;
511 506
507 if (perf_session__set_tracepoints_handlers(session, kmem_tracepoints)) {
508 pr_err("Initializing perf session tracepoint handlers failed\n");
509 return -1;
510 }
511
512 setup_pager(); 512 setup_pager();
513 err = perf_session__process_events(session, &perf_kmem); 513 err = perf_session__process_events(session, &perf_kmem);
514 if (err != 0) 514 if (err != 0)
diff --git a/tools/perf/builtin-kvm.c b/tools/perf/builtin-kvm.c
index 4d2aa2cbeca8..a28c9cad9048 100644
--- a/tools/perf/builtin-kvm.c
+++ b/tools/perf/builtin-kvm.c
@@ -1,6 +1,7 @@
1#include "builtin.h" 1#include "builtin.h"
2#include "perf.h" 2#include "perf.h"
3 3
4#include "util/evsel.h"
4#include "util/util.h" 5#include "util/util.h"
5#include "util/cache.h" 6#include "util/cache.h"
6#include "util/symbol.h" 7#include "util/symbol.h"
@@ -10,8 +11,10 @@
10 11
11#include "util/parse-options.h" 12#include "util/parse-options.h"
12#include "util/trace-event.h" 13#include "util/trace-event.h"
13
14#include "util/debug.h" 14#include "util/debug.h"
15#include "util/debugfs.h"
16#include "util/tool.h"
17#include "util/stat.h"
15 18
16#include <sys/prctl.h> 19#include <sys/prctl.h>
17 20
@@ -19,11 +22,836 @@
19#include <pthread.h> 22#include <pthread.h>
20#include <math.h> 23#include <math.h>
21 24
22static const char *file_name; 25#include "../../arch/x86/include/asm/svm.h"
26#include "../../arch/x86/include/asm/vmx.h"
27#include "../../arch/x86/include/asm/kvm.h"
28
29struct event_key {
30 #define INVALID_KEY (~0ULL)
31 u64 key;
32 int info;
33};
34
35struct kvm_events_ops {
36 bool (*is_begin_event)(struct perf_evsel *evsel,
37 struct perf_sample *sample,
38 struct event_key *key);
39 bool (*is_end_event)(struct perf_evsel *evsel,
40 struct perf_sample *sample, struct event_key *key);
41 void (*decode_key)(struct event_key *key, char decode[20]);
42 const char *name;
43};
44
45static void exit_event_get_key(struct perf_evsel *evsel,
46 struct perf_sample *sample,
47 struct event_key *key)
48{
49 key->info = 0;
50 key->key = perf_evsel__intval(evsel, sample, "exit_reason");
51}
52
53static bool kvm_exit_event(struct perf_evsel *evsel)
54{
55 return !strcmp(evsel->name, "kvm:kvm_exit");
56}
57
58static bool exit_event_begin(struct perf_evsel *evsel,
59 struct perf_sample *sample, struct event_key *key)
60{
61 if (kvm_exit_event(evsel)) {
62 exit_event_get_key(evsel, sample, key);
63 return true;
64 }
65
66 return false;
67}
68
69static bool kvm_entry_event(struct perf_evsel *evsel)
70{
71 return !strcmp(evsel->name, "kvm:kvm_entry");
72}
73
74static bool exit_event_end(struct perf_evsel *evsel,
75 struct perf_sample *sample __maybe_unused,
76 struct event_key *key __maybe_unused)
77{
78 return kvm_entry_event(evsel);
79}
80
81struct exit_reasons_table {
82 unsigned long exit_code;
83 const char *reason;
84};
85
86struct exit_reasons_table vmx_exit_reasons[] = {
87 VMX_EXIT_REASONS
88};
89
90struct exit_reasons_table svm_exit_reasons[] = {
91 SVM_EXIT_REASONS
92};
93
94static int cpu_isa;
95
96static const char *get_exit_reason(u64 exit_code)
97{
98 int table_size = ARRAY_SIZE(svm_exit_reasons);
99 struct exit_reasons_table *table = svm_exit_reasons;
100
101 if (cpu_isa == 1) {
102 table = vmx_exit_reasons;
103 table_size = ARRAY_SIZE(vmx_exit_reasons);
104 }
105
106 while (table_size--) {
107 if (table->exit_code == exit_code)
108 return table->reason;
109 table++;
110 }
111
112 pr_err("unknown kvm exit code:%lld on %s\n",
113 (unsigned long long)exit_code, cpu_isa ? "VMX" : "SVM");
114 return "UNKNOWN";
115}
116
117static void exit_event_decode_key(struct event_key *key, char decode[20])
118{
119 const char *exit_reason = get_exit_reason(key->key);
120
121 scnprintf(decode, 20, "%s", exit_reason);
122}
123
124static struct kvm_events_ops exit_events = {
125 .is_begin_event = exit_event_begin,
126 .is_end_event = exit_event_end,
127 .decode_key = exit_event_decode_key,
128 .name = "VM-EXIT"
129};
130
131 /*
132 * For the mmio events, we treat:
133 * the time of MMIO write: kvm_mmio(KVM_TRACE_MMIO_WRITE...) -> kvm_entry
134 * the time of MMIO read: kvm_exit -> kvm_mmio(KVM_TRACE_MMIO_READ...).
135 */
136static void mmio_event_get_key(struct perf_evsel *evsel, struct perf_sample *sample,
137 struct event_key *key)
138{
139 key->key = perf_evsel__intval(evsel, sample, "gpa");
140 key->info = perf_evsel__intval(evsel, sample, "type");
141}
142
143#define KVM_TRACE_MMIO_READ_UNSATISFIED 0
144#define KVM_TRACE_MMIO_READ 1
145#define KVM_TRACE_MMIO_WRITE 2
146
147static bool mmio_event_begin(struct perf_evsel *evsel,
148 struct perf_sample *sample, struct event_key *key)
149{
150 /* MMIO read begin event in kernel. */
151 if (kvm_exit_event(evsel))
152 return true;
153
154 /* MMIO write begin event in kernel. */
155 if (!strcmp(evsel->name, "kvm:kvm_mmio") &&
156 perf_evsel__intval(evsel, sample, "type") == KVM_TRACE_MMIO_WRITE) {
157 mmio_event_get_key(evsel, sample, key);
158 return true;
159 }
160
161 return false;
162}
163
164static bool mmio_event_end(struct perf_evsel *evsel, struct perf_sample *sample,
165 struct event_key *key)
166{
167 /* MMIO write end event in kernel. */
168 if (kvm_entry_event(evsel))
169 return true;
170
171 /* MMIO read end event in kernel.*/
172 if (!strcmp(evsel->name, "kvm:kvm_mmio") &&
173 perf_evsel__intval(evsel, sample, "type") == KVM_TRACE_MMIO_READ) {
174 mmio_event_get_key(evsel, sample, key);
175 return true;
176 }
177
178 return false;
179}
180
181static void mmio_event_decode_key(struct event_key *key, char decode[20])
182{
183 scnprintf(decode, 20, "%#lx:%s", (unsigned long)key->key,
184 key->info == KVM_TRACE_MMIO_WRITE ? "W" : "R");
185}
186
187static struct kvm_events_ops mmio_events = {
188 .is_begin_event = mmio_event_begin,
189 .is_end_event = mmio_event_end,
190 .decode_key = mmio_event_decode_key,
191 .name = "MMIO Access"
192};
193
194 /* The time of emulation pio access is from kvm_pio to kvm_entry. */
195static void ioport_event_get_key(struct perf_evsel *evsel,
196 struct perf_sample *sample,
197 struct event_key *key)
198{
199 key->key = perf_evsel__intval(evsel, sample, "port");
200 key->info = perf_evsel__intval(evsel, sample, "rw");
201}
202
203static bool ioport_event_begin(struct perf_evsel *evsel,
204 struct perf_sample *sample,
205 struct event_key *key)
206{
207 if (!strcmp(evsel->name, "kvm:kvm_pio")) {
208 ioport_event_get_key(evsel, sample, key);
209 return true;
210 }
211
212 return false;
213}
214
215static bool ioport_event_end(struct perf_evsel *evsel,
216 struct perf_sample *sample __maybe_unused,
217 struct event_key *key __maybe_unused)
218{
219 return kvm_entry_event(evsel);
220}
221
222static void ioport_event_decode_key(struct event_key *key, char decode[20])
223{
224 scnprintf(decode, 20, "%#llx:%s", (unsigned long long)key->key,
225 key->info ? "POUT" : "PIN");
226}
227
228static struct kvm_events_ops ioport_events = {
229 .is_begin_event = ioport_event_begin,
230 .is_end_event = ioport_event_end,
231 .decode_key = ioport_event_decode_key,
232 .name = "IO Port Access"
233};
234
235static const char *report_event = "vmexit";
236struct kvm_events_ops *events_ops;
237
238static bool register_kvm_events_ops(void)
239{
240 bool ret = true;
241
242 if (!strcmp(report_event, "vmexit"))
243 events_ops = &exit_events;
244 else if (!strcmp(report_event, "mmio"))
245 events_ops = &mmio_events;
246 else if (!strcmp(report_event, "ioport"))
247 events_ops = &ioport_events;
248 else {
249 pr_err("Unknown report event:%s\n", report_event);
250 ret = false;
251 }
252
253 return ret;
254}
255
256struct kvm_event_stats {
257 u64 time;
258 struct stats stats;
259};
260
261struct kvm_event {
262 struct list_head hash_entry;
263 struct rb_node rb;
264
265 struct event_key key;
266
267 struct kvm_event_stats total;
268
269 #define DEFAULT_VCPU_NUM 8
270 int max_vcpu;
271 struct kvm_event_stats *vcpu;
272};
273
274struct vcpu_event_record {
275 int vcpu_id;
276 u64 start_time;
277 struct kvm_event *last_event;
278};
279
280#define EVENTS_BITS 12
281#define EVENTS_CACHE_SIZE (1UL << EVENTS_BITS)
282
283static u64 total_time;
284static u64 total_count;
285static struct list_head kvm_events_cache[EVENTS_CACHE_SIZE];
286
287static void init_kvm_event_record(void)
288{
289 int i;
290
291 for (i = 0; i < (int)EVENTS_CACHE_SIZE; i++)
292 INIT_LIST_HEAD(&kvm_events_cache[i]);
293}
294
295static int kvm_events_hash_fn(u64 key)
296{
297 return key & (EVENTS_CACHE_SIZE - 1);
298}
299
300static bool kvm_event_expand(struct kvm_event *event, int vcpu_id)
301{
302 int old_max_vcpu = event->max_vcpu;
303
304 if (vcpu_id < event->max_vcpu)
305 return true;
306
307 while (event->max_vcpu <= vcpu_id)
308 event->max_vcpu += DEFAULT_VCPU_NUM;
309
310 event->vcpu = realloc(event->vcpu,
311 event->max_vcpu * sizeof(*event->vcpu));
312 if (!event->vcpu) {
313 pr_err("Not enough memory\n");
314 return false;
315 }
316
317 memset(event->vcpu + old_max_vcpu, 0,
318 (event->max_vcpu - old_max_vcpu) * sizeof(*event->vcpu));
319 return true;
320}
321
322static struct kvm_event *kvm_alloc_init_event(struct event_key *key)
323{
324 struct kvm_event *event;
325
326 event = zalloc(sizeof(*event));
327 if (!event) {
328 pr_err("Not enough memory\n");
329 return NULL;
330 }
331
332 event->key = *key;
333 return event;
334}
335
336static struct kvm_event *find_create_kvm_event(struct event_key *key)
337{
338 struct kvm_event *event;
339 struct list_head *head;
340
341 BUG_ON(key->key == INVALID_KEY);
342
343 head = &kvm_events_cache[kvm_events_hash_fn(key->key)];
344 list_for_each_entry(event, head, hash_entry)
345 if (event->key.key == key->key && event->key.info == key->info)
346 return event;
347
348 event = kvm_alloc_init_event(key);
349 if (!event)
350 return NULL;
351
352 list_add(&event->hash_entry, head);
353 return event;
354}
355
356static bool handle_begin_event(struct vcpu_event_record *vcpu_record,
357 struct event_key *key, u64 timestamp)
358{
359 struct kvm_event *event = NULL;
360
361 if (key->key != INVALID_KEY)
362 event = find_create_kvm_event(key);
363
364 vcpu_record->last_event = event;
365 vcpu_record->start_time = timestamp;
366 return true;
367}
368
369static void
370kvm_update_event_stats(struct kvm_event_stats *kvm_stats, u64 time_diff)
371{
372 kvm_stats->time += time_diff;
373 update_stats(&kvm_stats->stats, time_diff);
374}
375
376static double kvm_event_rel_stddev(int vcpu_id, struct kvm_event *event)
377{
378 struct kvm_event_stats *kvm_stats = &event->total;
379
380 if (vcpu_id != -1)
381 kvm_stats = &event->vcpu[vcpu_id];
382
383 return rel_stddev_stats(stddev_stats(&kvm_stats->stats),
384 avg_stats(&kvm_stats->stats));
385}
386
387static bool update_kvm_event(struct kvm_event *event, int vcpu_id,
388 u64 time_diff)
389{
390 kvm_update_event_stats(&event->total, time_diff);
391
392 if (!kvm_event_expand(event, vcpu_id))
393 return false;
394
395 kvm_update_event_stats(&event->vcpu[vcpu_id], time_diff);
396 return true;
397}
398
399static bool handle_end_event(struct vcpu_event_record *vcpu_record,
400 struct event_key *key, u64 timestamp)
401{
402 struct kvm_event *event;
403 u64 time_begin, time_diff;
404
405 event = vcpu_record->last_event;
406 time_begin = vcpu_record->start_time;
407
408 /* The begin event is not caught. */
409 if (!time_begin)
410 return true;
411
412 /*
413 * In some case, the 'begin event' only records the start timestamp,
414 * the actual event is recognized in the 'end event' (e.g. mmio-event).
415 */
416
417 /* Both begin and end events did not get the key. */
418 if (!event && key->key == INVALID_KEY)
419 return true;
420
421 if (!event)
422 event = find_create_kvm_event(key);
423
424 if (!event)
425 return false;
426
427 vcpu_record->last_event = NULL;
428 vcpu_record->start_time = 0;
429
430 BUG_ON(timestamp < time_begin);
431
432 time_diff = timestamp - time_begin;
433 return update_kvm_event(event, vcpu_record->vcpu_id, time_diff);
434}
435
436static
437struct vcpu_event_record *per_vcpu_record(struct thread *thread,
438 struct perf_evsel *evsel,
439 struct perf_sample *sample)
440{
441 /* Only kvm_entry records vcpu id. */
442 if (!thread->priv && kvm_entry_event(evsel)) {
443 struct vcpu_event_record *vcpu_record;
444
445 vcpu_record = zalloc(sizeof(*vcpu_record));
446 if (!vcpu_record) {
447 pr_err("%s: Not enough memory\n", __func__);
448 return NULL;
449 }
450
451 vcpu_record->vcpu_id = perf_evsel__intval(evsel, sample, "vcpu_id");
452 thread->priv = vcpu_record;
453 }
454
455 return thread->priv;
456}
457
458static bool handle_kvm_event(struct thread *thread, struct perf_evsel *evsel,
459 struct perf_sample *sample)
460{
461 struct vcpu_event_record *vcpu_record;
462 struct event_key key = {.key = INVALID_KEY};
463
464 vcpu_record = per_vcpu_record(thread, evsel, sample);
465 if (!vcpu_record)
466 return true;
467
468 if (events_ops->is_begin_event(evsel, sample, &key))
469 return handle_begin_event(vcpu_record, &key, sample->time);
470
471 if (events_ops->is_end_event(evsel, sample, &key))
472 return handle_end_event(vcpu_record, &key, sample->time);
473
474 return true;
475}
476
477typedef int (*key_cmp_fun)(struct kvm_event*, struct kvm_event*, int);
478struct kvm_event_key {
479 const char *name;
480 key_cmp_fun key;
481};
482
483static int trace_vcpu = -1;
484#define GET_EVENT_KEY(func, field) \
485static u64 get_event_ ##func(struct kvm_event *event, int vcpu) \
486{ \
487 if (vcpu == -1) \
488 return event->total.field; \
489 \
490 if (vcpu >= event->max_vcpu) \
491 return 0; \
492 \
493 return event->vcpu[vcpu].field; \
494}
495
496#define COMPARE_EVENT_KEY(func, field) \
497GET_EVENT_KEY(func, field) \
498static int compare_kvm_event_ ## func(struct kvm_event *one, \
499 struct kvm_event *two, int vcpu)\
500{ \
501 return get_event_ ##func(one, vcpu) > \
502 get_event_ ##func(two, vcpu); \
503}
504
505GET_EVENT_KEY(time, time);
506COMPARE_EVENT_KEY(count, stats.n);
507COMPARE_EVENT_KEY(mean, stats.mean);
508
509#define DEF_SORT_NAME_KEY(name, compare_key) \
510 { #name, compare_kvm_event_ ## compare_key }
511
512static struct kvm_event_key keys[] = {
513 DEF_SORT_NAME_KEY(sample, count),
514 DEF_SORT_NAME_KEY(time, mean),
515 { NULL, NULL }
516};
517
518static const char *sort_key = "sample";
519static key_cmp_fun compare;
520
521static bool select_key(void)
522{
523 int i;
524
525 for (i = 0; keys[i].name; i++) {
526 if (!strcmp(keys[i].name, sort_key)) {
527 compare = keys[i].key;
528 return true;
529 }
530 }
531
532 pr_err("Unknown compare key:%s\n", sort_key);
533 return false;
534}
535
536static struct rb_root result;
537static void insert_to_result(struct kvm_event *event, key_cmp_fun bigger,
538 int vcpu)
539{
540 struct rb_node **rb = &result.rb_node;
541 struct rb_node *parent = NULL;
542 struct kvm_event *p;
543
544 while (*rb) {
545 p = container_of(*rb, struct kvm_event, rb);
546 parent = *rb;
547
548 if (bigger(event, p, vcpu))
549 rb = &(*rb)->rb_left;
550 else
551 rb = &(*rb)->rb_right;
552 }
553
554 rb_link_node(&event->rb, parent, rb);
555 rb_insert_color(&event->rb, &result);
556}
557
558static void update_total_count(struct kvm_event *event, int vcpu)
559{
560 total_count += get_event_count(event, vcpu);
561 total_time += get_event_time(event, vcpu);
562}
563
564static bool event_is_valid(struct kvm_event *event, int vcpu)
565{
566 return !!get_event_count(event, vcpu);
567}
568
569static void sort_result(int vcpu)
570{
571 unsigned int i;
572 struct kvm_event *event;
573
574 for (i = 0; i < EVENTS_CACHE_SIZE; i++)
575 list_for_each_entry(event, &kvm_events_cache[i], hash_entry)
576 if (event_is_valid(event, vcpu)) {
577 update_total_count(event, vcpu);
578 insert_to_result(event, compare, vcpu);
579 }
580}
581
582/* returns left most element of result, and erase it */
583static struct kvm_event *pop_from_result(void)
584{
585 struct rb_node *node = rb_first(&result);
586
587 if (!node)
588 return NULL;
589
590 rb_erase(node, &result);
591 return container_of(node, struct kvm_event, rb);
592}
593
594static void print_vcpu_info(int vcpu)
595{
596 pr_info("Analyze events for ");
597
598 if (vcpu == -1)
599 pr_info("all VCPUs:\n\n");
600 else
601 pr_info("VCPU %d:\n\n", vcpu);
602}
603
604static void print_result(int vcpu)
605{
606 char decode[20];
607 struct kvm_event *event;
608
609 pr_info("\n\n");
610 print_vcpu_info(vcpu);
611 pr_info("%20s ", events_ops->name);
612 pr_info("%10s ", "Samples");
613 pr_info("%9s ", "Samples%");
614
615 pr_info("%9s ", "Time%");
616 pr_info("%16s ", "Avg time");
617 pr_info("\n\n");
618
619 while ((event = pop_from_result())) {
620 u64 ecount, etime;
621
622 ecount = get_event_count(event, vcpu);
623 etime = get_event_time(event, vcpu);
624
625 events_ops->decode_key(&event->key, decode);
626 pr_info("%20s ", decode);
627 pr_info("%10llu ", (unsigned long long)ecount);
628 pr_info("%8.2f%% ", (double)ecount / total_count * 100);
629 pr_info("%8.2f%% ", (double)etime / total_time * 100);
630 pr_info("%9.2fus ( +-%7.2f%% )", (double)etime / ecount/1e3,
631 kvm_event_rel_stddev(vcpu, event));
632 pr_info("\n");
633 }
634
635 pr_info("\nTotal Samples:%lld, Total events handled time:%.2fus.\n\n",
636 (unsigned long long)total_count, total_time / 1e3);
637}
638
639static int process_sample_event(struct perf_tool *tool __maybe_unused,
640 union perf_event *event,
641 struct perf_sample *sample,
642 struct perf_evsel *evsel,
643 struct machine *machine)
644{
645 struct thread *thread = machine__findnew_thread(machine, sample->tid);
646
647 if (thread == NULL) {
648 pr_debug("problem processing %d event, skipping it.\n",
649 event->header.type);
650 return -1;
651 }
652
653 if (!handle_kvm_event(thread, evsel, sample))
654 return -1;
655
656 return 0;
657}
658
659static struct perf_tool eops = {
660 .sample = process_sample_event,
661 .comm = perf_event__process_comm,
662 .ordered_samples = true,
663};
664
665static int get_cpu_isa(struct perf_session *session)
666{
667 char *cpuid = session->header.env.cpuid;
668 int isa;
669
670 if (strstr(cpuid, "Intel"))
671 isa = 1;
672 else if (strstr(cpuid, "AMD"))
673 isa = 0;
674 else {
675 pr_err("CPU %s is not supported.\n", cpuid);
676 isa = -ENOTSUP;
677 }
678
679 return isa;
680}
681
682static const char *file_name;
683
684static int read_events(void)
685{
686 struct perf_session *kvm_session;
687 int ret;
688
689 kvm_session = perf_session__new(file_name, O_RDONLY, 0, false, &eops);
690 if (!kvm_session) {
691 pr_err("Initializing perf session failed\n");
692 return -EINVAL;
693 }
694
695 if (!perf_session__has_traces(kvm_session, "kvm record"))
696 return -EINVAL;
697
698 /*
699 * Do not use 'isa' recorded in kvm_exit tracepoint since it is not
700 * traced in the old kernel.
701 */
702 ret = get_cpu_isa(kvm_session);
703
704 if (ret < 0)
705 return ret;
706
707 cpu_isa = ret;
708
709 return perf_session__process_events(kvm_session, &eops);
710}
711
712static bool verify_vcpu(int vcpu)
713{
714 if (vcpu != -1 && vcpu < 0) {
715 pr_err("Invalid vcpu:%d.\n", vcpu);
716 return false;
717 }
718
719 return true;
720}
721
722static int kvm_events_report_vcpu(int vcpu)
723{
724 int ret = -EINVAL;
725
726 if (!verify_vcpu(vcpu))
727 goto exit;
728
729 if (!select_key())
730 goto exit;
731
732 if (!register_kvm_events_ops())
733 goto exit;
734
735 init_kvm_event_record();
736 setup_pager();
737
738 ret = read_events();
739 if (ret)
740 goto exit;
741
742 sort_result(vcpu);
743 print_result(vcpu);
744exit:
745 return ret;
746}
747
748static const char * const record_args[] = {
749 "record",
750 "-R",
751 "-f",
752 "-m", "1024",
753 "-c", "1",
754 "-e", "kvm:kvm_entry",
755 "-e", "kvm:kvm_exit",
756 "-e", "kvm:kvm_mmio",
757 "-e", "kvm:kvm_pio",
758};
759
760#define STRDUP_FAIL_EXIT(s) \
761 ({ char *_p; \
762 _p = strdup(s); \
763 if (!_p) \
764 return -ENOMEM; \
765 _p; \
766 })
767
768static int kvm_events_record(int argc, const char **argv)
769{
770 unsigned int rec_argc, i, j;
771 const char **rec_argv;
772
773 rec_argc = ARRAY_SIZE(record_args) + argc + 2;
774 rec_argv = calloc(rec_argc + 1, sizeof(char *));
775
776 if (rec_argv == NULL)
777 return -ENOMEM;
778
779 for (i = 0; i < ARRAY_SIZE(record_args); i++)
780 rec_argv[i] = STRDUP_FAIL_EXIT(record_args[i]);
781
782 rec_argv[i++] = STRDUP_FAIL_EXIT("-o");
783 rec_argv[i++] = STRDUP_FAIL_EXIT(file_name);
784
785 for (j = 1; j < (unsigned int)argc; j++, i++)
786 rec_argv[i] = argv[j];
787
788 return cmd_record(i, rec_argv, NULL);
789}
790
791static const char * const kvm_events_report_usage[] = {
792 "perf kvm stat report [<options>]",
793 NULL
794};
795
796static const struct option kvm_events_report_options[] = {
797 OPT_STRING(0, "event", &report_event, "report event",
798 "event for reporting: vmexit, mmio, ioport"),
799 OPT_INTEGER(0, "vcpu", &trace_vcpu,
800 "vcpu id to report"),
801 OPT_STRING('k', "key", &sort_key, "sort-key",
802 "key for sorting: sample(sort by samples number)"
803 " time (sort by avg time)"),
804 OPT_END()
805};
806
807static int kvm_events_report(int argc, const char **argv)
808{
809 symbol__init();
810
811 if (argc) {
812 argc = parse_options(argc, argv,
813 kvm_events_report_options,
814 kvm_events_report_usage, 0);
815 if (argc)
816 usage_with_options(kvm_events_report_usage,
817 kvm_events_report_options);
818 }
819
820 return kvm_events_report_vcpu(trace_vcpu);
821}
822
823static void print_kvm_stat_usage(void)
824{
825 printf("Usage: perf kvm stat <command>\n\n");
826
827 printf("# Available commands:\n");
828 printf("\trecord: record kvm events\n");
829 printf("\treport: report statistical data of kvm events\n");
830
831 printf("\nOtherwise, it is the alias of 'perf stat':\n");
832}
833
834static int kvm_cmd_stat(int argc, const char **argv)
835{
836 if (argc == 1) {
837 print_kvm_stat_usage();
838 goto perf_stat;
839 }
840
841 if (!strncmp(argv[1], "rec", 3))
842 return kvm_events_record(argc - 1, argv + 1);
843
844 if (!strncmp(argv[1], "rep", 3))
845 return kvm_events_report(argc - 1 , argv + 1);
846
847perf_stat:
848 return cmd_stat(argc, argv, NULL);
849}
850
23static char name_buffer[256]; 851static char name_buffer[256];
24 852
25static const char * const kvm_usage[] = { 853static const char * const kvm_usage[] = {
26 "perf kvm [<options>] {top|record|report|diff|buildid-list}", 854 "perf kvm [<options>] {top|record|report|diff|buildid-list|stat}",
27 NULL 855 NULL
28}; 856};
29 857
@@ -135,6 +963,8 @@ int cmd_kvm(int argc, const char **argv, const char *prefix __maybe_unused)
135 return cmd_top(argc, argv, NULL); 963 return cmd_top(argc, argv, NULL);
136 else if (!strncmp(argv[0], "buildid-list", 12)) 964 else if (!strncmp(argv[0], "buildid-list", 12))
137 return __cmd_buildid_list(argc, argv); 965 return __cmd_buildid_list(argc, argv);
966 else if (!strncmp(argv[0], "stat", 4))
967 return kvm_cmd_stat(argc, argv);
138 else 968 else
139 usage_with_options(kvm_usage, kvm_options); 969 usage_with_options(kvm_usage, kvm_options);
140 970
diff --git a/tools/perf/builtin-lock.c b/tools/perf/builtin-lock.c
index a8035207a3dd..7d6e09949880 100644
--- a/tools/perf/builtin-lock.c
+++ b/tools/perf/builtin-lock.c
@@ -1,6 +1,7 @@
1#include "builtin.h" 1#include "builtin.h"
2#include "perf.h" 2#include "perf.h"
3 3
4#include "util/evlist.h"
4#include "util/evsel.h" 5#include "util/evsel.h"
5#include "util/util.h" 6#include "util/util.h"
6#include "util/cache.h" 7#include "util/cache.h"
@@ -41,7 +42,7 @@ struct lock_stat {
41 struct rb_node rb; /* used for sorting */ 42 struct rb_node rb; /* used for sorting */
42 43
43 /* 44 /*
44 * FIXME: raw_field_value() returns unsigned long long, 45 * FIXME: perf_evsel__intval() returns u64,
45 * so address of lockdep_map should be dealed as 64bit. 46 * so address of lockdep_map should be dealed as 64bit.
46 * Is there more better solution? 47 * Is there more better solution?
47 */ 48 */
@@ -336,44 +337,18 @@ alloc_failed:
336 337
337static const char *input_name; 338static const char *input_name;
338 339
339struct raw_event_sample {
340 u32 size;
341 char data[0];
342};
343
344struct trace_acquire_event {
345 void *addr;
346 const char *name;
347 int flag;
348};
349
350struct trace_acquired_event {
351 void *addr;
352 const char *name;
353};
354
355struct trace_contended_event {
356 void *addr;
357 const char *name;
358};
359
360struct trace_release_event {
361 void *addr;
362 const char *name;
363};
364
365struct trace_lock_handler { 340struct trace_lock_handler {
366 int (*acquire_event)(struct trace_acquire_event *, 341 int (*acquire_event)(struct perf_evsel *evsel,
367 const struct perf_sample *sample); 342 struct perf_sample *sample);
368 343
369 int (*acquired_event)(struct trace_acquired_event *, 344 int (*acquired_event)(struct perf_evsel *evsel,
370 const struct perf_sample *sample); 345 struct perf_sample *sample);
371 346
372 int (*contended_event)(struct trace_contended_event *, 347 int (*contended_event)(struct perf_evsel *evsel,
373 const struct perf_sample *sample); 348 struct perf_sample *sample);
374 349
375 int (*release_event)(struct trace_release_event *, 350 int (*release_event)(struct perf_evsel *evsel,
376 const struct perf_sample *sample); 351 struct perf_sample *sample);
377}; 352};
378 353
379static struct lock_seq_stat *get_seq(struct thread_stat *ts, void *addr) 354static struct lock_seq_stat *get_seq(struct thread_stat *ts, void *addr)
@@ -412,15 +387,20 @@ enum acquire_flags {
412 READ_LOCK = 2, 387 READ_LOCK = 2,
413}; 388};
414 389
415static int 390static int report_lock_acquire_event(struct perf_evsel *evsel,
416report_lock_acquire_event(struct trace_acquire_event *acquire_event, 391 struct perf_sample *sample)
417 const struct perf_sample *sample)
418{ 392{
393 void *addr;
419 struct lock_stat *ls; 394 struct lock_stat *ls;
420 struct thread_stat *ts; 395 struct thread_stat *ts;
421 struct lock_seq_stat *seq; 396 struct lock_seq_stat *seq;
397 const char *name = perf_evsel__strval(evsel, sample, "name");
398 u64 tmp = perf_evsel__intval(evsel, sample, "lockdep_addr");
399 int flag = perf_evsel__intval(evsel, sample, "flag");
422 400
423 ls = lock_stat_findnew(acquire_event->addr, acquire_event->name); 401 memcpy(&addr, &tmp, sizeof(void *));
402
403 ls = lock_stat_findnew(addr, name);
424 if (!ls) 404 if (!ls)
425 return -1; 405 return -1;
426 if (ls->discard) 406 if (ls->discard)
@@ -430,19 +410,19 @@ report_lock_acquire_event(struct trace_acquire_event *acquire_event,
430 if (!ts) 410 if (!ts)
431 return -1; 411 return -1;
432 412
433 seq = get_seq(ts, acquire_event->addr); 413 seq = get_seq(ts, addr);
434 if (!seq) 414 if (!seq)
435 return -1; 415 return -1;
436 416
437 switch (seq->state) { 417 switch (seq->state) {
438 case SEQ_STATE_UNINITIALIZED: 418 case SEQ_STATE_UNINITIALIZED:
439 case SEQ_STATE_RELEASED: 419 case SEQ_STATE_RELEASED:
440 if (!acquire_event->flag) { 420 if (!flag) {
441 seq->state = SEQ_STATE_ACQUIRING; 421 seq->state = SEQ_STATE_ACQUIRING;
442 } else { 422 } else {
443 if (acquire_event->flag & TRY_LOCK) 423 if (flag & TRY_LOCK)
444 ls->nr_trylock++; 424 ls->nr_trylock++;
445 if (acquire_event->flag & READ_LOCK) 425 if (flag & READ_LOCK)
446 ls->nr_readlock++; 426 ls->nr_readlock++;
447 seq->state = SEQ_STATE_READ_ACQUIRED; 427 seq->state = SEQ_STATE_READ_ACQUIRED;
448 seq->read_count = 1; 428 seq->read_count = 1;
@@ -450,7 +430,7 @@ report_lock_acquire_event(struct trace_acquire_event *acquire_event,
450 } 430 }
451 break; 431 break;
452 case SEQ_STATE_READ_ACQUIRED: 432 case SEQ_STATE_READ_ACQUIRED:
453 if (acquire_event->flag & READ_LOCK) { 433 if (flag & READ_LOCK) {
454 seq->read_count++; 434 seq->read_count++;
455 ls->nr_acquired++; 435 ls->nr_acquired++;
456 goto end; 436 goto end;
@@ -480,17 +460,20 @@ end:
480 return 0; 460 return 0;
481} 461}
482 462
483static int 463static int report_lock_acquired_event(struct perf_evsel *evsel,
484report_lock_acquired_event(struct trace_acquired_event *acquired_event, 464 struct perf_sample *sample)
485 const struct perf_sample *sample)
486{ 465{
487 u64 timestamp = sample->time; 466 void *addr;
488 struct lock_stat *ls; 467 struct lock_stat *ls;
489 struct thread_stat *ts; 468 struct thread_stat *ts;
490 struct lock_seq_stat *seq; 469 struct lock_seq_stat *seq;
491 u64 contended_term; 470 u64 contended_term;
471 const char *name = perf_evsel__strval(evsel, sample, "name");
472 u64 tmp = perf_evsel__intval(evsel, sample, "lockdep_addr");
473
474 memcpy(&addr, &tmp, sizeof(void *));
492 475
493 ls = lock_stat_findnew(acquired_event->addr, acquired_event->name); 476 ls = lock_stat_findnew(addr, name);
494 if (!ls) 477 if (!ls)
495 return -1; 478 return -1;
496 if (ls->discard) 479 if (ls->discard)
@@ -500,7 +483,7 @@ report_lock_acquired_event(struct trace_acquired_event *acquired_event,
500 if (!ts) 483 if (!ts)
501 return -1; 484 return -1;
502 485
503 seq = get_seq(ts, acquired_event->addr); 486 seq = get_seq(ts, addr);
504 if (!seq) 487 if (!seq)
505 return -1; 488 return -1;
506 489
@@ -511,7 +494,7 @@ report_lock_acquired_event(struct trace_acquired_event *acquired_event,
511 case SEQ_STATE_ACQUIRING: 494 case SEQ_STATE_ACQUIRING:
512 break; 495 break;
513 case SEQ_STATE_CONTENDED: 496 case SEQ_STATE_CONTENDED:
514 contended_term = timestamp - seq->prev_event_time; 497 contended_term = sample->time - seq->prev_event_time;
515 ls->wait_time_total += contended_term; 498 ls->wait_time_total += contended_term;
516 if (contended_term < ls->wait_time_min) 499 if (contended_term < ls->wait_time_min)
517 ls->wait_time_min = contended_term; 500 ls->wait_time_min = contended_term;
@@ -536,20 +519,24 @@ report_lock_acquired_event(struct trace_acquired_event *acquired_event,
536 519
537 seq->state = SEQ_STATE_ACQUIRED; 520 seq->state = SEQ_STATE_ACQUIRED;
538 ls->nr_acquired++; 521 ls->nr_acquired++;
539 seq->prev_event_time = timestamp; 522 seq->prev_event_time = sample->time;
540end: 523end:
541 return 0; 524 return 0;
542} 525}
543 526
544static int 527static int report_lock_contended_event(struct perf_evsel *evsel,
545report_lock_contended_event(struct trace_contended_event *contended_event, 528 struct perf_sample *sample)
546 const struct perf_sample *sample)
547{ 529{
530 void *addr;
548 struct lock_stat *ls; 531 struct lock_stat *ls;
549 struct thread_stat *ts; 532 struct thread_stat *ts;
550 struct lock_seq_stat *seq; 533 struct lock_seq_stat *seq;
534 const char *name = perf_evsel__strval(evsel, sample, "name");
535 u64 tmp = perf_evsel__intval(evsel, sample, "lockdep_addr");
536
537 memcpy(&addr, &tmp, sizeof(void *));
551 538
552 ls = lock_stat_findnew(contended_event->addr, contended_event->name); 539 ls = lock_stat_findnew(addr, name);
553 if (!ls) 540 if (!ls)
554 return -1; 541 return -1;
555 if (ls->discard) 542 if (ls->discard)
@@ -559,7 +546,7 @@ report_lock_contended_event(struct trace_contended_event *contended_event,
559 if (!ts) 546 if (!ts)
560 return -1; 547 return -1;
561 548
562 seq = get_seq(ts, contended_event->addr); 549 seq = get_seq(ts, addr);
563 if (!seq) 550 if (!seq)
564 return -1; 551 return -1;
565 552
@@ -592,15 +579,19 @@ end:
592 return 0; 579 return 0;
593} 580}
594 581
595static int 582static int report_lock_release_event(struct perf_evsel *evsel,
596report_lock_release_event(struct trace_release_event *release_event, 583 struct perf_sample *sample)
597 const struct perf_sample *sample)
598{ 584{
585 void *addr;
599 struct lock_stat *ls; 586 struct lock_stat *ls;
600 struct thread_stat *ts; 587 struct thread_stat *ts;
601 struct lock_seq_stat *seq; 588 struct lock_seq_stat *seq;
589 const char *name = perf_evsel__strval(evsel, sample, "name");
590 u64 tmp = perf_evsel__intval(evsel, sample, "lockdep_addr");
602 591
603 ls = lock_stat_findnew(release_event->addr, release_event->name); 592 memcpy(&addr, &tmp, sizeof(void *));
593
594 ls = lock_stat_findnew(addr, name);
604 if (!ls) 595 if (!ls)
605 return -1; 596 return -1;
606 if (ls->discard) 597 if (ls->discard)
@@ -610,7 +601,7 @@ report_lock_release_event(struct trace_release_event *release_event,
610 if (!ts) 601 if (!ts)
611 return -1; 602 return -1;
612 603
613 seq = get_seq(ts, release_event->addr); 604 seq = get_seq(ts, addr);
614 if (!seq) 605 if (!seq)
615 return -1; 606 return -1;
616 607
@@ -663,96 +654,33 @@ static struct trace_lock_handler *trace_handler;
663static int perf_evsel__process_lock_acquire(struct perf_evsel *evsel, 654static int perf_evsel__process_lock_acquire(struct perf_evsel *evsel,
664 struct perf_sample *sample) 655 struct perf_sample *sample)
665{ 656{
666 struct trace_acquire_event acquire_event;
667 struct event_format *event = evsel->tp_format;
668 void *data = sample->raw_data;
669 u64 tmp; /* this is required for casting... */
670 int rc = 0;
671
672 tmp = raw_field_value(event, "lockdep_addr", data);
673 memcpy(&acquire_event.addr, &tmp, sizeof(void *));
674 acquire_event.name = (char *)raw_field_ptr(event, "name", data);
675 acquire_event.flag = (int)raw_field_value(event, "flag", data);
676
677 if (trace_handler->acquire_event) 657 if (trace_handler->acquire_event)
678 rc = trace_handler->acquire_event(&acquire_event, sample); 658 return trace_handler->acquire_event(evsel, sample);
679 659 return 0;
680 return rc;
681} 660}
682 661
683static int perf_evsel__process_lock_acquired(struct perf_evsel *evsel, 662static int perf_evsel__process_lock_acquired(struct perf_evsel *evsel,
684 struct perf_sample *sample) 663 struct perf_sample *sample)
685{ 664{
686 struct trace_acquired_event acquired_event;
687 struct event_format *event = evsel->tp_format;
688 void *data = sample->raw_data;
689 u64 tmp; /* this is required for casting... */
690 int rc = 0;
691
692 tmp = raw_field_value(event, "lockdep_addr", data);
693 memcpy(&acquired_event.addr, &tmp, sizeof(void *));
694 acquired_event.name = (char *)raw_field_ptr(event, "name", data);
695
696 if (trace_handler->acquired_event) 665 if (trace_handler->acquired_event)
697 rc = trace_handler->acquired_event(&acquired_event, sample); 666 return trace_handler->acquired_event(evsel, sample);
698 667 return 0;
699 return rc;
700} 668}
701 669
702static int perf_evsel__process_lock_contended(struct perf_evsel *evsel, 670static int perf_evsel__process_lock_contended(struct perf_evsel *evsel,
703 struct perf_sample *sample) 671 struct perf_sample *sample)
704{ 672{
705 struct trace_contended_event contended_event;
706 struct event_format *event = evsel->tp_format;
707 void *data = sample->raw_data;
708 u64 tmp; /* this is required for casting... */
709 int rc = 0;
710
711 tmp = raw_field_value(event, "lockdep_addr", data);
712 memcpy(&contended_event.addr, &tmp, sizeof(void *));
713 contended_event.name = (char *)raw_field_ptr(event, "name", data);
714
715 if (trace_handler->contended_event) 673 if (trace_handler->contended_event)
716 rc = trace_handler->contended_event(&contended_event, sample); 674 return trace_handler->contended_event(evsel, sample);
717 675 return 0;
718 return rc;
719} 676}
720 677
721static int perf_evsel__process_lock_release(struct perf_evsel *evsel, 678static int perf_evsel__process_lock_release(struct perf_evsel *evsel,
722 struct perf_sample *sample) 679 struct perf_sample *sample)
723{ 680{
724 struct trace_release_event release_event;
725 struct event_format *event = evsel->tp_format;
726 void *data = sample->raw_data;
727 u64 tmp; /* this is required for casting... */
728 int rc = 0;
729
730 tmp = raw_field_value(event, "lockdep_addr", data);
731 memcpy(&release_event.addr, &tmp, sizeof(void *));
732 release_event.name = (char *)raw_field_ptr(event, "name", data);
733
734 if (trace_handler->release_event) 681 if (trace_handler->release_event)
735 rc = trace_handler->release_event(&release_event, sample); 682 return trace_handler->release_event(evsel, sample);
736 683 return 0;
737 return rc;
738}
739
740static int perf_evsel__process_lock_event(struct perf_evsel *evsel,
741 struct perf_sample *sample)
742{
743 struct event_format *event = evsel->tp_format;
744 int rc = 0;
745
746 if (!strcmp(event->name, "lock_acquire"))
747 rc = perf_evsel__process_lock_acquire(evsel, sample);
748 if (!strcmp(event->name, "lock_acquired"))
749 rc = perf_evsel__process_lock_acquired(evsel, sample);
750 if (!strcmp(event->name, "lock_contended"))
751 rc = perf_evsel__process_lock_contended(evsel, sample);
752 if (!strcmp(event->name, "lock_release"))
753 rc = perf_evsel__process_lock_release(evsel, sample);
754
755 return rc;
756} 684}
757 685
758static void print_bad_events(int bad, int total) 686static void print_bad_events(int bad, int total)
@@ -870,6 +798,9 @@ static int dump_info(void)
870 return rc; 798 return rc;
871} 799}
872 800
801typedef int (*tracepoint_handler)(struct perf_evsel *evsel,
802 struct perf_sample *sample);
803
873static int process_sample_event(struct perf_tool *tool __maybe_unused, 804static int process_sample_event(struct perf_tool *tool __maybe_unused,
874 union perf_event *event, 805 union perf_event *event,
875 struct perf_sample *sample, 806 struct perf_sample *sample,
@@ -884,7 +815,12 @@ static int process_sample_event(struct perf_tool *tool __maybe_unused,
884 return -1; 815 return -1;
885 } 816 }
886 817
887 return perf_evsel__process_lock_event(evsel, sample); 818 if (evsel->handler.func != NULL) {
819 tracepoint_handler f = evsel->handler.func;
820 return f(evsel, sample);
821 }
822
823 return 0;
888} 824}
889 825
890static struct perf_tool eops = { 826static struct perf_tool eops = {
@@ -893,6 +829,13 @@ static struct perf_tool eops = {
893 .ordered_samples = true, 829 .ordered_samples = true,
894}; 830};
895 831
832static const struct perf_evsel_str_handler lock_tracepoints[] = {
833 { "lock:lock_acquire", perf_evsel__process_lock_acquire, }, /* CONFIG_LOCKDEP */
834 { "lock:lock_acquired", perf_evsel__process_lock_acquired, }, /* CONFIG_LOCKDEP, CONFIG_LOCK_STAT */
835 { "lock:lock_contended", perf_evsel__process_lock_contended, }, /* CONFIG_LOCKDEP, CONFIG_LOCK_STAT */
836 { "lock:lock_release", perf_evsel__process_lock_release, }, /* CONFIG_LOCKDEP */
837};
838
896static int read_events(void) 839static int read_events(void)
897{ 840{
898 session = perf_session__new(input_name, O_RDONLY, 0, false, &eops); 841 session = perf_session__new(input_name, O_RDONLY, 0, false, &eops);
@@ -901,6 +844,11 @@ static int read_events(void)
901 return -1; 844 return -1;
902 } 845 }
903 846
847 if (perf_session__set_tracepoints_handlers(session, lock_tracepoints)) {
848 pr_err("Initializing perf session tracepoint handlers failed\n");
849 return -1;
850 }
851
904 return perf_session__process_events(session, &eops); 852 return perf_session__process_events(session, &eops);
905} 853}
906 854
@@ -967,13 +915,6 @@ static const struct option lock_options[] = {
967 OPT_END() 915 OPT_END()
968}; 916};
969 917
970static const char * const lock_tracepoints[] = {
971 "lock:lock_acquire", /* CONFIG_LOCKDEP */
972 "lock:lock_acquired", /* CONFIG_LOCKDEP, CONFIG_LOCK_STAT */
973 "lock:lock_contended", /* CONFIG_LOCKDEP, CONFIG_LOCK_STAT */
974 "lock:lock_release", /* CONFIG_LOCKDEP */
975};
976
977static const char *record_args[] = { 918static const char *record_args[] = {
978 "record", 919 "record",
979 "-R", 920 "-R",
@@ -988,10 +929,10 @@ static int __cmd_record(int argc, const char **argv)
988 const char **rec_argv; 929 const char **rec_argv;
989 930
990 for (i = 0; i < ARRAY_SIZE(lock_tracepoints); i++) { 931 for (i = 0; i < ARRAY_SIZE(lock_tracepoints); i++) {
991 if (!is_valid_tracepoint(lock_tracepoints[i])) { 932 if (!is_valid_tracepoint(lock_tracepoints[i].name)) {
992 pr_err("tracepoint %s is not enabled. " 933 pr_err("tracepoint %s is not enabled. "
993 "Are CONFIG_LOCKDEP and CONFIG_LOCK_STAT enabled?\n", 934 "Are CONFIG_LOCKDEP and CONFIG_LOCK_STAT enabled?\n",
994 lock_tracepoints[i]); 935 lock_tracepoints[i].name);
995 return 1; 936 return 1;
996 } 937 }
997 } 938 }
@@ -1009,7 +950,7 @@ static int __cmd_record(int argc, const char **argv)
1009 950
1010 for (j = 0; j < ARRAY_SIZE(lock_tracepoints); j++) { 951 for (j = 0; j < ARRAY_SIZE(lock_tracepoints); j++) {
1011 rec_argv[i++] = "-e"; 952 rec_argv[i++] = "-e";
1012 rec_argv[i++] = strdup(lock_tracepoints[j]); 953 rec_argv[i++] = strdup(lock_tracepoints[j].name);
1013 } 954 }
1014 955
1015 for (j = 1; j < (unsigned int)argc; j++, i++) 956 for (j = 1; j < (unsigned int)argc; j++, i++)
diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c
index c643ed669ef9..2cb74343de3e 100644
--- a/tools/perf/builtin-record.c
+++ b/tools/perf/builtin-record.c
@@ -297,8 +297,10 @@ try_again:
297 } 297 }
298 298
299 printf("\n"); 299 printf("\n");
300 error("sys_perf_event_open() syscall returned with %d (%s). /bin/dmesg may provide additional information.\n", 300 error("sys_perf_event_open() syscall returned with %d "
301 err, strerror(err)); 301 "(%s) for event %s. /bin/dmesg may provide "
302 "additional information.\n",
303 err, strerror(err), perf_evsel__name(pos));
302 304
303#if defined(__i386__) || defined(__x86_64__) 305#if defined(__i386__) || defined(__x86_64__)
304 if (attr->type == PERF_TYPE_HARDWARE && 306 if (attr->type == PERF_TYPE_HARDWARE &&
diff --git a/tools/perf/builtin-test.c b/tools/perf/builtin-test.c
index 4aed1553db56..32caf13cfe01 100644
--- a/tools/perf/builtin-test.c
+++ b/tools/perf/builtin-test.c
@@ -14,6 +14,7 @@
14#include "util/symbol.h" 14#include "util/symbol.h"
15#include "util/thread_map.h" 15#include "util/thread_map.h"
16#include "util/pmu.h" 16#include "util/pmu.h"
17#include "event-parse.h"
17#include "../../include/linux/hw_breakpoint.h" 18#include "../../include/linux/hw_breakpoint.h"
18 19
19#include <sys/mman.h> 20#include <sys/mman.h>
@@ -1207,6 +1208,87 @@ static int perf_evsel__roundtrip_name_test(void)
1207 return ret; 1208 return ret;
1208} 1209}
1209 1210
1211static int perf_evsel__test_field(struct perf_evsel *evsel, const char *name,
1212 int size, bool should_be_signed)
1213{
1214 struct format_field *field = perf_evsel__field(evsel, name);
1215 int is_signed;
1216 int ret = 0;
1217
1218 if (field == NULL) {
1219 pr_debug("%s: \"%s\" field not found!\n", evsel->name, name);
1220 return -1;
1221 }
1222
1223 is_signed = !!(field->flags | FIELD_IS_SIGNED);
1224 if (should_be_signed && !is_signed) {
1225 pr_debug("%s: \"%s\" signedness(%d) is wrong, should be %d\n",
1226 evsel->name, name, is_signed, should_be_signed);
1227 ret = -1;
1228 }
1229
1230 if (field->size != size) {
1231 pr_debug("%s: \"%s\" size (%d) should be %d!\n",
1232 evsel->name, name, field->size, size);
1233 ret = -1;
1234 }
1235
1236 return 0;
1237}
1238
1239static int perf_evsel__tp_sched_test(void)
1240{
1241 struct perf_evsel *evsel = perf_evsel__newtp("sched", "sched_switch", 0);
1242 int ret = 0;
1243
1244 if (evsel == NULL) {
1245 pr_debug("perf_evsel__new\n");
1246 return -1;
1247 }
1248
1249 if (perf_evsel__test_field(evsel, "prev_comm", 16, true))
1250 ret = -1;
1251
1252 if (perf_evsel__test_field(evsel, "prev_pid", 4, true))
1253 ret = -1;
1254
1255 if (perf_evsel__test_field(evsel, "prev_prio", 4, true))
1256 ret = -1;
1257
1258 if (perf_evsel__test_field(evsel, "prev_state", 8, true))
1259 ret = -1;
1260
1261 if (perf_evsel__test_field(evsel, "next_comm", 16, true))
1262 ret = -1;
1263
1264 if (perf_evsel__test_field(evsel, "next_pid", 4, true))
1265 ret = -1;
1266
1267 if (perf_evsel__test_field(evsel, "next_prio", 4, true))
1268 ret = -1;
1269
1270 perf_evsel__delete(evsel);
1271
1272 evsel = perf_evsel__newtp("sched", "sched_wakeup", 0);
1273
1274 if (perf_evsel__test_field(evsel, "comm", 16, true))
1275 ret = -1;
1276
1277 if (perf_evsel__test_field(evsel, "pid", 4, true))
1278 ret = -1;
1279
1280 if (perf_evsel__test_field(evsel, "prio", 4, true))
1281 ret = -1;
1282
1283 if (perf_evsel__test_field(evsel, "success", 4, true))
1284 ret = -1;
1285
1286 if (perf_evsel__test_field(evsel, "target_cpu", 4, true))
1287 ret = -1;
1288
1289 return 0;
1290}
1291
1210static struct test { 1292static struct test {
1211 const char *desc; 1293 const char *desc;
1212 int (*func)(void); 1294 int (*func)(void);
@@ -1254,6 +1336,10 @@ static struct test {
1254 .func = perf_evsel__roundtrip_name_test, 1336 .func = perf_evsel__roundtrip_name_test,
1255 }, 1337 },
1256 { 1338 {
1339 .desc = "Check parsing of sched tracepoints fields",
1340 .func = perf_evsel__tp_sched_test,
1341 },
1342 {
1257 .func = NULL, 1343 .func = NULL,
1258 }, 1344 },
1259}; 1345};
diff --git a/tools/perf/builtin-timechart.c b/tools/perf/builtin-timechart.c
index 55a3a6c6b9e7..b1a8a3b841cc 100644
--- a/tools/perf/builtin-timechart.c
+++ b/tools/perf/builtin-timechart.c
@@ -168,9 +168,8 @@ static struct per_pid *find_create_pid(int pid)
168 return cursor; 168 return cursor;
169 cursor = cursor->next; 169 cursor = cursor->next;
170 } 170 }
171 cursor = malloc(sizeof(struct per_pid)); 171 cursor = zalloc(sizeof(*cursor));
172 assert(cursor != NULL); 172 assert(cursor != NULL);
173 memset(cursor, 0, sizeof(struct per_pid));
174 cursor->pid = pid; 173 cursor->pid = pid;
175 cursor->next = all_data; 174 cursor->next = all_data;
176 all_data = cursor; 175 all_data = cursor;
@@ -195,9 +194,8 @@ static void pid_set_comm(int pid, char *comm)
195 } 194 }
196 c = c->next; 195 c = c->next;
197 } 196 }
198 c = malloc(sizeof(struct per_pidcomm)); 197 c = zalloc(sizeof(*c));
199 assert(c != NULL); 198 assert(c != NULL);
200 memset(c, 0, sizeof(struct per_pidcomm));
201 c->comm = strdup(comm); 199 c->comm = strdup(comm);
202 p->current = c; 200 p->current = c;
203 c->next = p->all; 201 c->next = p->all;
@@ -239,17 +237,15 @@ pid_put_sample(int pid, int type, unsigned int cpu, u64 start, u64 end)
239 p = find_create_pid(pid); 237 p = find_create_pid(pid);
240 c = p->current; 238 c = p->current;
241 if (!c) { 239 if (!c) {
242 c = malloc(sizeof(struct per_pidcomm)); 240 c = zalloc(sizeof(*c));
243 assert(c != NULL); 241 assert(c != NULL);
244 memset(c, 0, sizeof(struct per_pidcomm));
245 p->current = c; 242 p->current = c;
246 c->next = p->all; 243 c->next = p->all;
247 p->all = c; 244 p->all = c;
248 } 245 }
249 246
250 sample = malloc(sizeof(struct cpu_sample)); 247 sample = zalloc(sizeof(*sample));
251 assert(sample != NULL); 248 assert(sample != NULL);
252 memset(sample, 0, sizeof(struct cpu_sample));
253 sample->start_time = start; 249 sample->start_time = start;
254 sample->end_time = end; 250 sample->end_time = end;
255 sample->type = type; 251 sample->type = type;
@@ -373,11 +369,10 @@ static void c_state_start(int cpu, u64 timestamp, int state)
373 369
374static void c_state_end(int cpu, u64 timestamp) 370static void c_state_end(int cpu, u64 timestamp)
375{ 371{
376 struct power_event *pwr; 372 struct power_event *pwr = zalloc(sizeof(*pwr));
377 pwr = malloc(sizeof(struct power_event)); 373
378 if (!pwr) 374 if (!pwr)
379 return; 375 return;
380 memset(pwr, 0, sizeof(struct power_event));
381 376
382 pwr->state = cpus_cstate_state[cpu]; 377 pwr->state = cpus_cstate_state[cpu];
383 pwr->start_time = cpus_cstate_start_times[cpu]; 378 pwr->start_time = cpus_cstate_start_times[cpu];
@@ -392,14 +387,13 @@ static void c_state_end(int cpu, u64 timestamp)
392static void p_state_change(int cpu, u64 timestamp, u64 new_freq) 387static void p_state_change(int cpu, u64 timestamp, u64 new_freq)
393{ 388{
394 struct power_event *pwr; 389 struct power_event *pwr;
395 pwr = malloc(sizeof(struct power_event));
396 390
397 if (new_freq > 8000000) /* detect invalid data */ 391 if (new_freq > 8000000) /* detect invalid data */
398 return; 392 return;
399 393
394 pwr = zalloc(sizeof(*pwr));
400 if (!pwr) 395 if (!pwr)
401 return; 396 return;
402 memset(pwr, 0, sizeof(struct power_event));
403 397
404 pwr->state = cpus_pstate_state[cpu]; 398 pwr->state = cpus_pstate_state[cpu];
405 pwr->start_time = cpus_pstate_start_times[cpu]; 399 pwr->start_time = cpus_pstate_start_times[cpu];
@@ -429,15 +423,13 @@ static void p_state_change(int cpu, u64 timestamp, u64 new_freq)
429static void 423static void
430sched_wakeup(int cpu, u64 timestamp, int pid, struct trace_entry *te) 424sched_wakeup(int cpu, u64 timestamp, int pid, struct trace_entry *te)
431{ 425{
432 struct wake_event *we;
433 struct per_pid *p; 426 struct per_pid *p;
434 struct wakeup_entry *wake = (void *)te; 427 struct wakeup_entry *wake = (void *)te;
428 struct wake_event *we = zalloc(sizeof(*we));
435 429
436 we = malloc(sizeof(struct wake_event));
437 if (!we) 430 if (!we)
438 return; 431 return;
439 432
440 memset(we, 0, sizeof(struct wake_event));
441 we->time = timestamp; 433 we->time = timestamp;
442 we->waker = pid; 434 we->waker = pid;
443 435
@@ -579,13 +571,12 @@ static void end_sample_processing(void)
579 struct power_event *pwr; 571 struct power_event *pwr;
580 572
581 for (cpu = 0; cpu <= numcpus; cpu++) { 573 for (cpu = 0; cpu <= numcpus; cpu++) {
582 pwr = malloc(sizeof(struct power_event)); 574 /* C state */
575#if 0
576 pwr = zalloc(sizeof(*pwr));
583 if (!pwr) 577 if (!pwr)
584 return; 578 return;
585 memset(pwr, 0, sizeof(struct power_event));
586 579
587 /* C state */
588#if 0
589 pwr->state = cpus_cstate_state[cpu]; 580 pwr->state = cpus_cstate_state[cpu];
590 pwr->start_time = cpus_cstate_start_times[cpu]; 581 pwr->start_time = cpus_cstate_start_times[cpu];
591 pwr->end_time = last_time; 582 pwr->end_time = last_time;
@@ -597,10 +588,9 @@ static void end_sample_processing(void)
597#endif 588#endif
598 /* P state */ 589 /* P state */
599 590
600 pwr = malloc(sizeof(struct power_event)); 591 pwr = zalloc(sizeof(*pwr));
601 if (!pwr) 592 if (!pwr)
602 return; 593 return;
603 memset(pwr, 0, sizeof(struct power_event));
604 594
605 pwr->state = cpus_pstate_state[cpu]; 595 pwr->state = cpus_pstate_state[cpu];
606 pwr->start_time = cpus_pstate_start_times[cpu]; 596 pwr->start_time = cpus_pstate_start_times[cpu];
@@ -830,11 +820,9 @@ static void draw_process_bars(void)
830 820
831static void add_process_filter(const char *string) 821static void add_process_filter(const char *string)
832{ 822{
833 struct process_filter *filt; 823 int pid = strtoull(string, NULL, 10);
834 int pid; 824 struct process_filter *filt = malloc(sizeof(*filt));
835 825
836 pid = strtoull(string, NULL, 10);
837 filt = malloc(sizeof(struct process_filter));
838 if (!filt) 826 if (!filt)
839 return; 827 return;
840 828
diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c
index 1506ba0453f1..00936ad29ff2 100644
--- a/tools/perf/util/evsel.c
+++ b/tools/perf/util/evsel.c
@@ -10,6 +10,7 @@
10#include <byteswap.h> 10#include <byteswap.h>
11#include <linux/bitops.h> 11#include <linux/bitops.h>
12#include "asm/bug.h" 12#include "asm/bug.h"
13#include "debugfs.h"
13#include "event-parse.h" 14#include "event-parse.h"
14#include "evsel.h" 15#include "evsel.h"
15#include "evlist.h" 16#include "evlist.h"
@@ -69,6 +70,72 @@ struct perf_evsel *perf_evsel__new(struct perf_event_attr *attr, int idx)
69 return evsel; 70 return evsel;
70} 71}
71 72
73static struct event_format *event_format__new(const char *sys, const char *name)
74{
75 int fd, n;
76 char *filename;
77 void *bf = NULL, *nbf;
78 size_t size = 0, alloc_size = 0;
79 struct event_format *format = NULL;
80
81 if (asprintf(&filename, "%s/%s/%s/format", tracing_events_path, sys, name) < 0)
82 goto out;
83
84 fd = open(filename, O_RDONLY);
85 if (fd < 0)
86 goto out_free_filename;
87
88 do {
89 if (size == alloc_size) {
90 alloc_size += BUFSIZ;
91 nbf = realloc(bf, alloc_size);
92 if (nbf == NULL)
93 goto out_free_bf;
94 bf = nbf;
95 }
96
97 n = read(fd, bf + size, BUFSIZ);
98 if (n < 0)
99 goto out_free_bf;
100 size += n;
101 } while (n > 0);
102
103 pevent_parse_format(&format, bf, size, sys);
104
105out_free_bf:
106 free(bf);
107 close(fd);
108out_free_filename:
109 free(filename);
110out:
111 return format;
112}
113
114struct perf_evsel *perf_evsel__newtp(const char *sys, const char *name, int idx)
115{
116 struct perf_evsel *evsel = zalloc(sizeof(*evsel));
117
118 if (evsel != NULL) {
119 struct perf_event_attr attr = {
120 .type = PERF_TYPE_TRACEPOINT,
121 };
122
123 evsel->tp_format = event_format__new(sys, name);
124 if (evsel->tp_format == NULL)
125 goto out_free;
126
127 attr.config = evsel->tp_format->id;
128 perf_evsel__init(evsel, &attr, idx);
129 evsel->name = evsel->tp_format->name;
130 }
131
132 return evsel;
133
134out_free:
135 free(evsel);
136 return NULL;
137}
138
72const char *perf_evsel__hw_names[PERF_COUNT_HW_MAX] = { 139const char *perf_evsel__hw_names[PERF_COUNT_HW_MAX] = {
73 "cycles", 140 "cycles",
74 "instructions", 141 "instructions",
@@ -495,6 +562,10 @@ void perf_evsel__delete(struct perf_evsel *evsel)
495 perf_evsel__exit(evsel); 562 perf_evsel__exit(evsel);
496 close_cgroup(evsel->cgrp); 563 close_cgroup(evsel->cgrp);
497 free(evsel->group_name); 564 free(evsel->group_name);
565 if (evsel->tp_format && evsel->name == evsel->tp_format->name) {
566 evsel->name = NULL;
567 pevent_free_format(evsel->tp_format);
568 }
498 free(evsel->name); 569 free(evsel->name);
499 free(evsel); 570 free(evsel);
500} 571}
@@ -1002,14 +1073,19 @@ int perf_event__synthesize_sample(union perf_event *event, u64 type,
1002 return 0; 1073 return 0;
1003} 1074}
1004 1075
1076struct format_field *perf_evsel__field(struct perf_evsel *evsel, const char *name)
1077{
1078 return pevent_find_field(evsel->tp_format, name);
1079}
1080
1005char *perf_evsel__strval(struct perf_evsel *evsel, struct perf_sample *sample, 1081char *perf_evsel__strval(struct perf_evsel *evsel, struct perf_sample *sample,
1006 const char *name) 1082 const char *name)
1007{ 1083{
1008 struct format_field *field = pevent_find_field(evsel->tp_format, name); 1084 struct format_field *field = perf_evsel__field(evsel, name);
1009 int offset; 1085 int offset;
1010 1086
1011 if (!field) 1087 if (!field)
1012 return NULL; 1088 return NULL;
1013 1089
1014 offset = field->offset; 1090 offset = field->offset;
1015 1091
@@ -1024,11 +1100,11 @@ char *perf_evsel__strval(struct perf_evsel *evsel, struct perf_sample *sample,
1024u64 perf_evsel__intval(struct perf_evsel *evsel, struct perf_sample *sample, 1100u64 perf_evsel__intval(struct perf_evsel *evsel, struct perf_sample *sample,
1025 const char *name) 1101 const char *name)
1026{ 1102{
1027 struct format_field *field = pevent_find_field(evsel->tp_format, name); 1103 struct format_field *field = perf_evsel__field(evsel, name);
1028 u64 val; 1104 u64 val;
1029 1105
1030 if (!field) 1106 if (!field)
1031 return 0; 1107 return 0;
1032 1108
1033 val = pevent_read_number(evsel->tp_format->pevent, 1109 val = pevent_read_number(evsel->tp_format->pevent,
1034 sample->raw_data + field->offset, field->size); 1110 sample->raw_data + field->offset, field->size);
diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h
index 93876bad2e52..bb445d1cbc7b 100644
--- a/tools/perf/util/evsel.h
+++ b/tools/perf/util/evsel.h
@@ -81,6 +81,7 @@ struct perf_evlist;
81struct perf_record_opts; 81struct perf_record_opts;
82 82
83struct perf_evsel *perf_evsel__new(struct perf_event_attr *attr, int idx); 83struct perf_evsel *perf_evsel__new(struct perf_event_attr *attr, int idx);
84struct perf_evsel *perf_evsel__newtp(const char *sys, const char *name, int idx);
84void perf_evsel__init(struct perf_evsel *evsel, 85void perf_evsel__init(struct perf_evsel *evsel,
85 struct perf_event_attr *attr, int idx); 86 struct perf_event_attr *attr, int idx);
86void perf_evsel__exit(struct perf_evsel *evsel); 87void perf_evsel__exit(struct perf_evsel *evsel);
@@ -128,6 +129,10 @@ char *perf_evsel__strval(struct perf_evsel *evsel, struct perf_sample *sample,
128u64 perf_evsel__intval(struct perf_evsel *evsel, struct perf_sample *sample, 129u64 perf_evsel__intval(struct perf_evsel *evsel, struct perf_sample *sample,
129 const char *name); 130 const char *name);
130 131
132struct format_field;
133
134struct format_field *perf_evsel__field(struct perf_evsel *evsel, const char *name);
135
131#define perf_evsel__match(evsel, t, c) \ 136#define perf_evsel__match(evsel, t, c) \
132 (evsel->attr.type == PERF_TYPE_##t && \ 137 (evsel->attr.type == PERF_TYPE_##t && \
133 evsel->attr.config == PERF_COUNT_##c) 138 evsel->attr.config == PERF_COUNT_##c)
diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c
index acbf6336199e..6aae3290358e 100644
--- a/tools/perf/util/header.c
+++ b/tools/perf/util/header.c
@@ -22,6 +22,7 @@
22#include "cpumap.h" 22#include "cpumap.h"
23#include "pmu.h" 23#include "pmu.h"
24#include "vdso.h" 24#include "vdso.h"
25#include "strbuf.h"
25 26
26static bool no_buildid_cache = false; 27static bool no_buildid_cache = false;
27 28
@@ -1102,118 +1103,80 @@ static int write_branch_stack(int fd __maybe_unused,
1102 return 0; 1103 return 0;
1103} 1104}
1104 1105
1105static void print_hostname(struct perf_header *ph, int fd, FILE *fp) 1106static void print_hostname(struct perf_header *ph, int fd __maybe_unused,
1107 FILE *fp)
1106{ 1108{
1107 char *str = do_read_string(fd, ph); 1109 fprintf(fp, "# hostname : %s\n", ph->env.hostname);
1108 fprintf(fp, "# hostname : %s\n", str);
1109 free(str);
1110} 1110}
1111 1111
1112static void print_osrelease(struct perf_header *ph, int fd, FILE *fp) 1112static void print_osrelease(struct perf_header *ph, int fd __maybe_unused,
1113 FILE *fp)
1113{ 1114{
1114 char *str = do_read_string(fd, ph); 1115 fprintf(fp, "# os release : %s\n", ph->env.os_release);
1115 fprintf(fp, "# os release : %s\n", str);
1116 free(str);
1117} 1116}
1118 1117
1119static void print_arch(struct perf_header *ph, int fd, FILE *fp) 1118static void print_arch(struct perf_header *ph, int fd __maybe_unused, FILE *fp)
1120{ 1119{
1121 char *str = do_read_string(fd, ph); 1120 fprintf(fp, "# arch : %s\n", ph->env.arch);
1122 fprintf(fp, "# arch : %s\n", str);
1123 free(str);
1124} 1121}
1125 1122
1126static void print_cpudesc(struct perf_header *ph, int fd, FILE *fp) 1123static void print_cpudesc(struct perf_header *ph, int fd __maybe_unused,
1124 FILE *fp)
1127{ 1125{
1128 char *str = do_read_string(fd, ph); 1126 fprintf(fp, "# cpudesc : %s\n", ph->env.cpu_desc);
1129 fprintf(fp, "# cpudesc : %s\n", str);
1130 free(str);
1131} 1127}
1132 1128
1133static void print_nrcpus(struct perf_header *ph, int fd, FILE *fp) 1129static void print_nrcpus(struct perf_header *ph, int fd __maybe_unused,
1130 FILE *fp)
1134{ 1131{
1135 ssize_t ret; 1132 fprintf(fp, "# nrcpus online : %u\n", ph->env.nr_cpus_online);
1136 u32 nr; 1133 fprintf(fp, "# nrcpus avail : %u\n", ph->env.nr_cpus_avail);
1137
1138 ret = read(fd, &nr, sizeof(nr));
1139 if (ret != (ssize_t)sizeof(nr))
1140 nr = -1; /* interpreted as error */
1141
1142 if (ph->needs_swap)
1143 nr = bswap_32(nr);
1144
1145 fprintf(fp, "# nrcpus online : %u\n", nr);
1146
1147 ret = read(fd, &nr, sizeof(nr));
1148 if (ret != (ssize_t)sizeof(nr))
1149 nr = -1; /* interpreted as error */
1150
1151 if (ph->needs_swap)
1152 nr = bswap_32(nr);
1153
1154 fprintf(fp, "# nrcpus avail : %u\n", nr);
1155} 1134}
1156 1135
1157static void print_version(struct perf_header *ph, int fd, FILE *fp) 1136static void print_version(struct perf_header *ph, int fd __maybe_unused,
1137 FILE *fp)
1158{ 1138{
1159 char *str = do_read_string(fd, ph); 1139 fprintf(fp, "# perf version : %s\n", ph->env.version);
1160 fprintf(fp, "# perf version : %s\n", str);
1161 free(str);
1162} 1140}
1163 1141
1164static void print_cmdline(struct perf_header *ph, int fd, FILE *fp) 1142static void print_cmdline(struct perf_header *ph, int fd __maybe_unused,
1143 FILE *fp)
1165{ 1144{
1166 ssize_t ret; 1145 int nr, i;
1167 char *str; 1146 char *str;
1168 u32 nr, i;
1169
1170 ret = read(fd, &nr, sizeof(nr));
1171 if (ret != (ssize_t)sizeof(nr))
1172 return;
1173 1147
1174 if (ph->needs_swap) 1148 nr = ph->env.nr_cmdline;
1175 nr = bswap_32(nr); 1149 str = ph->env.cmdline;
1176 1150
1177 fprintf(fp, "# cmdline : "); 1151 fprintf(fp, "# cmdline : ");
1178 1152
1179 for (i = 0; i < nr; i++) { 1153 for (i = 0; i < nr; i++) {
1180 str = do_read_string(fd, ph);
1181 fprintf(fp, "%s ", str); 1154 fprintf(fp, "%s ", str);
1182 free(str); 1155 str += strlen(str) + 1;
1183 } 1156 }
1184 fputc('\n', fp); 1157 fputc('\n', fp);
1185} 1158}
1186 1159
1187static void print_cpu_topology(struct perf_header *ph, int fd, FILE *fp) 1160static void print_cpu_topology(struct perf_header *ph, int fd __maybe_unused,
1161 FILE *fp)
1188{ 1162{
1189 ssize_t ret; 1163 int nr, i;
1190 u32 nr, i;
1191 char *str; 1164 char *str;
1192 1165
1193 ret = read(fd, &nr, sizeof(nr)); 1166 nr = ph->env.nr_sibling_cores;
1194 if (ret != (ssize_t)sizeof(nr)) 1167 str = ph->env.sibling_cores;
1195 return;
1196
1197 if (ph->needs_swap)
1198 nr = bswap_32(nr);
1199 1168
1200 for (i = 0; i < nr; i++) { 1169 for (i = 0; i < nr; i++) {
1201 str = do_read_string(fd, ph);
1202 fprintf(fp, "# sibling cores : %s\n", str); 1170 fprintf(fp, "# sibling cores : %s\n", str);
1203 free(str); 1171 str += strlen(str) + 1;
1204 } 1172 }
1205 1173
1206 ret = read(fd, &nr, sizeof(nr)); 1174 nr = ph->env.nr_sibling_threads;
1207 if (ret != (ssize_t)sizeof(nr)) 1175 str = ph->env.sibling_threads;
1208 return;
1209
1210 if (ph->needs_swap)
1211 nr = bswap_32(nr);
1212 1176
1213 for (i = 0; i < nr; i++) { 1177 for (i = 0; i < nr; i++) {
1214 str = do_read_string(fd, ph);
1215 fprintf(fp, "# sibling threads : %s\n", str); 1178 fprintf(fp, "# sibling threads : %s\n", str);
1216 free(str); 1179 str += strlen(str) + 1;
1217 } 1180 }
1218} 1181}
1219 1182
@@ -1374,126 +1337,89 @@ static void print_event_desc(struct perf_header *ph, int fd, FILE *fp)
1374 free_event_desc(events); 1337 free_event_desc(events);
1375} 1338}
1376 1339
1377static void print_total_mem(struct perf_header *h __maybe_unused, int fd, 1340static void print_total_mem(struct perf_header *ph, int fd __maybe_unused,
1378 FILE *fp) 1341 FILE *fp)
1379{ 1342{
1380 uint64_t mem; 1343 fprintf(fp, "# total memory : %Lu kB\n", ph->env.total_mem);
1381 ssize_t ret;
1382
1383 ret = read(fd, &mem, sizeof(mem));
1384 if (ret != sizeof(mem))
1385 goto error;
1386
1387 if (h->needs_swap)
1388 mem = bswap_64(mem);
1389
1390 fprintf(fp, "# total memory : %"PRIu64" kB\n", mem);
1391 return;
1392error:
1393 fprintf(fp, "# total memory : unknown\n");
1394} 1344}
1395 1345
1396static void print_numa_topology(struct perf_header *h __maybe_unused, int fd, 1346static void print_numa_topology(struct perf_header *ph, int fd __maybe_unused,
1397 FILE *fp) 1347 FILE *fp)
1398{ 1348{
1399 ssize_t ret;
1400 u32 nr, c, i; 1349 u32 nr, c, i;
1401 char *str; 1350 char *str, *tmp;
1402 uint64_t mem_total, mem_free; 1351 uint64_t mem_total, mem_free;
1403 1352
1404 /* nr nodes */ 1353 /* nr nodes */
1405 ret = read(fd, &nr, sizeof(nr)); 1354 nr = ph->env.nr_numa_nodes;
1406 if (ret != (ssize_t)sizeof(nr)) 1355 str = ph->env.numa_nodes;
1407 goto error;
1408
1409 if (h->needs_swap)
1410 nr = bswap_32(nr);
1411 1356
1412 for (i = 0; i < nr; i++) { 1357 for (i = 0; i < nr; i++) {
1413
1414 /* node number */ 1358 /* node number */
1415 ret = read(fd, &c, sizeof(c)); 1359 c = strtoul(str, &tmp, 0);
1416 if (ret != (ssize_t)sizeof(c)) 1360 if (*tmp != ':')
1417 goto error; 1361 goto error;
1418 1362
1419 if (h->needs_swap) 1363 str = tmp + 1;
1420 c = bswap_32(c); 1364 mem_total = strtoull(str, &tmp, 0);
1421 1365 if (*tmp != ':')
1422 ret = read(fd, &mem_total, sizeof(u64));
1423 if (ret != sizeof(u64))
1424 goto error; 1366 goto error;
1425 1367
1426 ret = read(fd, &mem_free, sizeof(u64)); 1368 str = tmp + 1;
1427 if (ret != sizeof(u64)) 1369 mem_free = strtoull(str, &tmp, 0);
1370 if (*tmp != ':')
1428 goto error; 1371 goto error;
1429 1372
1430 if (h->needs_swap) {
1431 mem_total = bswap_64(mem_total);
1432 mem_free = bswap_64(mem_free);
1433 }
1434
1435 fprintf(fp, "# node%u meminfo : total = %"PRIu64" kB," 1373 fprintf(fp, "# node%u meminfo : total = %"PRIu64" kB,"
1436 " free = %"PRIu64" kB\n", 1374 " free = %"PRIu64" kB\n",
1437 c, 1375 c, mem_total, mem_free);
1438 mem_total,
1439 mem_free);
1440 1376
1441 str = do_read_string(fd, h); 1377 str = tmp + 1;
1442 fprintf(fp, "# node%u cpu list : %s\n", c, str); 1378 fprintf(fp, "# node%u cpu list : %s\n", c, str);
1443 free(str);
1444 } 1379 }
1445 return; 1380 return;
1446error: 1381error:
1447 fprintf(fp, "# numa topology : not available\n"); 1382 fprintf(fp, "# numa topology : not available\n");
1448} 1383}
1449 1384
1450static void print_cpuid(struct perf_header *ph, int fd, FILE *fp) 1385static void print_cpuid(struct perf_header *ph, int fd __maybe_unused, FILE *fp)
1451{ 1386{
1452 char *str = do_read_string(fd, ph); 1387 fprintf(fp, "# cpuid : %s\n", ph->env.cpuid);
1453 fprintf(fp, "# cpuid : %s\n", str);
1454 free(str);
1455} 1388}
1456 1389
1457static void print_branch_stack(struct perf_header *ph __maybe_unused, 1390static void print_branch_stack(struct perf_header *ph __maybe_unused,
1458 int fd __maybe_unused, 1391 int fd __maybe_unused, FILE *fp)
1459 FILE *fp)
1460{ 1392{
1461 fprintf(fp, "# contains samples with branch stack\n"); 1393 fprintf(fp, "# contains samples with branch stack\n");
1462} 1394}
1463 1395
1464static void print_pmu_mappings(struct perf_header *ph, int fd, FILE *fp) 1396static void print_pmu_mappings(struct perf_header *ph, int fd __maybe_unused,
1397 FILE *fp)
1465{ 1398{
1466 const char *delimiter = "# pmu mappings: "; 1399 const char *delimiter = "# pmu mappings: ";
1467 char *name; 1400 char *str, *tmp;
1468 int ret;
1469 u32 pmu_num; 1401 u32 pmu_num;
1470 u32 type; 1402 u32 type;
1471 1403
1472 ret = read(fd, &pmu_num, sizeof(pmu_num)); 1404 pmu_num = ph->env.nr_pmu_mappings;
1473 if (ret != sizeof(pmu_num))
1474 goto error;
1475
1476 if (ph->needs_swap)
1477 pmu_num = bswap_32(pmu_num);
1478
1479 if (!pmu_num) { 1405 if (!pmu_num) {
1480 fprintf(fp, "# pmu mappings: not available\n"); 1406 fprintf(fp, "# pmu mappings: not available\n");
1481 return; 1407 return;
1482 } 1408 }
1483 1409
1410 str = ph->env.pmu_mappings;
1411
1484 while (pmu_num) { 1412 while (pmu_num) {
1485 if (read(fd, &type, sizeof(type)) != sizeof(type)) 1413 type = strtoul(str, &tmp, 0);
1486 break; 1414 if (*tmp != ':')
1487 if (ph->needs_swap) 1415 goto error;
1488 type = bswap_32(type); 1416
1417 str = tmp + 1;
1418 fprintf(fp, "%s%s = %" PRIu32, delimiter, str, type);
1489 1419
1490 name = do_read_string(fd, ph);
1491 if (!name)
1492 break;
1493 pmu_num--;
1494 fprintf(fp, "%s%s = %" PRIu32, delimiter, name, type);
1495 free(name);
1496 delimiter = ", "; 1420 delimiter = ", ";
1421 str += strlen(str) + 1;
1422 pmu_num--;
1497 } 1423 }
1498 1424
1499 fprintf(fp, "\n"); 1425 fprintf(fp, "\n");
@@ -1654,18 +1580,16 @@ out:
1654 return err; 1580 return err;
1655} 1581}
1656 1582
1657static int process_tracing_data(struct perf_file_section *section 1583static int process_tracing_data(struct perf_file_section *section __maybe_unused,
1658 __maybe_unused, 1584 struct perf_header *ph __maybe_unused,
1659 struct perf_header *ph __maybe_unused, 1585 int fd, void *data)
1660 int feat __maybe_unused, int fd, void *data)
1661{ 1586{
1662 trace_report(fd, data, false); 1587 trace_report(fd, data, false);
1663 return 0; 1588 return 0;
1664} 1589}
1665 1590
1666static int process_build_id(struct perf_file_section *section, 1591static int process_build_id(struct perf_file_section *section,
1667 struct perf_header *ph, 1592 struct perf_header *ph, int fd,
1668 int feat __maybe_unused, int fd,
1669 void *data __maybe_unused) 1593 void *data __maybe_unused)
1670{ 1594{
1671 if (perf_header__read_build_ids(ph, fd, section->offset, section->size)) 1595 if (perf_header__read_build_ids(ph, fd, section->offset, section->size))
@@ -1673,6 +1597,99 @@ static int process_build_id(struct perf_file_section *section,
1673 return 0; 1597 return 0;
1674} 1598}
1675 1599
1600static int process_hostname(struct perf_file_section *section __maybe_unused,
1601 struct perf_header *ph, int fd,
1602 void *data __maybe_unused)
1603{
1604 ph->env.hostname = do_read_string(fd, ph);
1605 return ph->env.hostname ? 0 : -ENOMEM;
1606}
1607
1608static int process_osrelease(struct perf_file_section *section __maybe_unused,
1609 struct perf_header *ph, int fd,
1610 void *data __maybe_unused)
1611{
1612 ph->env.os_release = do_read_string(fd, ph);
1613 return ph->env.os_release ? 0 : -ENOMEM;
1614}
1615
1616static int process_version(struct perf_file_section *section __maybe_unused,
1617 struct perf_header *ph, int fd,
1618 void *data __maybe_unused)
1619{
1620 ph->env.version = do_read_string(fd, ph);
1621 return ph->env.version ? 0 : -ENOMEM;
1622}
1623
1624static int process_arch(struct perf_file_section *section __maybe_unused,
1625 struct perf_header *ph, int fd,
1626 void *data __maybe_unused)
1627{
1628 ph->env.arch = do_read_string(fd, ph);
1629 return ph->env.arch ? 0 : -ENOMEM;
1630}
1631
1632static int process_nrcpus(struct perf_file_section *section __maybe_unused,
1633 struct perf_header *ph, int fd,
1634 void *data __maybe_unused)
1635{
1636 size_t ret;
1637 u32 nr;
1638
1639 ret = read(fd, &nr, sizeof(nr));
1640 if (ret != sizeof(nr))
1641 return -1;
1642
1643 if (ph->needs_swap)
1644 nr = bswap_32(nr);
1645
1646 ph->env.nr_cpus_online = nr;
1647
1648 ret = read(fd, &nr, sizeof(nr));
1649 if (ret != sizeof(nr))
1650 return -1;
1651
1652 if (ph->needs_swap)
1653 nr = bswap_32(nr);
1654
1655 ph->env.nr_cpus_avail = nr;
1656 return 0;
1657}
1658
1659static int process_cpudesc(struct perf_file_section *section __maybe_unused,
1660 struct perf_header *ph, int fd,
1661 void *data __maybe_unused)
1662{
1663 ph->env.cpu_desc = do_read_string(fd, ph);
1664 return ph->env.cpu_desc ? 0 : -ENOMEM;
1665}
1666
1667static int process_cpuid(struct perf_file_section *section __maybe_unused,
1668 struct perf_header *ph, int fd,
1669 void *data __maybe_unused)
1670{
1671 ph->env.cpuid = do_read_string(fd, ph);
1672 return ph->env.cpuid ? 0 : -ENOMEM;
1673}
1674
1675static int process_total_mem(struct perf_file_section *section __maybe_unused,
1676 struct perf_header *ph, int fd,
1677 void *data __maybe_unused)
1678{
1679 uint64_t mem;
1680 size_t ret;
1681
1682 ret = read(fd, &mem, sizeof(mem));
1683 if (ret != sizeof(mem))
1684 return -1;
1685
1686 if (ph->needs_swap)
1687 mem = bswap_64(mem);
1688
1689 ph->env.total_mem = mem;
1690 return 0;
1691}
1692
1676static struct perf_evsel * 1693static struct perf_evsel *
1677perf_evlist__find_by_index(struct perf_evlist *evlist, int idx) 1694perf_evlist__find_by_index(struct perf_evlist *evlist, int idx)
1678{ 1695{
@@ -1687,7 +1704,8 @@ perf_evlist__find_by_index(struct perf_evlist *evlist, int idx)
1687} 1704}
1688 1705
1689static void 1706static void
1690perf_evlist__set_event_name(struct perf_evlist *evlist, struct perf_evsel *event) 1707perf_evlist__set_event_name(struct perf_evlist *evlist,
1708 struct perf_evsel *event)
1691{ 1709{
1692 struct perf_evsel *evsel; 1710 struct perf_evsel *evsel;
1693 1711
@@ -1706,15 +1724,16 @@ perf_evlist__set_event_name(struct perf_evlist *evlist, struct perf_evsel *event
1706 1724
1707static int 1725static int
1708process_event_desc(struct perf_file_section *section __maybe_unused, 1726process_event_desc(struct perf_file_section *section __maybe_unused,
1709 struct perf_header *header, int feat __maybe_unused, int fd, 1727 struct perf_header *header, int fd,
1710 void *data __maybe_unused) 1728 void *data __maybe_unused)
1711{ 1729{
1712 struct perf_session *session = container_of(header, struct perf_session, header); 1730 struct perf_session *session;
1713 struct perf_evsel *evsel, *events = read_event_desc(header, fd); 1731 struct perf_evsel *evsel, *events = read_event_desc(header, fd);
1714 1732
1715 if (!events) 1733 if (!events)
1716 return 0; 1734 return 0;
1717 1735
1736 session = container_of(header, struct perf_session, header);
1718 for (evsel = events; evsel->attr.size; evsel++) 1737 for (evsel = events; evsel->attr.size; evsel++)
1719 perf_evlist__set_event_name(session->evlist, evsel); 1738 perf_evlist__set_event_name(session->evlist, evsel);
1720 1739
@@ -1723,11 +1742,213 @@ process_event_desc(struct perf_file_section *section __maybe_unused,
1723 return 0; 1742 return 0;
1724} 1743}
1725 1744
1745static int process_cmdline(struct perf_file_section *section __maybe_unused,
1746 struct perf_header *ph, int fd,
1747 void *data __maybe_unused)
1748{
1749 size_t ret;
1750 char *str;
1751 u32 nr, i;
1752 struct strbuf sb;
1753
1754 ret = read(fd, &nr, sizeof(nr));
1755 if (ret != sizeof(nr))
1756 return -1;
1757
1758 if (ph->needs_swap)
1759 nr = bswap_32(nr);
1760
1761 ph->env.nr_cmdline = nr;
1762 strbuf_init(&sb, 128);
1763
1764 for (i = 0; i < nr; i++) {
1765 str = do_read_string(fd, ph);
1766 if (!str)
1767 goto error;
1768
1769 /* include a NULL character at the end */
1770 strbuf_add(&sb, str, strlen(str) + 1);
1771 free(str);
1772 }
1773 ph->env.cmdline = strbuf_detach(&sb, NULL);
1774 return 0;
1775
1776error:
1777 strbuf_release(&sb);
1778 return -1;
1779}
1780
1781static int process_cpu_topology(struct perf_file_section *section __maybe_unused,
1782 struct perf_header *ph, int fd,
1783 void *data __maybe_unused)
1784{
1785 size_t ret;
1786 u32 nr, i;
1787 char *str;
1788 struct strbuf sb;
1789
1790 ret = read(fd, &nr, sizeof(nr));
1791 if (ret != sizeof(nr))
1792 return -1;
1793
1794 if (ph->needs_swap)
1795 nr = bswap_32(nr);
1796
1797 ph->env.nr_sibling_cores = nr;
1798 strbuf_init(&sb, 128);
1799
1800 for (i = 0; i < nr; i++) {
1801 str = do_read_string(fd, ph);
1802 if (!str)
1803 goto error;
1804
1805 /* include a NULL character at the end */
1806 strbuf_add(&sb, str, strlen(str) + 1);
1807 free(str);
1808 }
1809 ph->env.sibling_cores = strbuf_detach(&sb, NULL);
1810
1811 ret = read(fd, &nr, sizeof(nr));
1812 if (ret != sizeof(nr))
1813 return -1;
1814
1815 if (ph->needs_swap)
1816 nr = bswap_32(nr);
1817
1818 ph->env.nr_sibling_threads = nr;
1819
1820 for (i = 0; i < nr; i++) {
1821 str = do_read_string(fd, ph);
1822 if (!str)
1823 goto error;
1824
1825 /* include a NULL character at the end */
1826 strbuf_add(&sb, str, strlen(str) + 1);
1827 free(str);
1828 }
1829 ph->env.sibling_threads = strbuf_detach(&sb, NULL);
1830 return 0;
1831
1832error:
1833 strbuf_release(&sb);
1834 return -1;
1835}
1836
1837static int process_numa_topology(struct perf_file_section *section __maybe_unused,
1838 struct perf_header *ph, int fd,
1839 void *data __maybe_unused)
1840{
1841 size_t ret;
1842 u32 nr, node, i;
1843 char *str;
1844 uint64_t mem_total, mem_free;
1845 struct strbuf sb;
1846
1847 /* nr nodes */
1848 ret = read(fd, &nr, sizeof(nr));
1849 if (ret != sizeof(nr))
1850 goto error;
1851
1852 if (ph->needs_swap)
1853 nr = bswap_32(nr);
1854
1855 ph->env.nr_numa_nodes = nr;
1856 strbuf_init(&sb, 256);
1857
1858 for (i = 0; i < nr; i++) {
1859 /* node number */
1860 ret = read(fd, &node, sizeof(node));
1861 if (ret != sizeof(node))
1862 goto error;
1863
1864 ret = read(fd, &mem_total, sizeof(u64));
1865 if (ret != sizeof(u64))
1866 goto error;
1867
1868 ret = read(fd, &mem_free, sizeof(u64));
1869 if (ret != sizeof(u64))
1870 goto error;
1871
1872 if (ph->needs_swap) {
1873 node = bswap_32(node);
1874 mem_total = bswap_64(mem_total);
1875 mem_free = bswap_64(mem_free);
1876 }
1877
1878 strbuf_addf(&sb, "%u:%"PRIu64":%"PRIu64":",
1879 node, mem_total, mem_free);
1880
1881 str = do_read_string(fd, ph);
1882 if (!str)
1883 goto error;
1884
1885 /* include a NULL character at the end */
1886 strbuf_add(&sb, str, strlen(str) + 1);
1887 free(str);
1888 }
1889 ph->env.numa_nodes = strbuf_detach(&sb, NULL);
1890 return 0;
1891
1892error:
1893 strbuf_release(&sb);
1894 return -1;
1895}
1896
1897static int process_pmu_mappings(struct perf_file_section *section __maybe_unused,
1898 struct perf_header *ph, int fd,
1899 void *data __maybe_unused)
1900{
1901 size_t ret;
1902 char *name;
1903 u32 pmu_num;
1904 u32 type;
1905 struct strbuf sb;
1906
1907 ret = read(fd, &pmu_num, sizeof(pmu_num));
1908 if (ret != sizeof(pmu_num))
1909 return -1;
1910
1911 if (ph->needs_swap)
1912 pmu_num = bswap_32(pmu_num);
1913
1914 if (!pmu_num) {
1915 pr_debug("pmu mappings not available\n");
1916 return 0;
1917 }
1918
1919 ph->env.nr_pmu_mappings = pmu_num;
1920 strbuf_init(&sb, 128);
1921
1922 while (pmu_num) {
1923 if (read(fd, &type, sizeof(type)) != sizeof(type))
1924 goto error;
1925 if (ph->needs_swap)
1926 type = bswap_32(type);
1927
1928 name = do_read_string(fd, ph);
1929 if (!name)
1930 goto error;
1931
1932 strbuf_addf(&sb, "%u:%s", type, name);
1933 /* include a NULL character at the end */
1934 strbuf_add(&sb, "", 1);
1935
1936 free(name);
1937 pmu_num--;
1938 }
1939 ph->env.pmu_mappings = strbuf_detach(&sb, NULL);
1940 return 0;
1941
1942error:
1943 strbuf_release(&sb);
1944 return -1;
1945}
1946
1726struct feature_ops { 1947struct feature_ops {
1727 int (*write)(int fd, struct perf_header *h, struct perf_evlist *evlist); 1948 int (*write)(int fd, struct perf_header *h, struct perf_evlist *evlist);
1728 void (*print)(struct perf_header *h, int fd, FILE *fp); 1949 void (*print)(struct perf_header *h, int fd, FILE *fp);
1729 int (*process)(struct perf_file_section *section, 1950 int (*process)(struct perf_file_section *section,
1730 struct perf_header *h, int feat, int fd, void *data); 1951 struct perf_header *h, int fd, void *data);
1731 const char *name; 1952 const char *name;
1732 bool full_only; 1953 bool full_only;
1733}; 1954};
@@ -1739,7 +1960,7 @@ struct feature_ops {
1739 .process = process_##func } 1960 .process = process_##func }
1740#define FEAT_OPF(n, func) \ 1961#define FEAT_OPF(n, func) \
1741 [n] = { .name = #n, .write = write_##func, .print = print_##func, \ 1962 [n] = { .name = #n, .write = write_##func, .print = print_##func, \
1742 .full_only = true } 1963 .process = process_##func, .full_only = true }
1743 1964
1744/* feature_ops not implemented: */ 1965/* feature_ops not implemented: */
1745#define print_tracing_data NULL 1966#define print_tracing_data NULL
@@ -1748,20 +1969,20 @@ struct feature_ops {
1748static const struct feature_ops feat_ops[HEADER_LAST_FEATURE] = { 1969static const struct feature_ops feat_ops[HEADER_LAST_FEATURE] = {
1749 FEAT_OPP(HEADER_TRACING_DATA, tracing_data), 1970 FEAT_OPP(HEADER_TRACING_DATA, tracing_data),
1750 FEAT_OPP(HEADER_BUILD_ID, build_id), 1971 FEAT_OPP(HEADER_BUILD_ID, build_id),
1751 FEAT_OPA(HEADER_HOSTNAME, hostname), 1972 FEAT_OPP(HEADER_HOSTNAME, hostname),
1752 FEAT_OPA(HEADER_OSRELEASE, osrelease), 1973 FEAT_OPP(HEADER_OSRELEASE, osrelease),
1753 FEAT_OPA(HEADER_VERSION, version), 1974 FEAT_OPP(HEADER_VERSION, version),
1754 FEAT_OPA(HEADER_ARCH, arch), 1975 FEAT_OPP(HEADER_ARCH, arch),
1755 FEAT_OPA(HEADER_NRCPUS, nrcpus), 1976 FEAT_OPP(HEADER_NRCPUS, nrcpus),
1756 FEAT_OPA(HEADER_CPUDESC, cpudesc), 1977 FEAT_OPP(HEADER_CPUDESC, cpudesc),
1757 FEAT_OPA(HEADER_CPUID, cpuid), 1978 FEAT_OPP(HEADER_CPUID, cpuid),
1758 FEAT_OPA(HEADER_TOTAL_MEM, total_mem), 1979 FEAT_OPP(HEADER_TOTAL_MEM, total_mem),
1759 FEAT_OPP(HEADER_EVENT_DESC, event_desc), 1980 FEAT_OPP(HEADER_EVENT_DESC, event_desc),
1760 FEAT_OPA(HEADER_CMDLINE, cmdline), 1981 FEAT_OPP(HEADER_CMDLINE, cmdline),
1761 FEAT_OPF(HEADER_CPU_TOPOLOGY, cpu_topology), 1982 FEAT_OPF(HEADER_CPU_TOPOLOGY, cpu_topology),
1762 FEAT_OPF(HEADER_NUMA_TOPOLOGY, numa_topology), 1983 FEAT_OPF(HEADER_NUMA_TOPOLOGY, numa_topology),
1763 FEAT_OPA(HEADER_BRANCH_STACK, branch_stack), 1984 FEAT_OPA(HEADER_BRANCH_STACK, branch_stack),
1764 FEAT_OPA(HEADER_PMU_MAPPINGS, pmu_mappings), 1985 FEAT_OPP(HEADER_PMU_MAPPINGS, pmu_mappings),
1765}; 1986};
1766 1987
1767struct header_print_data { 1988struct header_print_data {
@@ -2241,7 +2462,7 @@ static int perf_file_section__process(struct perf_file_section *section,
2241 if (!feat_ops[feat].process) 2462 if (!feat_ops[feat].process)
2242 return 0; 2463 return 0;
2243 2464
2244 return feat_ops[feat].process(section, ph, feat, fd, data); 2465 return feat_ops[feat].process(section, ph, fd, data);
2245} 2466}
2246 2467
2247static int perf_file_header__read_pipe(struct perf_pipe_file_header *header, 2468static int perf_file_header__read_pipe(struct perf_pipe_file_header *header,
diff --git a/tools/perf/util/header.h b/tools/perf/util/header.h
index 209dad4fee2b..99bdd3abce59 100644
--- a/tools/perf/util/header.h
+++ b/tools/perf/util/header.h
@@ -58,6 +58,29 @@ struct perf_header;
58int perf_file_header__read(struct perf_file_header *header, 58int perf_file_header__read(struct perf_file_header *header,
59 struct perf_header *ph, int fd); 59 struct perf_header *ph, int fd);
60 60
61struct perf_session_env {
62 char *hostname;
63 char *os_release;
64 char *version;
65 char *arch;
66 int nr_cpus_online;
67 int nr_cpus_avail;
68 char *cpu_desc;
69 char *cpuid;
70 unsigned long long total_mem;
71
72 int nr_cmdline;
73 char *cmdline;
74 int nr_sibling_cores;
75 char *sibling_cores;
76 int nr_sibling_threads;
77 char *sibling_threads;
78 int nr_numa_nodes;
79 char *numa_nodes;
80 int nr_pmu_mappings;
81 char *pmu_mappings;
82};
83
61struct perf_header { 84struct perf_header {
62 int frozen; 85 int frozen;
63 bool needs_swap; 86 bool needs_swap;
@@ -67,6 +90,7 @@ struct perf_header {
67 u64 event_offset; 90 u64 event_offset;
68 u64 event_size; 91 u64 event_size;
69 DECLARE_BITMAP(adds_features, HEADER_FEAT_BITS); 92 DECLARE_BITMAP(adds_features, HEADER_FEAT_BITS);
93 struct perf_session_env env;
70}; 94};
71 95
72struct perf_evlist; 96struct perf_evlist;
diff --git a/tools/perf/util/map.c b/tools/perf/util/map.c
index b442ee49452b..ead5316b3f89 100644
--- a/tools/perf/util/map.c
+++ b/tools/perf/util/map.c
@@ -243,15 +243,14 @@ size_t map__fprintf(struct map *self, FILE *fp)
243 243
244size_t map__fprintf_dsoname(struct map *map, FILE *fp) 244size_t map__fprintf_dsoname(struct map *map, FILE *fp)
245{ 245{
246 const char *dsoname; 246 const char *dsoname = "[unknown]";
247 247
248 if (map && map->dso && (map->dso->name || map->dso->long_name)) { 248 if (map && map->dso && (map->dso->name || map->dso->long_name)) {
249 if (symbol_conf.show_kernel_path && map->dso->long_name) 249 if (symbol_conf.show_kernel_path && map->dso->long_name)
250 dsoname = map->dso->long_name; 250 dsoname = map->dso->long_name;
251 else if (map->dso->name) 251 else if (map->dso->name)
252 dsoname = map->dso->name; 252 dsoname = map->dso->name;
253 } else 253 }
254 dsoname = "[unknown]";
255 254
256 return fprintf(fp, "%s", dsoname); 255 return fprintf(fp, "%s", dsoname);
257} 256}
diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c
index 4ce04c2281d3..49a256e6e0a2 100644
--- a/tools/perf/util/probe-event.c
+++ b/tools/perf/util/probe-event.c
@@ -1100,6 +1100,7 @@ static int parse_probe_trace_command(const char *cmd,
1100 struct probe_trace_point *tp = &tev->point; 1100 struct probe_trace_point *tp = &tev->point;
1101 char pr; 1101 char pr;
1102 char *p; 1102 char *p;
1103 char *argv0_str = NULL, *fmt, *fmt1_str, *fmt2_str, *fmt3_str;
1103 int ret, i, argc; 1104 int ret, i, argc;
1104 char **argv; 1105 char **argv;
1105 1106
@@ -1116,14 +1117,27 @@ static int parse_probe_trace_command(const char *cmd,
1116 } 1117 }
1117 1118
1118 /* Scan event and group name. */ 1119 /* Scan event and group name. */
1119 ret = sscanf(argv[0], "%c:%a[^/ \t]/%a[^ \t]", 1120 argv0_str = strdup(argv[0]);
1120 &pr, (float *)(void *)&tev->group, 1121 if (argv0_str == NULL) {
1121 (float *)(void *)&tev->event); 1122 ret = -ENOMEM;
1122 if (ret != 3) { 1123 goto out;
1124 }
1125 fmt1_str = strtok_r(argv0_str, ":", &fmt);
1126 fmt2_str = strtok_r(NULL, "/", &fmt);
1127 fmt3_str = strtok_r(NULL, " \t", &fmt);
1128 if (fmt1_str == NULL || strlen(fmt1_str) != 1 || fmt2_str == NULL
1129 || fmt3_str == NULL) {
1123 semantic_error("Failed to parse event name: %s\n", argv[0]); 1130 semantic_error("Failed to parse event name: %s\n", argv[0]);
1124 ret = -EINVAL; 1131 ret = -EINVAL;
1125 goto out; 1132 goto out;
1126 } 1133 }
1134 pr = fmt1_str[0];
1135 tev->group = strdup(fmt2_str);
1136 tev->event = strdup(fmt3_str);
1137 if (tev->group == NULL || tev->event == NULL) {
1138 ret = -ENOMEM;
1139 goto out;
1140 }
1127 pr_debug("Group:%s Event:%s probe:%c\n", tev->group, tev->event, pr); 1141 pr_debug("Group:%s Event:%s probe:%c\n", tev->group, tev->event, pr);
1128 1142
1129 tp->retprobe = (pr == 'r'); 1143 tp->retprobe = (pr == 'r');
@@ -1135,10 +1149,17 @@ static int parse_probe_trace_command(const char *cmd,
1135 p++; 1149 p++;
1136 } else 1150 } else
1137 p = argv[1]; 1151 p = argv[1];
1138 ret = sscanf(p, "%a[^+]+%lu", (float *)(void *)&tp->symbol, 1152 fmt1_str = strtok_r(p, "+", &fmt);
1139 &tp->offset); 1153 tp->symbol = strdup(fmt1_str);
1140 if (ret == 1) 1154 if (tp->symbol == NULL) {
1155 ret = -ENOMEM;
1156 goto out;
1157 }
1158 fmt2_str = strtok_r(NULL, "", &fmt);
1159 if (fmt2_str == NULL)
1141 tp->offset = 0; 1160 tp->offset = 0;
1161 else
1162 tp->offset = strtoul(fmt2_str, NULL, 10);
1142 1163
1143 tev->nargs = argc - 2; 1164 tev->nargs = argc - 2;
1144 tev->args = zalloc(sizeof(struct probe_trace_arg) * tev->nargs); 1165 tev->args = zalloc(sizeof(struct probe_trace_arg) * tev->nargs);
@@ -1162,6 +1183,7 @@ static int parse_probe_trace_command(const char *cmd,
1162 } 1183 }
1163 ret = 0; 1184 ret = 0;
1164out: 1185out:
1186 free(argv0_str);
1165 argv_free(argv); 1187 argv_free(argv);
1166 return ret; 1188 return ret;
1167} 1189}
diff --git a/tools/perf/util/scripting-engines/trace-event-perl.c b/tools/perf/util/scripting-engines/trace-event-perl.c
index ffde3e4e34aa..f80605eb1855 100644
--- a/tools/perf/util/scripting-engines/trace-event-perl.c
+++ b/tools/perf/util/scripting-engines/trace-event-perl.c
@@ -282,7 +282,7 @@ static void perl_process_tracepoint(union perf_event *perf_event __maybe_unused,
282 282
283 event = find_cache_event(evsel); 283 event = find_cache_event(evsel);
284 if (!event) 284 if (!event)
285 die("ug! no event found for type %d", evsel->attr.config); 285 die("ug! no event found for type %" PRIu64, evsel->attr.config);
286 286
287 pid = raw_field_value(event, "common_pid", data); 287 pid = raw_field_value(event, "common_pid", data);
288 288
diff --git a/tools/perf/util/symbol.h b/tools/perf/util/symbol.h
index 4ff45e30c726..b441b07172b7 100644
--- a/tools/perf/util/symbol.h
+++ b/tools/perf/util/symbol.h
@@ -34,6 +34,7 @@ static inline char *bfd_demangle(void __maybe_unused *v,
34 return NULL; 34 return NULL;
35} 35}
36#else 36#else
37#define PACKAGE 'perf'
37#include <bfd.h> 38#include <bfd.h>
38#endif 39#endif
39#endif 40#endif
diff --git a/tools/perf/util/thread.h b/tools/perf/util/thread.h
index 70c2c13ff679..f66610b7bacf 100644
--- a/tools/perf/util/thread.h
+++ b/tools/perf/util/thread.h
@@ -16,6 +16,8 @@ struct thread {
16 bool comm_set; 16 bool comm_set;
17 char *comm; 17 char *comm;
18 int comm_len; 18 int comm_len;
19
20 void *priv;
19}; 21};
20 22
21struct machine; 23struct machine;
diff --git a/tools/perf/util/trace-event-parse.c b/tools/perf/util/trace-event-parse.c
index aa4c860a21d1..3aabcd687cd5 100644
--- a/tools/perf/util/trace-event-parse.c
+++ b/tools/perf/util/trace-event-parse.c
@@ -229,24 +229,22 @@ void parse_proc_kallsyms(struct pevent *pevent,
229 char *next = NULL; 229 char *next = NULL;
230 char *addr_str; 230 char *addr_str;
231 char *mod; 231 char *mod;
232 char ch; 232 char *fmt;
233 233
234 line = strtok_r(file, "\n", &next); 234 line = strtok_r(file, "\n", &next);
235 while (line) { 235 while (line) {
236 mod = NULL; 236 mod = NULL;
237 sscanf(line, "%as %c %as\t[%as", 237 addr_str = strtok_r(line, " ", &fmt);
238 (float *)(void *)&addr_str, /* workaround gcc warning */
239 &ch, (float *)(void *)&func, (float *)(void *)&mod);
240 addr = strtoull(addr_str, NULL, 16); 238 addr = strtoull(addr_str, NULL, 16);
241 free(addr_str); 239 /* skip character */
242 240 strtok_r(NULL, " ", &fmt);
243 /* truncate the extra ']' */ 241 func = strtok_r(NULL, "\t", &fmt);
242 mod = strtok_r(NULL, "]", &fmt);
243 /* truncate the extra '[' */
244 if (mod) 244 if (mod)
245 mod[strlen(mod) - 1] = 0; 245 mod = mod + 1;
246 246
247 pevent_register_function(pevent, func, addr, mod); 247 pevent_register_function(pevent, func, addr, mod);
248 free(func);
249 free(mod);
250 248
251 line = strtok_r(NULL, "\n", &next); 249 line = strtok_r(NULL, "\n", &next);
252 } 250 }