diff options
Diffstat (limited to 'tools/perf')
-rw-r--r-- | tools/perf/util/machine.c | 57 | ||||
-rw-r--r-- | tools/perf/util/map.c | 14 | ||||
-rw-r--r-- | tools/perf/util/map.h | 1 |
3 files changed, 66 insertions, 6 deletions
diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c index 5b8087728f28..5484fa4385fc 100644 --- a/tools/perf/util/machine.c +++ b/tools/perf/util/machine.c | |||
@@ -272,6 +272,52 @@ void machines__set_id_hdr_size(struct machines *machines, u16 id_hdr_size) | |||
272 | return; | 272 | return; |
273 | } | 273 | } |
274 | 274 | ||
275 | static void machine__update_thread_pid(struct machine *machine, | ||
276 | struct thread *th, pid_t pid) | ||
277 | { | ||
278 | struct thread *leader; | ||
279 | |||
280 | if (pid == th->pid_ || pid == -1 || th->pid_ != -1) | ||
281 | return; | ||
282 | |||
283 | th->pid_ = pid; | ||
284 | |||
285 | if (th->pid_ == th->tid) | ||
286 | return; | ||
287 | |||
288 | leader = machine__findnew_thread(machine, th->pid_, th->pid_); | ||
289 | if (!leader) | ||
290 | goto out_err; | ||
291 | |||
292 | if (!leader->mg) | ||
293 | leader->mg = map_groups__new(); | ||
294 | |||
295 | if (!leader->mg) | ||
296 | goto out_err; | ||
297 | |||
298 | if (th->mg == leader->mg) | ||
299 | return; | ||
300 | |||
301 | if (th->mg) { | ||
302 | /* | ||
303 | * Maps are created from MMAP events which provide the pid and | ||
304 | * tid. Consequently there never should be any maps on a thread | ||
305 | * with an unknown pid. Just print an error if there are. | ||
306 | */ | ||
307 | if (!map_groups__empty(th->mg)) | ||
308 | pr_err("Discarding thread maps for %d:%d\n", | ||
309 | th->pid_, th->tid); | ||
310 | map_groups__delete(th->mg); | ||
311 | } | ||
312 | |||
313 | th->mg = map_groups__get(leader->mg); | ||
314 | |||
315 | return; | ||
316 | |||
317 | out_err: | ||
318 | pr_err("Failed to join map groups for %d:%d\n", th->pid_, th->tid); | ||
319 | } | ||
320 | |||
275 | static struct thread *__machine__findnew_thread(struct machine *machine, | 321 | static struct thread *__machine__findnew_thread(struct machine *machine, |
276 | pid_t pid, pid_t tid, | 322 | pid_t pid, pid_t tid, |
277 | bool create) | 323 | bool create) |
@@ -285,10 +331,10 @@ static struct thread *__machine__findnew_thread(struct machine *machine, | |||
285 | * so most of the time we dont have to look up | 331 | * so most of the time we dont have to look up |
286 | * the full rbtree: | 332 | * the full rbtree: |
287 | */ | 333 | */ |
288 | if (machine->last_match && machine->last_match->tid == tid) { | 334 | th = machine->last_match; |
289 | if (pid != -1 && pid != machine->last_match->pid_) | 335 | if (th && th->tid == tid) { |
290 | machine->last_match->pid_ = pid; | 336 | machine__update_thread_pid(machine, th, pid); |
291 | return machine->last_match; | 337 | return th; |
292 | } | 338 | } |
293 | 339 | ||
294 | while (*p != NULL) { | 340 | while (*p != NULL) { |
@@ -297,8 +343,7 @@ static struct thread *__machine__findnew_thread(struct machine *machine, | |||
297 | 343 | ||
298 | if (th->tid == tid) { | 344 | if (th->tid == tid) { |
299 | machine->last_match = th; | 345 | machine->last_match = th; |
300 | if (pid != -1 && pid != th->pid_) | 346 | machine__update_thread_pid(machine, th, pid); |
301 | th->pid_ = pid; | ||
302 | return th; | 347 | return th; |
303 | } | 348 | } |
304 | 349 | ||
diff --git a/tools/perf/util/map.c b/tools/perf/util/map.c index 25c571f4cba6..7af14807ee90 100644 --- a/tools/perf/util/map.c +++ b/tools/perf/util/map.c | |||
@@ -454,6 +454,20 @@ void map_groups__exit(struct map_groups *mg) | |||
454 | } | 454 | } |
455 | } | 455 | } |
456 | 456 | ||
457 | bool map_groups__empty(struct map_groups *mg) | ||
458 | { | ||
459 | int i; | ||
460 | |||
461 | for (i = 0; i < MAP__NR_TYPES; ++i) { | ||
462 | if (maps__first(&mg->maps[i])) | ||
463 | return false; | ||
464 | if (!list_empty(&mg->removed_maps[i])) | ||
465 | return false; | ||
466 | } | ||
467 | |||
468 | return true; | ||
469 | } | ||
470 | |||
457 | struct map_groups *map_groups__new(void) | 471 | struct map_groups *map_groups__new(void) |
458 | { | 472 | { |
459 | struct map_groups *mg = malloc(sizeof(*mg)); | 473 | struct map_groups *mg = malloc(sizeof(*mg)); |
diff --git a/tools/perf/util/map.h b/tools/perf/util/map.h index 7758c72522ef..5806a906198b 100644 --- a/tools/perf/util/map.h +++ b/tools/perf/util/map.h | |||
@@ -66,6 +66,7 @@ struct map_groups { | |||
66 | 66 | ||
67 | struct map_groups *map_groups__new(void); | 67 | struct map_groups *map_groups__new(void); |
68 | void map_groups__delete(struct map_groups *mg); | 68 | void map_groups__delete(struct map_groups *mg); |
69 | bool map_groups__empty(struct map_groups *mg); | ||
69 | 70 | ||
70 | static inline struct map_groups *map_groups__get(struct map_groups *mg) | 71 | static inline struct map_groups *map_groups__get(struct map_groups *mg) |
71 | { | 72 | { |