Skip to content

Commit

Permalink
perf tools: Identify which comms are from exec
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Adrian Hunter authored and Arnaldo Carvalho de Melo committed Aug 13, 2014
1 parent a5563ed commit 65de51f
Show file tree
Hide file tree
Showing 5 changed files with 40 additions and 11 deletions.
7 changes: 5 additions & 2 deletions tools/perf/util/comm.c
Original file line number Diff line number Diff line change
Expand Up @@ -74,14 +74,15 @@ static struct comm_str *comm_str__findnew(const char *str, struct rb_root *root)
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));

if (!comm)
return NULL;

comm->start = timestamp;
comm->exec = exec;

comm->comm_str = comm_str__findnew(str, &comm_str_root);
if (!comm->comm_str) {
Expand All @@ -94,7 +95,7 @@ struct comm *comm__new(const char *str, u64 timestamp)
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;

Expand All @@ -106,6 +107,8 @@ int comm__override(struct comm *comm, const char *str, u64 timestamp)
comm_str__put(old);
comm->comm_str = new;
comm->start = timestamp;
if (exec)
comm->exec = true;

return 0;
}
Expand Down
6 changes: 4 additions & 2 deletions tools/perf/util/comm.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,13 @@ struct comm {
struct comm_str *comm_str;
u64 start;
struct list_head list;
bool exec;
};

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);
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 */
4 changes: 3 additions & 1 deletion tools/perf/util/machine.c
Original file line number Diff line number Diff line change
Expand Up @@ -404,11 +404,13 @@ int machine__process_comm_event(struct machine *machine, union perf_event *event
struct thread *thread = machine__findnew_thread(machine,
event->comm.pid,
event->comm.tid);
bool exec = event->header.misc & PERF_RECORD_MISC_COMM_EXEC;

if (dump_trace)
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");
return -1;
}
Expand Down
24 changes: 19 additions & 5 deletions tools/perf/util/thread.c
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ struct thread *thread__new(pid_t pid, pid_t tid)
goto err_thread;

snprintf(comm_str, 32, ":%d", tid);
comm = comm__new(comm_str, 0);
comm = comm__new(comm_str, 0, false);
free(comm_str);
if (!comm)
goto err_thread;
Expand Down Expand Up @@ -81,19 +81,33 @@ struct comm *thread__comm(const struct thread *thread)
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 */
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);
int err;

/* Override latest entry if it had no specific time coverage */
if (!curr->start) {
err = comm__override(curr, str, timestamp);
if (!curr->start && !curr->exec) {
err = comm__override(curr, str, timestamp, exec);
if (err)
return err;
} else {
new = comm__new(str, timestamp);
new = comm__new(str, timestamp, exec);
if (!new)
return -ENOMEM;
list_add(&new->list, &thread->comm_list);
Expand Down
10 changes: 9 additions & 1 deletion tools/perf/util/thread.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,17 @@ static inline void thread__exited(struct thread *thread)
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);
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);
void thread__insert_map(struct thread *thread, struct map *map);
int thread__fork(struct thread *thread, struct thread *parent, u64 timestamp);
Expand Down

0 comments on commit 65de51f

Please sign in to comment.