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 1469aad6f1SArnaldo Carvalho de Melo struct list_head; 1532dcd021SJiri Olsa struct evsel; 1663503dbaSJiri Olsa struct evlist; 17b39b8393SJiri Olsa struct parse_events_error; 1869aad6f1SArnaldo Carvalho de Melo 195beeded1SJason Baron struct option; 2070943490SStephane Eranian struct perf_pmu; 215beeded1SJason Baron 221ef2ed10SFrederic Weisbecker struct tracepoint_path { 231ef2ed10SFrederic Weisbecker char *system; 241ef2ed10SFrederic Weisbecker char *name; 251ef2ed10SFrederic Weisbecker struct tracepoint_path *next; 261ef2ed10SFrederic Weisbecker }; 271ef2ed10SFrederic Weisbecker 283938bad4SArnaldo Carvalho de Melo struct tracepoint_path *tracepoint_id_to_path(u64 config); 293938bad4SArnaldo Carvalho de Melo struct tracepoint_path *tracepoint_name_to_path(const char *name); 303938bad4SArnaldo Carvalho de Melo bool have_tracepoints(struct list_head *evlist); 311ef2ed10SFrederic Weisbecker 321424dc96SDavid Ahern const char *event_type(int type); 338ad8db37SIngo Molnar 343938bad4SArnaldo Carvalho de Melo int parse_events_option(const struct option *opt, const char *str, int unset); 35d0abbc3cSArnaldo Carvalho de Melo int parse_events_option_new_evlist(const struct option *opt, const char *str, int unset); 363bf91aa5SArnaldo Carvalho de Melo int __parse_events(struct evlist *evlist, const char *str, struct parse_events_error *error, 373bf91aa5SArnaldo Carvalho de Melo struct perf_pmu *fake_pmu); 383bf91aa5SArnaldo Carvalho de Melo 393bf91aa5SArnaldo Carvalho de Melo static inline int parse_events(struct evlist *evlist, const char *str, 403bf91aa5SArnaldo Carvalho de Melo struct parse_events_error *err) 413bf91aa5SArnaldo Carvalho de Melo { 423bf91aa5SArnaldo Carvalho de Melo return __parse_events(evlist, str, err, NULL); 433bf91aa5SArnaldo Carvalho de Melo } 443bf91aa5SArnaldo Carvalho de Melo 453938bad4SArnaldo Carvalho de Melo int parse_events_terms(struct list_head *terms, const char *str); 463938bad4SArnaldo Carvalho de Melo int parse_filter(const struct option *opt, const char *str, int unset); 473938bad4SArnaldo Carvalho de Melo int exclude_perf(const struct option *opt, const char *arg, int unset); 488ad8db37SIngo Molnar 498ad8db37SIngo Molnar #define EVENTS_HELP_MAX (128*1024) 508ad8db37SIngo Molnar 51dcb4e102SKan Liang enum perf_pmu_event_symbol_type { 52dcb4e102SKan Liang PMU_EVENT_SYMBOL_ERR, /* not a PMU EVENT */ 53dcb4e102SKan Liang PMU_EVENT_SYMBOL, /* normal style PMU event */ 54dcb4e102SKan Liang PMU_EVENT_SYMBOL_PREFIX, /* prefix of pre-suf style event */ 55dcb4e102SKan Liang PMU_EVENT_SYMBOL_SUFFIX, /* suffix of pre-suf style event */ 56dcb4e102SKan Liang }; 57dcb4e102SKan Liang 58dcb4e102SKan Liang struct perf_pmu_event_symbol { 59dcb4e102SKan Liang char *symbol; 60dcb4e102SKan Liang enum perf_pmu_event_symbol_type type; 61dcb4e102SKan Liang }; 62dcb4e102SKan Liang 638f707d84SJiri Olsa enum { 6416fa7e82SJiri Olsa PARSE_EVENTS__TERM_TYPE_NUM, 6516fa7e82SJiri Olsa PARSE_EVENTS__TERM_TYPE_STR, 6616fa7e82SJiri Olsa }; 6716fa7e82SJiri Olsa 6816fa7e82SJiri Olsa enum { 6916fa7e82SJiri Olsa PARSE_EVENTS__TERM_TYPE_USER, 708f707d84SJiri Olsa PARSE_EVENTS__TERM_TYPE_CONFIG, 718f707d84SJiri Olsa PARSE_EVENTS__TERM_TYPE_CONFIG1, 728f707d84SJiri Olsa PARSE_EVENTS__TERM_TYPE_CONFIG2, 736b5fc39bSJiri Olsa PARSE_EVENTS__TERM_TYPE_NAME, 748f707d84SJiri Olsa PARSE_EVENTS__TERM_TYPE_SAMPLE_PERIOD, 7509af2a55SNamhyung Kim PARSE_EVENTS__TERM_TYPE_SAMPLE_FREQ, 768f707d84SJiri Olsa PARSE_EVENTS__TERM_TYPE_BRANCH_SAMPLE_TYPE, 7732067712SKan Liang PARSE_EVENTS__TERM_TYPE_TIME, 78d457c963SKan Liang PARSE_EVENTS__TERM_TYPE_CALLGRAPH, 79d457c963SKan Liang PARSE_EVENTS__TERM_TYPE_STACKSIZE, 80374ce938SWang Nan PARSE_EVENTS__TERM_TYPE_NOINHERIT, 8117cb5f84SWang Nan PARSE_EVENTS__TERM_TYPE_INHERIT, 82792d48b4SArnaldo Carvalho de Melo PARSE_EVENTS__TERM_TYPE_MAX_STACK, 832fda5adaSArnaldo Carvalho de Melo PARSE_EVENTS__TERM_TYPE_MAX_EVENTS, 84626a6b78SWang Nan PARSE_EVENTS__TERM_TYPE_NOOVERWRITE, 85626a6b78SWang Nan PARSE_EVENTS__TERM_TYPE_OVERWRITE, 86dd60fba7SMathieu Poirier PARSE_EVENTS__TERM_TYPE_DRV_CFG, 87064b4e82SJin Yao PARSE_EVENTS__TERM_TYPE_PERCORE, 881b992154SAdrian Hunter PARSE_EVENTS__TERM_TYPE_AUX_OUTPUT, 89eb7a52d4SAdrian Hunter PARSE_EVENTS__TERM_TYPE_AUX_SAMPLE_SIZE, 9017cb5f84SWang Nan __PARSE_EVENTS__TERM_TYPE_NR, 918f707d84SJiri Olsa }; 928f707d84SJiri Olsa 932d055bf2SWang Nan struct parse_events_array { 942d055bf2SWang Nan size_t nr_ranges; 952d055bf2SWang Nan struct { 962d055bf2SWang Nan unsigned int start; 972d055bf2SWang Nan size_t length; 982d055bf2SWang Nan } *ranges; 992d055bf2SWang Nan }; 1002d055bf2SWang Nan 1016cee6cd3SArnaldo Carvalho de Melo struct parse_events_term { 1028f707d84SJiri Olsa char *config; 1032d055bf2SWang Nan struct parse_events_array array; 1048f707d84SJiri Olsa union { 1058f707d84SJiri Olsa char *str; 106b527bab5SRobert Richter u64 num; 1078f707d84SJiri Olsa } val; 10816fa7e82SJiri Olsa int type_val; 10916fa7e82SJiri Olsa int type_term; 1108f707d84SJiri Olsa struct list_head list; 111688d4dfcSCody P Schafer bool used; 11299e7138eSJiri Olsa bool no_value; 113cecf3a2eSJiri Olsa 114cecf3a2eSJiri Olsa /* error string indexes for within parsed string */ 115cecf3a2eSJiri Olsa int err_term; 116cecf3a2eSJiri Olsa int err_val; 11759622fd4SAndi Kleen 11859622fd4SAndi Kleen /* Coming from implicit alias */ 11959622fd4SAndi Kleen bool weak; 1208f707d84SJiri Olsa }; 1218f707d84SJiri Olsa 122b39b8393SJiri Olsa struct parse_events_error { 123a910e466SIan Rogers int num_errors; /* number of errors encountered */ 124b39b8393SJiri Olsa int idx; /* index in the parsed string */ 125b39b8393SJiri Olsa char *str; /* string to display at the index */ 126b39b8393SJiri Olsa char *help; /* optional help string */ 127a910e466SIan Rogers int first_idx;/* as above, but for the first encountered error */ 128a910e466SIan Rogers char *first_str; 129a910e466SIan Rogers char *first_help; 130b39b8393SJiri Olsa }; 131b39b8393SJiri Olsa 1325d369a75SArnaldo Carvalho de Melo struct parse_events_state { 13346010ab2SJiri Olsa struct list_head list; 13446010ab2SJiri Olsa int idx; 13597f63e4aSNamhyung Kim int nr_groups; 136b39b8393SJiri Olsa struct parse_events_error *error; 13763503dbaSJiri Olsa struct evlist *evlist; 13890e2b22dSJiri Olsa struct list_head *terms; 1391244a327SJiri Olsa int stoken; 140387ad33fSJiri Olsa struct perf_pmu *fake_pmu; 141c93afadcSJin Yao char *hybrid_pmu_name; 14290e2b22dSJiri Olsa }; 14390e2b22dSJiri Olsa 144448d732cSIan Rogers void parse_events__handle_error(struct parse_events_error *err, int idx, 145448d732cSIan Rogers char *str, char *help); 1461669e509SWang Nan void parse_events__shrink_config_terms(void); 1476cee6cd3SArnaldo Carvalho de Melo int parse_events__is_hardcoded_term(struct parse_events_term *term); 148bb78ce7dSAdrian Hunter int parse_events_term__num(struct parse_events_term **term, 149bb78ce7dSAdrian Hunter int type_term, char *config, u64 num, 15099e7138eSJiri Olsa bool novalue, 151bb78ce7dSAdrian Hunter void *loc_term, void *loc_val); 152bb78ce7dSAdrian Hunter int parse_events_term__str(struct parse_events_term **term, 153bb78ce7dSAdrian Hunter int type_term, char *config, char *str, 154bb78ce7dSAdrian Hunter void *loc_term, void *loc_val); 1556cee6cd3SArnaldo Carvalho de Melo int parse_events_term__sym_hw(struct parse_events_term **term, 1561d33d6dcSJiri Olsa char *config, unsigned idx); 1576cee6cd3SArnaldo Carvalho de Melo int parse_events_term__clone(struct parse_events_term **new, 1586cee6cd3SArnaldo Carvalho de Melo struct parse_events_term *term); 1591dc92556SIan Rogers void parse_events_term__delete(struct parse_events_term *term); 1602146afc6SArnaldo Carvalho de Melo void parse_events_terms__delete(struct list_head *terms); 161fc0a2c1dSArnaldo Carvalho de Melo void parse_events_terms__purge(struct list_head *terms); 1622d055bf2SWang Nan void parse_events__clear_array(struct parse_events_array *a); 163f5b1135bSJiri Olsa int parse_events__modifier_event(struct list_head *list, char *str, bool add); 16489efb029SJiri Olsa int parse_events__modifier_group(struct list_head *list, char *event_mod); 165*8e8bbfb3SIan Rogers int parse_events_name(struct list_head *list, const char *name); 166c5cd8ac0SDavid Ahern int parse_events_add_tracepoint(struct list_head *list, int *idx, 1678c619d6aSWang Nan const char *sys, const char *event, 168e637d177SHe Kuang struct parse_events_error *error, 169e637d177SHe Kuang struct list_head *head_config); 1705d9cdc11SArnaldo Carvalho de Melo int parse_events_load_bpf(struct parse_events_state *parse_state, 17184c86ca1SWang Nan struct list_head *list, 172d509db04SWang Nan char *bpf_file_name, 173a34f3be7SWang Nan bool source, 174a34f3be7SWang Nan struct list_head *head_config); 17584c86ca1SWang Nan /* Provide this function for perf test */ 17684c86ca1SWang Nan struct bpf_object; 1775d9cdc11SArnaldo Carvalho de Melo int parse_events_load_bpf_obj(struct parse_events_state *parse_state, 17884c86ca1SWang Nan struct list_head *list, 17995088a59SWang Nan struct bpf_object *obj, 18095088a59SWang Nan struct list_head *head_config); 1815d9cdc11SArnaldo Carvalho de Melo int parse_events_add_numeric(struct parse_events_state *parse_state, 18287d650beSJiri Olsa struct list_head *list, 183b527bab5SRobert Richter u32 type, u64 config, 1848f707d84SJiri Olsa struct list_head *head_config); 185f0fbb114SAndi Kleen int parse_events_add_tool(struct parse_events_state *parse_state, 186f0fbb114SAndi Kleen struct list_head *list, 1878228e936SIan Rogers int tool_event); 188c5cd8ac0SDavid Ahern int parse_events_add_cache(struct list_head *list, int *idx, 18943d0b978SWang Nan char *type, char *op_result1, char *op_result2, 19043d0b978SWang Nan struct parse_events_error *error, 191c93afadcSJin Yao struct list_head *head_config, 192c93afadcSJin Yao struct parse_events_state *parse_state); 193c5cd8ac0SDavid Ahern int parse_events_add_breakpoint(struct list_head *list, int *idx, 194aa98d848SIan Rogers u64 addr, char *type, u64 len); 1955d9cdc11SArnaldo Carvalho de Melo int parse_events_add_pmu(struct parse_events_state *parse_state, 19636adec85SJiri Olsa struct list_head *list, char *name, 197369b2308SKan Liang struct list_head *head_config, 198369b2308SKan Liang bool auto_merge_stats, 199369b2308SKan Liang bool use_alias); 2002073ad33SAndi Kleen 20170943490SStephane Eranian struct evsel *parse_events__add_event(int idx, struct perf_event_attr *attr, 202*8e8bbfb3SIan Rogers const char *name, struct perf_pmu *pmu); 20370943490SStephane Eranian 2045d9cdc11SArnaldo Carvalho de Melo int parse_events_multi_pmu_add(struct parse_events_state *parse_state, 2052073ad33SAndi Kleen char *str, 2062073ad33SAndi Kleen struct list_head **listp); 2072073ad33SAndi Kleen 2088255718fSAndi Kleen int parse_events_copy_term_list(struct list_head *old, 2098255718fSAndi Kleen struct list_head **new); 2108255718fSAndi Kleen 211dcb4e102SKan Liang enum perf_pmu_event_symbol_type 212dcb4e102SKan Liang perf_pmu__parse_check(const char *name); 213369b2308SKan Liang void parse_events__set_leader(char *name, struct list_head *list, 214369b2308SKan Liang struct parse_events_state *parse_state); 2155d7be90eSJiri Olsa void parse_events_update_lists(struct list_head *list_event, 2165d7be90eSJiri Olsa struct list_head *list_all); 2175d9cdc11SArnaldo Carvalho de Melo void parse_events_evlist_error(struct parse_events_state *parse_state, 218b39b8393SJiri Olsa int idx, const char *str); 21989812fc8SJiri Olsa 220c8d6828aSSukadev Bhattiprolu void print_events(const char *event_glob, bool name_only, bool quiet, 221a7f6c8c8SJin Yao bool long_desc, bool details_flag, bool deprecated); 222705750f2SYunlong Song 223705750f2SYunlong Song struct event_symbol { 224705750f2SYunlong Song const char *symbol; 225705750f2SYunlong Song const char *alias; 226705750f2SYunlong Song }; 227705750f2SYunlong Song extern struct event_symbol event_symbols_hw[]; 228705750f2SYunlong Song extern struct event_symbol event_symbols_sw[]; 229705750f2SYunlong Song void print_symbol_events(const char *event_glob, unsigned type, 230705750f2SYunlong Song struct event_symbol *syms, unsigned max, 231705750f2SYunlong Song bool name_only); 2325e0861baSAndi Kleen void print_tool_events(const char *event_glob, bool name_only); 233a3277d2dSFrederic Weisbecker void print_tracepoint_events(const char *subsys_glob, const char *event_glob, 234a3277d2dSFrederic Weisbecker bool name_only); 235a3277d2dSFrederic Weisbecker int print_hwcache_events(const char *event_glob, bool name_only); 23640218daeSMasami Hiramatsu void print_sdt_events(const char *subsys_glob, const char *event_glob, 23740218daeSMasami Hiramatsu bool name_only); 2383938bad4SArnaldo Carvalho de Melo int is_valid_tracepoint(const char *event_string); 2398ad8db37SIngo Molnar 24023773ca1SSteven Rostedt (Red Hat) int valid_event_mount(const char *eventfs); 241ffeb883eSHe Kuang char *parse_events_formats_error_string(char *additional_terms); 2425beeded1SJason Baron 243333b5665SAndi Kleen void parse_events_print_error(struct parse_events_error *err, 244333b5665SAndi Kleen const char *event); 245333b5665SAndi Kleen 246af9100adSRavi Bangoria #ifdef HAVE_LIBELF_SUPPORT 247af9100adSRavi Bangoria /* 248af9100adSRavi Bangoria * If the probe point starts with '%', 249af9100adSRavi Bangoria * or starts with "sdt_" and has a ':' but no '=', 250af9100adSRavi Bangoria * then it should be a SDT/cached probe point. 251af9100adSRavi Bangoria */ 252af9100adSRavi Bangoria static inline bool is_sdt_event(char *str) 253af9100adSRavi Bangoria { 254af9100adSRavi Bangoria return (str[0] == '%' || 255af9100adSRavi Bangoria (!strncmp(str, "sdt_", 4) && 256af9100adSRavi Bangoria !!strchr(str, ':') && !strchr(str, '='))); 257af9100adSRavi Bangoria } 258af9100adSRavi Bangoria #else 259af9100adSRavi Bangoria static inline bool is_sdt_event(char *str __maybe_unused) 260af9100adSRavi Bangoria { 261af9100adSRavi Bangoria return false; 262af9100adSRavi Bangoria } 263af9100adSRavi Bangoria #endif /* HAVE_LIBELF_SUPPORT */ 264af9100adSRavi Bangoria 2654929e95aSJiri Olsa int perf_pmu__test_parse_init(void); 2664929e95aSJiri Olsa 2679cbfa2f6SJin Yao struct evsel *parse_events__add_event_hybrid(struct list_head *list, int *idx, 2689cbfa2f6SJin Yao struct perf_event_attr *attr, 269*8e8bbfb3SIan Rogers const char *name, 270*8e8bbfb3SIan Rogers struct perf_pmu *pmu, 2719cbfa2f6SJin Yao struct list_head *config_terms); 2729cbfa2f6SJin Yao 2738b40f521SJohn Kacur #endif /* __PERF_PARSE_EVENTS_H */ 274