1 | /* SPDX-License-Identifier: GPL-2.0 */ |
2 | #ifndef __PMU_H |
3 | #define __PMU_H |
4 | |
5 | #include <linux/bitmap.h> |
6 | #include <linux/compiler.h> |
7 | #include <linux/perf_event.h> |
8 | #include <linux/list.h> |
9 | #include <stdbool.h> |
10 | #include <stdio.h> |
11 | #include "parse-events.h" |
12 | #include "pmu-events/pmu-events.h" |
13 | #include "map_symbol.h" |
14 | #include "mem-events.h" |
15 | |
16 | struct evsel_config_term; |
17 | struct perf_cpu_map; |
18 | struct print_callbacks; |
19 | |
20 | enum { |
21 | PERF_PMU_FORMAT_VALUE_CONFIG, |
22 | PERF_PMU_FORMAT_VALUE_CONFIG1, |
23 | PERF_PMU_FORMAT_VALUE_CONFIG2, |
24 | PERF_PMU_FORMAT_VALUE_CONFIG3, |
25 | PERF_PMU_FORMAT_VALUE_CONFIG_END, |
26 | }; |
27 | |
28 | #define PERF_PMU_FORMAT_BITS 64 |
29 | #define MAX_PMU_NAME_LEN 128 |
30 | |
31 | struct perf_event_attr; |
32 | |
33 | struct perf_pmu_caps { |
34 | char *name; |
35 | char *value; |
36 | struct list_head list; |
37 | }; |
38 | |
39 | /** |
40 | * struct perf_pmu |
41 | */ |
42 | struct perf_pmu { |
43 | /** @name: The name of the PMU such as "cpu". */ |
44 | const char *name; |
45 | /** |
46 | * @alias_name: Optional alternate name for the PMU determined in |
47 | * architecture specific code. |
48 | */ |
49 | char *alias_name; |
50 | /** |
51 | * @id: Optional PMU identifier read from |
52 | * <sysfs>/bus/event_source/devices/<name>/identifier. |
53 | */ |
54 | const char *id; |
55 | /** |
56 | * @type: Perf event attributed type value, read from |
57 | * <sysfs>/bus/event_source/devices/<name>/type. |
58 | */ |
59 | __u32 type; |
60 | /** |
61 | * @selectable: Can the PMU name be selected as if it were an event? |
62 | */ |
63 | bool selectable; |
64 | /** |
65 | * @is_core: Is the PMU the core CPU PMU? Determined by the name being |
66 | * "cpu" or by the presence of |
67 | * <sysfs>/bus/event_source/devices/<name>/cpus. There may be >1 core |
68 | * PMU on systems like Intel hybrid. |
69 | */ |
70 | bool is_core; |
71 | /** |
72 | * @is_uncore: Is the PMU not within the CPU core? Determined by the |
73 | * presence of <sysfs>/bus/event_source/devices/<name>/cpumask. |
74 | */ |
75 | bool is_uncore; |
76 | /** |
77 | * @auxtrace: Are events auxiliary events? Determined in architecture |
78 | * specific code. |
79 | */ |
80 | bool auxtrace; |
81 | /** |
82 | * @formats_checked: Only check PMU's formats are valid for |
83 | * perf_event_attr once. |
84 | */ |
85 | bool formats_checked; |
86 | /** @config_masks_present: Are there config format values? */ |
87 | bool config_masks_present; |
88 | /** @config_masks_computed: Set when masks are lazily computed. */ |
89 | bool config_masks_computed; |
90 | /** |
91 | * @max_precise: Number of levels of :ppp precision supported by the |
92 | * PMU, read from |
93 | * <sysfs>/bus/event_source/devices/<name>/caps/max_precise. |
94 | */ |
95 | int max_precise; |
96 | /** |
97 | * @perf_event_attr_init_default: Optional function to default |
98 | * initialize PMU specific parts of the perf_event_attr. |
99 | */ |
100 | void (*perf_event_attr_init_default)(const struct perf_pmu *pmu, |
101 | struct perf_event_attr *attr); |
102 | /** |
103 | * @cpus: Empty or the contents of either of: |
104 | * <sysfs>/bus/event_source/devices/<name>/cpumask. |
105 | * <sysfs>/bus/event_source/devices/<cpu>/cpus. |
106 | */ |
107 | struct perf_cpu_map *cpus; |
108 | /** |
109 | * @format: Holds the contents of files read from |
110 | * <sysfs>/bus/event_source/devices/<name>/format/. The contents specify |
111 | * which event parameter changes what config, config1 or config2 bits. |
112 | */ |
113 | struct list_head format; |
114 | /** |
115 | * @aliases: List of struct perf_pmu_alias. Each alias corresponds to an |
116 | * event read from <sysfs>/bus/event_source/devices/<name>/events/ or |
117 | * from json events in pmu-events.c. |
118 | */ |
119 | struct list_head aliases; |
120 | /** |
121 | * @events_table: The events table for json events in pmu-events.c. |
122 | */ |
123 | const struct pmu_events_table *events_table; |
124 | /** @sysfs_aliases: Number of sysfs aliases loaded. */ |
125 | uint32_t sysfs_aliases; |
126 | /** @sysfs_aliases: Number of json event aliases loaded. */ |
127 | uint32_t loaded_json_aliases; |
128 | /** @sysfs_aliases_loaded: Are sysfs aliases loaded from disk? */ |
129 | bool sysfs_aliases_loaded; |
130 | /** |
131 | * @cpu_aliases_added: Have all json events table entries for the PMU |
132 | * been added? |
133 | */ |
134 | bool cpu_aliases_added; |
135 | /** @caps_initialized: Has the list caps been initialized? */ |
136 | bool caps_initialized; |
137 | /** @nr_caps: The length of the list caps. */ |
138 | u32 nr_caps; |
139 | /** |
140 | * @caps: Holds the contents of files read from |
141 | * <sysfs>/bus/event_source/devices/<name>/caps/. |
142 | * |
143 | * The contents are pairs of the filename with the value of its |
144 | * contents, for example, max_precise (see above) may have a value of 3. |
145 | */ |
146 | struct list_head caps; |
147 | /** @list: Element on pmus list in pmu.c. */ |
148 | struct list_head list; |
149 | |
150 | /** |
151 | * @config_masks: Derived from the PMU's format data, bits that are |
152 | * valid within the config value. |
153 | */ |
154 | __u64 config_masks[PERF_PMU_FORMAT_VALUE_CONFIG_END]; |
155 | |
156 | /** |
157 | * @missing_features: Features to inhibit when events on this PMU are |
158 | * opened. |
159 | */ |
160 | struct { |
161 | /** |
162 | * @exclude_guest: Disables perf_event_attr exclude_guest and |
163 | * exclude_host. |
164 | */ |
165 | bool exclude_guest; |
166 | } missing_features; |
167 | |
168 | /** |
169 | * @mem_events: List of the supported mem events |
170 | */ |
171 | struct perf_mem_event *mem_events; |
172 | }; |
173 | |
174 | /** @perf_pmu__fake: A special global PMU used for testing. */ |
175 | extern struct perf_pmu perf_pmu__fake; |
176 | |
177 | struct perf_pmu_info { |
178 | const char *unit; |
179 | double scale; |
180 | bool per_pkg; |
181 | bool snapshot; |
182 | }; |
183 | |
184 | struct pmu_event_info { |
185 | const struct perf_pmu *pmu; |
186 | const char *name; |
187 | const char* alias; |
188 | const char *scale_unit; |
189 | const char *desc; |
190 | const char *long_desc; |
191 | const char *encoding_desc; |
192 | const char *topic; |
193 | const char *pmu_name; |
194 | const char *str; |
195 | bool deprecated; |
196 | }; |
197 | |
198 | typedef int (*pmu_event_callback)(void *state, struct pmu_event_info *info); |
199 | |
200 | void pmu_add_sys_aliases(struct perf_pmu *pmu); |
201 | int perf_pmu__config(struct perf_pmu *pmu, struct perf_event_attr *attr, |
202 | struct parse_events_terms *head_terms, |
203 | struct parse_events_error *error); |
204 | int perf_pmu__config_terms(const struct perf_pmu *pmu, |
205 | struct perf_event_attr *attr, |
206 | struct parse_events_terms *terms, |
207 | bool zero, struct parse_events_error *error); |
208 | __u64 perf_pmu__format_bits(struct perf_pmu *pmu, const char *name); |
209 | int perf_pmu__format_type(struct perf_pmu *pmu, const char *name); |
210 | int perf_pmu__check_alias(struct perf_pmu *pmu, struct parse_events_terms *head_terms, |
211 | struct perf_pmu_info *info, bool *rewrote_terms, |
212 | struct parse_events_error *err); |
213 | int perf_pmu__find_event(struct perf_pmu *pmu, const char *event, void *state, pmu_event_callback cb); |
214 | |
215 | int perf_pmu__format_parse(struct perf_pmu *pmu, int dirfd, bool eager_load); |
216 | void perf_pmu_format__set_value(void *format, int config, unsigned long *bits); |
217 | bool perf_pmu__has_format(const struct perf_pmu *pmu, const char *name); |
218 | |
219 | bool is_pmu_core(const char *name); |
220 | bool perf_pmu__supports_legacy_cache(const struct perf_pmu *pmu); |
221 | bool perf_pmu__auto_merge_stats(const struct perf_pmu *pmu); |
222 | bool perf_pmu__have_event(struct perf_pmu *pmu, const char *name); |
223 | size_t perf_pmu__num_events(struct perf_pmu *pmu); |
224 | int perf_pmu__for_each_event(struct perf_pmu *pmu, bool skip_duplicate_pmus, |
225 | void *state, pmu_event_callback cb); |
226 | bool pmu__name_match(const struct perf_pmu *pmu, const char *pmu_name); |
227 | |
228 | /** |
229 | * perf_pmu_is_software - is the PMU a software PMU as in it uses the |
230 | * perf_sw_context in the kernel? |
231 | */ |
232 | bool perf_pmu__is_software(const struct perf_pmu *pmu); |
233 | |
234 | FILE *perf_pmu__open_file(const struct perf_pmu *pmu, const char *name); |
235 | FILE *perf_pmu__open_file_at(const struct perf_pmu *pmu, int dirfd, const char *name); |
236 | |
237 | int perf_pmu__scan_file(const struct perf_pmu *pmu, const char *name, const char *fmt, ...) |
238 | __scanf(3, 4); |
239 | int perf_pmu__scan_file_at(const struct perf_pmu *pmu, int dirfd, const char *name, |
240 | const char *fmt, ...) __scanf(4, 5); |
241 | |
242 | bool perf_pmu__file_exists(const struct perf_pmu *pmu, const char *name); |
243 | |
244 | int perf_pmu__test(void); |
245 | |
246 | void perf_pmu__arch_init(struct perf_pmu *pmu); |
247 | void pmu_add_cpu_aliases_table(struct perf_pmu *pmu, |
248 | const struct pmu_events_table *table); |
249 | |
250 | char *perf_pmu__getcpuid(struct perf_pmu *pmu); |
251 | const struct pmu_metrics_table *pmu_metrics_table__find(void); |
252 | bool pmu_uncore_identifier_match(const char *compat, const char *id); |
253 | |
254 | int perf_pmu__convert_scale(const char *scale, char **end, double *sval); |
255 | |
256 | int perf_pmu__caps_parse(struct perf_pmu *pmu); |
257 | |
258 | void perf_pmu__warn_invalid_config(struct perf_pmu *pmu, __u64 config, |
259 | const char *name, int config_num, |
260 | const char *config_name); |
261 | void perf_pmu__warn_invalid_formats(struct perf_pmu *pmu); |
262 | |
263 | int perf_pmu__match(const char *pattern, const char *name, const char *tok); |
264 | |
265 | double perf_pmu__cpu_slots_per_cycle(void); |
266 | int perf_pmu__event_source_devices_scnprintf(char *pathname, size_t size); |
267 | int perf_pmu__pathname_scnprintf(char *buf, size_t size, |
268 | const char *pmu_name, const char *filename); |
269 | int perf_pmu__event_source_devices_fd(void); |
270 | int perf_pmu__pathname_fd(int dirfd, const char *pmu_name, const char *filename, int flags); |
271 | |
272 | struct perf_pmu *perf_pmu__lookup(struct list_head *pmus, int dirfd, const char *lookup_name); |
273 | struct perf_pmu *perf_pmu__create_placeholder_core_pmu(struct list_head *core_pmus); |
274 | void perf_pmu__delete(struct perf_pmu *pmu); |
275 | struct perf_pmu *perf_pmus__find_core_pmu(void); |
276 | |
277 | #endif /* __PMU_H */ |
278 | |