aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf
diff options
context:
space:
mode:
authorChris Phlipot <cphlipot0@gmail.com>2016-04-28 04:19:08 -0400
committerArnaldo Carvalho de Melo <acme@redhat.com>2016-05-06 12:00:52 -0400
commit0a3eba3ad613fa9d5af754f7ae8c4b46047cb2a7 (patch)
treee561633b72418e54b68c5d0e00816538d9e88a93 /tools/perf
parent451db12617bc6ff1bb8ed456ed4f257594134255 (diff)
perf script: Enable db export to output sampled callchains
This change enables the db export api to export callchains. This is accomplished by adding callchains obtained from samples to the call_path_root structure and exporting them via the current call path export API. While the current API does support exporting call paths, this is not supported when sampling. This commit addresses that missing feature by allowing the export of call paths when callchains are present in samples. Summary: - This feature is activated by initializing the call_path_root member inside the db_export structure to a non-null value. - Callchains are resolved with thread__resolve_callchain() and then stored and exported by adding a call path under call path root. - Symbol and DSO for each callchain node are exported via db_ids_from_al() This commit puts in place infrastructure to be used by subsequent commits, and by itself, does not introduce any user-visible changes. Signed-off-by: Chris Phlipot <cphlipot0@gmail.com> Acked-by: Adrian Hunter <adrian.hunter@intel.com> Cc: Jiri Olsa <jolsa@kernel.org> Cc: Peter Zijlstra <peterz@infradead.org> Link: http://lkml.kernel.org/r/1461831551-12213-4-git-send-email-cphlipot0@gmail.com [ Made adjustments suggested by Adrian Hunter, see thread via this cset's Link: tag ] Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Diffstat (limited to 'tools/perf')
-rw-r--r--tools/perf/util/db-export.c82
-rw-r--r--tools/perf/util/db-export.h2
2 files changed, 84 insertions, 0 deletions
diff --git a/tools/perf/util/db-export.c b/tools/perf/util/db-export.c
index 4fc607c130b8..a0ca90c1fb50 100644
--- a/tools/perf/util/db-export.c
+++ b/tools/perf/util/db-export.c
@@ -23,6 +23,7 @@
23#include "event.h" 23#include "event.h"
24#include "util.h" 24#include "util.h"
25#include "thread-stack.h" 25#include "thread-stack.h"
26#include "callchain.h"
26#include "call-path.h" 27#include "call-path.h"
27#include "db-export.h" 28#include "db-export.h"
28 29
@@ -277,6 +278,79 @@ static int db_ids_from_al(struct db_export *dbe, struct addr_location *al,
277 return 0; 278 return 0;
278} 279}
279 280
281static struct call_path *call_path_from_sample(struct db_export *dbe,
282 struct machine *machine,
283 struct thread *thread,
284 struct perf_sample *sample,
285 struct perf_evsel *evsel)
286{
287 u64 kernel_start = machine__kernel_start(machine);
288 struct call_path *current = &dbe->cpr->call_path;
289 enum chain_order saved_order = callchain_param.order;
290 int err;
291
292 if (!symbol_conf.use_callchain || !sample->callchain)
293 return NULL;
294
295 /*
296 * Since the call path tree must be built starting with the root, we
297 * must use ORDER_CALL for call chain resolution, in order to process
298 * the callchain starting with the root node and ending with the leaf.
299 */
300 callchain_param.order = ORDER_CALLER;
301 err = thread__resolve_callchain(thread, &callchain_cursor, evsel,
302 sample, NULL, NULL,
303 sysctl_perf_event_max_stack);
304 if (err) {
305 callchain_param.order = saved_order;
306 return NULL;
307 }
308 callchain_cursor_commit(&callchain_cursor);
309
310 while (1) {
311 struct callchain_cursor_node *node;
312 struct addr_location al;
313 u64 dso_db_id = 0, sym_db_id = 0, offset = 0;
314
315 memset(&al, 0, sizeof(al));
316
317 node = callchain_cursor_current(&callchain_cursor);
318 if (!node)
319 break;
320 /*
321 * Handle export of symbol and dso for this node by
322 * constructing an addr_location struct and then passing it to
323 * db_ids_from_al() to perform the export.
324 */
325 al.sym = node->sym;
326 al.map = node->map;
327 al.machine = machine;
328 if (al.map)
329 al.addr = al.map->map_ip(al.map, node->ip);
330 else
331 al.addr = node->ip;
332
333 db_ids_from_al(dbe, &al, &dso_db_id, &sym_db_id, &offset);
334
335 /* add node to the call path tree if it doesn't exist */
336 current = call_path__findnew(dbe->cpr, current,
337 al.sym, node->ip,
338 kernel_start);
339
340 callchain_cursor_advance(&callchain_cursor);
341 }
342
343 /* Reset the callchain order to its prior value. */
344 callchain_param.order = saved_order;
345
346 if (current == &dbe->cpr->call_path) {
347 /* Bail because the callchain was empty. */
348 return NULL;
349 }
350
351 return current;
352}
353
280int db_export__branch_type(struct db_export *dbe, u32 branch_type, 354int db_export__branch_type(struct db_export *dbe, u32 branch_type,
281 const char *name) 355 const char *name)
282{ 356{
@@ -330,6 +404,14 @@ int db_export__sample(struct db_export *dbe, union perf_event *event,
330 if (err) 404 if (err)
331 goto out_put; 405 goto out_put;
332 406
407 if (dbe->cpr) {
408 struct call_path *cp = call_path_from_sample(dbe, al->machine,
409 thread, sample,
410 evsel);
411 if (cp)
412 db_export__call_path(dbe, cp);
413 }
414
333 if ((evsel->attr.sample_type & PERF_SAMPLE_ADDR) && 415 if ((evsel->attr.sample_type & PERF_SAMPLE_ADDR) &&
334 sample_addr_correlates_sym(&evsel->attr)) { 416 sample_addr_correlates_sym(&evsel->attr)) {
335 struct addr_location addr_al; 417 struct addr_location addr_al;
diff --git a/tools/perf/util/db-export.h b/tools/perf/util/db-export.h
index 25e22fd76aca..f5daf552054c 100644
--- a/tools/perf/util/db-export.h
+++ b/tools/perf/util/db-export.h
@@ -27,6 +27,7 @@ struct dso;
27struct perf_sample; 27struct perf_sample;
28struct addr_location; 28struct addr_location;
29struct call_return_processor; 29struct call_return_processor;
30struct call_path_root;
30struct call_path; 31struct call_path;
31struct call_return; 32struct call_return;
32 33
@@ -64,6 +65,7 @@ struct db_export {
64 int (*export_call_return)(struct db_export *dbe, 65 int (*export_call_return)(struct db_export *dbe,
65 struct call_return *cr); 66 struct call_return *cr);
66 struct call_return_processor *crp; 67 struct call_return_processor *crp;
68 struct call_path_root *cpr;
67 u64 evsel_last_db_id; 69 u64 evsel_last_db_id;
68 u64 machine_last_db_id; 70 u64 machine_last_db_id;
69 u64 thread_last_db_id; 71 u64 thread_last_db_id;