Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1758187AbbKSOd7 (ORCPT ); Thu, 19 Nov 2015 09:33:59 -0500 Received: from mail.kernel.org ([198.145.29.136]:55098 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1755152AbbKSOd5 (ORCPT ); Thu, 19 Nov 2015 09:33:57 -0500 Date: Thu, 19 Nov 2015 11:33:52 -0300 From: Arnaldo Carvalho de Melo To: Namhyung Kim Cc: Ingo Molnar , Peter Zijlstra , Jiri Olsa , LKML , Brendan Gregg , David Ahern , Frederic Weisbecker , Andi Kleen , Kan Liang Subject: Re: [PATCH] perf report: [WIP] Support '-F none' option to hide hist lines Message-ID: <20151119143352.GD29361@kernel.org> References: <1447047946-1691-1-git-send-email-namhyung@kernel.org> <1447047946-1691-3-git-send-email-namhyung@kernel.org> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <1447047946-1691-3-git-send-email-namhyung@kernel.org> X-Url: http://acmel.wordpress.com User-Agent: Mutt/1.5.23 (2014-03-12) Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 12015 Lines: 343 Em Mon, Nov 09, 2015 at 02:45:38PM +0900, Namhyung Kim escreveu: > For some reason, it sometimes wants to hide hist lines but only wants to > see callchains. To do that, add virtual 'none' field name to hide all > hist lines. It should be used solely and only meaningful on --stdio. > > WIP on TUI So, in the TUI its the navigation that doesnt work, i.e. it manages to elide the hist_entry main lines, shows the folded callchains, but the keys don't work... I'll try it if you don't, just busy with processing tons of patches at the moment :-\ Anyway, processed the other patches, pushing to Ingo for perf/core, to avoid patchbombing him too much in just one go :-) - Arnaldo > Cc: Brendan Gregg > Signed-off-by: Namhyung Kim > --- > tools/perf/Documentation/perf-report.txt | 3 ++ > tools/perf/ui/browsers/hists.c | 22 +++++++++-- > tools/perf/ui/gtk/hists.c | 65 ++++++++++++++++++++++++-------- > tools/perf/ui/stdio/hist.c | 5 +++ > tools/perf/util/sort.c | 5 +++ > 5 files changed, 82 insertions(+), 18 deletions(-) > > diff --git a/tools/perf/Documentation/perf-report.txt b/tools/perf/Documentation/perf-report.txt > index dab99ed2b339..6cfc643c0806 100644 > --- a/tools/perf/Documentation/perf-report.txt > +++ b/tools/perf/Documentation/perf-report.txt > @@ -127,6 +127,9 @@ OPTIONS > By default, every sort keys not specified in -F will be appended > automatically. > > + If "none" is specified, it hides all fields and --stdio output will show > + callchains only. > + > If --mem-mode option is used, following sort keys are also available > (incompatible with --branch-stack): > symbol_daddr, dso_daddr, locked, tlb, mem, snoop, dcacheline. > diff --git a/tools/perf/ui/browsers/hists.c b/tools/perf/ui/browsers/hists.c > index 3efe7c74f47d..c2f586f0c729 100644 > --- a/tools/perf/ui/browsers/hists.c > +++ b/tools/perf/ui/browsers/hists.c > @@ -78,6 +78,9 @@ static u32 hist_browser__nr_entries(struct hist_browser *hb) > nr_entries = hb->hists->nr_entries; > > hb->nr_callchain_rows = hist_browser__get_folding(hb); > + > + if (list_empty(&perf_hpp__list)) > + nr_entries = 1; > return nr_entries + hb->nr_callchain_rows; > } > > @@ -255,7 +258,10 @@ static bool hist_entry__toggle_fold(struct hist_entry *he) > if (!he->has_children) > return false; > > - he->unfolded = !he->unfolded; > + if (list_empty(&perf_hpp__list)) > + he->unfolded = true; > + else > + he->unfolded = !he->unfolded; > return true; > } > > @@ -329,6 +335,10 @@ static void hist_entry__init_have_children(struct hist_entry *he) > if (!he->init_have_children) { > he->has_children = !RB_EMPTY_ROOT(&he->sorted_chain); > callchain__init_have_children(&he->sorted_chain); > + if (list_empty(&perf_hpp__list)) { > + he->unfolded = true; > + he->nr_rows = callchain__count_rows(&he->sorted_chain); > + } > he->init_have_children = true; > } > } > @@ -1038,6 +1048,9 @@ static int hist_browser__show_entry(struct hist_browser *browser, > > hist_browser__gotorc(browser, row, 0); > > + if (list_empty(&perf_hpp__list)) > + goto print_callchain; > + > perf_hpp__for_each_format(fmt) { > if (perf_hpp__should_skip(fmt) || column++ < browser->b.horiz_scroll) > continue; > @@ -1080,6 +1093,7 @@ static int hist_browser__show_entry(struct hist_browser *browser, > } else > --row_offset; > > +print_callchain: > if (folded_sign == '-' && row != browser->b.rows) { > u64 total = hists__total_period(entry->hists); > struct callchain_print_arg arg = { > @@ -1313,7 +1327,8 @@ static void ui_browser__hists_seek(struct ui_browser *browser, > nd = hists__filter_entries(rb_next(nd), hb->min_pcnt); > if (nd == NULL) > break; > - --offset; > + if (!list_empty(&perf_hpp__list)) > + --offset; > browser->top = nd; > } while (offset != 0); > } else if (offset < 0) { > @@ -1347,7 +1362,8 @@ static void ui_browser__hists_seek(struct ui_browser *browser, > hb->min_pcnt); > if (nd == NULL) > break; > - ++offset; > + if (!list_empty(&perf_hpp__list)) > + ++offset; > browser->top = nd; > if (offset == 0) { > /* > diff --git a/tools/perf/ui/gtk/hists.c b/tools/perf/ui/gtk/hists.c > index 6105b4921754..535f8c5e74dc 100644 > --- a/tools/perf/ui/gtk/hists.c > +++ b/tools/perf/ui/gtk/hists.c > @@ -98,12 +98,12 @@ static void perf_gtk__add_callchain_flat(struct rb_root *root, GtkTreeStore *sto > for (nd = rb_first(root); nd; nd = rb_next(nd)) { > struct callchain_node *node; > struct callchain_list *chain; > - GtkTreeIter iter, new_parent; > + GtkTreeIter iter, new_parent_iter, *new_parent; > bool need_new_parent; > > node = rb_entry(nd, struct callchain_node, rb_node); > > - new_parent = *parent; > + new_parent = parent; > need_new_parent = !has_single_node; > > callchain_node__make_parent_list(node); > @@ -111,7 +111,7 @@ static void perf_gtk__add_callchain_flat(struct rb_root *root, GtkTreeStore *sto > list_for_each_entry(chain, &node->parent_val, list) { > char buf[128]; > > - gtk_tree_store_append(store, &iter, &new_parent); > + gtk_tree_store_append(store, &iter, new_parent); > > callchain_node__sprintf_value(node, buf, sizeof(buf), total); > gtk_tree_store_set(store, &iter, 0, buf, -1); > @@ -124,7 +124,8 @@ static void perf_gtk__add_callchain_flat(struct rb_root *root, GtkTreeStore *sto > * Only show the top-most symbol in a callchain > * if it's not the only callchain. > */ > - new_parent = iter; > + new_parent_iter = iter; > + new_parent = &new_parent_iter; > need_new_parent = false; > } > } > @@ -132,7 +133,7 @@ static void perf_gtk__add_callchain_flat(struct rb_root *root, GtkTreeStore *sto > list_for_each_entry(chain, &node->val, list) { > char buf[128]; > > - gtk_tree_store_append(store, &iter, &new_parent); > + gtk_tree_store_append(store, &iter, new_parent); > > callchain_node__sprintf_value(node, buf, sizeof(buf), total); > gtk_tree_store_set(store, &iter, 0, buf, -1); > @@ -145,7 +146,8 @@ static void perf_gtk__add_callchain_flat(struct rb_root *root, GtkTreeStore *sto > * Only show the top-most symbol in a callchain > * if it's not the only callchain. > */ > - new_parent = iter; > + new_parent_iter = iter; > + new_parent = &new_parent_iter; > need_new_parent = false; > } > } > @@ -221,19 +223,19 @@ static void perf_gtk__add_callchain_graph(struct rb_root *root, GtkTreeStore *st > for (nd = rb_first(root); nd; nd = rb_next(nd)) { > struct callchain_node *node; > struct callchain_list *chain; > - GtkTreeIter iter, new_parent; > + GtkTreeIter iter, new_parent_iter, *new_parent; > bool need_new_parent; > u64 child_total; > > node = rb_entry(nd, struct callchain_node, rb_node); > > - new_parent = *parent; > + new_parent = parent; > need_new_parent = !has_single_node && (node->val_nr > 1); > > list_for_each_entry(chain, &node->val, list) { > char buf[128]; > > - gtk_tree_store_append(store, &iter, &new_parent); > + gtk_tree_store_append(store, &iter, new_parent); > > callchain_node__sprintf_value(node, buf, sizeof(buf), total); > gtk_tree_store_set(store, &iter, 0, buf, -1); > @@ -246,7 +248,8 @@ static void perf_gtk__add_callchain_graph(struct rb_root *root, GtkTreeStore *st > * Only show the top-most symbol in a callchain > * if it's not the only callchain. > */ > - new_parent = iter; > + new_parent_iter = iter; > + new_parent = &new_parent_iter; > need_new_parent = false; > } > } > @@ -292,12 +295,14 @@ static void perf_gtk__show_hists(GtkWidget *window, struct hists *hists, > GType col_types[MAX_COLUMNS]; > GtkCellRenderer *renderer; > GtkTreeStore *store; > + GtkTreeIter *iter; > struct rb_node *nd; > GtkWidget *view; > int col_idx; > int sym_col = -1; > int nr_cols; > char s[512]; > + bool no_hists = false; > > struct perf_hpp hpp = { > .buf = s, > @@ -309,6 +314,18 @@ static void perf_gtk__show_hists(GtkWidget *window, struct hists *hists, > perf_hpp__for_each_format(fmt) > col_types[nr_cols++] = G_TYPE_STRING; > > + if (nr_cols == 0) { > + /* > + * user specified '-F none' to ignore hist entries. > + * Add two columns to print callchain value and symbols. > + */ > + no_hists = true; > + > + nr_cols = 2; > + col_types[0] = G_TYPE_STRING; > + col_types[1] = G_TYPE_STRING; > + } > + > store = gtk_tree_store_newv(nr_cols, col_types); > > view = gtk_tree_view_new(); > @@ -334,6 +351,18 @@ static void perf_gtk__show_hists(GtkWidget *window, struct hists *hists, > col_idx++, NULL); > } > > + if (no_hists) { > + sym_col = 1; > + gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(view), > + -1, "Overhead", > + renderer, "markup", > + 0, NULL); > + gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(view), > + -1, "Callchains", > + renderer, "markup", > + 1, NULL); > + } > + > for (col_idx = 0; col_idx < nr_cols; col_idx++) { > GtkTreeViewColumn *column; > > @@ -352,7 +381,7 @@ 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; > + GtkTreeIter this_iter; > u64 total = hists__total_period(h->hists); > float percent; > > @@ -363,7 +392,13 @@ static void perf_gtk__show_hists(GtkWidget *window, struct hists *hists, > if (percent < min_pcnt) > continue; > > - gtk_tree_store_append(store, &iter, NULL); > + if (no_hists) { > + /* NULL means that callchains are in top-level */ > + iter = NULL; > + } else { > + iter = &this_iter; > + gtk_tree_store_append(store, iter, NULL); > + } > > col_idx = 0; > > @@ -376,15 +411,15 @@ static void perf_gtk__show_hists(GtkWidget *window, struct hists *hists, > else > fmt->entry(fmt, &hpp, h); > > - gtk_tree_store_set(store, &iter, col_idx++, s, -1); > + gtk_tree_store_set(store, iter, col_idx++, s, -1); > } > > - if (symbol_conf.use_callchain && sort__has_sym) { > + if (symbol_conf.use_callchain) { > if (callchain_param.mode == CHAIN_GRAPH_REL) > total = symbol_conf.cumulate_callchain ? > h->stat_acc->period : h->stat.period; > > - perf_gtk__add_callchain(&h->sorted_chain, store, &iter, > + perf_gtk__add_callchain(&h->sorted_chain, store, iter, > sym_col, total); > } > } > diff --git a/tools/perf/ui/stdio/hist.c b/tools/perf/ui/stdio/hist.c > index 7ebc661be267..48ae34abf9c8 100644 > --- a/tools/perf/ui/stdio/hist.c > +++ b/tools/perf/ui/stdio/hist.c > @@ -422,6 +422,11 @@ static int hist_entry__fprintf(struct hist_entry *he, size_t size, > if (size == 0 || size > bfsz) > size = hpp.size = bfsz; > > + /* > + * In case of '-F none', the bf is not set at all. > + */ > + bf[0] = '\0'; > + > hist_entry__snprintf(he, &hpp); > > ret = fprintf(fp, "%s\n", bf); > diff --git a/tools/perf/util/sort.c b/tools/perf/util/sort.c > index 2d8ccd4d9e1b..8c731906d432 100644 > --- a/tools/perf/util/sort.c > +++ b/tools/perf/util/sort.c > @@ -1923,6 +1923,11 @@ static int __setup_output_field(void) > if (field_order == NULL) > return 0; > > + if (!strcmp(field_order, "none")) { > + symbol_conf.show_hist_headers = false; > + return 0; > + } > + > strp = str = strdup(field_order); > if (str == NULL) { > error("Not enough memory to setup output fields"); > -- > 2.6.2 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/