aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2014-10-19 14:55:41 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2014-10-19 14:55:41 -0400
commit1f6075f99073a8b5ec9649ae8c0bf2e06fdd42f1 (patch)
tree99d418273091b7f6779e779dfc6aa4e63c656d96
parent5e2ee7cd58fcee6c6cc954642faa584f54c8391e (diff)
parent3b10ea7f922b538ba5dcb3d979a6b6b4d07daae2 (diff)
Merge branch 'perf-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull more perf updates from Ingo Molnar: "A second (and last) round of late coming fixes and changes, almost all of them in perf tooling: User visible tooling changes: - Add period data column and make it default in 'perf script' (Jiri Olsa) - Add a visual cue for toggle zeroing of samples in 'perf top' (Taeung Song) - Improve callchains when using libunwind (Namhyung Kim) Tooling fixes and infrastructure changes: - Fix for double free in 'perf stat' when using some specific invalid command line combo (Yasser Shalabi) - Fix off-by-one bugs in map->end handling (Stephane Eranian) - Fix off-by-one bug in maps__find(), also related to map->end handling (Namhyung Kim) - Make struct symbol->end be the first addr after the symbol range, to make it match the convention used for struct map->end. (Arnaldo Carvalho de Melo) - Fix perf_evlist__add_pollfd() error handling in 'perf kvm stat live' (Jiri Olsa) - Fix python test build by moving callchain_param to an object linked into the python binding (Jiri Olsa) - Document sysfs events/ interfaces (Cody P Schafer) - Fix typos in perf/Documentation (Masanari Iida) - Add missing 'struct option' forward declaration (Arnaldo Carvalho de Melo) - Add option to copy events when queuing for sorting across cpu buffers and enable it for 'perf kvm stat live', to avoid having events left in the queue pointing to the ring buffer be rewritten in high volume sessions. (Alexander Yarygin, improving work done by David Ahern): - Do not include a struct hists per perf_evsel, untangling the histogram code from perf_evsel, to pave the way for exporting a minimalistic tools/lib/api/perf/ library usable by tools/perf and initially by the rasd daemon being developed by Borislav Petkov, Robert Richter and Jean Pihet. (Arnaldo Carvalho de Melo) - Make perf_evlist__open(evlist, NULL, NULL), i.e. without cpu and thread maps mean syswide monitoring, reducing the boilerplate for tools that only want system wide mode. (Arnaldo Carvalho de Melo) - Move exit stuff from perf_evsel__delete to perf_evsel__exit, delete should be just a front end for exit + free (Arnaldo Carvalho de Melo) - Add support to new style format of kernel PMU event. (Kan Liang) and other misc fixes" * 'perf-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (45 commits) perf script: Add period as a default output column perf script: Add period data column perf evsel: No need to drag util/cgroup.h perf evlist: Add missing 'struct option' forward declaration perf evsel: Move exit stuff from __delete to __exit kprobes/x86: Remove stale ARCH_SUPPORTS_KPROBES_ON_FTRACE define perf kvm stat live: Enable events copying perf session: Add option to copy events when queueing perf Documentation: Fix typos in perf/Documentation perf trace: Use thread_{,_set}_priv helpers perf kvm: Use thread_{,_set}_priv helpers perf callchain: Create an address space per thread perf report: Set callchain_param.record_mode for future use perf evlist: Fix for double free in tools/perf stat perf test: Add test case for pmu event new style format perf tools: Add support to new style format of kernel PMU event perf tools: Parse the pmu event prefix and suffix Revert "perf tools: Default to cpu// for events v5" perf Documentation: Remove Ruplicated docs for powerpc cpu specific events perf Documentation: sysfs events/ interfaces ...
-rw-r--r--Documentation/ABI/testing/sysfs-bus-event_source-devices-events611
-rw-r--r--arch/x86/include/asm/kprobes.h1
-rw-r--r--tools/perf/Documentation/perf-diff.txt6
-rw-r--r--tools/perf/Documentation/perf-kvm.txt4
-rw-r--r--tools/perf/Documentation/perf-list.txt2
-rw-r--r--tools/perf/Documentation/perf-record.txt2
-rw-r--r--tools/perf/Documentation/perf-script-perl.txt4
-rw-r--r--tools/perf/Documentation/perf-script-python.txt6
-rw-r--r--tools/perf/Documentation/perf-script.txt4
-rw-r--r--tools/perf/Documentation/perf-test.txt2
-rw-r--r--tools/perf/Documentation/perf-trace.txt2
-rw-r--r--tools/perf/builtin-annotate.c14
-rw-r--r--tools/perf/builtin-diff.c21
-rw-r--r--tools/perf/builtin-kvm.c29
-rw-r--r--tools/perf/builtin-record.c2
-rw-r--r--tools/perf/builtin-report.c31
-rw-r--r--tools/perf/builtin-sched.c3
-rw-r--r--tools/perf/builtin-script.c22
-rw-r--r--tools/perf/builtin-stat.c1
-rw-r--r--tools/perf/builtin-top.c60
-rw-r--r--tools/perf/builtin-trace.c16
-rw-r--r--tools/perf/tests/builtin-test.c5
-rw-r--r--tools/perf/tests/dwarf-unwind.c3
-rw-r--r--tools/perf/tests/hists_cumulate.c8
-rw-r--r--tools/perf/tests/hists_filter.c23
-rw-r--r--tools/perf/tests/hists_link.c23
-rw-r--r--tools/perf/tests/hists_output.c20
-rw-r--r--tools/perf/tests/parse-events.c36
-rw-r--r--tools/perf/ui/browsers/header.c1
-rw-r--r--tools/perf/ui/browsers/hists.c52
-rw-r--r--tools/perf/ui/gtk/hists.c2
-rw-r--r--tools/perf/util/annotate.c8
-rw-r--r--tools/perf/util/callchain.h2
-rw-r--r--tools/perf/util/event.h26
-rw-r--r--tools/perf/util/evlist.c49
-rw-r--r--tools/perf/util/evlist.h2
-rw-r--r--tools/perf/util/evsel.c77
-rw-r--r--tools/perf/util/evsel.h17
-rw-r--r--tools/perf/util/hist.c73
-rw-r--r--tools/perf/util/hist.h49
-rw-r--r--tools/perf/util/include/linux/string.h1
-rw-r--r--tools/perf/util/machine.c10
-rw-r--r--tools/perf/util/map.c8
-rw-r--r--tools/perf/util/ordered-events.c49
-rw-r--r--tools/perf/util/ordered-events.h10
-rw-r--r--tools/perf/util/parse-events.c133
-rw-r--r--tools/perf/util/parse-events.h14
-rw-r--r--tools/perf/util/parse-events.l30
-rw-r--r--tools/perf/util/parse-events.y40
-rw-r--r--tools/perf/util/pmu.c10
-rw-r--r--tools/perf/util/pmu.h10
-rw-r--r--tools/perf/util/scripting-engines/trace-event-python.c1
-rw-r--r--tools/perf/util/session.c28
-rw-r--r--tools/perf/util/session.h1
-rw-r--r--tools/perf/util/sort.c4
-rw-r--r--tools/perf/util/string.c24
-rw-r--r--tools/perf/util/symbol.c8
-rw-r--r--tools/perf/util/symbol.h2
-rw-r--r--tools/perf/util/thread.c6
-rw-r--r--tools/perf/util/thread_map.c21
-rw-r--r--tools/perf/util/thread_map.h1
-rw-r--r--tools/perf/util/unwind-libunwind.c37
-rw-r--r--tools/perf/util/unwind.h17
-rw-r--r--tools/perf/util/util.c8
64 files changed, 882 insertions, 910 deletions
diff --git a/Documentation/ABI/testing/sysfs-bus-event_source-devices-events b/Documentation/ABI/testing/sysfs-bus-event_source-devices-events
index 7b40a3cbc26a..20979f8b3edb 100644
--- a/Documentation/ABI/testing/sysfs-bus-event_source-devices-events
+++ b/Documentation/ABI/testing/sysfs-bus-event_source-devices-events
@@ -27,575 +27,62 @@ Description: Generic performance monitoring events
27 "basename". 27 "basename".
28 28
29 29
30What: /sys/devices/cpu/events/PM_1PLUS_PPC_CMPL 30What: /sys/bus/event_source/devices/<pmu>/events/<event>
31 /sys/devices/cpu/events/PM_BRU_FIN 31Date: 2014/02/24
32 /sys/devices/cpu/events/PM_BR_MPRED 32Contact: Linux kernel mailing list <linux-kernel@vger.kernel.org>
33 /sys/devices/cpu/events/PM_CMPLU_STALL 33Description: Per-pmu performance monitoring events specific to the running system
34 /sys/devices/cpu/events/PM_CMPLU_STALL_BRU
35 /sys/devices/cpu/events/PM_CMPLU_STALL_DCACHE_MISS
36 /sys/devices/cpu/events/PM_CMPLU_STALL_DFU
37 /sys/devices/cpu/events/PM_CMPLU_STALL_DIV
38 /sys/devices/cpu/events/PM_CMPLU_STALL_ERAT_MISS
39 /sys/devices/cpu/events/PM_CMPLU_STALL_FXU
40 /sys/devices/cpu/events/PM_CMPLU_STALL_IFU
41 /sys/devices/cpu/events/PM_CMPLU_STALL_LSU
42 /sys/devices/cpu/events/PM_CMPLU_STALL_REJECT
43 /sys/devices/cpu/events/PM_CMPLU_STALL_SCALAR
44 /sys/devices/cpu/events/PM_CMPLU_STALL_SCALAR_LONG
45 /sys/devices/cpu/events/PM_CMPLU_STALL_STORE
46 /sys/devices/cpu/events/PM_CMPLU_STALL_THRD
47 /sys/devices/cpu/events/PM_CMPLU_STALL_VECTOR
48 /sys/devices/cpu/events/PM_CMPLU_STALL_VECTOR_LONG
49 /sys/devices/cpu/events/PM_CYC
50 /sys/devices/cpu/events/PM_GCT_NOSLOT_BR_MPRED
51 /sys/devices/cpu/events/PM_GCT_NOSLOT_BR_MPRED_IC_MISS
52 /sys/devices/cpu/events/PM_GCT_NOSLOT_CYC
53 /sys/devices/cpu/events/PM_GCT_NOSLOT_IC_MISS
54 /sys/devices/cpu/events/PM_GRP_CMPL
55 /sys/devices/cpu/events/PM_INST_CMPL
56 /sys/devices/cpu/events/PM_LD_MISS_L1
57 /sys/devices/cpu/events/PM_LD_REF_L1
58 /sys/devices/cpu/events/PM_RUN_CYC
59 /sys/devices/cpu/events/PM_RUN_INST_CMPL
60 /sys/devices/cpu/events/PM_IC_DEMAND_L2_BR_ALL
61 /sys/devices/cpu/events/PM_GCT_UTIL_7_TO_10_SLOTS
62 /sys/devices/cpu/events/PM_PMC2_SAVED
63 /sys/devices/cpu/events/PM_VSU0_16FLOP
64 /sys/devices/cpu/events/PM_MRK_LSU_DERAT_MISS
65 /sys/devices/cpu/events/PM_MRK_ST_CMPL
66 /sys/devices/cpu/events/PM_NEST_PAIR3_ADD
67 /sys/devices/cpu/events/PM_L2_ST_DISP
68 /sys/devices/cpu/events/PM_L2_CASTOUT_MOD
69 /sys/devices/cpu/events/PM_ISEG
70 /sys/devices/cpu/events/PM_MRK_INST_TIMEO
71 /sys/devices/cpu/events/PM_L2_RCST_DISP_FAIL_ADDR
72 /sys/devices/cpu/events/PM_LSU1_DC_PREF_STREAM_CONFIRM
73 /sys/devices/cpu/events/PM_IERAT_WR_64K
74 /sys/devices/cpu/events/PM_MRK_DTLB_MISS_16M
75 /sys/devices/cpu/events/PM_IERAT_MISS
76 /sys/devices/cpu/events/PM_MRK_PTEG_FROM_LMEM
77 /sys/devices/cpu/events/PM_FLOP
78 /sys/devices/cpu/events/PM_THRD_PRIO_4_5_CYC
79 /sys/devices/cpu/events/PM_BR_PRED_TA
80 /sys/devices/cpu/events/PM_EXT_INT
81 /sys/devices/cpu/events/PM_VSU_FSQRT_FDIV
82 /sys/devices/cpu/events/PM_MRK_LD_MISS_EXPOSED_CYC
83 /sys/devices/cpu/events/PM_LSU1_LDF
84 /sys/devices/cpu/events/PM_IC_WRITE_ALL
85 /sys/devices/cpu/events/PM_LSU0_SRQ_STFWD
86 /sys/devices/cpu/events/PM_PTEG_FROM_RL2L3_MOD
87 /sys/devices/cpu/events/PM_MRK_DATA_FROM_L31_SHR
88 /sys/devices/cpu/events/PM_DATA_FROM_L21_MOD
89 /sys/devices/cpu/events/PM_VSU1_SCAL_DOUBLE_ISSUED
90 /sys/devices/cpu/events/PM_VSU0_8FLOP
91 /sys/devices/cpu/events/PM_POWER_EVENT1
92 /sys/devices/cpu/events/PM_DISP_CLB_HELD_BAL
93 /sys/devices/cpu/events/PM_VSU1_2FLOP
94 /sys/devices/cpu/events/PM_LWSYNC_HELD
95 /sys/devices/cpu/events/PM_PTEG_FROM_DL2L3_SHR
96 /sys/devices/cpu/events/PM_INST_FROM_L21_MOD
97 /sys/devices/cpu/events/PM_IERAT_XLATE_WR_16MPLUS
98 /sys/devices/cpu/events/PM_IC_REQ_ALL
99 /sys/devices/cpu/events/PM_DSLB_MISS
100 /sys/devices/cpu/events/PM_L3_MISS
101 /sys/devices/cpu/events/PM_LSU0_L1_PREF
102 /sys/devices/cpu/events/PM_VSU_SCALAR_SINGLE_ISSUED
103 /sys/devices/cpu/events/PM_LSU1_DC_PREF_STREAM_CONFIRM_STRIDE
104 /sys/devices/cpu/events/PM_L2_INST
105 /sys/devices/cpu/events/PM_VSU0_FRSP
106 /sys/devices/cpu/events/PM_FLUSH_DISP
107 /sys/devices/cpu/events/PM_PTEG_FROM_L2MISS
108 /sys/devices/cpu/events/PM_VSU1_DQ_ISSUED
109 /sys/devices/cpu/events/PM_MRK_DATA_FROM_DMEM
110 /sys/devices/cpu/events/PM_LSU_FLUSH_ULD
111 /sys/devices/cpu/events/PM_PTEG_FROM_LMEM
112 /sys/devices/cpu/events/PM_MRK_DERAT_MISS_16M
113 /sys/devices/cpu/events/PM_THRD_ALL_RUN_CYC
114 /sys/devices/cpu/events/PM_MEM0_PREFETCH_DISP
115 /sys/devices/cpu/events/PM_MRK_STALL_CMPLU_CYC_COUNT
116 /sys/devices/cpu/events/PM_DATA_FROM_DL2L3_MOD
117 /sys/devices/cpu/events/PM_VSU_FRSP
118 /sys/devices/cpu/events/PM_MRK_DATA_FROM_L21_MOD
119 /sys/devices/cpu/events/PM_PMC1_OVERFLOW
120 /sys/devices/cpu/events/PM_VSU0_SINGLE
121 /sys/devices/cpu/events/PM_MRK_PTEG_FROM_L3MISS
122 /sys/devices/cpu/events/PM_MRK_PTEG_FROM_L31_SHR
123 /sys/devices/cpu/events/PM_VSU0_VECTOR_SP_ISSUED
124 /sys/devices/cpu/events/PM_VSU1_FEST
125 /sys/devices/cpu/events/PM_MRK_INST_DISP
126 /sys/devices/cpu/events/PM_VSU0_COMPLEX_ISSUED
127 /sys/devices/cpu/events/PM_LSU1_FLUSH_UST
128 /sys/devices/cpu/events/PM_FXU_IDLE
129 /sys/devices/cpu/events/PM_LSU0_FLUSH_ULD
130 /sys/devices/cpu/events/PM_MRK_DATA_FROM_DL2L3_MOD
131 /sys/devices/cpu/events/PM_LSU_LMQ_SRQ_EMPTY_ALL_CYC
132 /sys/devices/cpu/events/PM_LSU1_REJECT_LMQ_FULL
133 /sys/devices/cpu/events/PM_INST_PTEG_FROM_L21_MOD
134 /sys/devices/cpu/events/PM_INST_FROM_RL2L3_MOD
135 /sys/devices/cpu/events/PM_SHL_CREATED
136 /sys/devices/cpu/events/PM_L2_ST_HIT
137 /sys/devices/cpu/events/PM_DATA_FROM_DMEM
138 /sys/devices/cpu/events/PM_L3_LD_MISS
139 /sys/devices/cpu/events/PM_FXU1_BUSY_FXU0_IDLE
140 /sys/devices/cpu/events/PM_DISP_CLB_HELD_RES
141 /sys/devices/cpu/events/PM_L2_SN_SX_I_DONE
142 /sys/devices/cpu/events/PM_STCX_CMPL
143 /sys/devices/cpu/events/PM_VSU0_2FLOP
144 /sys/devices/cpu/events/PM_L3_PREF_MISS
145 /sys/devices/cpu/events/PM_LSU_SRQ_SYNC_CYC
146 /sys/devices/cpu/events/PM_LSU_REJECT_ERAT_MISS
147 /sys/devices/cpu/events/PM_L1_ICACHE_MISS
148 /sys/devices/cpu/events/PM_LSU1_FLUSH_SRQ
149 /sys/devices/cpu/events/PM_LD_REF_L1_LSU0
150 /sys/devices/cpu/events/PM_VSU0_FEST
151 /sys/devices/cpu/events/PM_VSU_VECTOR_SINGLE_ISSUED
152 /sys/devices/cpu/events/PM_FREQ_UP
153 /sys/devices/cpu/events/PM_DATA_FROM_LMEM
154 /sys/devices/cpu/events/PM_LSU1_LDX
155 /sys/devices/cpu/events/PM_PMC3_OVERFLOW
156 /sys/devices/cpu/events/PM_MRK_BR_MPRED
157 /sys/devices/cpu/events/PM_SHL_MATCH
158 /sys/devices/cpu/events/PM_MRK_BR_TAKEN
159 /sys/devices/cpu/events/PM_ISLB_MISS
160 /sys/devices/cpu/events/PM_DISP_HELD_THERMAL
161 /sys/devices/cpu/events/PM_INST_PTEG_FROM_RL2L3_SHR
162 /sys/devices/cpu/events/PM_LSU1_SRQ_STFWD
163 /sys/devices/cpu/events/PM_PTEG_FROM_DMEM
164 /sys/devices/cpu/events/PM_VSU_2FLOP
165 /sys/devices/cpu/events/PM_GCT_FULL_CYC
166 /sys/devices/cpu/events/PM_MRK_DATA_FROM_L3_CYC
167 /sys/devices/cpu/events/PM_LSU_SRQ_S0_ALLOC
168 /sys/devices/cpu/events/PM_MRK_DERAT_MISS_4K
169 /sys/devices/cpu/events/PM_BR_MPRED_TA
170 /sys/devices/cpu/events/PM_INST_PTEG_FROM_L2MISS
171 /sys/devices/cpu/events/PM_DPU_HELD_POWER
172 /sys/devices/cpu/events/PM_MRK_VSU_FIN
173 /sys/devices/cpu/events/PM_LSU_SRQ_S0_VALID
174 /sys/devices/cpu/events/PM_GCT_EMPTY_CYC
175 /sys/devices/cpu/events/PM_IOPS_DISP
176 /sys/devices/cpu/events/PM_RUN_SPURR
177 /sys/devices/cpu/events/PM_PTEG_FROM_L21_MOD
178 /sys/devices/cpu/events/PM_VSU0_1FLOP
179 /sys/devices/cpu/events/PM_SNOOP_TLBIE
180 /sys/devices/cpu/events/PM_DATA_FROM_L3MISS
181 /sys/devices/cpu/events/PM_VSU_SINGLE
182 /sys/devices/cpu/events/PM_DTLB_MISS_16G
183 /sys/devices/cpu/events/PM_FLUSH
184 /sys/devices/cpu/events/PM_L2_LD_HIT
185 /sys/devices/cpu/events/PM_NEST_PAIR2_AND
186 /sys/devices/cpu/events/PM_VSU1_1FLOP
187 /sys/devices/cpu/events/PM_IC_PREF_REQ
188 /sys/devices/cpu/events/PM_L3_LD_HIT
189 /sys/devices/cpu/events/PM_DISP_HELD
190 /sys/devices/cpu/events/PM_L2_LD
191 /sys/devices/cpu/events/PM_LSU_FLUSH_SRQ
192 /sys/devices/cpu/events/PM_BC_PLUS_8_CONV
193 /sys/devices/cpu/events/PM_MRK_DATA_FROM_L31_MOD_CYC
194 /sys/devices/cpu/events/PM_L2_RCST_BUSY_RC_FULL
195 /sys/devices/cpu/events/PM_TB_BIT_TRANS
196 /sys/devices/cpu/events/PM_THERMAL_MAX
197 /sys/devices/cpu/events/PM_LSU1_FLUSH_ULD
198 /sys/devices/cpu/events/PM_LSU1_REJECT_LHS
199 /sys/devices/cpu/events/PM_LSU_LRQ_S0_ALLOC
200 /sys/devices/cpu/events/PM_L3_CO_L31
201 /sys/devices/cpu/events/PM_POWER_EVENT4
202 /sys/devices/cpu/events/PM_DATA_FROM_L31_SHR
203 /sys/devices/cpu/events/PM_BR_UNCOND
204 /sys/devices/cpu/events/PM_LSU1_DC_PREF_STREAM_ALLOC
205 /sys/devices/cpu/events/PM_PMC4_REWIND
206 /sys/devices/cpu/events/PM_L2_RCLD_DISP
207 /sys/devices/cpu/events/PM_THRD_PRIO_2_3_CYC
208 /sys/devices/cpu/events/PM_MRK_PTEG_FROM_L2MISS
209 /sys/devices/cpu/events/PM_IC_DEMAND_L2_BHT_REDIRECT
210 /sys/devices/cpu/events/PM_DATA_FROM_L31_SHR
211 /sys/devices/cpu/events/PM_IC_PREF_CANCEL_L2
212 /sys/devices/cpu/events/PM_MRK_FIN_STALL_CYC_COUNT
213 /sys/devices/cpu/events/PM_BR_PRED_CCACHE
214 /sys/devices/cpu/events/PM_GCT_UTIL_1_TO_2_SLOTS
215 /sys/devices/cpu/events/PM_MRK_ST_CMPL_INT
216 /sys/devices/cpu/events/PM_LSU_TWO_TABLEWALK_CYC
217 /sys/devices/cpu/events/PM_MRK_DATA_FROM_L3MISS
218 /sys/devices/cpu/events/PM_LSU_SET_MPRED
219 /sys/devices/cpu/events/PM_FLUSH_DISP_TLBIE
220 /sys/devices/cpu/events/PM_VSU1_FCONV
221 /sys/devices/cpu/events/PM_DERAT_MISS_16G
222 /sys/devices/cpu/events/PM_INST_FROM_LMEM
223 /sys/devices/cpu/events/PM_IC_DEMAND_L2_BR_REDIRECT
224 /sys/devices/cpu/events/PM_INST_PTEG_FROM_L2
225 /sys/devices/cpu/events/PM_PTEG_FROM_L2
226 /sys/devices/cpu/events/PM_MRK_DATA_FROM_L21_SHR_CYC
227 /sys/devices/cpu/events/PM_MRK_DTLB_MISS_4K
228 /sys/devices/cpu/events/PM_VSU0_FPSCR
229 /sys/devices/cpu/events/PM_VSU1_VECT_DOUBLE_ISSUED
230 /sys/devices/cpu/events/PM_MRK_PTEG_FROM_RL2L3_MOD
231 /sys/devices/cpu/events/PM_MEM0_RQ_DISP
232 /sys/devices/cpu/events/PM_L2_LD_MISS
233 /sys/devices/cpu/events/PM_VMX_RESULT_SAT_1
234 /sys/devices/cpu/events/PM_L1_PREF
235 /sys/devices/cpu/events/PM_MRK_DATA_FROM_LMEM_CYC
236 /sys/devices/cpu/events/PM_GRP_IC_MISS_NONSPEC
237 /sys/devices/cpu/events/PM_PB_NODE_PUMP
238 /sys/devices/cpu/events/PM_SHL_MERGED
239 /sys/devices/cpu/events/PM_NEST_PAIR1_ADD
240 /sys/devices/cpu/events/PM_DATA_FROM_L3
241 /sys/devices/cpu/events/PM_LSU_FLUSH
242 /sys/devices/cpu/events/PM_LSU_SRQ_SYNC_COUNT
243 /sys/devices/cpu/events/PM_PMC2_OVERFLOW
244 /sys/devices/cpu/events/PM_LSU_LDF
245 /sys/devices/cpu/events/PM_POWER_EVENT3
246 /sys/devices/cpu/events/PM_DISP_WT
247 /sys/devices/cpu/events/PM_IC_BANK_CONFLICT
248 /sys/devices/cpu/events/PM_BR_MPRED_CR_TA
249 /sys/devices/cpu/events/PM_L2_INST_MISS
250 /sys/devices/cpu/events/PM_NEST_PAIR2_ADD
251 /sys/devices/cpu/events/PM_MRK_LSU_FLUSH
252 /sys/devices/cpu/events/PM_L2_LDST
253 /sys/devices/cpu/events/PM_INST_FROM_L31_SHR
254 /sys/devices/cpu/events/PM_VSU0_FIN
255 /sys/devices/cpu/events/PM_VSU1_FCONV
256 /sys/devices/cpu/events/PM_INST_FROM_RMEM
257 /sys/devices/cpu/events/PM_DISP_CLB_HELD_TLBIE
258 /sys/devices/cpu/events/PM_MRK_DATA_FROM_DMEM_CYC
259 /sys/devices/cpu/events/PM_BR_PRED_CR
260 /sys/devices/cpu/events/PM_LSU_REJECT
261 /sys/devices/cpu/events/PM_GCT_UTIL_3_TO_6_SLOTS
262 /sys/devices/cpu/events/PM_CMPLU_STALL_END_GCT_NOSLOT
263 /sys/devices/cpu/events/PM_LSU0_REJECT_LMQ_FULL
264 /sys/devices/cpu/events/PM_VSU_FEST
265 /sys/devices/cpu/events/PM_NEST_PAIR0_AND
266 /sys/devices/cpu/events/PM_PTEG_FROM_L3
267 /sys/devices/cpu/events/PM_POWER_EVENT2
268 /sys/devices/cpu/events/PM_IC_PREF_CANCEL_PAGE
269 /sys/devices/cpu/events/PM_VSU0_FSQRT_FDIV
270 /sys/devices/cpu/events/PM_MRK_GRP_CMPL
271 /sys/devices/cpu/events/PM_VSU0_SCAL_DOUBLE_ISSUED
272 /sys/devices/cpu/events/PM_GRP_DISP
273 /sys/devices/cpu/events/PM_LSU0_LDX
274 /sys/devices/cpu/events/PM_DATA_FROM_L2
275 /sys/devices/cpu/events/PM_MRK_DATA_FROM_RL2L3_MOD
276 /sys/devices/cpu/events/PM_VSU0_VECT_DOUBLE_ISSUED
277 /sys/devices/cpu/events/PM_VSU1_2FLOP_DOUBLE
278 /sys/devices/cpu/events/PM_THRD_PRIO_6_7_CYC
279 /sys/devices/cpu/events/PM_BC_PLUS_8_RSLV_TAKEN
280 /sys/devices/cpu/events/PM_BR_MPRED_CR
281 /sys/devices/cpu/events/PM_L3_CO_MEM
282 /sys/devices/cpu/events/PM_DATA_FROM_RL2L3_MOD
283 /sys/devices/cpu/events/PM_LSU_SRQ_FULL_CYC
284 /sys/devices/cpu/events/PM_TABLEWALK_CYC
285 /sys/devices/cpu/events/PM_MRK_PTEG_FROM_RMEM
286 /sys/devices/cpu/events/PM_LSU_SRQ_STFWD
287 /sys/devices/cpu/events/PM_INST_PTEG_FROM_RMEM
288 /sys/devices/cpu/events/PM_FXU0_FIN
289 /sys/devices/cpu/events/PM_LSU1_L1_SW_PREF
290 /sys/devices/cpu/events/PM_PTEG_FROM_L31_MOD
291 /sys/devices/cpu/events/PM_PMC5_OVERFLOW
292 /sys/devices/cpu/events/PM_LD_REF_L1_LSU1
293 /sys/devices/cpu/events/PM_INST_PTEG_FROM_L21_SHR
294 /sys/devices/cpu/events/PM_DATA_FROM_RMEM
295 /sys/devices/cpu/events/PM_VSU0_SCAL_SINGLE_ISSUED
296 /sys/devices/cpu/events/PM_BR_MPRED_LSTACK
297 /sys/devices/cpu/events/PM_MRK_DATA_FROM_RL2L3_MOD_CYC
298 /sys/devices/cpu/events/PM_LSU0_FLUSH_UST
299 /sys/devices/cpu/events/PM_LSU_NCST
300 /sys/devices/cpu/events/PM_BR_TAKEN
301 /sys/devices/cpu/events/PM_INST_PTEG_FROM_LMEM
302 /sys/devices/cpu/events/PM_DTLB_MISS_4K
303 /sys/devices/cpu/events/PM_PMC4_SAVED
304 /sys/devices/cpu/events/PM_VSU1_PERMUTE_ISSUED
305 /sys/devices/cpu/events/PM_SLB_MISS
306 /sys/devices/cpu/events/PM_LSU1_FLUSH_LRQ
307 /sys/devices/cpu/events/PM_DTLB_MISS
308 /sys/devices/cpu/events/PM_VSU1_FRSP
309 /sys/devices/cpu/events/PM_VSU_VECTOR_DOUBLE_ISSUED
310 /sys/devices/cpu/events/PM_L2_CASTOUT_SHR
311 /sys/devices/cpu/events/PM_DATA_FROM_DL2L3_SHR
312 /sys/devices/cpu/events/PM_VSU1_STF
313 /sys/devices/cpu/events/PM_ST_FIN
314 /sys/devices/cpu/events/PM_PTEG_FROM_L21_SHR
315 /sys/devices/cpu/events/PM_L2_LOC_GUESS_WRONG
316 /sys/devices/cpu/events/PM_MRK_STCX_FAIL
317 /sys/devices/cpu/events/PM_LSU0_REJECT_LHS
318 /sys/devices/cpu/events/PM_IC_PREF_CANCEL_HIT
319 /sys/devices/cpu/events/PM_L3_PREF_BUSY
320 /sys/devices/cpu/events/PM_MRK_BRU_FIN
321 /sys/devices/cpu/events/PM_LSU1_NCLD
322 /sys/devices/cpu/events/PM_INST_PTEG_FROM_L31_MOD
323 /sys/devices/cpu/events/PM_LSU_NCLD
324 /sys/devices/cpu/events/PM_LSU_LDX
325 /sys/devices/cpu/events/PM_L2_LOC_GUESS_CORRECT
326 /sys/devices/cpu/events/PM_THRESH_TIMEO
327 /sys/devices/cpu/events/PM_L3_PREF_ST
328 /sys/devices/cpu/events/PM_DISP_CLB_HELD_SYNC
329 /sys/devices/cpu/events/PM_VSU_SIMPLE_ISSUED
330 /sys/devices/cpu/events/PM_VSU1_SINGLE
331 /sys/devices/cpu/events/PM_DATA_TABLEWALK_CYC
332 /sys/devices/cpu/events/PM_L2_RC_ST_DONE
333 /sys/devices/cpu/events/PM_MRK_PTEG_FROM_L21_MOD
334 /sys/devices/cpu/events/PM_LARX_LSU1
335 /sys/devices/cpu/events/PM_MRK_DATA_FROM_RMEM
336 /sys/devices/cpu/events/PM_DISP_CLB_HELD
337 /sys/devices/cpu/events/PM_DERAT_MISS_4K
338 /sys/devices/cpu/events/PM_L2_RCLD_DISP_FAIL_ADDR
339 /sys/devices/cpu/events/PM_SEG_EXCEPTION
340 /sys/devices/cpu/events/PM_FLUSH_DISP_SB
341 /sys/devices/cpu/events/PM_L2_DC_INV
342 /sys/devices/cpu/events/PM_PTEG_FROM_DL2L3_MOD
343 /sys/devices/cpu/events/PM_DSEG
344 /sys/devices/cpu/events/PM_BR_PRED_LSTACK
345 /sys/devices/cpu/events/PM_VSU0_STF
346 /sys/devices/cpu/events/PM_LSU_FX_FIN
347 /sys/devices/cpu/events/PM_DERAT_MISS_16M
348 /sys/devices/cpu/events/PM_MRK_PTEG_FROM_DL2L3_MOD
349 /sys/devices/cpu/events/PM_GCT_UTIL_11_PLUS_SLOTS
350 /sys/devices/cpu/events/PM_INST_FROM_L3
351 /sys/devices/cpu/events/PM_MRK_IFU_FIN
352 /sys/devices/cpu/events/PM_ITLB_MISS
353 /sys/devices/cpu/events/PM_VSU_STF
354 /sys/devices/cpu/events/PM_LSU_FLUSH_UST
355 /sys/devices/cpu/events/PM_L2_LDST_MISS
356 /sys/devices/cpu/events/PM_FXU1_FIN
357 /sys/devices/cpu/events/PM_SHL_DEALLOCATED
358 /sys/devices/cpu/events/PM_L2_SN_M_WR_DONE
359 /sys/devices/cpu/events/PM_LSU_REJECT_SET_MPRED
360 /sys/devices/cpu/events/PM_L3_PREF_LD
361 /sys/devices/cpu/events/PM_L2_SN_M_RD_DONE
362 /sys/devices/cpu/events/PM_MRK_DERAT_MISS_16G
363 /sys/devices/cpu/events/PM_VSU_FCONV
364 /sys/devices/cpu/events/PM_ANY_THRD_RUN_CYC
365 /sys/devices/cpu/events/PM_LSU_LMQ_FULL_CYC
366 /sys/devices/cpu/events/PM_MRK_LSU_REJECT_LHS
367 /sys/devices/cpu/events/PM_MRK_LD_MISS_L1_CYC
368 /sys/devices/cpu/events/PM_MRK_DATA_FROM_L2_CYC
369 /sys/devices/cpu/events/PM_INST_IMC_MATCH_DISP
370 /sys/devices/cpu/events/PM_MRK_DATA_FROM_RMEM_CYC
371 /sys/devices/cpu/events/PM_VSU0_SIMPLE_ISSUED
372 /sys/devices/cpu/events/PM_MRK_PTEG_FROM_RL2L3_SHR
373 /sys/devices/cpu/events/PM_VSU_FMA_DOUBLE
374 /sys/devices/cpu/events/PM_VSU_4FLOP
375 /sys/devices/cpu/events/PM_VSU1_FIN
376 /sys/devices/cpu/events/PM_NEST_PAIR1_AND
377 /sys/devices/cpu/events/PM_INST_PTEG_FROM_RL2L3_MOD
378 /sys/devices/cpu/events/PM_PTEG_FROM_RMEM
379 /sys/devices/cpu/events/PM_LSU_LRQ_S0_VALID
380 /sys/devices/cpu/events/PM_LSU0_LDF
381 /sys/devices/cpu/events/PM_FLUSH_COMPLETION
382 /sys/devices/cpu/events/PM_ST_MISS_L1
383 /sys/devices/cpu/events/PM_L2_NODE_PUMP
384 /sys/devices/cpu/events/PM_INST_FROM_DL2L3_SHR
385 /sys/devices/cpu/events/PM_MRK_STALL_CMPLU_CYC
386 /sys/devices/cpu/events/PM_VSU1_DENORM
387 /sys/devices/cpu/events/PM_MRK_DATA_FROM_L31_SHR_CYC
388 /sys/devices/cpu/events/PM_NEST_PAIR0_ADD
389 /sys/devices/cpu/events/PM_INST_FROM_L3MISS
390 /sys/devices/cpu/events/PM_EE_OFF_EXT_INT
391 /sys/devices/cpu/events/PM_INST_PTEG_FROM_DMEM
392 /sys/devices/cpu/events/PM_INST_FROM_DL2L3_MOD
393 /sys/devices/cpu/events/PM_PMC6_OVERFLOW
394 /sys/devices/cpu/events/PM_VSU_2FLOP_DOUBLE
395 /sys/devices/cpu/events/PM_TLB_MISS
396 /sys/devices/cpu/events/PM_FXU_BUSY
397 /sys/devices/cpu/events/PM_L2_RCLD_DISP_FAIL_OTHER
398 /sys/devices/cpu/events/PM_LSU_REJECT_LMQ_FULL
399 /sys/devices/cpu/events/PM_IC_RELOAD_SHR
400 /sys/devices/cpu/events/PM_GRP_MRK
401 /sys/devices/cpu/events/PM_MRK_ST_NEST
402 /sys/devices/cpu/events/PM_VSU1_FSQRT_FDIV
403 /sys/devices/cpu/events/PM_LSU0_FLUSH_LRQ
404 /sys/devices/cpu/events/PM_LARX_LSU0
405 /sys/devices/cpu/events/PM_IBUF_FULL_CYC
406 /sys/devices/cpu/events/PM_MRK_DATA_FROM_DL2L3_SHR_CYC
407 /sys/devices/cpu/events/PM_LSU_DC_PREF_STREAM_ALLOC
408 /sys/devices/cpu/events/PM_GRP_MRK_CYC
409 /sys/devices/cpu/events/PM_MRK_DATA_FROM_RL2L3_SHR_CYC
410 /sys/devices/cpu/events/PM_L2_GLOB_GUESS_CORRECT
411 /sys/devices/cpu/events/PM_LSU_REJECT_LHS
412 /sys/devices/cpu/events/PM_MRK_DATA_FROM_LMEM
413 /sys/devices/cpu/events/PM_INST_PTEG_FROM_L3
414 /sys/devices/cpu/events/PM_FREQ_DOWN
415 /sys/devices/cpu/events/PM_PB_RETRY_NODE_PUMP
416 /sys/devices/cpu/events/PM_INST_FROM_RL2L3_SHR
417 /sys/devices/cpu/events/PM_MRK_INST_ISSUED
418 /sys/devices/cpu/events/PM_PTEG_FROM_L3MISS
419 /sys/devices/cpu/events/PM_RUN_PURR
420 /sys/devices/cpu/events/PM_MRK_GRP_IC_MISS
421 /sys/devices/cpu/events/PM_MRK_DATA_FROM_L3
422 /sys/devices/cpu/events/PM_PTEG_FROM_RL2L3_SHR
423 /sys/devices/cpu/events/PM_LSU_FLUSH_LRQ
424 /sys/devices/cpu/events/PM_MRK_DERAT_MISS_64K
425 /sys/devices/cpu/events/PM_INST_PTEG_FROM_DL2L3_MOD
426 /sys/devices/cpu/events/PM_L2_ST_MISS
427 /sys/devices/cpu/events/PM_MRK_PTEG_FROM_L21_SHR
428 /sys/devices/cpu/events/PM_LWSYNC
429 /sys/devices/cpu/events/PM_LSU0_DC_PREF_STREAM_CONFIRM_STRIDE
430 /sys/devices/cpu/events/PM_MRK_LSU_FLUSH_LRQ
431 /sys/devices/cpu/events/PM_INST_IMC_MATCH_CMPL
432 /sys/devices/cpu/events/PM_NEST_PAIR3_AND
433 /sys/devices/cpu/events/PM_PB_RETRY_SYS_PUMP
434 /sys/devices/cpu/events/PM_MRK_INST_FIN
435 /sys/devices/cpu/events/PM_MRK_PTEG_FROM_DL2L3_SHR
436 /sys/devices/cpu/events/PM_INST_FROM_L31_MOD
437 /sys/devices/cpu/events/PM_MRK_DTLB_MISS_64K
438 /sys/devices/cpu/events/PM_LSU_FIN
439 /sys/devices/cpu/events/PM_MRK_LSU_REJECT
440 /sys/devices/cpu/events/PM_L2_CO_FAIL_BUSY
441 /sys/devices/cpu/events/PM_MEM0_WQ_DISP
442 /sys/devices/cpu/events/PM_DATA_FROM_L31_MOD
443 /sys/devices/cpu/events/PM_THERMAL_WARN
444 /sys/devices/cpu/events/PM_VSU0_4FLOP
445 /sys/devices/cpu/events/PM_BR_MPRED_CCACHE
446 /sys/devices/cpu/events/PM_L1_DEMAND_WRITE
447 /sys/devices/cpu/events/PM_FLUSH_BR_MPRED
448 /sys/devices/cpu/events/PM_MRK_DTLB_MISS_16G
449 /sys/devices/cpu/events/PM_MRK_PTEG_FROM_DMEM
450 /sys/devices/cpu/events/PM_L2_RCST_DISP
451 /sys/devices/cpu/events/PM_LSU_PARTIAL_CDF
452 /sys/devices/cpu/events/PM_DISP_CLB_HELD_SB
453 /sys/devices/cpu/events/PM_VSU0_FMA_DOUBLE
454 /sys/devices/cpu/events/PM_FXU0_BUSY_FXU1_IDLE
455 /sys/devices/cpu/events/PM_IC_DEMAND_CYC
456 /sys/devices/cpu/events/PM_MRK_DATA_FROM_L21_SHR
457 /sys/devices/cpu/events/PM_MRK_LSU_FLUSH_UST
458 /sys/devices/cpu/events/PM_INST_PTEG_FROM_L3MISS
459 /sys/devices/cpu/events/PM_VSU_DENORM
460 /sys/devices/cpu/events/PM_MRK_LSU_PARTIAL_CDF
461 /sys/devices/cpu/events/PM_INST_FROM_L21_SHR
462 /sys/devices/cpu/events/PM_IC_PREF_WRITE
463 /sys/devices/cpu/events/PM_BR_PRED
464 /sys/devices/cpu/events/PM_INST_FROM_DMEM
465 /sys/devices/cpu/events/PM_IC_PREF_CANCEL_ALL
466 /sys/devices/cpu/events/PM_LSU_DC_PREF_STREAM_CONFIRM
467 /sys/devices/cpu/events/PM_MRK_LSU_FLUSH_SRQ
468 /sys/devices/cpu/events/PM_MRK_FIN_STALL_CYC
469 /sys/devices/cpu/events/PM_L2_RCST_DISP_FAIL_OTHER
470 /sys/devices/cpu/events/PM_VSU1_DD_ISSUED
471 /sys/devices/cpu/events/PM_PTEG_FROM_L31_SHR
472 /sys/devices/cpu/events/PM_DATA_FROM_L21_SHR
473 /sys/devices/cpu/events/PM_LSU0_NCLD
474 /sys/devices/cpu/events/PM_VSU1_4FLOP
475 /sys/devices/cpu/events/PM_VSU1_8FLOP
476 /sys/devices/cpu/events/PM_VSU_8FLOP
477 /sys/devices/cpu/events/PM_LSU_LMQ_SRQ_EMPTY_CYC
478 /sys/devices/cpu/events/PM_DTLB_MISS_64K
479 /sys/devices/cpu/events/PM_THRD_CONC_RUN_INST
480 /sys/devices/cpu/events/PM_MRK_PTEG_FROM_L2
481 /sys/devices/cpu/events/PM_PB_SYS_PUMP
482 /sys/devices/cpu/events/PM_VSU_FIN
483 /sys/devices/cpu/events/PM_MRK_DATA_FROM_L31_MOD
484 /sys/devices/cpu/events/PM_THRD_PRIO_0_1_CYC
485 /sys/devices/cpu/events/PM_DERAT_MISS_64K
486 /sys/devices/cpu/events/PM_PMC2_REWIND
487 /sys/devices/cpu/events/PM_INST_FROM_L2
488 /sys/devices/cpu/events/PM_GRP_BR_MPRED_NONSPEC
489 /sys/devices/cpu/events/PM_INST_DISP
490 /sys/devices/cpu/events/PM_MEM0_RD_CANCEL_TOTAL
491 /sys/devices/cpu/events/PM_LSU0_DC_PREF_STREAM_CONFIRM
492 /sys/devices/cpu/events/PM_L1_DCACHE_RELOAD_VALID
493 /sys/devices/cpu/events/PM_VSU_SCALAR_DOUBLE_ISSUED
494 /sys/devices/cpu/events/PM_L3_PREF_HIT
495 /sys/devices/cpu/events/PM_MRK_PTEG_FROM_L31_MOD
496 /sys/devices/cpu/events/PM_MRK_FXU_FIN
497 /sys/devices/cpu/events/PM_PMC4_OVERFLOW
498 /sys/devices/cpu/events/PM_MRK_PTEG_FROM_L3
499 /sys/devices/cpu/events/PM_LSU0_LMQ_LHR_MERGE
500 /sys/devices/cpu/events/PM_BTAC_HIT
501 /sys/devices/cpu/events/PM_L3_RD_BUSY
502 /sys/devices/cpu/events/PM_LSU0_L1_SW_PREF
503 /sys/devices/cpu/events/PM_INST_FROM_L2MISS
504 /sys/devices/cpu/events/PM_LSU0_DC_PREF_STREAM_ALLOC
505 /sys/devices/cpu/events/PM_L2_ST
506 /sys/devices/cpu/events/PM_VSU0_DENORM
507 /sys/devices/cpu/events/PM_MRK_DATA_FROM_DL2L3_SHR
508 /sys/devices/cpu/events/PM_BR_PRED_CR_TA
509 /sys/devices/cpu/events/PM_VSU0_FCONV
510 /sys/devices/cpu/events/PM_MRK_LSU_FLUSH_ULD
511 /sys/devices/cpu/events/PM_BTAC_MISS
512 /sys/devices/cpu/events/PM_MRK_LD_MISS_EXPOSED_CYC_COUNT
513 /sys/devices/cpu/events/PM_MRK_DATA_FROM_L2
514 /sys/devices/cpu/events/PM_LSU_DCACHE_RELOAD_VALID
515 /sys/devices/cpu/events/PM_VSU_FMA
516 /sys/devices/cpu/events/PM_LSU0_FLUSH_SRQ
517 /sys/devices/cpu/events/PM_LSU1_L1_PREF
518 /sys/devices/cpu/events/PM_IOPS_CMPL
519 /sys/devices/cpu/events/PM_L2_SYS_PUMP
520 /sys/devices/cpu/events/PM_L2_RCLD_BUSY_RC_FULL
521 /sys/devices/cpu/events/PM_LSU_LMQ_S0_ALLOC
522 /sys/devices/cpu/events/PM_FLUSH_DISP_SYNC
523 /sys/devices/cpu/events/PM_MRK_DATA_FROM_DL2L3_MOD_CYC
524 /sys/devices/cpu/events/PM_L2_IC_INV
525 /sys/devices/cpu/events/PM_MRK_DATA_FROM_L21_MOD_CYC
526 /sys/devices/cpu/events/PM_L3_PREF_LDST
527 /sys/devices/cpu/events/PM_LSU_SRQ_EMPTY_CYC
528 /sys/devices/cpu/events/PM_LSU_LMQ_S0_VALID
529 /sys/devices/cpu/events/PM_FLUSH_PARTIAL
530 /sys/devices/cpu/events/PM_VSU1_FMA_DOUBLE
531 /sys/devices/cpu/events/PM_1PLUS_PPC_DISP
532 /sys/devices/cpu/events/PM_DATA_FROM_L2MISS
533 /sys/devices/cpu/events/PM_SUSPENDED
534 /sys/devices/cpu/events/PM_VSU0_FMA
535 /sys/devices/cpu/events/PM_STCX_FAIL
536 /sys/devices/cpu/events/PM_VSU0_FSQRT_FDIV_DOUBLE
537 /sys/devices/cpu/events/PM_DC_PREF_DST
538 /sys/devices/cpu/events/PM_VSU1_SCAL_SINGLE_ISSUED
539 /sys/devices/cpu/events/PM_L3_HIT
540 /sys/devices/cpu/events/PM_L2_GLOB_GUESS_WRONG
541 /sys/devices/cpu/events/PM_MRK_DFU_FIN
542 /sys/devices/cpu/events/PM_INST_FROM_L1
543 /sys/devices/cpu/events/PM_IC_DEMAND_REQ
544 /sys/devices/cpu/events/PM_VSU1_FSQRT_FDIV_DOUBLE
545 /sys/devices/cpu/events/PM_VSU1_FMA
546 /sys/devices/cpu/events/PM_MRK_LD_MISS_L1
547 /sys/devices/cpu/events/PM_VSU0_2FLOP_DOUBLE
548 /sys/devices/cpu/events/PM_LSU_DC_PREF_STRIDED_STREAM_CONFIRM
549 /sys/devices/cpu/events/PM_INST_PTEG_FROM_L31_SHR
550 /sys/devices/cpu/events/PM_MRK_LSU_REJECT_ERAT_MISS
551 /sys/devices/cpu/events/PM_MRK_DATA_FROM_L2MISS
552 /sys/devices/cpu/events/PM_DATA_FROM_RL2L3_SHR
553 /sys/devices/cpu/events/PM_INST_FROM_PREF
554 /sys/devices/cpu/events/PM_VSU1_SQ
555 /sys/devices/cpu/events/PM_L2_LD_DISP
556 /sys/devices/cpu/events/PM_L2_DISP_ALL
557 /sys/devices/cpu/events/PM_THRD_GRP_CMPL_BOTH_CYC
558 /sys/devices/cpu/events/PM_VSU_FSQRT_FDIV_DOUBLE
559 /sys/devices/cpu/events/PM_INST_PTEG_FROM_DL2L3_SHR
560 /sys/devices/cpu/events/PM_VSU_1FLOP
561 /sys/devices/cpu/events/PM_HV_CYC
562 /sys/devices/cpu/events/PM_MRK_LSU_FIN
563 /sys/devices/cpu/events/PM_MRK_DATA_FROM_RL2L3_SHR
564 /sys/devices/cpu/events/PM_DTLB_MISS_16M
565 /sys/devices/cpu/events/PM_LSU1_LMQ_LHR_MERGE
566 /sys/devices/cpu/events/PM_IFU_FIN
567 /sys/devices/cpu/events/PM_1THRD_CON_RUN_INSTR
568 /sys/devices/cpu/events/PM_CMPLU_STALL_COUNT
569 /sys/devices/cpu/events/PM_MEM0_PB_RD_CL
570 /sys/devices/cpu/events/PM_THRD_1_RUN_CYC
571 /sys/devices/cpu/events/PM_THRD_2_CONC_RUN_INSTR
572 /sys/devices/cpu/events/PM_THRD_2_RUN_CYC
573 /sys/devices/cpu/events/PM_THRD_3_CONC_RUN_INST
574 /sys/devices/cpu/events/PM_THRD_3_RUN_CYC
575 /sys/devices/cpu/events/PM_THRD_4_CONC_RUN_INST
576 /sys/devices/cpu/events/PM_THRD_4_RUN_CYC
577 34
578Date: 2013/01/08 35 Each file (except for some of those with a '.' in them, '.unit'
36 and '.scale') in the 'events' directory describes a single
37 performance monitoring event supported by the <pmu>. The name
38 of the file is the name of the event.
39
40 File contents:
41
42 <term>[=<value>][,<term>[=<value>]]...
43
44 Where <term> is one of the terms listed under
45 /sys/bus/event_source/devices/<pmu>/format/ and <value> is
46 a number is base-16 format with a '0x' prefix (lowercase only).
47 If a <term> is specified alone (without an assigned value), it
48 is implied that 0x1 is assigned to that <term>.
579 49
50 Examples (each of these lines would be in a seperate file):
51
52 event=0x2abc
53 event=0x423,inv,cmask=0x3
54 domain=0x1,offset=0x8,starting_index=0xffff
55
56 Each of the assignments indicates a value to be assigned to a
57 particular set of bits (as defined by the format file
58 corresponding to the <term>) in the perf_event structure passed
59 to the perf_open syscall.
60
61What: /sys/bus/event_source/devices/<pmu>/events/<event>.unit
62Date: 2014/02/24
580Contact: Linux kernel mailing list <linux-kernel@vger.kernel.org> 63Contact: Linux kernel mailing list <linux-kernel@vger.kernel.org>
581 Linux Powerpc mailing list <linuxppc-dev@ozlabs.org> 64Description: Perf event units
582 65
583Description: POWER-systems specific performance monitoring events 66 A string specifying the English plural numerical unit that <event>
67 (once multiplied by <event>.scale) represents.
584 68
585 A collection of performance monitoring events that may be 69 Example:
586 supported by the POWER CPU. These events can be monitored
587 using the 'perf(1)' tool.
588 70
589 These events may not be supported by other CPUs. 71 Joules
590 72
591 The contents of each file would look like: 73What: /sys/bus/event_source/devices/<pmu>/events/<event>.scale
74Date: 2014/02/24
75Contact: Linux kernel mailing list <linux-kernel@vger.kernel.org>
76Description: Perf event scaling factors
592 77
593 event=0xNNNN 78 A string representing a floating point value expressed in
79 scientific notation to be multiplied by the event count
80 recieved from the kernel to match the unit specified in the
81 <event>.unit file.
594 82
595 where 'N' is a hex digit and the number '0xNNNN' shows the 83 Example:
596 "raw code" for the perf event identified by the file's 84
597 "basename". 85 2.3283064365386962890625e-10
598 86
599 Further, multiple terms like 'event=0xNNNN' can be specified 87 This is provided to avoid performing floating point arithmetic
600 and separated with comma. All available terms are defined in 88 in the kernel.
601 the /sys/bus/event_source/devices/<dev>/format file.
diff --git a/arch/x86/include/asm/kprobes.h b/arch/x86/include/asm/kprobes.h
index 53cdfb2857ab..4421b5da409d 100644
--- a/arch/x86/include/asm/kprobes.h
+++ b/arch/x86/include/asm/kprobes.h
@@ -27,7 +27,6 @@
27#include <asm/insn.h> 27#include <asm/insn.h>
28 28
29#define __ARCH_WANT_KPROBES_INSN_SLOT 29#define __ARCH_WANT_KPROBES_INSN_SLOT
30#define ARCH_SUPPORTS_KPROBES_ON_FTRACE
31 30
32struct pt_regs; 31struct pt_regs;
33struct kprobe; 32struct kprobe;
diff --git a/tools/perf/Documentation/perf-diff.txt b/tools/perf/Documentation/perf-diff.txt
index b3b8abae62b8..e463caa3eb49 100644
--- a/tools/perf/Documentation/perf-diff.txt
+++ b/tools/perf/Documentation/perf-diff.txt
@@ -196,10 +196,10 @@ If specified the 'Weighted diff' column is displayed with value 'd' computed as:
196 196
197 - period being the hist entry period value 197 - period being the hist entry period value
198 198
199 - WEIGHT-A/WEIGHT-B being user suplied weights in the the '-c' option 199 - WEIGHT-A/WEIGHT-B being user supplied weights in the the '-c' option
200 behind ':' separator like '-c wdiff:1,2'. 200 behind ':' separator like '-c wdiff:1,2'.
201 - WIEGHT-A being the weight of the data file 201 - WEIGHT-A being the weight of the data file
202 - WIEGHT-B being the weight of the baseline data file 202 - WEIGHT-B being the weight of the baseline data file
203 203
204SEE ALSO 204SEE ALSO
205-------- 205--------
diff --git a/tools/perf/Documentation/perf-kvm.txt b/tools/perf/Documentation/perf-kvm.txt
index 6e689dc89a2f..6252e776009c 100644
--- a/tools/perf/Documentation/perf-kvm.txt
+++ b/tools/perf/Documentation/perf-kvm.txt
@@ -100,7 +100,7 @@ OPTIONS
100STAT REPORT OPTIONS 100STAT REPORT OPTIONS
101------------------- 101-------------------
102--vcpu=<value>:: 102--vcpu=<value>::
103 analyze events which occures on this vcpu. (default: all vcpus) 103 analyze events which occur on this vcpu. (default: all vcpus)
104 104
105--event=<value>:: 105--event=<value>::
106 event to be analyzed. Possible values: vmexit, mmio (x86 only), 106 event to be analyzed. Possible values: vmexit, mmio (x86 only),
@@ -134,7 +134,7 @@ STAT LIVE OPTIONS
134 Analyze events only for given process ID(s) (comma separated list). 134 Analyze events only for given process ID(s) (comma separated list).
135 135
136--vcpu=<value>:: 136--vcpu=<value>::
137 analyze events which occures on this vcpu. (default: all vcpus) 137 analyze events which occur on this vcpu. (default: all vcpus)
138 138
139 139
140--event=<value>:: 140--event=<value>::
diff --git a/tools/perf/Documentation/perf-list.txt b/tools/perf/Documentation/perf-list.txt
index 6fce6a622206..cbb4f743d921 100644
--- a/tools/perf/Documentation/perf-list.txt
+++ b/tools/perf/Documentation/perf-list.txt
@@ -19,7 +19,7 @@ various perf commands with the -e option.
19EVENT MODIFIERS 19EVENT MODIFIERS
20--------------- 20---------------
21 21
22Events can optionally have a modifer by appending a colon and one or 22Events can optionally have a modifier by appending a colon and one or
23more modifiers. Modifiers allow the user to restrict the events to be 23more modifiers. Modifiers allow the user to restrict the events to be
24counted. The following modifiers exist: 24counted. The following modifiers exist:
25 25
diff --git a/tools/perf/Documentation/perf-record.txt b/tools/perf/Documentation/perf-record.txt
index d460049cae8e..398f8d53bd6d 100644
--- a/tools/perf/Documentation/perf-record.txt
+++ b/tools/perf/Documentation/perf-record.txt
@@ -146,7 +146,7 @@ the thread executes on the designated CPUs. Default is to monitor all CPUs.
146 146
147-N:: 147-N::
148--no-buildid-cache:: 148--no-buildid-cache::
149Do not update the builid cache. This saves some overhead in situations 149Do not update the buildid cache. This saves some overhead in situations
150where the information in the perf.data file (which includes buildids) 150where the information in the perf.data file (which includes buildids)
151is sufficient. 151is sufficient.
152 152
diff --git a/tools/perf/Documentation/perf-script-perl.txt b/tools/perf/Documentation/perf-script-perl.txt
index d00bef231340..dfbb506d2c34 100644
--- a/tools/perf/Documentation/perf-script-perl.txt
+++ b/tools/perf/Documentation/perf-script-perl.txt
@@ -181,8 +181,8 @@ strings for flag and symbolic fields. These correspond to the strings
181and values parsed from the 'print fmt' fields of the event format 181and values parsed from the 'print fmt' fields of the event format
182files: 182files:
183 183
184 flag_str($event_name, $field_name, $field_value) - returns the string represention corresponding to $field_value for the flag field $field_name of event $event_name 184 flag_str($event_name, $field_name, $field_value) - returns the string representation corresponding to $field_value for the flag field $field_name of event $event_name
185 symbol_str($event_name, $field_name, $field_value) - returns the string represention corresponding to $field_value for the symbolic field $field_name of event $event_name 185 symbol_str($event_name, $field_name, $field_value) - returns the string representation corresponding to $field_value for the symbolic field $field_name of event $event_name
186 186
187Perf::Trace::Context Module 187Perf::Trace::Context Module
188~~~~~~~~~~~~~~~~~~~~~~~~~~~ 188~~~~~~~~~~~~~~~~~~~~~~~~~~~
diff --git a/tools/perf/Documentation/perf-script-python.txt b/tools/perf/Documentation/perf-script-python.txt
index 9f1f054b8432..54acba221558 100644
--- a/tools/perf/Documentation/perf-script-python.txt
+++ b/tools/perf/Documentation/perf-script-python.txt
@@ -263,7 +263,7 @@ and having the counts we've tallied as values.
263 263
264The print_syscall_totals() function iterates over the entries in the 264The print_syscall_totals() function iterates over the entries in the
265dictionary and displays a line for each entry containing the syscall 265dictionary and displays a line for each entry containing the syscall
266name (the dictonary keys contain the syscall ids, which are passed to 266name (the dictionary keys contain the syscall ids, which are passed to
267the Util function syscall_name(), which translates the raw syscall 267the Util function syscall_name(), which translates the raw syscall
268numbers to the corresponding syscall name strings). The output is 268numbers to the corresponding syscall name strings). The output is
269displayed after all the events in the trace have been processed, by 269displayed after all the events in the trace have been processed, by
@@ -576,8 +576,8 @@ strings for flag and symbolic fields. These correspond to the strings
576and values parsed from the 'print fmt' fields of the event format 576and values parsed from the 'print fmt' fields of the event format
577files: 577files:
578 578
579 flag_str(event_name, field_name, field_value) - returns the string represention corresponding to field_value for the flag field field_name of event event_name 579 flag_str(event_name, field_name, field_value) - returns the string representation corresponding to field_value for the flag field field_name of event event_name
580 symbol_str(event_name, field_name, field_value) - returns the string represention corresponding to field_value for the symbolic field field_name of event event_name 580 symbol_str(event_name, field_name, field_value) - returns the string representation corresponding to field_value for the symbolic field field_name of event event_name
581 581
582The *autodict* function returns a special kind of Python 582The *autodict* function returns a special kind of Python
583dictionary that implements Perl's 'autovivifying' hashes in Python 583dictionary that implements Perl's 'autovivifying' hashes in Python
diff --git a/tools/perf/Documentation/perf-script.txt b/tools/perf/Documentation/perf-script.txt
index 05f9a0a6784c..21494806c0ab 100644
--- a/tools/perf/Documentation/perf-script.txt
+++ b/tools/perf/Documentation/perf-script.txt
@@ -115,7 +115,7 @@ OPTIONS
115-f:: 115-f::
116--fields:: 116--fields::
117 Comma separated list of fields to print. Options are: 117 Comma separated list of fields to print. Options are:
118 comm, tid, pid, time, cpu, event, trace, ip, sym, dso, addr, symoff, srcline. 118 comm, tid, pid, time, cpu, event, trace, ip, sym, dso, addr, symoff, srcline, period.
119 Field list can be prepended with the type, trace, sw or hw, 119 Field list can be prepended with the type, trace, sw or hw,
120 to indicate to which event type the field list applies. 120 to indicate to which event type the field list applies.
121 e.g., -f sw:comm,tid,time,ip,sym and -f trace:time,cpu,trace 121 e.g., -f sw:comm,tid,time,ip,sym and -f trace:time,cpu,trace
@@ -140,7 +140,7 @@ OPTIONS
140 140
141 "Overriding previous field request for all events." 141 "Overriding previous field request for all events."
142 142
143 Alternativey, consider the order: 143 Alternatively, consider the order:
144 144
145 -f comm,tid,time,ip,sym -f trace: 145 -f comm,tid,time,ip,sym -f trace:
146 146
diff --git a/tools/perf/Documentation/perf-test.txt b/tools/perf/Documentation/perf-test.txt
index d1d3e5121f89..31a5c3ea7f74 100644
--- a/tools/perf/Documentation/perf-test.txt
+++ b/tools/perf/Documentation/perf-test.txt
@@ -25,7 +25,7 @@ OPTIONS
25------- 25-------
26-s:: 26-s::
27--skip:: 27--skip::
28 Tests to skip (comma separater numeric list). 28 Tests to skip (comma separated numeric list).
29 29
30-v:: 30-v::
31--verbose:: 31--verbose::
diff --git a/tools/perf/Documentation/perf-trace.txt b/tools/perf/Documentation/perf-trace.txt
index 02aac831bdd9..7e1b1f2bb83c 100644
--- a/tools/perf/Documentation/perf-trace.txt
+++ b/tools/perf/Documentation/perf-trace.txt
@@ -20,7 +20,7 @@ scheduling events, etc.
20This is a live mode tool in addition to working with perf.data files like 20This is a live mode tool in addition to working with perf.data files like
21the other perf tools. Files can be generated using the 'perf record' command 21the other perf tools. Files can be generated using the 'perf record' command
22but the session needs to include the raw_syscalls events (-e 'raw_syscalls:*'). 22but the session needs to include the raw_syscalls events (-e 'raw_syscalls:*').
23Alernatively, the 'perf trace record' can be used as a shortcut to 23Alternatively, 'perf trace record' can be used as a shortcut to
24automatically include the raw_syscalls events when writing events to a file. 24automatically include the raw_syscalls events when writing events to a file.
25 25
26The following options apply to perf trace; options to perf trace record are 26The following options apply to perf trace; options to perf trace record are
diff --git a/tools/perf/builtin-annotate.c b/tools/perf/builtin-annotate.c
index be5939418425..e7417fe97a97 100644
--- a/tools/perf/builtin-annotate.c
+++ b/tools/perf/builtin-annotate.c
@@ -51,6 +51,7 @@ static int perf_evsel__add_sample(struct perf_evsel *evsel,
51 struct addr_location *al, 51 struct addr_location *al,
52 struct perf_annotate *ann) 52 struct perf_annotate *ann)
53{ 53{
54 struct hists *hists = evsel__hists(evsel);
54 struct hist_entry *he; 55 struct hist_entry *he;
55 int ret; 56 int ret;
56 57
@@ -66,13 +67,12 @@ static int perf_evsel__add_sample(struct perf_evsel *evsel,
66 return 0; 67 return 0;
67 } 68 }
68 69
69 he = __hists__add_entry(&evsel->hists, al, NULL, NULL, NULL, 1, 1, 0, 70 he = __hists__add_entry(hists, al, NULL, NULL, NULL, 1, 1, 0, true);
70 true);
71 if (he == NULL) 71 if (he == NULL)
72 return -ENOMEM; 72 return -ENOMEM;
73 73
74 ret = hist_entry__inc_addr_samples(he, evsel->idx, al->addr); 74 ret = hist_entry__inc_addr_samples(he, evsel->idx, al->addr);
75 hists__inc_nr_samples(&evsel->hists, true); 75 hists__inc_nr_samples(hists, true);
76 return ret; 76 return ret;
77} 77}
78 78
@@ -214,6 +214,7 @@ static int __cmd_annotate(struct perf_annotate *ann)
214 214
215 if (dump_trace) { 215 if (dump_trace) {
216 perf_session__fprintf_nr_events(session, stdout); 216 perf_session__fprintf_nr_events(session, stdout);
217 perf_evlist__fprintf_nr_events(session->evlist, stdout);
217 goto out; 218 goto out;
218 } 219 }
219 220
@@ -225,7 +226,7 @@ static int __cmd_annotate(struct perf_annotate *ann)
225 226
226 total_nr_samples = 0; 227 total_nr_samples = 0;
227 evlist__for_each(session->evlist, pos) { 228 evlist__for_each(session->evlist, pos) {
228 struct hists *hists = &pos->hists; 229 struct hists *hists = evsel__hists(pos);
229 u32 nr_samples = hists->stats.nr_events[PERF_RECORD_SAMPLE]; 230 u32 nr_samples = hists->stats.nr_events[PERF_RECORD_SAMPLE];
230 231
231 if (nr_samples > 0) { 232 if (nr_samples > 0) {
@@ -325,7 +326,10 @@ int cmd_annotate(int argc, const char **argv, const char *prefix __maybe_unused)
325 "Show event group information together"), 326 "Show event group information together"),
326 OPT_END() 327 OPT_END()
327 }; 328 };
328 int ret; 329 int ret = hists__init();
330
331 if (ret < 0)
332 return ret;
329 333
330 argc = parse_options(argc, argv, options, annotate_usage, 0); 334 argc = parse_options(argc, argv, options, annotate_usage, 0);
331 335
diff --git a/tools/perf/builtin-diff.c b/tools/perf/builtin-diff.c
index a3ce19f7aebd..8c5c11ca8c53 100644
--- a/tools/perf/builtin-diff.c
+++ b/tools/perf/builtin-diff.c
@@ -327,6 +327,7 @@ static int diff__process_sample_event(struct perf_tool *tool __maybe_unused,
327 struct machine *machine) 327 struct machine *machine)
328{ 328{
329 struct addr_location al; 329 struct addr_location al;
330 struct hists *hists = evsel__hists(evsel);
330 331
331 if (perf_event__preprocess_sample(event, machine, &al, sample) < 0) { 332 if (perf_event__preprocess_sample(event, machine, &al, sample) < 0) {
332 pr_warning("problem processing %d event, skipping it.\n", 333 pr_warning("problem processing %d event, skipping it.\n",
@@ -334,7 +335,7 @@ static int diff__process_sample_event(struct perf_tool *tool __maybe_unused,
334 return -1; 335 return -1;
335 } 336 }
336 337
337 if (hists__add_entry(&evsel->hists, &al, sample->period, 338 if (hists__add_entry(hists, &al, sample->period,
338 sample->weight, sample->transaction)) { 339 sample->weight, sample->transaction)) {
339 pr_warning("problem incrementing symbol period, skipping event\n"); 340 pr_warning("problem incrementing symbol period, skipping event\n");
340 return -1; 341 return -1;
@@ -346,9 +347,9 @@ static int diff__process_sample_event(struct perf_tool *tool __maybe_unused,
346 * hists__output_resort() and precompute needs the total 347 * hists__output_resort() and precompute needs the total
347 * period in order to sort entries by percentage delta. 348 * period in order to sort entries by percentage delta.
348 */ 349 */
349 evsel->hists.stats.total_period += sample->period; 350 hists->stats.total_period += sample->period;
350 if (!al.filtered) 351 if (!al.filtered)
351 evsel->hists.stats.total_non_filtered_period += sample->period; 352 hists->stats.total_non_filtered_period += sample->period;
352 353
353 return 0; 354 return 0;
354} 355}
@@ -382,7 +383,7 @@ static void perf_evlist__collapse_resort(struct perf_evlist *evlist)
382 struct perf_evsel *evsel; 383 struct perf_evsel *evsel;
383 384
384 evlist__for_each(evlist, evsel) { 385 evlist__for_each(evlist, evsel) {
385 struct hists *hists = &evsel->hists; 386 struct hists *hists = evsel__hists(evsel);
386 387
387 hists__collapse_resort(hists, NULL); 388 hists__collapse_resort(hists, NULL);
388 } 389 }
@@ -631,24 +632,26 @@ static void data_process(void)
631 bool first = true; 632 bool first = true;
632 633
633 evlist__for_each(evlist_base, evsel_base) { 634 evlist__for_each(evlist_base, evsel_base) {
635 struct hists *hists_base = evsel__hists(evsel_base);
634 struct data__file *d; 636 struct data__file *d;
635 int i; 637 int i;
636 638
637 data__for_each_file_new(i, d) { 639 data__for_each_file_new(i, d) {
638 struct perf_evlist *evlist = d->session->evlist; 640 struct perf_evlist *evlist = d->session->evlist;
639 struct perf_evsel *evsel; 641 struct perf_evsel *evsel;
642 struct hists *hists;
640 643
641 evsel = evsel_match(evsel_base, evlist); 644 evsel = evsel_match(evsel_base, evlist);
642 if (!evsel) 645 if (!evsel)
643 continue; 646 continue;
644 647
645 d->hists = &evsel->hists; 648 hists = evsel__hists(evsel);
649 d->hists = hists;
646 650
647 hists__match(&evsel_base->hists, &evsel->hists); 651 hists__match(hists_base, hists);
648 652
649 if (!show_baseline_only) 653 if (!show_baseline_only)
650 hists__link(&evsel_base->hists, 654 hists__link(hists_base, hists);
651 &evsel->hists);
652 } 655 }
653 656
654 fprintf(stdout, "%s# Event '%s'\n#\n", first ? "" : "\n", 657 fprintf(stdout, "%s# Event '%s'\n#\n", first ? "" : "\n",
@@ -659,7 +662,7 @@ static void data_process(void)
659 if (verbose || data__files_cnt > 2) 662 if (verbose || data__files_cnt > 2)
660 data__fprintf(); 663 data__fprintf();
661 664
662 hists__process(&evsel_base->hists); 665 hists__process(hists_base);
663 } 666 }
664} 667}
665 668
diff --git a/tools/perf/builtin-kvm.c b/tools/perf/builtin-kvm.c
index d8bf2271f4ea..b65eb0507b38 100644
--- a/tools/perf/builtin-kvm.c
+++ b/tools/perf/builtin-kvm.c
@@ -376,7 +376,7 @@ struct vcpu_event_record *per_vcpu_record(struct thread *thread,
376 struct perf_sample *sample) 376 struct perf_sample *sample)
377{ 377{
378 /* Only kvm_entry records vcpu id. */ 378 /* Only kvm_entry records vcpu id. */
379 if (!thread->priv && kvm_entry_event(evsel)) { 379 if (!thread__priv(thread) && kvm_entry_event(evsel)) {
380 struct vcpu_event_record *vcpu_record; 380 struct vcpu_event_record *vcpu_record;
381 381
382 vcpu_record = zalloc(sizeof(*vcpu_record)); 382 vcpu_record = zalloc(sizeof(*vcpu_record));
@@ -386,10 +386,10 @@ struct vcpu_event_record *per_vcpu_record(struct thread *thread,
386 } 386 }
387 387
388 vcpu_record->vcpu_id = perf_evsel__intval(evsel, sample, VCPU_ID); 388 vcpu_record->vcpu_id = perf_evsel__intval(evsel, sample, VCPU_ID);
389 thread->priv = vcpu_record; 389 thread__set_priv(thread, vcpu_record);
390 } 390 }
391 391
392 return thread->priv; 392 return thread__priv(thread);
393} 393}
394 394
395static bool handle_kvm_event(struct perf_kvm_stat *kvm, 395static bool handle_kvm_event(struct perf_kvm_stat *kvm,
@@ -896,8 +896,7 @@ static int perf_kvm__handle_stdin(void)
896 896
897static int kvm_events_live_report(struct perf_kvm_stat *kvm) 897static int kvm_events_live_report(struct perf_kvm_stat *kvm)
898{ 898{
899 struct pollfd *pollfds = NULL; 899 int nr_stdin, ret, err = -EINVAL;
900 int nr_fds, nr_stdin, ret, err = -EINVAL;
901 struct termios save; 900 struct termios save;
902 901
903 /* live flag must be set first */ 902 /* live flag must be set first */
@@ -919,34 +918,27 @@ static int kvm_events_live_report(struct perf_kvm_stat *kvm)
919 signal(SIGINT, sig_handler); 918 signal(SIGINT, sig_handler);
920 signal(SIGTERM, sig_handler); 919 signal(SIGTERM, sig_handler);
921 920
922 /* use pollfds -- need to add timerfd and stdin */
923 nr_fds = kvm->evlist->pollfd.nr;
924
925 /* add timer fd */ 921 /* add timer fd */
926 if (perf_kvm__timerfd_create(kvm) < 0) { 922 if (perf_kvm__timerfd_create(kvm) < 0) {
927 err = -1; 923 err = -1;
928 goto out; 924 goto out;
929 } 925 }
930 926
931 if (perf_evlist__add_pollfd(kvm->evlist, kvm->timerfd)) 927 if (perf_evlist__add_pollfd(kvm->evlist, kvm->timerfd) < 0)
932 goto out; 928 goto out;
933 929
934 nr_fds++; 930 nr_stdin = perf_evlist__add_pollfd(kvm->evlist, fileno(stdin));
935 931 if (nr_stdin < 0)
936 if (perf_evlist__add_pollfd(kvm->evlist, fileno(stdin)))
937 goto out; 932 goto out;
938 933
939 nr_stdin = nr_fds;
940 nr_fds++;
941 if (fd_set_nonblock(fileno(stdin)) != 0) 934 if (fd_set_nonblock(fileno(stdin)) != 0)
942 goto out; 935 goto out;
943 936
944 pollfds = kvm->evlist->pollfd.entries;
945
946 /* everything is good - enable the events and process */ 937 /* everything is good - enable the events and process */
947 perf_evlist__enable(kvm->evlist); 938 perf_evlist__enable(kvm->evlist);
948 939
949 while (!done) { 940 while (!done) {
941 struct fdarray *fda = &kvm->evlist->pollfd;
950 int rc; 942 int rc;
951 943
952 rc = perf_kvm__mmap_read(kvm); 944 rc = perf_kvm__mmap_read(kvm);
@@ -957,11 +949,11 @@ static int kvm_events_live_report(struct perf_kvm_stat *kvm)
957 if (err) 949 if (err)
958 goto out; 950 goto out;
959 951
960 if (pollfds[nr_stdin].revents & POLLIN) 952 if (fda->entries[nr_stdin].revents & POLLIN)
961 done = perf_kvm__handle_stdin(); 953 done = perf_kvm__handle_stdin();
962 954
963 if (!rc && !done) 955 if (!rc && !done)
964 err = poll(pollfds, nr_fds, 100); 956 err = fdarray__poll(fda, 100);
965 } 957 }
966 958
967 perf_evlist__disable(kvm->evlist); 959 perf_evlist__disable(kvm->evlist);
@@ -1366,6 +1358,7 @@ static int kvm_events_live(struct perf_kvm_stat *kvm,
1366 } 1358 }
1367 kvm->session->evlist = kvm->evlist; 1359 kvm->session->evlist = kvm->evlist;
1368 perf_session__set_id_hdr_size(kvm->session); 1360 perf_session__set_id_hdr_size(kvm->session);
1361 ordered_events__set_copy_on_queue(&kvm->session->ordered_events, true);
1369 machine__synthesize_threads(&kvm->session->machines.host, &kvm->opts.target, 1362 machine__synthesize_threads(&kvm->session->machines.host, &kvm->opts.target,
1370 kvm->evlist->threads, false); 1363 kvm->evlist->threads, false);
1371 err = kvm_live_open_events(kvm); 1364 err = kvm_live_open_events(kvm);
diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c
index 44c6f3d55ce7..2583a9b04317 100644
--- a/tools/perf/builtin-record.c
+++ b/tools/perf/builtin-record.c
@@ -14,6 +14,8 @@
14#include "util/parse-options.h" 14#include "util/parse-options.h"
15#include "util/parse-events.h" 15#include "util/parse-events.h"
16 16
17#include "util/callchain.h"
18#include "util/cgroup.h"
17#include "util/header.h" 19#include "util/header.h"
18#include "util/event.h" 20#include "util/event.h"
19#include "util/evlist.h" 21#include "util/evlist.h"
diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c
index ac145fae0521..140a6cd88351 100644
--- a/tools/perf/builtin-report.c
+++ b/tools/perf/builtin-report.c
@@ -257,6 +257,13 @@ static int report__setup_sample_type(struct report *rep)
257 } 257 }
258 } 258 }
259 259
260 if (symbol_conf.use_callchain || symbol_conf.cumulate_callchain) {
261 if ((sample_type & PERF_SAMPLE_REGS_USER) &&
262 (sample_type & PERF_SAMPLE_STACK_USER))
263 callchain_param.record_mode = CALLCHAIN_DWARF;
264 else
265 callchain_param.record_mode = CALLCHAIN_FP;
266 }
260 return 0; 267 return 0;
261} 268}
262 269
@@ -288,12 +295,14 @@ static size_t hists__fprintf_nr_sample_events(struct hists *hists, struct report
288 evname = buf; 295 evname = buf;
289 296
290 for_each_group_member(pos, evsel) { 297 for_each_group_member(pos, evsel) {
298 const struct hists *pos_hists = evsel__hists(pos);
299
291 if (symbol_conf.filter_relative) { 300 if (symbol_conf.filter_relative) {
292 nr_samples += pos->hists.stats.nr_non_filtered_samples; 301 nr_samples += pos_hists->stats.nr_non_filtered_samples;
293 nr_events += pos->hists.stats.total_non_filtered_period; 302 nr_events += pos_hists->stats.total_non_filtered_period;
294 } else { 303 } else {
295 nr_samples += pos->hists.stats.nr_events[PERF_RECORD_SAMPLE]; 304 nr_samples += pos_hists->stats.nr_events[PERF_RECORD_SAMPLE];
296 nr_events += pos->hists.stats.total_period; 305 nr_events += pos_hists->stats.total_period;
297 } 306 }
298 } 307 }
299 } 308 }
@@ -318,7 +327,7 @@ static int perf_evlist__tty_browse_hists(struct perf_evlist *evlist,
318 struct perf_evsel *pos; 327 struct perf_evsel *pos;
319 328
320 evlist__for_each(evlist, pos) { 329 evlist__for_each(evlist, pos) {
321 struct hists *hists = &pos->hists; 330 struct hists *hists = evsel__hists(pos);
322 const char *evname = perf_evsel__name(pos); 331 const char *evname = perf_evsel__name(pos);
323 332
324 if (symbol_conf.event_group && 333 if (symbol_conf.event_group &&
@@ -427,7 +436,7 @@ static void report__collapse_hists(struct report *rep)
427 ui_progress__init(&prog, rep->nr_entries, "Merging related events..."); 436 ui_progress__init(&prog, rep->nr_entries, "Merging related events...");
428 437
429 evlist__for_each(rep->session->evlist, pos) { 438 evlist__for_each(rep->session->evlist, pos) {
430 struct hists *hists = &pos->hists; 439 struct hists *hists = evsel__hists(pos);
431 440
432 if (pos->idx == 0) 441 if (pos->idx == 0)
433 hists->symbol_filter_str = rep->symbol_filter_str; 442 hists->symbol_filter_str = rep->symbol_filter_str;
@@ -437,7 +446,7 @@ static void report__collapse_hists(struct report *rep)
437 /* Non-group events are considered as leader */ 446 /* Non-group events are considered as leader */
438 if (symbol_conf.event_group && 447 if (symbol_conf.event_group &&
439 !perf_evsel__is_group_leader(pos)) { 448 !perf_evsel__is_group_leader(pos)) {
440 struct hists *leader_hists = &pos->leader->hists; 449 struct hists *leader_hists = evsel__hists(pos->leader);
441 450
442 hists__match(leader_hists, hists); 451 hists__match(leader_hists, hists);
443 hists__link(leader_hists, hists); 452 hists__link(leader_hists, hists);
@@ -485,6 +494,7 @@ static int __cmd_report(struct report *rep)
485 494
486 if (dump_trace) { 495 if (dump_trace) {
487 perf_session__fprintf_nr_events(session, stdout); 496 perf_session__fprintf_nr_events(session, stdout);
497 perf_evlist__fprintf_nr_events(session->evlist, stdout);
488 return 0; 498 return 0;
489 } 499 }
490 } 500 }
@@ -500,7 +510,7 @@ static int __cmd_report(struct report *rep)
500 } 510 }
501 511
502 evlist__for_each(session->evlist, pos) 512 evlist__for_each(session->evlist, pos)
503 hists__output_resort(&pos->hists); 513 hists__output_resort(evsel__hists(pos));
504 514
505 return report__browse_hists(rep); 515 return report__browse_hists(rep);
506} 516}
@@ -565,7 +575,6 @@ int cmd_report(int argc, const char **argv, const char *prefix __maybe_unused)
565 struct stat st; 575 struct stat st;
566 bool has_br_stack = false; 576 bool has_br_stack = false;
567 int branch_mode = -1; 577 int branch_mode = -1;
568 int ret = -1;
569 char callchain_default_opt[] = "fractal,0.5,callee"; 578 char callchain_default_opt[] = "fractal,0.5,callee";
570 const char * const report_usage[] = { 579 const char * const report_usage[] = {
571 "perf report [<options>]", 580 "perf report [<options>]",
@@ -692,6 +701,10 @@ int cmd_report(int argc, const char **argv, const char *prefix __maybe_unused)
692 struct perf_data_file file = { 701 struct perf_data_file file = {
693 .mode = PERF_DATA_MODE_READ, 702 .mode = PERF_DATA_MODE_READ,
694 }; 703 };
704 int ret = hists__init();
705
706 if (ret < 0)
707 return ret;
695 708
696 perf_config(report__config, &report); 709 perf_config(report__config, &report);
697 710
diff --git a/tools/perf/builtin-sched.c b/tools/perf/builtin-sched.c
index 9c9287fbf8e9..891c3930080e 100644
--- a/tools/perf/builtin-sched.c
+++ b/tools/perf/builtin-sched.c
@@ -1431,9 +1431,6 @@ static int perf_sched__process_tracepoint_sample(struct perf_tool *tool __maybe_
1431{ 1431{
1432 int err = 0; 1432 int err = 0;
1433 1433
1434 evsel->hists.stats.total_period += sample->period;
1435 hists__inc_nr_samples(&evsel->hists, true);
1436
1437 if (evsel->handler != NULL) { 1434 if (evsel->handler != NULL) {
1438 tracepoint_handler f = evsel->handler; 1435 tracepoint_handler f = evsel->handler;
1439 err = f(tool, evsel, sample, machine); 1436 err = f(tool, evsel, sample, machine);
diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c
index b9b9e58a6c39..9708a1290571 100644
--- a/tools/perf/builtin-script.c
+++ b/tools/perf/builtin-script.c
@@ -44,6 +44,7 @@ enum perf_output_field {
44 PERF_OUTPUT_ADDR = 1U << 10, 44 PERF_OUTPUT_ADDR = 1U << 10,
45 PERF_OUTPUT_SYMOFFSET = 1U << 11, 45 PERF_OUTPUT_SYMOFFSET = 1U << 11,
46 PERF_OUTPUT_SRCLINE = 1U << 12, 46 PERF_OUTPUT_SRCLINE = 1U << 12,
47 PERF_OUTPUT_PERIOD = 1U << 13,
47}; 48};
48 49
49struct output_option { 50struct output_option {
@@ -63,6 +64,7 @@ struct output_option {
63 {.str = "addr", .field = PERF_OUTPUT_ADDR}, 64 {.str = "addr", .field = PERF_OUTPUT_ADDR},
64 {.str = "symoff", .field = PERF_OUTPUT_SYMOFFSET}, 65 {.str = "symoff", .field = PERF_OUTPUT_SYMOFFSET},
65 {.str = "srcline", .field = PERF_OUTPUT_SRCLINE}, 66 {.str = "srcline", .field = PERF_OUTPUT_SRCLINE},
67 {.str = "period", .field = PERF_OUTPUT_PERIOD},
66}; 68};
67 69
68/* default set to maintain compatibility with current format */ 70/* default set to maintain compatibility with current format */
@@ -80,7 +82,8 @@ static struct {
80 .fields = PERF_OUTPUT_COMM | PERF_OUTPUT_TID | 82 .fields = PERF_OUTPUT_COMM | PERF_OUTPUT_TID |
81 PERF_OUTPUT_CPU | PERF_OUTPUT_TIME | 83 PERF_OUTPUT_CPU | PERF_OUTPUT_TIME |
82 PERF_OUTPUT_EVNAME | PERF_OUTPUT_IP | 84 PERF_OUTPUT_EVNAME | PERF_OUTPUT_IP |
83 PERF_OUTPUT_SYM | PERF_OUTPUT_DSO, 85 PERF_OUTPUT_SYM | PERF_OUTPUT_DSO |
86 PERF_OUTPUT_PERIOD,
84 87
85 .invalid_fields = PERF_OUTPUT_TRACE, 88 .invalid_fields = PERF_OUTPUT_TRACE,
86 }, 89 },
@@ -91,7 +94,8 @@ static struct {
91 .fields = PERF_OUTPUT_COMM | PERF_OUTPUT_TID | 94 .fields = PERF_OUTPUT_COMM | PERF_OUTPUT_TID |
92 PERF_OUTPUT_CPU | PERF_OUTPUT_TIME | 95 PERF_OUTPUT_CPU | PERF_OUTPUT_TIME |
93 PERF_OUTPUT_EVNAME | PERF_OUTPUT_IP | 96 PERF_OUTPUT_EVNAME | PERF_OUTPUT_IP |
94 PERF_OUTPUT_SYM | PERF_OUTPUT_DSO, 97 PERF_OUTPUT_SYM | PERF_OUTPUT_DSO |
98 PERF_OUTPUT_PERIOD,
95 99
96 .invalid_fields = PERF_OUTPUT_TRACE, 100 .invalid_fields = PERF_OUTPUT_TRACE,
97 }, 101 },
@@ -110,7 +114,8 @@ static struct {
110 .fields = PERF_OUTPUT_COMM | PERF_OUTPUT_TID | 114 .fields = PERF_OUTPUT_COMM | PERF_OUTPUT_TID |
111 PERF_OUTPUT_CPU | PERF_OUTPUT_TIME | 115 PERF_OUTPUT_CPU | PERF_OUTPUT_TIME |
112 PERF_OUTPUT_EVNAME | PERF_OUTPUT_IP | 116 PERF_OUTPUT_EVNAME | PERF_OUTPUT_IP |
113 PERF_OUTPUT_SYM | PERF_OUTPUT_DSO, 117 PERF_OUTPUT_SYM | PERF_OUTPUT_DSO |
118 PERF_OUTPUT_PERIOD,
114 119
115 .invalid_fields = PERF_OUTPUT_TRACE, 120 .invalid_fields = PERF_OUTPUT_TRACE,
116 }, 121 },
@@ -229,6 +234,11 @@ static int perf_evsel__check_attr(struct perf_evsel *evsel,
229 PERF_OUTPUT_CPU)) 234 PERF_OUTPUT_CPU))
230 return -EINVAL; 235 return -EINVAL;
231 236
237 if (PRINT_FIELD(PERIOD) &&
238 perf_evsel__check_stype(evsel, PERF_SAMPLE_PERIOD, "PERIOD",
239 PERF_OUTPUT_PERIOD))
240 return -EINVAL;
241
232 return 0; 242 return 0;
233} 243}
234 244
@@ -448,6 +458,9 @@ static void process_event(union perf_event *event, struct perf_sample *sample,
448 458
449 print_sample_start(sample, thread, evsel); 459 print_sample_start(sample, thread, evsel);
450 460
461 if (PRINT_FIELD(PERIOD))
462 printf("%10" PRIu64 " ", sample->period);
463
451 if (PRINT_FIELD(EVNAME)) { 464 if (PRINT_FIELD(EVNAME)) {
452 const char *evname = perf_evsel__name(evsel); 465 const char *evname = perf_evsel__name(evsel);
453 printf("%s: ", evname ? evname : "[unknown]"); 466 printf("%s: ", evname ? evname : "[unknown]");
@@ -572,7 +585,6 @@ static int process_sample_event(struct perf_tool *tool __maybe_unused,
572 585
573 scripting_ops->process_event(event, sample, evsel, thread, &al); 586 scripting_ops->process_event(event, sample, evsel, thread, &al);
574 587
575 evsel->hists.stats.total_period += sample->period;
576 return 0; 588 return 0;
577} 589}
578 590
@@ -1544,7 +1556,7 @@ int cmd_script(int argc, const char **argv, const char *prefix __maybe_unused)
1544 "comma separated output fields prepend with 'type:'. " 1556 "comma separated output fields prepend with 'type:'. "
1545 "Valid types: hw,sw,trace,raw. " 1557 "Valid types: hw,sw,trace,raw. "
1546 "Fields: comm,tid,pid,time,cpu,event,trace,ip,sym,dso," 1558 "Fields: comm,tid,pid,time,cpu,event,trace,ip,sym,dso,"
1547 "addr,symoff", parse_output_fields), 1559 "addr,symoff,period", parse_output_fields),
1548 OPT_BOOLEAN('a', "all-cpus", &system_wide, 1560 OPT_BOOLEAN('a', "all-cpus", &system_wide,
1549 "system-wide collection from all CPUs"), 1561 "system-wide collection from all CPUs"),
1550 OPT_STRING('S', "symbols", &symbol_conf.sym_list_str, "symbol[,symbol...]", 1562 OPT_STRING('S', "symbols", &symbol_conf.sym_list_str, "symbol[,symbol...]",
diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c
index b22c62f80078..055ce9232c9e 100644
--- a/tools/perf/builtin-stat.c
+++ b/tools/perf/builtin-stat.c
@@ -43,6 +43,7 @@
43 43
44#include "perf.h" 44#include "perf.h"
45#include "builtin.h" 45#include "builtin.h"
46#include "util/cgroup.h"
46#include "util/util.h" 47#include "util/util.h"
47#include "util/parse-options.h" 48#include "util/parse-options.h"
48#include "util/parse-events.h" 49#include "util/parse-events.h"
diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c
index fc3d55f832ac..0aa7747ff139 100644
--- a/tools/perf/builtin-top.c
+++ b/tools/perf/builtin-top.c
@@ -251,6 +251,7 @@ static void perf_top__print_sym_table(struct perf_top *top)
251 char bf[160]; 251 char bf[160];
252 int printed = 0; 252 int printed = 0;
253 const int win_width = top->winsize.ws_col - 1; 253 const int win_width = top->winsize.ws_col - 1;
254 struct hists *hists = evsel__hists(top->sym_evsel);
254 255
255 puts(CONSOLE_CLEAR); 256 puts(CONSOLE_CLEAR);
256 257
@@ -261,13 +262,13 @@ static void perf_top__print_sym_table(struct perf_top *top)
261 262
262 printf("%-*.*s\n", win_width, win_width, graph_dotted_line); 263 printf("%-*.*s\n", win_width, win_width, graph_dotted_line);
263 264
264 if (top->sym_evsel->hists.stats.nr_lost_warned != 265 if (hists->stats.nr_lost_warned !=
265 top->sym_evsel->hists.stats.nr_events[PERF_RECORD_LOST]) { 266 hists->stats.nr_events[PERF_RECORD_LOST]) {
266 top->sym_evsel->hists.stats.nr_lost_warned = 267 hists->stats.nr_lost_warned =
267 top->sym_evsel->hists.stats.nr_events[PERF_RECORD_LOST]; 268 hists->stats.nr_events[PERF_RECORD_LOST];
268 color_fprintf(stdout, PERF_COLOR_RED, 269 color_fprintf(stdout, PERF_COLOR_RED,
269 "WARNING: LOST %d chunks, Check IO/CPU overload", 270 "WARNING: LOST %d chunks, Check IO/CPU overload",
270 top->sym_evsel->hists.stats.nr_lost_warned); 271 hists->stats.nr_lost_warned);
271 ++printed; 272 ++printed;
272 } 273 }
273 274
@@ -277,21 +278,18 @@ static void perf_top__print_sym_table(struct perf_top *top)
277 } 278 }
278 279
279 if (top->zero) { 280 if (top->zero) {
280 hists__delete_entries(&top->sym_evsel->hists); 281 hists__delete_entries(hists);
281 } else { 282 } else {
282 hists__decay_entries(&top->sym_evsel->hists, 283 hists__decay_entries(hists, top->hide_user_symbols,
283 top->hide_user_symbols,
284 top->hide_kernel_symbols); 284 top->hide_kernel_symbols);
285 } 285 }
286 286
287 hists__collapse_resort(&top->sym_evsel->hists, NULL); 287 hists__collapse_resort(hists, NULL);
288 hists__output_resort(&top->sym_evsel->hists); 288 hists__output_resort(hists);
289 289
290 hists__output_recalc_col_len(&top->sym_evsel->hists, 290 hists__output_recalc_col_len(hists, top->print_entries - printed);
291 top->print_entries - printed);
292 putchar('\n'); 291 putchar('\n');
293 hists__fprintf(&top->sym_evsel->hists, false, 292 hists__fprintf(hists, false, top->print_entries - printed, win_width,
294 top->print_entries - printed, win_width,
295 top->min_percent, stdout); 293 top->min_percent, stdout);
296} 294}
297 295
@@ -334,6 +332,7 @@ static void perf_top__prompt_symbol(struct perf_top *top, const char *msg)
334{ 332{
335 char *buf = malloc(0), *p; 333 char *buf = malloc(0), *p;
336 struct hist_entry *syme = top->sym_filter_entry, *n, *found = NULL; 334 struct hist_entry *syme = top->sym_filter_entry, *n, *found = NULL;
335 struct hists *hists = evsel__hists(top->sym_evsel);
337 struct rb_node *next; 336 struct rb_node *next;
338 size_t dummy = 0; 337 size_t dummy = 0;
339 338
@@ -351,7 +350,7 @@ static void perf_top__prompt_symbol(struct perf_top *top, const char *msg)
351 if (p) 350 if (p)
352 *p = 0; 351 *p = 0;
353 352
354 next = rb_first(&top->sym_evsel->hists.entries); 353 next = rb_first(&hists->entries);
355 while (next) { 354 while (next) {
356 n = rb_entry(next, struct hist_entry, rb_node); 355 n = rb_entry(next, struct hist_entry, rb_node);
357 if (n->ms.sym && !strcmp(buf, n->ms.sym->name)) { 356 if (n->ms.sym && !strcmp(buf, n->ms.sym->name)) {
@@ -538,21 +537,24 @@ static bool perf_top__handle_keypress(struct perf_top *top, int c)
538static void perf_top__sort_new_samples(void *arg) 537static void perf_top__sort_new_samples(void *arg)
539{ 538{
540 struct perf_top *t = arg; 539 struct perf_top *t = arg;
540 struct hists *hists;
541
541 perf_top__reset_sample_counters(t); 542 perf_top__reset_sample_counters(t);
542 543
543 if (t->evlist->selected != NULL) 544 if (t->evlist->selected != NULL)
544 t->sym_evsel = t->evlist->selected; 545 t->sym_evsel = t->evlist->selected;
545 546
547 hists = evsel__hists(t->sym_evsel);
548
546 if (t->zero) { 549 if (t->zero) {
547 hists__delete_entries(&t->sym_evsel->hists); 550 hists__delete_entries(hists);
548 } else { 551 } else {
549 hists__decay_entries(&t->sym_evsel->hists, 552 hists__decay_entries(hists, t->hide_user_symbols,
550 t->hide_user_symbols,
551 t->hide_kernel_symbols); 553 t->hide_kernel_symbols);
552 } 554 }
553 555
554 hists__collapse_resort(&t->sym_evsel->hists, NULL); 556 hists__collapse_resort(hists, NULL);
555 hists__output_resort(&t->sym_evsel->hists); 557 hists__output_resort(hists);
556} 558}
557 559
558static void *display_thread_tui(void *arg) 560static void *display_thread_tui(void *arg)
@@ -573,8 +575,10 @@ static void *display_thread_tui(void *arg)
573 * Zooming in/out UIDs. For now juse use whatever the user passed 575 * Zooming in/out UIDs. For now juse use whatever the user passed
574 * via --uid. 576 * via --uid.
575 */ 577 */
576 evlist__for_each(top->evlist, pos) 578 evlist__for_each(top->evlist, pos) {
577 pos->hists.uid_filter_str = top->record_opts.target.uid_str; 579 struct hists *hists = evsel__hists(pos);
580 hists->uid_filter_str = top->record_opts.target.uid_str;
581 }
578 582
579 perf_evlist__tui_browse_hists(top->evlist, help, &hbt, top->min_percent, 583 perf_evlist__tui_browse_hists(top->evlist, help, &hbt, top->min_percent,
580 &top->session->header.env); 584 &top->session->header.env);
@@ -768,6 +772,7 @@ static void perf_event__process_sample(struct perf_tool *tool,
768 } 772 }
769 773
770 if (al.sym == NULL || !al.sym->ignore) { 774 if (al.sym == NULL || !al.sym->ignore) {
775 struct hists *hists = evsel__hists(evsel);
771 struct hist_entry_iter iter = { 776 struct hist_entry_iter iter = {
772 .add_entry_cb = hist_iter__top_callback, 777 .add_entry_cb = hist_iter__top_callback,
773 }; 778 };
@@ -777,14 +782,14 @@ static void perf_event__process_sample(struct perf_tool *tool,
777 else 782 else
778 iter.ops = &hist_iter_normal; 783 iter.ops = &hist_iter_normal;
779 784
780 pthread_mutex_lock(&evsel->hists.lock); 785 pthread_mutex_lock(&hists->lock);
781 786
782 err = hist_entry_iter__add(&iter, &al, evsel, sample, 787 err = hist_entry_iter__add(&iter, &al, evsel, sample,
783 top->max_stack, top); 788 top->max_stack, top);
784 if (err < 0) 789 if (err < 0)
785 pr_err("Problem incrementing symbol period, skipping event\n"); 790 pr_err("Problem incrementing symbol period, skipping event\n");
786 791
787 pthread_mutex_unlock(&evsel->hists.lock); 792 pthread_mutex_unlock(&hists->lock);
788 } 793 }
789 794
790 return; 795 return;
@@ -849,7 +854,7 @@ static void perf_top__mmap_read_idx(struct perf_top *top, int idx)
849 perf_event__process_sample(&top->tool, event, evsel, 854 perf_event__process_sample(&top->tool, event, evsel,
850 &sample, machine); 855 &sample, machine);
851 } else if (event->header.type < PERF_RECORD_MAX) { 856 } else if (event->header.type < PERF_RECORD_MAX) {
852 hists__inc_nr_events(&evsel->hists, event->header.type); 857 hists__inc_nr_events(evsel__hists(evsel), event->header.type);
853 machine__process_event(machine, event, &sample); 858 machine__process_event(machine, event, &sample);
854 } else 859 } else
855 ++session->stats.nr_unknown_events; 860 ++session->stats.nr_unknown_events;
@@ -1042,7 +1047,6 @@ parse_percent_limit(const struct option *opt, const char *arg,
1042 1047
1043int cmd_top(int argc, const char **argv, const char *prefix __maybe_unused) 1048int cmd_top(int argc, const char **argv, const char *prefix __maybe_unused)
1044{ 1049{
1045 int status = -1;
1046 char errbuf[BUFSIZ]; 1050 char errbuf[BUFSIZ];
1047 struct perf_top top = { 1051 struct perf_top top = {
1048 .count_filter = 5, 1052 .count_filter = 5,
@@ -1160,6 +1164,10 @@ int cmd_top(int argc, const char **argv, const char *prefix __maybe_unused)
1160 "perf top [<options>]", 1164 "perf top [<options>]",
1161 NULL 1165 NULL
1162 }; 1166 };
1167 int status = hists__init();
1168
1169 if (status < 0)
1170 return status;
1163 1171
1164 top.evlist = perf_evlist__new(); 1172 top.evlist = perf_evlist__new();
1165 if (top.evlist == NULL) 1173 if (top.evlist == NULL)
diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c
index 09bcf2393910..fb126459b134 100644
--- a/tools/perf/builtin-trace.c
+++ b/tools/perf/builtin-trace.c
@@ -1189,13 +1189,13 @@ static struct thread_trace *thread__trace(struct thread *thread, FILE *fp)
1189 if (thread == NULL) 1189 if (thread == NULL)
1190 goto fail; 1190 goto fail;
1191 1191
1192 if (thread->priv == NULL) 1192 if (thread__priv(thread) == NULL)
1193 thread->priv = thread_trace__new(); 1193 thread__set_priv(thread, thread_trace__new());
1194 1194
1195 if (thread->priv == NULL) 1195 if (thread__priv(thread) == NULL)
1196 goto fail; 1196 goto fail;
1197 1197
1198 ttrace = thread->priv; 1198 ttrace = thread__priv(thread);
1199 ++ttrace->nr_events; 1199 ++ttrace->nr_events;
1200 1200
1201 return ttrace; 1201 return ttrace;
@@ -1248,7 +1248,7 @@ struct trace {
1248 1248
1249static int trace__set_fd_pathname(struct thread *thread, int fd, const char *pathname) 1249static int trace__set_fd_pathname(struct thread *thread, int fd, const char *pathname)
1250{ 1250{
1251 struct thread_trace *ttrace = thread->priv; 1251 struct thread_trace *ttrace = thread__priv(thread);
1252 1252
1253 if (fd > ttrace->paths.max) { 1253 if (fd > ttrace->paths.max) {
1254 char **npath = realloc(ttrace->paths.table, (fd + 1) * sizeof(char *)); 1254 char **npath = realloc(ttrace->paths.table, (fd + 1) * sizeof(char *));
@@ -1301,7 +1301,7 @@ static int thread__read_fd_path(struct thread *thread, int fd)
1301static const char *thread__fd_path(struct thread *thread, int fd, 1301static const char *thread__fd_path(struct thread *thread, int fd,
1302 struct trace *trace) 1302 struct trace *trace)
1303{ 1303{
1304 struct thread_trace *ttrace = thread->priv; 1304 struct thread_trace *ttrace = thread__priv(thread);
1305 1305
1306 if (ttrace == NULL) 1306 if (ttrace == NULL)
1307 return NULL; 1307 return NULL;
@@ -1338,7 +1338,7 @@ static size_t syscall_arg__scnprintf_close_fd(char *bf, size_t size,
1338{ 1338{
1339 int fd = arg->val; 1339 int fd = arg->val;
1340 size_t printed = syscall_arg__scnprintf_fd(bf, size, arg); 1340 size_t printed = syscall_arg__scnprintf_fd(bf, size, arg);
1341 struct thread_trace *ttrace = arg->thread->priv; 1341 struct thread_trace *ttrace = thread__priv(arg->thread);
1342 1342
1343 if (ttrace && fd >= 0 && fd <= ttrace->paths.max) 1343 if (ttrace && fd >= 0 && fd <= ttrace->paths.max)
1344 zfree(&ttrace->paths.table[fd]); 1344 zfree(&ttrace->paths.table[fd]);
@@ -2381,7 +2381,7 @@ static int trace__fprintf_one_thread(struct thread *thread, void *priv)
2381 FILE *fp = data->fp; 2381 FILE *fp = data->fp;
2382 size_t printed = data->printed; 2382 size_t printed = data->printed;
2383 struct trace *trace = data->trace; 2383 struct trace *trace = data->trace;
2384 struct thread_trace *ttrace = thread->priv; 2384 struct thread_trace *ttrace = thread__priv(thread);
2385 double ratio; 2385 double ratio;
2386 2386
2387 if (ttrace == NULL) 2387 if (ttrace == NULL)
diff --git a/tools/perf/tests/builtin-test.c b/tools/perf/tests/builtin-test.c
index ac655b0700e7..162c978f1491 100644
--- a/tools/perf/tests/builtin-test.c
+++ b/tools/perf/tests/builtin-test.c
@@ -6,6 +6,7 @@
6#include <unistd.h> 6#include <unistd.h>
7#include <string.h> 7#include <string.h>
8#include "builtin.h" 8#include "builtin.h"
9#include "hist.h"
9#include "intlist.h" 10#include "intlist.h"
10#include "tests.h" 11#include "tests.h"
11#include "debug.h" 12#include "debug.h"
@@ -302,6 +303,10 @@ int cmd_test(int argc, const char **argv, const char *prefix __maybe_unused)
302 OPT_END() 303 OPT_END()
303 }; 304 };
304 struct intlist *skiplist = NULL; 305 struct intlist *skiplist = NULL;
306 int ret = hists__init();
307
308 if (ret < 0)
309 return ret;
305 310
306 argc = parse_options(argc, argv, test_options, test_usage, 0); 311 argc = parse_options(argc, argv, test_options, test_usage, 0);
307 if (argc >= 1 && !strcmp(argv[0], "list")) 312 if (argc >= 1 && !strcmp(argv[0], "list"))
diff --git a/tools/perf/tests/dwarf-unwind.c b/tools/perf/tests/dwarf-unwind.c
index 96adb730b744..fc25e57f4a5d 100644
--- a/tools/perf/tests/dwarf-unwind.c
+++ b/tools/perf/tests/dwarf-unwind.c
@@ -9,6 +9,7 @@
9#include "perf_regs.h" 9#include "perf_regs.h"
10#include "map.h" 10#include "map.h"
11#include "thread.h" 11#include "thread.h"
12#include "callchain.h"
12 13
13static int mmap_handler(struct perf_tool *tool __maybe_unused, 14static int mmap_handler(struct perf_tool *tool __maybe_unused,
14 union perf_event *event, 15 union perf_event *event,
@@ -120,6 +121,8 @@ int test__dwarf_unwind(void)
120 return -1; 121 return -1;
121 } 122 }
122 123
124 callchain_param.record_mode = CALLCHAIN_DWARF;
125
123 if (init_live_machine(machine)) { 126 if (init_live_machine(machine)) {
124 pr_err("Could not init machine\n"); 127 pr_err("Could not init machine\n");
125 goto out; 128 goto out;
diff --git a/tools/perf/tests/hists_cumulate.c b/tools/perf/tests/hists_cumulate.c
index 0ac240db2e24..614d5c4978ab 100644
--- a/tools/perf/tests/hists_cumulate.c
+++ b/tools/perf/tests/hists_cumulate.c
@@ -245,7 +245,7 @@ static int do_test(struct hists *hists, struct result *expected, size_t nr_expec
245static int test1(struct perf_evsel *evsel, struct machine *machine) 245static int test1(struct perf_evsel *evsel, struct machine *machine)
246{ 246{
247 int err; 247 int err;
248 struct hists *hists = &evsel->hists; 248 struct hists *hists = evsel__hists(evsel);
249 /* 249 /*
250 * expected output: 250 * expected output:
251 * 251 *
@@ -295,7 +295,7 @@ out:
295static int test2(struct perf_evsel *evsel, struct machine *machine) 295static int test2(struct perf_evsel *evsel, struct machine *machine)
296{ 296{
297 int err; 297 int err;
298 struct hists *hists = &evsel->hists; 298 struct hists *hists = evsel__hists(evsel);
299 /* 299 /*
300 * expected output: 300 * expected output:
301 * 301 *
@@ -442,7 +442,7 @@ out:
442static int test3(struct perf_evsel *evsel, struct machine *machine) 442static int test3(struct perf_evsel *evsel, struct machine *machine)
443{ 443{
444 int err; 444 int err;
445 struct hists *hists = &evsel->hists; 445 struct hists *hists = evsel__hists(evsel);
446 /* 446 /*
447 * expected output: 447 * expected output:
448 * 448 *
@@ -498,7 +498,7 @@ out:
498static int test4(struct perf_evsel *evsel, struct machine *machine) 498static int test4(struct perf_evsel *evsel, struct machine *machine)
499{ 499{
500 int err; 500 int err;
501 struct hists *hists = &evsel->hists; 501 struct hists *hists = evsel__hists(evsel);
502 /* 502 /*
503 * expected output: 503 * expected output:
504 * 504 *
diff --git a/tools/perf/tests/hists_filter.c b/tools/perf/tests/hists_filter.c
index 821f581fd930..5a31787cc6b9 100644
--- a/tools/perf/tests/hists_filter.c
+++ b/tools/perf/tests/hists_filter.c
@@ -66,11 +66,12 @@ static int add_hist_entries(struct perf_evlist *evlist,
66 .ops = &hist_iter_normal, 66 .ops = &hist_iter_normal,
67 .hide_unresolved = false, 67 .hide_unresolved = false,
68 }; 68 };
69 struct hists *hists = evsel__hists(evsel);
69 70
70 /* make sure it has no filter at first */ 71 /* make sure it has no filter at first */
71 evsel->hists.thread_filter = NULL; 72 hists->thread_filter = NULL;
72 evsel->hists.dso_filter = NULL; 73 hists->dso_filter = NULL;
73 evsel->hists.symbol_filter_str = NULL; 74 hists->symbol_filter_str = NULL;
74 75
75 sample.pid = fake_samples[i].pid; 76 sample.pid = fake_samples[i].pid;
76 sample.tid = fake_samples[i].pid; 77 sample.tid = fake_samples[i].pid;
@@ -134,7 +135,7 @@ int test__hists_filter(void)
134 goto out; 135 goto out;
135 136
136 evlist__for_each(evlist, evsel) { 137 evlist__for_each(evlist, evsel) {
137 struct hists *hists = &evsel->hists; 138 struct hists *hists = evsel__hists(evsel);
138 139
139 hists__collapse_resort(hists, NULL); 140 hists__collapse_resort(hists, NULL);
140 hists__output_resort(hists); 141 hists__output_resort(hists);
@@ -160,7 +161,7 @@ int test__hists_filter(void)
160 hists->stats.total_non_filtered_period); 161 hists->stats.total_non_filtered_period);
161 162
162 /* now applying thread filter for 'bash' */ 163 /* now applying thread filter for 'bash' */
163 evsel->hists.thread_filter = fake_samples[9].thread; 164 hists->thread_filter = fake_samples[9].thread;
164 hists__filter_by_thread(hists); 165 hists__filter_by_thread(hists);
165 166
166 if (verbose > 2) { 167 if (verbose > 2) {
@@ -185,11 +186,11 @@ int test__hists_filter(void)
185 hists->stats.total_non_filtered_period == 400); 186 hists->stats.total_non_filtered_period == 400);
186 187
187 /* remove thread filter first */ 188 /* remove thread filter first */
188 evsel->hists.thread_filter = NULL; 189 hists->thread_filter = NULL;
189 hists__filter_by_thread(hists); 190 hists__filter_by_thread(hists);
190 191
191 /* now applying dso filter for 'kernel' */ 192 /* now applying dso filter for 'kernel' */
192 evsel->hists.dso_filter = fake_samples[0].map->dso; 193 hists->dso_filter = fake_samples[0].map->dso;
193 hists__filter_by_dso(hists); 194 hists__filter_by_dso(hists);
194 195
195 if (verbose > 2) { 196 if (verbose > 2) {
@@ -214,7 +215,7 @@ int test__hists_filter(void)
214 hists->stats.total_non_filtered_period == 300); 215 hists->stats.total_non_filtered_period == 300);
215 216
216 /* remove dso filter first */ 217 /* remove dso filter first */
217 evsel->hists.dso_filter = NULL; 218 hists->dso_filter = NULL;
218 hists__filter_by_dso(hists); 219 hists__filter_by_dso(hists);
219 220
220 /* 221 /*
@@ -224,7 +225,7 @@ int test__hists_filter(void)
224 * be counted as a separate entry but the sample count and 225 * be counted as a separate entry but the sample count and
225 * total period will be remained. 226 * total period will be remained.
226 */ 227 */
227 evsel->hists.symbol_filter_str = "main"; 228 hists->symbol_filter_str = "main";
228 hists__filter_by_symbol(hists); 229 hists__filter_by_symbol(hists);
229 230
230 if (verbose > 2) { 231 if (verbose > 2) {
@@ -249,8 +250,8 @@ int test__hists_filter(void)
249 hists->stats.total_non_filtered_period == 300); 250 hists->stats.total_non_filtered_period == 300);
250 251
251 /* now applying all filters at once. */ 252 /* now applying all filters at once. */
252 evsel->hists.thread_filter = fake_samples[1].thread; 253 hists->thread_filter = fake_samples[1].thread;
253 evsel->hists.dso_filter = fake_samples[1].map->dso; 254 hists->dso_filter = fake_samples[1].map->dso;
254 hists__filter_by_thread(hists); 255 hists__filter_by_thread(hists);
255 hists__filter_by_dso(hists); 256 hists__filter_by_dso(hists);
256 257
diff --git a/tools/perf/tests/hists_link.c b/tools/perf/tests/hists_link.c
index d4b34b0f50a2..278ba8344c23 100644
--- a/tools/perf/tests/hists_link.c
+++ b/tools/perf/tests/hists_link.c
@@ -73,6 +73,8 @@ static int add_hist_entries(struct perf_evlist *evlist, struct machine *machine)
73 * "bash [libc] malloc" so total 9 entries will be in the tree. 73 * "bash [libc] malloc" so total 9 entries will be in the tree.
74 */ 74 */
75 evlist__for_each(evlist, evsel) { 75 evlist__for_each(evlist, evsel) {
76 struct hists *hists = evsel__hists(evsel);
77
76 for (k = 0; k < ARRAY_SIZE(fake_common_samples); k++) { 78 for (k = 0; k < ARRAY_SIZE(fake_common_samples); k++) {
77 const union perf_event event = { 79 const union perf_event event = {
78 .header = { 80 .header = {
@@ -87,7 +89,7 @@ static int add_hist_entries(struct perf_evlist *evlist, struct machine *machine)
87 &sample) < 0) 89 &sample) < 0)
88 goto out; 90 goto out;
89 91
90 he = __hists__add_entry(&evsel->hists, &al, NULL, 92 he = __hists__add_entry(hists, &al, NULL,
91 NULL, NULL, 1, 1, 0, true); 93 NULL, NULL, 1, 1, 0, true);
92 if (he == NULL) 94 if (he == NULL)
93 goto out; 95 goto out;
@@ -111,7 +113,7 @@ static int add_hist_entries(struct perf_evlist *evlist, struct machine *machine)
111 &sample) < 0) 113 &sample) < 0)
112 goto out; 114 goto out;
113 115
114 he = __hists__add_entry(&evsel->hists, &al, NULL, 116 he = __hists__add_entry(hists, &al, NULL,
115 NULL, NULL, 1, 1, 0, true); 117 NULL, NULL, 1, 1, 0, true);
116 if (he == NULL) 118 if (he == NULL)
117 goto out; 119 goto out;
@@ -271,6 +273,7 @@ static int validate_link(struct hists *leader, struct hists *other)
271int test__hists_link(void) 273int test__hists_link(void)
272{ 274{
273 int err = -1; 275 int err = -1;
276 struct hists *hists, *first_hists;
274 struct machines machines; 277 struct machines machines;
275 struct machine *machine = NULL; 278 struct machine *machine = NULL;
276 struct perf_evsel *evsel, *first; 279 struct perf_evsel *evsel, *first;
@@ -306,24 +309,28 @@ int test__hists_link(void)
306 goto out; 309 goto out;
307 310
308 evlist__for_each(evlist, evsel) { 311 evlist__for_each(evlist, evsel) {
309 hists__collapse_resort(&evsel->hists, NULL); 312 hists = evsel__hists(evsel);
313 hists__collapse_resort(hists, NULL);
310 314
311 if (verbose > 2) 315 if (verbose > 2)
312 print_hists_in(&evsel->hists); 316 print_hists_in(hists);
313 } 317 }
314 318
315 first = perf_evlist__first(evlist); 319 first = perf_evlist__first(evlist);
316 evsel = perf_evlist__last(evlist); 320 evsel = perf_evlist__last(evlist);
317 321
322 first_hists = evsel__hists(first);
323 hists = evsel__hists(evsel);
324
318 /* match common entries */ 325 /* match common entries */
319 hists__match(&first->hists, &evsel->hists); 326 hists__match(first_hists, hists);
320 err = validate_match(&first->hists, &evsel->hists); 327 err = validate_match(first_hists, hists);
321 if (err) 328 if (err)
322 goto out; 329 goto out;
323 330
324 /* link common and/or dummy entries */ 331 /* link common and/or dummy entries */
325 hists__link(&first->hists, &evsel->hists); 332 hists__link(first_hists, hists);
326 err = validate_link(&first->hists, &evsel->hists); 333 err = validate_link(first_hists, hists);
327 if (err) 334 if (err)
328 goto out; 335 goto out;
329 336
diff --git a/tools/perf/tests/hists_output.c b/tools/perf/tests/hists_output.c
index e3bbd6c54c1b..a748f2be1222 100644
--- a/tools/perf/tests/hists_output.c
+++ b/tools/perf/tests/hists_output.c
@@ -122,7 +122,7 @@ typedef int (*test_fn_t)(struct perf_evsel *, struct machine *);
122static int test1(struct perf_evsel *evsel, struct machine *machine) 122static int test1(struct perf_evsel *evsel, struct machine *machine)
123{ 123{
124 int err; 124 int err;
125 struct hists *hists = &evsel->hists; 125 struct hists *hists = evsel__hists(evsel);
126 struct hist_entry *he; 126 struct hist_entry *he;
127 struct rb_root *root; 127 struct rb_root *root;
128 struct rb_node *node; 128 struct rb_node *node;
@@ -159,7 +159,7 @@ static int test1(struct perf_evsel *evsel, struct machine *machine)
159 print_hists_out(hists); 159 print_hists_out(hists);
160 } 160 }
161 161
162 root = &evsel->hists.entries; 162 root = &hists->entries;
163 node = rb_first(root); 163 node = rb_first(root);
164 he = rb_entry(node, struct hist_entry, rb_node); 164 he = rb_entry(node, struct hist_entry, rb_node);
165 TEST_ASSERT_VAL("Invalid hist entry", 165 TEST_ASSERT_VAL("Invalid hist entry",
@@ -224,7 +224,7 @@ out:
224static int test2(struct perf_evsel *evsel, struct machine *machine) 224static int test2(struct perf_evsel *evsel, struct machine *machine)
225{ 225{
226 int err; 226 int err;
227 struct hists *hists = &evsel->hists; 227 struct hists *hists = evsel__hists(evsel);
228 struct hist_entry *he; 228 struct hist_entry *he;
229 struct rb_root *root; 229 struct rb_root *root;
230 struct rb_node *node; 230 struct rb_node *node;
@@ -259,7 +259,7 @@ static int test2(struct perf_evsel *evsel, struct machine *machine)
259 print_hists_out(hists); 259 print_hists_out(hists);
260 } 260 }
261 261
262 root = &evsel->hists.entries; 262 root = &hists->entries;
263 node = rb_first(root); 263 node = rb_first(root);
264 he = rb_entry(node, struct hist_entry, rb_node); 264 he = rb_entry(node, struct hist_entry, rb_node);
265 TEST_ASSERT_VAL("Invalid hist entry", 265 TEST_ASSERT_VAL("Invalid hist entry",
@@ -280,7 +280,7 @@ out:
280static int test3(struct perf_evsel *evsel, struct machine *machine) 280static int test3(struct perf_evsel *evsel, struct machine *machine)
281{ 281{
282 int err; 282 int err;
283 struct hists *hists = &evsel->hists; 283 struct hists *hists = evsel__hists(evsel);
284 struct hist_entry *he; 284 struct hist_entry *he;
285 struct rb_root *root; 285 struct rb_root *root;
286 struct rb_node *node; 286 struct rb_node *node;
@@ -313,7 +313,7 @@ static int test3(struct perf_evsel *evsel, struct machine *machine)
313 print_hists_out(hists); 313 print_hists_out(hists);
314 } 314 }
315 315
316 root = &evsel->hists.entries; 316 root = &hists->entries;
317 node = rb_first(root); 317 node = rb_first(root);
318 he = rb_entry(node, struct hist_entry, rb_node); 318 he = rb_entry(node, struct hist_entry, rb_node);
319 TEST_ASSERT_VAL("Invalid hist entry", 319 TEST_ASSERT_VAL("Invalid hist entry",
@@ -354,7 +354,7 @@ out:
354static int test4(struct perf_evsel *evsel, struct machine *machine) 354static int test4(struct perf_evsel *evsel, struct machine *machine)
355{ 355{
356 int err; 356 int err;
357 struct hists *hists = &evsel->hists; 357 struct hists *hists = evsel__hists(evsel);
358 struct hist_entry *he; 358 struct hist_entry *he;
359 struct rb_root *root; 359 struct rb_root *root;
360 struct rb_node *node; 360 struct rb_node *node;
@@ -391,7 +391,7 @@ static int test4(struct perf_evsel *evsel, struct machine *machine)
391 print_hists_out(hists); 391 print_hists_out(hists);
392 } 392 }
393 393
394 root = &evsel->hists.entries; 394 root = &hists->entries;
395 node = rb_first(root); 395 node = rb_first(root);
396 he = rb_entry(node, struct hist_entry, rb_node); 396 he = rb_entry(node, struct hist_entry, rb_node);
397 TEST_ASSERT_VAL("Invalid hist entry", 397 TEST_ASSERT_VAL("Invalid hist entry",
@@ -456,7 +456,7 @@ out:
456static int test5(struct perf_evsel *evsel, struct machine *machine) 456static int test5(struct perf_evsel *evsel, struct machine *machine)
457{ 457{
458 int err; 458 int err;
459 struct hists *hists = &evsel->hists; 459 struct hists *hists = evsel__hists(evsel);
460 struct hist_entry *he; 460 struct hist_entry *he;
461 struct rb_root *root; 461 struct rb_root *root;
462 struct rb_node *node; 462 struct rb_node *node;
@@ -494,7 +494,7 @@ static int test5(struct perf_evsel *evsel, struct machine *machine)
494 print_hists_out(hists); 494 print_hists_out(hists);
495 } 495 }
496 496
497 root = &evsel->hists.entries; 497 root = &hists->entries;
498 node = rb_first(root); 498 node = rb_first(root);
499 he = rb_entry(node, struct hist_entry, rb_node); 499 he = rb_entry(node, struct hist_entry, rb_node);
500 500
diff --git a/tools/perf/tests/parse-events.c b/tools/perf/tests/parse-events.c
index 5941927a4b7f..7f2f51f93619 100644
--- a/tools/perf/tests/parse-events.c
+++ b/tools/perf/tests/parse-events.c
@@ -457,6 +457,36 @@ static int test__checkevent_pmu_events(struct perf_evlist *evlist)
457 return 0; 457 return 0;
458} 458}
459 459
460
461static int test__checkevent_pmu_events_mix(struct perf_evlist *evlist)
462{
463 struct perf_evsel *evsel = perf_evlist__first(evlist);
464
465 /* pmu-event:u */
466 TEST_ASSERT_VAL("wrong number of entries", 2 == evlist->nr_entries);
467 TEST_ASSERT_VAL("wrong exclude_user",
468 !evsel->attr.exclude_user);
469 TEST_ASSERT_VAL("wrong exclude_kernel",
470 evsel->attr.exclude_kernel);
471 TEST_ASSERT_VAL("wrong exclude_hv", evsel->attr.exclude_hv);
472 TEST_ASSERT_VAL("wrong precise_ip", !evsel->attr.precise_ip);
473 TEST_ASSERT_VAL("wrong pinned", !evsel->attr.pinned);
474
475 /* cpu/pmu-event/u*/
476 evsel = perf_evsel__next(evsel);
477 TEST_ASSERT_VAL("wrong number of entries", 2 == evlist->nr_entries);
478 TEST_ASSERT_VAL("wrong type", PERF_TYPE_RAW == evsel->attr.type);
479 TEST_ASSERT_VAL("wrong exclude_user",
480 !evsel->attr.exclude_user);
481 TEST_ASSERT_VAL("wrong exclude_kernel",
482 evsel->attr.exclude_kernel);
483 TEST_ASSERT_VAL("wrong exclude_hv", evsel->attr.exclude_hv);
484 TEST_ASSERT_VAL("wrong precise_ip", !evsel->attr.precise_ip);
485 TEST_ASSERT_VAL("wrong pinned", !evsel->attr.pinned);
486
487 return 0;
488}
489
460static int test__checkterms_simple(struct list_head *terms) 490static int test__checkterms_simple(struct list_head *terms)
461{ 491{
462 struct parse_events_term *term; 492 struct parse_events_term *term;
@@ -1554,6 +1584,12 @@ static int test_pmu_events(void)
1554 e.check = test__checkevent_pmu_events; 1584 e.check = test__checkevent_pmu_events;
1555 1585
1556 ret = test_event(&e); 1586 ret = test_event(&e);
1587 if (ret)
1588 break;
1589 snprintf(name, MAX_NAME, "%s:u,cpu/event=%s/u", ent->d_name, ent->d_name);
1590 e.name = name;
1591 e.check = test__checkevent_pmu_events_mix;
1592 ret = test_event(&e);
1557#undef MAX_NAME 1593#undef MAX_NAME
1558 } 1594 }
1559 1595
diff --git a/tools/perf/ui/browsers/header.c b/tools/perf/ui/browsers/header.c
index 89c16b988618..e8278c558d4a 100644
--- a/tools/perf/ui/browsers/header.c
+++ b/tools/perf/ui/browsers/header.c
@@ -1,6 +1,7 @@
1#include "util/cache.h" 1#include "util/cache.h"
2#include "util/debug.h" 2#include "util/debug.h"
3#include "ui/browser.h" 3#include "ui/browser.h"
4#include "ui/keysyms.h"
4#include "ui/ui.h" 5#include "ui/ui.h"
5#include "ui/util.h" 6#include "ui/util.h"
6#include "ui/libslang.h" 7#include "ui/libslang.h"
diff --git a/tools/perf/ui/browsers/hists.c b/tools/perf/ui/browsers/hists.c
index 8f60a970404f..cfb976b3de3a 100644
--- a/tools/perf/ui/browsers/hists.c
+++ b/tools/perf/ui/browsers/hists.c
@@ -35,7 +35,9 @@ struct hist_browser {
35 35
36extern void hist_browser__init_hpp(void); 36extern void hist_browser__init_hpp(void);
37 37
38static int hists__browser_title(struct hists *hists, char *bf, size_t size); 38static int hists__browser_title(struct hists *hists,
39 struct hist_browser_timer *hbt,
40 char *bf, size_t size);
39static void hist_browser__update_nr_entries(struct hist_browser *hb); 41static void hist_browser__update_nr_entries(struct hist_browser *hb);
40 42
41static struct rb_node *hists__filter_entries(struct rb_node *nd, 43static struct rb_node *hists__filter_entries(struct rb_node *nd,
@@ -390,7 +392,7 @@ static int hist_browser__run(struct hist_browser *browser,
390 browser->b.entries = &browser->hists->entries; 392 browser->b.entries = &browser->hists->entries;
391 browser->b.nr_entries = hist_browser__nr_entries(browser); 393 browser->b.nr_entries = hist_browser__nr_entries(browser);
392 394
393 hists__browser_title(browser->hists, title, sizeof(title)); 395 hists__browser_title(browser->hists, hbt, title, sizeof(title));
394 396
395 if (ui_browser__show(&browser->b, title, 397 if (ui_browser__show(&browser->b, title,
396 "Press '?' for help on key bindings") < 0) 398 "Press '?' for help on key bindings") < 0)
@@ -417,7 +419,8 @@ static int hist_browser__run(struct hist_browser *browser,
417 ui_browser__warn_lost_events(&browser->b); 419 ui_browser__warn_lost_events(&browser->b);
418 } 420 }
419 421
420 hists__browser_title(browser->hists, title, sizeof(title)); 422 hists__browser_title(browser->hists,
423 hbt, title, sizeof(title));
421 ui_browser__show_title(&browser->b, title); 424 ui_browser__show_title(&browser->b, title);
422 continue; 425 continue;
423 } 426 }
@@ -1204,7 +1207,15 @@ static struct thread *hist_browser__selected_thread(struct hist_browser *browser
1204 return browser->he_selection->thread; 1207 return browser->he_selection->thread;
1205} 1208}
1206 1209
1207static int hists__browser_title(struct hists *hists, char *bf, size_t size) 1210/* Check whether the browser is for 'top' or 'report' */
1211static inline bool is_report_browser(void *timer)
1212{
1213 return timer == NULL;
1214}
1215
1216static int hists__browser_title(struct hists *hists,
1217 struct hist_browser_timer *hbt,
1218 char *bf, size_t size)
1208{ 1219{
1209 char unit; 1220 char unit;
1210 int printed; 1221 int printed;
@@ -1229,12 +1240,14 @@ static int hists__browser_title(struct hists *hists, char *bf, size_t size)
1229 ev_name = buf; 1240 ev_name = buf;
1230 1241
1231 for_each_group_member(pos, evsel) { 1242 for_each_group_member(pos, evsel) {
1243 struct hists *pos_hists = evsel__hists(pos);
1244
1232 if (symbol_conf.filter_relative) { 1245 if (symbol_conf.filter_relative) {
1233 nr_samples += pos->hists.stats.nr_non_filtered_samples; 1246 nr_samples += pos_hists->stats.nr_non_filtered_samples;
1234 nr_events += pos->hists.stats.total_non_filtered_period; 1247 nr_events += pos_hists->stats.total_non_filtered_period;
1235 } else { 1248 } else {
1236 nr_samples += pos->hists.stats.nr_events[PERF_RECORD_SAMPLE]; 1249 nr_samples += pos_hists->stats.nr_events[PERF_RECORD_SAMPLE];
1237 nr_events += pos->hists.stats.total_period; 1250 nr_events += pos_hists->stats.total_period;
1238 } 1251 }
1239 } 1252 }
1240 } 1253 }
@@ -1256,6 +1269,13 @@ static int hists__browser_title(struct hists *hists, char *bf, size_t size)
1256 if (dso) 1269 if (dso)
1257 printed += scnprintf(bf + printed, size - printed, 1270 printed += scnprintf(bf + printed, size - printed,
1258 ", DSO: %s", dso->short_name); 1271 ", DSO: %s", dso->short_name);
1272 if (!is_report_browser(hbt)) {
1273 struct perf_top *top = hbt->arg;
1274
1275 if (top->zero)
1276 printed += scnprintf(bf + printed, size - printed, " [z]");
1277 }
1278
1259 return printed; 1279 return printed;
1260} 1280}
1261 1281
@@ -1267,12 +1287,6 @@ static inline void free_popup_options(char **options, int n)
1267 zfree(&options[i]); 1287 zfree(&options[i]);
1268} 1288}
1269 1289
1270/* Check whether the browser is for 'top' or 'report' */
1271static inline bool is_report_browser(void *timer)
1272{
1273 return timer == NULL;
1274}
1275
1276/* 1290/*
1277 * Only runtime switching of perf data file will make "input_name" point 1291 * Only runtime switching of perf data file will make "input_name" point
1278 * to a malloced buffer. So add "is_input_name_malloced" flag to decide 1292 * to a malloced buffer. So add "is_input_name_malloced" flag to decide
@@ -1387,7 +1401,7 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events,
1387 float min_pcnt, 1401 float min_pcnt,
1388 struct perf_session_env *env) 1402 struct perf_session_env *env)
1389{ 1403{
1390 struct hists *hists = &evsel->hists; 1404 struct hists *hists = evsel__hists(evsel);
1391 struct hist_browser *browser = hist_browser__new(hists); 1405 struct hist_browser *browser = hist_browser__new(hists);
1392 struct branch_info *bi; 1406 struct branch_info *bi;
1393 struct pstack *fstack; 1407 struct pstack *fstack;
@@ -1802,8 +1816,9 @@ static void perf_evsel_menu__write(struct ui_browser *browser,
1802 struct perf_evsel_menu *menu = container_of(browser, 1816 struct perf_evsel_menu *menu = container_of(browser,
1803 struct perf_evsel_menu, b); 1817 struct perf_evsel_menu, b);
1804 struct perf_evsel *evsel = list_entry(entry, struct perf_evsel, node); 1818 struct perf_evsel *evsel = list_entry(entry, struct perf_evsel, node);
1819 struct hists *hists = evsel__hists(evsel);
1805 bool current_entry = ui_browser__is_current_entry(browser, row); 1820 bool current_entry = ui_browser__is_current_entry(browser, row);
1806 unsigned long nr_events = evsel->hists.stats.nr_events[PERF_RECORD_SAMPLE]; 1821 unsigned long nr_events = hists->stats.nr_events[PERF_RECORD_SAMPLE];
1807 const char *ev_name = perf_evsel__name(evsel); 1822 const char *ev_name = perf_evsel__name(evsel);
1808 char bf[256], unit; 1823 char bf[256], unit;
1809 const char *warn = " "; 1824 const char *warn = " ";
@@ -1818,7 +1833,8 @@ static void perf_evsel_menu__write(struct ui_browser *browser,
1818 ev_name = perf_evsel__group_name(evsel); 1833 ev_name = perf_evsel__group_name(evsel);
1819 1834
1820 for_each_group_member(pos, evsel) { 1835 for_each_group_member(pos, evsel) {
1821 nr_events += pos->hists.stats.nr_events[PERF_RECORD_SAMPLE]; 1836 struct hists *pos_hists = evsel__hists(pos);
1837 nr_events += pos_hists->stats.nr_events[PERF_RECORD_SAMPLE];
1822 } 1838 }
1823 } 1839 }
1824 1840
@@ -1827,7 +1843,7 @@ static void perf_evsel_menu__write(struct ui_browser *browser,
1827 unit, unit == ' ' ? "" : " ", ev_name); 1843 unit, unit == ' ' ? "" : " ", ev_name);
1828 slsmg_printf("%s", bf); 1844 slsmg_printf("%s", bf);
1829 1845
1830 nr_events = evsel->hists.stats.nr_events[PERF_RECORD_LOST]; 1846 nr_events = hists->stats.nr_events[PERF_RECORD_LOST];
1831 if (nr_events != 0) { 1847 if (nr_events != 0) {
1832 menu->lost_events = true; 1848 menu->lost_events = true;
1833 if (!current_entry) 1849 if (!current_entry)
diff --git a/tools/perf/ui/gtk/hists.c b/tools/perf/ui/gtk/hists.c
index f3fa4258b256..fc654fb77ace 100644
--- a/tools/perf/ui/gtk/hists.c
+++ b/tools/perf/ui/gtk/hists.c
@@ -319,7 +319,7 @@ int perf_evlist__gtk_browse_hists(struct perf_evlist *evlist,
319 gtk_container_add(GTK_CONTAINER(window), vbox); 319 gtk_container_add(GTK_CONTAINER(window), vbox);
320 320
321 evlist__for_each(evlist, pos) { 321 evlist__for_each(evlist, pos) {
322 struct hists *hists = &pos->hists; 322 struct hists *hists = evsel__hists(pos);
323 const char *evname = perf_evsel__name(pos); 323 const char *evname = perf_evsel__name(pos);
324 GtkWidget *scrolled_window; 324 GtkWidget *scrolled_window;
325 GtkWidget *tab_label; 325 GtkWidget *tab_label;
diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c
index 36437527dbb3..7dabde14ea54 100644
--- a/tools/perf/util/annotate.c
+++ b/tools/perf/util/annotate.c
@@ -478,7 +478,7 @@ static int __symbol__inc_addr_samples(struct symbol *sym, struct map *map,
478 478
479 pr_debug3("%s: addr=%#" PRIx64 "\n", __func__, map->unmap_ip(map, addr)); 479 pr_debug3("%s: addr=%#" PRIx64 "\n", __func__, map->unmap_ip(map, addr));
480 480
481 if (addr < sym->start || addr > sym->end) 481 if (addr < sym->start || addr >= sym->end)
482 return -ERANGE; 482 return -ERANGE;
483 483
484 offset = addr - sym->start; 484 offset = addr - sym->start;
@@ -836,7 +836,7 @@ static int symbol__parse_objdump_line(struct symbol *sym, struct map *map,
836 end = map__rip_2objdump(map, sym->end); 836 end = map__rip_2objdump(map, sym->end);
837 837
838 offset = line_ip - start; 838 offset = line_ip - start;
839 if ((u64)line_ip < start || (u64)line_ip > end) 839 if ((u64)line_ip < start || (u64)line_ip >= end)
840 offset = -1; 840 offset = -1;
841 else 841 else
842 parsed_line = tmp2 + 1; 842 parsed_line = tmp2 + 1;
@@ -966,7 +966,7 @@ fallback:
966 kce.kcore_filename = symfs_filename; 966 kce.kcore_filename = symfs_filename;
967 kce.addr = map__rip_2objdump(map, sym->start); 967 kce.addr = map__rip_2objdump(map, sym->start);
968 kce.offs = sym->start; 968 kce.offs = sym->start;
969 kce.len = sym->end + 1 - sym->start; 969 kce.len = sym->end - sym->start;
970 if (!kcore_extract__create(&kce)) { 970 if (!kcore_extract__create(&kce)) {
971 delete_extract = true; 971 delete_extract = true;
972 strlcpy(symfs_filename, kce.extract_filename, 972 strlcpy(symfs_filename, kce.extract_filename,
@@ -987,7 +987,7 @@ fallback:
987 disassembler_style ? "-M " : "", 987 disassembler_style ? "-M " : "",
988 disassembler_style ? disassembler_style : "", 988 disassembler_style ? disassembler_style : "",
989 map__rip_2objdump(map, sym->start), 989 map__rip_2objdump(map, sym->start),
990 map__rip_2objdump(map, sym->end+1), 990 map__rip_2objdump(map, sym->end),
991 symbol_conf.annotate_asm_raw ? "" : "--no-show-raw", 991 symbol_conf.annotate_asm_raw ? "" : "--no-show-raw",
992 symbol_conf.annotate_src ? "-S" : "", 992 symbol_conf.annotate_src ? "-S" : "",
993 symfs_filename, filename); 993 symfs_filename, filename);
diff --git a/tools/perf/util/callchain.h b/tools/perf/util/callchain.h
index 2a1f5a46543a..94cfefddf4db 100644
--- a/tools/perf/util/callchain.h
+++ b/tools/perf/util/callchain.h
@@ -65,6 +65,8 @@ struct callchain_param {
65 enum chain_key key; 65 enum chain_key key;
66}; 66};
67 67
68extern struct callchain_param callchain_param;
69
68struct callchain_list { 70struct callchain_list {
69 u64 ip; 71 u64 ip;
70 struct map_symbol ms; 72 struct map_symbol ms;
diff --git a/tools/perf/util/event.h b/tools/perf/util/event.h
index 7eb7107731ec..5699e7e2a790 100644
--- a/tools/perf/util/event.h
+++ b/tools/perf/util/event.h
@@ -190,6 +190,32 @@ enum perf_user_event_type { /* above any possible kernel type */
190 PERF_RECORD_HEADER_MAX 190 PERF_RECORD_HEADER_MAX
191}; 191};
192 192
193/*
194 * The kernel collects the number of events it couldn't send in a stretch and
195 * when possible sends this number in a PERF_RECORD_LOST event. The number of
196 * such "chunks" of lost events is stored in .nr_events[PERF_EVENT_LOST] while
197 * total_lost tells exactly how many events the kernel in fact lost, i.e. it is
198 * the sum of all struct lost_event.lost fields reported.
199 *
200 * The total_period is needed because by default auto-freq is used, so
201 * multipling nr_events[PERF_EVENT_SAMPLE] by a frequency isn't possible to get
202 * the total number of low level events, it is necessary to to sum all struct
203 * sample_event.period and stash the result in total_period.
204 */
205struct events_stats {
206 u64 total_period;
207 u64 total_non_filtered_period;
208 u64 total_lost;
209 u64 total_invalid_chains;
210 u32 nr_events[PERF_RECORD_HEADER_MAX];
211 u32 nr_non_filtered_samples;
212 u32 nr_lost_warned;
213 u32 nr_unknown_events;
214 u32 nr_invalid_chains;
215 u32 nr_unknown_id;
216 u32 nr_unprocessable_samples;
217};
218
193struct attr_event { 219struct attr_event {
194 struct perf_event_header header; 220 struct perf_event_header header;
195 struct perf_event_attr attr; 221 struct perf_event_attr attr;
diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c
index 3cebc9a8d52e..3c9e77d6b4c2 100644
--- a/tools/perf/util/evlist.c
+++ b/tools/perf/util/evlist.c
@@ -1003,6 +1003,7 @@ int perf_evlist__create_maps(struct perf_evlist *evlist, struct target *target)
1003 1003
1004out_delete_threads: 1004out_delete_threads:
1005 thread_map__delete(evlist->threads); 1005 thread_map__delete(evlist->threads);
1006 evlist->threads = NULL;
1006 return -1; 1007 return -1;
1007} 1008}
1008 1009
@@ -1175,11 +1176,51 @@ void perf_evlist__close(struct perf_evlist *evlist)
1175 } 1176 }
1176} 1177}
1177 1178
1179static int perf_evlist__create_syswide_maps(struct perf_evlist *evlist)
1180{
1181 int err = -ENOMEM;
1182
1183 /*
1184 * Try reading /sys/devices/system/cpu/online to get
1185 * an all cpus map.
1186 *
1187 * FIXME: -ENOMEM is the best we can do here, the cpu_map
1188 * code needs an overhaul to properly forward the
1189 * error, and we may not want to do that fallback to a
1190 * default cpu identity map :-\
1191 */
1192 evlist->cpus = cpu_map__new(NULL);
1193 if (evlist->cpus == NULL)
1194 goto out;
1195
1196 evlist->threads = thread_map__new_dummy();
1197 if (evlist->threads == NULL)
1198 goto out_free_cpus;
1199
1200 err = 0;
1201out:
1202 return err;
1203out_free_cpus:
1204 cpu_map__delete(evlist->cpus);
1205 evlist->cpus = NULL;
1206 goto out;
1207}
1208
1178int perf_evlist__open(struct perf_evlist *evlist) 1209int perf_evlist__open(struct perf_evlist *evlist)
1179{ 1210{
1180 struct perf_evsel *evsel; 1211 struct perf_evsel *evsel;
1181 int err; 1212 int err;
1182 1213
1214 /*
1215 * Default: one fd per CPU, all threads, aka systemwide
1216 * as sys_perf_event_open(cpu = -1, thread = -1) is EINVAL
1217 */
1218 if (evlist->threads == NULL && evlist->cpus == NULL) {
1219 err = perf_evlist__create_syswide_maps(evlist);
1220 if (err < 0)
1221 goto out_err;
1222 }
1223
1183 perf_evlist__update_id_pos(evlist); 1224 perf_evlist__update_id_pos(evlist);
1184 1225
1185 evlist__for_each(evlist, evsel) { 1226 evlist__for_each(evlist, evsel) {
@@ -1276,8 +1317,14 @@ int perf_evlist__prepare_workload(struct perf_evlist *evlist, struct target *tar
1276 sigaction(SIGUSR1, &act, NULL); 1317 sigaction(SIGUSR1, &act, NULL);
1277 } 1318 }
1278 1319
1279 if (target__none(target)) 1320 if (target__none(target)) {
1321 if (evlist->threads == NULL) {
1322 fprintf(stderr, "FATAL: evlist->threads need to be set at this point (%s:%d).\n",
1323 __func__, __LINE__);
1324 goto out_close_pipes;
1325 }
1280 evlist->threads->map[0] = evlist->workload.pid; 1326 evlist->threads->map[0] = evlist->workload.pid;
1327 }
1281 1328
1282 close(child_ready_pipe[1]); 1329 close(child_ready_pipe[1]);
1283 close(go_pipe[0]); 1330 close(go_pipe[0]);
diff --git a/tools/perf/util/evlist.h b/tools/perf/util/evlist.h
index bd312b01e876..649b0c597283 100644
--- a/tools/perf/util/evlist.h
+++ b/tools/perf/util/evlist.h
@@ -117,6 +117,8 @@ int perf_evlist__prepare_workload(struct perf_evlist *evlist,
117 void *ucontext)); 117 void *ucontext));
118int perf_evlist__start_workload(struct perf_evlist *evlist); 118int perf_evlist__start_workload(struct perf_evlist *evlist);
119 119
120struct option;
121
120int perf_evlist__parse_mmap_pages(const struct option *opt, 122int perf_evlist__parse_mmap_pages(const struct option *opt,
121 const char *str, 123 const char *str,
122 int unset); 124 int unset);
diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c
index e0868a901c4a..2f9e68025ede 100644
--- a/tools/perf/util/evsel.c
+++ b/tools/perf/util/evsel.c
@@ -15,6 +15,8 @@
15#include <linux/perf_event.h> 15#include <linux/perf_event.h>
16#include <sys/resource.h> 16#include <sys/resource.h>
17#include "asm/bug.h" 17#include "asm/bug.h"
18#include "callchain.h"
19#include "cgroup.h"
18#include "evsel.h" 20#include "evsel.h"
19#include "evlist.h" 21#include "evlist.h"
20#include "util.h" 22#include "util.h"
@@ -32,6 +34,48 @@ static struct {
32 bool cloexec; 34 bool cloexec;
33} perf_missing_features; 35} perf_missing_features;
34 36
37static int perf_evsel__no_extra_init(struct perf_evsel *evsel __maybe_unused)
38{
39 return 0;
40}
41
42static void perf_evsel__no_extra_fini(struct perf_evsel *evsel __maybe_unused)
43{
44}
45
46static struct {
47 size_t size;
48 int (*init)(struct perf_evsel *evsel);
49 void (*fini)(struct perf_evsel *evsel);
50} perf_evsel__object = {
51 .size = sizeof(struct perf_evsel),
52 .init = perf_evsel__no_extra_init,
53 .fini = perf_evsel__no_extra_fini,
54};
55
56int perf_evsel__object_config(size_t object_size,
57 int (*init)(struct perf_evsel *evsel),
58 void (*fini)(struct perf_evsel *evsel))
59{
60
61 if (object_size == 0)
62 goto set_methods;
63
64 if (perf_evsel__object.size > object_size)
65 return -EINVAL;
66
67 perf_evsel__object.size = object_size;
68
69set_methods:
70 if (init != NULL)
71 perf_evsel__object.init = init;
72
73 if (fini != NULL)
74 perf_evsel__object.fini = fini;
75
76 return 0;
77}
78
35#define FD(e, x, y) (*(int *)xyarray__entry(e->fd, x, y)) 79#define FD(e, x, y) (*(int *)xyarray__entry(e->fd, x, y))
36 80
37int __perf_evsel__sample_size(u64 sample_type) 81int __perf_evsel__sample_size(u64 sample_type)
@@ -116,16 +160,6 @@ void perf_evsel__calc_id_pos(struct perf_evsel *evsel)
116 evsel->is_pos = __perf_evsel__calc_is_pos(evsel->attr.sample_type); 160 evsel->is_pos = __perf_evsel__calc_is_pos(evsel->attr.sample_type);
117} 161}
118 162
119void hists__init(struct hists *hists)
120{
121 memset(hists, 0, sizeof(*hists));
122 hists->entries_in_array[0] = hists->entries_in_array[1] = RB_ROOT;
123 hists->entries_in = &hists->entries_in_array[0];
124 hists->entries_collapsed = RB_ROOT;
125 hists->entries = RB_ROOT;
126 pthread_mutex_init(&hists->lock, NULL);
127}
128
129void __perf_evsel__set_sample_bit(struct perf_evsel *evsel, 163void __perf_evsel__set_sample_bit(struct perf_evsel *evsel,
130 enum perf_event_sample_format bit) 164 enum perf_event_sample_format bit)
131{ 165{
@@ -168,14 +202,14 @@ void perf_evsel__init(struct perf_evsel *evsel,
168 evsel->unit = ""; 202 evsel->unit = "";
169 evsel->scale = 1.0; 203 evsel->scale = 1.0;
170 INIT_LIST_HEAD(&evsel->node); 204 INIT_LIST_HEAD(&evsel->node);
171 hists__init(&evsel->hists); 205 perf_evsel__object.init(evsel);
172 evsel->sample_size = __perf_evsel__sample_size(attr->sample_type); 206 evsel->sample_size = __perf_evsel__sample_size(attr->sample_type);
173 perf_evsel__calc_id_pos(evsel); 207 perf_evsel__calc_id_pos(evsel);
174} 208}
175 209
176struct perf_evsel *perf_evsel__new_idx(struct perf_event_attr *attr, int idx) 210struct perf_evsel *perf_evsel__new_idx(struct perf_event_attr *attr, int idx)
177{ 211{
178 struct perf_evsel *evsel = zalloc(sizeof(*evsel)); 212 struct perf_evsel *evsel = zalloc(perf_evsel__object.size);
179 213
180 if (evsel != NULL) 214 if (evsel != NULL)
181 perf_evsel__init(evsel, attr, idx); 215 perf_evsel__init(evsel, attr, idx);
@@ -185,7 +219,7 @@ struct perf_evsel *perf_evsel__new_idx(struct perf_event_attr *attr, int idx)
185 219
186struct perf_evsel *perf_evsel__newtp_idx(const char *sys, const char *name, int idx) 220struct perf_evsel *perf_evsel__newtp_idx(const char *sys, const char *name, int idx)
187{ 221{
188 struct perf_evsel *evsel = zalloc(sizeof(*evsel)); 222 struct perf_evsel *evsel = zalloc(perf_evsel__object.size);
189 223
190 if (evsel != NULL) { 224 if (evsel != NULL) {
191 struct perf_event_attr attr = { 225 struct perf_event_attr attr = {
@@ -692,7 +726,7 @@ void perf_evsel__config(struct perf_evsel *evsel, struct record_opts *opts)
692 } 726 }
693} 727}
694 728
695int perf_evsel__alloc_fd(struct perf_evsel *evsel, int ncpus, int nthreads) 729static int perf_evsel__alloc_fd(struct perf_evsel *evsel, int ncpus, int nthreads)
696{ 730{
697 int cpu, thread; 731 int cpu, thread;
698 732
@@ -780,13 +814,13 @@ int perf_evsel__alloc_counts(struct perf_evsel *evsel, int ncpus)
780 return evsel->counts != NULL ? 0 : -ENOMEM; 814 return evsel->counts != NULL ? 0 : -ENOMEM;
781} 815}
782 816
783void perf_evsel__free_fd(struct perf_evsel *evsel) 817static void perf_evsel__free_fd(struct perf_evsel *evsel)
784{ 818{
785 xyarray__delete(evsel->fd); 819 xyarray__delete(evsel->fd);
786 evsel->fd = NULL; 820 evsel->fd = NULL;
787} 821}
788 822
789void perf_evsel__free_id(struct perf_evsel *evsel) 823static void perf_evsel__free_id(struct perf_evsel *evsel)
790{ 824{
791 xyarray__delete(evsel->sample_id); 825 xyarray__delete(evsel->sample_id);
792 evsel->sample_id = NULL; 826 evsel->sample_id = NULL;
@@ -817,16 +851,17 @@ void perf_evsel__exit(struct perf_evsel *evsel)
817 assert(list_empty(&evsel->node)); 851 assert(list_empty(&evsel->node));
818 perf_evsel__free_fd(evsel); 852 perf_evsel__free_fd(evsel);
819 perf_evsel__free_id(evsel); 853 perf_evsel__free_id(evsel);
820}
821
822void perf_evsel__delete(struct perf_evsel *evsel)
823{
824 perf_evsel__exit(evsel);
825 close_cgroup(evsel->cgrp); 854 close_cgroup(evsel->cgrp);
826 zfree(&evsel->group_name); 855 zfree(&evsel->group_name);
827 if (evsel->tp_format) 856 if (evsel->tp_format)
828 pevent_free_format(evsel->tp_format); 857 pevent_free_format(evsel->tp_format);
829 zfree(&evsel->name); 858 zfree(&evsel->name);
859 perf_evsel__object.fini(evsel);
860}
861
862void perf_evsel__delete(struct perf_evsel *evsel)
863{
864 perf_evsel__exit(evsel);
830 free(evsel); 865 free(evsel);
831} 866}
832 867
diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h
index 7bc314be6a7b..163c5604e5d1 100644
--- a/tools/perf/util/evsel.h
+++ b/tools/perf/util/evsel.h
@@ -7,8 +7,6 @@
7#include <linux/perf_event.h> 7#include <linux/perf_event.h>
8#include <linux/types.h> 8#include <linux/types.h>
9#include "xyarray.h" 9#include "xyarray.h"
10#include "cgroup.h"
11#include "hist.h"
12#include "symbol.h" 10#include "symbol.h"
13 11
14struct perf_counts_values { 12struct perf_counts_values {
@@ -43,6 +41,8 @@ struct perf_sample_id {
43 u64 period; 41 u64 period;
44}; 42};
45 43
44struct cgroup_sel;
45
46/** struct perf_evsel - event selector 46/** struct perf_evsel - event selector
47 * 47 *
48 * @name - Can be set to retain the original event name passed by the user, 48 * @name - Can be set to retain the original event name passed by the user,
@@ -66,7 +66,6 @@ struct perf_evsel {
66 struct perf_counts *prev_raw_counts; 66 struct perf_counts *prev_raw_counts;
67 int idx; 67 int idx;
68 u32 ids; 68 u32 ids;
69 struct hists hists;
70 char *name; 69 char *name;
71 double scale; 70 double scale;
72 const char *unit; 71 const char *unit;
@@ -100,13 +99,16 @@ union u64_swap {
100 u32 val32[2]; 99 u32 val32[2];
101}; 100};
102 101
103#define hists_to_evsel(h) container_of(h, struct perf_evsel, hists)
104
105struct cpu_map; 102struct cpu_map;
103struct target;
106struct thread_map; 104struct thread_map;
107struct perf_evlist; 105struct perf_evlist;
108struct record_opts; 106struct record_opts;
109 107
108int perf_evsel__object_config(size_t object_size,
109 int (*init)(struct perf_evsel *evsel),
110 void (*fini)(struct perf_evsel *evsel));
111
110struct perf_evsel *perf_evsel__new_idx(struct perf_event_attr *attr, int idx); 112struct perf_evsel *perf_evsel__new_idx(struct perf_event_attr *attr, int idx);
111 113
112static inline struct perf_evsel *perf_evsel__new(struct perf_event_attr *attr) 114static inline struct perf_evsel *perf_evsel__new(struct perf_event_attr *attr)
@@ -153,12 +155,9 @@ const char *perf_evsel__name(struct perf_evsel *evsel);
153const char *perf_evsel__group_name(struct perf_evsel *evsel); 155const char *perf_evsel__group_name(struct perf_evsel *evsel);
154int perf_evsel__group_desc(struct perf_evsel *evsel, char *buf, size_t size); 156int perf_evsel__group_desc(struct perf_evsel *evsel, char *buf, size_t size);
155 157
156int perf_evsel__alloc_fd(struct perf_evsel *evsel, int ncpus, int nthreads);
157int perf_evsel__alloc_id(struct perf_evsel *evsel, int ncpus, int nthreads); 158int perf_evsel__alloc_id(struct perf_evsel *evsel, int ncpus, int nthreads);
158int perf_evsel__alloc_counts(struct perf_evsel *evsel, int ncpus); 159int perf_evsel__alloc_counts(struct perf_evsel *evsel, int ncpus);
159void perf_evsel__reset_counts(struct perf_evsel *evsel, int ncpus); 160void perf_evsel__reset_counts(struct perf_evsel *evsel, int ncpus);
160void perf_evsel__free_fd(struct perf_evsel *evsel);
161void perf_evsel__free_id(struct perf_evsel *evsel);
162void perf_evsel__free_counts(struct perf_evsel *evsel); 161void perf_evsel__free_counts(struct perf_evsel *evsel);
163void perf_evsel__close_fd(struct perf_evsel *evsel, int ncpus, int nthreads); 162void perf_evsel__close_fd(struct perf_evsel *evsel, int ncpus, int nthreads);
164 163
@@ -281,8 +280,6 @@ static inline int perf_evsel__read_scaled(struct perf_evsel *evsel,
281 return __perf_evsel__read(evsel, ncpus, nthreads, true); 280 return __perf_evsel__read(evsel, ncpus, nthreads, true);
282} 281}
283 282
284void hists__init(struct hists *hists);
285
286int perf_evsel__parse_sample(struct perf_evsel *evsel, union perf_event *event, 283int perf_evsel__parse_sample(struct perf_evsel *evsel, union perf_event *event,
287 struct perf_sample *sample); 284 struct perf_sample *sample);
288 285
diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c
index 86569fa3651d..6e88b9e395df 100644
--- a/tools/perf/util/hist.c
+++ b/tools/perf/util/hist.c
@@ -3,6 +3,7 @@
3#include "hist.h" 3#include "hist.h"
4#include "session.h" 4#include "session.h"
5#include "sort.h" 5#include "sort.h"
6#include "evlist.h"
6#include "evsel.h" 7#include "evsel.h"
7#include "annotate.h" 8#include "annotate.h"
8#include <math.h> 9#include <math.h>
@@ -14,13 +15,6 @@ static bool hists__filter_entry_by_thread(struct hists *hists,
14static bool hists__filter_entry_by_symbol(struct hists *hists, 15static bool hists__filter_entry_by_symbol(struct hists *hists,
15 struct hist_entry *he); 16 struct hist_entry *he);
16 17
17struct callchain_param callchain_param = {
18 .mode = CHAIN_GRAPH_REL,
19 .min_percent = 0.5,
20 .order = ORDER_CALLEE,
21 .key = CCKEY_FUNCTION
22};
23
24u16 hists__col_len(struct hists *hists, enum hist_column col) 18u16 hists__col_len(struct hists *hists, enum hist_column col)
25{ 19{
26 return hists->col_len[col]; 20 return hists->col_len[col];
@@ -516,6 +510,7 @@ iter_add_single_mem_entry(struct hist_entry_iter *iter, struct addr_location *al
516{ 510{
517 u64 cost; 511 u64 cost;
518 struct mem_info *mi = iter->priv; 512 struct mem_info *mi = iter->priv;
513 struct hists *hists = evsel__hists(iter->evsel);
519 struct hist_entry *he; 514 struct hist_entry *he;
520 515
521 if (mi == NULL) 516 if (mi == NULL)
@@ -532,7 +527,7 @@ iter_add_single_mem_entry(struct hist_entry_iter *iter, struct addr_location *al
532 * and this is indirectly achieved by passing period=weight here 527 * and this is indirectly achieved by passing period=weight here
533 * and the he_stat__add_period() function. 528 * and the he_stat__add_period() function.
534 */ 529 */
535 he = __hists__add_entry(&iter->evsel->hists, al, iter->parent, NULL, mi, 530 he = __hists__add_entry(hists, al, iter->parent, NULL, mi,
536 cost, cost, 0, true); 531 cost, cost, 0, true);
537 if (!he) 532 if (!he)
538 return -ENOMEM; 533 return -ENOMEM;
@@ -546,13 +541,14 @@ iter_finish_mem_entry(struct hist_entry_iter *iter,
546 struct addr_location *al __maybe_unused) 541 struct addr_location *al __maybe_unused)
547{ 542{
548 struct perf_evsel *evsel = iter->evsel; 543 struct perf_evsel *evsel = iter->evsel;
544 struct hists *hists = evsel__hists(evsel);
549 struct hist_entry *he = iter->he; 545 struct hist_entry *he = iter->he;
550 int err = -EINVAL; 546 int err = -EINVAL;
551 547
552 if (he == NULL) 548 if (he == NULL)
553 goto out; 549 goto out;
554 550
555 hists__inc_nr_samples(&evsel->hists, he->filtered); 551 hists__inc_nr_samples(hists, he->filtered);
556 552
557 err = hist_entry__append_callchain(he, iter->sample); 553 err = hist_entry__append_callchain(he, iter->sample);
558 554
@@ -618,6 +614,7 @@ iter_add_next_branch_entry(struct hist_entry_iter *iter, struct addr_location *a
618{ 614{
619 struct branch_info *bi; 615 struct branch_info *bi;
620 struct perf_evsel *evsel = iter->evsel; 616 struct perf_evsel *evsel = iter->evsel;
617 struct hists *hists = evsel__hists(evsel);
621 struct hist_entry *he = NULL; 618 struct hist_entry *he = NULL;
622 int i = iter->curr; 619 int i = iter->curr;
623 int err = 0; 620 int err = 0;
@@ -631,12 +628,12 @@ iter_add_next_branch_entry(struct hist_entry_iter *iter, struct addr_location *a
631 * The report shows the percentage of total branches captured 628 * The report shows the percentage of total branches captured
632 * and not events sampled. Thus we use a pseudo period of 1. 629 * and not events sampled. Thus we use a pseudo period of 1.
633 */ 630 */
634 he = __hists__add_entry(&evsel->hists, al, iter->parent, &bi[i], NULL, 631 he = __hists__add_entry(hists, al, iter->parent, &bi[i], NULL,
635 1, 1, 0, true); 632 1, 1, 0, true);
636 if (he == NULL) 633 if (he == NULL)
637 return -ENOMEM; 634 return -ENOMEM;
638 635
639 hists__inc_nr_samples(&evsel->hists, he->filtered); 636 hists__inc_nr_samples(hists, he->filtered);
640 637
641out: 638out:
642 iter->he = he; 639 iter->he = he;
@@ -668,7 +665,7 @@ iter_add_single_normal_entry(struct hist_entry_iter *iter, struct addr_location
668 struct perf_sample *sample = iter->sample; 665 struct perf_sample *sample = iter->sample;
669 struct hist_entry *he; 666 struct hist_entry *he;
670 667
671 he = __hists__add_entry(&evsel->hists, al, iter->parent, NULL, NULL, 668 he = __hists__add_entry(evsel__hists(evsel), al, iter->parent, NULL, NULL,
672 sample->period, sample->weight, 669 sample->period, sample->weight,
673 sample->transaction, true); 670 sample->transaction, true);
674 if (he == NULL) 671 if (he == NULL)
@@ -691,7 +688,7 @@ iter_finish_normal_entry(struct hist_entry_iter *iter,
691 688
692 iter->he = NULL; 689 iter->he = NULL;
693 690
694 hists__inc_nr_samples(&evsel->hists, he->filtered); 691 hists__inc_nr_samples(evsel__hists(evsel), he->filtered);
695 692
696 return hist_entry__append_callchain(he, sample); 693 return hist_entry__append_callchain(he, sample);
697} 694}
@@ -724,12 +721,13 @@ iter_add_single_cumulative_entry(struct hist_entry_iter *iter,
724 struct addr_location *al) 721 struct addr_location *al)
725{ 722{
726 struct perf_evsel *evsel = iter->evsel; 723 struct perf_evsel *evsel = iter->evsel;
724 struct hists *hists = evsel__hists(evsel);
727 struct perf_sample *sample = iter->sample; 725 struct perf_sample *sample = iter->sample;
728 struct hist_entry **he_cache = iter->priv; 726 struct hist_entry **he_cache = iter->priv;
729 struct hist_entry *he; 727 struct hist_entry *he;
730 int err = 0; 728 int err = 0;
731 729
732 he = __hists__add_entry(&evsel->hists, al, iter->parent, NULL, NULL, 730 he = __hists__add_entry(hists, al, iter->parent, NULL, NULL,
733 sample->period, sample->weight, 731 sample->period, sample->weight,
734 sample->transaction, true); 732 sample->transaction, true);
735 if (he == NULL) 733 if (he == NULL)
@@ -746,7 +744,7 @@ iter_add_single_cumulative_entry(struct hist_entry_iter *iter,
746 */ 744 */
747 callchain_cursor_commit(&callchain_cursor); 745 callchain_cursor_commit(&callchain_cursor);
748 746
749 hists__inc_nr_samples(&evsel->hists, he->filtered); 747 hists__inc_nr_samples(hists, he->filtered);
750 748
751 return err; 749 return err;
752} 750}
@@ -802,7 +800,7 @@ iter_add_next_cumulative_entry(struct hist_entry_iter *iter,
802 } 800 }
803 } 801 }
804 802
805 he = __hists__add_entry(&evsel->hists, al, iter->parent, NULL, NULL, 803 he = __hists__add_entry(evsel__hists(evsel), al, iter->parent, NULL, NULL,
806 sample->period, sample->weight, 804 sample->period, sample->weight,
807 sample->transaction, false); 805 sample->transaction, false);
808 if (he == NULL) 806 if (he == NULL)
@@ -1408,6 +1406,21 @@ int hists__link(struct hists *leader, struct hists *other)
1408 return 0; 1406 return 0;
1409} 1407}
1410 1408
1409
1410size_t perf_evlist__fprintf_nr_events(struct perf_evlist *evlist, FILE *fp)
1411{
1412 struct perf_evsel *pos;
1413 size_t ret = 0;
1414
1415 evlist__for_each(evlist, pos) {
1416 ret += fprintf(fp, "%s stats:\n", perf_evsel__name(pos));
1417 ret += events_stats__fprintf(&evsel__hists(pos)->stats, fp);
1418 }
1419
1420 return ret;
1421}
1422
1423
1411u64 hists__total_period(struct hists *hists) 1424u64 hists__total_period(struct hists *hists)
1412{ 1425{
1413 return symbol_conf.filter_relative ? hists->stats.total_non_filtered_period : 1426 return symbol_conf.filter_relative ? hists->stats.total_non_filtered_period :
@@ -1434,3 +1447,31 @@ int perf_hist_config(const char *var, const char *value)
1434 1447
1435 return 0; 1448 return 0;
1436} 1449}
1450
1451static int hists_evsel__init(struct perf_evsel *evsel)
1452{
1453 struct hists *hists = evsel__hists(evsel);
1454
1455 memset(hists, 0, sizeof(*hists));
1456 hists->entries_in_array[0] = hists->entries_in_array[1] = RB_ROOT;
1457 hists->entries_in = &hists->entries_in_array[0];
1458 hists->entries_collapsed = RB_ROOT;
1459 hists->entries = RB_ROOT;
1460 pthread_mutex_init(&hists->lock, NULL);
1461 return 0;
1462}
1463
1464/*
1465 * XXX We probably need a hists_evsel__exit() to free the hist_entries
1466 * stored in the rbtree...
1467 */
1468
1469int hists__init(void)
1470{
1471 int err = perf_evsel__object_config(sizeof(struct hists_evsel),
1472 hists_evsel__init, NULL);
1473 if (err)
1474 fputs("FATAL ERROR: Couldn't setup hists class\n", stderr);
1475
1476 return err;
1477}
diff --git a/tools/perf/util/hist.h b/tools/perf/util/hist.h
index 8c9c70e18cbb..d0ef9a19a744 100644
--- a/tools/perf/util/hist.h
+++ b/tools/perf/util/hist.h
@@ -4,12 +4,11 @@
4#include <linux/types.h> 4#include <linux/types.h>
5#include <pthread.h> 5#include <pthread.h>
6#include "callchain.h" 6#include "callchain.h"
7#include "evsel.h"
7#include "header.h" 8#include "header.h"
8#include "color.h" 9#include "color.h"
9#include "ui/progress.h" 10#include "ui/progress.h"
10 11
11extern struct callchain_param callchain_param;
12
13struct hist_entry; 12struct hist_entry;
14struct addr_location; 13struct addr_location;
15struct symbol; 14struct symbol;
@@ -23,32 +22,6 @@ enum hist_filter {
23 HIST_FILTER__HOST, 22 HIST_FILTER__HOST,
24}; 23};
25 24
26/*
27 * The kernel collects the number of events it couldn't send in a stretch and
28 * when possible sends this number in a PERF_RECORD_LOST event. The number of
29 * such "chunks" of lost events is stored in .nr_events[PERF_EVENT_LOST] while
30 * total_lost tells exactly how many events the kernel in fact lost, i.e. it is
31 * the sum of all struct lost_event.lost fields reported.
32 *
33 * The total_period is needed because by default auto-freq is used, so
34 * multipling nr_events[PERF_EVENT_SAMPLE] by a frequency isn't possible to get
35 * the total number of low level events, it is necessary to to sum all struct
36 * sample_event.period and stash the result in total_period.
37 */
38struct events_stats {
39 u64 total_period;
40 u64 total_non_filtered_period;
41 u64 total_lost;
42 u64 total_invalid_chains;
43 u32 nr_events[PERF_RECORD_HEADER_MAX];
44 u32 nr_non_filtered_samples;
45 u32 nr_lost_warned;
46 u32 nr_unknown_events;
47 u32 nr_invalid_chains;
48 u32 nr_unknown_id;
49 u32 nr_unprocessable_samples;
50};
51
52enum hist_column { 25enum hist_column {
53 HISTC_SYMBOL, 26 HISTC_SYMBOL,
54 HISTC_DSO, 27 HISTC_DSO,
@@ -165,6 +138,7 @@ size_t events_stats__fprintf(struct events_stats *stats, FILE *fp);
165 138
166size_t hists__fprintf(struct hists *hists, bool show_header, int max_rows, 139size_t hists__fprintf(struct hists *hists, bool show_header, int max_rows,
167 int max_cols, float min_pcnt, FILE *fp); 140 int max_cols, float min_pcnt, FILE *fp);
141size_t perf_evlist__fprintf_nr_events(struct perf_evlist *evlist, FILE *fp);
168 142
169void hists__filter_by_dso(struct hists *hists); 143void hists__filter_by_dso(struct hists *hists);
170void hists__filter_by_thread(struct hists *hists); 144void hists__filter_by_thread(struct hists *hists);
@@ -185,6 +159,25 @@ void hists__calc_col_len(struct hists *hists, struct hist_entry *he);
185void hists__match(struct hists *leader, struct hists *other); 159void hists__match(struct hists *leader, struct hists *other);
186int hists__link(struct hists *leader, struct hists *other); 160int hists__link(struct hists *leader, struct hists *other);
187 161
162struct hists_evsel {
163 struct perf_evsel evsel;
164 struct hists hists;
165};
166
167static inline struct perf_evsel *hists_to_evsel(struct hists *hists)
168{
169 struct hists_evsel *hevsel = container_of(hists, struct hists_evsel, hists);
170 return &hevsel->evsel;
171}
172
173static inline struct hists *evsel__hists(struct perf_evsel *evsel)
174{
175 struct hists_evsel *hevsel = (struct hists_evsel *)evsel;
176 return &hevsel->hists;
177}
178
179int hists__init(void);
180
188struct perf_hpp { 181struct perf_hpp {
189 char *buf; 182 char *buf;
190 size_t size; 183 size_t size;
diff --git a/tools/perf/util/include/linux/string.h b/tools/perf/util/include/linux/string.h
index 97a800738226..6f19c548ecc0 100644
--- a/tools/perf/util/include/linux/string.h
+++ b/tools/perf/util/include/linux/string.h
@@ -1,4 +1,3 @@
1#include <string.h> 1#include <string.h>
2 2
3void *memdup(const void *src, size_t len); 3void *memdup(const void *src, size_t len);
4int str_append(char **s, int *len, const char *a);
diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c
index b7d477fbda02..34fc7c8672e4 100644
--- a/tools/perf/util/machine.c
+++ b/tools/perf/util/machine.c
@@ -13,12 +13,18 @@
13#include <symbol/kallsyms.h> 13#include <symbol/kallsyms.h>
14#include "unwind.h" 14#include "unwind.h"
15 15
16static void dsos__init(struct dsos *dsos)
17{
18 INIT_LIST_HEAD(&dsos->head);
19 dsos->root = RB_ROOT;
20}
21
16int machine__init(struct machine *machine, const char *root_dir, pid_t pid) 22int machine__init(struct machine *machine, const char *root_dir, pid_t pid)
17{ 23{
18 map_groups__init(&machine->kmaps); 24 map_groups__init(&machine->kmaps);
19 RB_CLEAR_NODE(&machine->rb_node); 25 RB_CLEAR_NODE(&machine->rb_node);
20 INIT_LIST_HEAD(&machine->user_dsos.head); 26 dsos__init(&machine->user_dsos);
21 INIT_LIST_HEAD(&machine->kernel_dsos.head); 27 dsos__init(&machine->kernel_dsos);
22 28
23 machine->threads = RB_ROOT; 29 machine->threads = RB_ROOT;
24 INIT_LIST_HEAD(&machine->dead_threads); 30 INIT_LIST_HEAD(&machine->dead_threads);
diff --git a/tools/perf/util/map.c b/tools/perf/util/map.c
index b7090596ac50..2137c4596ec7 100644
--- a/tools/perf/util/map.c
+++ b/tools/perf/util/map.c
@@ -556,7 +556,7 @@ struct symbol *map_groups__find_symbol_by_name(struct map_groups *mg,
556 556
557int map_groups__find_ams(struct addr_map_symbol *ams, symbol_filter_t filter) 557int map_groups__find_ams(struct addr_map_symbol *ams, symbol_filter_t filter)
558{ 558{
559 if (ams->addr < ams->map->start || ams->addr > ams->map->end) { 559 if (ams->addr < ams->map->start || ams->addr >= ams->map->end) {
560 if (ams->map->groups == NULL) 560 if (ams->map->groups == NULL)
561 return -1; 561 return -1;
562 ams->map = map_groups__find(ams->map->groups, ams->map->type, 562 ams->map = map_groups__find(ams->map->groups, ams->map->type,
@@ -664,7 +664,7 @@ int map_groups__fixup_overlappings(struct map_groups *mg, struct map *map,
664 goto move_map; 664 goto move_map;
665 } 665 }
666 666
667 before->end = map->start - 1; 667 before->end = map->start;
668 map_groups__insert(mg, before); 668 map_groups__insert(mg, before);
669 if (verbose >= 2) 669 if (verbose >= 2)
670 map__fprintf(before, fp); 670 map__fprintf(before, fp);
@@ -678,7 +678,7 @@ int map_groups__fixup_overlappings(struct map_groups *mg, struct map *map,
678 goto move_map; 678 goto move_map;
679 } 679 }
680 680
681 after->start = map->end + 1; 681 after->start = map->end;
682 map_groups__insert(mg, after); 682 map_groups__insert(mg, after);
683 if (verbose >= 2) 683 if (verbose >= 2)
684 map__fprintf(after, fp); 684 map__fprintf(after, fp);
@@ -752,7 +752,7 @@ struct map *maps__find(struct rb_root *maps, u64 ip)
752 m = rb_entry(parent, struct map, rb_node); 752 m = rb_entry(parent, struct map, rb_node);
753 if (ip < m->start) 753 if (ip < m->start)
754 p = &(*p)->rb_left; 754 p = &(*p)->rb_left;
755 else if (ip > m->end) 755 else if (ip >= m->end)
756 p = &(*p)->rb_right; 756 p = &(*p)->rb_right;
757 else 757 else
758 return m; 758 return m;
diff --git a/tools/perf/util/ordered-events.c b/tools/perf/util/ordered-events.c
index 706ce1a66169..fd4be94125fb 100644
--- a/tools/perf/util/ordered-events.c
+++ b/tools/perf/util/ordered-events.c
@@ -1,5 +1,6 @@
1#include <linux/list.h> 1#include <linux/list.h>
2#include <linux/compiler.h> 2#include <linux/compiler.h>
3#include <linux/string.h>
3#include "ordered-events.h" 4#include "ordered-events.h"
4#include "evlist.h" 5#include "evlist.h"
5#include "session.h" 6#include "session.h"
@@ -57,11 +58,45 @@ static void queue_event(struct ordered_events *oe, struct ordered_event *new)
57 } 58 }
58} 59}
59 60
61static union perf_event *__dup_event(struct ordered_events *oe,
62 union perf_event *event)
63{
64 union perf_event *new_event = NULL;
65
66 if (oe->cur_alloc_size < oe->max_alloc_size) {
67 new_event = memdup(event, event->header.size);
68 if (new_event)
69 oe->cur_alloc_size += event->header.size;
70 }
71
72 return new_event;
73}
74
75static union perf_event *dup_event(struct ordered_events *oe,
76 union perf_event *event)
77{
78 return oe->copy_on_queue ? __dup_event(oe, event) : event;
79}
80
81static void free_dup_event(struct ordered_events *oe, union perf_event *event)
82{
83 if (oe->copy_on_queue) {
84 oe->cur_alloc_size -= event->header.size;
85 free(event);
86 }
87}
88
60#define MAX_SAMPLE_BUFFER (64 * 1024 / sizeof(struct ordered_event)) 89#define MAX_SAMPLE_BUFFER (64 * 1024 / sizeof(struct ordered_event))
61static struct ordered_event *alloc_event(struct ordered_events *oe) 90static struct ordered_event *alloc_event(struct ordered_events *oe,
91 union perf_event *event)
62{ 92{
63 struct list_head *cache = &oe->cache; 93 struct list_head *cache = &oe->cache;
64 struct ordered_event *new = NULL; 94 struct ordered_event *new = NULL;
95 union perf_event *new_event;
96
97 new_event = dup_event(oe, event);
98 if (!new_event)
99 return NULL;
65 100
66 if (!list_empty(cache)) { 101 if (!list_empty(cache)) {
67 new = list_entry(cache->next, struct ordered_event, list); 102 new = list_entry(cache->next, struct ordered_event, list);
@@ -74,8 +109,10 @@ static struct ordered_event *alloc_event(struct ordered_events *oe)
74 size_t size = MAX_SAMPLE_BUFFER * sizeof(*new); 109 size_t size = MAX_SAMPLE_BUFFER * sizeof(*new);
75 110
76 oe->buffer = malloc(size); 111 oe->buffer = malloc(size);
77 if (!oe->buffer) 112 if (!oe->buffer) {
113 free_dup_event(oe, new_event);
78 return NULL; 114 return NULL;
115 }
79 116
80 pr("alloc size %" PRIu64 "B (+%zu), max %" PRIu64 "B\n", 117 pr("alloc size %" PRIu64 "B (+%zu), max %" PRIu64 "B\n",
81 oe->cur_alloc_size, size, oe->max_alloc_size); 118 oe->cur_alloc_size, size, oe->max_alloc_size);
@@ -90,15 +127,17 @@ static struct ordered_event *alloc_event(struct ordered_events *oe)
90 pr("allocation limit reached %" PRIu64 "B\n", oe->max_alloc_size); 127 pr("allocation limit reached %" PRIu64 "B\n", oe->max_alloc_size);
91 } 128 }
92 129
130 new->event = new_event;
93 return new; 131 return new;
94} 132}
95 133
96struct ordered_event * 134struct ordered_event *
97ordered_events__new(struct ordered_events *oe, u64 timestamp) 135ordered_events__new(struct ordered_events *oe, u64 timestamp,
136 union perf_event *event)
98{ 137{
99 struct ordered_event *new; 138 struct ordered_event *new;
100 139
101 new = alloc_event(oe); 140 new = alloc_event(oe, event);
102 if (new) { 141 if (new) {
103 new->timestamp = timestamp; 142 new->timestamp = timestamp;
104 queue_event(oe, new); 143 queue_event(oe, new);
@@ -111,6 +150,7 @@ void ordered_events__delete(struct ordered_events *oe, struct ordered_event *eve
111{ 150{
112 list_move(&event->list, &oe->cache); 151 list_move(&event->list, &oe->cache);
113 oe->nr_events--; 152 oe->nr_events--;
153 free_dup_event(oe, event->event);
114} 154}
115 155
116static int __ordered_events__flush(struct perf_session *s, 156static int __ordered_events__flush(struct perf_session *s,
@@ -240,6 +280,7 @@ void ordered_events__free(struct ordered_events *oe)
240 280
241 event = list_entry(oe->to_free.next, struct ordered_event, list); 281 event = list_entry(oe->to_free.next, struct ordered_event, list);
242 list_del(&event->list); 282 list_del(&event->list);
283 free_dup_event(oe, event->event);
243 free(event); 284 free(event);
244 } 285 }
245} 286}
diff --git a/tools/perf/util/ordered-events.h b/tools/perf/util/ordered-events.h
index 3b2f20542a01..7b8f9b011f38 100644
--- a/tools/perf/util/ordered-events.h
+++ b/tools/perf/util/ordered-events.h
@@ -34,9 +34,11 @@ struct ordered_events {
34 int buffer_idx; 34 int buffer_idx;
35 unsigned int nr_events; 35 unsigned int nr_events;
36 enum oe_flush last_flush_type; 36 enum oe_flush last_flush_type;
37 bool copy_on_queue;
37}; 38};
38 39
39struct ordered_event *ordered_events__new(struct ordered_events *oe, u64 timestamp); 40struct ordered_event *ordered_events__new(struct ordered_events *oe, u64 timestamp,
41 union perf_event *event);
40void ordered_events__delete(struct ordered_events *oe, struct ordered_event *event); 42void ordered_events__delete(struct ordered_events *oe, struct ordered_event *event);
41int ordered_events__flush(struct perf_session *s, struct perf_tool *tool, 43int ordered_events__flush(struct perf_session *s, struct perf_tool *tool,
42 enum oe_flush how); 44 enum oe_flush how);
@@ -48,4 +50,10 @@ void ordered_events__set_alloc_size(struct ordered_events *oe, u64 size)
48{ 50{
49 oe->max_alloc_size = size; 51 oe->max_alloc_size = size;
50} 52}
53
54static inline
55void ordered_events__set_copy_on_queue(struct ordered_events *oe, bool copy)
56{
57 oe->copy_on_queue = copy;
58}
51#endif /* __ORDERED_EVENTS_H */ 59#endif /* __ORDERED_EVENTS_H */
diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c
index d76aa30cb1fb..c659a3ca1283 100644
--- a/tools/perf/util/parse-events.c
+++ b/tools/perf/util/parse-events.c
@@ -6,7 +6,7 @@
6#include "parse-options.h" 6#include "parse-options.h"
7#include "parse-events.h" 7#include "parse-events.h"
8#include "exec_cmd.h" 8#include "exec_cmd.h"
9#include "linux/string.h" 9#include "string.h"
10#include "symbol.h" 10#include "symbol.h"
11#include "cache.h" 11#include "cache.h"
12#include "header.h" 12#include "header.h"
@@ -30,6 +30,15 @@ extern int parse_events_debug;
30#endif 30#endif
31int parse_events_parse(void *data, void *scanner); 31int parse_events_parse(void *data, void *scanner);
32 32
33static struct perf_pmu_event_symbol *perf_pmu_events_list;
34/*
35 * The variable indicates the number of supported pmu event symbols.
36 * 0 means not initialized and ready to init
37 * -1 means failed to init, don't try anymore
38 * >0 is the number of supported pmu event symbols
39 */
40static int perf_pmu_events_list_num;
41
33static struct event_symbol event_symbols_hw[PERF_COUNT_HW_MAX] = { 42static struct event_symbol event_symbols_hw[PERF_COUNT_HW_MAX] = {
34 [PERF_COUNT_HW_CPU_CYCLES] = { 43 [PERF_COUNT_HW_CPU_CYCLES] = {
35 .symbol = "cpu-cycles", 44 .symbol = "cpu-cycles",
@@ -863,30 +872,111 @@ int parse_events_name(struct list_head *list, char *name)
863 return 0; 872 return 0;
864} 873}
865 874
866static int parse_events__scanner(const char *str, void *data, int start_token); 875static int
876comp_pmu(const void *p1, const void *p2)
877{
878 struct perf_pmu_event_symbol *pmu1 = (struct perf_pmu_event_symbol *) p1;
879 struct perf_pmu_event_symbol *pmu2 = (struct perf_pmu_event_symbol *) p2;
867 880
868static int parse_events_fixup(int ret, const char *str, void *data, 881 return strcmp(pmu1->symbol, pmu2->symbol);
869 int start_token) 882}
883
884static void perf_pmu__parse_cleanup(void)
870{ 885{
871 char *o = strdup(str); 886 if (perf_pmu_events_list_num > 0) {
872 char *s = NULL; 887 struct perf_pmu_event_symbol *p;
873 char *t = o; 888 int i;
874 char *p; 889
890 for (i = 0; i < perf_pmu_events_list_num; i++) {
891 p = perf_pmu_events_list + i;
892 free(p->symbol);
893 }
894 free(perf_pmu_events_list);
895 perf_pmu_events_list = NULL;
896 perf_pmu_events_list_num = 0;
897 }
898}
899
900#define SET_SYMBOL(str, stype) \
901do { \
902 p->symbol = str; \
903 if (!p->symbol) \
904 goto err; \
905 p->type = stype; \
906} while (0)
907
908/*
909 * Read the pmu events list from sysfs
910 * Save it into perf_pmu_events_list
911 */
912static void perf_pmu__parse_init(void)
913{
914
915 struct perf_pmu *pmu = NULL;
916 struct perf_pmu_alias *alias;
875 int len = 0; 917 int len = 0;
876 918
877 if (!o) 919 pmu = perf_pmu__find("cpu");
878 return ret; 920 if ((pmu == NULL) || list_empty(&pmu->aliases)) {
879 while ((p = strsep(&t, ",")) != NULL) { 921 perf_pmu_events_list_num = -1;
880 if (s) 922 return;
881 str_append(&s, &len, ",");
882 str_append(&s, &len, "cpu/");
883 str_append(&s, &len, p);
884 str_append(&s, &len, "/");
885 } 923 }
886 free(o); 924 list_for_each_entry(alias, &pmu->aliases, list) {
887 if (!s) 925 if (strchr(alias->name, '-'))
888 return -ENOMEM; 926 len++;
889 return parse_events__scanner(s, data, start_token); 927 len++;
928 }
929 perf_pmu_events_list = malloc(sizeof(struct perf_pmu_event_symbol) * len);
930 if (!perf_pmu_events_list)
931 return;
932 perf_pmu_events_list_num = len;
933
934 len = 0;
935 list_for_each_entry(alias, &pmu->aliases, list) {
936 struct perf_pmu_event_symbol *p = perf_pmu_events_list + len;
937 char *tmp = strchr(alias->name, '-');
938
939 if (tmp != NULL) {
940 SET_SYMBOL(strndup(alias->name, tmp - alias->name),
941 PMU_EVENT_SYMBOL_PREFIX);
942 p++;
943 SET_SYMBOL(strdup(++tmp), PMU_EVENT_SYMBOL_SUFFIX);
944 len += 2;
945 } else {
946 SET_SYMBOL(strdup(alias->name), PMU_EVENT_SYMBOL);
947 len++;
948 }
949 }
950 qsort(perf_pmu_events_list, len,
951 sizeof(struct perf_pmu_event_symbol), comp_pmu);
952
953 return;
954err:
955 perf_pmu__parse_cleanup();
956}
957
958enum perf_pmu_event_symbol_type
959perf_pmu__parse_check(const char *name)
960{
961 struct perf_pmu_event_symbol p, *r;
962
963 /* scan kernel pmu events from sysfs if needed */
964 if (perf_pmu_events_list_num == 0)
965 perf_pmu__parse_init();
966 /*
967 * name "cpu" could be prefix of cpu-cycles or cpu// events.
968 * cpu-cycles has been handled by hardcode.
969 * So it must be cpu// events, not kernel pmu event.
970 */
971 if ((perf_pmu_events_list_num <= 0) || !strcmp(name, "cpu"))
972 return PMU_EVENT_SYMBOL_ERR;
973
974 p.symbol = strdup(name);
975 r = bsearch(&p, perf_pmu_events_list,
976 (size_t) perf_pmu_events_list_num,
977 sizeof(struct perf_pmu_event_symbol), comp_pmu);
978 free(p.symbol);
979 return r ? r->type : PMU_EVENT_SYMBOL_ERR;
890} 980}
891 981
892static int parse_events__scanner(const char *str, void *data, int start_token) 982static int parse_events__scanner(const char *str, void *data, int start_token)
@@ -909,8 +999,6 @@ static int parse_events__scanner(const char *str, void *data, int start_token)
909 parse_events__flush_buffer(buffer, scanner); 999 parse_events__flush_buffer(buffer, scanner);
910 parse_events__delete_buffer(buffer, scanner); 1000 parse_events__delete_buffer(buffer, scanner);
911 parse_events_lex_destroy(scanner); 1001 parse_events_lex_destroy(scanner);
912 if (ret && !strchr(str, '/'))
913 ret = parse_events_fixup(ret, str, data, start_token);
914 return ret; 1002 return ret;
915} 1003}
916 1004
@@ -945,6 +1033,7 @@ int parse_events(struct perf_evlist *evlist, const char *str)
945 int ret; 1033 int ret;
946 1034
947 ret = parse_events__scanner(str, &data, PE_START_EVENTS); 1035 ret = parse_events__scanner(str, &data, PE_START_EVENTS);
1036 perf_pmu__parse_cleanup();
948 if (!ret) { 1037 if (!ret) {
949 int entries = data.idx - evlist->nr_entries; 1038 int entries = data.idx - evlist->nr_entries;
950 perf_evlist__splice_list_tail(evlist, &data.list, entries); 1039 perf_evlist__splice_list_tail(evlist, &data.list, entries);
diff --git a/tools/perf/util/parse-events.h b/tools/perf/util/parse-events.h
index df094b4ed5ed..db2cf78ff0f3 100644
--- a/tools/perf/util/parse-events.h
+++ b/tools/perf/util/parse-events.h
@@ -35,6 +35,18 @@ extern int parse_filter(const struct option *opt, const char *str, int unset);
35 35
36#define EVENTS_HELP_MAX (128*1024) 36#define EVENTS_HELP_MAX (128*1024)
37 37
38enum perf_pmu_event_symbol_type {
39 PMU_EVENT_SYMBOL_ERR, /* not a PMU EVENT */
40 PMU_EVENT_SYMBOL, /* normal style PMU event */
41 PMU_EVENT_SYMBOL_PREFIX, /* prefix of pre-suf style event */
42 PMU_EVENT_SYMBOL_SUFFIX, /* suffix of pre-suf style event */
43};
44
45struct perf_pmu_event_symbol {
46 char *symbol;
47 enum perf_pmu_event_symbol_type type;
48};
49
38enum { 50enum {
39 PARSE_EVENTS__TERM_TYPE_NUM, 51 PARSE_EVENTS__TERM_TYPE_NUM,
40 PARSE_EVENTS__TERM_TYPE_STR, 52 PARSE_EVENTS__TERM_TYPE_STR,
@@ -95,6 +107,8 @@ int parse_events_add_breakpoint(struct list_head *list, int *idx,
95 void *ptr, char *type); 107 void *ptr, char *type);
96int parse_events_add_pmu(struct list_head *list, int *idx, 108int parse_events_add_pmu(struct list_head *list, int *idx,
97 char *pmu , struct list_head *head_config); 109 char *pmu , struct list_head *head_config);
110enum perf_pmu_event_symbol_type
111perf_pmu__parse_check(const char *name);
98void parse_events__set_leader(char *name, struct list_head *list); 112void parse_events__set_leader(char *name, struct list_head *list);
99void parse_events_update_lists(struct list_head *list_event, 113void parse_events_update_lists(struct list_head *list_event,
100 struct list_head *list_all); 114 struct list_head *list_all);
diff --git a/tools/perf/util/parse-events.l b/tools/perf/util/parse-events.l
index 343299575b30..906630bbf8eb 100644
--- a/tools/perf/util/parse-events.l
+++ b/tools/perf/util/parse-events.l
@@ -51,6 +51,24 @@ static int str(yyscan_t scanner, int token)
51 return token; 51 return token;
52} 52}
53 53
54static int pmu_str_check(yyscan_t scanner)
55{
56 YYSTYPE *yylval = parse_events_get_lval(scanner);
57 char *text = parse_events_get_text(scanner);
58
59 yylval->str = strdup(text);
60 switch (perf_pmu__parse_check(text)) {
61 case PMU_EVENT_SYMBOL_PREFIX:
62 return PE_PMU_EVENT_PRE;
63 case PMU_EVENT_SYMBOL_SUFFIX:
64 return PE_PMU_EVENT_SUF;
65 case PMU_EVENT_SYMBOL:
66 return PE_KERNEL_PMU_EVENT;
67 default:
68 return PE_NAME;
69 }
70}
71
54static int sym(yyscan_t scanner, int type, int config) 72static int sym(yyscan_t scanner, int type, int config)
55{ 73{
56 YYSTYPE *yylval = parse_events_get_lval(scanner); 74 YYSTYPE *yylval = parse_events_get_lval(scanner);
@@ -178,6 +196,16 @@ alignment-faults { return sym(yyscanner, PERF_TYPE_SOFTWARE, PERF_COUNT_SW_AL
178emulation-faults { return sym(yyscanner, PERF_TYPE_SOFTWARE, PERF_COUNT_SW_EMULATION_FAULTS); } 196emulation-faults { return sym(yyscanner, PERF_TYPE_SOFTWARE, PERF_COUNT_SW_EMULATION_FAULTS); }
179dummy { return sym(yyscanner, PERF_TYPE_SOFTWARE, PERF_COUNT_SW_DUMMY); } 197dummy { return sym(yyscanner, PERF_TYPE_SOFTWARE, PERF_COUNT_SW_DUMMY); }
180 198
199 /*
200 * We have to handle the kernel PMU event cycles-ct/cycles-t/mem-loads/mem-stores separately.
201 * Because the prefix cycles is mixed up with cpu-cycles.
202 * loads and stores are mixed up with cache event
203 */
204cycles-ct { return str(yyscanner, PE_KERNEL_PMU_EVENT); }
205cycles-t { return str(yyscanner, PE_KERNEL_PMU_EVENT); }
206mem-loads { return str(yyscanner, PE_KERNEL_PMU_EVENT); }
207mem-stores { return str(yyscanner, PE_KERNEL_PMU_EVENT); }
208
181L1-dcache|l1-d|l1d|L1-data | 209L1-dcache|l1-d|l1d|L1-data |
182L1-icache|l1-i|l1i|L1-instruction | 210L1-icache|l1-i|l1i|L1-instruction |
183LLC|L2 | 211LLC|L2 |
@@ -199,7 +227,7 @@ r{num_raw_hex} { return raw(yyscanner); }
199{num_hex} { return value(yyscanner, 16); } 227{num_hex} { return value(yyscanner, 16); }
200 228
201{modifier_event} { return str(yyscanner, PE_MODIFIER_EVENT); } 229{modifier_event} { return str(yyscanner, PE_MODIFIER_EVENT); }
202{name} { return str(yyscanner, PE_NAME); } 230{name} { return pmu_str_check(yyscanner); }
203"/" { BEGIN(config); return '/'; } 231"/" { BEGIN(config); return '/'; }
204- { return '-'; } 232- { return '-'; }
205, { BEGIN(event); return ','; } 233, { BEGIN(event); return ','; }
diff --git a/tools/perf/util/parse-events.y b/tools/perf/util/parse-events.y
index 55fab6ad609a..93c4c9fbc922 100644
--- a/tools/perf/util/parse-events.y
+++ b/tools/perf/util/parse-events.y
@@ -47,6 +47,7 @@ static inc_group_count(struct list_head *list,
47%token PE_NAME_CACHE_TYPE PE_NAME_CACHE_OP_RESULT 47%token PE_NAME_CACHE_TYPE PE_NAME_CACHE_OP_RESULT
48%token PE_PREFIX_MEM PE_PREFIX_RAW PE_PREFIX_GROUP 48%token PE_PREFIX_MEM PE_PREFIX_RAW PE_PREFIX_GROUP
49%token PE_ERROR 49%token PE_ERROR
50%token PE_PMU_EVENT_PRE PE_PMU_EVENT_SUF PE_KERNEL_PMU_EVENT
50%type <num> PE_VALUE 51%type <num> PE_VALUE
51%type <num> PE_VALUE_SYM_HW 52%type <num> PE_VALUE_SYM_HW
52%type <num> PE_VALUE_SYM_SW 53%type <num> PE_VALUE_SYM_SW
@@ -58,6 +59,7 @@ static inc_group_count(struct list_head *list,
58%type <str> PE_MODIFIER_EVENT 59%type <str> PE_MODIFIER_EVENT
59%type <str> PE_MODIFIER_BP 60%type <str> PE_MODIFIER_BP
60%type <str> PE_EVENT_NAME 61%type <str> PE_EVENT_NAME
62%type <str> PE_PMU_EVENT_PRE PE_PMU_EVENT_SUF PE_KERNEL_PMU_EVENT
61%type <num> value_sym 63%type <num> value_sym
62%type <head> event_config 64%type <head> event_config
63%type <term> event_term 65%type <term> event_term
@@ -220,6 +222,44 @@ PE_NAME '/' '/'
220 ABORT_ON(parse_events_add_pmu(list, &data->idx, $1, NULL)); 222 ABORT_ON(parse_events_add_pmu(list, &data->idx, $1, NULL));
221 $$ = list; 223 $$ = list;
222} 224}
225|
226PE_KERNEL_PMU_EVENT sep_dc
227{
228 struct parse_events_evlist *data = _data;
229 struct list_head *head;
230 struct parse_events_term *term;
231 struct list_head *list;
232
233 ALLOC_LIST(head);
234 ABORT_ON(parse_events_term__num(&term, PARSE_EVENTS__TERM_TYPE_USER,
235 $1, 1));
236 list_add_tail(&term->list, head);
237
238 ALLOC_LIST(list);
239 ABORT_ON(parse_events_add_pmu(list, &data->idx, "cpu", head));
240 parse_events__free_terms(head);
241 $$ = list;
242}
243|
244PE_PMU_EVENT_PRE '-' PE_PMU_EVENT_SUF sep_dc
245{
246 struct parse_events_evlist *data = _data;
247 struct list_head *head;
248 struct parse_events_term *term;
249 struct list_head *list;
250 char pmu_name[128];
251 snprintf(&pmu_name, 128, "%s-%s", $1, $3);
252
253 ALLOC_LIST(head);
254 ABORT_ON(parse_events_term__num(&term, PARSE_EVENTS__TERM_TYPE_USER,
255 &pmu_name, 1));
256 list_add_tail(&term->list, head);
257
258 ALLOC_LIST(list);
259 ABORT_ON(parse_events_add_pmu(list, &data->idx, "cpu", head));
260 parse_events__free_terms(head);
261 $$ = list;
262}
223 263
224value_sym: 264value_sym:
225PE_VALUE_SYM_HW 265PE_VALUE_SYM_HW
diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c
index 93a41ca96b8e..e243ad962a4d 100644
--- a/tools/perf/util/pmu.c
+++ b/tools/perf/util/pmu.c
@@ -12,16 +12,6 @@
12#include "parse-events.h" 12#include "parse-events.h"
13#include "cpumap.h" 13#include "cpumap.h"
14 14
15#define UNIT_MAX_LEN 31 /* max length for event unit name */
16
17struct perf_pmu_alias {
18 char *name;
19 struct list_head terms; /* HEAD struct parse_events_term -> list */
20 struct list_head list; /* ELEM */
21 char unit[UNIT_MAX_LEN+1];
22 double scale;
23};
24
25struct perf_pmu_format { 15struct perf_pmu_format {
26 char *name; 16 char *name;
27 int value; 17 int value;
diff --git a/tools/perf/util/pmu.h b/tools/perf/util/pmu.h
index fe90a012c003..fe9dfbee8eed 100644
--- a/tools/perf/util/pmu.h
+++ b/tools/perf/util/pmu.h
@@ -30,6 +30,16 @@ struct perf_pmu_info {
30 double scale; 30 double scale;
31}; 31};
32 32
33#define UNIT_MAX_LEN 31 /* max length for event unit name */
34
35struct perf_pmu_alias {
36 char *name;
37 struct list_head terms; /* HEAD struct parse_events_term -> list */
38 struct list_head list; /* ELEM */
39 char unit[UNIT_MAX_LEN+1];
40 double scale;
41};
42
33struct perf_pmu *perf_pmu__find(const char *name); 43struct perf_pmu *perf_pmu__find(const char *name);
34int perf_pmu__config(struct perf_pmu *pmu, struct perf_event_attr *attr, 44int perf_pmu__config(struct perf_pmu *pmu, struct perf_event_attr *attr,
35 struct list_head *head_terms); 45 struct list_head *head_terms);
diff --git a/tools/perf/util/scripting-engines/trace-event-python.c b/tools/perf/util/scripting-engines/trace-event-python.c
index 56ba07cce549..496f21cadd97 100644
--- a/tools/perf/util/scripting-engines/trace-event-python.c
+++ b/tools/perf/util/scripting-engines/trace-event-python.c
@@ -28,6 +28,7 @@
28 28
29#include "../../perf.h" 29#include "../../perf.h"
30#include "../debug.h" 30#include "../debug.h"
31#include "../callchain.h"
31#include "../evsel.h" 32#include "../evsel.h"
32#include "../util.h" 33#include "../util.h"
33#include "../event.h" 34#include "../event.h"
diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c
index 883406f4b381..6702ac28754b 100644
--- a/tools/perf/util/session.c
+++ b/tools/perf/util/session.c
@@ -532,17 +532,16 @@ int perf_session_queue_event(struct perf_session *s, union perf_event *event,
532 return -EINVAL; 532 return -EINVAL;
533 } 533 }
534 534
535 new = ordered_events__new(oe, timestamp); 535 new = ordered_events__new(oe, timestamp, event);
536 if (!new) { 536 if (!new) {
537 ordered_events__flush(s, tool, OE_FLUSH__HALF); 537 ordered_events__flush(s, tool, OE_FLUSH__HALF);
538 new = ordered_events__new(oe, timestamp); 538 new = ordered_events__new(oe, timestamp, event);
539 } 539 }
540 540
541 if (!new) 541 if (!new)
542 return -ENOMEM; 542 return -ENOMEM;
543 543
544 new->file_offset = file_offset; 544 new->file_offset = file_offset;
545 new->event = event;
546 return 0; 545 return 0;
547} 546}
548 547
@@ -813,22 +812,6 @@ int perf_session__deliver_event(struct perf_session *session,
813 dump_event(session, event, file_offset, sample); 812 dump_event(session, event, file_offset, sample);
814 813
815 evsel = perf_evlist__id2evsel(session->evlist, sample->id); 814 evsel = perf_evlist__id2evsel(session->evlist, sample->id);
816 if (evsel != NULL && event->header.type != PERF_RECORD_SAMPLE) {
817 /*
818 * XXX We're leaving PERF_RECORD_SAMPLE unnacounted here
819 * because the tools right now may apply filters, discarding
820 * some of the samples. For consistency, in the future we
821 * should have something like nr_filtered_samples and remove
822 * the sample->period from total_sample_period, etc, KISS for
823 * now tho.
824 *
825 * Also testing against NULL allows us to handle files without
826 * attr.sample_id_all and/or without PERF_SAMPLE_ID. In the
827 * future probably it'll be a good idea to restrict event
828 * processing via perf_session to files with both set.
829 */
830 hists__inc_nr_events(&evsel->hists, event->header.type);
831 }
832 815
833 machine = perf_session__find_machine_for_cpumode(session, event, 816 machine = perf_session__find_machine_for_cpumode(session, event,
834 sample); 817 sample);
@@ -1391,16 +1374,9 @@ size_t perf_session__fprintf_dsos_buildid(struct perf_session *session, FILE *fp
1391 1374
1392size_t perf_session__fprintf_nr_events(struct perf_session *session, FILE *fp) 1375size_t perf_session__fprintf_nr_events(struct perf_session *session, FILE *fp)
1393{ 1376{
1394 struct perf_evsel *pos;
1395 size_t ret = fprintf(fp, "Aggregated stats:\n"); 1377 size_t ret = fprintf(fp, "Aggregated stats:\n");
1396 1378
1397 ret += events_stats__fprintf(&session->stats, fp); 1379 ret += events_stats__fprintf(&session->stats, fp);
1398
1399 evlist__for_each(session->evlist, pos) {
1400 ret += fprintf(fp, "%s stats:\n", perf_evsel__name(pos));
1401 ret += events_stats__fprintf(&pos->hists.stats, fp);
1402 }
1403
1404 return ret; 1380 return ret;
1405} 1381}
1406 1382
diff --git a/tools/perf/util/session.h b/tools/perf/util/session.h
index ffb440462008..a4be851f1a90 100644
--- a/tools/perf/util/session.h
+++ b/tools/perf/util/session.h
@@ -2,7 +2,6 @@
2#define __PERF_SESSION_H 2#define __PERF_SESSION_H
3 3
4#include "trace-event.h" 4#include "trace-event.h"
5#include "hist.h"
6#include "event.h" 5#include "event.h"
7#include "header.h" 6#include "header.h"
8#include "machine.h" 7#include "machine.h"
diff --git a/tools/perf/util/sort.c b/tools/perf/util/sort.c
index 289df9d1e65a..4906cd81cb56 100644
--- a/tools/perf/util/sort.c
+++ b/tools/perf/util/sort.c
@@ -1218,7 +1218,7 @@ static int __sort__hpp_header(struct perf_hpp_fmt *fmt, struct perf_hpp *hpp,
1218 hse = container_of(fmt, struct hpp_sort_entry, hpp); 1218 hse = container_of(fmt, struct hpp_sort_entry, hpp);
1219 1219
1220 if (!len) 1220 if (!len)
1221 len = hists__col_len(&evsel->hists, hse->se->se_width_idx); 1221 len = hists__col_len(evsel__hists(evsel), hse->se->se_width_idx);
1222 1222
1223 return scnprintf(hpp->buf, hpp->size, "%-*.*s", len, len, fmt->name); 1223 return scnprintf(hpp->buf, hpp->size, "%-*.*s", len, len, fmt->name);
1224} 1224}
@@ -1233,7 +1233,7 @@ static int __sort__hpp_width(struct perf_hpp_fmt *fmt,
1233 hse = container_of(fmt, struct hpp_sort_entry, hpp); 1233 hse = container_of(fmt, struct hpp_sort_entry, hpp);
1234 1234
1235 if (!len) 1235 if (!len)
1236 len = hists__col_len(&evsel->hists, hse->se->se_width_idx); 1236 len = hists__col_len(evsel__hists(evsel), hse->se->se_width_idx);
1237 1237
1238 return len; 1238 return len;
1239} 1239}
diff --git a/tools/perf/util/string.c b/tools/perf/util/string.c
index d87767f76903..6afd6106ceb5 100644
--- a/tools/perf/util/string.c
+++ b/tools/perf/util/string.c
@@ -357,27 +357,3 @@ void *memdup(const void *src, size_t len)
357 357
358 return p; 358 return p;
359} 359}
360
361/**
362 * str_append - reallocate string and append another
363 * @s: pointer to string pointer
364 * @len: pointer to len (initialized)
365 * @a: string to append.
366 */
367int str_append(char **s, int *len, const char *a)
368{
369 int olen = *s ? strlen(*s) : 0;
370 int nlen = olen + strlen(a) + 1;
371 if (*len < nlen) {
372 *len = *len * 2;
373 if (*len < nlen)
374 *len = nlen;
375 *s = realloc(*s, *len);
376 if (!*s)
377 return -ENOMEM;
378 if (olen == 0)
379 **s = 0;
380 }
381 strcat(*s, a);
382 return 0;
383}
diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c
index be84f7a9838b..078331140d8c 100644
--- a/tools/perf/util/symbol.c
+++ b/tools/perf/util/symbol.c
@@ -186,7 +186,7 @@ void symbols__fixup_end(struct rb_root *symbols)
186 curr = rb_entry(nd, struct symbol, rb_node); 186 curr = rb_entry(nd, struct symbol, rb_node);
187 187
188 if (prev->end == prev->start && prev->end != curr->start) 188 if (prev->end == prev->start && prev->end != curr->start)
189 prev->end = curr->start - 1; 189 prev->end = curr->start;
190 } 190 }
191 191
192 /* Last entry */ 192 /* Last entry */
@@ -207,7 +207,7 @@ void __map_groups__fixup_end(struct map_groups *mg, enum map_type type)
207 for (nd = rb_next(prevnd); nd; nd = rb_next(nd)) { 207 for (nd = rb_next(prevnd); nd; nd = rb_next(nd)) {
208 prev = curr; 208 prev = curr;
209 curr = rb_entry(nd, struct map, rb_node); 209 curr = rb_entry(nd, struct map, rb_node);
210 prev->end = curr->start - 1; 210 prev->end = curr->start;
211 } 211 }
212 212
213 /* 213 /*
@@ -229,7 +229,7 @@ struct symbol *symbol__new(u64 start, u64 len, u8 binding, const char *name)
229 sym = ((void *)sym) + symbol_conf.priv_size; 229 sym = ((void *)sym) + symbol_conf.priv_size;
230 230
231 sym->start = start; 231 sym->start = start;
232 sym->end = len ? start + len - 1 : start; 232 sym->end = len ? start + len : start;
233 sym->binding = binding; 233 sym->binding = binding;
234 sym->namelen = namelen - 1; 234 sym->namelen = namelen - 1;
235 235
@@ -325,7 +325,7 @@ static struct symbol *symbols__find(struct rb_root *symbols, u64 ip)
325 325
326 if (ip < s->start) 326 if (ip < s->start)
327 n = n->rb_left; 327 n = n->rb_left;
328 else if (ip > s->end) 328 else if (ip >= s->end)
329 n = n->rb_right; 329 n = n->rb_right;
330 else 330 else
331 return s; 331 return s;
diff --git a/tools/perf/util/symbol.h b/tools/perf/util/symbol.h
index bec4b7bd09de..eb2c19bf8d90 100644
--- a/tools/perf/util/symbol.h
+++ b/tools/perf/util/symbol.h
@@ -95,7 +95,7 @@ void symbols__delete(struct rb_root *symbols);
95 95
96static inline size_t symbol__size(const struct symbol *sym) 96static inline size_t symbol__size(const struct symbol *sym)
97{ 97{
98 return sym->end - sym->start + 1; 98 return sym->end - sym->start;
99} 99}
100 100
101struct strlist; 101struct strlist;
diff --git a/tools/perf/util/thread.c b/tools/perf/util/thread.c
index a9df7f2c6dc9..2b7b2d91c016 100644
--- a/tools/perf/util/thread.c
+++ b/tools/perf/util/thread.c
@@ -7,6 +7,7 @@
7#include "util.h" 7#include "util.h"
8#include "debug.h" 8#include "debug.h"
9#include "comm.h" 9#include "comm.h"
10#include "unwind.h"
10 11
11int thread__init_map_groups(struct thread *thread, struct machine *machine) 12int thread__init_map_groups(struct thread *thread, struct machine *machine)
12{ 13{
@@ -37,6 +38,9 @@ struct thread *thread__new(pid_t pid, pid_t tid)
37 thread->cpu = -1; 38 thread->cpu = -1;
38 INIT_LIST_HEAD(&thread->comm_list); 39 INIT_LIST_HEAD(&thread->comm_list);
39 40
41 if (unwind__prepare_access(thread) < 0)
42 goto err_thread;
43
40 comm_str = malloc(32); 44 comm_str = malloc(32);
41 if (!comm_str) 45 if (!comm_str)
42 goto err_thread; 46 goto err_thread;
@@ -48,6 +52,7 @@ struct thread *thread__new(pid_t pid, pid_t tid)
48 goto err_thread; 52 goto err_thread;
49 53
50 list_add(&comm->list, &thread->comm_list); 54 list_add(&comm->list, &thread->comm_list);
55
51 } 56 }
52 57
53 return thread; 58 return thread;
@@ -69,6 +74,7 @@ void thread__delete(struct thread *thread)
69 list_del(&comm->list); 74 list_del(&comm->list);
70 comm__free(comm); 75 comm__free(comm);
71 } 76 }
77 unwind__finish_access(thread);
72 78
73 free(thread); 79 free(thread);
74} 80}
diff --git a/tools/perf/util/thread_map.c b/tools/perf/util/thread_map.c
index 5d3215912105..f93b9734735b 100644
--- a/tools/perf/util/thread_map.c
+++ b/tools/perf/util/thread_map.c
@@ -214,6 +214,17 @@ out_free_threads:
214 goto out; 214 goto out;
215} 215}
216 216
217struct thread_map *thread_map__new_dummy(void)
218{
219 struct thread_map *threads = malloc(sizeof(*threads) + sizeof(pid_t));
220
221 if (threads != NULL) {
222 threads->map[0] = -1;
223 threads->nr = 1;
224 }
225 return threads;
226}
227
217static struct thread_map *thread_map__new_by_tid_str(const char *tid_str) 228static struct thread_map *thread_map__new_by_tid_str(const char *tid_str)
218{ 229{
219 struct thread_map *threads = NULL, *nt; 230 struct thread_map *threads = NULL, *nt;
@@ -224,14 +235,8 @@ static struct thread_map *thread_map__new_by_tid_str(const char *tid_str)
224 struct strlist *slist; 235 struct strlist *slist;
225 236
226 /* perf-stat expects threads to be generated even if tid not given */ 237 /* perf-stat expects threads to be generated even if tid not given */
227 if (!tid_str) { 238 if (!tid_str)
228 threads = malloc(sizeof(*threads) + sizeof(pid_t)); 239 return thread_map__new_dummy();
229 if (threads != NULL) {
230 threads->map[0] = -1;
231 threads->nr = 1;
232 }
233 return threads;
234 }
235 240
236 slist = strlist__new(false, tid_str); 241 slist = strlist__new(false, tid_str);
237 if (!slist) 242 if (!slist)
diff --git a/tools/perf/util/thread_map.h b/tools/perf/util/thread_map.h
index 0cd8b3108084..95313f43cc0f 100644
--- a/tools/perf/util/thread_map.h
+++ b/tools/perf/util/thread_map.h
@@ -9,6 +9,7 @@ struct thread_map {
9 pid_t map[]; 9 pid_t map[];
10}; 10};
11 11
12struct thread_map *thread_map__new_dummy(void);
12struct thread_map *thread_map__new_by_pid(pid_t pid); 13struct thread_map *thread_map__new_by_pid(pid_t pid);
13struct thread_map *thread_map__new_by_tid(pid_t tid); 14struct thread_map *thread_map__new_by_tid(pid_t tid);
14struct thread_map *thread_map__new_by_uid(uid_t uid); 15struct thread_map *thread_map__new_by_uid(uid_t uid);
diff --git a/tools/perf/util/unwind-libunwind.c b/tools/perf/util/unwind-libunwind.c
index 92b56db52471..e060386165c5 100644
--- a/tools/perf/util/unwind-libunwind.c
+++ b/tools/perf/util/unwind-libunwind.c
@@ -24,6 +24,7 @@
24#include <linux/list.h> 24#include <linux/list.h>
25#include <libunwind.h> 25#include <libunwind.h>
26#include <libunwind-ptrace.h> 26#include <libunwind-ptrace.h>
27#include "callchain.h"
27#include "thread.h" 28#include "thread.h"
28#include "session.h" 29#include "session.h"
29#include "perf_regs.h" 30#include "perf_regs.h"
@@ -525,12 +526,12 @@ static unw_accessors_t accessors = {
525 .get_proc_name = get_proc_name, 526 .get_proc_name = get_proc_name,
526}; 527};
527 528
528static int get_entries(struct unwind_info *ui, unwind_entry_cb_t cb, 529int unwind__prepare_access(struct thread *thread)
529 void *arg, int max_stack)
530{ 530{
531 unw_addr_space_t addr_space; 531 unw_addr_space_t addr_space;
532 unw_cursor_t c; 532
533 int ret; 533 if (callchain_param.record_mode != CALLCHAIN_DWARF)
534 return 0;
534 535
535 addr_space = unw_create_addr_space(&accessors, 0); 536 addr_space = unw_create_addr_space(&accessors, 0);
536 if (!addr_space) { 537 if (!addr_space) {
@@ -538,6 +539,33 @@ static int get_entries(struct unwind_info *ui, unwind_entry_cb_t cb,
538 return -ENOMEM; 539 return -ENOMEM;
539 } 540 }
540 541
542 thread__set_priv(thread, addr_space);
543
544 return 0;
545}
546
547void unwind__finish_access(struct thread *thread)
548{
549 unw_addr_space_t addr_space;
550
551 if (callchain_param.record_mode != CALLCHAIN_DWARF)
552 return;
553
554 addr_space = thread__priv(thread);
555 unw_destroy_addr_space(addr_space);
556}
557
558static int get_entries(struct unwind_info *ui, unwind_entry_cb_t cb,
559 void *arg, int max_stack)
560{
561 unw_addr_space_t addr_space;
562 unw_cursor_t c;
563 int ret;
564
565 addr_space = thread__priv(ui->thread);
566 if (addr_space == NULL)
567 return -1;
568
541 ret = unw_init_remote(&c, addr_space, ui); 569 ret = unw_init_remote(&c, addr_space, ui);
542 if (ret) 570 if (ret)
543 display_error(ret); 571 display_error(ret);
@@ -549,7 +577,6 @@ static int get_entries(struct unwind_info *ui, unwind_entry_cb_t cb,
549 ret = ip ? entry(ip, ui->thread, ui->machine, cb, arg) : 0; 577 ret = ip ? entry(ip, ui->thread, ui->machine, cb, arg) : 0;
550 } 578 }
551 579
552 unw_destroy_addr_space(addr_space);
553 return ret; 580 return ret;
554} 581}
555 582
diff --git a/tools/perf/util/unwind.h b/tools/perf/util/unwind.h
index f03061260b4e..c17c4855bdbc 100644
--- a/tools/perf/util/unwind.h
+++ b/tools/perf/util/unwind.h
@@ -4,6 +4,7 @@
4#include <linux/types.h> 4#include <linux/types.h>
5#include "event.h" 5#include "event.h"
6#include "symbol.h" 6#include "symbol.h"
7#include "thread.h"
7 8
8struct unwind_entry { 9struct unwind_entry {
9 struct map *map; 10 struct map *map;
@@ -21,6 +22,15 @@ int unwind__get_entries(unwind_entry_cb_t cb, void *arg,
21/* libunwind specific */ 22/* libunwind specific */
22#ifdef HAVE_LIBUNWIND_SUPPORT 23#ifdef HAVE_LIBUNWIND_SUPPORT
23int libunwind__arch_reg_id(int regnum); 24int libunwind__arch_reg_id(int regnum);
25int unwind__prepare_access(struct thread *thread);
26void unwind__finish_access(struct thread *thread);
27#else
28static inline int unwind__prepare_access(struct thread *thread __maybe_unused)
29{
30 return 0;
31}
32
33static inline void unwind__finish_access(struct thread *thread __maybe_unused) {}
24#endif 34#endif
25#else 35#else
26static inline int 36static inline int
@@ -33,5 +43,12 @@ unwind__get_entries(unwind_entry_cb_t cb __maybe_unused,
33{ 43{
34 return 0; 44 return 0;
35} 45}
46
47static inline int unwind__prepare_access(struct thread *thread __maybe_unused)
48{
49 return 0;
50}
51
52static inline void unwind__finish_access(struct thread *thread __maybe_unused) {}
36#endif /* HAVE_DWARF_UNWIND_SUPPORT */ 53#endif /* HAVE_DWARF_UNWIND_SUPPORT */
37#endif /* __UNWIND_H */ 54#endif /* __UNWIND_H */
diff --git a/tools/perf/util/util.c b/tools/perf/util/util.c
index 24e8d871b74e..d5eab3f3323f 100644
--- a/tools/perf/util/util.c
+++ b/tools/perf/util/util.c
@@ -14,6 +14,14 @@
14#include <byteswap.h> 14#include <byteswap.h>
15#include <linux/kernel.h> 15#include <linux/kernel.h>
16#include <unistd.h> 16#include <unistd.h>
17#include "callchain.h"
18
19struct callchain_param callchain_param = {
20 .mode = CHAIN_GRAPH_REL,
21 .min_percent = 0.5,
22 .order = ORDER_CALLEE,
23 .key = CCKEY_FUNCTION
24};
17 25
18/* 26/*
19 * XXX We need to find a better place for these things... 27 * XXX We need to find a better place for these things...