From 1ab1fa5dfb429c533fbc791e524788cf0cc43775 Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Thu, 26 Dec 2013 15:11:52 +0900 Subject: perf hists: Add support for showing relative percentage When filtering by thread, dso or symbol on TUI it also update total period so that the output shows different result than no filter - the percentage changed to relative to filtered entries only. Sometimes this is not desired since users might expect same results with filter. So new filtered_* fields to hists->stats to count them separately. They'll be controlled/used by user later. Signed-off-by: Namhyung Kim Link: http://lkml.kernel.org/r/1397145720-8063-2-git-send-email-namhyung@kernel.org Signed-off-by: Jiri Olsa --- tools/perf/builtin-report.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'tools/perf/builtin-report.c') diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c index c8f2113..2fca56c9 100644 --- a/tools/perf/builtin-report.c +++ b/tools/perf/builtin-report.c @@ -123,6 +123,8 @@ static int report__add_mem_hist_entry(struct report *rep, struct addr_location * evsel->hists.stats.total_period += cost; hists__inc_nr_events(&evsel->hists, PERF_RECORD_SAMPLE); + if (!he->filtered) + evsel->hists.stats.nr_non_filtered_samples++; err = hist_entry__append_callchain(he, sample); out: return err; @@ -176,6 +178,8 @@ static int report__add_branch_hist_entry(struct report *rep, struct addr_locatio evsel->hists.stats.total_period += 1; hists__inc_nr_events(&evsel->hists, PERF_RECORD_SAMPLE); + if (!he->filtered) + evsel->hists.stats.nr_non_filtered_samples++; } else goto out; } @@ -209,6 +213,8 @@ static int report__add_hist_entry(struct report *rep, struct perf_evsel *evsel, err = hist_entry__inc_addr_samples(he, evsel->idx, al->addr); evsel->hists.stats.total_period += sample->period; + if (!he->filtered) + evsel->hists.stats.nr_non_filtered_samples++; hists__inc_nr_events(&evsel->hists, PERF_RECORD_SAMPLE); out: return err; -- cgit v1.1 From f2148330544a697481219b5bc34261f6dd049bfb Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Tue, 14 Jan 2014 11:52:48 +0900 Subject: perf report: Add --percentage option The --percentage option is for controlling overhead percentage displayed. It can only receive either of "relative" or "absolute". "relative" means it's relative to filtered entries only so that the sum of shown entries will be always 100%. "absolute" means it retains the original value before and after the filter is applied. $ perf report -s comm # Overhead Command # ........ ............ # 74.19% cc1 7.61% gcc 6.11% as 4.35% sh 4.14% make 1.13% fixdep ... $ perf report -s comm -c cc1,gcc --percentage absolute # Overhead Command # ........ ............ # 74.19% cc1 7.61% gcc $ perf report -s comm -c cc1,gcc --percentage relative # Overhead Command # ........ ............ # 90.69% cc1 9.31% gcc Note that it has zero effect if no filter was applied. Suggested-by: Arnaldo Carvalho de Melo Signed-off-by: Namhyung Kim Link: http://lkml.kernel.org/r/1397145720-8063-3-git-send-email-namhyung@kernel.org Signed-off-by: Jiri Olsa --- tools/perf/builtin-report.c | 30 ++++++++++++++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) (limited to 'tools/perf/builtin-report.c') diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c index 2fca56c9..7ec351b 100644 --- a/tools/perf/builtin-report.c +++ b/tools/perf/builtin-report.c @@ -343,6 +343,11 @@ static size_t hists__fprintf_nr_sample_events(struct hists *hists, struct report char buf[512]; size_t size = sizeof(buf); + if (symbol_conf.filter_relative) { + nr_samples = hists->stats.nr_non_filtered_samples; + nr_events = hists->stats.total_non_filtered_period; + } + if (perf_evsel__is_group_event(evsel)) { struct perf_evsel *pos; @@ -350,8 +355,13 @@ static size_t hists__fprintf_nr_sample_events(struct hists *hists, struct report evname = buf; for_each_group_member(pos, evsel) { - nr_samples += pos->hists.stats.nr_events[PERF_RECORD_SAMPLE]; - nr_events += pos->hists.stats.total_period; + if (symbol_conf.filter_relative) { + nr_samples += pos->hists.stats.nr_non_filtered_samples; + nr_events += pos->hists.stats.total_non_filtered_period; + } else { + nr_samples += pos->hists.stats.nr_events[PERF_RECORD_SAMPLE]; + nr_events += pos->hists.stats.total_period; + } } } @@ -707,6 +717,20 @@ parse_percent_limit(const struct option *opt, const char *str, return 0; } +static int +parse_percentage(const struct option *opt __maybe_unused, const char *str, + int unset __maybe_unused) +{ + if (!strcmp(str, "relative")) + symbol_conf.filter_relative = true; + else if (!strcmp(str, "absolute")) + symbol_conf.filter_relative = false; + else + return -1; + + return 0; +} + int cmd_report(int argc, const char **argv, const char *prefix __maybe_unused) { struct perf_session *session; @@ -829,6 +853,8 @@ int cmd_report(int argc, const char **argv, const char *prefix __maybe_unused) OPT_BOOLEAN(0, "mem-mode", &report.mem_mode, "mem access profile"), OPT_CALLBACK(0, "percent-limit", &report, "percent", "Don't show entries under that percent", parse_percent_limit), + OPT_CALLBACK(0, "percentage", NULL, "relative|absolute", + "how to display percentage of filtered entries", parse_percentage), OPT_END() }; struct perf_data_file file = { -- cgit v1.1 From 33db4568e1f41efe6d0e4695483f968fc1135bf3 Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Fri, 7 Feb 2014 12:06:07 +0900 Subject: perf top: Add --percentage option The --percentage option is for controlling overhead percentage displayed. It can only receive either of "relative" or "absolute". Move the parser callback function into a common location since it's used by multiple commands now. For more information, please see previous commit same thing done to "perf report". Signed-off-by: Namhyung Kim Link: http://lkml.kernel.org/r/1397145720-8063-4-git-send-email-namhyung@kernel.org Signed-off-by: Jiri Olsa --- tools/perf/builtin-report.c | 16 +--------------- 1 file changed, 1 insertion(+), 15 deletions(-) (limited to 'tools/perf/builtin-report.c') diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c index 7ec351b..af8cb7a 100644 --- a/tools/perf/builtin-report.c +++ b/tools/perf/builtin-report.c @@ -717,20 +717,6 @@ parse_percent_limit(const struct option *opt, const char *str, return 0; } -static int -parse_percentage(const struct option *opt __maybe_unused, const char *str, - int unset __maybe_unused) -{ - if (!strcmp(str, "relative")) - symbol_conf.filter_relative = true; - else if (!strcmp(str, "absolute")) - symbol_conf.filter_relative = false; - else - return -1; - - return 0; -} - int cmd_report(int argc, const char **argv, const char *prefix __maybe_unused) { struct perf_session *session; @@ -854,7 +840,7 @@ int cmd_report(int argc, const char **argv, const char *prefix __maybe_unused) OPT_CALLBACK(0, "percent-limit", &report, "percent", "Don't show entries under that percent", parse_percent_limit), OPT_CALLBACK(0, "percentage", NULL, "relative|absolute", - "how to display percentage of filtered entries", parse_percentage), + "how to display percentage of filtered entries", parse_filter_percentage), OPT_END() }; struct perf_data_file file = { -- cgit v1.1 From cff6bb46d477383092f46682a0d12e323e4b84d2 Mon Sep 17 00:00:00 2001 From: Don Zickus Date: Mon, 7 Apr 2014 14:55:24 -0400 Subject: perf callchain: Add generic report parse callchain callback function This takes the parse_callchain_opt function and copies it into the callchain.c file. Now the c2c tool can use it too without duplicating. Update perf-report to use the new routine too. Signed-off-by: Don Zickus Reviewed-by: Namhyung Kim Link: http://lkml.kernel.org/r/1396896924-129847-5-git-send-email-dzickus@redhat.com [ Adding missing braces to multiline if condition ] Signed-off-by: Jiri Olsa --- tools/perf/builtin-report.c | 81 ++------------------------------------------- 1 file changed, 3 insertions(+), 78 deletions(-) (limited to 'tools/perf/builtin-report.c') diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c index af8cb7a..76e2bb6 100644 --- a/tools/perf/builtin-report.c +++ b/tools/perf/builtin-report.c @@ -589,11 +589,9 @@ static int __cmd_report(struct report *rep) } static int -parse_callchain_opt(const struct option *opt, const char *arg, int unset) +report_parse_callchain_opt(const struct option *opt, const char *arg, int unset) { struct report *rep = (struct report *)opt->value; - char *tok, *tok2; - char *endptr; /* * --no-call-graph @@ -603,80 +601,7 @@ parse_callchain_opt(const struct option *opt, const char *arg, int unset) return 0; } - symbol_conf.use_callchain = true; - - if (!arg) - return 0; - - tok = strtok((char *)arg, ","); - if (!tok) - return -1; - - /* get the output mode */ - if (!strncmp(tok, "graph", strlen(arg))) - callchain_param.mode = CHAIN_GRAPH_ABS; - - else if (!strncmp(tok, "flat", strlen(arg))) - callchain_param.mode = CHAIN_FLAT; - - else if (!strncmp(tok, "fractal", strlen(arg))) - callchain_param.mode = CHAIN_GRAPH_REL; - - else if (!strncmp(tok, "none", strlen(arg))) { - callchain_param.mode = CHAIN_NONE; - symbol_conf.use_callchain = false; - - return 0; - } - - else - return -1; - - /* get the min percentage */ - tok = strtok(NULL, ","); - if (!tok) - goto setup; - - callchain_param.min_percent = strtod(tok, &endptr); - if (tok == endptr) - return -1; - - /* get the print limit */ - tok2 = strtok(NULL, ","); - if (!tok2) - goto setup; - - if (tok2[0] != 'c') { - callchain_param.print_limit = strtoul(tok2, &endptr, 0); - tok2 = strtok(NULL, ","); - if (!tok2) - goto setup; - } - - /* get the call chain order */ - if (!strncmp(tok2, "caller", strlen("caller"))) - callchain_param.order = ORDER_CALLER; - else if (!strncmp(tok2, "callee", strlen("callee"))) - callchain_param.order = ORDER_CALLEE; - else - return -1; - - /* Get the sort key */ - tok2 = strtok(NULL, ","); - if (!tok2) - goto setup; - if (!strncmp(tok2, "function", strlen("function"))) - callchain_param.key = CCKEY_FUNCTION; - else if (!strncmp(tok2, "address", strlen("address"))) - callchain_param.key = CCKEY_ADDRESS; - else - return -1; -setup: - if (callchain_register_param(&callchain_param) < 0) { - pr_err("Can't register callchain params\n"); - return -1; - } - return 0; + return parse_callchain_report_opt(arg); } int @@ -788,7 +713,7 @@ int cmd_report(int argc, const char **argv, const char *prefix __maybe_unused) "Only display entries with parent-match"), OPT_CALLBACK_DEFAULT('g', "call-graph", &report, "output_type,min_percent[,print_limit],call_order", "Display callchains using output_type (graph, flat, fractal, or none) , min percent threshold, optional print limit, callchain order, key (function or address). " - "Default: fractal,0.5,callee,function", &parse_callchain_opt, callchain_default_opt), + "Default: fractal,0.5,callee,function", &report_parse_callchain_opt, callchain_default_opt), OPT_INTEGER(0, "max-stack", &report.max_stack, "Set the maximum stack depth when parsing the callchain, " "anything beyond the specified depth will be ignored. " -- cgit v1.1 From 58c311da9cec97d7a665156a726bd1653384c65c Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Tue, 22 Apr 2014 09:47:25 +0900 Subject: perf report: Count number of entries separately The hists->nr_entries is counted in multiple places so that they can confuse readers of the code. This is a preparation of later change and do not intend any functional difference. Note that report__collapse_hists() now changed to return nothing since its return value (nr_samples) is only for checking if there's any data in the input file and this can be acheived by checking ->nr_entries. Signed-off-by: Namhyung Kim Link: http://lkml.kernel.org/r/1398327843-31845-2-git-send-email-namhyung@kernel.org Signed-off-by: Jiri Olsa --- tools/perf/builtin-report.c | 42 ++++++++++++++++++++++-------------------- 1 file changed, 22 insertions(+), 20 deletions(-) (limited to 'tools/perf/builtin-report.c') diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c index 76e2bb6..aed5203 100644 --- a/tools/perf/builtin-report.c +++ b/tools/perf/builtin-report.c @@ -57,6 +57,7 @@ struct report { const char *cpu_list; const char *symbol_filter_str; float min_percent; + u64 nr_entries; DECLARE_BITMAP(cpu_bitmap, MAX_NR_CPUS); }; @@ -75,6 +76,17 @@ static int report__config(const char *var, const char *value, void *cb) return perf_default_config(var, value, cb); } +static void report__inc_stats(struct report *rep, struct hist_entry *he) +{ + /* + * The @he is either of a newly created one or an existing one + * merging current sample. We only want to count a new one so + * checking ->nr_events being 1. + */ + if (he->stat.nr_events == 1) + rep->nr_entries++; +} + static int report__add_mem_hist_entry(struct report *rep, struct addr_location *al, struct perf_sample *sample, struct perf_evsel *evsel) { @@ -121,6 +133,8 @@ static int report__add_mem_hist_entry(struct report *rep, struct addr_location * goto out; } + report__inc_stats(rep, he); + evsel->hists.stats.total_period += cost; hists__inc_nr_events(&evsel->hists, PERF_RECORD_SAMPLE); if (!he->filtered) @@ -176,6 +190,8 @@ static int report__add_branch_hist_entry(struct report *rep, struct addr_locatio goto out; } + report__inc_stats(rep, he); + evsel->hists.stats.total_period += 1; hists__inc_nr_events(&evsel->hists, PERF_RECORD_SAMPLE); if (!he->filtered) @@ -212,6 +228,8 @@ static int report__add_hist_entry(struct report *rep, struct perf_evsel *evsel, if (ui__has_annotation()) err = hist_entry__inc_addr_samples(he, evsel->idx, al->addr); + report__inc_stats(rep, he); + evsel->hists.stats.total_period += sample->period; if (!he->filtered) evsel->hists.stats.nr_non_filtered_samples++; @@ -486,24 +504,12 @@ static int report__browse_hists(struct report *rep) return ret; } -static u64 report__collapse_hists(struct report *rep) +static void report__collapse_hists(struct report *rep) { struct ui_progress prog; struct perf_evsel *pos; - u64 nr_samples = 0; - /* - * Count number of histogram entries to use when showing progress, - * reusing nr_samples variable. - */ - evlist__for_each(rep->session->evlist, pos) - nr_samples += pos->hists.nr_entries; - ui_progress__init(&prog, nr_samples, "Merging related events..."); - /* - * Count total number of samples, will be used to check if this - * session had any. - */ - nr_samples = 0; + ui_progress__init(&prog, rep->nr_entries, "Merging related events..."); evlist__for_each(rep->session->evlist, pos) { struct hists *hists = &pos->hists; @@ -512,7 +518,6 @@ static u64 report__collapse_hists(struct report *rep) hists->symbol_filter_str = rep->symbol_filter_str; hists__collapse_resort(hists, &prog); - nr_samples += hists->stats.nr_events[PERF_RECORD_SAMPLE]; /* Non-group events are considered as leader */ if (symbol_conf.event_group && @@ -525,14 +530,11 @@ static u64 report__collapse_hists(struct report *rep) } ui_progress__finish(); - - return nr_samples; } static int __cmd_report(struct report *rep) { int ret; - u64 nr_samples; struct perf_session *session = rep->session; struct perf_evsel *pos; struct perf_data_file *file = session->file; @@ -572,12 +574,12 @@ static int __cmd_report(struct report *rep) } } - nr_samples = report__collapse_hists(rep); + report__collapse_hists(rep); if (session_done()) return 0; - if (nr_samples == 0) { + if (rep->nr_entries == 0) { ui__error("The %s file has no samples!\n", file->path); return 0; } -- cgit v1.1 From 820bc81f4cdaac09a8f25040d3a20d86f3da292b Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Tue, 22 Apr 2014 11:44:21 +0900 Subject: perf tools: Account entry stats when it's added to the output tree Currently, accounting each sample is done in multiple places - once when adding them to the input tree, other when adding them to the output tree. It's not only confusing but also can cause a subtle problem since concurrent processing like in perf top might see the updated stats before adding entries into the output tree - like seeing more (blank) lines at the end and/or slight inaccurate percentage. To fix this, only account the entries when it's moved into the output tree so that they cannot be seen prematurely. There're some exceptional cases here and there - they should be addressed separately with comments. Signed-off-by: Namhyung Kim Link: http://lkml.kernel.org/r/1398327843-31845-7-git-send-email-namhyung@kernel.org Signed-off-by: Jiri Olsa --- tools/perf/builtin-report.c | 24 ++++++++++-------------- 1 file changed, 10 insertions(+), 14 deletions(-) (limited to 'tools/perf/builtin-report.c') diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c index aed5203..89c9528 100644 --- a/tools/perf/builtin-report.c +++ b/tools/perf/builtin-report.c @@ -85,6 +85,16 @@ static void report__inc_stats(struct report *rep, struct hist_entry *he) */ if (he->stat.nr_events == 1) rep->nr_entries++; + + /* + * Only counts number of samples at this stage as it's more + * natural to do it here and non-sample events are also + * counted in perf_session_deliver_event(). The dump_trace + * requires this info is ready before going to the output tree. + */ + hists__inc_nr_events(he->hists, PERF_RECORD_SAMPLE); + if (!he->filtered) + he->hists->stats.nr_non_filtered_samples++; } static int report__add_mem_hist_entry(struct report *rep, struct addr_location *al, @@ -135,10 +145,6 @@ static int report__add_mem_hist_entry(struct report *rep, struct addr_location * report__inc_stats(rep, he); - evsel->hists.stats.total_period += cost; - hists__inc_nr_events(&evsel->hists, PERF_RECORD_SAMPLE); - if (!he->filtered) - evsel->hists.stats.nr_non_filtered_samples++; err = hist_entry__append_callchain(he, sample); out: return err; @@ -189,13 +195,7 @@ static int report__add_branch_hist_entry(struct report *rep, struct addr_locatio if (err) goto out; } - report__inc_stats(rep, he); - - evsel->hists.stats.total_period += 1; - hists__inc_nr_events(&evsel->hists, PERF_RECORD_SAMPLE); - if (!he->filtered) - evsel->hists.stats.nr_non_filtered_samples++; } else goto out; } @@ -230,10 +230,6 @@ static int report__add_hist_entry(struct report *rep, struct perf_evsel *evsel, report__inc_stats(rep, he); - evsel->hists.stats.total_period += sample->period; - if (!he->filtered) - evsel->hists.stats.nr_non_filtered_samples++; - hists__inc_nr_events(&evsel->hists, PERF_RECORD_SAMPLE); out: return err; } -- cgit v1.1 From a2ce067e55e328f1a6fe3dddf77a173381ffdfe1 Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Tue, 4 Mar 2014 09:06:42 +0900 Subject: perf tools: Allow hpp fields to be sort keys Add overhead{,_sys,_us,_guest_sys,_guest_us}, sample and period sort keys so that they can be selected with --sort/-s option. $ perf report -s period,comm --stdio ... # Overhead Period Command # ........ ............ ............... # 47.06% 152 swapper 13.93% 45 qemu-system-arm 12.38% 40 synergys 3.72% 12 firefox 2.48% 8 xchat Signed-off-by: Namhyung Kim Acked-by: Ingo Molnar Link: http://lkml.kernel.org/r/1400480762-22852-9-git-send-email-namhyung@kernel.org Signed-off-by: Jiri Olsa --- tools/perf/builtin-report.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'tools/perf/builtin-report.c') diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c index 89c9528..d0180d5 100644 --- a/tools/perf/builtin-report.c +++ b/tools/perf/builtin-report.c @@ -699,10 +699,8 @@ int cmd_report(int argc, const char **argv, const char *prefix __maybe_unused) OPT_BOOLEAN(0, "header-only", &report.header_only, "Show only data header."), OPT_STRING('s', "sort", &sort_order, "key[,key2...]", - "sort by key(s): pid, comm, dso, symbol, parent, cpu, srcline," - " dso_to, dso_from, symbol_to, symbol_from, mispredict," - " weight, local_weight, mem, symbol_daddr, dso_daddr, tlb, " - "snoop, locked, abort, in_tx, transaction"), + "sort by key(s): pid, comm, dso, symbol, parent, cpu, srcline, ..." + " Please refer the man page for the complete list."), OPT_BOOLEAN(0, "showcpuutilization", &symbol_conf.show_cpu_utilization, "Show sample percentage for different cpu modes"), OPT_STRING('p', "parent", &parent_pattern, "regex", -- cgit v1.1 From 512ae1bd6acb811c72e44e2540099eccd31f773d Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Tue, 18 Mar 2014 11:31:39 +0900 Subject: perf tools: Consolidate management of default sort orders The perf uses different default sort orders for different use-cases, and this was scattered throughout the code. Add get_default_sort_ order() function to handle this and change initial value of sort_order to NULL to distinguish it from user-given one. Signed-off-by: Namhyung Kim Cc: Stephane Eranian Link: http://lkml.kernel.org/r/1400480762-22852-10-git-send-email-namhyung@kernel.org Signed-off-by: Jiri Olsa --- tools/perf/builtin-report.c | 18 ------------------ 1 file changed, 18 deletions(-) (limited to 'tools/perf/builtin-report.c') diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c index d0180d5..f4d640cf 100644 --- a/tools/perf/builtin-report.c +++ b/tools/perf/builtin-report.c @@ -805,30 +805,12 @@ repeat: if (branch_mode == -1 && has_br_stack) sort__mode = SORT_MODE__BRANCH; - /* sort__mode could be NORMAL if --no-branch-stack */ - if (sort__mode == SORT_MODE__BRANCH) { - /* - * if no sort_order is provided, then specify - * branch-mode specific order - */ - if (sort_order == default_sort_order) - sort_order = "comm,dso_from,symbol_from," - "dso_to,symbol_to"; - - } if (report.mem_mode) { if (sort__mode == SORT_MODE__BRANCH) { pr_err("branch and mem mode incompatible\n"); goto error; } sort__mode = SORT_MODE__MEMORY; - - /* - * if no sort_order is provided, then specify - * branch-mode specific order - */ - if (sort_order == default_sort_order) - sort_order = "local_weight,mem,sym,dso,symbol_daddr,dso_daddr,snoop,tlb,locked"; } if (setup_sorting() < 0) { -- cgit v1.1 From 22af969e8cfc6ea46d3e1a774a16d7e19b8cf4db Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Wed, 16 Apr 2014 11:04:51 +0900 Subject: perf tools: Call perf_hpp__init() before setting up GUI browsers So that it can be set properly prior to set up output fields. That makes easy to handle/warn errors during the setup since it doesn't need to be bothered with the GUI. Signed-off-by: Namhyung Kim Link: http://lkml.kernel.org/r/1400480762-22852-11-git-send-email-namhyung@kernel.org Signed-off-by: Jiri Olsa --- tools/perf/builtin-report.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'tools/perf/builtin-report.c') diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c index f4d640cf..c4dab7a 100644 --- a/tools/perf/builtin-report.c +++ b/tools/perf/builtin-report.c @@ -823,16 +823,16 @@ repeat: goto error; } + perf_hpp__init(); + /* Force tty output for header output. */ if (report.header || report.header_only) use_browser = 0; if (strcmp(input_name, "-") != 0) setup_browser(true); - else { + else use_browser = 0; - perf_hpp__init(); - } if (report.header || report.header_only) { perf_session__fprintf_info(session, stdout, -- cgit v1.1 From a7d945bc91602f916d2d0c794c179d9a784859e7 Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Tue, 4 Mar 2014 10:46:34 +0900 Subject: perf report: Add -F option to specify output fields The -F/--fields option is to allow user setup output field in any order. It can receive any sort keys and following (hpp) fields: overhead, overhead_sys, overhead_us, sample and period If guest profiling is enabled, overhead_guest_{sys,us} will be available too. The output fields also affect sort order unless you give -s/--sort option. And any keys specified on -s option, will also be added to the output field list automatically. $ perf report -F sym,sample,overhead ... # Symbol Samples Overhead # .......................... ............ ........ # [.] __cxa_atexit 2 2.50% [.] __libc_csu_init 4 5.00% [.] __new_exitfn 3 3.75% [.] _dl_check_map_versions 1 1.25% [.] _dl_name_match_p 4 5.00% [.] _dl_setup_hash 1 1.25% [.] _dl_sysdep_start 1 1.25% [.] _init 5 6.25% [.] _setjmp 6 7.50% [.] a 8 10.00% [.] b 8 10.00% [.] brk 1 1.25% [.] c 8 10.00% Note that, the example output above is captured after applying next patch which fixes sort/comparing behavior. Requested-by: Ingo Molnar Signed-off-by: Namhyung Kim Acked-by: Ingo Molnar Link: http://lkml.kernel.org/r/1400480762-22852-12-git-send-email-namhyung@kernel.org Signed-off-by: Jiri Olsa --- tools/perf/builtin-report.c | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) (limited to 'tools/perf/builtin-report.c') diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c index c4dab7a..bc0eec1 100644 --- a/tools/perf/builtin-report.c +++ b/tools/perf/builtin-report.c @@ -701,6 +701,8 @@ int cmd_report(int argc, const char **argv, const char *prefix __maybe_unused) OPT_STRING('s', "sort", &sort_order, "key[,key2...]", "sort by key(s): pid, comm, dso, symbol, parent, cpu, srcline, ..." " Please refer the man page for the complete list."), + OPT_STRING('F', "fields", &field_order, "key[,keys...]", + "output field(s): overhead, period, sample plus all of sort keys"), OPT_BOOLEAN(0, "showcpuutilization", &symbol_conf.show_cpu_utilization, "Show sample percentage for different cpu modes"), OPT_STRING('p', "parent", &parent_pattern, "regex", @@ -814,17 +816,14 @@ repeat: } if (setup_sorting() < 0) { - parse_options_usage(report_usage, options, "s", 1); + if (sort_order) + parse_options_usage(report_usage, options, "s", 1); + if (field_order) + parse_options_usage(sort_order ? NULL : report_usage, + options, "F", 1); goto error; } - if (parent_pattern != default_parent_pattern) { - if (sort_dimension__add("parent") < 0) - goto error; - } - - perf_hpp__init(); - /* Force tty output for header output. */ if (report.header || report.header_only) use_browser = 0; -- cgit v1.1