Commit | Line | Data |
---|---|---|
b2441318 | 1 | /* SPDX-License-Identifier: GPL-2.0 */ |
8b40f521 JK |
2 | #ifndef __PERF_PARSE_EVENTS_H |
3 | #define __PERF_PARSE_EVENTS_H | |
5242519b IM |
4 | /* |
5 | * Parse symbolic events/counts passed in as options: | |
6 | */ | |
7 | ||
f50246e2 | 8 | #include <linux/list.h> |
c651214e | 9 | #include <stdbool.h> |
d944c4ee | 10 | #include <linux/types.h> |
d2709c7c | 11 | #include <linux/perf_event.h> |
edb217ff | 12 | #include <stdio.h> |
af9100ad | 13 | #include <string.h> |
69aad6f1 | 14 | |
32dcd021 | 15 | struct evsel; |
63503dba | 16 | struct evlist; |
b39b8393 | 17 | struct parse_events_error; |
69aad6f1 | 18 | |
5beeded1 | 19 | struct option; |
70943490 | 20 | struct perf_pmu; |
7a6e9164 | 21 | struct strbuf; |
5beeded1 | 22 | |
1424dc96 | 23 | const char *event_type(int type); |
8ad8db37 | 24 | |
411ad22e IR |
25 | /* Arguments encoded in opt->value. */ |
26 | struct parse_events_option_args { | |
27 | struct evlist **evlistp; | |
28 | const char *pmu_filter; | |
29 | }; | |
3938bad4 | 30 | int parse_events_option(const struct option *opt, const char *str, int unset); |
d0abbc3c | 31 | int parse_events_option_new_evlist(const struct option *opt, const char *str, int unset); |
411ad22e IR |
32 | __attribute__((nonnull(1, 2, 4))) |
33 | int __parse_events(struct evlist *evlist, const char *str, const char *pmu_filter, | |
92532073 | 34 | struct parse_events_error *error, bool fake_pmu, |
a2a6604e | 35 | bool warn_if_reordered, bool fake_tp); |
3bf91aa5 | 36 | |
a4c7d7c5 | 37 | __attribute__((nonnull(1, 2, 3))) |
3bf91aa5 ACM |
38 | static inline int parse_events(struct evlist *evlist, const char *str, |
39 | struct parse_events_error *err) | |
40 | { | |
92532073 | 41 | return __parse_events(evlist, str, /*pmu_filter=*/NULL, err, /*fake_pmu=*/false, |
a2a6604e | 42 | /*warn_if_reordered=*/true, /*fake_tp=*/false); |
3bf91aa5 ACM |
43 | } |
44 | ||
806731a9 AH |
45 | int parse_event(struct evlist *evlist, const char *str); |
46 | ||
3938bad4 ACM |
47 | int parse_filter(const struct option *opt, const char *str, int unset); |
48 | int exclude_perf(const struct option *opt, const char *arg, int unset); | |
8ad8db37 | 49 | |
58d3a4ce | 50 | enum parse_events__term_val_type { |
16fa7e82 JO |
51 | PARSE_EVENTS__TERM_TYPE_NUM, |
52 | PARSE_EVENTS__TERM_TYPE_STR, | |
53 | }; | |
54 | ||
58d3a4ce | 55 | enum parse_events__term_type { |
16fa7e82 | 56 | PARSE_EVENTS__TERM_TYPE_USER, |
8f707d84 JO |
57 | PARSE_EVENTS__TERM_TYPE_CONFIG, |
58 | PARSE_EVENTS__TERM_TYPE_CONFIG1, | |
59 | PARSE_EVENTS__TERM_TYPE_CONFIG2, | |
204e7c49 | 60 | PARSE_EVENTS__TERM_TYPE_CONFIG3, |
6b5fc39b | 61 | PARSE_EVENTS__TERM_TYPE_NAME, |
8f707d84 | 62 | PARSE_EVENTS__TERM_TYPE_SAMPLE_PERIOD, |
09af2a55 | 63 | PARSE_EVENTS__TERM_TYPE_SAMPLE_FREQ, |
8f707d84 | 64 | PARSE_EVENTS__TERM_TYPE_BRANCH_SAMPLE_TYPE, |
32067712 | 65 | PARSE_EVENTS__TERM_TYPE_TIME, |
d457c963 KL |
66 | PARSE_EVENTS__TERM_TYPE_CALLGRAPH, |
67 | PARSE_EVENTS__TERM_TYPE_STACKSIZE, | |
374ce938 | 68 | PARSE_EVENTS__TERM_TYPE_NOINHERIT, |
17cb5f84 | 69 | PARSE_EVENTS__TERM_TYPE_INHERIT, |
792d48b4 | 70 | PARSE_EVENTS__TERM_TYPE_MAX_STACK, |
2fda5ada | 71 | PARSE_EVENTS__TERM_TYPE_MAX_EVENTS, |
626a6b78 WN |
72 | PARSE_EVENTS__TERM_TYPE_NOOVERWRITE, |
73 | PARSE_EVENTS__TERM_TYPE_OVERWRITE, | |
dd60fba7 | 74 | PARSE_EVENTS__TERM_TYPE_DRV_CFG, |
064b4e82 | 75 | PARSE_EVENTS__TERM_TYPE_PERCORE, |
1b992154 | 76 | PARSE_EVENTS__TERM_TYPE_AUX_OUTPUT, |
eb7a52d4 | 77 | PARSE_EVENTS__TERM_TYPE_AUX_SAMPLE_SIZE, |
2b62b3a6 | 78 | PARSE_EVENTS__TERM_TYPE_METRIC_ID, |
70c90e4a | 79 | PARSE_EVENTS__TERM_TYPE_RAW, |
6fd1e519 | 80 | PARSE_EVENTS__TERM_TYPE_LEGACY_CACHE, |
5ea8f2cc | 81 | PARSE_EVENTS__TERM_TYPE_HARDWARE, |
58d3a4ce | 82 | #define __PARSE_EVENTS__TERM_TYPE_NR (PARSE_EVENTS__TERM_TYPE_HARDWARE + 1) |
8f707d84 JO |
83 | }; |
84 | ||
6cee6cd3 | 85 | struct parse_events_term { |
58d3a4ce IR |
86 | /** @list: The term list the term is a part of. */ |
87 | struct list_head list; | |
88 | /** | |
89 | * @config: The left-hand side of a term assignment, so the term | |
90 | * "event=8" would have the config be "event" | |
91 | */ | |
970ef02e | 92 | const char *config; |
58d3a4ce IR |
93 | /** |
94 | * @val: The right-hand side of a term assignment that can either be a | |
95 | * string or a number depending on type_val. | |
96 | */ | |
8f707d84 JO |
97 | union { |
98 | char *str; | |
b527bab5 | 99 | u64 num; |
8f707d84 | 100 | } val; |
58d3a4ce IR |
101 | /** @type_val: The union variable in val to be used for the term. */ |
102 | enum parse_events__term_val_type type_val; | |
103 | /** | |
104 | * @type_term: A predefined term type or PARSE_EVENTS__TERM_TYPE_USER | |
105 | * when not inbuilt. | |
106 | */ | |
107 | enum parse_events__term_type type_term; | |
108 | /** | |
109 | * @err_term: The column index of the term from parsing, used during | |
110 | * error output. | |
111 | */ | |
cecf3a2e | 112 | int err_term; |
58d3a4ce IR |
113 | /** |
114 | * @err_val: The column index of the val from parsing, used during error | |
115 | * output. | |
116 | */ | |
cecf3a2e | 117 | int err_val; |
58d3a4ce IR |
118 | /** @used: Was the term used during parameterized-eval. */ |
119 | bool used; | |
120 | /** | |
121 | * @weak: A term from the sysfs or json encoding of an event that | |
122 | * shouldn't override terms coming from the command line. | |
123 | */ | |
59622fd4 | 124 | bool weak; |
58d3a4ce | 125 | /** |
9ea150a8 IR |
126 | * @no_value: Is there no value. If a numeric term has no value then the |
127 | * value is assumed to be 1. An event name also has no value. | |
58d3a4ce IR |
128 | */ |
129 | bool no_value; | |
8f707d84 JO |
130 | }; |
131 | ||
b39b8393 | 132 | struct parse_events_error { |
fd7b8e8f IR |
133 | /** @list: The head of a list of errors. */ |
134 | struct list_head list; | |
b39b8393 JO |
135 | }; |
136 | ||
0d3f0e6f IR |
137 | /* A wrapper around a list of terms for the sake of better type safety. */ |
138 | struct parse_events_terms { | |
139 | struct list_head terms; | |
140 | }; | |
141 | ||
5d369a75 | 142 | struct parse_events_state { |
22881e2b | 143 | /* The list parsed events are placed on. */ |
b39b8393 | 144 | struct list_head list; |
22881e2b | 145 | /* The updated index used by entries as they are added. */ |
b39b8393 | 146 | int idx; |
22881e2b | 147 | /* Error information. */ |
b39b8393 | 148 | struct parse_events_error *error; |
22881e2b | 149 | /* Holds returned terms for term parsing. */ |
0d3f0e6f | 150 | struct parse_events_terms *terms; |
22881e2b | 151 | /* Start token. */ |
1244a327 | 152 | int stoken; |
92532073 IR |
153 | /* Use the fake PMU marker for testing. */ |
154 | bool fake_pmu; | |
a2a6604e DM |
155 | /* Skip actual tracepoint processing for testing. */ |
156 | bool fake_tp; | |
411ad22e IR |
157 | /* If non-null, when wildcard matching only match the given PMU. */ |
158 | const char *pmu_filter; | |
6fd1e519 IR |
159 | /* Should PE_LEGACY_NAME tokens be generated for config terms? */ |
160 | bool match_legacy_cache_terms; | |
22881e2b | 161 | /* Were multiple PMUs scanned to find events? */ |
a4c7d7c5 | 162 | bool wild_card_pmus; |
90e2b22d JO |
163 | }; |
164 | ||
411ad22e IR |
165 | bool parse_events__filter_pmu(const struct parse_events_state *parse_state, |
166 | const struct perf_pmu *pmu); | |
1669e509 | 167 | void parse_events__shrink_config_terms(void); |
6cee6cd3 | 168 | int parse_events__is_hardcoded_term(struct parse_events_term *term); |
bb78ce7d | 169 | int parse_events_term__num(struct parse_events_term **term, |
58d3a4ce IR |
170 | enum parse_events__term_type type_term, |
171 | const char *config, u64 num, | |
99e7138e | 172 | bool novalue, |
bb78ce7d AH |
173 | void *loc_term, void *loc_val); |
174 | int parse_events_term__str(struct parse_events_term **term, | |
58d3a4ce IR |
175 | enum parse_events__term_type type_term, |
176 | char *config, char *str, | |
bb78ce7d | 177 | void *loc_term, void *loc_val); |
e831f3cc | 178 | int parse_events_term__term(struct parse_events_term **term, |
58d3a4ce IR |
179 | enum parse_events__term_type term_lhs, |
180 | enum parse_events__term_type term_rhs, | |
e831f3cc | 181 | void *loc_term, void *loc_val); |
6cee6cd3 | 182 | int parse_events_term__clone(struct parse_events_term **new, |
aa1551f2 | 183 | const struct parse_events_term *term); |
1dc92556 | 184 | void parse_events_term__delete(struct parse_events_term *term); |
0d3f0e6f IR |
185 | |
186 | void parse_events_terms__delete(struct parse_events_terms *terms); | |
187 | void parse_events_terms__init(struct parse_events_terms *terms); | |
188 | void parse_events_terms__exit(struct parse_events_terms *terms); | |
189 | int parse_events_terms(struct parse_events_terms *terms, const char *str, FILE *input); | |
190 | int parse_events_terms__to_strbuf(const struct parse_events_terms *terms, struct strbuf *sb); | |
e30a7912 IR |
191 | |
192 | struct parse_events_modifier { | |
193 | u8 precise; /* Number of repeated 'p' for precision. */ | |
194 | bool precise_max : 1; /* 'P' */ | |
195 | bool non_idle : 1; /* 'I' */ | |
196 | bool sample_read : 1; /* 'S' */ | |
197 | bool pinned : 1; /* 'D' */ | |
198 | bool exclusive : 1; /* 'e' */ | |
199 | bool weak : 1; /* 'W' */ | |
200 | bool bpf : 1; /* 'b' */ | |
201 | bool user : 1; /* 'u' */ | |
202 | bool kernel : 1; /* 'k' */ | |
203 | bool hypervisor : 1; /* 'h' */ | |
204 | bool guest : 1; /* 'G' */ | |
205 | bool host : 1; /* 'H' */ | |
807746b9 | 206 | bool retire_lat : 1; /* 'R' */ |
e30a7912 IR |
207 | }; |
208 | ||
209 | int parse_events__modifier_event(struct parse_events_state *parse_state, void *loc, | |
210 | struct list_head *list, struct parse_events_modifier mod); | |
211 | int parse_events__modifier_group(struct parse_events_state *parse_state, void *loc, | |
212 | struct list_head *list, struct parse_events_modifier mod); | |
bb65ff78 | 213 | int parse_events__set_default_name(struct list_head *list, char *name); |
11a42964 DM |
214 | int parse_events_add_tracepoint(struct parse_events_state *parse_state, |
215 | struct list_head *list, | |
8c619d6a | 216 | const char *sys, const char *event, |
e637d177 | 217 | struct parse_events_error *error, |
0d3f0e6f | 218 | struct parse_events_terms *head_config, void *loc); |
5d9cdc11 | 219 | int parse_events_add_numeric(struct parse_events_state *parse_state, |
87d650be | 220 | struct list_head *list, |
b527bab5 | 221 | u32 type, u64 config, |
5ccc4edf | 222 | const struct parse_events_terms *head_config, |
8bc75f69 | 223 | bool wildcard); |
f0fbb114 AK |
224 | int parse_events_add_tool(struct parse_events_state *parse_state, |
225 | struct list_head *list, | |
8228e936 | 226 | int tool_event); |
70c90e4a | 227 | int parse_events_add_cache(struct list_head *list, int *idx, const char *name, |
411ad22e | 228 | struct parse_events_state *parse_state, |
62593394 | 229 | struct parse_events_terms *parsed_terms); |
d7f21df0 | 230 | int parse_events__decode_legacy_cache(const char *name, int pmu_type, __u64 *config); |
f0617f52 AH |
231 | int parse_events_add_breakpoint(struct parse_events_state *parse_state, |
232 | struct list_head *list, | |
233 | u64 addr, char *type, u64 len, | |
0d3f0e6f | 234 | struct parse_events_terms *head_config); |
2073ad33 | 235 | |
70943490 | 236 | struct evsel *parse_events__add_event(int idx, struct perf_event_attr *attr, |
2b62b3a6 IR |
237 | const char *name, const char *metric_id, |
238 | struct perf_pmu *pmu); | |
70943490 | 239 | |
5d9cdc11 | 240 | int parse_events_multi_pmu_add(struct parse_events_state *parse_state, |
4f1b0673 | 241 | const char *event_name, |
0d3f0e6f | 242 | const struct parse_events_terms *const_parsed_terms, |
81a4e31f | 243 | struct list_head **listp, void *loc); |
2073ad33 | 244 | |
8b734eaa IR |
245 | int parse_events_multi_pmu_add_or_add_pmu(struct parse_events_state *parse_state, |
246 | const char *event_or_pmu, | |
247 | const struct parse_events_terms *const_parsed_terms, | |
248 | struct list_head **listp, | |
249 | void *loc_); | |
250 | ||
347c2f0a | 251 | void parse_events__set_leader(char *name, struct list_head *list); |
89812fc8 | 252 | |
705750f2 YS |
253 | struct event_symbol { |
254 | const char *symbol; | |
255 | const char *alias; | |
256 | }; | |
4a20e793 IR |
257 | extern const struct event_symbol event_symbols_hw[]; |
258 | extern const struct event_symbol event_symbols_sw[]; | |
9b7c7728 | 259 | |
ffeb883e | 260 | char *parse_events_formats_error_string(char *additional_terms); |
5beeded1 | 261 | |
07eafd4e IR |
262 | void parse_events_error__init(struct parse_events_error *err); |
263 | void parse_events_error__exit(struct parse_events_error *err); | |
6c191289 IR |
264 | void parse_events_error__handle(struct parse_events_error *err, int idx, |
265 | char *str, char *help); | |
fd7b8e8f | 266 | void parse_events_error__print(const struct parse_events_error *err, |
6c191289 | 267 | const char *event); |
fd7b8e8f IR |
268 | bool parse_events_error__contains(const struct parse_events_error *err, |
269 | const char *needle); | |
af9100ad RB |
270 | #ifdef HAVE_LIBELF_SUPPORT |
271 | /* | |
272 | * If the probe point starts with '%', | |
273 | * or starts with "sdt_" and has a ':' but no '=', | |
274 | * then it should be a SDT/cached probe point. | |
275 | */ | |
276 | static inline bool is_sdt_event(char *str) | |
277 | { | |
278 | return (str[0] == '%' || | |
279 | (!strncmp(str, "sdt_", 4) && | |
280 | !!strchr(str, ':') && !strchr(str, '='))); | |
281 | } | |
282 | #else | |
283 | static inline bool is_sdt_event(char *str __maybe_unused) | |
284 | { | |
285 | return false; | |
286 | } | |
287 | #endif /* HAVE_LIBELF_SUPPORT */ | |
288 | ||
70b27c75 IR |
289 | size_t default_breakpoint_len(void); |
290 | ||
8b40f521 | 291 | #endif /* __PERF_PARSE_EVENTS_H */ |