at v6.5-rc2 340 lines 8.6 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 74struct thread *thread__get(struct thread *thread); 75void thread__put(struct thread *thread); 76 77static inline void __thread__zput(struct thread **thread) 78{ 79 thread__put(*thread); 80 *thread = NULL; 81} 82 83#define thread__zput(thread) __thread__zput(&thread) 84 85struct namespaces *thread__namespaces(struct thread *thread); 86int thread__set_namespaces(struct thread *thread, u64 timestamp, 87 struct perf_record_namespaces *event); 88 89int __thread__set_comm(struct thread *thread, const char *comm, u64 timestamp, 90 bool exec); 91static inline int thread__set_comm(struct thread *thread, const char *comm, 92 u64 timestamp) 93{ 94 return __thread__set_comm(thread, comm, timestamp, false); 95} 96 97int thread__set_comm_from_proc(struct thread *thread); 98 99int thread__comm_len(struct thread *thread); 100struct comm *thread__comm(struct thread *thread); 101struct comm *thread__exec_comm(struct thread *thread); 102const char *thread__comm_str(struct thread *thread); 103int thread__insert_map(struct thread *thread, struct map *map); 104int thread__fork(struct thread *thread, struct thread *parent, u64 timestamp, bool do_maps_clone); 105size_t thread__fprintf(struct thread *thread, FILE *fp); 106 107struct thread *thread__main_thread(struct machine *machine, struct thread *thread); 108 109struct map *thread__find_map(struct thread *thread, u8 cpumode, u64 addr, 110 struct addr_location *al); 111struct map *thread__find_map_fb(struct thread *thread, u8 cpumode, u64 addr, 112 struct addr_location *al); 113 114struct symbol *thread__find_symbol(struct thread *thread, u8 cpumode, 115 u64 addr, struct addr_location *al); 116struct symbol *thread__find_symbol_fb(struct thread *thread, u8 cpumode, 117 u64 addr, struct addr_location *al); 118 119void thread__find_cpumode_addr_location(struct thread *thread, u64 addr, 120 struct addr_location *al); 121 122int thread__memcpy(struct thread *thread, struct machine *machine, 123 void *buf, u64 ip, int len, bool *is64bit); 124 125static inline struct maps *thread__maps(struct thread *thread) 126{ 127 return RC_CHK_ACCESS(thread)->maps; 128} 129 130static inline void thread__set_maps(struct thread *thread, struct maps *maps) 131{ 132 RC_CHK_ACCESS(thread)->maps = maps; 133} 134 135static inline pid_t thread__pid(const struct thread *thread) 136{ 137 return RC_CHK_ACCESS(thread)->pid_; 138} 139 140static inline void thread__set_pid(struct thread *thread, pid_t pid_) 141{ 142 RC_CHK_ACCESS(thread)->pid_ = pid_; 143} 144 145static inline pid_t thread__tid(const struct thread *thread) 146{ 147 return RC_CHK_ACCESS(thread)->tid; 148} 149 150static inline void thread__set_tid(struct thread *thread, pid_t tid) 151{ 152 RC_CHK_ACCESS(thread)->tid = tid; 153} 154 155static inline pid_t thread__ppid(const struct thread *thread) 156{ 157 return RC_CHK_ACCESS(thread)->ppid; 158} 159 160static inline void thread__set_ppid(struct thread *thread, pid_t ppid) 161{ 162 RC_CHK_ACCESS(thread)->ppid = ppid; 163} 164 165static inline int thread__cpu(const struct thread *thread) 166{ 167 return RC_CHK_ACCESS(thread)->cpu; 168} 169 170static inline void thread__set_cpu(struct thread *thread, int cpu) 171{ 172 RC_CHK_ACCESS(thread)->cpu = cpu; 173} 174 175static inline int thread__guest_cpu(const struct thread *thread) 176{ 177 return RC_CHK_ACCESS(thread)->guest_cpu; 178} 179 180static inline void thread__set_guest_cpu(struct thread *thread, int guest_cpu) 181{ 182 RC_CHK_ACCESS(thread)->guest_cpu = guest_cpu; 183} 184 185static inline refcount_t *thread__refcnt(struct thread *thread) 186{ 187 return &RC_CHK_ACCESS(thread)->refcnt; 188} 189 190static inline bool thread__comm_set(const struct thread *thread) 191{ 192 return RC_CHK_ACCESS(thread)->comm_set; 193} 194 195static inline void thread__set_comm_set(struct thread *thread, bool set) 196{ 197 RC_CHK_ACCESS(thread)->comm_set = set; 198} 199 200static inline int thread__var_comm_len(const struct thread *thread) 201{ 202 return RC_CHK_ACCESS(thread)->comm_len; 203} 204 205static inline void thread__set_comm_len(struct thread *thread, int len) 206{ 207 RC_CHK_ACCESS(thread)->comm_len = len; 208} 209 210static inline struct list_head *thread__namespaces_list(struct thread *thread) 211{ 212 return &RC_CHK_ACCESS(thread)->namespaces_list; 213} 214 215static inline int thread__namespaces_list_empty(const struct thread *thread) 216{ 217 return list_empty(&RC_CHK_ACCESS(thread)->namespaces_list); 218} 219 220static inline struct rw_semaphore *thread__namespaces_lock(struct thread *thread) 221{ 222 return &RC_CHK_ACCESS(thread)->namespaces_lock; 223} 224 225static inline struct list_head *thread__comm_list(struct thread *thread) 226{ 227 return &RC_CHK_ACCESS(thread)->comm_list; 228} 229 230static inline struct rw_semaphore *thread__comm_lock(struct thread *thread) 231{ 232 return &RC_CHK_ACCESS(thread)->comm_lock; 233} 234 235static inline u64 thread__db_id(const struct thread *thread) 236{ 237 return RC_CHK_ACCESS(thread)->db_id; 238} 239 240static inline void thread__set_db_id(struct thread *thread, u64 db_id) 241{ 242 RC_CHK_ACCESS(thread)->db_id = db_id; 243} 244 245static inline void *thread__priv(struct thread *thread) 246{ 247 return RC_CHK_ACCESS(thread)->priv; 248} 249 250static inline void thread__set_priv(struct thread *thread, void *p) 251{ 252 RC_CHK_ACCESS(thread)->priv = p; 253} 254 255static inline struct thread_stack *thread__ts(struct thread *thread) 256{ 257 return RC_CHK_ACCESS(thread)->ts; 258} 259 260static inline void thread__set_ts(struct thread *thread, struct thread_stack *ts) 261{ 262 RC_CHK_ACCESS(thread)->ts = ts; 263} 264 265static inline struct nsinfo *thread__nsinfo(struct thread *thread) 266{ 267 return RC_CHK_ACCESS(thread)->nsinfo; 268} 269 270static inline struct srccode_state *thread__srccode_state(struct thread *thread) 271{ 272 return &RC_CHK_ACCESS(thread)->srccode_state; 273} 274 275static inline bool thread__filter(const struct thread *thread) 276{ 277 return RC_CHK_ACCESS(thread)->filter; 278} 279 280static inline void thread__set_filter(struct thread *thread, bool filter) 281{ 282 RC_CHK_ACCESS(thread)->filter = filter; 283} 284 285static inline int thread__filter_entry_depth(const struct thread *thread) 286{ 287 return RC_CHK_ACCESS(thread)->filter_entry_depth; 288} 289 290static inline void thread__set_filter_entry_depth(struct thread *thread, int depth) 291{ 292 RC_CHK_ACCESS(thread)->filter_entry_depth = depth; 293} 294 295static inline bool thread__lbr_stitch_enable(const struct thread *thread) 296{ 297 return RC_CHK_ACCESS(thread)->lbr_stitch_enable; 298} 299 300static inline void thread__set_lbr_stitch_enable(struct thread *thread, bool en) 301{ 302 RC_CHK_ACCESS(thread)->lbr_stitch_enable = en; 303} 304 305static inline struct lbr_stitch *thread__lbr_stitch(struct thread *thread) 306{ 307 return RC_CHK_ACCESS(thread)->lbr_stitch; 308} 309 310static inline void thread__set_lbr_stitch(struct thread *thread, struct lbr_stitch *lbrs) 311{ 312 RC_CHK_ACCESS(thread)->lbr_stitch = lbrs; 313} 314 315static inline bool thread__is_filtered(struct thread *thread) 316{ 317 if (symbol_conf.comm_list && 318 !strlist__has_entry(symbol_conf.comm_list, thread__comm_str(thread))) { 319 return true; 320 } 321 322 if (symbol_conf.pid_list && 323 !intlist__has_entry(symbol_conf.pid_list, thread__pid(thread))) { 324 return true; 325 } 326 327 if (symbol_conf.tid_list && 328 !intlist__has_entry(symbol_conf.tid_list, thread__tid(thread))) { 329 return true; 330 } 331 332 return false; 333} 334 335void thread__free_stitch_list(struct thread *thread); 336 337void thread__resolve(struct thread *thread, struct addr_location *al, 338 struct perf_sample *sample); 339 340#endif /* __PERF_THREAD_H */