Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > linux.kernel > #1310972 > unrolled thread

[RFC/PATCHSET 00/17] perf tools: Add support for hierachy view (v2)

Started byNamhyung Kim <namhyung@kernel.org>
First post2016-01-16 17:10 +0100
Last post2016-01-20 01:20 +0100
Articles 20 on this page of 77 — 6 participants

Back to article view | Back to linux.kernel


Contents

  [RFC/PATCHSET 00/17] perf tools: Add support for hierachy view (v2) Namhyung Kim <namhyung@kernel.org> - 2016-01-16 17:10 +0100
    [PATCH 16/17] perf hists: Support decaying in hierarchy mode Namhyung Kim <namhyung@kernel.org> - 2016-01-16 17:10 +0100
    [PATCH 13/17] perf hists browser: Align column header in hierarchy mode Namhyung Kim <namhyung@kernel.org> - 2016-01-16 17:10 +0100
    [PATCH 15/17] perf report: Add --hierarchy option Namhyung Kim <namhyung@kernel.org> - 2016-01-16 17:10 +0100
    [PATCH 01/17] perf hists: Basic support of hierarchical report view Namhyung Kim <namhyung@kernel.org> - 2016-01-16 17:10 +0100
      Re: [PATCH 01/17] perf hists: Basic support of hierarchical report  view Jiri Olsa <jolsa@redhat.com> - 2016-01-17 17:20 +0100
        Re: [PATCH 01/17] perf hists: Basic support of hierarchical report  view Namhyung Kim <namhyung@kernel.org> - 2016-01-19 12:00 +0100
          Re: [PATCH 01/17] perf hists: Basic support of hierarchical report  view Arnaldo Carvalho de Melo <acme@kernel.org> - 2016-01-19 18:00 +0100
            Re: [PATCH 01/17] perf hists: Basic support of hierarchical report  view Jiri Olsa <jolsa@redhat.com> - 2016-01-20 18:10 +0100
              Re: [PATCH 01/17] perf hists: Basic support of hierarchical report  view Arnaldo Carvalho de Melo <acme@kernel.org> - 2016-01-20 18:20 +0100
              Re: [PATCH 01/17] perf hists: Basic support of hierarchical report  view Namhyung Kim <namhyung@kernel.org> - 2016-01-21 05:10 +0100
      Re: [PATCH 01/17] perf hists: Basic support of hierarchical report  view Jiri Olsa <jolsa@redhat.com> - 2016-01-21 11:50 +0100
        Re: [PATCH 01/17] perf hists: Basic support of hierarchical report  view Namhyung Kim <namhyung@kernel.org> - 2016-01-21 14:00 +0100
          Re: [PATCH 01/17] perf hists: Basic support of hierarchical report  view Jiri Olsa <jolsa@redhat.com> - 2016-01-21 14:40 +0100
            Re: [PATCH 01/17] perf hists: Basic support of hierarchical report  view Arnaldo Carvalho de Melo <acme@kernel.org> - 2016-01-21 15:10 +0100
              Re: [PATCH 01/17] perf hists: Basic support of hierarchical report  view Namhyung Kim <namhyung@kernel.org> - 2016-01-22 11:50 +0100
            Re: [PATCH 01/17] perf hists: Basic support of hierarchical report  view Namhyung Kim <namhyung@kernel.org> - 2016-01-22 11:50 +0100
              Re: [PATCH 01/17] perf hists: Basic support of hierarchical report  view Jiri Olsa <jolsa@redhat.com> - 2016-01-22 12:40 +0100
      Re: [PATCH 01/17] perf hists: Basic support of hierarchical report  view Jiri Olsa <jolsa@redhat.com> - 2016-01-21 12:40 +0100
        Re: [PATCH 01/17] perf hists: Basic support of hierarchical report  view Namhyung Kim <namhyung@kernel.org> - 2016-01-21 14:10 +0100
    [PATCH 08/17] perf hists browser: Fix context menu item Namhyung Kim <namhyung@kernel.org> - 2016-01-16 17:10 +0100
      Re: [PATCH 08/17] perf hists browser: Fix context menu item Arnaldo Carvalho de Melo <acme@kernel.org> - 2016-01-21 02:00 +0100
        Re: [PATCH 08/17] perf hists browser: Fix context menu item Namhyung Kim <namhyung@kernel.org> - 2016-01-21 05:10 +0100
          Re: [PATCH 08/17] perf hists browser: Fix context menu item Arnaldo Carvalho de Melo <acme@kernel.org> - 2016-01-22 01:00 +0100
            Re: [PATCH 08/17] perf hists browser: Fix context menu item Namhyung Kim <namhyung@kernel.org> - 2016-01-22 12:10 +0100
      Dynamicly add/remove sort keys was: Re: [PATCH 08/17] perf hists  browser: Fix context menu item Arnaldo Carvalho de Melo <acme@kernel.org> - 2016-01-22 15:40 +0100
    [PATCH 04/17] perf hists: Cleanup filtering functions Namhyung Kim <namhyung@kernel.org> - 2016-01-16 17:10 +0100
      Re: [PATCH 04/17] perf hists: Cleanup filtering functions Arnaldo Carvalho de Melo <acme@kernel.org> - 2016-01-19 21:40 +0100
        [PATCH v2 04.1/17] perf hists: Remove parent filter check in DSO filter function Namhyung Kim <namhyung@kernel.org> - 2016-01-20 02:30 +0100
          [PATCH v2 04.2/17] perf hists: Cleanup filtering functions Namhyung Kim <namhyung@kernel.org> - 2016-01-20 02:30 +0100
            Re: [PATCH v2 04.2/17] perf hists: Cleanup filtering functions Jiri Olsa <jolsa@redhat.com> - 2016-01-21 13:10 +0100
          Re: [PATCH v2 04.1/17] perf hists: Remove parent filter check in DSO  filter function Jiri Olsa <jolsa@redhat.com> - 2016-01-21 13:10 +0100
    [PATCH 02/17] perf hists: Resort hist entries with hierarchy Namhyung Kim <namhyung@kernel.org> - 2016-01-16 17:10 +0100
      Re: [PATCH 02/17] perf hists: Resort hist entries with hierarchy Jiri Olsa <jolsa@redhat.com> - 2016-01-21 12:50 +0100
        Re: [PATCH 02/17] perf hists: Resort hist entries with hierarchy Namhyung Kim <namhyung@kernel.org> - 2016-01-21 14:10 +0100
    [PATCH 10/17] perf hists browser: Support collapsing/expanding whole entries in hierarchy Namhyung Kim <namhyung@kernel.org> - 2016-01-16 17:10 +0100
    [PATCH 07/17] perf ui/stdio: Align column header for hierarchy output Namhyung Kim <namhyung@kernel.org> - 2016-01-16 17:10 +0100
      Re: [PATCH 07/17] perf ui/stdio: Align column header for hierarchy  output Arnaldo Carvalho de Melo <acme@kernel.org> - 2016-01-20 23:50 +0100
        Re: [PATCH 07/17] perf ui/stdio: Align column header for hierarchy  output Namhyung Kim <namhyung@kernel.org> - 2016-01-21 05:10 +0100
    [PATCH 12/17] perf hists browser: Implement hierarchy output Namhyung Kim <namhyung@kernel.org> - 2016-01-16 17:10 +0100
    [PATCH 05/17] perf hists: Support filtering in hierarchy mode Namhyung Kim <namhyung@kernel.org> - 2016-01-16 17:10 +0100
    [PATCH 11/17] perf hists browser: Factor out hist_browser__show_callchain() Namhyung Kim <namhyung@kernel.org> - 2016-01-16 17:10 +0100
    [PATCH 06/17] perf ui/stdio: Implement hierarchy output mode Namhyung Kim <namhyung@kernel.org> - 2016-01-16 17:10 +0100
    [PATCH 03/17] perf hists: Add helper functions for hierarchy mode Namhyung Kim <namhyung@kernel.org> - 2016-01-16 17:10 +0100
      Re: [PATCH 03/17] perf hists: Add helper functions for hierarchy mode Arnaldo Carvalho de Melo <acme@kernel.org> - 2016-01-20 23:20 +0100
        Re: [PATCH 03/17] perf hists: Add helper functions for hierarchy mode Namhyung Kim <namhyung@kernel.org> - 2016-01-21 05:00 +0100
          [PATCH v2 03/17] perf hists: Add helper functions for hierarchy mode Namhyung Kim <namhyung@kernel.org> - 2016-01-21 05:20 +0100
            Re: [PATCH v2 03/17] perf hists: Add helper functions for hierarchy  mode Namhyung Kim <namhyung@kernel.org> - 2016-01-21 14:10 +0100
    [PATCH 09/17] perf hists browser: Count number of hierarchy entries Namhyung Kim <namhyung@kernel.org> - 2016-01-16 17:10 +0100
    Re: [RFC/PATCHSET 00/17] perf tools: Add support for hierachy view (v2) Pekka Enberg <penberg@kernel.org> - 2016-01-17 11:30 +0100
      Re: [RFC/PATCHSET 00/17] perf tools: Add support for hierachy view  (v2) Namhyung Kim <namhyung@kernel.org> - 2016-01-19 11:50 +0100
    Re: [RFC/PATCHSET 00/17] perf tools: Add support for hierachy view  (v2) Andi Kleen <andi@firstfloor.org> - 2016-01-17 20:40 +0100
      Re: [RFC/PATCHSET 00/17] perf tools: Add support for hierachy view  (v2) Namhyung Kim <namhyung@kernel.org> - 2016-01-19 11:50 +0100
        Re: [RFC/PATCHSET 00/17] perf tools: Add support for hierachy view  (v2) Arnaldo Carvalho de Melo <acme@kernel.org> - 2016-01-19 22:10 +0100
          Re: [RFC/PATCHSET 00/17] perf tools: Add support for hierachy view  (v2) Arnaldo Carvalho de Melo <acme@kernel.org> - 2016-01-19 22:10 +0100
        Re: [RFC/PATCHSET 00/17] perf tools: Add support for hierachy view  (v2) Andi Kleen <andi@firstfloor.org> - 2016-01-19 23:20 +0100
          Re: [RFC/PATCHSET 00/17] perf tools: Add support for hierachy view  (v2) Arnaldo Carvalho de Melo <acme@kernel.org> - 2016-01-19 23:30 +0100
            Re: [RFC/PATCHSET 00/17] perf tools: Add support for hierachy view  (v2) Namhyung Kim <namhyung@kernel.org> - 2016-01-20 02:00 +0100
              Re: [RFC/PATCHSET 00/17] perf tools: Add support for hierachy view  (v2) Namhyung Kim <namhyung@kernel.org> - 2016-01-20 02:40 +0100
                Re: [RFC/PATCHSET 00/17] perf tools: Add support for hierachy view  (v2) Andi Kleen <andi@firstfloor.org> - 2016-01-20 02:50 +0100
              Re: [RFC/PATCHSET 00/17] perf tools: Add support for hierachy view  (v2) Andi Kleen <andi@firstfloor.org> - 2016-01-20 03:00 +0100
              Re: [RFC/PATCHSET 00/17] perf tools: Add support for hierachy view  (v2) Arnaldo Carvalho de Melo <acme@kernel.org> - 2016-01-20 14:40 +0100
    Re: [RFC/PATCHSET 00/17] perf tools: Add support for hierachy view  (v2) Arnaldo Carvalho de Melo <acme@kernel.org> - 2016-01-19 21:10 +0100
    Re: [RFC/PATCHSET 00/17] perf tools: Add support for hierachy view  (v2) Arnaldo Carvalho de Melo <acme@kernel.org> - 2016-01-19 22:00 +0100
      Re: [RFC/PATCHSET 00/17] perf tools: Add support for hierachy view  (v2) Namhyung Kim <namhyung@kernel.org> - 2016-01-20 01:40 +0100
        Re: [RFC/PATCHSET 00/17] perf tools: Add support for hierachy view  (v2) Andi Kleen <andi@firstfloor.org> - 2016-01-20 06:30 +0100
        Re: [RFC/PATCHSET 00/17] perf tools: Add support for hierachy view  (v2) Taeung Song <taeung.dev@gmail.com> - 2016-01-20 09:00 +0100
          Re: [RFC/PATCHSET 00/17] perf tools: Add support for hierachy view  (v2) Namhyung Kim <namhyung@kernel.org> - 2016-01-20 16:10 +0100
            Re: [RFC/PATCHSET 00/17] perf tools: Add support for hierachy view  (v2) Taeung Song <taeung.dev@gmail.com> - 2016-01-20 17:40 +0100
              Re: [RFC/PATCHSET 00/17] perf tools: Add support for hierachy view  (v2) Namhyung Kim <namhyung@kernel.org> - 2016-01-21 05:20 +0100
                Re: [RFC/PATCHSET 00/17] perf tools: Add support for hierachy view  (v2) Taeung Song <taeung.dev@gmail.com> - 2016-01-21 06:00 +0100
        Re: [RFC/PATCHSET 00/17] perf tools: Add support for hierachy view  (v2) Arnaldo Carvalho de Melo <acme@kernel.org> - 2016-01-20 14:40 +0100
          Re: [RFC/PATCHSET 00/17] perf tools: Add support for hierachy view  (v2) Namhyung Kim <namhyung@kernel.org> - 2016-01-20 16:10 +0100
            Re: [RFC/PATCHSET 00/17] perf tools: Add support for hierachy view  (v2) Arnaldo Carvalho de Melo <acme@kernel.org> - 2016-01-20 16:30 +0100
              Re: [RFC/PATCHSET 00/17] perf tools: Add support for hierachy view  (v2) Arnaldo Carvalho de Melo <acme@kernel.org> - 2016-01-20 16:30 +0100
    Re: [RFC/PATCHSET 00/17] perf tools: Add support for hierachy view  (v2) Arnaldo Carvalho de Melo <acme@kernel.org> - 2016-01-19 22:00 +0100
      Re: [RFC/PATCHSET 00/17] perf tools: Add support for hierachy view  (v2) Namhyung Kim <namhyung@kernel.org> - 2016-01-20 01:20 +0100

Page 3 of 4 — ← Prev page 1 2 [3] 4  Next page →


#1310984 — [PATCH 05/17] perf hists: Support filtering in hierarchy mode

FromNamhyung Kim <namhyung@kernel.org>
Date2016-01-16 17:10 +0100
Subject[PATCH 05/17] perf hists: Support filtering in hierarchy mode
Message-ID<qRBAo-6Ad-51@gated-at.bofh.it>
In reply to#1310972
The hists__filter_hierarchy() function implements filtering in hierarchy
mode.  Now struct perf_hpp_fmt has optional ->filter callback which is
called from this function.  The callback can return 3 kind of values.

A negative value means that it's not filtered by this type.  It marks
current entry as filtered tentatively so if a lower level entry removes
the filter it also removes the all parent so that we can find the entry
in the output.

Zero means it's filtered out by this type and positive value means it's
not filtered so it removes the filter.  In these cases, it moves to next
entry since lower level entry won't match by this type of filter
anymore.  Thus all children will be filtered or not together.

Signed-off-by: Namhyung Kim <namhyung@kernel.org>
---
 tools/perf/util/hist.c | 131 ++++++++++++++++++++++++++++++++++++++++++++++---
 tools/perf/util/hist.h |   2 +
 tools/perf/util/sort.c | 113 ++++++++++++++++++++++++++++++++++++++++++
 tools/perf/util/sort.h |   1 +
 4 files changed, 239 insertions(+), 8 deletions(-)

diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c
index 0790c053f65c..a0808f73e0d9 100644
--- a/tools/perf/util/hist.c
+++ b/tools/perf/util/hist.c
@@ -1444,6 +1444,27 @@ static void hists__remove_entry_filter(struct hists *hists, struct hist_entry *h
 				       enum hist_filter filter)
 {
 	h->filtered &= ~(1 << filter);
+
+	if (symbol_conf.report_hierarchy) {
+		struct hist_entry *parent = h->parent_he;
+
+		while (parent) {
+			he_stat__add_stat(&parent->stat, &h->stat);
+
+			parent->filtered &= ~(1 << filter);
+
+			if (parent->filtered)
+				goto next;
+
+			/* force fold unfiltered entry for simplicity */
+			parent->unfolded = false;
+			parent->row_offset = 0;
+			parent->nr_rows = 0;
+next:
+			parent = parent->parent_he;
+		}
+	}
+
 	if (h->filtered)
 		return;
 
@@ -1529,28 +1550,122 @@ static void hists__filter_by_type(struct hists *hists, int type, filter_fn_t fil
 	}
 }
 
+static void hists__filter_hierarchy(struct hists *hists, int type, const void *arg)
+{
+	struct rb_node *nd;
+	struct rb_root tmp = RB_ROOT;
+	bool saved_unfolded;
+
+	hists->stats.nr_non_filtered_samples = 0;
+
+	hists__reset_filter_stats(hists);
+	hists__reset_col_len(hists);
+
+	nd = rb_first(&hists->entries);
+	while (nd) {
+		struct hist_entry *h = rb_entry(nd, struct hist_entry, rb_node);
+		int ret;
+
+		ret = hist_entry__filter(h, type, arg);
+
+		/*
+		 * case 1. non-matching type
+		 * zero out the period, set filtered and move to child
+		 */
+		if (ret < 0) {
+			memset(&h->stat, 0, sizeof(h->stat));
+			h->filtered |= (1 << type);
+
+			/* force to go down in the hierarchy */
+			saved_unfolded = h->unfolded;
+			h->unfolded = true;
+
+			nd = rb_hierarchy_next(&h->rb_node);
+			h->unfolded = saved_unfolded;
+		}
+		/*
+		 * case 2. matched (filter out)
+		 * set filtered and move to next
+		 */
+		else if (ret == 1) {
+			h->filtered |= (1 << type);
+
+			/* force to go to sibling in the hierarchy */
+			saved_unfolded = h->unfolded;
+			h->unfolded = false;
+
+			nd = rb_hierarchy_next(&h->rb_node);
+			h->unfolded = saved_unfolded;
+		}
+		/*
+		 * case 3. ok (not filtered)
+		 * add period to hists and parents, erase filtered
+		 * and move to next
+		 */
+		else {
+			hists__remove_entry_filter(hists, h, type);
+
+			/* force to go to sibling in the hierarchy */
+			saved_unfolded = h->unfolded;
+			h->unfolded = false;
+
+			nd = rb_hierarchy_next(&h->rb_node);
+			h->unfolded = saved_unfolded;
+		}
+	}
+
+	/* resort output (top-level entries only) */
+	nd = rb_first(&hists->entries);
+	while (nd) {
+		struct hist_entry *h = rb_entry(nd, struct hist_entry, rb_node);
+
+		nd = rb_next(nd);
+		rb_erase(&h->rb_node, &hists->entries);
+
+		__hists__insert_output_entry(&tmp, h, 0, false);
+	}
+
+	hists->entries = tmp;
+}
+
 void hists__filter_by_thread(struct hists *hists)
 {
-	hists__filter_by_type(hists, HIST_FILTER__THREAD,
-			      hists__filter_entry_by_thread);
+	if (symbol_conf.report_hierarchy)
+		hists__filter_hierarchy(hists, HIST_FILTER__THREAD,
+					hists->thread_filter);
+	else
+		hists__filter_by_type(hists, HIST_FILTER__THREAD,
+				      hists__filter_entry_by_thread);
 }
 
 void hists__filter_by_dso(struct hists *hists)
 {
-	hists__filter_by_type(hists, HIST_FILTER__DSO,
-			      hists__filter_entry_by_dso);
+	if (symbol_conf.report_hierarchy)
+		hists__filter_hierarchy(hists, HIST_FILTER__DSO,
+					hists->dso_filter);
+	else
+		hists__filter_by_type(hists, HIST_FILTER__DSO,
+				      hists__filter_entry_by_dso);
 }
 
 void hists__filter_by_symbol(struct hists *hists)
 {
-	hists__filter_by_type(hists, HIST_FILTER__SYMBOL,
-			      hists__filter_entry_by_symbol);
+	if (symbol_conf.report_hierarchy)
+		hists__filter_hierarchy(hists, HIST_FILTER__SYMBOL,
+					hists->symbol_filter_str);
+	else
+		hists__filter_by_type(hists, HIST_FILTER__SYMBOL,
+				      hists__filter_entry_by_symbol);
 }
 
 void hists__filter_by_socket(struct hists *hists)
 {
-	hists__filter_by_type(hists, HIST_FILTER__SOCKET,
-			      hists__filter_entry_by_socket);
+	if (symbol_conf.report_hierarchy)
+		hists__filter_hierarchy(hists, HIST_FILTER__SOCKET,
+					&hists->socket_filter);
+	else
+		hists__filter_by_type(hists, HIST_FILTER__SOCKET,
+				      hists__filter_entry_by_socket);
 }
 
 void events_stats__inc(struct events_stats *stats, u32 type)
diff --git a/tools/perf/util/hist.h b/tools/perf/util/hist.h
index 96b7ff817d3e..6c276c87cfc3 100644
--- a/tools/perf/util/hist.h
+++ b/tools/perf/util/hist.h
@@ -270,6 +270,8 @@ bool perf_hpp__same_sort_entry(struct perf_hpp_fmt *a, struct perf_hpp_fmt *b);
 bool perf_hpp__is_dynamic_entry(struct perf_hpp_fmt *format);
 bool perf_hpp__defined_dynamic_entry(struct perf_hpp_fmt *fmt, struct hists *hists);
 
+int hist_entry__filter(struct hist_entry *he, int type, const void *arg);
+
 static inline bool perf_hpp__should_skip(struct perf_hpp_fmt *format,
 					 struct hists *hists)
 {
diff --git a/tools/perf/util/sort.c b/tools/perf/util/sort.c
index ec722346e6ff..4632475bc5e4 100644
--- a/tools/perf/util/sort.c
+++ b/tools/perf/util/sort.c
@@ -80,10 +80,21 @@ static int hist_entry__thread_snprintf(struct hist_entry *he, char *bf,
 			       width, width, comm ?: "");
 }
 
+static int hist_entry__thread_filter(struct hist_entry *he, int type, const void *arg)
+{
+	const struct thread *th = arg;
+
+	if (type != HIST_FILTER__THREAD)
+		return -1;
+
+	return th && he->thread != th;
+}
+
 struct sort_entry sort_thread = {
 	.se_header	= "  Pid:Command",
 	.se_cmp		= sort__thread_cmp,
 	.se_snprintf	= hist_entry__thread_snprintf,
+	.se_filter	= hist_entry__thread_filter,
 	.se_width_idx	= HISTC_THREAD,
 };
 
@@ -121,6 +132,7 @@ struct sort_entry sort_comm = {
 	.se_collapse	= sort__comm_collapse,
 	.se_sort	= sort__comm_sort,
 	.se_snprintf	= hist_entry__comm_snprintf,
+	.se_filter	= hist_entry__thread_filter,
 	.se_width_idx	= HISTC_COMM,
 };
 
@@ -170,10 +182,21 @@ static int hist_entry__dso_snprintf(struct hist_entry *he, char *bf,
 	return _hist_entry__dso_snprintf(he->ms.map, bf, size, width);
 }
 
+static int hist_entry__dso_filter(struct hist_entry *he, int type, const void *arg)
+{
+	const struct dso *dso = arg;
+
+	if (type != HIST_FILTER__DSO)
+		return -1;
+
+	return dso && (!he->ms.map || he->ms.map->dso != dso);
+}
+
 struct sort_entry sort_dso = {
 	.se_header	= "Shared Object",
 	.se_cmp		= sort__dso_cmp,
 	.se_snprintf	= hist_entry__dso_snprintf,
+	.se_filter	= hist_entry__dso_filter,
 	.se_width_idx	= HISTC_DSO,
 };
 
@@ -274,11 +297,22 @@ static int hist_entry__sym_snprintf(struct hist_entry *he, char *bf,
 					 he->level, bf, size, width);
 }
 
+static int hist_entry__sym_filter(struct hist_entry *he, int type, const void *arg)
+{
+	const char *sym = arg;
+
+	if (type != HIST_FILTER__SYMBOL)
+		return -1;
+
+	return sym && (!he->ms.sym || !strstr(he->ms.sym->name, sym));
+}
+
 struct sort_entry sort_sym = {
 	.se_header	= "Symbol",
 	.se_cmp		= sort__sym_cmp,
 	.se_sort	= sort__sym_sort,
 	.se_snprintf	= hist_entry__sym_snprintf,
+	.se_filter	= hist_entry__sym_filter,
 	.se_width_idx	= HISTC_SYMBOL,
 };
 
@@ -439,10 +473,21 @@ static int hist_entry__socket_snprintf(struct hist_entry *he, char *bf,
 	return repsep_snprintf(bf, size, "%*.*d", width, width-3, he->socket);
 }
 
+static int hist_entry__socket_filter(struct hist_entry *he, int type, const void *arg)
+{
+	int socket = *(const int *)arg;
+
+	if (type != HIST_FILTER__SOCKET)
+		return -1;
+
+	return socket >= 0 && he->socket != socket;
+}
+
 struct sort_entry sort_socket = {
 	.se_header      = "Socket",
 	.se_cmp	        = sort__socket_cmp,
 	.se_snprintf    = hist_entry__socket_snprintf,
+	.se_filter      = hist_entry__socket_filter,
 	.se_width_idx	= HISTC_SOCKET,
 };
 
@@ -532,6 +577,18 @@ static int hist_entry__dso_from_snprintf(struct hist_entry *he, char *bf,
 		return repsep_snprintf(bf, size, "%-*.*s", width, width, "N/A");
 }
 
+static int hist_entry__dso_from_filter(struct hist_entry *he, int type,
+				       const void *arg)
+{
+	const struct dso *dso = arg;
+
+	if (type != HIST_FILTER__DSO)
+		return -1;
+
+	return dso && (!he->branch_info || !he->branch_info->from.map ||
+		       he->branch_info->from.map->dso != dso);
+}
+
 static int64_t
 sort__dso_to_cmp(struct hist_entry *left, struct hist_entry *right)
 {
@@ -552,6 +609,18 @@ static int hist_entry__dso_to_snprintf(struct hist_entry *he, char *bf,
 		return repsep_snprintf(bf, size, "%-*.*s", width, width, "N/A");
 }
 
+static int hist_entry__dso_to_filter(struct hist_entry *he, int type,
+				     const void *arg)
+{
+	const struct dso *dso = arg;
+
+	if (type != HIST_FILTER__DSO)
+		return -1;
+
+	return dso && (!he->branch_info || !he->branch_info->to.map ||
+		       he->branch_info->to.map->dso != dso);
+}
+
 static int64_t
 sort__sym_from_cmp(struct hist_entry *left, struct hist_entry *right)
 {
@@ -613,10 +682,35 @@ static int hist_entry__sym_to_snprintf(struct hist_entry *he, char *bf,
 	return repsep_snprintf(bf, size, "%-*.*s", width, width, "N/A");
 }
 
+static int hist_entry__sym_from_filter(struct hist_entry *he, int type,
+				       const void *arg)
+{
+	const char *sym = arg;
+
+	if (type != HIST_FILTER__SYMBOL)
+		return -1;
+
+	return sym && !(he->branch_info && he->branch_info->from.sym &&
+			strstr(he->branch_info->from.sym->name, sym));
+}
+
+static int hist_entry__sym_to_filter(struct hist_entry *he, int type,
+				       const void *arg)
+{
+	const char *sym = arg;
+
+	if (type != HIST_FILTER__SYMBOL)
+		return -1;
+
+	return sym && !(he->branch_info && he->branch_info->to.sym &&
+		        strstr(he->branch_info->to.sym->name, sym));
+}
+
 struct sort_entry sort_dso_from = {
 	.se_header	= "Source Shared Object",
 	.se_cmp		= sort__dso_from_cmp,
 	.se_snprintf	= hist_entry__dso_from_snprintf,
+	.se_filter	= hist_entry__dso_from_filter,
 	.se_width_idx	= HISTC_DSO_FROM,
 };
 
@@ -624,6 +718,7 @@ struct sort_entry sort_dso_to = {
 	.se_header	= "Target Shared Object",
 	.se_cmp		= sort__dso_to_cmp,
 	.se_snprintf	= hist_entry__dso_to_snprintf,
+	.se_filter	= hist_entry__dso_to_filter,
 	.se_width_idx	= HISTC_DSO_TO,
 };
 
@@ -631,6 +726,7 @@ struct sort_entry sort_sym_from = {
 	.se_header	= "Source Symbol",
 	.se_cmp		= sort__sym_from_cmp,
 	.se_snprintf	= hist_entry__sym_from_snprintf,
+	.se_filter	= hist_entry__sym_from_filter,
 	.se_width_idx	= HISTC_SYMBOL_FROM,
 };
 
@@ -638,6 +734,7 @@ struct sort_entry sort_sym_to = {
 	.se_header	= "Target Symbol",
 	.se_cmp		= sort__sym_to_cmp,
 	.se_snprintf	= hist_entry__sym_to_snprintf,
+	.se_filter	= hist_entry__sym_to_filter,
 	.se_width_idx	= HISTC_SYMBOL_TO,
 };
 
@@ -1575,6 +1672,22 @@ bool perf_hpp__is_sort_entry(struct perf_hpp_fmt *format)
 	return format->header == __sort__hpp_header;
 }
 
+int hist_entry__filter(struct hist_entry *he, int type, const void *arg)
+{
+	struct perf_hpp_fmt *fmt;
+	struct hpp_sort_entry *hse;
+
+	fmt = he->fmt;
+	if (fmt == NULL || !perf_hpp__is_sort_entry(fmt))
+		return -1;
+
+	hse = container_of(fmt, struct hpp_sort_entry, hpp);
+	if (hse->se->se_filter == NULL)
+		return -1;
+
+	return hse->se->se_filter(he, type, arg);
+}
+
 static int __sort_dimension__add_hpp_sort(struct sort_dimension *sd)
 {
 	struct hpp_sort_entry *hse = __sort_dimension__alloc_hpp(sd);
diff --git a/tools/perf/util/sort.h b/tools/perf/util/sort.h
index 15a75d44de91..051739615847 100644
--- a/tools/perf/util/sort.h
+++ b/tools/perf/util/sort.h
@@ -232,6 +232,7 @@ struct sort_entry {
 	int64_t	(*se_sort)(struct hist_entry *, struct hist_entry *);
 	int	(*se_snprintf)(struct hist_entry *he, char *bf, size_t size,
 			       unsigned int width);
+	int	(*se_filter)(struct hist_entry *he, int type, const void *arg);
 	u8	se_width_idx;
 };
 
-- 
2.6.4

[toc] | [prev] | [next] | [standalone]


#1310985 — [PATCH 11/17] perf hists browser: Factor out hist_browser__show_callchain()

FromNamhyung Kim <namhyung@kernel.org>
Date2016-01-16 17:10 +0100
Subject[PATCH 11/17] perf hists browser: Factor out hist_browser__show_callchain()
Message-ID<qRBAo-6Ad-61@gated-at.bofh.it>
In reply to#1310972
Factor out callchain printing code so that it can be called by other
functions easily.  It renames the existing function which prints
graph-style callchain.  This also fixes hist_browser__dump() which
missed to be updated by commit 8c430a348699 ("perf hists browser:
Support folded callchains").

Signed-off-by: Namhyung Kim <namhyung@kernel.org>
---
 tools/perf/ui/browsers/hists.c | 73 ++++++++++++++++++++++++------------------
 1 file changed, 41 insertions(+), 32 deletions(-)

diff --git a/tools/perf/ui/browsers/hists.c b/tools/perf/ui/browsers/hists.c
index 8452528fa29b..353e0477c1f5 100644
--- a/tools/perf/ui/browsers/hists.c
+++ b/tools/perf/ui/browsers/hists.c
@@ -952,7 +952,7 @@ next:
 	return row - first_row;
 }
 
-static int hist_browser__show_callchain(struct hist_browser *browser,
+static int hist_browser__show_callchain_graph(struct hist_browser *browser,
 					struct rb_root *root, int level,
 					unsigned short row, u64 total,
 					print_callchain_entry_fn print,
@@ -1006,7 +1006,7 @@ static int hist_browser__show_callchain(struct hist_browser *browser,
 			else
 				new_total = total;
 
-			row += hist_browser__show_callchain(browser, &child->rb_root,
+			row += hist_browser__show_callchain_graph(browser, &child->rb_root,
 							    new_level, row, new_total,
 							    print, arg, is_output_full);
 		}
@@ -1018,6 +1018,43 @@ out:
 	return row - first_row;
 }
 
+static int hist_browser__show_callchain(struct hist_browser *browser,
+					struct hist_entry *entry, int level,
+					unsigned short row,
+					print_callchain_entry_fn print,
+					struct callchain_print_arg *arg,
+					check_output_full_fn is_output_full)
+{
+	u64 total = hists__total_period(entry->hists);
+	int printed;
+
+	if (callchain_param.mode == CHAIN_GRAPH_REL) {
+		if (symbol_conf.cumulate_callchain)
+			total = entry->stat_acc->period;
+		else
+			total = entry->stat.period;
+	}
+
+	if (callchain_param.mode == CHAIN_FLAT) {
+		printed = hist_browser__show_callchain_flat(browser,
+						&entry->sorted_chain, row, total,
+						print, arg, is_output_full);
+	} else if (callchain_param.mode == CHAIN_FOLDED) {
+		printed = hist_browser__show_callchain_folded(browser,
+						&entry->sorted_chain, row, total,
+						print, arg, is_output_full);
+	} else {
+		printed = hist_browser__show_callchain_graph(browser,
+						&entry->sorted_chain, level, row, total,
+						print, arg, is_output_full);
+	}
+
+	if (arg->is_current_entry)
+		browser->he_selection = entry;
+
+	return printed;
+}
+
 struct hpp_arg {
 	struct ui_browser *b;
 	char folded_sign;
@@ -1192,38 +1229,14 @@ static int hist_browser__show_entry(struct hist_browser *browser,
 		--row_offset;
 
 	if (folded_sign == '-' && row != browser->b.rows) {
-		u64 total = hists__total_period(entry->hists);
 		struct callchain_print_arg arg = {
 			.row_offset = row_offset,
 			.is_current_entry = current_entry,
 		};
 
-		if (callchain_param.mode == CHAIN_GRAPH_REL) {
-			if (symbol_conf.cumulate_callchain)
-				total = entry->stat_acc->period;
-			else
-				total = entry->stat.period;
-		}
-
-		if (callchain_param.mode == CHAIN_FLAT) {
-			printed += hist_browser__show_callchain_flat(browser,
-					&entry->sorted_chain, row, total,
+		printed += hist_browser__show_callchain(browser, entry, 1, row,
 					hist_browser__show_callchain_entry, &arg,
 					hist_browser__check_output_full);
-		} else if (callchain_param.mode == CHAIN_FOLDED) {
-			printed += hist_browser__show_callchain_folded(browser,
-					&entry->sorted_chain, row, total,
-					hist_browser__show_callchain_entry, &arg,
-					hist_browser__check_output_full);
-		} else {
-			printed += hist_browser__show_callchain(browser,
-					&entry->sorted_chain, 1, row, total,
-					hist_browser__show_callchain_entry, &arg,
-					hist_browser__check_output_full);
-		}
-
-		if (arg.is_current_entry)
-			browser->he_selection = entry;
 	}
 
 	return printed;
@@ -1488,15 +1501,11 @@ do_offset:
 static int hist_browser__fprintf_callchain(struct hist_browser *browser,
 					   struct hist_entry *he, FILE *fp)
 {
-	u64 total = hists__total_period(he->hists);
 	struct callchain_print_arg arg  = {
 		.fp = fp,
 	};
 
-	if (symbol_conf.cumulate_callchain)
-		total = he->stat_acc->period;
-
-	hist_browser__show_callchain(browser, &he->sorted_chain, 1, 0, total,
+	hist_browser__show_callchain(browser, he, 1, 0,
 				     hist_browser__fprintf_callchain_entry, &arg,
 				     hist_browser__check_dump_full);
 	return arg.printed;
-- 
2.6.4

[toc] | [prev] | [next] | [standalone]


#1310987 — [PATCH 06/17] perf ui/stdio: Implement hierarchy output mode

FromNamhyung Kim <namhyung@kernel.org>
Date2016-01-16 17:10 +0100
Subject[PATCH 06/17] perf ui/stdio: Implement hierarchy output mode
Message-ID<qRBAo-6Ad-63@gated-at.bofh.it>
In reply to#1310972
The hierarchy output mode is to group entries for each level so that
user can see higher level picture more easily.  It also helps to find
out which component is most costly.  The output will look like below:

      15.11%     swapper
         14.97%     [kernel.vmlinux]
          0.09%     [libahci]
          0.05%     [iwlwifi]
      10.29%     irq/33-iwlwifi
          6.45%     [kernel.vmlinux]
          1.41%     [mac80211]
          1.15%     [iwldvm]
          1.14%     [iwlwifi]
          0.14%     [cfg80211]
       4.81%     firefox
          3.92%     libxul.so
          0.34%     [kernel.vmlinux]

Signed-off-by: Namhyung Kim <namhyung@kernel.org>
---
 tools/perf/ui/hist.c       | 14 +++++++++
 tools/perf/ui/stdio/hist.c | 75 +++++++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 88 insertions(+), 1 deletion(-)

diff --git a/tools/perf/ui/hist.c b/tools/perf/ui/hist.c
index bf2a66e254ea..86c0f3d0ae04 100644
--- a/tools/perf/ui/hist.c
+++ b/tools/perf/ui/hist.c
@@ -679,3 +679,17 @@ void perf_hpp__set_user_width(const char *width_list_str)
 			break;
 	}
 }
+
+int perf_hpp__count_sort_keys(void)
+{
+	int nr_sort = 0;
+	struct perf_hpp_fmt *fmt;
+
+	perf_hpp__for_each_format(fmt) {
+		if (perf_hpp__is_sort_entry(fmt) ||
+		    perf_hpp__is_dynamic_entry(fmt))
+			nr_sort++;
+	}
+
+	return nr_sort;
+}
diff --git a/tools/perf/ui/stdio/hist.c b/tools/perf/ui/stdio/hist.c
index 387110d50b00..0cd7c651a0e8 100644
--- a/tools/perf/ui/stdio/hist.c
+++ b/tools/perf/ui/stdio/hist.c
@@ -409,6 +409,69 @@ static int hist_entry__snprintf(struct hist_entry *he, struct perf_hpp *hpp)
 	return hpp->buf - start;
 }
 
+static int hist_entry__hierarchy_fprintf(struct hist_entry *he,
+					 struct perf_hpp *hpp,
+					 int nr_sort_key, struct hists *hists,
+					 FILE *fp)
+{
+	const char *sep = symbol_conf.field_sep;
+	struct perf_hpp_fmt *fmt;
+	char *buf = hpp->buf;
+	int ret, printed = 0;
+	bool first = true;
+
+	if (symbol_conf.exclude_other && !he->parent)
+		return 0;
+
+	ret = scnprintf(hpp->buf, hpp->size, "%*s", he->depth * HIERARCHY_INDENT, "");
+	advance_hpp(hpp, ret);
+
+	perf_hpp__for_each_format(fmt) {
+		if (perf_hpp__is_sort_entry(fmt) || perf_hpp__is_dynamic_entry(fmt))
+			break;
+
+		/*
+		 * If there's no field_sep, we still need
+		 * to display initial '  '.
+		 */
+		if (!sep || !first) {
+			ret = scnprintf(hpp->buf, hpp->size, "%s", sep ?: "  ");
+			advance_hpp(hpp, ret);
+		} else
+			first = false;
+
+		if (perf_hpp__use_color() && fmt->color)
+			ret = fmt->color(fmt, hpp, he);
+		else
+			ret = fmt->entry(fmt, hpp, he);
+
+		advance_hpp(hpp, ret);
+	}
+
+	if (sep)
+		ret = scnprintf(hpp->buf, hpp->size, "%s", sep);
+	else
+		ret = scnprintf(hpp->buf, hpp->size, "%*s",
+				(nr_sort_key - 1) * HIERARCHY_INDENT + 2, "");
+	advance_hpp(hpp, ret);
+
+	fmt = he->fmt;
+	if (perf_hpp__use_color() && fmt->color)
+		fmt->color(fmt, hpp, he);
+	else
+		fmt->entry(fmt, hpp, he);
+
+	printed += fprintf(fp, "%s\n", buf);
+
+	if (symbol_conf.use_callchain && he->leaf) {
+		printed += hist_entry__callchain_fprintf(he, hists, fp);
+		goto out;
+	}
+
+out:
+	return printed;
+}
+
 static int hist_entry__fprintf(struct hist_entry *he, size_t size,
 			       struct hists *hists,
 			       char *bf, size_t bfsz, FILE *fp)
@@ -422,6 +485,13 @@ static int hist_entry__fprintf(struct hist_entry *he, size_t size,
 	if (size == 0 || size > bfsz)
 		size = hpp.size = bfsz;
 
+	if (symbol_conf.report_hierarchy) {
+		int nr_sort = perf_hpp__count_sort_keys();
+
+		return hist_entry__hierarchy_fprintf(he, &hpp, nr_sort,
+						     hists, fp);
+	}
+
 	hist_entry__snprintf(he, &hpp);
 
 	ret = fprintf(fp, "%s\n", bf);
@@ -520,7 +590,7 @@ print_entries:
 		goto out;
 	}
 
-	for (nd = rb_first(&hists->entries); nd; nd = rb_next(nd)) {
+	for (nd = rb_first(&hists->entries); nd; nd = rb_hierarchy_next(nd)) {
 		struct hist_entry *h = rb_entry(nd, struct hist_entry, rb_node);
 		float percent;
 
@@ -541,6 +611,9 @@ print_entries:
 						   MAP__FUNCTION, fp);
 			fprintf(fp, "%.10s end\n", graph_dotted_line);
 		}
+
+		if (symbol_conf.report_hierarchy)
+			h->unfolded = true;
 	}
 
 	free(line);
-- 
2.6.4

[toc] | [prev] | [next] | [standalone]


#1310988 — [PATCH 03/17] perf hists: Add helper functions for hierarchy mode

FromNamhyung Kim <namhyung@kernel.org>
Date2016-01-16 17:10 +0100
Subject[PATCH 03/17] perf hists: Add helper functions for hierarchy mode
Message-ID<qRBAo-6Ad-55@gated-at.bofh.it>
In reply to#1310972
The rb_hierarchy_{first,last,next,prev} functions are to traverse all
hist entries in a hierarchy.  They will be used by various function
which supports hierarchy output.

Signed-off-by: Namhyung Kim <namhyung@kernel.org>
---
 tools/perf/util/hist.c | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++
 tools/perf/util/hist.h |  9 +++++++++
 2 files changed, 59 insertions(+)

diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c
index 931353f49c72..9354455aec5b 100644
--- a/tools/perf/util/hist.c
+++ b/tools/perf/util/hist.c
@@ -1390,6 +1390,56 @@ void hists__output_resort(struct hists *hists, struct ui_progress *prog)
 	}
 }
 
+struct rb_node *rb_hierarchy_first(struct rb_node *node)
+{
+	return node;
+}
+
+struct rb_node *rb_hierarchy_last(struct rb_node *node)
+{
+	struct hist_entry *he = rb_entry(node, struct hist_entry, rb_node);
+
+	while (he->unfolded && !he->leaf) {
+		node = rb_last(&he->hroot_out);
+		he = rb_entry(node, struct hist_entry, rb_node);
+	}
+	return node;
+}
+
+struct rb_node *rb_hierarchy_next(struct rb_node *node)
+{
+	struct hist_entry *he = rb_entry(node, struct hist_entry, rb_node);
+
+	if (!he->leaf && he->unfolded)
+		node = rb_first(&he->hroot_out);
+	else
+		node = rb_next(node);
+
+	while (node == NULL) {
+		he = he->parent_he;
+		if (he == NULL)
+			break;
+
+		node = rb_next(&he->rb_node);
+	}
+	return node;
+}
+
+struct rb_node *rb_hierarchy_prev(struct rb_node *node)
+{
+	struct hist_entry *he = rb_entry(node, struct hist_entry, rb_node);
+
+	node = rb_prev(node);
+	if (node)
+		return rb_hierarchy_last(node);
+
+	he = he->parent_he;
+	if (he == NULL)
+		return NULL;
+
+	return &he->rb_node;
+}
+
 static void hists__remove_entry_filter(struct hists *hists, struct hist_entry *h,
 				       enum hist_filter filter)
 {
diff --git a/tools/perf/util/hist.h b/tools/perf/util/hist.h
index d4ec4822a103..96b7ff817d3e 100644
--- a/tools/perf/util/hist.h
+++ b/tools/perf/util/hist.h
@@ -381,4 +381,13 @@ 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);
 
+#define HIERARCHY_INDENT  3
+
+int perf_hpp__count_sort_keys(void);
+
+struct rb_node *rb_hierarchy_first(struct rb_node *node);
+struct rb_node *rb_hierarchy_last(struct rb_node *node);
+struct rb_node *rb_hierarchy_next(struct rb_node *node);
+struct rb_node *rb_hierarchy_prev(struct rb_node *node);
+
 #endif	/* __PERF_HIST_H */
-- 
2.6.4

[toc] | [prev] | [next] | [standalone]


#1313609 — Re: [PATCH 03/17] perf hists: Add helper functions for hierarchy mode

FromArnaldo Carvalho de Melo <acme@kernel.org>
Date2016-01-20 23:20 +0100
SubjectRe: [PATCH 03/17] perf hists: Add helper functions for hierarchy mode
Message-ID<qT9gE-4lI-69@gated-at.bofh.it>
In reply to#1310988
Em Sun, Jan 17, 2016 at 01:03:03AM +0900, Namhyung Kim escreveu:
> The rb_hierarchy_{first,last,next,prev} functions are to traverse all
> hist entries in a hierarchy.  They will be used by various function
> which supports hierarchy output.
> 
> Signed-off-by: Namhyung Kim <namhyung@kernel.org>
> ---
>  tools/perf/util/hist.c | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++
>  tools/perf/util/hist.h |  9 +++++++++
>  2 files changed, 59 insertions(+)
> 
> diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c
> index 931353f49c72..9354455aec5b 100644
> --- a/tools/perf/util/hist.c
> +++ b/tools/perf/util/hist.c
> @@ -1390,6 +1390,56 @@ void hists__output_resort(struct hists *hists, struct ui_progress *prog)
>  	}
>  }
>  
> +struct rb_node *rb_hierarchy_first(struct rb_node *node)
> +{
> +	return node;
> +}

rb_hierarchy_first() is not used in this patchkit, you end up starting
from rb_first(&hists->entries), so I guess we can remove this one, if
you ever need it, then reintroduce it.

- Arnaldo

> +
> +struct rb_node *rb_hierarchy_last(struct rb_node *node)
> +{
> +	struct hist_entry *he = rb_entry(node, struct hist_entry, rb_node);
> +
> +	while (he->unfolded && !he->leaf) {
> +		node = rb_last(&he->hroot_out);
> +		he = rb_entry(node, struct hist_entry, rb_node);
> +	}
> +	return node;
> +}
> +
> +struct rb_node *rb_hierarchy_next(struct rb_node *node)
> +{
> +	struct hist_entry *he = rb_entry(node, struct hist_entry, rb_node);
> +
> +	if (!he->leaf && he->unfolded)
> +		node = rb_first(&he->hroot_out);
> +	else
> +		node = rb_next(node);
> +
> +	while (node == NULL) {
> +		he = he->parent_he;
> +		if (he == NULL)
> +			break;
> +
> +		node = rb_next(&he->rb_node);
> +	}
> +	return node;
> +}
> +
> +struct rb_node *rb_hierarchy_prev(struct rb_node *node)
> +{
> +	struct hist_entry *he = rb_entry(node, struct hist_entry, rb_node);
> +
> +	node = rb_prev(node);
> +	if (node)
> +		return rb_hierarchy_last(node);
> +
> +	he = he->parent_he;
> +	if (he == NULL)
> +		return NULL;
> +
> +	return &he->rb_node;
> +}
> +
>  static void hists__remove_entry_filter(struct hists *hists, struct hist_entry *h,
>  				       enum hist_filter filter)
>  {
> diff --git a/tools/perf/util/hist.h b/tools/perf/util/hist.h
> index d4ec4822a103..96b7ff817d3e 100644
> --- a/tools/perf/util/hist.h
> +++ b/tools/perf/util/hist.h
> @@ -381,4 +381,13 @@ 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);
>  
> +#define HIERARCHY_INDENT  3
> +
> +int perf_hpp__count_sort_keys(void);
> +
> +struct rb_node *rb_hierarchy_first(struct rb_node *node);
> +struct rb_node *rb_hierarchy_last(struct rb_node *node);
> +struct rb_node *rb_hierarchy_next(struct rb_node *node);
> +struct rb_node *rb_hierarchy_prev(struct rb_node *node);
> +
>  #endif	/* __PERF_HIST_H */
> -- 
> 2.6.4

[toc] | [prev] | [next] | [standalone]


#1313847 — Re: [PATCH 03/17] perf hists: Add helper functions for hierarchy mode

FromNamhyung Kim <namhyung@kernel.org>
Date2016-01-21 05:00 +0100
SubjectRe: [PATCH 03/17] perf hists: Add helper functions for hierarchy mode
Message-ID<qTezE-7XT-15@gated-at.bofh.it>
In reply to#1313609
Hi Arnaldo,

On Wed, Jan 20, 2016 at 07:19:03PM -0300, Arnaldo Carvalho de Melo wrote:
> Em Sun, Jan 17, 2016 at 01:03:03AM +0900, Namhyung Kim escreveu:
> > The rb_hierarchy_{first,last,next,prev} functions are to traverse all
> > hist entries in a hierarchy.  They will be used by various function
> > which supports hierarchy output.
> > 
> > Signed-off-by: Namhyung Kim <namhyung@kernel.org>
> > ---
> >  tools/perf/util/hist.c | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++
> >  tools/perf/util/hist.h |  9 +++++++++
> >  2 files changed, 59 insertions(+)
> > 
> > diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c
> > index 931353f49c72..9354455aec5b 100644
> > --- a/tools/perf/util/hist.c
> > +++ b/tools/perf/util/hist.c
> > @@ -1390,6 +1390,56 @@ void hists__output_resort(struct hists *hists, struct ui_progress *prog)
> >  	}
> >  }
> >  
> > +struct rb_node *rb_hierarchy_first(struct rb_node *node)
> > +{
> > +	return node;
> > +}
> 
> rb_hierarchy_first() is not used in this patchkit, you end up starting
> from rb_first(&hists->entries), so I guess we can remove this one, if
> you ever need it, then reintroduce it.

Right.  I firstly thought it might be needed, but it's not.  Will remove.

Thanks,
Namhyung


> > +
> > +struct rb_node *rb_hierarchy_last(struct rb_node *node)
> > +{
> > +	struct hist_entry *he = rb_entry(node, struct hist_entry, rb_node);
> > +
> > +	while (he->unfolded && !he->leaf) {
> > +		node = rb_last(&he->hroot_out);
> > +		he = rb_entry(node, struct hist_entry, rb_node);
> > +	}
> > +	return node;
> > +}
> > +
> > +struct rb_node *rb_hierarchy_next(struct rb_node *node)
> > +{
> > +	struct hist_entry *he = rb_entry(node, struct hist_entry, rb_node);
> > +
> > +	if (!he->leaf && he->unfolded)
> > +		node = rb_first(&he->hroot_out);
> > +	else
> > +		node = rb_next(node);
> > +
> > +	while (node == NULL) {
> > +		he = he->parent_he;
> > +		if (he == NULL)
> > +			break;
> > +
> > +		node = rb_next(&he->rb_node);
> > +	}
> > +	return node;
> > +}
> > +
> > +struct rb_node *rb_hierarchy_prev(struct rb_node *node)
> > +{
> > +	struct hist_entry *he = rb_entry(node, struct hist_entry, rb_node);
> > +
> > +	node = rb_prev(node);
> > +	if (node)
> > +		return rb_hierarchy_last(node);
> > +
> > +	he = he->parent_he;
> > +	if (he == NULL)
> > +		return NULL;
> > +
> > +	return &he->rb_node;
> > +}
> > +
> >  static void hists__remove_entry_filter(struct hists *hists, struct hist_entry *h,
> >  				       enum hist_filter filter)
> >  {
> > diff --git a/tools/perf/util/hist.h b/tools/perf/util/hist.h
> > index d4ec4822a103..96b7ff817d3e 100644
> > --- a/tools/perf/util/hist.h
> > +++ b/tools/perf/util/hist.h
> > @@ -381,4 +381,13 @@ 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);
> >  
> > +#define HIERARCHY_INDENT  3
> > +
> > +int perf_hpp__count_sort_keys(void);
> > +
> > +struct rb_node *rb_hierarchy_first(struct rb_node *node);
> > +struct rb_node *rb_hierarchy_last(struct rb_node *node);
> > +struct rb_node *rb_hierarchy_next(struct rb_node *node);
> > +struct rb_node *rb_hierarchy_prev(struct rb_node *node);
> > +
> >  #endif	/* __PERF_HIST_H */
> > -- 
> > 2.6.4

[toc] | [prev] | [next] | [standalone]


#1313854 — [PATCH v2 03/17] perf hists: Add helper functions for hierarchy mode

FromNamhyung Kim <namhyung@kernel.org>
Date2016-01-21 05:20 +0100
Subject[PATCH v2 03/17] perf hists: Add helper functions for hierarchy mode
Message-ID<qTeT1-8lg-15@gated-at.bofh.it>
In reply to#1313847
The rb_hierarchy_{first,last,next,prev} functions are to traverse all
hist entries in a hierarchy.  They will be used by various function
which supports hierarchy output.

Signed-off-by: Namhyung Kim <namhyung@kernel.org>
---
removed rb_hierarchy_first().

 tools/perf/util/hist.c | 45 +++++++++++++++++++++++++++++++++++++++++++++
 tools/perf/util/hist.h |  8 ++++++++
 2 files changed, 53 insertions(+)

diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c
index 931353f49c72..e9eff7c4bbaf 100644
--- a/tools/perf/util/hist.c
+++ b/tools/perf/util/hist.c
@@ -1390,6 +1390,51 @@ void hists__output_resort(struct hists *hists, struct ui_progress *prog)
 	}
 }
 
+struct rb_node *rb_hierarchy_last(struct rb_node *node)
+{
+	struct hist_entry *he = rb_entry(node, struct hist_entry, rb_node);
+
+	while (he->unfolded && !he->leaf) {
+		node = rb_last(&he->hroot_out);
+		he = rb_entry(node, struct hist_entry, rb_node);
+	}
+	return node;
+}
+
+struct rb_node *rb_hierarchy_next(struct rb_node *node)
+{
+	struct hist_entry *he = rb_entry(node, struct hist_entry, rb_node);
+
+	if (!he->leaf && he->unfolded)
+		node = rb_first(&he->hroot_out);
+	else
+		node = rb_next(node);
+
+	while (node == NULL) {
+		he = he->parent_he;
+		if (he == NULL)
+			break;
+
+		node = rb_next(&he->rb_node);
+	}
+	return node;
+}
+
+struct rb_node *rb_hierarchy_prev(struct rb_node *node)
+{
+	struct hist_entry *he = rb_entry(node, struct hist_entry, rb_node);
+
+	node = rb_prev(node);
+	if (node)
+		return rb_hierarchy_last(node);
+
+	he = he->parent_he;
+	if (he == NULL)
+		return NULL;
+
+	return &he->rb_node;
+}
+
 static void hists__remove_entry_filter(struct hists *hists, struct hist_entry *h,
 				       enum hist_filter filter)
 {
diff --git a/tools/perf/util/hist.h b/tools/perf/util/hist.h
index d4ec4822a103..2b8a73ea12c3 100644
--- a/tools/perf/util/hist.h
+++ b/tools/perf/util/hist.h
@@ -381,4 +381,12 @@ 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);
 
+#define HIERARCHY_INDENT  3
+
+int perf_hpp__count_sort_keys(void);
+
+struct rb_node *rb_hierarchy_last(struct rb_node *node);
+struct rb_node *rb_hierarchy_next(struct rb_node *node);
+struct rb_node *rb_hierarchy_prev(struct rb_node *node);
+
 #endif	/* __PERF_HIST_H */
-- 
2.7.0

[toc] | [prev] | [next] | [standalone]


#1314190 — Re: [PATCH v2 03/17] perf hists: Add helper functions for hierarchy mode

FromNamhyung Kim <namhyung@kernel.org>
Date2016-01-21 14:10 +0100
SubjectRe: [PATCH v2 03/17] perf hists: Add helper functions for hierarchy mode
Message-ID<qTn9U-5Gc-11@gated-at.bofh.it>
In reply to#1313854
On Thu, Jan 21, 2016 at 01:19:31PM +0900, Namhyung Kim wrote:
> The rb_hierarchy_{first,last,next,prev} functions are to traverse all

Ouch, missed to remove 'first' here.


> hist entries in a hierarchy.  They will be used by various function
> which supports hierarchy output.
> 
> Signed-off-by: Namhyung Kim <namhyung@kernel.org>
> ---
> removed rb_hierarchy_first().

[toc] | [prev] | [next] | [standalone]


#1310989 — [PATCH 09/17] perf hists browser: Count number of hierarchy entries

FromNamhyung Kim <namhyung@kernel.org>
Date2016-01-16 17:10 +0100
Subject[PATCH 09/17] perf hists browser: Count number of hierarchy entries
Message-ID<qRBAo-6Ad-65@gated-at.bofh.it>
In reply to#1310972
Add nr_hierarchy_entries field to keep current number of (unfolded) hist
entries.  And the hist_entry->nr_rows carries number of direct children.
But in the hierarchy mode, entry can have grand children and callchains.
So update the number properly using hierarchy_count_rows() when toggling
the folded state (by pressing ENTER key).

Signed-off-by: Namhyung Kim <namhyung@kernel.org>
---
 tools/perf/ui/browsers/hists.c | 94 +++++++++++++++++++++++++++++++++++-------
 1 file changed, 80 insertions(+), 14 deletions(-)

diff --git a/tools/perf/ui/browsers/hists.c b/tools/perf/ui/browsers/hists.c
index cd6349ebd0d6..ae9e6407ea3c 100644
--- a/tools/perf/ui/browsers/hists.c
+++ b/tools/perf/ui/browsers/hists.c
@@ -32,6 +32,7 @@ struct hist_browser {
 	bool		     show_headers;
 	float		     min_pcnt;
 	u64		     nr_non_filtered_entries;
+	u64		     nr_hierarchy_entries;
 	u64		     nr_callchain_rows;
 };
 
@@ -58,11 +59,11 @@ static int hist_browser__get_folding(struct hist_browser *browser)
 
 	for (nd = rb_first(&hists->entries);
 	     (nd = hists__filter_entries(nd, browser->min_pcnt)) != NULL;
-	     nd = rb_next(nd)) {
+	     nd = rb_hierarchy_next(nd)) {
 		struct hist_entry *he =
 			rb_entry(nd, struct hist_entry, rb_node);
 
-		if (he->unfolded)
+		if (he->leaf && he->unfolded)
 			unfolded_rows += he->nr_rows;
 	}
 	return unfolded_rows;
@@ -72,7 +73,9 @@ static u32 hist_browser__nr_entries(struct hist_browser *hb)
 {
 	u32 nr_entries;
 
-	if (hist_browser__has_filter(hb))
+	if (symbol_conf.report_hierarchy)
+		nr_entries = hb->nr_hierarchy_entries;
+	else if (hist_browser__has_filter(hb))
 		nr_entries = hb->nr_non_filtered_entries;
 	else
 		nr_entries = hb->hists->nr_entries;
@@ -215,7 +218,7 @@ static int callchain_node__count_folded_rows(struct callchain_node *node __maybe
 static int callchain_node__count_rows(struct callchain_node *node)
 {
 	struct callchain_list *chain;
-	bool unfolded = false;
+	char folded_sign = ' ';
 	int n = 0;
 
 	if (callchain_param.mode == CHAIN_FLAT)
@@ -225,10 +228,13 @@ static int callchain_node__count_rows(struct callchain_node *node)
 
 	list_for_each_entry(chain, &node->val, list) {
 		++n;
-		unfolded = chain->unfolded;
+
+		folded_sign = callchain_list__folded(chain);
+		if (folded_sign == '+')
+			break;
 	}
 
-	if (unfolded)
+	if (folded_sign == '-')
 		n += callchain_node__count_rows_rb_tree(node);
 
 	return n;
@@ -247,6 +253,35 @@ static int callchain__count_rows(struct rb_root *chain)
 	return n;
 }
 
+static int hierarchy_count_rows(struct hist_browser *hb, struct hist_entry *he,
+				bool include_children)
+{
+	int count = 0;
+	struct rb_node *node;
+	struct hist_entry *child;
+
+	if (he->leaf)
+		return callchain__count_rows(&he->sorted_chain);
+
+	node = rb_first(&he->hroot_out);
+	while (node) {
+		float percent;
+
+		child = rb_entry(node, struct hist_entry, rb_node);
+		percent = hist_entry__get_percent_limit(child);
+
+		if (!child->filtered && percent >= hb->min_pcnt) {
+			count++;
+
+			if (include_children && child->unfolded)
+				count += hierarchy_count_rows(hb, child, true);
+		}
+
+		node = rb_next(node);
+	}
+	return count;
+}
+
 static bool hist_entry__toggle_fold(struct hist_entry *he)
 {
 	if (!he)
@@ -326,11 +361,17 @@ static void callchain__init_have_children(struct rb_root *root)
 
 static void hist_entry__init_have_children(struct hist_entry *he)
 {
-	if (!he->init_have_children) {
+	if (he->init_have_children)
+		return;
+
+	if (he->leaf) {
 		he->has_children = !RB_EMPTY_ROOT(&he->sorted_chain);
 		callchain__init_have_children(&he->sorted_chain);
-		he->init_have_children = true;
+	} else {
+		he->has_children = !RB_EMPTY_ROOT(&he->hroot_out);
 	}
+
+	he->init_have_children = true;
 }
 
 static bool hist_browser__toggle_fold(struct hist_browser *browser)
@@ -349,17 +390,41 @@ static bool hist_browser__toggle_fold(struct hist_browser *browser)
 		has_children = callchain_list__toggle_fold(cl);
 
 	if (has_children) {
+		int child_rows = 0;
+
 		hist_entry__init_have_children(he);
 		browser->b.nr_entries -= he->nr_rows;
-		browser->nr_callchain_rows -= he->nr_rows;
 
-		if (he->unfolded)
-			he->nr_rows = callchain__count_rows(&he->sorted_chain);
+		if (he->leaf)
+			browser->nr_callchain_rows -= he->nr_rows;
 		else
+			browser->nr_hierarchy_entries -= he->nr_rows;
+
+		if (symbol_conf.report_hierarchy)
+			child_rows = hierarchy_count_rows(browser, he, true);
+
+		if (he->unfolded) {
+			if (he->leaf)
+				he->nr_rows = callchain__count_rows(&he->sorted_chain);
+			else
+				he->nr_rows = hierarchy_count_rows(browser, he, false);
+
+			/* account grand children */
+			if (symbol_conf.report_hierarchy)
+				browser->b.nr_entries += child_rows - he->nr_rows;
+		} else {
+			if (symbol_conf.report_hierarchy)
+				browser->b.nr_entries -= child_rows - he->nr_rows;
+
 			he->nr_rows = 0;
+		}
 
 		browser->b.nr_entries += he->nr_rows;
-		browser->nr_callchain_rows += he->nr_rows;
+
+		if (he->leaf)
+			browser->nr_callchain_rows += he->nr_rows;
+		else
+			browser->nr_hierarchy_entries += he->nr_rows;
 
 		return true;
 	}
@@ -1989,17 +2054,18 @@ static void hist_browser__update_nr_entries(struct hist_browser *hb)
 	u64 nr_entries = 0;
 	struct rb_node *nd = rb_first(&hb->hists->entries);
 
-	if (hb->min_pcnt == 0) {
+	if (hb->min_pcnt == 0 && !symbol_conf.report_hierarchy) {
 		hb->nr_non_filtered_entries = hb->hists->nr_non_filtered_entries;
 		return;
 	}
 
 	while ((nd = hists__filter_entries(nd, hb->min_pcnt)) != NULL) {
 		nr_entries++;
-		nd = rb_next(nd);
+		nd = rb_hierarchy_next(nd);
 	}
 
 	hb->nr_non_filtered_entries = nr_entries;
+	hb->nr_hierarchy_entries = nr_entries;
 }
 
 static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events,
-- 
2.6.4

[toc] | [prev] | [next] | [standalone]


#1311125

FromPekka Enberg <penberg@kernel.org>
Date2016-01-17 11:30 +0100
Message-ID<qRSKS-1cj-1@gated-at.bofh.it>
In reply to#1310972
On Sat, Jan 16, 2016 at 6:03 PM, Namhyung Kim <namhyung@kernel.org> wrote:
> This is v2 attempt of my earlier patchset [1].  This patchset
> implements a new feature that collects hist entries in a hierachical
> manner.  That means lower-level entries belong to an upper-level
> entry.  The entry hierachy is built on the sort keys given, so users
> can set it whatever they want.  It only shows top-level entries first,
> and user can expand/collapse it dynamically.

FWIW, for the series:

Acked-by: Pekka Enberg <penberg@kernel.org>

- Pekka

[toc] | [prev] | [next] | [standalone]


#1312096 — Re: [RFC/PATCHSET 00/17] perf tools: Add support for hierachy view (v2)

FromNamhyung Kim <namhyung@kernel.org>
Date2016-01-19 11:50 +0100
SubjectRe: [RFC/PATCHSET 00/17] perf tools: Add support for hierachy view (v2)
Message-ID<qSC1k-6y1-13@gated-at.bofh.it>
In reply to#1311125
Hi Pekka,

On Sun, Jan 17, 2016 at 12:25:00PM +0200, Pekka Enberg wrote:
> On Sat, Jan 16, 2016 at 6:03 PM, Namhyung Kim <namhyung@kernel.org> wrote:
> > This is v2 attempt of my earlier patchset [1].  This patchset
> > implements a new feature that collects hist entries in a hierachical
> > manner.  That means lower-level entries belong to an upper-level
> > entry.  The entry hierachy is built on the sort keys given, so users
> > can set it whatever they want.  It only shows top-level entries first,
> > and user can expand/collapse it dynamically.
> 
> FWIW, for the series:
> 
> Acked-by: Pekka Enberg <penberg@kernel.org>

Thank you!
Namhyung

[toc] | [prev] | [next] | [standalone]


#1311183 — Re: [RFC/PATCHSET 00/17] perf tools: Add support for hierachy view (v2)

FromAndi Kleen <andi@firstfloor.org>
Date2016-01-17 20:40 +0100
SubjectRe: [RFC/PATCHSET 00/17] perf tools: Add support for hierachy view (v2)
Message-ID<qS1l8-6M6-11@gated-at.bofh.it>
In reply to#1310972
On Sun, Jan 17, 2016 at 01:03:00AM +0900, Namhyung Kim wrote:
> Hello,
> 
> This is v2 attempt of my earlier patchset [1].  This patchset
> implements a new feature that collects hist entries in a hierachical
> manner.  That means lower-level entries belong to an upper-level
> entry.  The entry hierachy is built on the sort keys given, so users
> can set it whatever they want.  It only shows top-level entries first,
> and user can expand/collapse it dynamically.

Thanks that's very nice. Especially for TSX profiling it was always
very annoying that the other sort keys didn't actually sort.
It should be very useful for LBR view too.

Now we only need a better percent-limit that handles all
leaves correctly...

-Andi

[toc] | [prev] | [next] | [standalone]


#1312097 — Re: [RFC/PATCHSET 00/17] perf tools: Add support for hierachy view (v2)

FromNamhyung Kim <namhyung@kernel.org>
Date2016-01-19 11:50 +0100
SubjectRe: [RFC/PATCHSET 00/17] perf tools: Add support for hierachy view (v2)
Message-ID<qSC1k-6y1-15@gated-at.bofh.it>
In reply to#1311183
Hi Andi,

On Sun, Jan 17, 2016 at 08:31:53PM +0100, Andi Kleen wrote:
> On Sun, Jan 17, 2016 at 01:03:00AM +0900, Namhyung Kim wrote:
> > Hello,
> > 
> > This is v2 attempt of my earlier patchset [1].  This patchset
> > implements a new feature that collects hist entries in a hierachical
> > manner.  That means lower-level entries belong to an upper-level
> > entry.  The entry hierachy is built on the sort keys given, so users
> > can set it whatever they want.  It only shows top-level entries first,
> > and user can expand/collapse it dynamically.
> 
> Thanks that's very nice. Especially for TSX profiling it was always
> very annoying that the other sort keys didn't actually sort.
> It should be very useful for LBR view too.

Glad to hear that you like it. :)


> 
> Now we only need a better percent-limit that handles all
> leaves correctly...

Hmm.. could you tell me where the percent-limit doesn't work
correctly?

Thanks,
Namhyung

[toc] | [prev] | [next] | [standalone]


#1312515 — Re: [RFC/PATCHSET 00/17] perf tools: Add support for hierachy view (v2)

FromArnaldo Carvalho de Melo <acme@kernel.org>
Date2016-01-19 22:10 +0100
SubjectRe: [RFC/PATCHSET 00/17] perf tools: Add support for hierachy view (v2)
Message-ID<qSLHk-4Uh-17@gated-at.bofh.it>
In reply to#1312097
Em Tue, Jan 19, 2016 at 07:45:06PM +0900, Namhyung Kim escreveu:
> Hi Andi,
> 
> On Sun, Jan 17, 2016 at 08:31:53PM +0100, Andi Kleen wrote:
> > On Sun, Jan 17, 2016 at 01:03:00AM +0900, Namhyung Kim wrote:
> > > Hello,
> > > 
> > > This is v2 attempt of my earlier patchset [1].  This patchset
> > > implements a new feature that collects hist entries in a hierachical
> > > manner.  That means lower-level entries belong to an upper-level
> > > entry.  The entry hierachy is built on the sort keys given, so users
> > > can set it whatever they want.  It only shows top-level entries first,
> > > and user can expand/collapse it dynamically.
> > 
> > Thanks that's very nice. Especially for TSX profiling it was always
> > very annoying that the other sort keys didn't actually sort.
> > It should be very useful for LBR view too.
> 
> Glad to hear that you like it. :)
> 
> 
> > 
> > Now we only need a better percent-limit that handles all
> > leaves correctly...
> 
> Hmm.. could you tell me where the percent-limit doesn't work
> correctly?

Yeah, please elaborate, I'm testing:

perf top -s comm,dso,sym --hierarchy --percent-limit 0.5


And it seems to work...

- Arnaldo

[toc] | [prev] | [next] | [standalone]


#1312517 — Re: [RFC/PATCHSET 00/17] perf tools: Add support for hierachy view (v2)

FromArnaldo Carvalho de Melo <acme@kernel.org>
Date2016-01-19 22:10 +0100
SubjectRe: [RFC/PATCHSET 00/17] perf tools: Add support for hierachy view (v2)
Message-ID<qSLHl-4Uh-31@gated-at.bofh.it>
In reply to#1312515
Em Tue, Jan 19, 2016 at 06:03:39PM -0300, Arnaldo Carvalho de Melo escreveu:
> Em Tue, Jan 19, 2016 at 07:45:06PM +0900, Namhyung Kim escreveu:
> > On Sun, Jan 17, 2016 at 08:31:53PM +0100, Andi Kleen wrote:
> > > Now we only need a better percent-limit that handles all
> > > leaves correctly...

> > Hmm.. could you tell me where the percent-limit doesn't work
> > correctly?

> Yeah, please elaborate, I'm testing:

> perf top -s comm,dso,sym --hierarchy --percent-limit 0.5
> 
> And it seems to work...

For instance, running that top command above, then expanding some of the
callchains and pressing 'P' to generate a perf.hist.0 output file, all
obey the 0.5 threshold for discading entries with less than that
percentage, what is the problem you're noticing? Is it only in stdio or
what?

-  76.76%            cc1
   -  62.43%            cc1
          2.82%            [.] _cpp_lex_token
          1.59%            [.] ht_lookup_with_hash
          1.23%            [.] ggc_internal_alloc
          0.85%            [.] bitmap_set_bit
          0.53%            [.] cpp_get_token_with_location
          0.51%            [.] ht_lookup
   -   7.77%            libc-2.22.so
          2.06%            [.] _int_malloc
          0.84%            [.] _int_free
          0.57%            [.] _IO_putc
          0.55%            [.] malloc_consolidate
   -   5.86%            [kernel]
-   9.38%            as
   +   6.03%            as
   +   1.39%            [kernel]
   +   1.28%            libc-2.22.so
-   3.41%            gcc
   +   1.63%            [kernel]
   +   0.64%            [unknown]
   -   0.52%            ccache
+   2.28%            ld
+   1.85%            perf
+   1.45%            sh
+   1.16%            perl
+   0.55%            make

[toc] | [prev] | [next] | [standalone]


#1312554 — Re: [RFC/PATCHSET 00/17] perf tools: Add support for hierachy view (v2)

FromAndi Kleen <andi@firstfloor.org>
Date2016-01-19 23:20 +0100
SubjectRe: [RFC/PATCHSET 00/17] perf tools: Add support for hierachy view (v2)
Message-ID<qSMN3-5zF-9@gated-at.bofh.it>
In reply to#1312097
> > Now we only need a better percent-limit that handles all
> > leaves correctly...
> 
> Hmm.. could you tell me where the percent-limit doesn't work
> correctly?

It doesn't work well together with call chains.

It only considers the hits on the leaf function, but doesn't hide
the individual call chains leading to that function which are below
the limit.

So if you have a lot of different cold callers you still end up
with far too much output.

Also would be nice to be able to set it dynamically from the UI.

-Andi

-- 
ak@linux.intel.com -- Speaking for myself only.

[toc] | [prev] | [next] | [standalone]


#1312561 — Re: [RFC/PATCHSET 00/17] perf tools: Add support for hierachy view (v2)

FromArnaldo Carvalho de Melo <acme@kernel.org>
Date2016-01-19 23:30 +0100
SubjectRe: [RFC/PATCHSET 00/17] perf tools: Add support for hierachy view (v2)
Message-ID<qSMWK-5DX-23@gated-at.bofh.it>
In reply to#1312554
Em Tue, Jan 19, 2016 at 11:12:04PM +0100, Andi Kleen escreveu:
> > > Now we only need a better percent-limit that handles all
> > > leaves correctly...
> > 
> > Hmm.. could you tell me where the percent-limit doesn't work
> > correctly?
> 
> It doesn't work well together with call chains.

Ok, that is the missing piece of info, lemme check... Yeah that seems
to be the case.
 
> It only considers the hits on the leaf function, but doesn't hide
> the individual call chains leading to that function which are below
> the limit.
> 
> So if you have a lot of different cold callers you still end up
> with far too much output.
> 
> Also would be nice to be able to set it dynamically from the UI.

To set the mim percent? Yeah, we need to allow setting all those knobs
from the UI.

I.e. should be like when we press '/' to set a substring filter.

- Arnaldo

[toc] | [prev] | [next] | [standalone]


#1312630 — Re: [RFC/PATCHSET 00/17] perf tools: Add support for hierachy view (v2)

FromNamhyung Kim <namhyung@kernel.org>
Date2016-01-20 02:00 +0100
SubjectRe: [RFC/PATCHSET 00/17] perf tools: Add support for hierachy view (v2)
Message-ID<qSPhX-77l-65@gated-at.bofh.it>
In reply to#1312561
On Tue, Jan 19, 2016 at 07:24:49PM -0300, Arnaldo Carvalho de Melo wrote:
> Em Tue, Jan 19, 2016 at 11:12:04PM +0100, Andi Kleen escreveu:
> > > > Now we only need a better percent-limit that handles all
> > > > leaves correctly...
> > > 
> > > Hmm.. could you tell me where the percent-limit doesn't work
> > > correctly?
> > 
> > It doesn't work well together with call chains.
> 
> Ok, that is the missing piece of info, lemme check... Yeah that seems
> to be the case.

So technically this is a callchain issue not a hist entry, right?  If
so, it should be fixed separately.  Currently --percent-limit option
works only for hist entries, and for callchain, users should use
-g/--call-graph option.  With hierarchy report, we might consider
merging them since it provides continuous interface to callchains..


>  
> > It only considers the hits on the leaf function, but doesn't hide
> > the individual call chains leading to that function which are below
> > the limit.
> > 
> > So if you have a lot of different cold callers you still end up
> > with far too much output.

Could you please be more specific?  Let me try with an example..

  $ perf report
  ...
  +    1.00%  perf  perf  some_function
           some_function
         - common_caller
            - 0.6% caller1
              + 0.4% caller1_1
              + 0.2% caller1_2
            + 0.3% caller2
            + 0.1% caller3

In this case, do you want this?

  $ perf report --percent-limit 0.5
  ...
  +    1.00%  perf  perf  some_function
           some_function
         - common_caller
            - 0.6% caller1


> > 
> > Also would be nice to be able to set it dynamically from the UI.
> 
> To set the mim percent? Yeah, we need to allow setting all those knobs
> from the UI.
> 
> I.e. should be like when we press '/' to set a substring filter.

Yes, how about 'L' key for limit?

Thanks,
Namhyung

[toc] | [prev] | [next] | [standalone]


#1312758 — Re: [RFC/PATCHSET 00/17] perf tools: Add support for hierachy view (v2)

FromNamhyung Kim <namhyung@kernel.org>
Date2016-01-20 02:40 +0100
SubjectRe: [RFC/PATCHSET 00/17] perf tools: Add support for hierachy view (v2)
Message-ID<qSPUF-7Iz-79@gated-at.bofh.it>
In reply to#1312630
Hi Andi,

On Wed, Jan 20, 2016 at 02:11:00AM +0100, Andi Kleen wrote:
> On Wed, Jan 20, 2016 at 09:56:47AM +0900, Namhyung Kim wrote:
> > On Tue, Jan 19, 2016 at 07:24:49PM -0300, Arnaldo Carvalho de Melo wrote:
> > > Em Tue, Jan 19, 2016 at 11:12:04PM +0100, Andi Kleen escreveu:
> > > > It only considers the hits on the leaf function, but doesn't hide
> > > > the individual call chains leading to that function which are below
> > > > the limit.
> > > > 
> > > > So if you have a lot of different cold callers you still end up
> > > > with far too much output.
> > 
> > Could you please be more specific?  Let me try with an example..
> > 
> >   $ perf report
> >   ...
> >   +    1.00%  perf  perf  some_function
> >            some_function
> >          - common_caller
> >             - 0.6% caller1
> >               + 0.4% caller1_1
> >               + 0.2% caller1_2
> >             + 0.3% caller2
> >             + 0.1% caller3
> > 
> > In this case, do you want this?
> > 
> >   $ perf report --percent-limit 0.5
> >   ...
> >   +    1.00%  perf  perf  some_function
> >            some_function
> >          - common_caller
> >             - 0.6% caller1
> 
> Right. Only call chains whose total percentage is larger than the limit.

So in this case, caller1_1 and caller1_2 are both under the percent
limit but after they merged at caller1, it should be shown.  Look like
a reasonable result.  I'll add it into my TODO list. :)

Btw, is it all you wanted to say?  Is there any other case for trouble
(wrt callchain percent limit)?

Thanks,
Namhyung

[toc] | [prev] | [next] | [standalone]


#1312773 — Re: [RFC/PATCHSET 00/17] perf tools: Add support for hierachy view (v2)

FromAndi Kleen <andi@firstfloor.org>
Date2016-01-20 02:50 +0100
SubjectRe: [RFC/PATCHSET 00/17] perf tools: Add support for hierachy view (v2)
Message-ID<qSQ4i-7Np-17@gated-at.bofh.it>
In reply to#1312758
> Btw, is it all you wanted to say?  Is there any other case for trouble
> (wrt callchain percent limit)?

Yes that's all.  Don't know of more issues.

-Andi


-- 
ak@linux.intel.com -- Speaking for myself only.

[toc] | [prev] | [next] | [standalone]


Page 3 of 4 — ← Prev page 1 2 [3] 4  Next page →

Back to top | Article view | linux.kernel


csiph-web