Commit 9a92b479b2f088ee2d3194243f4c8e59b1b8c9c2

Authored by Frederic Weisbecker
Committed by Ingo Molnar
1 parent 016e92fbc9

perf tools: Improve thread comm resolution in perf sched

When we get sched traces that involve a task that was already
created before opening the event, we won't have the comm event for
it.

So if we can't find the comm event for a given thread, we look at
the traces that may contain these informations.

Before:

 ata/1:371             |      0.000 ms |        1 | avg: 3988.693 ms | max: 3988.693 ms |
 kondemand/1:421       |      0.096 ms |        3 | avg:  345.346 ms | max: 1035.989 ms |
 kondemand/0:420       |      0.025 ms |        3 | avg:  421.332 ms | max:  964.014 ms |
 :5124:5124            |      0.103 ms |        5 | avg:   74.082 ms | max:  277.194 ms |
 :6244:6244            |      0.691 ms |        9 | avg:  125.655 ms | max:  271.306 ms |
 firefox:5080          |      0.924 ms |        5 | avg:   53.833 ms | max:  257.828 ms |
 npviewer.bin:6225     |     21.871 ms |       53 | avg:   22.462 ms | max:  220.835 ms |
 :6245:6245            |      9.631 ms |       21 | avg:   41.864 ms | max:  213.349 ms |

After:

 ata/1:371             |      0.000 ms |        1 | avg: 3988.693 ms | max: 3988.693 ms |
 kondemand/1:421       |      0.096 ms |        3 | avg:  345.346 ms | max: 1035.989 ms |
 kondemand/0:420       |      0.025 ms |        3 | avg:  421.332 ms | max:  964.014 ms |
 firefox:5124          |      0.103 ms |        5 | avg:   74.082 ms | max:  277.194 ms |
 npviewer.bin:6244     |      0.691 ms |        9 | avg:  125.655 ms | max:  271.306 ms |
 firefox:5080          |      0.924 ms |        5 | avg:   53.833 ms | max:  257.828 ms |
 npviewer.bin:6225     |     21.871 ms |       53 | avg:   22.462 ms | max:  220.835 ms |
 npviewer.bin:6245     |      9.631 ms |       21 | avg:   41.864 ms | max:  213.349 ms |

Signed-off-by: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Paul Mackerras <paulus@samba.org>
LKML-Reference: <1255012632-7882-1-git-send-email-fweisbec@gmail.com>
Signed-off-by: Ingo Molnar <mingo@elte.hu>

Showing 3 changed files with 67 additions and 12 deletions Side-by-side Diff

tools/perf/builtin-sched.c
... ... @@ -1034,6 +1034,36 @@
1034 1034 atoms->nb_atoms++;
1035 1035 }
1036 1036  
  1037 +static struct thread *
  1038 +threads__findnew_from_ctx(u32 pid, struct trace_switch_event *switch_event)
  1039 +{
  1040 + struct thread *th;
  1041 +
  1042 + th = threads__findnew_nocomm(pid, &threads, &last_match);
  1043 + if (th->comm)
  1044 + return th;
  1045 +
  1046 + if (pid == switch_event->prev_pid)
  1047 + thread__set_comm(th, switch_event->prev_comm);
  1048 + else
  1049 + thread__set_comm(th, switch_event->next_comm);
  1050 + return th;
  1051 +}
  1052 +
  1053 +static struct thread *
  1054 +threads__findnew_from_wakeup(struct trace_wakeup_event *wakeup_event)
  1055 +{
  1056 + struct thread *th;
  1057 +
  1058 + th = threads__findnew_nocomm(wakeup_event->pid, &threads, &last_match);
  1059 + if (th->comm)
  1060 + return th;
  1061 +
  1062 + thread__set_comm(th, wakeup_event->comm);
  1063 +
  1064 + return th;
  1065 +}
  1066 +
1037 1067 static void
1038 1068 latency_switch_event(struct trace_switch_event *switch_event,
1039 1069 struct event *event __used,
... ... @@ -1059,8 +1089,10 @@
1059 1089 die("hm, delta: %Ld < 0 ?\n", delta);
1060 1090  
1061 1091  
1062   - sched_out = threads__findnew(switch_event->prev_pid, &threads, &last_match);
1063   - sched_in = threads__findnew(switch_event->next_pid, &threads, &last_match);
  1092 + sched_out = threads__findnew_from_ctx(switch_event->prev_pid,
  1093 + switch_event);
  1094 + sched_in = threads__findnew_from_ctx(switch_event->next_pid,
  1095 + switch_event);
1064 1096  
1065 1097 out_events = thread_atoms_search(&atom_root, sched_out, &cmp_pid);
1066 1098 if (!out_events) {
... ... @@ -1126,7 +1158,7 @@
1126 1158 if (!wakeup_event->success)
1127 1159 return;
1128 1160  
1129   - wakee = threads__findnew(wakeup_event->pid, &threads, &last_match);
  1161 + wakee = threads__findnew_from_wakeup(wakeup_event);
1130 1162 atoms = thread_atoms_search(&atom_root, wakee, &cmp_pid);
1131 1163 if (!atoms) {
1132 1164 thread_atoms_insert(wakee);
... ... @@ -1386,8 +1418,10 @@
1386 1418 die("hm, delta: %Ld < 0 ?\n", delta);
1387 1419  
1388 1420  
1389   - sched_out = threads__findnew(switch_event->prev_pid, &threads, &last_match);
1390   - sched_in = threads__findnew(switch_event->next_pid, &threads, &last_match);
  1421 + sched_out = threads__findnew_from_ctx(switch_event->prev_pid,
  1422 + switch_event);
  1423 + sched_in = threads__findnew_from_ctx(switch_event->next_pid,
  1424 + switch_event);
1391 1425  
1392 1426 curr_thread[this_cpu] = sched_in;
1393 1427  
tools/perf/util/thread.c
... ... @@ -6,15 +6,17 @@
6 6 #include "util.h"
7 7 #include "debug.h"
8 8  
9   -static struct thread *thread__new(pid_t pid)
  9 +static struct thread *thread__new(pid_t pid, int set_comm)
10 10 {
11 11 struct thread *self = calloc(1, sizeof(*self));
12 12  
13 13 if (self != NULL) {
14 14 self->pid = pid;
15   - self->comm = malloc(32);
16   - if (self->comm)
17   - snprintf(self->comm, 32, ":%d", self->pid);
  15 + if (set_comm) {
  16 + self->comm = malloc(32);
  17 + if (self->comm)
  18 + snprintf(self->comm, 32, ":%d", self->pid);
  19 + }
18 20 self->maps = RB_ROOT;
19 21 INIT_LIST_HEAD(&self->removed_maps);
20 22 }
... ... @@ -50,8 +52,10 @@
50 52 return ret;
51 53 }
52 54  
53   -struct thread *
54   -threads__findnew(pid_t pid, struct rb_root *threads, struct thread **last_match)
  55 +static struct thread *
  56 +__threads__findnew(pid_t pid, struct rb_root *threads,
  57 + struct thread **last_match,
  58 + int set_comm)
55 59 {
56 60 struct rb_node **p = &threads->rb_node;
57 61 struct rb_node *parent = NULL;
... ... @@ -80,7 +84,8 @@
80 84 p = &(*p)->rb_right;
81 85 }
82 86  
83   - th = thread__new(pid);
  87 + th = thread__new(pid, set_comm);
  88 +
84 89 if (th != NULL) {
85 90 rb_link_node(&th->rb_node, parent, p);
86 91 rb_insert_color(&th->rb_node, threads);
... ... @@ -88,6 +93,19 @@
88 93 }
89 94  
90 95 return th;
  96 +}
  97 +
  98 +struct thread *
  99 +threads__findnew(pid_t pid, struct rb_root *threads, struct thread **last_match)
  100 +{
  101 + return __threads__findnew(pid, threads, last_match, 1);
  102 +}
  103 +
  104 +struct thread *
  105 +threads__findnew_nocomm(pid_t pid, struct rb_root *threads,
  106 + struct thread **last_match)
  107 +{
  108 + return __threads__findnew(pid, threads, last_match, 0);
91 109 }
92 110  
93 111 struct thread *
tools/perf/util/thread.h
... ... @@ -18,6 +18,9 @@
18 18 struct thread *
19 19 threads__findnew(pid_t pid, struct rb_root *threads, struct thread **last_match);
20 20 struct thread *
  21 +threads__findnew_nocomm(pid_t pid, struct rb_root *threads,
  22 + struct thread **last_match);
  23 +struct thread *
21 24 register_idle_thread(struct rb_root *threads, struct thread **last_match);
22 25 void thread__insert_map(struct thread *self, struct map *map);
23 26 int thread__fork(struct thread *self, struct thread *parent);