summaryrefslogtreecommitdiff
path: root/tools
diff options
context:
space:
mode:
Diffstat (limited to 'tools')
-rw-r--r--tools/perf/Documentation/perf-report.txt15
-rw-r--r--tools/perf/builtin-report.c33
-rw-r--r--tools/perf/util/callchain.h6
-rw-r--r--tools/perf/util/hist.c3
-rw-r--r--tools/perf/util/session.c7
5 files changed, 53 insertions, 11 deletions
diff --git a/tools/perf/Documentation/perf-report.txt b/tools/perf/Documentation/perf-report.txt
index 8ba03d6e539..cfa8e513d0f 100644
--- a/tools/perf/Documentation/perf-report.txt
+++ b/tools/perf/Documentation/perf-report.txt
@@ -80,15 +80,24 @@ OPTIONS
--dump-raw-trace::
Dump raw trace in ASCII.
--g [type,min]::
+-g [type,min,order]::
--call-graph::
- Display call chains using type and min percent threshold.
+ Display call chains using type, min percent threshold and order.
type can be either:
- flat: single column, linear exposure of call chains.
- graph: use a graph tree, displaying absolute overhead rates.
- fractal: like graph, but displays relative rates. Each branch of
the tree is considered as a new profiled object. +
- Default: fractal,0.5.
+
+ order can be either:
+ - callee: callee based call graph.
+ - caller: inverted caller based call graph.
+
+ Default: fractal,0.5,callee.
+
+-G::
+--inverted::
+ alias for inverted caller based call graph.
--pretty=<key>::
Pretty printing style. key: normal, raw
diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c
index 287a173523a..271e252dc65 100644
--- a/tools/perf/builtin-report.c
+++ b/tools/perf/builtin-report.c
@@ -45,7 +45,8 @@ static struct perf_read_values show_threads_values;
static const char default_pretty_printing_style[] = "normal";
static const char *pretty_printing_style = default_pretty_printing_style;
-static char callchain_default_opt[] = "fractal,0.5";
+static char callchain_default_opt[] = "fractal,0.5,callee";
+static bool inverted_callchain;
static symbol_filter_t annotate_init;
static int perf_session__add_hist_entry(struct perf_session *session,
@@ -386,13 +387,29 @@ parse_callchain_opt(const struct option *opt __used, const char *arg,
if (!tok)
goto setup;
- tok2 = strtok(NULL, ",");
callchain_param.min_percent = strtod(tok, &endptr);
if (tok == endptr)
return -1;
- if (tok2)
+ /* get the print limit */
+ tok2 = strtok(NULL, ",");
+ if (!tok2)
+ goto setup;
+
+ if (tok2[0] != 'c') {
callchain_param.print_limit = strtod(tok2, &endptr);
+ tok2 = strtok(NULL, ",");
+ if (!tok2)
+ goto setup;
+ }
+
+ /* get the call chain order */
+ if (!strcmp(tok2, "caller"))
+ callchain_param.order = ORDER_CALLER;
+ else if (!strcmp(tok2, "callee"))
+ callchain_param.order = ORDER_CALLEE;
+ else
+ return -1;
setup:
if (callchain_register_param(&callchain_param) < 0) {
fprintf(stderr, "Can't register callchain params\n");
@@ -436,9 +453,10 @@ static const struct option options[] = {
"regex filter to identify parent, see: '--sort parent'"),
OPT_BOOLEAN('x', "exclude-other", &symbol_conf.exclude_other,
"Only display entries with parent-match"),
- OPT_CALLBACK_DEFAULT('g', "call-graph", NULL, "output_type,min_percent",
- "Display callchains using output_type (graph, flat, fractal, or none) and min percent threshold. "
- "Default: fractal,0.5", &parse_callchain_opt, callchain_default_opt),
+ OPT_CALLBACK_DEFAULT('g', "call-graph", NULL, "output_type,min_percent, call_order",
+ "Display callchains using output_type (graph, flat, fractal, or none) , min percent threshold and callchain order. "
+ "Default: fractal,0.5,callee", &parse_callchain_opt, callchain_default_opt),
+ OPT_BOOLEAN('G', "inverted", &inverted_callchain, "alias for inverted call graph"),
OPT_STRING('d', "dsos", &symbol_conf.dso_list_str, "dso[,dso...]",
"only consider symbols in these dsos"),
OPT_STRING('C', "comms", &symbol_conf.comm_list_str, "comm[,comm...]",
@@ -467,6 +485,9 @@ int cmd_report(int argc, const char **argv, const char *prefix __used)
else if (use_tui)
use_browser = 1;
+ if (inverted_callchain)
+ callchain_param.order = ORDER_CALLER;
+
if (strcmp(input_name, "-") != 0)
setup_browser(true);
else
diff --git a/tools/perf/util/callchain.h b/tools/perf/util/callchain.h
index 1a79df9f739..9b4ff16cac9 100644
--- a/tools/perf/util/callchain.h
+++ b/tools/perf/util/callchain.h
@@ -14,6 +14,11 @@ enum chain_mode {
CHAIN_GRAPH_REL
};
+enum chain_order {
+ ORDER_CALLER,
+ ORDER_CALLEE
+};
+
struct callchain_node {
struct callchain_node *parent;
struct list_head siblings;
@@ -41,6 +46,7 @@ struct callchain_param {
u32 print_limit;
double min_percent;
sort_chain_func_t sort;
+ enum chain_order order;
};
struct callchain_list {
diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c
index 627a02e03c5..dae4202fa65 100644
--- a/tools/perf/util/hist.c
+++ b/tools/perf/util/hist.c
@@ -14,7 +14,8 @@ enum hist_filter {
struct callchain_param callchain_param = {
.mode = CHAIN_GRAPH_REL,
- .min_percent = 0.5
+ .min_percent = 0.5,
+ .order = ORDER_CALLEE
};
u16 hists__col_len(struct hists *self, enum hist_column col)
diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c
index b723f211881..558bcf99694 100644
--- a/tools/perf/util/session.c
+++ b/tools/perf/util/session.c
@@ -247,9 +247,14 @@ int perf_session__resolve_callchain(struct perf_session *self,
callchain_cursor_reset(&self->callchain_cursor);
for (i = 0; i < chain->nr; i++) {
- u64 ip = chain->ips[i];
+ u64 ip;
struct addr_location al;
+ if (callchain_param.order == ORDER_CALLEE)
+ ip = chain->ips[i];
+ else
+ ip = chain->ips[chain->nr - i - 1];
+
if (ip >= PERF_CONTEXT_MAX) {
switch (ip) {
case PERF_CONTEXT_HV: