summaryrefslogtreecommitdiff
path: root/tools/perf/builtin-report.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/perf/builtin-report.c')
-rw-r--r--tools/perf/builtin-report.c57
1 files changed, 50 insertions, 7 deletions
diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c
index 287a173523a7..f854efda7686 100644
--- a/tools/perf/builtin-report.c
+++ b/tools/perf/builtin-report.c
@@ -33,6 +33,8 @@
#include "util/sort.h"
#include "util/hist.h"
+#include <linux/bitmap.h>
+
static char const *input_name = "perf.data";
static bool force, use_tui, use_stdio;
@@ -45,9 +47,13 @@ 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 const char *cpu_list;
+static DECLARE_BITMAP(cpu_bitmap, MAX_NR_CPUS);
+
static int perf_session__add_hist_entry(struct perf_session *session,
struct addr_location *al,
struct perf_sample *sample,
@@ -116,6 +122,9 @@ static int process_sample_event(union perf_event *event,
if (al.filtered || (hide_unresolved && al.sym == NULL))
return 0;
+ if (cpu_list && !test_bit(sample->cpu, cpu_bitmap))
+ return 0;
+
if (al.map != NULL)
al.map->dso->hit = 1;
@@ -262,6 +271,12 @@ static int __cmd_report(void)
if (session == NULL)
return -ENOMEM;
+ if (cpu_list) {
+ ret = perf_session__cpu_bitmap(session, cpu_list, cpu_bitmap);
+ if (ret)
+ goto out_delete;
+ }
+
if (show_threads)
perf_read_values_init(&show_threads_values);
@@ -386,13 +401,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 +467,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...]",
@@ -455,6 +487,7 @@ static const struct option options[] = {
"Only display entries resolved to a symbol"),
OPT_STRING(0, "symfs", &symbol_conf.symfs, "directory",
"Look for files with symbols relative to this directory"),
+ OPT_STRING('c', "cpu", &cpu_list, "cpu", "list of cpus to profile"),
OPT_END()
};
@@ -467,6 +500,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
@@ -504,7 +540,14 @@ int cmd_report(int argc, const char **argv, const char *prefix __used)
if (parent_pattern != default_parent_pattern) {
if (sort_dimension__add("parent") < 0)
return -1;
- sort_parent.elide = 1;
+
+ /*
+ * Only show the parent fields if we explicitly
+ * sort that way. If we only use parent machinery
+ * for filtering, we don't want it.
+ */
+ if (!strstr(sort_order, "parent"))
+ sort_parent.elide = 1;
} else
symbol_conf.exclude_other = false;