aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/util/session.c
diff options
context:
space:
mode:
authorFrederic Weisbecker <fweisbec@gmail.com>2011-01-13 22:51:58 -0500
committerArnaldo Carvalho de Melo <acme@redhat.com>2011-01-22 16:56:31 -0500
commit1b3a0e9592ebf174af934b3908a2bf6a6fa86169 (patch)
tree22de930ec03920ea7a4d602d9a582f5125595916 /tools/perf/util/session.c
parentde5fa3a8a05cd60f59622e88cfeb90416760d78e (diff)
perf callchain: Feed callchains into a cursor
The callchains are fed with an array of a fixed size. As a result we iterate over each callchains three times: - 1st to resolve symbols - 2nd to filter out context boundaries - 3rd for the insertion into the tree This also involves some pairs of memory allocation/deallocation everytime we insert a callchain, for the filtered out array of addresses and for the array of symbols that comes along. Instead, feed the callchains through a linked list with persistent allocations. It brings several pros like: - Merge the 1st and 2nd iterations in one. That was possible before but in a way that would involve allocating an array slightly taller than necessary because we don't know in advance the number of context boundaries to filter out. - Much lesser allocations/deallocations. The linked list keeps persistent empty entries for the next usages and is extendable at will. - Makes it easier for multiple sources of callchains to feed a stacktrace together. This is deemed to pave the way for cfi based callchains wherein traditional frame pointer based kernel stacktraces will precede cfi based user ones, producing an overall callchain which size is hardly predictable. This requirement makes the static array obsolete and makes a linked list based iterator a much more flexible fit. Basic testing on a big perf file containing callchains (~ 176 MB) has shown a throughput gain of about 11% with perf report. Cc: Ingo Molnar <mingo@elte.hu> Cc: Paul Mackerras <paulus@samba.org> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> LKML-Reference: <1294977121-5700-2-git-send-email-fweisbec@gmail.com> Signed-off-by: Frederic Weisbecker <fweisbec@gmail.com> Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Diffstat (limited to 'tools/perf/util/session.c')
-rw-r--r--tools/perf/util/session.c22
1 files changed, 12 insertions, 10 deletions
diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c
index 105f00bfd555..b58a48a5e5a9 100644
--- a/tools/perf/util/session.c
+++ b/tools/perf/util/session.c
@@ -242,17 +242,16 @@ static bool symbol__match_parent_regex(struct symbol *sym)
242 return 0; 242 return 0;
243} 243}
244 244
245struct map_symbol *perf_session__resolve_callchain(struct perf_session *self, 245int perf_session__resolve_callchain(struct perf_session *self,
246 struct thread *thread, 246 struct thread *thread,
247 struct ip_callchain *chain, 247 struct ip_callchain *chain,
248 struct symbol **parent) 248 struct symbol **parent)
249{ 249{
250 u8 cpumode = PERF_RECORD_MISC_USER; 250 u8 cpumode = PERF_RECORD_MISC_USER;
251 unsigned int i; 251 unsigned int i;
252 struct map_symbol *syms = calloc(chain->nr, sizeof(*syms)); 252 int err;
253 253
254 if (!syms) 254 callchain_cursor_reset(&self->callchain_cursor);
255 return NULL;
256 255
257 for (i = 0; i < chain->nr; i++) { 256 for (i = 0; i < chain->nr; i++) {
258 u64 ip = chain->ips[i]; 257 u64 ip = chain->ips[i];
@@ -281,12 +280,15 @@ struct map_symbol *perf_session__resolve_callchain(struct perf_session *self,
281 *parent = al.sym; 280 *parent = al.sym;
282 if (!symbol_conf.use_callchain) 281 if (!symbol_conf.use_callchain)
283 break; 282 break;
284 syms[i].map = al.map;
285 syms[i].sym = al.sym;
286 } 283 }
284
285 err = callchain_cursor_append(&self->callchain_cursor,
286 ip, al.map, al.sym);
287 if (err)
288 return err;
287 } 289 }
288 290
289 return syms; 291 return 0;
290} 292}
291 293
292static int process_event_synth_stub(event_t *event __used, 294static int process_event_synth_stub(event_t *event __used,