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>
This commit is contained in:
parent
a5563edfa1
commit
65de51f93e
@ -74,7 +74,7 @@ static struct comm_str *comm_str__findnew(const char *str, struct rb_root *root)
|
|||||||
return new;
|
return new;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct comm *comm__new(const char *str, u64 timestamp)
|
struct comm *comm__new(const char *str, u64 timestamp, bool exec)
|
||||||
{
|
{
|
||||||
struct comm *comm = zalloc(sizeof(*comm));
|
struct comm *comm = zalloc(sizeof(*comm));
|
||||||
|
|
||||||
@ -82,6 +82,7 @@ struct comm *comm__new(const char *str, u64 timestamp)
|
|||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
comm->start = timestamp;
|
comm->start = timestamp;
|
||||||
|
comm->exec = exec;
|
||||||
|
|
||||||
comm->comm_str = comm_str__findnew(str, &comm_str_root);
|
comm->comm_str = comm_str__findnew(str, &comm_str_root);
|
||||||
if (!comm->comm_str) {
|
if (!comm->comm_str) {
|
||||||
@ -94,7 +95,7 @@ struct comm *comm__new(const char *str, u64 timestamp)
|
|||||||
return comm;
|
return comm;
|
||||||
}
|
}
|
||||||
|
|
||||||
int comm__override(struct comm *comm, const char *str, u64 timestamp)
|
int comm__override(struct comm *comm, const char *str, u64 timestamp, bool exec)
|
||||||
{
|
{
|
||||||
struct comm_str *new, *old = comm->comm_str;
|
struct comm_str *new, *old = comm->comm_str;
|
||||||
|
|
||||||
@ -106,6 +107,8 @@ int comm__override(struct comm *comm, const char *str, u64 timestamp)
|
|||||||
comm_str__put(old);
|
comm_str__put(old);
|
||||||
comm->comm_str = new;
|
comm->comm_str = new;
|
||||||
comm->start = timestamp;
|
comm->start = timestamp;
|
||||||
|
if (exec)
|
||||||
|
comm->exec = true;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -11,11 +11,13 @@ struct comm {
|
|||||||
struct comm_str *comm_str;
|
struct comm_str *comm_str;
|
||||||
u64 start;
|
u64 start;
|
||||||
struct list_head list;
|
struct list_head list;
|
||||||
|
bool exec;
|
||||||
};
|
};
|
||||||
|
|
||||||
void comm__free(struct comm *comm);
|
void comm__free(struct comm *comm);
|
||||||
struct comm *comm__new(const char *str, u64 timestamp);
|
struct comm *comm__new(const char *str, u64 timestamp, bool exec);
|
||||||
const char *comm__str(const struct comm *comm);
|
const char *comm__str(const struct comm *comm);
|
||||||
int comm__override(struct comm *comm, const char *str, u64 timestamp);
|
int comm__override(struct comm *comm, const char *str, u64 timestamp,
|
||||||
|
bool exec);
|
||||||
|
|
||||||
#endif /* __PERF_COMM_H */
|
#endif /* __PERF_COMM_H */
|
||||||
|
@ -404,11 +404,13 @@ int machine__process_comm_event(struct machine *machine, union perf_event *event
|
|||||||
struct thread *thread = machine__findnew_thread(machine,
|
struct thread *thread = machine__findnew_thread(machine,
|
||||||
event->comm.pid,
|
event->comm.pid,
|
||||||
event->comm.tid);
|
event->comm.tid);
|
||||||
|
bool exec = event->header.misc & PERF_RECORD_MISC_COMM_EXEC;
|
||||||
|
|
||||||
if (dump_trace)
|
if (dump_trace)
|
||||||
perf_event__fprintf_comm(event, stdout);
|
perf_event__fprintf_comm(event, stdout);
|
||||||
|
|
||||||
if (thread == NULL || thread__set_comm(thread, event->comm.comm, sample->time)) {
|
if (thread == NULL ||
|
||||||
|
__thread__set_comm(thread, event->comm.comm, sample->time, exec)) {
|
||||||
dump_printf("problem processing PERF_RECORD_COMM, skipping event.\n");
|
dump_printf("problem processing PERF_RECORD_COMM, skipping event.\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -42,7 +42,7 @@ struct thread *thread__new(pid_t pid, pid_t tid)
|
|||||||
goto err_thread;
|
goto err_thread;
|
||||||
|
|
||||||
snprintf(comm_str, 32, ":%d", tid);
|
snprintf(comm_str, 32, ":%d", tid);
|
||||||
comm = comm__new(comm_str, 0);
|
comm = comm__new(comm_str, 0, false);
|
||||||
free(comm_str);
|
free(comm_str);
|
||||||
if (!comm)
|
if (!comm)
|
||||||
goto err_thread;
|
goto err_thread;
|
||||||
@ -81,19 +81,33 @@ struct comm *thread__comm(const struct thread *thread)
|
|||||||
return list_first_entry(&thread->comm_list, struct comm, list);
|
return list_first_entry(&thread->comm_list, struct comm, list);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct comm *thread__exec_comm(const struct thread *thread)
|
||||||
|
{
|
||||||
|
struct comm *comm, *last = NULL;
|
||||||
|
|
||||||
|
list_for_each_entry(comm, &thread->comm_list, list) {
|
||||||
|
if (comm->exec)
|
||||||
|
return comm;
|
||||||
|
last = comm;
|
||||||
|
}
|
||||||
|
|
||||||
|
return last;
|
||||||
|
}
|
||||||
|
|
||||||
/* CHECKME: time should always be 0 if event aren't ordered */
|
/* CHECKME: time should always be 0 if event aren't ordered */
|
||||||
int thread__set_comm(struct thread *thread, const char *str, u64 timestamp)
|
int __thread__set_comm(struct thread *thread, const char *str, u64 timestamp,
|
||||||
|
bool exec)
|
||||||
{
|
{
|
||||||
struct comm *new, *curr = thread__comm(thread);
|
struct comm *new, *curr = thread__comm(thread);
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
/* Override latest entry if it had no specific time coverage */
|
/* Override latest entry if it had no specific time coverage */
|
||||||
if (!curr->start) {
|
if (!curr->start && !curr->exec) {
|
||||||
err = comm__override(curr, str, timestamp);
|
err = comm__override(curr, str, timestamp, exec);
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
} else {
|
} else {
|
||||||
new = comm__new(str, timestamp);
|
new = comm__new(str, timestamp, exec);
|
||||||
if (!new)
|
if (!new)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
list_add(&new->list, &thread->comm_list);
|
list_add(&new->list, &thread->comm_list);
|
||||||
|
@ -38,9 +38,17 @@ static inline void thread__exited(struct thread *thread)
|
|||||||
thread->dead = true;
|
thread->dead = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
int thread__set_comm(struct thread *thread, const char *comm, u64 timestamp);
|
int __thread__set_comm(struct thread *thread, const char *comm, u64 timestamp,
|
||||||
|
bool exec);
|
||||||
|
static inline int thread__set_comm(struct thread *thread, const char *comm,
|
||||||
|
u64 timestamp)
|
||||||
|
{
|
||||||
|
return __thread__set_comm(thread, comm, timestamp, false);
|
||||||
|
}
|
||||||
|
|
||||||
int thread__comm_len(struct thread *thread);
|
int thread__comm_len(struct thread *thread);
|
||||||
struct comm *thread__comm(const struct thread *thread);
|
struct comm *thread__comm(const struct thread *thread);
|
||||||
|
struct comm *thread__exec_comm(const struct thread *thread);
|
||||||
const char *thread__comm_str(const struct thread *thread);
|
const char *thread__comm_str(const struct thread *thread);
|
||||||
void thread__insert_map(struct thread *thread, struct map *map);
|
void thread__insert_map(struct thread *thread, struct map *map);
|
||||||
int thread__fork(struct thread *thread, struct thread *parent, u64 timestamp);
|
int thread__fork(struct thread *thread, struct thread *parent, u64 timestamp);
|
||||||
|
Loading…
Reference in New Issue
Block a user