xref: /linux/tools/perf/util/parse-events.h (revision 411ad22ecf0281d666a82aa7f4de90c70365da7d)
1b2441318SGreg Kroah-Hartman /* SPDX-License-Identifier: GPL-2.0 */
28b40f521SJohn Kacur #ifndef __PERF_PARSE_EVENTS_H
38b40f521SJohn Kacur #define __PERF_PARSE_EVENTS_H
45242519bSIngo Molnar /*
55242519bSIngo Molnar  * Parse symbolic events/counts passed in as options:
65242519bSIngo Molnar  */
75242519bSIngo Molnar 
8f50246e2SJiri Olsa #include <linux/list.h>
9c651214eSRobert Richter #include <stdbool.h>
10d944c4eeSBorislav Petkov #include <linux/types.h>
11d2709c7cSDavid Howells #include <linux/perf_event.h>
12af9100adSRavi Bangoria #include <string.h>
1369aad6f1SArnaldo Carvalho de Melo 
1432dcd021SJiri Olsa struct evsel;
1563503dbaSJiri Olsa struct evlist;
16b39b8393SJiri Olsa struct parse_events_error;
1769aad6f1SArnaldo Carvalho de Melo 
185beeded1SJason Baron struct option;
1970943490SStephane Eranian struct perf_pmu;
205beeded1SJason Baron 
2171c86cdaSZhengjun Xing bool is_event_supported(u8 type, u64 config);
221ef2ed10SFrederic Weisbecker 
231424dc96SDavid Ahern const char *event_type(int type);
248ad8db37SIngo Molnar 
25*411ad22eSIan Rogers /* Arguments encoded in opt->value. */
26*411ad22eSIan Rogers struct parse_events_option_args {
27*411ad22eSIan Rogers 	struct evlist **evlistp;
28*411ad22eSIan Rogers 	const char *pmu_filter;
29*411ad22eSIan Rogers };
303938bad4SArnaldo Carvalho de Melo int parse_events_option(const struct option *opt, const char *str, int unset);
31d0abbc3cSArnaldo Carvalho de Melo int parse_events_option_new_evlist(const struct option *opt, const char *str, int unset);
32*411ad22eSIan Rogers __attribute__((nonnull(1, 2, 4)))
33*411ad22eSIan Rogers int __parse_events(struct evlist *evlist, const char *str, const char *pmu_filter,
34*411ad22eSIan Rogers 		   struct parse_events_error *error, struct perf_pmu *fake_pmu,
35*411ad22eSIan Rogers 		   bool warn_if_reordered);
363bf91aa5SArnaldo Carvalho de Melo 
37a4c7d7c5SIan Rogers __attribute__((nonnull(1, 2, 3)))
383bf91aa5SArnaldo Carvalho de Melo static inline int parse_events(struct evlist *evlist, const char *str,
393bf91aa5SArnaldo Carvalho de Melo 			       struct parse_events_error *err)
403bf91aa5SArnaldo Carvalho de Melo {
41*411ad22eSIan Rogers 	return __parse_events(evlist, str, /*pmu_filter=*/NULL, err, /*fake_pmu=*/NULL,
42*411ad22eSIan Rogers 			      /*warn_if_reordered=*/true);
433bf91aa5SArnaldo Carvalho de Melo }
443bf91aa5SArnaldo Carvalho de Melo 
45806731a9SAdrian Hunter int parse_event(struct evlist *evlist, const char *str);
46806731a9SAdrian Hunter 
473938bad4SArnaldo Carvalho de Melo int parse_events_terms(struct list_head *terms, const char *str);
483938bad4SArnaldo Carvalho de Melo int parse_filter(const struct option *opt, const char *str, int unset);
493938bad4SArnaldo Carvalho de Melo int exclude_perf(const struct option *opt, const char *arg, int unset);
508ad8db37SIngo Molnar 
518f707d84SJiri Olsa enum {
5216fa7e82SJiri Olsa 	PARSE_EVENTS__TERM_TYPE_NUM,
5316fa7e82SJiri Olsa 	PARSE_EVENTS__TERM_TYPE_STR,
5416fa7e82SJiri Olsa };
5516fa7e82SJiri Olsa 
5616fa7e82SJiri Olsa enum {
5716fa7e82SJiri Olsa 	PARSE_EVENTS__TERM_TYPE_USER,
588f707d84SJiri Olsa 	PARSE_EVENTS__TERM_TYPE_CONFIG,
598f707d84SJiri Olsa 	PARSE_EVENTS__TERM_TYPE_CONFIG1,
608f707d84SJiri Olsa 	PARSE_EVENTS__TERM_TYPE_CONFIG2,
61204e7c49SRob Herring 	PARSE_EVENTS__TERM_TYPE_CONFIG3,
626b5fc39bSJiri Olsa 	PARSE_EVENTS__TERM_TYPE_NAME,
638f707d84SJiri Olsa 	PARSE_EVENTS__TERM_TYPE_SAMPLE_PERIOD,
6409af2a55SNamhyung Kim 	PARSE_EVENTS__TERM_TYPE_SAMPLE_FREQ,
658f707d84SJiri Olsa 	PARSE_EVENTS__TERM_TYPE_BRANCH_SAMPLE_TYPE,
6632067712SKan Liang 	PARSE_EVENTS__TERM_TYPE_TIME,
67d457c963SKan Liang 	PARSE_EVENTS__TERM_TYPE_CALLGRAPH,
68d457c963SKan Liang 	PARSE_EVENTS__TERM_TYPE_STACKSIZE,
69374ce938SWang Nan 	PARSE_EVENTS__TERM_TYPE_NOINHERIT,
7017cb5f84SWang Nan 	PARSE_EVENTS__TERM_TYPE_INHERIT,
71792d48b4SArnaldo Carvalho de Melo 	PARSE_EVENTS__TERM_TYPE_MAX_STACK,
722fda5adaSArnaldo Carvalho de Melo 	PARSE_EVENTS__TERM_TYPE_MAX_EVENTS,
73626a6b78SWang Nan 	PARSE_EVENTS__TERM_TYPE_NOOVERWRITE,
74626a6b78SWang Nan 	PARSE_EVENTS__TERM_TYPE_OVERWRITE,
75dd60fba7SMathieu Poirier 	PARSE_EVENTS__TERM_TYPE_DRV_CFG,
76064b4e82SJin Yao 	PARSE_EVENTS__TERM_TYPE_PERCORE,
771b992154SAdrian Hunter 	PARSE_EVENTS__TERM_TYPE_AUX_OUTPUT,
78eb7a52d4SAdrian Hunter 	PARSE_EVENTS__TERM_TYPE_AUX_SAMPLE_SIZE,
792b62b3a6SIan Rogers 	PARSE_EVENTS__TERM_TYPE_METRIC_ID,
8070c90e4aSIan Rogers 	PARSE_EVENTS__TERM_TYPE_RAW,
816fd1e519SIan Rogers 	PARSE_EVENTS__TERM_TYPE_LEGACY_CACHE,
8217cb5f84SWang Nan 	__PARSE_EVENTS__TERM_TYPE_NR,
838f707d84SJiri Olsa };
848f707d84SJiri Olsa 
852d055bf2SWang Nan struct parse_events_array {
862d055bf2SWang Nan 	size_t nr_ranges;
872d055bf2SWang Nan 	struct {
882d055bf2SWang Nan 		unsigned int start;
892d055bf2SWang Nan 		size_t length;
902d055bf2SWang Nan 	} *ranges;
912d055bf2SWang Nan };
922d055bf2SWang Nan 
936cee6cd3SArnaldo Carvalho de Melo struct parse_events_term {
948f707d84SJiri Olsa 	char *config;
952d055bf2SWang Nan 	struct parse_events_array array;
968f707d84SJiri Olsa 	union {
978f707d84SJiri Olsa 		char *str;
98b527bab5SRobert Richter 		u64  num;
998f707d84SJiri Olsa 	} val;
10016fa7e82SJiri Olsa 	int type_val;
10116fa7e82SJiri Olsa 	int type_term;
1028f707d84SJiri Olsa 	struct list_head list;
103688d4dfcSCody P Schafer 	bool used;
10499e7138eSJiri Olsa 	bool no_value;
105cecf3a2eSJiri Olsa 
106cecf3a2eSJiri Olsa 	/* error string indexes for within parsed string */
107cecf3a2eSJiri Olsa 	int err_term;
108cecf3a2eSJiri Olsa 	int err_val;
10959622fd4SAndi Kleen 
11059622fd4SAndi Kleen 	/* Coming from implicit alias */
11159622fd4SAndi Kleen 	bool weak;
1128f707d84SJiri Olsa };
1138f707d84SJiri Olsa 
114b39b8393SJiri Olsa struct parse_events_error {
115a910e466SIan Rogers 	int   num_errors;       /* number of errors encountered */
116b39b8393SJiri Olsa 	int   idx;	/* index in the parsed string */
117b39b8393SJiri Olsa 	char *str;      /* string to display at the index */
118b39b8393SJiri Olsa 	char *help;	/* optional help string */
119a910e466SIan Rogers 	int   first_idx;/* as above, but for the first encountered error */
120a910e466SIan Rogers 	char *first_str;
121a910e466SIan Rogers 	char *first_help;
122b39b8393SJiri Olsa };
123b39b8393SJiri Olsa 
1245d369a75SArnaldo Carvalho de Melo struct parse_events_state {
12546010ab2SJiri Olsa 	struct list_head	   list;
12646010ab2SJiri Olsa 	int			   idx;
127b39b8393SJiri Olsa 	struct parse_events_error *error;
12863503dbaSJiri Olsa 	struct evlist		  *evlist;
12990e2b22dSJiri Olsa 	struct list_head	  *terms;
1301244a327SJiri Olsa 	int			   stoken;
131387ad33fSJiri Olsa 	struct perf_pmu		  *fake_pmu;
132*411ad22eSIan Rogers 	/* If non-null, when wildcard matching only match the given PMU. */
133*411ad22eSIan Rogers 	const char		  *pmu_filter;
1346fd1e519SIan Rogers 	/* Should PE_LEGACY_NAME tokens be generated for config terms? */
1356fd1e519SIan Rogers 	bool			   match_legacy_cache_terms;
136a4c7d7c5SIan Rogers 	bool			   wild_card_pmus;
13790e2b22dSJiri Olsa };
13890e2b22dSJiri Olsa 
139*411ad22eSIan Rogers bool parse_events__filter_pmu(const struct parse_events_state *parse_state,
140*411ad22eSIan Rogers 			      const struct perf_pmu *pmu);
1411669e509SWang Nan void parse_events__shrink_config_terms(void);
1426cee6cd3SArnaldo Carvalho de Melo int parse_events__is_hardcoded_term(struct parse_events_term *term);
143bb78ce7dSAdrian Hunter int parse_events_term__num(struct parse_events_term **term,
144bb78ce7dSAdrian Hunter 			   int type_term, char *config, u64 num,
14599e7138eSJiri Olsa 			   bool novalue,
146bb78ce7dSAdrian Hunter 			   void *loc_term, void *loc_val);
147bb78ce7dSAdrian Hunter int parse_events_term__str(struct parse_events_term **term,
148bb78ce7dSAdrian Hunter 			   int type_term, char *config, char *str,
149bb78ce7dSAdrian Hunter 			   void *loc_term, void *loc_val);
1506cee6cd3SArnaldo Carvalho de Melo int parse_events_term__sym_hw(struct parse_events_term **term,
1511d33d6dcSJiri Olsa 			      char *config, unsigned idx);
1526cee6cd3SArnaldo Carvalho de Melo int parse_events_term__clone(struct parse_events_term **new,
1536cee6cd3SArnaldo Carvalho de Melo 			     struct parse_events_term *term);
1541dc92556SIan Rogers void parse_events_term__delete(struct parse_events_term *term);
1552146afc6SArnaldo Carvalho de Melo void parse_events_terms__delete(struct list_head *terms);
156fc0a2c1dSArnaldo Carvalho de Melo void parse_events_terms__purge(struct list_head *terms);
1572d055bf2SWang Nan void parse_events__clear_array(struct parse_events_array *a);
158f5b1135bSJiri Olsa int parse_events__modifier_event(struct list_head *list, char *str, bool add);
15989efb029SJiri Olsa int parse_events__modifier_group(struct list_head *list, char *event_mod);
1608e8bbfb3SIan Rogers int parse_events_name(struct list_head *list, const char *name);
161c5cd8ac0SDavid Ahern int parse_events_add_tracepoint(struct list_head *list, int *idx,
1628c619d6aSWang Nan 				const char *sys, const char *event,
163e637d177SHe Kuang 				struct parse_events_error *error,
164e637d177SHe Kuang 				struct list_head *head_config);
1655d9cdc11SArnaldo Carvalho de Melo int parse_events_load_bpf(struct parse_events_state *parse_state,
16684c86ca1SWang Nan 			  struct list_head *list,
167d509db04SWang Nan 			  char *bpf_file_name,
168a34f3be7SWang Nan 			  bool source,
169a34f3be7SWang Nan 			  struct list_head *head_config);
17084c86ca1SWang Nan /* Provide this function for perf test */
17184c86ca1SWang Nan struct bpf_object;
1725d9cdc11SArnaldo Carvalho de Melo int parse_events_load_bpf_obj(struct parse_events_state *parse_state,
17384c86ca1SWang Nan 			      struct list_head *list,
17495088a59SWang Nan 			      struct bpf_object *obj,
17595088a59SWang Nan 			      struct list_head *head_config);
1765d9cdc11SArnaldo Carvalho de Melo int parse_events_add_numeric(struct parse_events_state *parse_state,
17787d650beSJiri Olsa 			     struct list_head *list,
178b527bab5SRobert Richter 			     u32 type, u64 config,
1798bc75f69SIan Rogers 			     struct list_head *head_config,
1808bc75f69SIan Rogers 			     bool wildcard);
181f0fbb114SAndi Kleen int parse_events_add_tool(struct parse_events_state *parse_state,
182f0fbb114SAndi Kleen 			  struct list_head *list,
1838228e936SIan Rogers 			  int tool_event);
18470c90e4aSIan Rogers int parse_events_add_cache(struct list_head *list, int *idx, const char *name,
185*411ad22eSIan Rogers 			   struct parse_events_state *parse_state,
1862bdf4d7eSIan Rogers 			   struct list_head *head_config);
187d7f21df0SIan Rogers int parse_events__decode_legacy_cache(const char *name, int pmu_type, __u64 *config);
188c5cd8ac0SDavid Ahern int parse_events_add_breakpoint(struct list_head *list, int *idx,
189aa98d848SIan Rogers 				u64 addr, char *type, u64 len);
1905d9cdc11SArnaldo Carvalho de Melo int parse_events_add_pmu(struct parse_events_state *parse_state,
19136adec85SJiri Olsa 			 struct list_head *list, char *name,
192369b2308SKan Liang 			 struct list_head *head_config,
193e733f87eSIan Rogers 			 bool auto_merge_stats);
1942073ad33SAndi Kleen 
19570943490SStephane Eranian struct evsel *parse_events__add_event(int idx, struct perf_event_attr *attr,
1962b62b3a6SIan Rogers 				      const char *name, const char *metric_id,
1972b62b3a6SIan Rogers 				      struct perf_pmu *pmu);
19870943490SStephane Eranian 
1995d9cdc11SArnaldo Carvalho de Melo int parse_events_multi_pmu_add(struct parse_events_state *parse_state,
2002073ad33SAndi Kleen 			       char *str,
201fb081153SIan Rogers 			       struct list_head *head_config,
2022073ad33SAndi Kleen 			       struct list_head **listp);
2032073ad33SAndi Kleen 
2048255718fSAndi Kleen int parse_events_copy_term_list(struct list_head *old,
2058255718fSAndi Kleen 				 struct list_head **new);
2068255718fSAndi Kleen 
207347c2f0aSIan Rogers void parse_events__set_leader(char *name, struct list_head *list);
2085d7be90eSJiri Olsa void parse_events_update_lists(struct list_head *list_event,
2095d7be90eSJiri Olsa 			       struct list_head *list_all);
2105d9cdc11SArnaldo Carvalho de Melo void parse_events_evlist_error(struct parse_events_state *parse_state,
211b39b8393SJiri Olsa 			       int idx, const char *str);
21289812fc8SJiri Olsa 
213705750f2SYunlong Song struct event_symbol {
214705750f2SYunlong Song 	const char	*symbol;
215705750f2SYunlong Song 	const char	*alias;
216705750f2SYunlong Song };
217705750f2SYunlong Song extern struct event_symbol event_symbols_hw[];
218705750f2SYunlong Song extern struct event_symbol event_symbols_sw[];
2198ad8db37SIngo Molnar 
220ffeb883eSHe Kuang char *parse_events_formats_error_string(char *additional_terms);
2215beeded1SJason Baron 
22207eafd4eSIan Rogers void parse_events_error__init(struct parse_events_error *err);
22307eafd4eSIan Rogers void parse_events_error__exit(struct parse_events_error *err);
2246c191289SIan Rogers void parse_events_error__handle(struct parse_events_error *err, int idx,
2256c191289SIan Rogers 				char *str, char *help);
2266c191289SIan Rogers void parse_events_error__print(struct parse_events_error *err,
227333b5665SAndi Kleen 			       const char *event);
228333b5665SAndi Kleen 
229af9100adSRavi Bangoria #ifdef HAVE_LIBELF_SUPPORT
230af9100adSRavi Bangoria /*
231af9100adSRavi Bangoria  * If the probe point starts with '%',
232af9100adSRavi Bangoria  * or starts with "sdt_" and has a ':' but no '=',
233af9100adSRavi Bangoria  * then it should be a SDT/cached probe point.
234af9100adSRavi Bangoria  */
235af9100adSRavi Bangoria static inline bool is_sdt_event(char *str)
236af9100adSRavi Bangoria {
237af9100adSRavi Bangoria 	return (str[0] == '%' ||
238af9100adSRavi Bangoria 		(!strncmp(str, "sdt_", 4) &&
239af9100adSRavi Bangoria 		 !!strchr(str, ':') && !strchr(str, '=')));
240af9100adSRavi Bangoria }
241af9100adSRavi Bangoria #else
242af9100adSRavi Bangoria static inline bool is_sdt_event(char *str __maybe_unused)
243af9100adSRavi Bangoria {
244af9100adSRavi Bangoria 	return false;
245af9100adSRavi Bangoria }
246af9100adSRavi Bangoria #endif /* HAVE_LIBELF_SUPPORT */
247af9100adSRavi Bangoria 
2488b40f521SJohn Kacur #endif /* __PERF_PARSE_EVENTS_H */
249