diff options
author | Adrian Hunter <adrian.hunter@intel.com> | 2014-07-31 02:00:44 -0400 |
---|---|---|
committer | Arnaldo Carvalho de Melo <acme@redhat.com> | 2014-08-13 18:23:08 -0400 |
commit | 65de51f93ebf9305ec011da59c0b5fe29429d1b9 (patch) | |
tree | 80a42fb96d8820b8ec0ba70189a9ea138dd28cd1 /tools/perf/util | |
parent | a5563edfa1bd25d052d81f5ad7fe74ba71c3d44e (diff) |
perf tools: Identify which comms are from exec
For grouping together all the data from a single execution, which is
needed for pairing calls and returns e.g. any outstanding calls when a
process exec's will never return.
Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Namhyung Kim <namhyung@gmail.com>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Link: http://lkml.kernel.org/r/1406786474-9306-2-git-send-email-adrian.hunter@intel.com
[ Remove testing if comm->exec is false before setting it to true ]
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Diffstat (limited to 'tools/perf/util')
-rw-r--r-- | tools/perf/util/comm.c | 7 | ||||
-rw-r--r-- | tools/perf/util/comm.h | 6 | ||||
-rw-r--r-- | tools/perf/util/machine.c | 4 | ||||
-rw-r--r-- | tools/perf/util/thread.c | 24 | ||||
-rw-r--r-- | tools/perf/util/thread.h | 10 |
5 files changed, 40 insertions, 11 deletions
diff --git a/tools/perf/util/comm.c b/tools/perf/util/comm.c index f9e777629e21..b2bb59df65e1 100644 --- a/tools/perf/util/comm.c +++ b/tools/perf/util/comm.c | |||
@@ -74,7 +74,7 @@ static struct comm_str *comm_str__findnew(const char *str, struct rb_root *root) | |||
74 | return new; | 74 | return new; |
75 | } | 75 | } |
76 | 76 | ||
77 | struct comm *comm__new(const char *str, u64 timestamp) | 77 | struct comm *comm__new(const char *str, u64 timestamp, bool exec) |
78 | { | 78 | { |
79 | struct comm *comm = zalloc(sizeof(*comm)); | 79 | struct comm *comm = zalloc(sizeof(*comm)); |
80 | 80 | ||
@@ -82,6 +82,7 @@ struct comm *comm__new(const char *str, u64 timestamp) | |||
82 | return NULL; | 82 | return NULL; |
83 | 83 | ||
84 | comm->start = timestamp; | 84 | comm->start = timestamp; |
85 | comm->exec = exec; | ||
85 | 86 | ||
86 | comm->comm_str = comm_str__findnew(str, &comm_str_root); | 87 | comm->comm_str = comm_str__findnew(str, &comm_str_root); |
87 | if (!comm->comm_str) { | 88 | if (!comm->comm_str) { |
@@ -94,7 +95,7 @@ struct comm *comm__new(const char *str, u64 timestamp) | |||
94 | return comm; | 95 | return comm; |
95 | } | 96 | } |
96 | 97 | ||
97 | int comm__override(struct comm *comm, const char *str, u64 timestamp) | 98 | int comm__override(struct comm *comm, const char *str, u64 timestamp, bool exec) |
98 | { | 99 | { |
99 | struct comm_str *new, *old = comm->comm_str; | 100 | struct comm_str *new, *old = comm->comm_str; |
100 | 101 | ||
@@ -106,6 +107,8 @@ int comm__override(struct comm *comm, const char *str, u64 timestamp) | |||
106 | comm_str__put(old); | 107 | comm_str__put(old); |
107 | comm->comm_str = new; | 108 | comm->comm_str = new; |
108 | comm->start = timestamp; | 109 | comm->start = timestamp; |
110 | if (exec) | ||
111 | comm->exec = true; | ||
109 | 112 | ||
110 | return 0; | 113 | return 0; |
111 | } | 114 | } |
diff --git a/tools/perf/util/comm.h b/tools/perf/util/comm.h index fac5bd51befc..51c10ab257f8 100644 --- a/tools/perf/util/comm.h +++ b/tools/perf/util/comm.h | |||
@@ -11,11 +11,13 @@ struct comm { | |||
11 | struct comm_str *comm_str; | 11 | struct comm_str *comm_str; |
12 | u64 start; | 12 | u64 start; |
13 | struct list_head list; | 13 | struct list_head list; |
14 | bool exec; | ||
14 | }; | 15 | }; |
15 | 16 | ||
16 | void comm__free(struct comm *comm); | 17 | void comm__free(struct comm *comm); |
17 | struct comm *comm__new(const char *str, u64 timestamp); | 18 | struct comm *comm__new(const char *str, u64 timestamp, bool exec); |
18 | const char *comm__str(const struct comm *comm); | 19 | const char *comm__str(const struct comm *comm); |
19 | int comm__override(struct comm *comm, const char *str, u64 timestamp); | 20 | int comm__override(struct comm *comm, const char *str, u64 timestamp, |
21 | bool exec); | ||
20 | 22 | ||
21 | #endif /* __PERF_COMM_H */ | 23 | #endif /* __PERF_COMM_H */ |
diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c index 16bba9fff2c8..ea3e09f6a9c6 100644 --- a/tools/perf/util/machine.c +++ b/tools/perf/util/machine.c | |||
@@ -404,11 +404,13 @@ int machine__process_comm_event(struct machine *machine, union perf_event *event | |||
404 | struct thread *thread = machine__findnew_thread(machine, | 404 | struct thread *thread = machine__findnew_thread(machine, |
405 | event->comm.pid, | 405 | event->comm.pid, |
406 | event->comm.tid); | 406 | event->comm.tid); |
407 | bool exec = event->header.misc & PERF_RECORD_MISC_COMM_EXEC; | ||
407 | 408 | ||
408 | if (dump_trace) | 409 | if (dump_trace) |
409 | perf_event__fprintf_comm(event, stdout); | 410 | perf_event__fprintf_comm(event, stdout); |
410 | 411 | ||
411 | if (thread == NULL || thread__set_comm(thread, event->comm.comm, sample->time)) { | 412 | if (thread == NULL || |
413 | __thread__set_comm(thread, event->comm.comm, sample->time, exec)) { | ||
412 | dump_printf("problem processing PERF_RECORD_COMM, skipping event.\n"); | 414 | dump_printf("problem processing PERF_RECORD_COMM, skipping event.\n"); |
413 | return -1; | 415 | return -1; |
414 | } | 416 | } |
diff --git a/tools/perf/util/thread.c b/tools/perf/util/thread.c index 12c7a253a63c..a9df7f2c6dc9 100644 --- a/tools/perf/util/thread.c +++ b/tools/perf/util/thread.c | |||
@@ -42,7 +42,7 @@ struct thread *thread__new(pid_t pid, pid_t tid) | |||
42 | goto err_thread; | 42 | goto err_thread; |
43 | 43 | ||
44 | snprintf(comm_str, 32, ":%d", tid); | 44 | snprintf(comm_str, 32, ":%d", tid); |
45 | comm = comm__new(comm_str, 0); | 45 | comm = comm__new(comm_str, 0, false); |
46 | free(comm_str); | 46 | free(comm_str); |
47 | if (!comm) | 47 | if (!comm) |
48 | goto err_thread; | 48 | goto err_thread; |
@@ -81,19 +81,33 @@ struct comm *thread__comm(const struct thread *thread) | |||
81 | return list_first_entry(&thread->comm_list, struct comm, list); | 81 | return list_first_entry(&thread->comm_list, struct comm, list); |
82 | } | 82 | } |
83 | 83 | ||
84 | struct comm *thread__exec_comm(const struct thread *thread) | ||
85 | { | ||
86 | struct comm *comm, *last = NULL; | ||
87 | |||
88 | list_for_each_entry(comm, &thread->comm_list, list) { | ||
89 | if (comm->exec) | ||
90 | return comm; | ||
91 | last = comm; | ||
92 | } | ||
93 | |||
94 | return last; | ||
95 | } | ||
96 | |||
84 | /* CHECKME: time should always be 0 if event aren't ordered */ | 97 | /* CHECKME: time should always be 0 if event aren't ordered */ |
85 | int thread__set_comm(struct thread *thread, const char *str, u64 timestamp) | 98 | int __thread__set_comm(struct thread *thread, const char *str, u64 timestamp, |
99 | bool exec) | ||
86 | { | 100 | { |
87 | struct comm *new, *curr = thread__comm(thread); | 101 | struct comm *new, *curr = thread__comm(thread); |
88 | int err; | 102 | int err; |
89 | 103 | ||
90 | /* Override latest entry if it had no specific time coverage */ | 104 | /* Override latest entry if it had no specific time coverage */ |
91 | if (!curr->start) { | 105 | if (!curr->start && !curr->exec) { |
92 | err = comm__override(curr, str, timestamp); | 106 | err = comm__override(curr, str, timestamp, exec); |
93 | if (err) | 107 | if (err) |
94 | return err; | 108 | return err; |
95 | } else { | 109 | } else { |
96 | new = comm__new(str, timestamp); | 110 | new = comm__new(str, timestamp, exec); |
97 | if (!new) | 111 | if (!new) |
98 | return -ENOMEM; | 112 | return -ENOMEM; |
99 | list_add(&new->list, &thread->comm_list); | 113 | list_add(&new->list, &thread->comm_list); |
diff --git a/tools/perf/util/thread.h b/tools/perf/util/thread.h index 716b7723cce2..8c75fa774706 100644 --- a/tools/perf/util/thread.h +++ b/tools/perf/util/thread.h | |||
@@ -38,9 +38,17 @@ static inline void thread__exited(struct thread *thread) | |||
38 | thread->dead = true; | 38 | thread->dead = true; |
39 | } | 39 | } |
40 | 40 | ||
41 | int thread__set_comm(struct thread *thread, const char *comm, u64 timestamp); | 41 | int __thread__set_comm(struct thread *thread, const char *comm, u64 timestamp, |
42 | bool exec); | ||
43 | static inline int thread__set_comm(struct thread *thread, const char *comm, | ||
44 | u64 timestamp) | ||
45 | { | ||
46 | return __thread__set_comm(thread, comm, timestamp, false); | ||
47 | } | ||
48 | |||
42 | int thread__comm_len(struct thread *thread); | 49 | int thread__comm_len(struct thread *thread); |
43 | struct comm *thread__comm(const struct thread *thread); | 50 | struct comm *thread__comm(const struct thread *thread); |
51 | struct comm *thread__exec_comm(const struct thread *thread); | ||
44 | const char *thread__comm_str(const struct thread *thread); | 52 | const char *thread__comm_str(const struct thread *thread); |
45 | void thread__insert_map(struct thread *thread, struct map *map); | 53 | void thread__insert_map(struct thread *thread, struct map *map); |
46 | int thread__fork(struct thread *thread, struct thread *parent, u64 timestamp); | 54 | int thread__fork(struct thread *thread, struct thread *parent, u64 timestamp); |