[PATCH 5/5] perf tools: Share process map groups within process threads

From: Jiri Olsa
Date: Fri Mar 14 2014 - 10:01:28 EST


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 <jolsa@xxxxxxxxxx>
Cc: Don Zickus <dzickus@xxxxxxxxxx>
Cc: Corey Ashford <cjashfor@xxxxxxxxxxxxxxxxxx>
Cc: David Ahern <dsahern@xxxxxxxxx>
Cc: Frederic Weisbecker <fweisbec@xxxxxxxxx>
Cc: Ingo Molnar <mingo@xxxxxxxxxx>
Cc: Namhyung Kim <namhyung@xxxxxxxxxx>
Cc: Paul Mackerras <paulus@xxxxxxxxx>
Cc: Peter Zijlstra <a.p.zijlstra@xxxxxxxxx>
Cc: Arnaldo Carvalho de Melo <acme@xxxxxxxxxxxxxxxxxx>
---
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 majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/