]>
Commit | Line | Data |
---|---|---|
b2441318 | 1 | /* SPDX-License-Identifier: GPL-2.0 */ |
69aad6f1 ACM |
2 | #ifndef __PERF_EVSEL_H |
3 | #define __PERF_EVSEL_H 1 | |
4 | ||
5 | #include <linux/list.h> | |
c52b12ed | 6 | #include <stdbool.h> |
f7004f59 | 7 | #include <sys/types.h> |
d2709c7c | 8 | #include <linux/perf_event.h> |
d944c4ee | 9 | #include <linux/types.h> |
b27c4ece | 10 | #include <internal/evsel.h> |
69714a4e | 11 | #include <perf/evsel.h> |
9cd997f8 | 12 | #include "symbol_conf.h" |
f7004f59 | 13 | #include <internal/cpumap.h> |
69aad6f1 | 14 | |
ca125277 ACM |
15 | struct bpf_object; |
16 | struct cgroup; | |
17 | struct perf_counts; | |
e669e833 | 18 | struct perf_stat_evsel; |
ca125277 | 19 | union perf_event; |
e669e833 | 20 | |
65ddce3f | 21 | typedef int (evsel__sb_cb_t)(union perf_event *event, void *data); |
657ee553 | 22 | |
f0fbb114 AK |
23 | enum perf_tool_event { |
24 | PERF_TOOL_NONE = 0, | |
25 | PERF_TOOL_DURATION_TIME = 1, | |
26 | }; | |
27 | ||
32dcd021 | 28 | /** struct evsel - event selector |
f0c55bcf | 29 | * |
d49e4695 | 30 | * @evlist - evlist this evsel is in, if it is in one. |
b27c4ece | 31 | * @core - libperf evsel object |
f0c55bcf SE |
32 | * @name - Can be set to retain the original event name passed by the user, |
33 | * so that when showing results in tools such as 'perf stat', we | |
34 | * show the name used, not some alias. | |
75562573 AH |
35 | * @id_pos: the position of the event id (PERF_SAMPLE_ID or |
36 | * PERF_SAMPLE_IDENTIFIER) in a sample event i.e. in the array of | |
69d81f09 | 37 | * struct perf_record_sample |
75562573 AH |
38 | * @is_pos: the position (counting backwards) of the event id (PERF_SAMPLE_ID or |
39 | * PERF_SAMPLE_IDENTIFIER) in a non-sample event i.e. if sample_id_all | |
40 | * is used there is an id sample appended to non-sample events | |
0db15b1e | 41 | * @priv: And what is in its containing unnamed union are tool specific |
f0c55bcf | 42 | */ |
32dcd021 | 43 | struct evsel { |
b27c4ece | 44 | struct perf_evsel core; |
63503dba | 45 | struct evlist *evlist; |
69aad6f1 | 46 | char *filter; |
c52b12ed | 47 | struct perf_counts *counts; |
c7a79c47 | 48 | struct perf_counts *prev_raw_counts; |
69aad6f1 | 49 | int idx; |
2fda5ada | 50 | unsigned long max_events; |
a9c5e6c1 | 51 | unsigned long nr_events_printed; |
f0c55bcf | 52 | char *name; |
410136f5 SE |
53 | double scale; |
54 | const char *unit; | |
97fbf3f0 | 55 | struct tep_event *tp_format; |
af339981 | 56 | off_t id_offset; |
e669e833 | 57 | struct perf_stat_evsel *stats; |
616df645 CP |
58 | void *priv; |
59 | u64 db_id; | |
3ca32f69 | 60 | struct cgroup *cgrp; |
744a9719 | 61 | void *handler; |
bde09467 | 62 | unsigned int sample_size; |
75562573 AH |
63 | int id_pos; |
64 | int is_pos; | |
f0fbb114 | 65 | enum perf_tool_event tool_event; |
80ee8c58 | 66 | bool uniquified_name; |
86066064 | 67 | bool snapshot; |
2cee77c4 | 68 | bool supported; |
0807d2d8 | 69 | bool needs_swap; |
b7e8452b | 70 | bool disabled; |
6ff1ce76 | 71 | bool no_aux_samples; |
2afd2bcf | 72 | bool immediate; |
60b0896c | 73 | bool tracking; |
044330c1 | 74 | bool per_pkg; |
7f94af7a | 75 | bool precise_max; |
a359c17a | 76 | bool ignore_missing_thread; |
8ef278bb | 77 | bool forced_leader; |
3cdc5c2c | 78 | bool use_uncore_alias; |
f5b1135b JO |
79 | /* parse modifier helper */ |
80 | int exclude_GH; | |
3c176311 | 81 | int sample_read; |
86066064 | 82 | unsigned long *per_pkg_mask; |
32dcd021 | 83 | struct evsel *leader; |
6a4bb04c | 84 | char *group_name; |
15bfd2cc | 85 | bool cmdline_group_boundary; |
930a2e29 | 86 | struct list_head config_terms; |
af4a0991 | 87 | struct bpf_object *bpf_obj; |
1f45b1d4 | 88 | int bpf_fd; |
4b49ab70 | 89 | int err; |
63ce8449 | 90 | bool auto_merge_stats; |
430daf2d | 91 | bool merged_stat; |
37932c18 | 92 | const char * metric_expr; |
96284814 | 93 | const char * metric_name; |
32dcd021 | 94 | struct evsel **metric_events; |
f01642e4 | 95 | struct evsel *metric_leader; |
37932c18 | 96 | bool collect_stat; |
5a5dfe4b | 97 | bool weak_group; |
4804e011 AK |
98 | bool reset_group; |
99 | bool errored; | |
064b4e82 | 100 | bool percore; |
a8cbe40f | 101 | int cpu_iter; |
8c5421c0 | 102 | const char *pmu_name; |
657ee553 | 103 | struct { |
65ddce3f ACM |
104 | evsel__sb_cb_t *cb; |
105 | void *data; | |
657ee553 | 106 | } side_band; |
e11869a0 AH |
107 | /* |
108 | * For reporting purposes, an evsel sample can have a callchain | |
109 | * synthesized from AUX area data. Keep track of synthesized sample | |
110 | * types here. Note, the recorded sample_type cannot be changed because | |
111 | * it is needed to continue to parse events. | |
112 | * See also evsel__has_callchain(). | |
113 | */ | |
114 | __u64 synth_sample_type; | |
69aad6f1 ACM |
115 | }; |
116 | ||
9a831b3a ACM |
117 | struct perf_missing_features { |
118 | bool sample_id_all; | |
119 | bool exclude_guest; | |
120 | bool mmap2; | |
121 | bool cloexec; | |
122 | bool clockid; | |
123 | bool clockid_wrong; | |
124 | bool lbr_flags; | |
125 | bool write_backward; | |
126 | bool group_read; | |
9aa0bfa3 | 127 | bool ksymbol; |
74a1e863 | 128 | bool bpf; |
acb9f2d4 | 129 | bool aux_output; |
d3f85437 | 130 | bool branch_hw_idx; |
8fb4b679 | 131 | bool cgroup; |
9a831b3a ACM |
132 | }; |
133 | ||
134 | extern struct perf_missing_features perf_missing_features; | |
135 | ||
f854839b | 136 | struct perf_cpu_map; |
80b2210c | 137 | struct target; |
86bd5e86 | 138 | struct thread_map; |
b4006796 | 139 | struct record_opts; |
86bd5e86 | 140 | |
b49aca3e | 141 | static inline struct perf_cpu_map *evsel__cpus(struct evsel *evsel) |
a22e99cd | 142 | { |
0ff1a0fd | 143 | return perf_evsel__cpus(&evsel->core); |
a22e99cd JO |
144 | } |
145 | ||
5eb88f04 | 146 | static inline int evsel__nr_cpus(struct evsel *evsel) |
a22e99cd | 147 | { |
b49aca3e | 148 | return evsel__cpus(evsel)->nr; |
a22e99cd JO |
149 | } |
150 | ||
13112bbf JO |
151 | void perf_counts_values__scale(struct perf_counts_values *count, |
152 | bool scale, s8 *pscaled); | |
153 | ||
12f5261d ACM |
154 | void evsel__compute_deltas(struct evsel *evsel, int cpu, int thread, |
155 | struct perf_counts_values *count); | |
857a94a2 | 156 | |
ce8ccff5 | 157 | int perf_evsel__object_config(size_t object_size, |
32dcd021 JO |
158 | int (*init)(struct evsel *evsel), |
159 | void (*fini)(struct evsel *evsel)); | |
ce8ccff5 | 160 | |
e76026bd | 161 | struct perf_pmu *evsel__find_pmu(struct evsel *evsel); |
39453ed5 | 162 | bool evsel__is_aux_event(struct evsel *evsel); |
e12ee9f7 | 163 | |
32dcd021 | 164 | struct evsel *perf_evsel__new_idx(struct perf_event_attr *attr, int idx); |
ef503831 | 165 | |
365c3ae7 | 166 | static inline struct evsel *evsel__new(struct perf_event_attr *attr) |
ef503831 ACM |
167 | { |
168 | return perf_evsel__new_idx(attr, 0); | |
169 | } | |
170 | ||
32dcd021 | 171 | struct evsel *perf_evsel__newtp_idx(const char *sys, const char *name, int idx); |
ef503831 | 172 | |
8dd2a131 JO |
173 | /* |
174 | * Returns pointer with encoded error via <linux/err.h> interface. | |
175 | */ | |
32dcd021 | 176 | static inline struct evsel *perf_evsel__newtp(const char *sys, const char *name) |
ef503831 ACM |
177 | { |
178 | return perf_evsel__newtp_idx(sys, name, 0); | |
179 | } | |
201b7334 | 180 | |
32dcd021 | 181 | struct evsel *perf_evsel__new_cycles(bool precise); |
7c48dcfd | 182 | |
97fbf3f0 | 183 | struct tep_event *event_format__new(const char *sys, const char *name); |
201b7334 | 184 | |
b4b62ee6 | 185 | void evsel__init(struct evsel *evsel, struct perf_event_attr *attr, int idx); |
30f7c591 | 186 | void evsel__exit(struct evsel *evsel); |
5eb2dd2a | 187 | void evsel__delete(struct evsel *evsel); |
69aad6f1 | 188 | |
e68ae9cf ACM |
189 | struct callchain_param; |
190 | ||
6ec17b4e ACM |
191 | void evsel__config(struct evsel *evsel, struct record_opts *opts, |
192 | struct callchain_param *callchain); | |
193 | void evsel__config_callchain(struct evsel *evsel, struct record_opts *opts, | |
194 | struct callchain_param *callchain); | |
0f82ebc4 | 195 | |
2aaefde4 | 196 | int __evsel__sample_size(u64 sample_type); |
4b5e87b7 | 197 | void evsel__calc_id_pos(struct evsel *evsel); |
75562573 | 198 | |
c754c382 | 199 | bool evsel__is_cache_op_valid(u8 type, u8 op); |
0b668bc9 ACM |
200 | |
201 | #define PERF_EVSEL__MAX_ALIASES 8 | |
202 | ||
203 | extern const char *perf_evsel__hw_cache[PERF_COUNT_HW_CACHE_MAX] | |
204 | [PERF_EVSEL__MAX_ALIASES]; | |
205 | extern const char *perf_evsel__hw_cache_op[PERF_COUNT_HW_CACHE_OP_MAX] | |
206 | [PERF_EVSEL__MAX_ALIASES]; | |
8ad7013b ACM |
207 | extern const char *perf_evsel__hw_cache_result[PERF_COUNT_HW_CACHE_RESULT_MAX] |
208 | [PERF_EVSEL__MAX_ALIASES]; | |
209 | extern const char *perf_evsel__hw_names[PERF_COUNT_HW_MAX]; | |
210 | extern const char *perf_evsel__sw_names[PERF_COUNT_SW_MAX]; | |
8ab2e96d ACM |
211 | int __evsel__hw_cache_type_op_res_name(u8 type, u8 op, u8 result, char *bf, size_t size); |
212 | const char *evsel__name(struct evsel *evsel); | |
410136f5 | 213 | |
8ab2e96d | 214 | const char *evsel__group_name(struct evsel *evsel); |
347c751a | 215 | int evsel__group_desc(struct evsel *evsel, char *buf, size_t size); |
c410431c | 216 | |
862b2f8f ACM |
217 | void __evsel__set_sample_bit(struct evsel *evsel, enum perf_event_sample_format bit); |
218 | void __evsel__reset_sample_bit(struct evsel *evsel, enum perf_event_sample_format bit); | |
7be5ebe8 | 219 | |
862b2f8f ACM |
220 | #define evsel__set_sample_bit(evsel, bit) \ |
221 | __evsel__set_sample_bit(evsel, PERF_SAMPLE_##bit) | |
7be5ebe8 | 222 | |
862b2f8f ACM |
223 | #define evsel__reset_sample_bit(evsel, bit) \ |
224 | __evsel__reset_sample_bit(evsel, PERF_SAMPLE_##bit) | |
7be5ebe8 | 225 | |
862b2f8f | 226 | void evsel__set_sample_id(struct evsel *evsel, bool use_sample_identifier); |
7a5a5ca5 | 227 | |
ad681adf ACM |
228 | int evsel__set_filter(struct evsel *evsel, const char *filter); |
229 | int evsel__append_tp_filter(struct evsel *evsel, const char *filter); | |
230 | int evsel__append_addr_filter(struct evsel *evsel, const char *filter); | |
363fb121 | 231 | int evsel__enable_cpu(struct evsel *evsel, int cpu); |
ec7f24ef | 232 | int evsel__enable(struct evsel *evsel); |
9a10bb22 | 233 | int evsel__disable(struct evsel *evsel); |
363fb121 | 234 | int evsel__disable_cpu(struct evsel *evsel, int cpu); |
745cefc5 | 235 | |
aa8c406b ACM |
236 | int evsel__open_per_cpu(struct evsel *evsel, struct perf_cpu_map *cpus, int cpu); |
237 | int evsel__open_per_thread(struct evsel *evsel, struct perf_thread_map *threads); | |
5972d1e0 JO |
238 | int evsel__open(struct evsel *evsel, struct perf_cpu_map *cpus, |
239 | struct perf_thread_map *threads); | |
88761fa1 | 240 | void evsel__close(struct evsel *evsel); |
48290609 | 241 | |
5555ded4 ACM |
242 | struct perf_sample; |
243 | ||
efc0cdc9 ACM |
244 | void *evsel__rawptr(struct evsel *evsel, struct perf_sample *sample, const char *name); |
245 | u64 evsel__intval(struct evsel *evsel, struct perf_sample *sample, const char *name); | |
246 | ||
247 | static inline char *evsel__strval(struct evsel *evsel, struct perf_sample *sample, const char *name) | |
5d2074ea | 248 | { |
efc0cdc9 | 249 | return evsel__rawptr(evsel, sample, name); |
5d2074ea ACM |
250 | } |
251 | ||
2c92f982 | 252 | struct tep_format_field; |
efd2b924 | 253 | |
2c92f982 | 254 | u64 format_field__intval(struct tep_format_field *field, struct perf_sample *sample, bool needs_swap); |
90525176 | 255 | |
efc0cdc9 | 256 | struct tep_format_field *evsel__field(struct evsel *evsel, const char *name); |
efd2b924 | 257 | |
c754c382 | 258 | #define evsel__match(evsel, t, c) \ |
1fc632ce JO |
259 | (evsel->core.attr.type == PERF_TYPE_##t && \ |
260 | evsel->core.attr.config == PERF_COUNT_##c) | |
daec78a0 | 261 | |
c754c382 | 262 | static inline bool evsel__match2(struct evsel *e1, struct evsel *e2) |
863e451f | 263 | { |
1fc632ce JO |
264 | return (e1->core.attr.type == e2->core.attr.type) && |
265 | (e1->core.attr.config == e2->core.attr.config); | |
863e451f JO |
266 | } |
267 | ||
ea089692 | 268 | int evsel__read_counter(struct evsel *evsel, int cpu, int thread); |
f7794d52 | 269 | |
ea089692 | 270 | int __evsel__read_on_cpu(struct evsel *evsel, int cpu, int thread, bool scale); |
c52b12ed ACM |
271 | |
272 | /** | |
ea089692 | 273 | * evsel__read_on_cpu - Read out the results on a CPU and thread |
c52b12ed ACM |
274 | * |
275 | * @evsel - event selector to read value | |
276 | * @cpu - CPU of interest | |
277 | * @thread - thread of interest | |
278 | */ | |
ea089692 | 279 | static inline int evsel__read_on_cpu(struct evsel *evsel, int cpu, int thread) |
c52b12ed | 280 | { |
ea089692 | 281 | return __evsel__read_on_cpu(evsel, cpu, thread, false); |
c52b12ed ACM |
282 | } |
283 | ||
284 | /** | |
ea089692 | 285 | * evsel__read_on_cpu_scaled - Read out the results on a CPU and thread, scaled |
c52b12ed ACM |
286 | * |
287 | * @evsel - event selector to read value | |
288 | * @cpu - CPU of interest | |
289 | * @thread - thread of interest | |
290 | */ | |
ea089692 | 291 | static inline int evsel__read_on_cpu_scaled(struct evsel *evsel, int cpu, int thread) |
c52b12ed | 292 | { |
ea089692 | 293 | return __evsel__read_on_cpu(evsel, cpu, thread, true); |
c52b12ed ACM |
294 | } |
295 | ||
6b6017a2 ACM |
296 | int evsel__parse_sample(struct evsel *evsel, union perf_event *event, |
297 | struct perf_sample *sample); | |
0c21f736 | 298 | |
6b6017a2 ACM |
299 | int evsel__parse_sample_timestamp(struct evsel *evsel, union perf_event *event, |
300 | u64 *timestamp); | |
01468120 | 301 | |
e470daea | 302 | static inline struct evsel *evsel__next(struct evsel *evsel) |
0c21f736 | 303 | { |
b27c4ece | 304 | return list_entry(evsel->core.node.next, struct evsel, core.node); |
0c21f736 | 305 | } |
07ac002f | 306 | |
e470daea | 307 | static inline struct evsel *evsel__prev(struct evsel *evsel) |
d87fcb4a | 308 | { |
b27c4ece | 309 | return list_entry(evsel->core.node.prev, struct evsel, core.node); |
d87fcb4a ACM |
310 | } |
311 | ||
759ff497 | 312 | /** |
c754c382 | 313 | * evsel__is_group_leader - Return whether given evsel is a leader event |
759ff497 NK |
314 | * |
315 | * @evsel - evsel selector to be tested | |
316 | * | |
317 | * Return %true if @evsel is a group leader or a stand-alone event | |
318 | */ | |
c754c382 | 319 | static inline bool evsel__is_group_leader(const struct evsel *evsel) |
07ac002f | 320 | { |
823254ed | 321 | return evsel->leader == evsel; |
07ac002f | 322 | } |
0698aedd | 323 | |
759ff497 | 324 | /** |
c754c382 | 325 | * evsel__is_group_event - Return whether given evsel is a group event |
759ff497 NK |
326 | * |
327 | * @evsel - evsel selector to be tested | |
328 | * | |
329 | * Return %true iff event group view is enabled and @evsel is a actual group | |
330 | * leader which has other members in the group | |
331 | */ | |
c754c382 | 332 | static inline bool evsel__is_group_event(struct evsel *evsel) |
759ff497 NK |
333 | { |
334 | if (!symbol_conf.event_group) | |
335 | return false; | |
336 | ||
c754c382 | 337 | return evsel__is_group_leader(evsel) && evsel->core.nr_members > 1; |
759ff497 NK |
338 | } |
339 | ||
c754c382 | 340 | bool evsel__is_function_event(struct evsel *evsel); |
6bedfab6 | 341 | |
c754c382 | 342 | static inline bool evsel__is_bpf_output(struct evsel *evsel) |
03e0a7df | 343 | { |
c754c382 | 344 | return evsel__match(evsel, SOFTWARE, SW_BPF_OUTPUT); |
03e0a7df WN |
345 | } |
346 | ||
c754c382 | 347 | static inline bool evsel__is_clock(struct evsel *evsel) |
0aa802a7 | 348 | { |
c754c382 ACM |
349 | return evsel__match(evsel, SOFTWARE, SW_CPU_CLOCK) || |
350 | evsel__match(evsel, SOFTWARE, SW_TASK_CLOCK); | |
0aa802a7 JO |
351 | } |
352 | ||
ae430892 | 353 | bool evsel__fallback(struct evsel *evsel, int err, char *msg, size_t msgsize); |
2bb72dbb ACM |
354 | int evsel__open_strerror(struct evsel *evsel, struct target *target, |
355 | int err, char *msg, size_t size); | |
97f63e4a | 356 | |
2bb72dbb | 357 | static inline int evsel__group_idx(struct evsel *evsel) |
97f63e4a NK |
358 | { |
359 | return evsel->idx - evsel->leader->idx; | |
360 | } | |
717e263f | 361 | |
2bcf7306 | 362 | /* Iterates group WITHOUT the leader. */ |
717e263f | 363 | #define for_each_group_member(_evsel, _leader) \ |
b27c4ece | 364 | for ((_evsel) = list_entry((_leader)->core.node.next, struct evsel, core.node); \ |
717e263f | 365 | (_evsel) && (_evsel)->leader == (_leader); \ |
b27c4ece | 366 | (_evsel) = list_entry((_evsel)->core.node.next, struct evsel, core.node)) |
717e263f | 367 | |
2bcf7306 JO |
368 | /* Iterates group WITH the leader. */ |
369 | #define for_each_group_evsel(_evsel, _leader) \ | |
370 | for ((_evsel) = _leader; \ | |
371 | (_evsel) && (_evsel)->leader == (_leader); \ | |
b27c4ece | 372 | (_evsel) = list_entry((_evsel)->core.node.next, struct evsel, core.node)) |
2bcf7306 | 373 | |
4f138a9e | 374 | static inline bool evsel__has_branch_callstack(const struct evsel *evsel) |
384b6055 | 375 | { |
1fc632ce | 376 | return evsel->core.attr.branch_sample_type & PERF_SAMPLE_BRANCH_CALL_STACK; |
384b6055 | 377 | } |
2c5e8c52 | 378 | |
4f138a9e | 379 | static inline bool evsel__has_branch_hw_idx(const struct evsel *evsel) |
42bbabed KL |
380 | { |
381 | return evsel->core.attr.branch_sample_type & PERF_SAMPLE_BRANCH_HW_INDEX; | |
382 | } | |
383 | ||
32dcd021 | 384 | static inline bool evsel__has_callchain(const struct evsel *evsel) |
27de9b2b | 385 | { |
e11869a0 AH |
386 | /* |
387 | * For reporting purposes, an evsel sample can have a recorded callchain | |
388 | * or a callchain synthesized from AUX area data. | |
389 | */ | |
390 | return evsel->core.attr.sample_type & PERF_SAMPLE_CALLCHAIN || | |
391 | evsel->synth_sample_type & PERF_SAMPLE_CALLCHAIN; | |
27de9b2b ACM |
392 | } |
393 | ||
6cd2cbfc AH |
394 | static inline bool evsel__has_br_stack(const struct evsel *evsel) |
395 | { | |
396 | /* | |
397 | * For reporting purposes, an evsel sample can have a recorded branch | |
398 | * stack or a branch stack synthesized from AUX area data. | |
399 | */ | |
400 | return evsel->core.attr.sample_type & PERF_SAMPLE_BRANCH_STACK || | |
401 | evsel->synth_sample_type & PERF_SAMPLE_BRANCH_STACK; | |
402 | } | |
403 | ||
32dcd021 | 404 | struct perf_env *perf_evsel__env(struct evsel *evsel); |
f4e47f9f | 405 | |
63503dba | 406 | int perf_evsel__store_ids(struct evsel *evsel, struct evlist *evlist); |
69aad6f1 | 407 | #endif /* __PERF_EVSEL_H */ |