Sharing map groups within all process threads. This way there's only one copy of mmap info and it's reachale from any thread within the process.
Signed-off-by: Jiri Olsa <jo...@redhat.com> Cc: Don Zickus <dzic...@redhat.com> Cc: Corey Ashford <cjash...@linux.vnet.ibm.com> Cc: David Ahern <dsah...@gmail.com> Cc: Frederic Weisbecker <fweis...@gmail.com> Cc: Ingo Molnar <mi...@kernel.org> Cc: Namhyung Kim <namhy...@kernel.org> Cc: Paul Mackerras <pau...@samba.org> Cc: Peter Zijlstra <a.p.zijls...@chello.nl> Cc: Arnaldo Carvalho de Melo <a...@ghostprotocols.net> --- tools/perf/util/map.h | 2 ++ tools/perf/util/thread.c | 37 ++++++++++++++++++++++++++++++++++--- 2 files changed, 36 insertions(+), 3 deletions(-) diff --git a/tools/perf/util/map.h b/tools/perf/util/map.h index 99a6488..d4c8df2 100644 --- a/tools/perf/util/map.h +++ b/tools/perf/util/map.h @@ -59,6 +59,8 @@ struct map_groups { struct rb_root maps[MAP__NR_TYPES]; struct list_head removed_maps[MAP__NR_TYPES]; struct machine *machine; + /* Used for thread sharing */ + int refcnt; }; static inline struct kmap *map__kmap(struct map *map) diff --git a/tools/perf/util/thread.c b/tools/perf/util/thread.c index 7c1aad0..2599754 100644 --- a/tools/perf/util/thread.c +++ b/tools/perf/util/thread.c @@ -156,6 +156,16 @@ int thread__fork(struct thread *thread, struct thread *parent, u64 timestamp) return 0; } +static struct thread* thread__get_leader(struct thread *thread) +{ + pid_t pid = thread->pid_; + + if (pid == thread->tid) + return thread; + + return machine__findnew_thread(thread->machine, pid, pid); +} + static struct map_groups* thread__map_groups_alloc(struct thread *thread) { struct map_groups* mg = zalloc(sizeof(*mg)); @@ -172,13 +182,34 @@ struct map_groups* thread__map_groups_get(struct thread *thread) { struct map_groups* mg = thread->mg; - if (!mg) - mg = thread__map_groups_alloc(thread); + if (!mg) { + struct thread *leader = thread__get_leader(thread); + + if (!leader) + return NULL; + + if (leader->mg) + mg = leader->mg; + else + mg = thread__map_groups_alloc(leader); + + if (leader != thread) + thread->mg = mg; + + mg->refcnt++; + } return mg; } void thread__map_groups_put(struct thread *thread) { - zfree(&thread->mg); + struct map_groups* mg = thread->mg; + + if (mg) { + BUG_ON(!mg->refcnt); + + if (!--mg->refcnt) + zfree(&thread->mg); + } } -- 1.8.3.1 -- 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/