Em Mon, Jul 14, 2014 at 01:02:26PM +0300, Adrian Hunter escreveu: > Events like sched_switch do not provide a pid (tgid) > which can result in threads with an unknown pid. If > the pid is later discovered, join the map groups. > Note the thread's map groups should be empty because > they are populated by MMAP events which do provide the > pid and tid. > > Signed-off-by: Adrian Hunter <adrian.hun...@intel.com> > --- > tools/perf/util/machine.c | 22 ++++++++++++++++------ > tools/perf/util/map.c | 14 ++++++++++++++ > tools/perf/util/map.h | 1 + > tools/perf/util/thread.c | 35 +++++++++++++++++++++++++++++++++++ > tools/perf/util/thread.h | 1 + > 5 files changed, 67 insertions(+), 6 deletions(-) > > diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c > index 5b80877..0fa93c1 100644 > --- a/tools/perf/util/machine.c > +++ b/tools/perf/util/machine.c > @@ -272,6 +272,17 @@ void machines__set_id_hdr_size(struct machines > *machines, u16 id_hdr_size) > return; > } > > +static void machine__update_thread_pid(struct machine *machine, > + struct thread *th, pid_t pid) > +{ > + if (pid != th->pid_ && pid != -1 && th->pid_ == -1) { > + th->pid_ = pid; > + if (thread__join_map_groups(th, machine)) > + pr_err("Failed to join map groups for %d:%d\n", > + th->pid_, th->tid); > + } > +} > +
I think you should combine the above function with thread__join_map_groups, and I think that the method belongs to the 'machine' class, see below for further comments on this... > static struct thread *__machine__findnew_thread(struct machine *machine, > pid_t pid, pid_t tid, > bool create) > @@ -285,10 +296,10 @@ static struct thread *__machine__findnew_thread(struct > machine *machine, > * so most of the time we dont have to look up > * the full rbtree: > */ > - if (machine->last_match && machine->last_match->tid == tid) { > - if (pid != -1 && pid != machine->last_match->pid_) > - machine->last_match->pid_ = pid; > - return machine->last_match; > + th = machine->last_match; > + if (th && th->tid == tid) { > + machine__update_thread_pid(machine, th, pid); > + return th; > } > > while (*p != NULL) { > @@ -297,8 +308,7 @@ static struct thread *__machine__findnew_thread(struct > machine *machine, > > if (th->tid == tid) { > machine->last_match = th; > - if (pid != -1 && pid != th->pid_) > - th->pid_ = pid; > + machine__update_thread_pid(machine, th, pid); > return th; > } > > diff --git a/tools/perf/util/map.c b/tools/perf/util/map.c > index 25c571f..7af1480 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) > } > } > > +bool map_groups__empty(struct map_groups *mg) > +{ > + int i; > + > + for (i = 0; i < MAP__NR_TYPES; ++i) { > + if (maps__first(&mg->maps[i])) > + return false; > + if (!list_empty(&mg->removed_maps[i])) > + return false; > + } > + > + return true; > +} > + > struct map_groups *map_groups__new(void) > { > struct map_groups *mg = malloc(sizeof(*mg)); > diff --git a/tools/perf/util/map.h b/tools/perf/util/map.h > index 7758c72..5806a90 100644 > --- a/tools/perf/util/map.h > +++ b/tools/perf/util/map.h > @@ -66,6 +66,7 @@ struct map_groups { > > struct map_groups *map_groups__new(void); > void map_groups__delete(struct map_groups *mg); > +bool map_groups__empty(struct map_groups *mg); > > static inline struct map_groups *map_groups__get(struct map_groups *mg) > { > diff --git a/tools/perf/util/thread.c b/tools/perf/util/thread.c > index 7a32f44..ca94295 100644 > --- a/tools/perf/util/thread.c > +++ b/tools/perf/util/thread.c > @@ -24,6 +24,41 @@ int thread__init_map_groups(struct thread *thread, struct > machine *machine) > return thread->mg ? 0 : -1; > } > > +int thread__join_map_groups(struct thread *thread, struct machine *machine) > +{ > + struct thread *leader; > + pid_t pid = thread->pid_; > + > + if (pid == thread->tid) > + return 0; > + > + leader = machine__findnew_thread(machine, pid, pid); > + if (!leader) > + return -ENOMEM; > + > + if (!leader->mg) > + leader->mg = map_groups__new(); > + > + if (!leader->mg) > + return -ENOMEM; > + > + if (thread->mg) { > + /* > + * Maps are created from MMAP events which provide the pid and > + * tid. Consequently there never should be any maps on a thread > + * with an unknown pid. Just print an error if there are. > + */ > + if (!map_groups__empty(thread->mg)) > + pr_err("Discarding thread maps for %d:%d\n", > + thread->pid_, thread->tid); Because there is nothing in this function (thread__join_map_groups), checking if it is operating on a thread that has an unknown pid. So, please consider merging this and its sole caller, machine__update_thread_pid, so that the test is in the same function as the assumption that it is operating on a thread with an unknown pid. Continuing to look at the other patches... > + map_groups__delete(thread->mg); > + } > + > + thread->mg = map_groups__get(leader->mg); > + > + return 0; > +} > + > struct thread *thread__new(pid_t pid, pid_t tid) > { > char *comm_str; > diff --git a/tools/perf/util/thread.h b/tools/perf/util/thread.h > index 3c0c272..9de0629 100644 > --- a/tools/perf/util/thread.h > +++ b/tools/perf/util/thread.h > @@ -31,6 +31,7 @@ struct comm; > > struct thread *thread__new(pid_t pid, pid_t tid); > int thread__init_map_groups(struct thread *thread, struct machine *machine); > +int thread__join_map_groups(struct thread *thread, struct machine *machine); > void thread__delete(struct thread *thread); > static inline void thread__exited(struct thread *thread) > { > -- > 1.8.3.2 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/