at v6.7-rc2 8.7 kB view raw
1/* SPDX-License-Identifier: GPL-2.0 */ 2#ifndef __PERF_THREAD_H 3#define __PERF_THREAD_H 4 5#include <linux/refcount.h> 6#include <linux/rbtree.h> 7#include <linux/list.h> 8#include <stdio.h> 9#include <unistd.h> 10#include <sys/types.h> 11#include "srccode.h" 12#include "symbol_conf.h" 13#include <strlist.h> 14#include <intlist.h> 15#include "rwsem.h" 16#include "event.h" 17#include "callchain.h" 18#include <internal/rc_check.h> 19 20struct addr_location; 21struct map; 22struct perf_record_namespaces; 23struct thread_stack; 24struct unwind_libunwind_ops; 25 26struct lbr_stitch { 27 struct list_head lists; 28 struct list_head free_lists; 29 struct perf_sample prev_sample; 30 struct callchain_cursor_node *prev_lbr_cursor; 31}; 32 33struct thread_rb_node { 34 struct rb_node rb_node; 35 struct thread *thread; 36}; 37 38DECLARE_RC_STRUCT(thread) { 39 struct maps *maps; 40 pid_t pid_; /* Not all tools update this */ 41 pid_t tid; 42 pid_t ppid; 43 int cpu; 44 int guest_cpu; /* For QEMU thread */ 45 refcount_t refcnt; 46 bool comm_set; 47 int comm_len; 48 struct list_head namespaces_list; 49 struct rw_semaphore namespaces_lock; 50 struct list_head comm_list; 51 struct rw_semaphore comm_lock; 52 u64 db_id; 53 54 void *priv; 55 struct thread_stack *ts; 56 struct nsinfo *nsinfo; 57 struct srccode_state srccode_state; 58 bool filter; 59 int filter_entry_depth; 60 61 /* LBR call stack stitch */ 62 bool lbr_stitch_enable; 63 struct lbr_stitch *lbr_stitch; 64}; 65 66struct machine; 67struct namespaces; 68struct comm; 69 70struct thread *thread__new(pid_t pid, pid_t tid); 71int thread__init_maps(struct thread *thread, struct machine *machine); 72void thread__delete(struct thread *thread); 73 74void thread__set_priv_destructor(void (*destructor)(void *priv)); 75 76struct thread *thread__get(struct thread *thread); 77void thread__put(struct thread *thread); 78 79static inline void __thread__zput(struct thread **thread) 80{ 81 thread__put(*thread); 82 *thread = NULL; 83} 84 85#define thread__zput(thread) __thread__zput(&thread) 86 87struct namespaces *thread__namespaces(struct thread *thread); 88int thread__set_namespaces(struct thread *thread, u64 timestamp, 89 struct perf_record_namespaces *event); 90 91int __thread__set_comm(struct thread *thread, const char *comm, u64 timestamp, 92 bool exec); 93static inline int thread__set_comm(struct thread *thread, const char *comm, 94 u64 timestamp) 95{ 96 return __thread__set_comm(thread, comm, timestamp, false); 97} 98 99int thread__set_comm_from_proc(struct thread *thread); 100 101int thread__comm_len(struct thread *thread); 102struct comm *thread__comm(struct thread *thread); 103struct comm *thread__exec_comm(struct thread *thread); 104const char *thread__comm_str(struct thread *thread); 105int thread__insert_map(struct thread *thread, struct map *map); 106int thread__fork(struct thread *thread, struct thread *parent, u64 timestamp, bool do_maps_clone); 107size_t thread__fprintf(struct thread *thread, FILE *fp); 108 109struct thread *thread__main_thread(struct machine *machine, struct thread *thread); 110 111struct map *thread__find_map(struct thread *thread, u8 cpumode, u64 addr, 112 struct addr_location *al); 113struct map *thread__find_map_fb(struct thread *thread, u8 cpumode, u64 addr, 114 struct addr_location *al); 115 116struct symbol *thread__find_symbol(struct thread *thread, u8 cpumode, 117 u64 addr, struct addr_location *al); 118struct symbol *thread__find_symbol_fb(struct thread *thread, u8 cpumode, 119 u64 addr, struct addr_location *al); 120 121void thread__find_cpumode_addr_location(struct thread *thread, u64 addr, 122 struct addr_location *al); 123 124int thread__memcpy(struct thread *thread, struct machine *machine, 125 void *buf, u64 ip, int len, bool *is64bit); 126 127static inline struct maps *thread__maps(struct thread *thread) 128{ 129 return RC_CHK_ACCESS(thread)->maps; 130} 131 132static inline void thread__set_maps(struct thread *thread, struct maps *maps) 133{ 134 RC_CHK_ACCESS(thread)->maps = maps; 135} 136 137static inline pid_t thread__pid(const struct thread *thread) 138{ 139 return RC_CHK_ACCESS(thread)->pid_; 140} 141 142static inline void thread__set_pid(struct thread *thread, pid_t pid_) 143{ 144 RC_CHK_ACCESS(thread)->pid_ = pid_; 145} 146 147static inline pid_t thread__tid(const struct thread *thread) 148{ 149 return RC_CHK_ACCESS(thread)->tid; 150} 151 152static inline void thread__set_tid(struct thread *thread, pid_t tid) 153{ 154 RC_CHK_ACCESS(thread)->tid = tid; 155} 156 157static inline pid_t thread__ppid(const struct thread *thread) 158{ 159 return RC_CHK_ACCESS(thread)->ppid; 160} 161 162static inline void thread__set_ppid(struct thread *thread, pid_t ppid) 163{ 164 RC_CHK_ACCESS(thread)->ppid = ppid; 165} 166 167static inline int thread__cpu(const struct thread *thread) 168{ 169 return RC_CHK_ACCESS(thread)->cpu; 170} 171 172static inline void thread__set_cpu(struct thread *thread, int cpu) 173{ 174 RC_CHK_ACCESS(thread)->cpu = cpu; 175} 176 177static inline int thread__guest_cpu(const struct thread *thread) 178{ 179 return RC_CHK_ACCESS(thread)->guest_cpu; 180} 181 182static inline void thread__set_guest_cpu(struct thread *thread, int guest_cpu) 183{ 184 RC_CHK_ACCESS(thread)->guest_cpu = guest_cpu; 185} 186 187static inline refcount_t *thread__refcnt(struct thread *thread) 188{ 189 return &RC_CHK_ACCESS(thread)->refcnt; 190} 191 192static inline bool thread__comm_set(const struct thread *thread) 193{ 194 return RC_CHK_ACCESS(thread)->comm_set; 195} 196 197static inline void thread__set_comm_set(struct thread *thread, bool set) 198{ 199 RC_CHK_ACCESS(thread)->comm_set = set; 200} 201 202static inline int thread__var_comm_len(const struct thread *thread) 203{ 204 return RC_CHK_ACCESS(thread)->comm_len; 205} 206 207static inline void thread__set_comm_len(struct thread *thread, int len) 208{ 209 RC_CHK_ACCESS(thread)->comm_len = len; 210} 211 212static inline struct list_head *thread__namespaces_list(struct thread *thread) 213{ 214 return &RC_CHK_ACCESS(thread)->namespaces_list; 215} 216 217static inline int thread__namespaces_list_empty(const struct thread *thread) 218{ 219 return list_empty(&RC_CHK_ACCESS(thread)->namespaces_list); 220} 221 222static inline struct rw_semaphore *thread__namespaces_lock(struct thread *thread) 223{ 224 return &RC_CHK_ACCESS(thread)->namespaces_lock; 225} 226 227static inline struct list_head *thread__comm_list(struct thread *thread) 228{ 229 return &RC_CHK_ACCESS(thread)->comm_list; 230} 231 232static inline struct rw_semaphore *thread__comm_lock(struct thread *thread) 233{ 234 return &RC_CHK_ACCESS(thread)->comm_lock; 235} 236 237static inline u64 thread__db_id(const struct thread *thread) 238{ 239 return RC_CHK_ACCESS(thread)->db_id; 240} 241 242static inline void thread__set_db_id(struct thread *thread, u64 db_id) 243{ 244 RC_CHK_ACCESS(thread)->db_id = db_id; 245} 246 247static inline void *thread__priv(struct thread *thread) 248{ 249 return RC_CHK_ACCESS(thread)->priv; 250} 251 252static inline void thread__set_priv(struct thread *thread, void *p) 253{ 254 RC_CHK_ACCESS(thread)->priv = p; 255} 256 257static inline struct thread_stack *thread__ts(struct thread *thread) 258{ 259 return RC_CHK_ACCESS(thread)->ts; 260} 261 262static inline void thread__set_ts(struct thread *thread, struct thread_stack *ts) 263{ 264 RC_CHK_ACCESS(thread)->ts = ts; 265} 266 267static inline struct nsinfo *thread__nsinfo(struct thread *thread) 268{ 269 return RC_CHK_ACCESS(thread)->nsinfo; 270} 271 272static inline struct srccode_state *thread__srccode_state(struct thread *thread) 273{ 274 return &RC_CHK_ACCESS(thread)->srccode_state; 275} 276 277static inline bool thread__filter(const struct thread *thread) 278{ 279 return RC_CHK_ACCESS(thread)->filter; 280} 281 282static inline void thread__set_filter(struct thread *thread, bool filter) 283{ 284 RC_CHK_ACCESS(thread)->filter = filter; 285} 286 287static inline int thread__filter_entry_depth(const struct thread *thread) 288{ 289 return RC_CHK_ACCESS(thread)->filter_entry_depth; 290} 291 292static inline void thread__set_filter_entry_depth(struct thread *thread, int depth) 293{ 294 RC_CHK_ACCESS(thread)->filter_entry_depth = depth; 295} 296 297static inline bool thread__lbr_stitch_enable(const struct thread *thread) 298{ 299 return RC_CHK_ACCESS(thread)->lbr_stitch_enable; 300} 301 302static inline void thread__set_lbr_stitch_enable(struct thread *thread, bool en) 303{ 304 RC_CHK_ACCESS(thread)->lbr_stitch_enable = en; 305} 306 307static inline struct lbr_stitch *thread__lbr_stitch(struct thread *thread) 308{ 309 return RC_CHK_ACCESS(thread)->lbr_stitch; 310} 311 312static inline void thread__set_lbr_stitch(struct thread *thread, struct lbr_stitch *lbrs) 313{ 314 RC_CHK_ACCESS(thread)->lbr_stitch = lbrs; 315} 316 317static inline bool thread__is_filtered(struct thread *thread) 318{ 319 if (symbol_conf.comm_list && 320 !strlist__has_entry(symbol_conf.comm_list, thread__comm_str(thread))) { 321 return true; 322 } 323 324 if (symbol_conf.pid_list && 325 !intlist__has_entry(symbol_conf.pid_list, thread__pid(thread))) { 326 return true; 327 } 328 329 if (symbol_conf.tid_list && 330 !intlist__has_entry(symbol_conf.tid_list, thread__tid(thread))) { 331 return true; 332 } 333 334 return false; 335} 336 337void thread__free_stitch_list(struct thread *thread); 338 339void thread__resolve(struct thread *thread, struct addr_location *al, 340 struct perf_sample *sample); 341 342#endif /* __PERF_THREAD_H */