Loading...
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 | /* SPDX-License-Identifier: GPL-2.0 */ #ifndef __PERF_PARSE_EVENTS_H #define __PERF_PARSE_EVENTS_H /* * Parse symbolic events/counts passed in as options: */ #include <linux/list.h> #include <stdbool.h> #include <linux/types.h> #include <linux/perf_event.h> #include <stdio.h> #include <string.h> struct evsel; struct evlist; struct parse_events_error; struct option; struct perf_pmu; struct strbuf; const char *event_type(int type); /* Arguments encoded in opt->value. */ struct parse_events_option_args { struct evlist **evlistp; const char *pmu_filter; }; int parse_events_option(const struct option *opt, const char *str, int unset); int parse_events_option_new_evlist(const struct option *opt, const char *str, int unset); __attribute__((nonnull(1, 2, 4))) int __parse_events(struct evlist *evlist, const char *str, const char *pmu_filter, struct parse_events_error *error, struct perf_pmu *fake_pmu, bool warn_if_reordered); __attribute__((nonnull(1, 2, 3))) static inline int parse_events(struct evlist *evlist, const char *str, struct parse_events_error *err) { return __parse_events(evlist, str, /*pmu_filter=*/NULL, err, /*fake_pmu=*/NULL, /*warn_if_reordered=*/true); } int parse_event(struct evlist *evlist, const char *str); int parse_filter(const struct option *opt, const char *str, int unset); int exclude_perf(const struct option *opt, const char *arg, int unset); enum parse_events__term_val_type { PARSE_EVENTS__TERM_TYPE_NUM, PARSE_EVENTS__TERM_TYPE_STR, }; enum parse_events__term_type { PARSE_EVENTS__TERM_TYPE_USER, PARSE_EVENTS__TERM_TYPE_CONFIG, PARSE_EVENTS__TERM_TYPE_CONFIG1, PARSE_EVENTS__TERM_TYPE_CONFIG2, PARSE_EVENTS__TERM_TYPE_CONFIG3, PARSE_EVENTS__TERM_TYPE_NAME, PARSE_EVENTS__TERM_TYPE_SAMPLE_PERIOD, PARSE_EVENTS__TERM_TYPE_SAMPLE_FREQ, PARSE_EVENTS__TERM_TYPE_BRANCH_SAMPLE_TYPE, PARSE_EVENTS__TERM_TYPE_TIME, PARSE_EVENTS__TERM_TYPE_CALLGRAPH, PARSE_EVENTS__TERM_TYPE_STACKSIZE, PARSE_EVENTS__TERM_TYPE_NOINHERIT, PARSE_EVENTS__TERM_TYPE_INHERIT, PARSE_EVENTS__TERM_TYPE_MAX_STACK, PARSE_EVENTS__TERM_TYPE_MAX_EVENTS, PARSE_EVENTS__TERM_TYPE_NOOVERWRITE, PARSE_EVENTS__TERM_TYPE_OVERWRITE, PARSE_EVENTS__TERM_TYPE_DRV_CFG, PARSE_EVENTS__TERM_TYPE_PERCORE, PARSE_EVENTS__TERM_TYPE_AUX_OUTPUT, PARSE_EVENTS__TERM_TYPE_AUX_SAMPLE_SIZE, PARSE_EVENTS__TERM_TYPE_METRIC_ID, PARSE_EVENTS__TERM_TYPE_RAW, PARSE_EVENTS__TERM_TYPE_LEGACY_CACHE, PARSE_EVENTS__TERM_TYPE_HARDWARE, #define __PARSE_EVENTS__TERM_TYPE_NR (PARSE_EVENTS__TERM_TYPE_HARDWARE + 1) }; struct parse_events_term { /** @list: The term list the term is a part of. */ struct list_head list; /** * @config: The left-hand side of a term assignment, so the term * "event=8" would have the config be "event" */ const char *config; /** * @val: The right-hand side of a term assignment that can either be a * string or a number depending on type_val. */ union { char *str; u64 num; } val; /** @type_val: The union variable in val to be used for the term. */ enum parse_events__term_val_type type_val; /** * @type_term: A predefined term type or PARSE_EVENTS__TERM_TYPE_USER * when not inbuilt. */ enum parse_events__term_type type_term; /** * @err_term: The column index of the term from parsing, used during * error output. */ int err_term; /** * @err_val: The column index of the val from parsing, used during error * output. */ int err_val; /** @used: Was the term used during parameterized-eval. */ bool used; /** * @weak: A term from the sysfs or json encoding of an event that * shouldn't override terms coming from the command line. */ bool weak; /** * @no_value: Is there no value. If a numeric term has no value then the * value is assumed to be 1. An event name also has no value. */ bool no_value; }; struct parse_events_error { /** @list: The head of a list of errors. */ struct list_head list; }; /* A wrapper around a list of terms for the sake of better type safety. */ struct parse_events_terms { struct list_head terms; }; struct parse_events_state { /* The list parsed events are placed on. */ struct list_head list; /* The updated index used by entries as they are added. */ int idx; /* Error information. */ struct parse_events_error *error; /* Holds returned terms for term parsing. */ struct parse_events_terms *terms; /* Start token. */ int stoken; /* Special fake PMU marker for testing. */ struct perf_pmu *fake_pmu; /* If non-null, when wildcard matching only match the given PMU. */ const char *pmu_filter; /* Should PE_LEGACY_NAME tokens be generated for config terms? */ bool match_legacy_cache_terms; /* Were multiple PMUs scanned to find events? */ bool wild_card_pmus; }; bool parse_events__filter_pmu(const struct parse_events_state *parse_state, const struct perf_pmu *pmu); void parse_events__shrink_config_terms(void); int parse_events__is_hardcoded_term(struct parse_events_term *term); int parse_events_term__num(struct parse_events_term **term, enum parse_events__term_type type_term, const char *config, u64 num, bool novalue, void *loc_term, void *loc_val); int parse_events_term__str(struct parse_events_term **term, enum parse_events__term_type type_term, char *config, char *str, void *loc_term, void *loc_val); int parse_events_term__term(struct parse_events_term **term, enum parse_events__term_type term_lhs, enum parse_events__term_type term_rhs, void *loc_term, void *loc_val); int parse_events_term__clone(struct parse_events_term **new, struct parse_events_term *term); void parse_events_term__delete(struct parse_events_term *term); void parse_events_terms__delete(struct parse_events_terms *terms); void parse_events_terms__init(struct parse_events_terms *terms); void parse_events_terms__exit(struct parse_events_terms *terms); int parse_events_terms(struct parse_events_terms *terms, const char *str, FILE *input); int parse_events_terms__to_strbuf(const struct parse_events_terms *terms, struct strbuf *sb); int parse_events__modifier_event(struct list_head *list, char *str, bool add); int parse_events__modifier_group(struct list_head *list, char *event_mod); int parse_events_name(struct list_head *list, const char *name); int parse_events_add_tracepoint(struct list_head *list, int *idx, const char *sys, const char *event, struct parse_events_error *error, struct parse_events_terms *head_config, void *loc); int parse_events_add_numeric(struct parse_events_state *parse_state, struct list_head *list, u32 type, u64 config, struct parse_events_terms *head_config, bool wildcard); int parse_events_add_tool(struct parse_events_state *parse_state, struct list_head *list, int tool_event); int parse_events_add_cache(struct list_head *list, int *idx, const char *name, struct parse_events_state *parse_state, struct parse_events_terms *head_config); int parse_events__decode_legacy_cache(const char *name, int pmu_type, __u64 *config); int parse_events_add_breakpoint(struct parse_events_state *parse_state, struct list_head *list, u64 addr, char *type, u64 len, struct parse_events_terms *head_config); int parse_events_add_pmu(struct parse_events_state *parse_state, struct list_head *list, const char *name, const struct parse_events_terms *const_parsed_terms, bool auto_merge_stats, void *loc); struct evsel *parse_events__add_event(int idx, struct perf_event_attr *attr, const char *name, const char *metric_id, struct perf_pmu *pmu); int parse_events_multi_pmu_add(struct parse_events_state *parse_state, const char *event_name, const struct parse_events_terms *const_parsed_terms, struct list_head **listp, void *loc); void parse_events__set_leader(char *name, struct list_head *list); void parse_events_update_lists(struct list_head *list_event, struct list_head *list_all); void parse_events_evlist_error(struct parse_events_state *parse_state, int idx, const char *str); struct event_symbol { const char *symbol; const char *alias; }; extern struct event_symbol event_symbols_hw[]; extern struct event_symbol event_symbols_sw[]; char *parse_events_formats_error_string(char *additional_terms); void parse_events_error__init(struct parse_events_error *err); void parse_events_error__exit(struct parse_events_error *err); void parse_events_error__handle(struct parse_events_error *err, int idx, char *str, char *help); void parse_events_error__print(const struct parse_events_error *err, const char *event); bool parse_events_error__contains(const struct parse_events_error *err, const char *needle); #ifdef HAVE_LIBELF_SUPPORT /* * If the probe point starts with '%', * or starts with "sdt_" and has a ':' but no '=', * then it should be a SDT/cached probe point. */ static inline bool is_sdt_event(char *str) { return (str[0] == '%' || (!strncmp(str, "sdt_", 4) && !!strchr(str, ':') && !strchr(str, '='))); } #else static inline bool is_sdt_event(char *str __maybe_unused) { return false; } #endif /* HAVE_LIBELF_SUPPORT */ #endif /* __PERF_PARSE_EVENTS_H */ |