1 // SPDX-License-Identifier: GPL-2.0 2 #include "../perf.h" 3 #include <errno.h> 4 #include <stdlib.h> 5 #include <stdio.h> 6 #include <string.h> 7 #include <linux/kernel.h> 8 #include "session.h" 9 #include "thread.h" 10 #include "thread-stack.h" 11 #include "util.h" 12 #include "debug.h" 13 #include "namespaces.h" 14 #include "comm.h" 15 #include "unwind.h" 16 17 #include <api/fs/fs.h> 18 19 int thread__init_map_groups(struct thread *thread, struct machine *machine) 20 { 21 pid_t pid = thread->pid_; 22 23 if (pid == thread->tid || pid == -1) { 24 thread->mg = map_groups__new(machine); 25 } else { 26 struct thread *leader = __machine__findnew_thread(machine, pid, pid); 27 if (leader) { 28 thread->mg = map_groups__get(leader->mg); 29 thread__put(leader); 30 } 31 } 32 33 return thread->mg ? 0 : -1; 34 } 35 36 struct thread *thread__new(pid_t pid, pid_t tid) 37 { 38 char *comm_str; 39 struct comm *comm; 40 struct thread *thread = zalloc(sizeof(*thread)); 41 42 if (thread != NULL) { 43 thread->pid_ = pid; 44 thread->tid = tid; 45 thread->ppid = -1; 46 thread->cpu = -1; 47 INIT_LIST_HEAD(&thread->namespaces_list); 48 INIT_LIST_HEAD(&thread->comm_list); 49 init_rwsem(&thread->namespaces_lock); 50 init_rwsem(&thread->comm_lock); 51 52 comm_str = malloc(32); 53 if (!comm_str) 54 goto err_thread; 55 56 snprintf(comm_str, 32, ":%d", tid); 57 comm = comm__new(comm_str, 0, false); 58 free(comm_str); 59 if (!comm) 60 goto err_thread; 61 62 list_add(&comm->list, &thread->comm_list); 63 refcount_set(&thread->refcnt, 1); 64 RB_CLEAR_NODE(&thread->rb_node); 65 /* Thread holds first ref to nsdata. */ 66 thread->nsinfo = nsinfo__new(pid); 67 } 68 69 return thread; 70 71 err_thread: 72 free(thread); 73 return NULL; 74 } 75 76 void thread__delete(struct thread *thread) 77 { 78 struct namespaces *namespaces, *tmp_namespaces; 79 struct comm *comm, *tmp_comm; 80 81 BUG_ON(!RB_EMPTY_NODE(&thread->rb_node)); 82 83 thread_stack__free(thread); 84 85 if (thread->mg) { 86 map_groups__put(thread->mg); 87 thread->mg = NULL; 88 } 89 down_write(&thread->namespaces_lock); 90 list_for_each_entry_safe(namespaces, tmp_namespaces, 91 &thread->namespaces_list, list) { 92 list_del(&namespaces->list); 93 namespaces__free(namespaces); 94 } 95 up_write(&thread->namespaces_lock); 96 97 down_write(&thread->comm_lock); 98 list_for_each_entry_safe(comm, tmp_comm, &thread->comm_list, list) { 99 list_del(&comm->list); 100 comm__free(comm); 101 } 102 up_write(&thread->comm_lock); 103 104 unwind__finish_access(thread); 105 nsinfo__zput(thread->nsinfo); 106 107 exit_rwsem(&thread->namespaces_lock); 108 exit_rwsem(&thread->comm_lock); 109 free(thread); 110 } 111 112 struct thread *thread__get(struct thread *thread) 113 { 114 if (thread) 115 refcount_inc(&thread->refcnt); 116 return thread; 117 } 118 119 void thread__put(struct thread *thread) 120 { 121 if (thread && refcount_dec_and_test(&thread->refcnt)) { 122 /* 123 * Remove it from the dead_threads list, as last reference 124 * is gone. 125 */ 126 list_del_init(&thread->node); 127 thread__delete(thread); 128 } 129 } 130 131 struct namespaces *thread__namespaces(const struct thread *thread) 132 { 133 if (list_empty(&thread->namespaces_list)) 134 return NULL; 135 136 return list_first_entry(&thread->namespaces_list, struct namespaces, list); 137 } 138 139 static int __thread__set_namespaces(struct thread *thread, u64 timestamp, 140 struct namespaces_event *event) 141 { 142 struct namespaces *new, *curr = thread__namespaces(thread); 143 144 new = namespaces__new(event); 145 if (!new) 146 return -ENOMEM; 147 148 list_add(&new->list, &thread->namespaces_list); 149 150 if (timestamp && curr) { 151 /* 152 * setns syscall must have changed few or all the namespaces 153 * of this thread. Update end time for the namespaces 154 * previously used. 155 */ 156 curr = list_next_entry(new, list); 157 curr->end_time = timestamp; 158 } 159 160 return 0; 161 } 162 163 int thread__set_namespaces(struct thread *thread, u64 timestamp, 164 struct namespaces_event *event) 165 { 166 int ret; 167 168 down_write(&thread->namespaces_lock); 169 ret = __thread__set_namespaces(thread, timestamp, event); 170 up_write(&thread->namespaces_lock); 171 return ret; 172 } 173 174 struct comm *thread__comm(const struct thread *thread) 175 { 176 if (list_empty(&thread->comm_list)) 177 return NULL; 178 179 return list_first_entry(&thread->comm_list, struct comm, list); 180 } 181 182 struct comm *thread__exec_comm(const struct thread *thread) 183 { 184 struct comm *comm, *last = NULL; 185 186 list_for_each_entry(comm, &thread->comm_list, list) { 187 if (comm->exec) 188 return comm; 189 last = comm; 190 } 191 192 return last; 193 } 194 195 static int ____thread__set_comm(struct thread *thread, const char *str, 196 u64 timestamp, bool exec) 197 { 198 struct comm *new, *curr = thread__comm(thread); 199 200 /* Override the default :tid entry */ 201 if (!thread->comm_set) { 202 int err = comm__override(curr, str, timestamp, exec); 203 if (err) 204 return err; 205 } else { 206 new = comm__new(str, timestamp, exec); 207 if (!new) 208 return -ENOMEM; 209 list_add(&new->list, &thread->comm_list); 210 211 if (exec) 212 unwind__flush_access(thread); 213 } 214 215 thread->comm_set = true; 216 217 return 0; 218 } 219 220 int __thread__set_comm(struct thread *thread, const char *str, u64 timestamp, 221 bool exec) 222 { 223 int ret; 224 225 down_write(&thread->comm_lock); 226 ret = ____thread__set_comm(thread, str, timestamp, exec); 227 up_write(&thread->comm_lock); 228 return ret; 229 } 230 231 int thread__set_comm_from_proc(struct thread *thread) 232 { 233 char path[64]; 234 char *comm = NULL; 235 size_t sz; 236 int err = -1; 237 238 if (!(snprintf(path, sizeof(path), "%d/task/%d/comm", 239 thread->pid_, thread->tid) >= (int)sizeof(path)) && 240 procfs__read_str(path, &comm, &sz) == 0) { 241 comm[sz - 1] = '\0'; 242 err = thread__set_comm(thread, comm, 0); 243 } 244 245 return err; 246 } 247 248 static const char *__thread__comm_str(const struct thread *thread) 249 { 250 const struct comm *comm = thread__comm(thread); 251 252 if (!comm) 253 return NULL; 254 255 return comm__str(comm); 256 } 257 258 const char *thread__comm_str(const struct thread *thread) 259 { 260 const char *str; 261 262 down_read((struct rw_semaphore *)&thread->comm_lock); 263 str = __thread__comm_str(thread); 264 up_read((struct rw_semaphore *)&thread->comm_lock); 265 266 return str; 267 } 268 269 /* CHECKME: it should probably better return the max comm len from its comm list */ 270 int thread__comm_len(struct thread *thread) 271 { 272 if (!thread->comm_len) { 273 const char *comm = thread__comm_str(thread); 274 if (!comm) 275 return 0; 276 thread->comm_len = strlen(comm); 277 } 278 279 return thread->comm_len; 280 } 281 282 size_t thread__fprintf(struct thread *thread, FILE *fp) 283 { 284 return fprintf(fp, "Thread %d %s\n", thread->tid, thread__comm_str(thread)) + 285 map_groups__fprintf(thread->mg, fp); 286 } 287 288 int thread__insert_map(struct thread *thread, struct map *map) 289 { 290 int ret; 291 292 ret = unwind__prepare_access(thread, map, NULL); 293 if (ret) 294 return ret; 295 296 map_groups__fixup_overlappings(thread->mg, map, stderr); 297 map_groups__insert(thread->mg, map); 298 299 return 0; 300 } 301 302 static int __thread__prepare_access(struct thread *thread) 303 { 304 bool initialized = false; 305 int i, err = 0; 306 307 for (i = 0; i < MAP__NR_TYPES; ++i) { 308 struct maps *maps = &thread->mg->maps[i]; 309 struct map *map; 310 311 down_read(&maps->lock); 312 313 for (map = maps__first(maps); map; map = map__next(map)) { 314 err = unwind__prepare_access(thread, map, &initialized); 315 if (err || initialized) 316 break; 317 } 318 319 up_read(&maps->lock); 320 } 321 322 return err; 323 } 324 325 static int thread__prepare_access(struct thread *thread) 326 { 327 int err = 0; 328 329 if (symbol_conf.use_callchain) 330 err = __thread__prepare_access(thread); 331 332 return err; 333 } 334 335 static int thread__clone_map_groups(struct thread *thread, 336 struct thread *parent) 337 { 338 int i; 339 340 /* This is new thread, we share map groups for process. */ 341 if (thread->pid_ == parent->pid_) 342 return thread__prepare_access(thread); 343 344 if (thread->mg == parent->mg) { 345 pr_debug("broken map groups on thread %d/%d parent %d/%d\n", 346 thread->pid_, thread->tid, parent->pid_, parent->tid); 347 return 0; 348 } 349 350 /* But this one is new process, copy maps. */ 351 for (i = 0; i < MAP__NR_TYPES; ++i) 352 if (map_groups__clone(thread, parent->mg, i) < 0) 353 return -ENOMEM; 354 355 return 0; 356 } 357 358 int thread__fork(struct thread *thread, struct thread *parent, u64 timestamp) 359 { 360 if (parent->comm_set) { 361 const char *comm = thread__comm_str(parent); 362 int err; 363 if (!comm) 364 return -ENOMEM; 365 err = thread__set_comm(thread, comm, timestamp); 366 if (err) 367 return err; 368 } 369 370 thread->ppid = parent->tid; 371 return thread__clone_map_groups(thread, parent); 372 } 373 374 void thread__find_cpumode_addr_location(struct thread *thread, 375 enum map_type type, u64 addr, 376 struct addr_location *al) 377 { 378 size_t i; 379 const u8 cpumodes[] = { 380 PERF_RECORD_MISC_USER, 381 PERF_RECORD_MISC_KERNEL, 382 PERF_RECORD_MISC_GUEST_USER, 383 PERF_RECORD_MISC_GUEST_KERNEL 384 }; 385 386 for (i = 0; i < ARRAY_SIZE(cpumodes); i++) { 387 thread__find_addr_location(thread, cpumodes[i], type, addr, al); 388 if (al->map) 389 break; 390 } 391 } 392 393 struct thread *thread__main_thread(struct machine *machine, struct thread *thread) 394 { 395 if (thread->pid_ == thread->tid) 396 return thread__get(thread); 397 398 if (thread->pid_ == -1) 399 return NULL; 400 401 return machine__find_thread(machine, thread->pid_, thread->pid_); 402 } 403