1 | /* SPDX-License-Identifier: GPL-2.0 */ |
2 | #ifndef __PERF_MACHINE_H |
3 | #define __PERF_MACHINE_H |
4 | |
5 | #include <sys/types.h> |
6 | #include <linux/rbtree.h> |
7 | #include "maps.h" |
8 | #include "dsos.h" |
9 | #include "rwsem.h" |
10 | |
11 | struct addr_location; |
12 | struct branch_stack; |
13 | struct dso; |
14 | struct dso_id; |
15 | struct evsel; |
16 | struct perf_sample; |
17 | struct symbol; |
18 | struct target; |
19 | struct thread; |
20 | union perf_event; |
21 | struct machines; |
22 | |
23 | /* Native host kernel uses -1 as pid index in machine */ |
24 | #define HOST_KERNEL_ID (-1) |
25 | #define DEFAULT_GUEST_KERNEL_ID (0) |
26 | |
27 | extern const char *ref_reloc_sym_names[]; |
28 | |
29 | struct vdso_info; |
30 | |
31 | #define THREADS__TABLE_BITS 8 |
32 | #define THREADS__TABLE_SIZE (1 << THREADS__TABLE_BITS) |
33 | |
34 | struct threads { |
35 | struct rb_root_cached entries; |
36 | struct rw_semaphore lock; |
37 | unsigned int nr; |
38 | struct thread *last_match; |
39 | }; |
40 | |
41 | struct machine { |
42 | struct rb_node rb_node; |
43 | pid_t pid; |
44 | u16 id_hdr_size; |
45 | bool comm_exec; |
46 | bool kptr_restrict_warned; |
47 | bool single_address_space; |
48 | char *root_dir; |
49 | char *mmap_name; |
50 | char *kallsyms_filename; |
51 | struct threads threads[THREADS__TABLE_SIZE]; |
52 | struct vdso_info *vdso_info; |
53 | struct perf_env *env; |
54 | struct dsos dsos; |
55 | struct maps *kmaps; |
56 | struct map *vmlinux_map; |
57 | u64 kernel_start; |
58 | struct { |
59 | u64 text_start; |
60 | u64 text_end; |
61 | } sched, lock; |
62 | pid_t *current_tid; |
63 | size_t current_tid_sz; |
64 | union { /* Tool specific area */ |
65 | void *priv; |
66 | u64 db_id; |
67 | }; |
68 | struct machines *machines; |
69 | bool trampolines_mapped; |
70 | }; |
71 | |
72 | static inline struct threads *machine__threads(struct machine *machine, pid_t tid) |
73 | { |
74 | /* Cast it to handle tid == -1 */ |
75 | return &machine->threads[(unsigned int)tid % THREADS__TABLE_SIZE]; |
76 | } |
77 | |
78 | /* |
79 | * The main kernel (vmlinux) map |
80 | */ |
81 | static inline |
82 | struct map *machine__kernel_map(struct machine *machine) |
83 | { |
84 | return machine->vmlinux_map; |
85 | } |
86 | |
87 | /* |
88 | * kernel (the one returned by machine__kernel_map()) plus kernel modules maps |
89 | */ |
90 | static inline |
91 | struct maps *machine__kernel_maps(struct machine *machine) |
92 | { |
93 | return machine->kmaps; |
94 | } |
95 | |
96 | int machine__get_kernel_start(struct machine *machine); |
97 | |
98 | static inline u64 machine__kernel_start(struct machine *machine) |
99 | { |
100 | if (!machine->kernel_start) |
101 | machine__get_kernel_start(machine); |
102 | return machine->kernel_start; |
103 | } |
104 | |
105 | static inline bool machine__kernel_ip(struct machine *machine, u64 ip) |
106 | { |
107 | u64 kernel_start = machine__kernel_start(machine); |
108 | |
109 | return ip >= kernel_start; |
110 | } |
111 | |
112 | u8 machine__addr_cpumode(struct machine *machine, u8 cpumode, u64 addr); |
113 | |
114 | struct thread *machine__find_thread(struct machine *machine, pid_t pid, |
115 | pid_t tid); |
116 | struct thread *machine__idle_thread(struct machine *machine); |
117 | struct comm *machine__thread_exec_comm(struct machine *machine, |
118 | struct thread *thread); |
119 | |
120 | int machine__process_comm_event(struct machine *machine, union perf_event *event, |
121 | struct perf_sample *sample); |
122 | int machine__process_exit_event(struct machine *machine, union perf_event *event, |
123 | struct perf_sample *sample); |
124 | int machine__process_fork_event(struct machine *machine, union perf_event *event, |
125 | struct perf_sample *sample); |
126 | int machine__process_lost_event(struct machine *machine, union perf_event *event, |
127 | struct perf_sample *sample); |
128 | int machine__process_lost_samples_event(struct machine *machine, union perf_event *event, |
129 | struct perf_sample *sample); |
130 | int machine__process_aux_event(struct machine *machine, |
131 | union perf_event *event); |
132 | int machine__process_itrace_start_event(struct machine *machine, |
133 | union perf_event *event); |
134 | int machine__process_aux_output_hw_id_event(struct machine *machine, |
135 | union perf_event *event); |
136 | int machine__process_switch_event(struct machine *machine, |
137 | union perf_event *event); |
138 | int machine__process_namespaces_event(struct machine *machine, |
139 | union perf_event *event, |
140 | struct perf_sample *sample); |
141 | int machine__process_cgroup_event(struct machine *machine, |
142 | union perf_event *event, |
143 | struct perf_sample *sample); |
144 | int machine__process_mmap_event(struct machine *machine, union perf_event *event, |
145 | struct perf_sample *sample); |
146 | int machine__process_mmap2_event(struct machine *machine, union perf_event *event, |
147 | struct perf_sample *sample); |
148 | int machine__process_ksymbol(struct machine *machine, |
149 | union perf_event *event, |
150 | struct perf_sample *sample); |
151 | int machine__process_text_poke(struct machine *machine, |
152 | union perf_event *event, |
153 | struct perf_sample *sample); |
154 | int machine__process_event(struct machine *machine, union perf_event *event, |
155 | struct perf_sample *sample); |
156 | |
157 | typedef void (*machine__process_t)(struct machine *machine, void *data); |
158 | |
159 | struct machines { |
160 | struct machine host; |
161 | struct rb_root_cached guests; |
162 | }; |
163 | |
164 | void machines__init(struct machines *machines); |
165 | void machines__exit(struct machines *machines); |
166 | |
167 | void machines__process_guests(struct machines *machines, |
168 | machine__process_t process, void *data); |
169 | |
170 | struct machine *machines__add(struct machines *machines, pid_t pid, |
171 | const char *root_dir); |
172 | struct machine *machines__find(struct machines *machines, pid_t pid); |
173 | struct machine *machines__findnew(struct machines *machines, pid_t pid); |
174 | struct machine *machines__find_guest(struct machines *machines, pid_t pid); |
175 | struct thread *machines__findnew_guest_code(struct machines *machines, pid_t pid); |
176 | struct thread *machine__findnew_guest_code(struct machine *machine, pid_t pid); |
177 | |
178 | void machines__set_id_hdr_size(struct machines *machines, u16 id_hdr_size); |
179 | void machines__set_comm_exec(struct machines *machines, bool comm_exec); |
180 | |
181 | struct machine *machine__new_host(void); |
182 | struct machine *machine__new_kallsyms(void); |
183 | int machine__init(struct machine *machine, const char *root_dir, pid_t pid); |
184 | void machine__exit(struct machine *machine); |
185 | void machine__delete_threads(struct machine *machine); |
186 | void machine__delete(struct machine *machine); |
187 | void machine__remove_thread(struct machine *machine, struct thread *th); |
188 | |
189 | struct branch_info *sample__resolve_bstack(struct perf_sample *sample, |
190 | struct addr_location *al); |
191 | struct mem_info *sample__resolve_mem(struct perf_sample *sample, |
192 | struct addr_location *al); |
193 | |
194 | struct callchain_cursor; |
195 | |
196 | int thread__resolve_callchain(struct thread *thread, |
197 | struct callchain_cursor *cursor, |
198 | struct evsel *evsel, |
199 | struct perf_sample *sample, |
200 | struct symbol **parent, |
201 | struct addr_location *root_al, |
202 | int max_stack); |
203 | |
204 | /* |
205 | * Default guest kernel is defined by parameter --guestkallsyms |
206 | * and --guestmodules |
207 | */ |
208 | static inline bool machine__is_default_guest(struct machine *machine) |
209 | { |
210 | return machine ? machine->pid == DEFAULT_GUEST_KERNEL_ID : false; |
211 | } |
212 | |
213 | static inline bool machine__is_host(struct machine *machine) |
214 | { |
215 | return machine ? machine->pid == HOST_KERNEL_ID : false; |
216 | } |
217 | |
218 | bool machine__is_lock_function(struct machine *machine, u64 addr); |
219 | bool machine__is(struct machine *machine, const char *arch); |
220 | bool machine__normalized_is(struct machine *machine, const char *arch); |
221 | int machine__nr_cpus_avail(struct machine *machine); |
222 | |
223 | struct thread *__machine__findnew_thread(struct machine *machine, pid_t pid, pid_t tid); |
224 | struct thread *machine__findnew_thread(struct machine *machine, pid_t pid, pid_t tid); |
225 | |
226 | struct dso *machine__findnew_dso_id(struct machine *machine, const char *filename, struct dso_id *id); |
227 | struct dso *machine__findnew_dso(struct machine *machine, const char *filename); |
228 | |
229 | size_t machine__fprintf(struct machine *machine, FILE *fp); |
230 | |
231 | static inline |
232 | struct symbol *machine__find_kernel_symbol(struct machine *machine, u64 addr, |
233 | struct map **mapp) |
234 | { |
235 | return maps__find_symbol(maps: machine->kmaps, addr, mapp); |
236 | } |
237 | |
238 | static inline |
239 | struct symbol *machine__find_kernel_symbol_by_name(struct machine *machine, |
240 | const char *name, |
241 | struct map **mapp) |
242 | { |
243 | return maps__find_symbol_by_name(maps: machine->kmaps, name, mapp); |
244 | } |
245 | |
246 | int arch__fix_module_text_start(u64 *start, u64 *size, const char *name); |
247 | |
248 | int machine__load_kallsyms(struct machine *machine, const char *filename); |
249 | |
250 | int machine__load_vmlinux_path(struct machine *machine); |
251 | |
252 | size_t machine__fprintf_dsos_buildid(struct machine *machine, FILE *fp, |
253 | bool (skip)(struct dso *dso, int parm), int parm); |
254 | size_t machines__fprintf_dsos(struct machines *machines, FILE *fp); |
255 | size_t machines__fprintf_dsos_buildid(struct machines *machines, FILE *fp, |
256 | bool (skip)(struct dso *dso, int parm), int parm); |
257 | |
258 | void machine__destroy_kernel_maps(struct machine *machine); |
259 | int machine__create_kernel_maps(struct machine *machine); |
260 | |
261 | int machines__create_kernel_maps(struct machines *machines, pid_t pid); |
262 | int machines__create_guest_kernel_maps(struct machines *machines); |
263 | void machines__destroy_kernel_maps(struct machines *machines); |
264 | |
265 | size_t machine__fprintf_vmlinux_path(struct machine *machine, FILE *fp); |
266 | |
267 | typedef int (*machine__dso_t)(struct dso *dso, struct machine *machine, void *priv); |
268 | |
269 | int machine__for_each_dso(struct machine *machine, machine__dso_t fn, |
270 | void *priv); |
271 | |
272 | typedef int (*machine__map_t)(struct map *map, void *priv); |
273 | int machine__for_each_kernel_map(struct machine *machine, machine__map_t fn, |
274 | void *priv); |
275 | |
276 | int machine__for_each_thread(struct machine *machine, |
277 | int (*fn)(struct thread *thread, void *p), |
278 | void *priv); |
279 | int machines__for_each_thread(struct machines *machines, |
280 | int (*fn)(struct thread *thread, void *p), |
281 | void *priv); |
282 | |
283 | pid_t machine__get_current_tid(struct machine *machine, int cpu); |
284 | int machine__set_current_tid(struct machine *machine, int cpu, pid_t pid, |
285 | pid_t tid); |
286 | /* |
287 | * For use with libtraceevent's tep_set_function_resolver() |
288 | */ |
289 | char *machine__resolve_kernel_addr(void *vmachine, unsigned long long *addrp, char **modp); |
290 | |
291 | void machine__get_kallsyms_filename(struct machine *machine, char *buf, |
292 | size_t bufsz); |
293 | |
294 | int (struct machine *machine, |
295 | struct dso *kernel); |
296 | |
297 | /* Kernel-space maps for symbols that are outside the main kernel map and module maps */ |
298 | struct { |
299 | u64 ; |
300 | u64 ; |
301 | u64 ; |
302 | char [KMAP_NAME_LEN]; |
303 | }; |
304 | |
305 | int (struct machine *machine, |
306 | struct dso *kernel, |
307 | struct extra_kernel_map *xm); |
308 | |
309 | int machine__map_x86_64_entry_trampolines(struct machine *machine, |
310 | struct dso *kernel); |
311 | |
312 | int machine__resolve(struct machine *machine, struct addr_location *al, |
313 | struct perf_sample *sample); |
314 | |
315 | #endif /* __PERF_MACHINE_H */ |
316 | |