Commit 0d71a2b2 authored by Jiri Olsa's avatar Jiri Olsa Committed by Arnaldo Carvalho de Melo

perf callchain: Setup callchain properly in pipe mode

Callchains are automatically initialized by checking on event's
sample_type. For pipe mode we need to put this check into attr event
code.

Moving the callchains setup code into callchain_param_setup function and
calling it from attr event process code.

This enables pipe output having callchains, like:

  # perf record -g -e 'raw_syscalls:sys_enter' true | perf script
  # perf record -g -e 'raw_syscalls:sys_enter' true | perf report

Committer notes:

We still need the next patch for the above output to work.
Reported-by: default avatarPaul Khuong <pvk@pvk.ca>
Signed-off-by: default avatarJiri Olsa <jolsa@kernel.org>
Tested-by: default avatarArnaldo Carvalho de Melo <acme@redhat.com>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Ian Rogers <irogers@google.com>
Cc: Michael Petlan <mpetlan@redhat.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Link: http://lore.kernel.org/lkml/20200507095024.2789147-5-jolsa@kernel.orgSigned-off-by: default avatarArnaldo Carvalho de Melo <acme@redhat.com>
parent 14d3d540
......@@ -402,16 +402,7 @@ static int report__setup_sample_type(struct report *rep)
}
}
if (symbol_conf.use_callchain || symbol_conf.cumulate_callchain) {
if ((sample_type & PERF_SAMPLE_REGS_USER) &&
(sample_type & PERF_SAMPLE_STACK_USER)) {
callchain_param.record_mode = CALLCHAIN_DWARF;
dwarf_callchain_users = true;
} else if (sample_type & PERF_SAMPLE_BRANCH_STACK)
callchain_param.record_mode = CALLCHAIN_LBR;
else
callchain_param.record_mode = CALLCHAIN_FP;
}
callchain_param_setup(sample_type);
if (rep->stitch_lbr && (callchain_param.record_mode != CALLCHAIN_LBR)) {
ui__warning("Can't find LBR callchain. Switch off --stitch-lbr.\n"
......@@ -1089,6 +1080,26 @@ parse_percent_limit(const struct option *opt, const char *str,
return 0;
}
static int process_attr(struct perf_tool *tool __maybe_unused,
union perf_event *event,
struct evlist **pevlist)
{
u64 sample_type;
int err;
err = perf_event__process_attr(tool, event, pevlist);
if (err)
return err;
/*
* Check if we need to enable callchains based
* on events sample_type.
*/
sample_type = perf_evlist__combined_sample_type(*pevlist);
callchain_param_setup(sample_type);
return 0;
}
int cmd_report(int argc, const char **argv)
{
struct perf_session *session;
......@@ -1119,7 +1130,7 @@ int cmd_report(int argc, const char **argv)
.fork = perf_event__process_fork,
.lost = perf_event__process_lost,
.read = process_read_event,
.attr = perf_event__process_attr,
.attr = process_attr,
.tracing_data = perf_event__process_tracing_data,
.build_id = perf_event__process_build_id,
.id_index = perf_event__process_id_index,
......
......@@ -2085,6 +2085,7 @@ static int process_attr(struct perf_tool *tool, union perf_event *event,
struct perf_script *scr = container_of(tool, struct perf_script, tool);
struct evlist *evlist;
struct evsel *evsel, *pos;
u64 sample_type;
int err;
static struct evsel_script *es;
......@@ -2119,10 +2120,19 @@ static int process_attr(struct perf_tool *tool, union perf_event *event,
set_print_ip_opts(&evsel->core.attr);
if (evsel->core.attr.sample_type)
if (evsel->core.attr.sample_type) {
err = perf_evsel__check_attr(evsel, scr->session);
if (err)
return err;
}
return err;
/*
* Check if we need to enable callchains based
* on events sample_type.
*/
sample_type = perf_evlist__combined_sample_type(evlist);
callchain_param_setup(sample_type);
return 0;
}
static int print_event_with_time(struct perf_tool *tool,
......
......@@ -1599,3 +1599,17 @@ void callchain_cursor_reset(struct callchain_cursor *cursor)
for (node = cursor->first; node != NULL; node = node->next)
map__zput(node->ms.map);
}
void callchain_param_setup(u64 sample_type)
{
if (symbol_conf.use_callchain || symbol_conf.cumulate_callchain) {
if ((sample_type & PERF_SAMPLE_REGS_USER) &&
(sample_type & PERF_SAMPLE_STACK_USER)) {
callchain_param.record_mode = CALLCHAIN_DWARF;
dwarf_callchain_users = true;
} else if (sample_type & PERF_SAMPLE_BRANCH_STACK)
callchain_param.record_mode = CALLCHAIN_LBR;
else
callchain_param.record_mode = CALLCHAIN_FP;
}
}
......@@ -297,4 +297,5 @@ int callchain_branch_counts(struct callchain_root *root,
u64 *branch_count, u64 *predicted_count,
u64 *abort_count, u64 *cycles_count);
void callchain_param_setup(u64 sample_type);
#endif /* __PERF_CALLCHAIN_H */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment