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 ++++++ tools/perf/builtin-top.c | 3 +++ tools/perf/util/hist.c | 17 ++++++++++++++--- tools/perf/util/hist.h | 3 +++ 4 files changed, 26 insertions(+), 3 deletions(-) diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c index c8f21137dfd..2fca56c9d68 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; diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c index 65aaa5bbf7e..25269014164 100644 --- a/tools/perf/builtin-top.c +++ b/tools/perf/builtin-top.c @@ -253,6 +253,9 @@ static struct hist_entry *perf_evsel__add_hist_entry(struct perf_evsel *evsel, return NULL; hists__inc_nr_events(&evsel->hists, PERF_RECORD_SAMPLE); + if (!he->filtered) + evsel->hists.stats.nr_non_filtered_samples++; + return he; } diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c index f38590d7561..1ed3e2b86f0 100644 --- a/tools/perf/util/hist.c +++ b/tools/perf/util/hist.c @@ -674,8 +674,8 @@ void hists__output_resort(struct hists *hists) next = rb_first(root); hists->entries = RB_ROOT; - hists->nr_entries = 0; - hists->stats.total_period = 0; + hists->nr_entries = hists->nr_non_filtered_entries = 0; + hists->stats.total_period = hists->stats.total_non_filtered_period = 0; hists__reset_col_len(hists); while (next) { @@ -695,11 +695,16 @@ static void hists__remove_entry_filter(struct hists *hists, struct hist_entry *h return; ++hists->nr_entries; - if (h->ms.unfolded) + ++hists->nr_non_filtered_entries; + if (h->ms.unfolded) { hists->nr_entries += h->nr_rows; + hists->nr_non_filtered_entries += h->nr_rows; + } h->row_offset = 0; hists->stats.total_period += h->stat.period; + hists->stats.total_non_filtered_period += h->stat.period; hists->stats.nr_events[PERF_RECORD_SAMPLE] += h->stat.nr_events; + hists->stats.nr_non_filtered_samples += h->stat.nr_events; hists__calc_col_len(hists, h); } @@ -722,7 +727,9 @@ void hists__filter_by_dso(struct hists *hists) struct rb_node *nd; hists->nr_entries = hists->stats.total_period = 0; + hists->nr_non_filtered_entries = hists->stats.total_non_filtered_period = 0; hists->stats.nr_events[PERF_RECORD_SAMPLE] = 0; + hists->stats.nr_non_filtered_samples = 0; hists__reset_col_len(hists); for (nd = rb_first(&hists->entries); nd; nd = rb_next(nd)) { @@ -755,7 +762,9 @@ void hists__filter_by_thread(struct hists *hists) struct rb_node *nd; hists->nr_entries = hists->stats.total_period = 0; + hists->nr_non_filtered_entries = hists->stats.total_non_filtered_period = 0; hists->stats.nr_events[PERF_RECORD_SAMPLE] = 0; + hists->stats.nr_non_filtered_samples = 0; hists__reset_col_len(hists); for (nd = rb_first(&hists->entries); nd; nd = rb_next(nd)) { @@ -786,7 +795,9 @@ void hists__filter_by_symbol(struct hists *hists) struct rb_node *nd; hists->nr_entries = hists->stats.total_period = 0; + hists->nr_non_filtered_entries = hists->stats.total_non_filtered_period = 0; hists->stats.nr_events[PERF_RECORD_SAMPLE] = 0; + hists->stats.nr_non_filtered_samples = 0; hists__reset_col_len(hists); for (nd = rb_first(&hists->entries); nd; nd = rb_next(nd)) { diff --git a/tools/perf/util/hist.h b/tools/perf/util/hist.h index 1f1f513dfe7..213551469f3 100644 --- a/tools/perf/util/hist.h +++ b/tools/perf/util/hist.h @@ -37,9 +37,11 @@ enum hist_filter { */ struct events_stats { u64 total_period; + u64 total_non_filtered_period; u64 total_lost; u64 total_invalid_chains; u32 nr_events[PERF_RECORD_HEADER_MAX]; + u32 nr_non_filtered_samples; u32 nr_lost_warned; u32 nr_unknown_events; u32 nr_invalid_chains; @@ -83,6 +85,7 @@ struct hists { struct rb_root entries; struct rb_root entries_collapsed; u64 nr_entries; + u64 nr_non_filtered_entries; const struct thread *thread_filter; const struct dso *dso_filter; const char *uid_filter_str; -- cgit v1.2.3-70-g09d2 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/Documentation/perf-report.txt | 24 +++++++++++++++----- tools/perf/builtin-report.c | 30 ++++++++++++++++++++++-- tools/perf/ui/browsers/hists.c | 35 +++++++++++++++++++++------- tools/perf/ui/gtk/hists.c | 11 ++++----- tools/perf/ui/hist.c | 8 +++---- tools/perf/util/hist.c | 39 ++++++++++++++++---------------- tools/perf/util/hist.h | 1 + tools/perf/util/symbol.c | 1 + tools/perf/util/symbol.h | 3 ++- 9 files changed, 106 insertions(+), 46 deletions(-) diff --git a/tools/perf/Documentation/perf-report.txt b/tools/perf/Documentation/perf-report.txt index 8eab8a4bdeb..09af6629856 100644 --- a/tools/perf/Documentation/perf-report.txt +++ b/tools/perf/Documentation/perf-report.txt @@ -25,10 +25,6 @@ OPTIONS --verbose:: Be more verbose. (show symbol address, etc) --d:: ---dsos=:: - Only consider symbols in these dsos. CSV that understands - file://filename entries. -n:: --show-nr-samples:: Show the number of samples for each symbol @@ -42,11 +38,18 @@ OPTIONS -c:: --comms=:: Only consider symbols in these comms. CSV that understands - file://filename entries. + file://filename entries. This option will affect the percentage of + the overhead column. See --percentage for more info. +-d:: +--dsos=:: + Only consider symbols in these dsos. CSV that understands + file://filename entries. This option will affect the percentage of + the overhead column. See --percentage for more info. -S:: --symbols=:: Only consider these symbols. CSV that understands - file://filename entries. + file://filename entries. This option will affect the percentage of + the overhead column. See --percentage for more info. --symbol-filter=:: Only show symbols that match (partially) with this filter. @@ -237,6 +240,15 @@ OPTIONS Do not show entries which have an overhead under that percent. (Default: 0). +--percentage:: + Determine how to display the overhead percentage of filtered entries. + Filters can be applied by --comms, --dsos and/or --symbols options and + Zoom operations on the TUI (thread, dso, etc). + + "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. + --header:: Show header information in the perf.data file. This includes various information like hostname, OS and perf version, cpu/mem diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c index 2fca56c9d68..7ec351bda83 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 = { diff --git a/tools/perf/ui/browsers/hists.c b/tools/perf/ui/browsers/hists.c index 7ec871af3f6..7ad11477a0f 100644 --- a/tools/perf/ui/browsers/hists.c +++ b/tools/perf/ui/browsers/hists.c @@ -769,12 +769,15 @@ static unsigned int hist_browser__refresh(struct ui_browser *browser) for (nd = browser->top; nd; nd = rb_next(nd)) { struct hist_entry *h = rb_entry(nd, struct hist_entry, rb_node); - float percent = h->stat.period * 100.0 / - hb->hists->stats.total_period; + u64 total = hists__total_period(h->hists); + float percent = 0.0; if (h->filtered) continue; + if (total) + percent = h->stat.period * 100.0 / total; + if (percent < hb->min_pcnt) continue; @@ -792,8 +795,11 @@ static struct rb_node *hists__filter_entries(struct rb_node *nd, { while (nd != NULL) { struct hist_entry *h = rb_entry(nd, struct hist_entry, rb_node); - float percent = h->stat.period * 100.0 / - hists->stats.total_period; + u64 total = hists__total_period(hists); + float percent = 0.0; + + if (total) + percent = h->stat.period * 100.0 / total; if (percent < min_pcnt) return NULL; @@ -813,8 +819,11 @@ static struct rb_node *hists__filter_prev_entries(struct rb_node *nd, { while (nd != NULL) { struct hist_entry *h = rb_entry(nd, struct hist_entry, rb_node); - float percent = h->stat.period * 100.0 / - hists->stats.total_period; + u64 total = hists__total_period(hists); + float percent = 0.0; + + if (total) + percent = h->stat.period * 100.0 / total; if (!h->filtered && percent >= min_pcnt) return nd; @@ -1189,6 +1198,11 @@ static int hists__browser_title(struct hists *hists, char *bf, size_t size, char buf[512]; size_t buflen = 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; @@ -1196,8 +1210,13 @@ static int hists__browser_title(struct hists *hists, char *bf, size_t size, ev_name = 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; + } } } diff --git a/tools/perf/ui/gtk/hists.c b/tools/perf/ui/gtk/hists.c index e395ef9b0ae..91f10f3f6dd 100644 --- a/tools/perf/ui/gtk/hists.c +++ b/tools/perf/ui/gtk/hists.c @@ -228,12 +228,15 @@ static void perf_gtk__show_hists(GtkWidget *window, struct hists *hists, for (nd = rb_first(&hists->entries); nd; nd = rb_next(nd)) { struct hist_entry *h = rb_entry(nd, struct hist_entry, rb_node); GtkTreeIter iter; - float percent = h->stat.period * 100.0 / - hists->stats.total_period; + u64 total = hists__total_period(h->hists); + float percent = 0.0; if (h->filtered) continue; + if (total) + percent = h->stat.period * 100.0 / total; + if (percent < min_pcnt) continue; @@ -261,12 +264,8 @@ static void perf_gtk__show_hists(GtkWidget *window, struct hists *hists, } if (symbol_conf.use_callchain && sort__has_sym) { - u64 total; - if (callchain_param.mode == CHAIN_GRAPH_REL) total = h->stat.period; - else - total = hists->stats.total_period; perf_gtk__add_callchain(&h->sorted_chain, store, &iter, sym_col, total); diff --git a/tools/perf/ui/hist.c b/tools/perf/ui/hist.c index 0f403b83e9d..0912805c08f 100644 --- a/tools/perf/ui/hist.c +++ b/tools/perf/ui/hist.c @@ -32,10 +32,10 @@ int __hpp__fmt(struct perf_hpp *hpp, struct hist_entry *he, if (fmt_percent) { double percent = 0.0; + u64 total = hists__total_period(hists); - if (hists->stats.total_period) - percent = 100.0 * get_field(he) / - hists->stats.total_period; + if (total) + percent = 100.0 * get_field(he) / total; ret += hpp__call_print_fn(hpp, print_fn, fmt, percent); } else @@ -50,7 +50,7 @@ int __hpp__fmt(struct perf_hpp *hpp, struct hist_entry *he, list_for_each_entry(pair, &he->pairs.head, pairs.node) { u64 period = get_field(pair); - u64 total = pair->hists->stats.total_period; + u64 total = hists__total_period(pair->hists); if (!total) continue; diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c index 1ed3e2b86f0..3ebd89a2825 100644 --- a/tools/perf/util/hist.c +++ b/tools/perf/util/hist.c @@ -321,9 +321,11 @@ void hists__inc_nr_entries(struct hists *hists, struct hist_entry *h) { if (!h->filtered) { hists__calc_col_len(hists, h); - ++hists->nr_entries; - hists->stats.total_period += h->stat.period; + hists->nr_non_filtered_entries++; + hists->stats.total_non_filtered_period += h->stat.period; } + hists->nr_entries++; + hists->stats.total_period += h->stat.period; } static u8 symbol__parent_filter(const struct symbol *parent) @@ -674,8 +676,9 @@ void hists__output_resort(struct hists *hists) next = rb_first(root); hists->entries = RB_ROOT; - hists->nr_entries = hists->nr_non_filtered_entries = 0; - hists->stats.total_period = hists->stats.total_non_filtered_period = 0; + hists->nr_non_filtered_entries = 0; + hists->stats.total_period = 0; + hists->stats.total_non_filtered_period = 0; hists__reset_col_len(hists); while (next) { @@ -694,16 +697,11 @@ static void hists__remove_entry_filter(struct hists *hists, struct hist_entry *h if (h->filtered) return; - ++hists->nr_entries; ++hists->nr_non_filtered_entries; - if (h->ms.unfolded) { - hists->nr_entries += h->nr_rows; + if (h->ms.unfolded) hists->nr_non_filtered_entries += h->nr_rows; - } h->row_offset = 0; - hists->stats.total_period += h->stat.period; hists->stats.total_non_filtered_period += h->stat.period; - hists->stats.nr_events[PERF_RECORD_SAMPLE] += h->stat.nr_events; hists->stats.nr_non_filtered_samples += h->stat.nr_events; hists__calc_col_len(hists, h); @@ -726,9 +724,8 @@ void hists__filter_by_dso(struct hists *hists) { struct rb_node *nd; - hists->nr_entries = hists->stats.total_period = 0; - hists->nr_non_filtered_entries = hists->stats.total_non_filtered_period = 0; - hists->stats.nr_events[PERF_RECORD_SAMPLE] = 0; + hists->nr_non_filtered_entries = 0; + hists->stats.total_non_filtered_period = 0; hists->stats.nr_non_filtered_samples = 0; hists__reset_col_len(hists); @@ -761,9 +758,8 @@ void hists__filter_by_thread(struct hists *hists) { struct rb_node *nd; - hists->nr_entries = hists->stats.total_period = 0; - hists->nr_non_filtered_entries = hists->stats.total_non_filtered_period = 0; - hists->stats.nr_events[PERF_RECORD_SAMPLE] = 0; + hists->nr_non_filtered_entries = 0; + hists->stats.total_non_filtered_period = 0; hists->stats.nr_non_filtered_samples = 0; hists__reset_col_len(hists); @@ -794,9 +790,8 @@ void hists__filter_by_symbol(struct hists *hists) { struct rb_node *nd; - hists->nr_entries = hists->stats.total_period = 0; - hists->nr_non_filtered_entries = hists->stats.total_non_filtered_period = 0; - hists->stats.nr_events[PERF_RECORD_SAMPLE] = 0; + hists->nr_non_filtered_entries = 0; + hists->stats.total_non_filtered_period = 0; hists->stats.nr_non_filtered_samples = 0; hists__reset_col_len(hists); @@ -942,3 +937,9 @@ int hists__link(struct hists *leader, struct hists *other) return 0; } + +u64 hists__total_period(struct hists *hists) +{ + return symbol_conf.filter_relative ? hists->stats.total_non_filtered_period : + hists->stats.total_period; +} diff --git a/tools/perf/util/hist.h b/tools/perf/util/hist.h index 213551469f3..3191496bd3b 100644 --- a/tools/perf/util/hist.h +++ b/tools/perf/util/hist.h @@ -115,6 +115,7 @@ void hists__collapse_resort(struct hists *hists, struct ui_progress *prog); void hists__decay_entries(struct hists *hists, bool zap_user, bool zap_kernel); void hists__output_recalc_col_len(struct hists *hists, int max_rows); +u64 hists__total_period(struct hists *hists); void hists__inc_nr_entries(struct hists *hists, struct hist_entry *h); void hists__inc_nr_events(struct hists *hists, u32 type); void events_stats__inc(struct events_stats *stats, u32 type); diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c index 95e24977993..b2eca6c17a7 100644 --- a/tools/perf/util/symbol.c +++ b/tools/perf/util/symbol.c @@ -33,6 +33,7 @@ struct symbol_conf symbol_conf = { .try_vmlinux_path = true, .annotate_src = true, .demangle = true, + .filter_relative = true, .symfs = "", }; diff --git a/tools/perf/util/symbol.h b/tools/perf/util/symbol.h index 501e4e722e8..ae94e006a52 100644 --- a/tools/perf/util/symbol.h +++ b/tools/perf/util/symbol.h @@ -115,7 +115,8 @@ struct symbol_conf { annotate_asm_raw, annotate_src, event_group, - demangle; + demangle, + filter_relative; const char *vmlinux_name, *kallsyms_name, *source_prefix, -- cgit v1.2.3-70-g09d2 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/Documentation/perf-top.txt | 18 +++++++++++++++--- tools/perf/builtin-report.c | 16 +--------------- tools/perf/builtin-top.c | 5 +++-- tools/perf/util/hist.c | 13 +++++++++++++ tools/perf/util/hist.h | 5 +++++ 5 files changed, 37 insertions(+), 20 deletions(-) diff --git a/tools/perf/Documentation/perf-top.txt b/tools/perf/Documentation/perf-top.txt index 976b00c6cdb..64ed79c4363 100644 --- a/tools/perf/Documentation/perf-top.txt +++ b/tools/perf/Documentation/perf-top.txt @@ -123,13 +123,16 @@ Default is to monitor all CPUS. Show a column with the sum of periods. --dsos:: - Only consider symbols in these dsos. + Only consider symbols in these dsos. This option will affect the + percentage of the overhead column. See --percentage for more info. --comms:: - Only consider symbols in these comms. + Only consider symbols in these comms. This option will affect the + percentage of the overhead column. See --percentage for more info. --symbols:: - Only consider these symbols. + Only consider these symbols. This option will affect the + percentage of the overhead column. See --percentage for more info. -M:: --disassembler-style=:: Set disassembler style for objdump. @@ -165,6 +168,15 @@ Default is to monitor all CPUS. Do not show entries which have an overhead under that percent. (Default: 0). +--percentage:: + Determine how to display the overhead percentage of filtered entries. + Filters can be applied by --comms, --dsos and/or --symbols options and + Zoom operations on the TUI (thread, dso, etc). + + "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. + INTERACTIVE PROMPTING KEYS -------------------------- diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c index 7ec351bda83..af8cb7a2c9b 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 = { diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c index 25269014164..37d30460bad 100644 --- a/tools/perf/builtin-top.c +++ b/tools/perf/builtin-top.c @@ -697,8 +697,7 @@ static void perf_event__process_sample(struct perf_tool *tool, if (event->header.misc & PERF_RECORD_MISC_EXACT_IP) top->exact_samples++; - if (perf_event__preprocess_sample(event, machine, &al, sample) < 0 || - al.filtered) + if (perf_event__preprocess_sample(event, machine, &al, sample) < 0) return; if (!top->kptr_restrict_warned && @@ -1119,6 +1118,8 @@ int cmd_top(int argc, const char **argv, const char *prefix __maybe_unused) OPT_STRING('u', "uid", &target->uid_str, "user", "user to profile"), OPT_CALLBACK(0, "percent-limit", &top, "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_filter_percentage), OPT_END() }; const char * const top_usage[] = { diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c index 3ebd89a2825..3c2dd233b98 100644 --- a/tools/perf/util/hist.c +++ b/tools/perf/util/hist.c @@ -943,3 +943,16 @@ u64 hists__total_period(struct hists *hists) return symbol_conf.filter_relative ? hists->stats.total_non_filtered_period : hists->stats.total_period; } + +int parse_filter_percentage(const struct option *opt __maybe_unused, + const char *arg, int unset __maybe_unused) +{ + if (!strcmp(arg, "relative")) + symbol_conf.filter_relative = true; + else if (!strcmp(arg, "absolute")) + symbol_conf.filter_relative = false; + else + return -1; + + return 0; +} diff --git a/tools/perf/util/hist.h b/tools/perf/util/hist.h index 3191496bd3b..a4ec336ae3f 100644 --- a/tools/perf/util/hist.h +++ b/tools/perf/util/hist.h @@ -254,4 +254,9 @@ static inline int script_browse(const char *script_opt __maybe_unused) #endif unsigned int hists__sort_list_width(struct hists *hists); + +struct option; +int parse_filter_percentage(const struct option *opt __maybe_unused, + const char *arg, int unset __maybe_unused); + #endif /* __PERF_HIST_H */ -- cgit v1.2.3-70-g09d2 From 8810f6ced73556c1a63b6269a6cdad8d630aaaf0 Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Fri, 7 Feb 2014 12:06:07 +0900 Subject: perf diff: Add --percentage option The --percentage option is for controlling overhead percentage displayed. It can only receive either of "relative" or "absolute" and affects -c delta output only. 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-5-git-send-email-namhyung@kernel.org Signed-off-by: Jiri Olsa --- tools/perf/Documentation/perf-diff.txt | 21 ++++++++++++++++++--- tools/perf/builtin-diff.c | 30 ++++++++++++++++++++++-------- 2 files changed, 40 insertions(+), 11 deletions(-) diff --git a/tools/perf/Documentation/perf-diff.txt b/tools/perf/Documentation/perf-diff.txt index fdfceee0ffd..fbfa1192923 100644 --- a/tools/perf/Documentation/perf-diff.txt +++ b/tools/perf/Documentation/perf-diff.txt @@ -33,17 +33,20 @@ OPTIONS -d:: --dsos=:: Only consider symbols in these dsos. CSV that understands - file://filename entries. + file://filename entries. This option will affect the percentage + of the Baseline/Delta column. See --percentage for more info. -C:: --comms=:: Only consider symbols in these comms. CSV that understands - file://filename entries. + file://filename entries. This option will affect the percentage + of the Baseline/Delta column. See --percentage for more info. -S:: --symbols=:: Only consider these symbols. CSV that understands - file://filename entries. + file://filename entries. This option will affect the percentage + of the Baseline/Delta column. See --percentage for more info. -s:: --sort=:: @@ -89,6 +92,14 @@ OPTIONS --order:: Specify compute sorting column number. +--percentage:: + Determine how to display the overhead percentage of filtered entries. + Filters can be applied by --comms, --dsos and/or --symbols options. + + "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. + COMPARISON ---------- The comparison is governed by the baseline file. The baseline perf.data @@ -157,6 +168,10 @@ with: - period_percent being the % of the hist entry period value within single data file + - with filtering by -C, -d and/or -S, period_percent might be changed + relative to how entries are filtered. Use --percentage=absolute to + prevent such fluctuation. + ratio ~~~~~ If specified the 'Ratio' column is displayed with value 'r' computed as: diff --git a/tools/perf/builtin-diff.c b/tools/perf/builtin-diff.c index 204fffe2253..c903fe13c17 100644 --- a/tools/perf/builtin-diff.c +++ b/tools/perf/builtin-diff.c @@ -220,7 +220,8 @@ static int setup_compute(const struct option *opt, const char *str, static double period_percent(struct hist_entry *he, u64 period) { - u64 total = he->hists->stats.total_period; + u64 total = hists__total_period(he->hists); + return (period * 100.0) / total; } @@ -259,11 +260,18 @@ static s64 compute_wdiff(struct hist_entry *he, struct hist_entry *pair) static int formula_delta(struct hist_entry *he, struct hist_entry *pair, char *buf, size_t size) { + u64 he_total = he->hists->stats.total_period; + u64 pair_total = pair->hists->stats.total_period; + + if (symbol_conf.filter_relative) { + he_total = he->hists->stats.total_non_filtered_period; + pair_total = pair->hists->stats.total_non_filtered_period; + } return scnprintf(buf, size, "(%" PRIu64 " * 100 / %" PRIu64 ") - " "(%" PRIu64 " * 100 / %" PRIu64 ")", - pair->stat.period, pair->hists->stats.total_period, - he->stat.period, he->hists->stats.total_period); + pair->stat.period, pair_total, + he->stat.period, he_total); } static int formula_ratio(struct hist_entry *he, struct hist_entry *pair, @@ -327,15 +335,16 @@ static int diff__process_sample_event(struct perf_tool *tool __maybe_unused, return -1; } - if (al.filtered) - return 0; - if (hists__add_entry(&evsel->hists, &al, sample->period, sample->weight, sample->transaction)) { pr_warning("problem incrementing symbol period, skipping event\n"); return -1; } + if (al.filtered == 0) { + evsel->hists.stats.total_non_filtered_period += sample->period; + evsel->hists.nr_non_filtered_entries++; + } evsel->hists.stats.total_period += sample->period; return 0; } @@ -565,7 +574,9 @@ static void hists__compute_resort(struct hists *hists) next = rb_first(root); hists->nr_entries = 0; + hists->nr_non_filtered_entries = 0; hists->stats.total_period = 0; + hists->stats.total_non_filtered_period = 0; hists__reset_col_len(hists); while (next != NULL) { @@ -732,13 +743,16 @@ static const struct option options[] = { OPT_STRING(0, "symfs", &symbol_conf.symfs, "directory", "Look for files with symbols relative to this directory"), OPT_UINTEGER('o', "order", &sort_compute, "Specify compute sorting."), + OPT_CALLBACK(0, "percentage", NULL, "relative|absolute", + "How to display percentage of filtered entries", parse_filter_percentage), OPT_END() }; static double baseline_percent(struct hist_entry *he) { - struct hists *hists = he->hists; - return 100.0 * he->stat.period / hists->stats.total_period; + u64 total = hists__total_period(he->hists); + + return 100.0 * he->stat.period / total; } static int hpp__color_baseline(struct perf_hpp_fmt *fmt, -- cgit v1.2.3-70-g09d2 From 0b93da1756df4fe930ee0220a6addce263a6e0ab Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Tue, 14 Jan 2014 12:02:15 +0900 Subject: perf tools: Add hist.percentage config option Add hist.percentage option for setting default value of the symbol_conf.filter_relative. It affects the output of various perf commands (like perf report, top and diff) only if filter(s) applied. An user can write .perfconfig file like below to show absolute percentage of filtered entries by default: $ cat ~/.perfconfig [hist] percentage = absolute And it can be changed through command line: $ perf report --percentage relative Signed-off-by: Namhyung Kim Link: http://lkml.kernel.org/r/1397145720-8063-6-git-send-email-namhyung@kernel.org Signed-off-by: Jiri Olsa --- tools/perf/builtin-diff.c | 2 ++ tools/perf/util/config.c | 4 ++++ tools/perf/util/hist.c | 8 ++++++++ tools/perf/util/hist.h | 1 + 4 files changed, 15 insertions(+) diff --git a/tools/perf/builtin-diff.c b/tools/perf/builtin-diff.c index c903fe13c17..6ef80f22c1e 100644 --- a/tools/perf/builtin-diff.c +++ b/tools/perf/builtin-diff.c @@ -1134,6 +1134,8 @@ static int data_init(int argc, const char **argv) int cmd_diff(int argc, const char **argv, const char *prefix __maybe_unused) { + perf_config(perf_default_config, NULL); + sort_order = diff__default_sort_order; argc = parse_options(argc, argv, options, diff_usage, 0); diff --git a/tools/perf/util/config.c b/tools/perf/util/config.c index 3e0fdd369cc..24519e14ac5 100644 --- a/tools/perf/util/config.c +++ b/tools/perf/util/config.c @@ -11,6 +11,7 @@ #include "util.h" #include "cache.h" #include "exec_cmd.h" +#include "util/hist.h" /* perf_hist_config */ #define MAXNAME (256) @@ -355,6 +356,9 @@ int perf_default_config(const char *var, const char *value, if (!prefixcmp(var, "core.")) return perf_default_core_config(var, value); + if (!prefixcmp(var, "hist.")) + return perf_hist_config(var, value); + /* Add other config variables here. */ return 0; } diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c index 3c2dd233b98..5a892477aa5 100644 --- a/tools/perf/util/hist.c +++ b/tools/perf/util/hist.c @@ -956,3 +956,11 @@ int parse_filter_percentage(const struct option *opt __maybe_unused, return 0; } + +int perf_hist_config(const char *var, const char *value) +{ + if (!strcmp(var, "hist.percentage")) + return parse_filter_percentage(NULL, value, 0); + + return 0; +} diff --git a/tools/perf/util/hist.h b/tools/perf/util/hist.h index a4ec336ae3f..5a0343eb22e 100644 --- a/tools/perf/util/hist.h +++ b/tools/perf/util/hist.h @@ -258,5 +258,6 @@ unsigned int hists__sort_list_width(struct hists *hists); struct option; int parse_filter_percentage(const struct option *opt __maybe_unused, const char *arg, int unset __maybe_unused); +int perf_hist_config(const char *var, const char *value); #endif /* __PERF_HIST_H */ -- cgit v1.2.3-70-g09d2 From 105eb30f18197a217695eac4ddf87526f2cba867 Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Mon, 10 Feb 2014 11:20:10 +0900 Subject: perf ui/tui: Add 'F' hotkey to toggle percentage output Add 'F' hotkey to toggle relative and absolute percentage of filtered entries. Suggested-by: Jiri Olsa Signed-off-by: Namhyung Kim Link: http://lkml.kernel.org/r/1397145720-8063-7-git-send-email-namhyung@kernel.org Signed-off-by: Jiri Olsa --- tools/perf/ui/browsers/hists.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tools/perf/ui/browsers/hists.c b/tools/perf/ui/browsers/hists.c index 7ad11477a0f..4d416984c59 100644 --- a/tools/perf/ui/browsers/hists.c +++ b/tools/perf/ui/browsers/hists.c @@ -1389,6 +1389,7 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events, "C Collapse all callchains\n" \ "d Zoom into current DSO\n" \ "E Expand all callchains\n" \ + "F Toggle percentage of filtered entries\n" \ /* help messages are sorted by lexical order of the hotkey */ const char report_help[] = HIST_BROWSER_HELP_COMMON @@ -1494,6 +1495,9 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events, if (env->arch) tui__header_window(env); continue; + case 'F': + symbol_conf.filter_relative ^= 1; + continue; case K_F1: case 'h': case '?': -- cgit v1.2.3-70-g09d2 From 95ce0ba17d5a0a04bbad61720512381d8165d157 Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Tue, 14 Jan 2014 12:05:27 +0900 Subject: perf tools: Show absolute percentage by default Now perf report will show absolute percentage on filter entries by default. Suggested-by: Jiri Olsa Signed-off-by: Namhyung Kim Link: http://lkml.kernel.org/r/1397145720-8063-8-git-send-email-namhyung@kernel.org Signed-off-by: Jiri Olsa --- tools/perf/util/symbol.c | 1 - 1 file changed, 1 deletion(-) diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c index b2eca6c17a7..95e24977993 100644 --- a/tools/perf/util/symbol.c +++ b/tools/perf/util/symbol.c @@ -33,7 +33,6 @@ struct symbol_conf symbol_conf = { .try_vmlinux_path = true, .annotate_src = true, .demangle = true, - .filter_relative = true, .symfs = "", }; -- cgit v1.2.3-70-g09d2 From 3bca23543b910a84d3c58a819663e0a4fad72bb6 Mon Sep 17 00:00:00 2001 From: Ramkumar Ramachandra Date: Fri, 14 Mar 2014 23:17:51 -0400 Subject: perf kmem: Introduce --list-cmds for use by scripts Signed-off-by: Ramkumar Ramachandra Acked-by: David Ahern Cc: Jiri Olsa Link: http://lkml.kernel.org/r/1394853474-31019-2-git-send-email-artagnon@gmail.com Signed-off-by: Arnaldo Carvalho de Melo Signed-off-by: Jiri Olsa --- tools/perf/builtin-kmem.c | 8 +++++--- tools/perf/perf-completion.sh | 4 ++-- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/tools/perf/builtin-kmem.c b/tools/perf/builtin-kmem.c index 929462aa494..bd91de07d2a 100644 --- a/tools/perf/builtin-kmem.c +++ b/tools/perf/builtin-kmem.c @@ -756,11 +756,13 @@ int cmd_kmem(int argc, const char **argv, const char *prefix __maybe_unused) OPT_BOOLEAN(0, "raw-ip", &raw_ip, "show raw ip instead of symbol"), OPT_END() }; - const char * const kmem_usage[] = { - "perf kmem [] {record|stat}", + const char *const kmem_subcommands[] = { "record", "stat", NULL }; + const char *kmem_usage[] = { + NULL, NULL }; - argc = parse_options(argc, argv, kmem_options, kmem_usage, 0); + argc = parse_options_subcommand(argc, argv, kmem_options, + kmem_subcommands, kmem_usage, 0); if (!argc) usage_with_options(kmem_usage, kmem_options); diff --git a/tools/perf/perf-completion.sh b/tools/perf/perf-completion.sh index ae3a57694b6..0ef59dd4c78 100644 --- a/tools/perf/perf-completion.sh +++ b/tools/perf/perf-completion.sh @@ -121,8 +121,8 @@ __perf_main () elif [[ $prev == "-e" && "${words[1]}" == @(record|stat|top) ]]; then evts=$($cmd list --raw-dump) __perfcomp_colon "$evts" "$cur" - # List subcommands for 'perf kvm' - elif [[ $prev == "kvm" ]]; then + # List subcommands for perf commands + elif [[ $prev == @(kvm|kmem) ]]; then subcmds=$($cmd $prev --list-cmds) __perfcomp_colon "$subcmds" "$cur" # List long option names -- cgit v1.2.3-70-g09d2 From 8d2a2a1d885d36e978c4619a3db8791f9768dd6a Mon Sep 17 00:00:00 2001 From: Ramkumar Ramachandra Date: Fri, 14 Mar 2014 23:17:52 -0400 Subject: perf mem: Introduce --list-cmds for use by scripts Signed-off-by: Ramkumar Ramachandra Acked-by: David Ahern Cc: David Ahern Cc: Jiri Olsa Link: http://lkml.kernel.org/r/1394853474-31019-3-git-send-email-artagnon@gmail.com Signed-off-by: Arnaldo Carvalho de Melo Signed-off-by: Jiri Olsa --- tools/perf/builtin-mem.c | 15 ++++++++------- tools/perf/perf-completion.sh | 2 +- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/tools/perf/builtin-mem.c b/tools/perf/builtin-mem.c index 2e3ade69a58..4a1a6c94a5e 100644 --- a/tools/perf/builtin-mem.c +++ b/tools/perf/builtin-mem.c @@ -21,11 +21,6 @@ struct perf_mem { DECLARE_BITMAP(cpu_bitmap, MAX_NR_CPUS); }; -static const char * const mem_usage[] = { - "perf mem [] {record |report}", - NULL -}; - static int __cmd_record(int argc, const char **argv) { int rec_argc, i = 0, j; @@ -220,9 +215,15 @@ int cmd_mem(int argc, const char **argv, const char *prefix __maybe_unused) " between columns '.' is reserved."), OPT_END() }; + const char *const mem_subcommands[] = { "record", "report", NULL }; + const char *mem_usage[] = { + NULL, + NULL + }; + - argc = parse_options(argc, argv, mem_options, mem_usage, - PARSE_OPT_STOP_AT_NON_OPTION); + argc = parse_options_subcommand(argc, argv, mem_options, mem_subcommands, + mem_usage, PARSE_OPT_STOP_AT_NON_OPTION); if (!argc || !(strncmp(argv[0], "rec", 3) || mem_operation)) usage_with_options(mem_usage, mem_options); diff --git a/tools/perf/perf-completion.sh b/tools/perf/perf-completion.sh index 0ef59dd4c78..f44c04b1015 100644 --- a/tools/perf/perf-completion.sh +++ b/tools/perf/perf-completion.sh @@ -122,7 +122,7 @@ __perf_main () evts=$($cmd list --raw-dump) __perfcomp_colon "$evts" "$cur" # List subcommands for perf commands - elif [[ $prev == @(kvm|kmem) ]]; then + elif [[ $prev == @(kvm|kmem|mem) ]]; then subcmds=$($cmd $prev --list-cmds) __perfcomp_colon "$subcmds" "$cur" # List long option names -- cgit v1.2.3-70-g09d2 From a2368c3199eba493d72c6d0e5b804f908a09706c Mon Sep 17 00:00:00 2001 From: Ramkumar Ramachandra Date: Fri, 14 Mar 2014 23:17:53 -0400 Subject: perf lock: Introduce --list-cmds for use by scripts Signed-off-by: Ramkumar Ramachandra Acked-by: David Ahern Cc: David Ahern Cc: Jiri Olsa Link: http://lkml.kernel.org/r/1394853474-31019-4-git-send-email-artagnon@gmail.com Signed-off-by: Arnaldo Carvalho de Melo Signed-off-by: Jiri Olsa --- tools/perf/builtin-lock.c | 10 ++++++---- tools/perf/perf-completion.sh | 2 +- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/tools/perf/builtin-lock.c b/tools/perf/builtin-lock.c index c852c7a85d3..6148afc995c 100644 --- a/tools/perf/builtin-lock.c +++ b/tools/perf/builtin-lock.c @@ -961,8 +961,10 @@ int cmd_lock(int argc, const char **argv, const char *prefix __maybe_unused) "perf lock info []", NULL }; - const char * const lock_usage[] = { - "perf lock [] {record|report|script|info}", + const char *const lock_subcommands[] = { "record", "report", "script", + "info", NULL }; + const char *lock_usage[] = { + NULL, NULL }; const char * const report_usage[] = { @@ -976,8 +978,8 @@ int cmd_lock(int argc, const char **argv, const char *prefix __maybe_unused) for (i = 0; i < LOCKHASH_SIZE; i++) INIT_LIST_HEAD(lockhash_table + i); - argc = parse_options(argc, argv, lock_options, lock_usage, - PARSE_OPT_STOP_AT_NON_OPTION); + argc = parse_options_subcommand(argc, argv, lock_options, lock_subcommands, + lock_usage, PARSE_OPT_STOP_AT_NON_OPTION); if (!argc) usage_with_options(lock_usage, lock_options); diff --git a/tools/perf/perf-completion.sh b/tools/perf/perf-completion.sh index f44c04b1015..ecedab6524e 100644 --- a/tools/perf/perf-completion.sh +++ b/tools/perf/perf-completion.sh @@ -122,7 +122,7 @@ __perf_main () evts=$($cmd list --raw-dump) __perfcomp_colon "$evts" "$cur" # List subcommands for perf commands - elif [[ $prev == @(kvm|kmem|mem) ]]; then + elif [[ $prev == @(kvm|kmem|mem|lock) ]]; then subcmds=$($cmd $prev --list-cmds) __perfcomp_colon "$subcmds" "$cur" # List long option names -- cgit v1.2.3-70-g09d2 From a83edb2dfc5989fbadc594109c933bae528a2809 Mon Sep 17 00:00:00 2001 From: Ramkumar Ramachandra Date: Fri, 14 Mar 2014 23:17:54 -0400 Subject: perf sched: Introduce --list-cmds for use by scripts Signed-off-by: Ramkumar Ramachandra Acked-by: David Ahern Cc: David Ahern Cc: Jiri Olsa Link: http://lkml.kernel.org/r/1394853474-31019-5-git-send-email-artagnon@gmail.com Signed-off-by: Arnaldo Carvalho de Melo Signed-off-by: Jiri Olsa --- tools/perf/builtin-sched.c | 10 ++++++---- tools/perf/perf-completion.sh | 2 +- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/tools/perf/builtin-sched.c b/tools/perf/builtin-sched.c index 9ac0a495c95..d3fb0ed7240 100644 --- a/tools/perf/builtin-sched.c +++ b/tools/perf/builtin-sched.c @@ -1713,8 +1713,10 @@ int cmd_sched(int argc, const char **argv, const char *prefix __maybe_unused) "perf sched replay []", NULL }; - const char * const sched_usage[] = { - "perf sched [] {record|latency|map|replay|script}", + const char *const sched_subcommands[] = { "record", "latency", "map", + "replay", "script", NULL }; + const char *sched_usage[] = { + NULL, NULL }; struct trace_sched_handler lat_ops = { @@ -1736,8 +1738,8 @@ int cmd_sched(int argc, const char **argv, const char *prefix __maybe_unused) for (i = 0; i < ARRAY_SIZE(sched.curr_pid); i++) sched.curr_pid[i] = -1; - argc = parse_options(argc, argv, sched_options, sched_usage, - PARSE_OPT_STOP_AT_NON_OPTION); + argc = parse_options_subcommand(argc, argv, sched_options, sched_subcommands, + sched_usage, PARSE_OPT_STOP_AT_NON_OPTION); if (!argc) usage_with_options(sched_usage, sched_options); diff --git a/tools/perf/perf-completion.sh b/tools/perf/perf-completion.sh index ecedab6524e..33569847fdc 100644 --- a/tools/perf/perf-completion.sh +++ b/tools/perf/perf-completion.sh @@ -122,7 +122,7 @@ __perf_main () evts=$($cmd list --raw-dump) __perfcomp_colon "$evts" "$cur" # List subcommands for perf commands - elif [[ $prev == @(kvm|kmem|mem|lock) ]]; then + elif [[ $prev == @(kvm|kmem|mem|lock|sched) ]]; then subcmds=$($cmd $prev --list-cmds) __perfcomp_colon "$subcmds" "$cur" # List long option names -- cgit v1.2.3-70-g09d2