aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf
diff options
context:
space:
mode:
authorJiri Olsa <jolsa@kernel.org>2014-04-09 14:54:29 -0400
committerJiri Olsa <jolsa@kernel.org>2014-04-28 07:43:33 -0400
commitcddcef607782966f1601808c17fe9c4c5f79f9f4 (patch)
tree651244dff025c51f8583c29d984ffd3dce63f5ab /tools/perf
parenta26ca6716a6c683f40bd676cea7e89704653b98d (diff)
perf tools: Share map_groups among threads of the same group
Sharing map groups within all process threads. This way there's only one copy of mmap info and it's reachable from any thread within the process. Original-patch-by: Arnaldo Carvalho de Melo <acme@kernel.org> Acked-by: Namhyung Kim <namhyung@kernel.org> Cc: Adrian Hunter <adrian.hunter@intel.com> Cc: Corey Ashford <cjashfor@linux.vnet.ibm.com> Cc: David Ahern <dsahern@gmail.com> Cc: Don Zickus <dzickus@redhat.com> Cc: Frederic Weisbecker <fweisbec@gmail.com> Cc: Ingo Molnar <mingo@kernel.org> Cc: Mike Galbraith <efault@gmx.de> Cc: Namhyung Kim <namhyung@kernel.org> Cc: Paul Mackerras <paulus@samba.org> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Cc: Stephane Eranian <eranian@google.com> Link: http://lkml.kernel.org/r/1397490723-1992-5-git-send-email-jolsa@redhat.com Signed-off-by: Jiri Olsa <jolsa@kernel.org>
Diffstat (limited to 'tools/perf')
-rw-r--r--tools/perf/util/machine.c11
-rw-r--r--tools/perf/util/thread.c48
-rw-r--r--tools/perf/util/thread.h1
3 files changed, 47 insertions, 13 deletions
diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c
index a53cd0b8c151..98ec56dc890b 100644
--- a/tools/perf/util/machine.c
+++ b/tools/perf/util/machine.c
@@ -316,6 +316,17 @@ static struct thread *__machine__findnew_thread(struct machine *machine,
316 rb_link_node(&th->rb_node, parent, p); 316 rb_link_node(&th->rb_node, parent, p);
317 rb_insert_color(&th->rb_node, &machine->threads); 317 rb_insert_color(&th->rb_node, &machine->threads);
318 machine->last_match = th; 318 machine->last_match = th;
319
320 /*
321 * We have to initialize map_groups separately
322 * after rb tree is updated.
323 *
324 * The reason is that we call machine__findnew_thread
325 * within thread__init_map_groups to find the thread
326 * leader and that would screwed the rb tree.
327 */
328 if (thread__init_map_groups(th, machine))
329 return NULL;
319 } 330 }
320 331
321 return th; 332 return th;
diff --git a/tools/perf/util/thread.c b/tools/perf/util/thread.c
index b501848a8424..2fde0d5e40b5 100644
--- a/tools/perf/util/thread.c
+++ b/tools/perf/util/thread.c
@@ -8,6 +8,22 @@
8#include "debug.h" 8#include "debug.h"
9#include "comm.h" 9#include "comm.h"
10 10
11int thread__init_map_groups(struct thread *thread, struct machine *machine)
12{
13 struct thread *leader;
14 pid_t pid = thread->pid_;
15
16 if (pid == thread->tid) {
17 thread->mg = map_groups__new();
18 } else {
19 leader = machine__findnew_thread(machine, pid, pid);
20 if (leader)
21 thread->mg = map_groups__get(leader->mg);
22 }
23
24 return thread->mg ? 0 : -1;
25}
26
11struct thread *thread__new(pid_t pid, pid_t tid) 27struct thread *thread__new(pid_t pid, pid_t tid)
12{ 28{
13 char *comm_str; 29 char *comm_str;
@@ -15,10 +31,6 @@ struct thread *thread__new(pid_t pid, pid_t tid)
15 struct thread *thread = zalloc(sizeof(*thread)); 31 struct thread *thread = zalloc(sizeof(*thread));
16 32
17 if (thread != NULL) { 33 if (thread != NULL) {
18 thread->mg = map_groups__new();
19 if (thread->mg == NULL)
20 goto out_free;
21
22 thread->pid_ = pid; 34 thread->pid_ = pid;
23 thread->tid = tid; 35 thread->tid = tid;
24 thread->ppid = -1; 36 thread->ppid = -1;
@@ -40,8 +52,6 @@ struct thread *thread__new(pid_t pid, pid_t tid)
40 return thread; 52 return thread;
41 53
42err_thread: 54err_thread:
43 map_groups__delete(thread->mg);
44out_free:
45 free(thread); 55 free(thread);
46 return NULL; 56 return NULL;
47} 57}
@@ -126,9 +136,26 @@ void thread__insert_map(struct thread *thread, struct map *map)
126 map_groups__insert(thread->mg, map); 136 map_groups__insert(thread->mg, map);
127} 137}
128 138
139static int thread__clone_map_groups(struct thread *thread,
140 struct thread *parent)
141{
142 int i;
143
144 /* This is new thread, we share map groups for process. */
145 if (thread->pid_ == parent->pid_)
146 return 0;
147
148 /* But this one is new process, copy maps. */
149 for (i = 0; i < MAP__NR_TYPES; ++i)
150 if (map_groups__clone(thread->mg, parent->mg, i) < 0)
151 return -ENOMEM;
152
153 return 0;
154}
155
129int thread__fork(struct thread *thread, struct thread *parent, u64 timestamp) 156int thread__fork(struct thread *thread, struct thread *parent, u64 timestamp)
130{ 157{
131 int i, err; 158 int err;
132 159
133 if (parent->comm_set) { 160 if (parent->comm_set) {
134 const char *comm = thread__comm_str(parent); 161 const char *comm = thread__comm_str(parent);
@@ -140,13 +167,8 @@ int thread__fork(struct thread *thread, struct thread *parent, u64 timestamp)
140 thread->comm_set = true; 167 thread->comm_set = true;
141 } 168 }
142 169
143 for (i = 0; i < MAP__NR_TYPES; ++i)
144 if (map_groups__clone(thread->mg, parent->mg, i) < 0)
145 return -ENOMEM;
146
147 thread->ppid = parent->tid; 170 thread->ppid = parent->tid;
148 171 return thread__clone_map_groups(thread, parent);
149 return 0;
150} 172}
151 173
152void thread__find_cpumode_addr_location(struct thread *thread, 174void thread__find_cpumode_addr_location(struct thread *thread,
diff --git a/tools/perf/util/thread.h b/tools/perf/util/thread.h
index bee1eb0f73bc..3c0c2724f82c 100644
--- a/tools/perf/util/thread.h
+++ b/tools/perf/util/thread.h
@@ -30,6 +30,7 @@ struct machine;
30struct comm; 30struct comm;
31 31
32struct thread *thread__new(pid_t pid, pid_t tid); 32struct thread *thread__new(pid_t pid, pid_t tid);
33int thread__init_map_groups(struct thread *thread, struct machine *machine);
33void thread__delete(struct thread *thread); 34void thread__delete(struct thread *thread);
34static inline void thread__exited(struct thread *thread) 35static inline void thread__exited(struct thread *thread)
35{ 36{