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 2 of 4 — ← Prev page 1 [2] 3 4  Next page →


#1310978 — [PATCH 08/17] perf hists browser: Fix context menu item

FromNamhyung Kim <namhyung@kernel.org>
Date2016-01-16 17:10 +0100
Subject[PATCH 08/17] perf hists browser: Fix context menu item
Message-ID<qRBAn-6Ad-31@gated-at.bofh.it>
In reply to#1310972
When symbol sort key is not given, it doesn't show any item other than
exit.  Check sort key to select possible items.  Also check items more
strictly using sort key information.

Signed-off-by: Namhyung Kim <namhyung@kernel.org>
---
 tools/perf/ui/browsers/hists.c | 50 ++++++++++++++++++++++++------------------
 tools/perf/util/sort.c         |  3 +++
 tools/perf/util/sort.h         |  2 ++
 3 files changed, 34 insertions(+), 21 deletions(-)

diff --git a/tools/perf/ui/browsers/hists.c b/tools/perf/ui/browsers/hists.c
index 08c09ad755d2..cd6349ebd0d6 100644
--- a/tools/perf/ui/browsers/hists.c
+++ b/tools/perf/ui/browsers/hists.c
@@ -2263,10 +2263,7 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events,
 			continue;
 		}
 
-		if (!sort__has_sym)
-			goto add_exit_option;
-
-		if (browser->selection == NULL)
+		if (!sort__has_sym || browser->selection == NULL)
 			goto skip_annotation;
 
 		if (sort__mode == SORT_MODE__BRANCH) {
@@ -2294,23 +2291,33 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events,
 						       browser->selection->sym);
 		}
 skip_annotation:
-		nr_options += add_thread_opt(browser, &actions[nr_options],
-					     &options[nr_options], thread);
-		nr_options += add_dso_opt(browser, &actions[nr_options],
-					  &options[nr_options], map);
-		nr_options += add_map_opt(browser, &actions[nr_options],
-					  &options[nr_options],
-					  browser->selection ?
-						browser->selection->map : NULL);
-		nr_options += add_socket_opt(browser, &actions[nr_options],
-					     &options[nr_options],
-					     socked_id);
+		if (sort__has_thread) {
+			nr_options += add_thread_opt(browser, &actions[nr_options],
+						     &options[nr_options], thread);
+		}
+		if (sort__has_dso) {
+			nr_options += add_dso_opt(browser, &actions[nr_options],
+						  &options[nr_options], map);
+			nr_options += add_map_opt(browser, &actions[nr_options],
+						  &options[nr_options],
+						  browser->selection ?
+						  browser->selection->map : NULL);
+		}
+		if (sort__has_socket) {
+			nr_options += add_socket_opt(browser, &actions[nr_options],
+						     &options[nr_options],
+						     socked_id);
+		}
+
 		/* perf script support */
 		if (browser->he_selection) {
-			nr_options += add_script_opt(browser,
-						     &actions[nr_options],
-						     &options[nr_options],
-						     thread, NULL);
+			if (sort__has_thread) {
+				nr_options += add_script_opt(browser,
+							     &actions[nr_options],
+							     &options[nr_options],
+							     thread, NULL);
+			}
+
 			/*
 			 * Note that browser->selection != NULL
 			 * when browser->he_selection is not NULL,
@@ -2320,16 +2327,17 @@ skip_annotation:
 			 *
 			 * See hist_browser__show_entry.
 			 */
-			nr_options += add_script_opt(browser,
+			if (sort__has_sym && browser->selection->sym) {
+				nr_options += add_script_opt(browser,
 						     &actions[nr_options],
 						     &options[nr_options],
 						     NULL, browser->selection->sym);
+			}
 		}
 		nr_options += add_script_opt(browser, &actions[nr_options],
 					     &options[nr_options], NULL, NULL);
 		nr_options += add_switch_opt(browser, &actions[nr_options],
 					     &options[nr_options]);
-add_exit_option:
 		nr_options += add_exit_opt(browser, &actions[nr_options],
 					   &options[nr_options]);
 
diff --git a/tools/perf/util/sort.c b/tools/perf/util/sort.c
index 4632475bc5e4..8ff873ee39a8 100644
--- a/tools/perf/util/sort.c
+++ b/tools/perf/util/sort.c
@@ -21,6 +21,7 @@ const char	*field_order;
 regex_t		ignore_callees_regex;
 int		have_ignore_callees = 0;
 int		sort__need_collapse = 0;
+int		sort__has_thread = 0;
 int		sort__has_parent = 0;
 int		sort__has_sym = 0;
 int		sort__has_dso = 0;
@@ -2249,6 +2250,8 @@ static int sort_dimension__add(const char *tok,
 			sort__has_dso = 1;
 		} else if (sd->entry == &sort_socket) {
 			sort__has_socket = 1;
+		} else if (sd->entry == &sort_comm || sd->entry == &sort_thread) {
+			sort__has_thread = 1;
 		}
 
 		return __sort_dimension__add(sd);
diff --git a/tools/perf/util/sort.h b/tools/perf/util/sort.h
index 051739615847..879513e61dba 100644
--- a/tools/perf/util/sort.h
+++ b/tools/perf/util/sort.h
@@ -32,7 +32,9 @@ extern const char default_sort_order[];
 extern regex_t ignore_callees_regex;
 extern int have_ignore_callees;
 extern int sort__need_collapse;
+extern int sort__has_thread;
 extern int sort__has_parent;
+extern int sort__has_dso;
 extern int sort__has_sym;
 extern int sort__has_socket;
 extern enum sort_mode sort__mode;
-- 
2.6.4

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


#1313758 — Re: [PATCH 08/17] perf hists browser: Fix context menu item

FromArnaldo Carvalho de Melo <acme@kernel.org>
Date2016-01-21 02:00 +0100
SubjectRe: [PATCH 08/17] perf hists browser: Fix context menu item
Message-ID<qTbLs-5Sa-3@gated-at.bofh.it>
In reply to#1310978
Em Sun, Jan 17, 2016 at 01:03:08AM +0900, Namhyung Kim escreveu:
> When symbol sort key is not given, it doesn't show any item other than
> exit.  Check sort key to select possible items.  Also check items more
> strictly using sort key information.

So, without this patch when I press enter on 'perf top' I can zoom into
threads, with it I lose that option.

- Arnaldo
 
> Signed-off-by: Namhyung Kim <namhyung@kernel.org>
> ---
>  tools/perf/ui/browsers/hists.c | 50 ++++++++++++++++++++++++------------------
>  tools/perf/util/sort.c         |  3 +++
>  tools/perf/util/sort.h         |  2 ++
>  3 files changed, 34 insertions(+), 21 deletions(-)
> 
> diff --git a/tools/perf/ui/browsers/hists.c b/tools/perf/ui/browsers/hists.c
> index 08c09ad755d2..cd6349ebd0d6 100644
> --- a/tools/perf/ui/browsers/hists.c
> +++ b/tools/perf/ui/browsers/hists.c
> @@ -2263,10 +2263,7 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events,
>  			continue;
>  		}
>  
> -		if (!sort__has_sym)
> -			goto add_exit_option;
> -
> -		if (browser->selection == NULL)
> +		if (!sort__has_sym || browser->selection == NULL)
>  			goto skip_annotation;
>  
>  		if (sort__mode == SORT_MODE__BRANCH) {
> @@ -2294,23 +2291,33 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events,
>  						       browser->selection->sym);
>  		}
>  skip_annotation:
> -		nr_options += add_thread_opt(browser, &actions[nr_options],
> -					     &options[nr_options], thread);
> -		nr_options += add_dso_opt(browser, &actions[nr_options],
> -					  &options[nr_options], map);
> -		nr_options += add_map_opt(browser, &actions[nr_options],
> -					  &options[nr_options],
> -					  browser->selection ?
> -						browser->selection->map : NULL);
> -		nr_options += add_socket_opt(browser, &actions[nr_options],
> -					     &options[nr_options],
> -					     socked_id);
> +		if (sort__has_thread) {
> +			nr_options += add_thread_opt(browser, &actions[nr_options],
> +						     &options[nr_options], thread);
> +		}
> +		if (sort__has_dso) {
> +			nr_options += add_dso_opt(browser, &actions[nr_options],
> +						  &options[nr_options], map);
> +			nr_options += add_map_opt(browser, &actions[nr_options],
> +						  &options[nr_options],
> +						  browser->selection ?
> +						  browser->selection->map : NULL);
> +		}
> +		if (sort__has_socket) {
> +			nr_options += add_socket_opt(browser, &actions[nr_options],
> +						     &options[nr_options],
> +						     socked_id);
> +		}
> +
>  		/* perf script support */
>  		if (browser->he_selection) {
> -			nr_options += add_script_opt(browser,
> -						     &actions[nr_options],
> -						     &options[nr_options],
> -						     thread, NULL);
> +			if (sort__has_thread) {
> +				nr_options += add_script_opt(browser,
> +							     &actions[nr_options],
> +							     &options[nr_options],
> +							     thread, NULL);
> +			}
> +
>  			/*
>  			 * Note that browser->selection != NULL
>  			 * when browser->he_selection is not NULL,
> @@ -2320,16 +2327,17 @@ skip_annotation:
>  			 *
>  			 * See hist_browser__show_entry.
>  			 */
> -			nr_options += add_script_opt(browser,
> +			if (sort__has_sym && browser->selection->sym) {
> +				nr_options += add_script_opt(browser,
>  						     &actions[nr_options],
>  						     &options[nr_options],
>  						     NULL, browser->selection->sym);
> +			}
>  		}
>  		nr_options += add_script_opt(browser, &actions[nr_options],
>  					     &options[nr_options], NULL, NULL);
>  		nr_options += add_switch_opt(browser, &actions[nr_options],
>  					     &options[nr_options]);
> -add_exit_option:
>  		nr_options += add_exit_opt(browser, &actions[nr_options],
>  					   &options[nr_options]);
>  
> diff --git a/tools/perf/util/sort.c b/tools/perf/util/sort.c
> index 4632475bc5e4..8ff873ee39a8 100644
> --- a/tools/perf/util/sort.c
> +++ b/tools/perf/util/sort.c
> @@ -21,6 +21,7 @@ const char	*field_order;
>  regex_t		ignore_callees_regex;
>  int		have_ignore_callees = 0;
>  int		sort__need_collapse = 0;
> +int		sort__has_thread = 0;
>  int		sort__has_parent = 0;
>  int		sort__has_sym = 0;
>  int		sort__has_dso = 0;
> @@ -2249,6 +2250,8 @@ static int sort_dimension__add(const char *tok,
>  			sort__has_dso = 1;
>  		} else if (sd->entry == &sort_socket) {
>  			sort__has_socket = 1;
> +		} else if (sd->entry == &sort_comm || sd->entry == &sort_thread) {
> +			sort__has_thread = 1;
>  		}
>  
>  		return __sort_dimension__add(sd);
> diff --git a/tools/perf/util/sort.h b/tools/perf/util/sort.h
> index 051739615847..879513e61dba 100644
> --- a/tools/perf/util/sort.h
> +++ b/tools/perf/util/sort.h
> @@ -32,7 +32,9 @@ extern const char default_sort_order[];
>  extern regex_t ignore_callees_regex;
>  extern int have_ignore_callees;
>  extern int sort__need_collapse;
> +extern int sort__has_thread;
>  extern int sort__has_parent;
> +extern int sort__has_dso;
>  extern int sort__has_sym;
>  extern int sort__has_socket;
>  extern enum sort_mode sort__mode;
> -- 
> 2.6.4

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


#1313848 — Re: [PATCH 08/17] perf hists browser: Fix context menu item

FromNamhyung Kim <namhyung@kernel.org>
Date2016-01-21 05:10 +0100
SubjectRe: [PATCH 08/17] perf hists browser: Fix context menu item
Message-ID<qTeJj-8hS-1@gated-at.bofh.it>
In reply to#1313758
On Wed, Jan 20, 2016 at 09:52:45PM -0300, Arnaldo Carvalho de Melo wrote:
> Em Sun, Jan 17, 2016 at 01:03:08AM +0900, Namhyung Kim escreveu:
> > When symbol sort key is not given, it doesn't show any item other than
> > exit.  Check sort key to select possible items.  Also check items more
> > strictly using sort key information.
> 
> So, without this patch when I press enter on 'perf top' I can zoom into
> threads, with it I lose that option.

Yes, but it was incorrect information.  The default sort key of 'perf
top' doesn't contain 'comm' (or 'pid') so hist entries it shows can
have samples from different threads.  The result is that it only shows
thread of the first sample of the entry.  Filtering based on this
incorrect info should be avoided IMHO.

Thanks,
Namhyung

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


#1314651 — Re: [PATCH 08/17] perf hists browser: Fix context menu item

FromArnaldo Carvalho de Melo <acme@kernel.org>
Date2016-01-22 01:00 +0100
SubjectRe: [PATCH 08/17] perf hists browser: Fix context menu item
Message-ID<qTxiW-3Zo-9@gated-at.bofh.it>
In reply to#1313848
Em Thu, Jan 21, 2016 at 01:07:10PM +0900, Namhyung Kim escreveu:
> On Wed, Jan 20, 2016 at 09:52:45PM -0300, Arnaldo Carvalho de Melo wrote:
> > Em Sun, Jan 17, 2016 at 01:03:08AM +0900, Namhyung Kim escreveu:
> > > When symbol sort key is not given, it doesn't show any item other than
> > > exit.  Check sort key to select possible items.  Also check items more
> > > strictly using sort key information.

> > So, without this patch when I press enter on 'perf top' I can zoom into
> > threads, with it I lose that option.
 
> Yes, but it was incorrect information.  The default sort key of 'perf
> top' doesn't contain 'comm' (or 'pid') so hist entries it shows can
> have samples from different threads.  The result is that it only shows
> thread of the first sample of the entry.  Filtering based on this
> incorrect info should be avoided IMHO.

Ok, agreed, but this patch is doing way too many things at once, please
take a look at my current perf/core branch, it has the first few patches
I carved out from this one, see if you are ok with it, will continue.

And this is not hierarchy related, so will go first, as fixes in
perf/core.

- Arnaldo

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


#1314908 — Re: [PATCH 08/17] perf hists browser: Fix context menu item

FromNamhyung Kim <namhyung@kernel.org>
Date2016-01-22 12:10 +0100
SubjectRe: [PATCH 08/17] perf hists browser: Fix context menu item
Message-ID<qTHLn-3dT-91@gated-at.bofh.it>
In reply to#1314651
On Thu, Jan 21, 2016 at 08:51:33PM -0300, Arnaldo Carvalho de Melo wrote:
> Em Thu, Jan 21, 2016 at 01:07:10PM +0900, Namhyung Kim escreveu:
> > On Wed, Jan 20, 2016 at 09:52:45PM -0300, Arnaldo Carvalho de Melo wrote:
> > > Em Sun, Jan 17, 2016 at 01:03:08AM +0900, Namhyung Kim escreveu:
> > > > When symbol sort key is not given, it doesn't show any item other than
> > > > exit.  Check sort key to select possible items.  Also check items more
> > > > strictly using sort key information.
> 
> > > So, without this patch when I press enter on 'perf top' I can zoom into
> > > threads, with it I lose that option.
>  
> > Yes, but it was incorrect information.  The default sort key of 'perf
> > top' doesn't contain 'comm' (or 'pid') so hist entries it shows can
> > have samples from different threads.  The result is that it only shows
> > thread of the first sample of the entry.  Filtering based on this
> > incorrect info should be avoided IMHO.
> 
> Ok, agreed, but this patch is doing way too many things at once, please
> take a look at my current perf/core branch, it has the first few patches
> I carved out from this one, see if you are ok with it, will continue.

Look good to me!

> 
> And this is not hierarchy related, so will go first, as fixes in
> perf/core.

Thanks,
Namhyung

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


#1315043 — Dynamicly add/remove sort keys was: Re: [PATCH 08/17] perf hists browser: Fix context menu item

FromArnaldo Carvalho de Melo <acme@kernel.org>
Date2016-01-22 15:40 +0100
SubjectDynamicly add/remove sort keys was: Re: [PATCH 08/17] perf hists browser: Fix context menu item
Message-ID<qTL2z-5iq-45@gated-at.bofh.it>
In reply to#1310978
Hi Namhyung,

	While continuing to process this series, I thought about one new
feature: A popup menu that would allow adding/removing sort keys, which
would entail resorting with the new sort order, what do you think?

	It may be relatively simple to implement, or I may be missing
something, this is just a brainstorm...

	To avoid reprocessing everything, which may not even be
possible (perf top case) we could mark the field as such and when
showing such hist_entries it would have a <?> marker.

	Say DSO wasn't in the sort order, then each bucket wouldn't be
for just one DSO, sure, in this case, when invoking the popup to add DSO
to the sort order, we would keep those old hist entries around but when
showing them the column for DSO would have <?>, in the top case those
would at some point decay, with the new ones with this info appearing as
time goes by.

	This is part of a general trend of removing the need to restart
the session when wanting to change the sort order, min percent, max
stack, etc, etc.

	Anyway, back to processing patches :-)

- Arnaldo

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


#1310979 — [PATCH 04/17] perf hists: Cleanup filtering functions

FromNamhyung Kim <namhyung@kernel.org>
Date2016-01-16 17:10 +0100
Subject[PATCH 04/17] perf hists: Cleanup filtering functions
Message-ID<qRBAn-6Ad-27@gated-at.bofh.it>
In reply to#1310972
The hists__filter_by_xxx functions share same logic with different
filters.  Factor out the common code into the hists__filter_by_type.

The hists__filter_by_dso() code contained a check for parent, but I
think it should not be there.  The PARENT filter bit was set by
symbol__parent_filter() which is related to symbol instead of dso.  Also
it didn't change the filter state anyway so end result will be same.

Signed-off-by: Namhyung Kim <namhyung@kernel.org>
---
 tools/perf/util/hist.c | 92 ++++++++++++++++----------------------------------
 1 file changed, 29 insertions(+), 63 deletions(-)

diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c
index 9354455aec5b..0790c053f65c 100644
--- a/tools/perf/util/hist.c
+++ b/tools/perf/util/hist.c
@@ -1471,28 +1471,6 @@ static bool hists__filter_entry_by_dso(struct hists *hists,
 	return false;
 }
 
-void hists__filter_by_dso(struct hists *hists)
-{
-	struct rb_node *nd;
-
-	hists->stats.nr_non_filtered_samples = 0;
-
-	hists__reset_filter_stats(hists);
-	hists__reset_col_len(hists);
-
-	for (nd = rb_first(&hists->entries); nd; nd = rb_next(nd)) {
-		struct hist_entry *h = rb_entry(nd, struct hist_entry, rb_node);
-
-		if (symbol_conf.exclude_other && !h->parent)
-			continue;
-
-		if (hists__filter_entry_by_dso(hists, h))
-			continue;
-
-		hists__remove_entry_filter(hists, h, HIST_FILTER__DSO);
-	}
-}
-
 static bool hists__filter_entry_by_thread(struct hists *hists,
 					  struct hist_entry *he)
 {
@@ -1505,25 +1483,6 @@ static bool hists__filter_entry_by_thread(struct hists *hists,
 	return false;
 }
 
-void hists__filter_by_thread(struct hists *hists)
-{
-	struct rb_node *nd;
-
-	hists->stats.nr_non_filtered_samples = 0;
-
-	hists__reset_filter_stats(hists);
-	hists__reset_col_len(hists);
-
-	for (nd = rb_first(&hists->entries); nd; nd = rb_next(nd)) {
-		struct hist_entry *h = rb_entry(nd, struct hist_entry, rb_node);
-
-		if (hists__filter_entry_by_thread(hists, h))
-			continue;
-
-		hists__remove_entry_filter(hists, h, HIST_FILTER__THREAD);
-	}
-}
-
 static bool hists__filter_entry_by_symbol(struct hists *hists,
 					  struct hist_entry *he)
 {
@@ -1537,25 +1496,6 @@ static bool hists__filter_entry_by_symbol(struct hists *hists,
 	return false;
 }
 
-void hists__filter_by_symbol(struct hists *hists)
-{
-	struct rb_node *nd;
-
-	hists->stats.nr_non_filtered_samples = 0;
-
-	hists__reset_filter_stats(hists);
-	hists__reset_col_len(hists);
-
-	for (nd = rb_first(&hists->entries); nd; nd = rb_next(nd)) {
-		struct hist_entry *h = rb_entry(nd, struct hist_entry, rb_node);
-
-		if (hists__filter_entry_by_symbol(hists, h))
-			continue;
-
-		hists__remove_entry_filter(hists, h, HIST_FILTER__SYMBOL);
-	}
-}
-
 static bool hists__filter_entry_by_socket(struct hists *hists,
 					  struct hist_entry *he)
 {
@@ -1568,7 +1508,9 @@ static bool hists__filter_entry_by_socket(struct hists *hists,
 	return false;
 }
 
-void hists__filter_by_socket(struct hists *hists)
+typedef bool (*filter_fn_t)(struct hists *hists, struct hist_entry *he);
+
+static void hists__filter_by_type(struct hists *hists, int type, filter_fn_t filter)
 {
 	struct rb_node *nd;
 
@@ -1580,13 +1522,37 @@ void hists__filter_by_socket(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);
 
-		if (hists__filter_entry_by_socket(hists, h))
+		if (filter(hists, h))
 			continue;
 
-		hists__remove_entry_filter(hists, h, HIST_FILTER__SOCKET);
+		hists__remove_entry_filter(hists, h, type);
 	}
 }
 
+void hists__filter_by_thread(struct hists *hists)
+{
+	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);
+}
+
+void hists__filter_by_symbol(struct hists *hists)
+{
+	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);
+}
+
 void events_stats__inc(struct events_stats *stats, u32 type)
 {
 	++stats->nr_events[0];
-- 
2.6.4

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


#1312498 — Re: [PATCH 04/17] perf hists: Cleanup filtering functions

FromArnaldo Carvalho de Melo <acme@kernel.org>
Date2016-01-19 21:40 +0100
SubjectRe: [PATCH 04/17] perf hists: Cleanup filtering functions
Message-ID<qSLej-4ue-31@gated-at.bofh.it>
In reply to#1310979
Em Sun, Jan 17, 2016 at 01:03:04AM +0900, Namhyung Kim escreveu:
> The hists__filter_by_xxx functions share same logic with different
> filters.  Factor out the common code into the hists__filter_by_type.
> 
> The hists__filter_by_dso() code contained a check for parent, but I
> think it should not be there.  The PARENT filter bit was set by
> symbol__parent_filter() which is related to symbol instead of dso.  Also

Ok, so break the patch in two, one removing the check for parent in
hists__filter_by_dso(), then the patch introducing the function that
receives the filter callback + type,

Thanks,

- Arnaldo

> it didn't change the filter state anyway so end result will be same.
> 
> Signed-off-by: Namhyung Kim <namhyung@kernel.org>
> ---
>  tools/perf/util/hist.c | 92 ++++++++++++++++----------------------------------
>  1 file changed, 29 insertions(+), 63 deletions(-)
> 
> diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c
> index 9354455aec5b..0790c053f65c 100644
> --- a/tools/perf/util/hist.c
> +++ b/tools/perf/util/hist.c
> @@ -1471,28 +1471,6 @@ static bool hists__filter_entry_by_dso(struct hists *hists,
>  	return false;
>  }
>  
> -void hists__filter_by_dso(struct hists *hists)
> -{
> -	struct rb_node *nd;
> -
> -	hists->stats.nr_non_filtered_samples = 0;
> -
> -	hists__reset_filter_stats(hists);
> -	hists__reset_col_len(hists);
> -
> -	for (nd = rb_first(&hists->entries); nd; nd = rb_next(nd)) {
> -		struct hist_entry *h = rb_entry(nd, struct hist_entry, rb_node);
> -
> -		if (symbol_conf.exclude_other && !h->parent)
> -			continue;
> -
> -		if (hists__filter_entry_by_dso(hists, h))
> -			continue;
> -
> -		hists__remove_entry_filter(hists, h, HIST_FILTER__DSO);
> -	}
> -}
> -
>  static bool hists__filter_entry_by_thread(struct hists *hists,
>  					  struct hist_entry *he)
>  {
> @@ -1505,25 +1483,6 @@ static bool hists__filter_entry_by_thread(struct hists *hists,
>  	return false;
>  }
>  
> -void hists__filter_by_thread(struct hists *hists)
> -{
> -	struct rb_node *nd;
> -
> -	hists->stats.nr_non_filtered_samples = 0;
> -
> -	hists__reset_filter_stats(hists);
> -	hists__reset_col_len(hists);
> -
> -	for (nd = rb_first(&hists->entries); nd; nd = rb_next(nd)) {
> -		struct hist_entry *h = rb_entry(nd, struct hist_entry, rb_node);
> -
> -		if (hists__filter_entry_by_thread(hists, h))
> -			continue;
> -
> -		hists__remove_entry_filter(hists, h, HIST_FILTER__THREAD);
> -	}
> -}
> -
>  static bool hists__filter_entry_by_symbol(struct hists *hists,
>  					  struct hist_entry *he)
>  {
> @@ -1537,25 +1496,6 @@ static bool hists__filter_entry_by_symbol(struct hists *hists,
>  	return false;
>  }
>  
> -void hists__filter_by_symbol(struct hists *hists)
> -{
> -	struct rb_node *nd;
> -
> -	hists->stats.nr_non_filtered_samples = 0;
> -
> -	hists__reset_filter_stats(hists);
> -	hists__reset_col_len(hists);
> -
> -	for (nd = rb_first(&hists->entries); nd; nd = rb_next(nd)) {
> -		struct hist_entry *h = rb_entry(nd, struct hist_entry, rb_node);
> -
> -		if (hists__filter_entry_by_symbol(hists, h))
> -			continue;
> -
> -		hists__remove_entry_filter(hists, h, HIST_FILTER__SYMBOL);
> -	}
> -}
> -
>  static bool hists__filter_entry_by_socket(struct hists *hists,
>  					  struct hist_entry *he)
>  {
> @@ -1568,7 +1508,9 @@ static bool hists__filter_entry_by_socket(struct hists *hists,
>  	return false;
>  }
>  
> -void hists__filter_by_socket(struct hists *hists)
> +typedef bool (*filter_fn_t)(struct hists *hists, struct hist_entry *he);
> +
> +static void hists__filter_by_type(struct hists *hists, int type, filter_fn_t filter)
>  {
>  	struct rb_node *nd;
>  
> @@ -1580,13 +1522,37 @@ void hists__filter_by_socket(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);
>  
> -		if (hists__filter_entry_by_socket(hists, h))
> +		if (filter(hists, h))
>  			continue;
>  
> -		hists__remove_entry_filter(hists, h, HIST_FILTER__SOCKET);
> +		hists__remove_entry_filter(hists, h, type);
>  	}
>  }
>  
> +void hists__filter_by_thread(struct hists *hists)
> +{
> +	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);
> +}
> +
> +void hists__filter_by_symbol(struct hists *hists)
> +{
> +	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);
> +}
> +
>  void events_stats__inc(struct events_stats *stats, u32 type)
>  {
>  	++stats->nr_events[0];
> -- 
> 2.6.4

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


#1312695 — [PATCH v2 04.1/17] perf hists: Remove parent filter check in DSO filter function

FromNamhyung Kim <namhyung@kernel.org>
Date2016-01-20 02:30 +0100
Subject[PATCH v2 04.1/17] perf hists: Remove parent filter check in DSO filter function
Message-ID<qSPKW-7CF-1@gated-at.bofh.it>
In reply to#1312498
The --exclude-other option sets HIST_FILTER__PARENT bit and it's only
set when a hist entry was created.  DSO filters don't change this so
no need to have the check in hists__filter_by_dso() IMHO.

Signed-off-by: Namhyung Kim <namhyung@kernel.org>
---
 tools/perf/util/hist.c | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c
index 9354455aec5b..7c9af05726ad 100644
--- a/tools/perf/util/hist.c
+++ b/tools/perf/util/hist.c
@@ -1483,9 +1483,6 @@ void hists__filter_by_dso(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);
 
-		if (symbol_conf.exclude_other && !h->parent)
-			continue;
-
 		if (hists__filter_entry_by_dso(hists, h))
 			continue;
 
-- 
2.7.0

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


#1312699 — [PATCH v2 04.2/17] perf hists: Cleanup filtering functions

FromNamhyung Kim <namhyung@kernel.org>
Date2016-01-20 02:30 +0100
Subject[PATCH v2 04.2/17] perf hists: Cleanup filtering functions
Message-ID<qSPKW-7CF-11@gated-at.bofh.it>
In reply to#1312695
The hists__filter_by_xxx functions share same logic with different
filters.  Factor out the common code into the hists__filter_by_type.

Signed-off-by: Namhyung Kim <namhyung@kernel.org>
---
 tools/perf/util/hist.c | 89 ++++++++++++++++----------------------------------
 1 file changed, 29 insertions(+), 60 deletions(-)

diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c
index 7c9af05726ad..0790c053f65c 100644
--- a/tools/perf/util/hist.c
+++ b/tools/perf/util/hist.c
@@ -1471,25 +1471,6 @@ static bool hists__filter_entry_by_dso(struct hists *hists,
 	return false;
 }
 
-void hists__filter_by_dso(struct hists *hists)
-{
-	struct rb_node *nd;
-
-	hists->stats.nr_non_filtered_samples = 0;
-
-	hists__reset_filter_stats(hists);
-	hists__reset_col_len(hists);
-
-	for (nd = rb_first(&hists->entries); nd; nd = rb_next(nd)) {
-		struct hist_entry *h = rb_entry(nd, struct hist_entry, rb_node);
-
-		if (hists__filter_entry_by_dso(hists, h))
-			continue;
-
-		hists__remove_entry_filter(hists, h, HIST_FILTER__DSO);
-	}
-}
-
 static bool hists__filter_entry_by_thread(struct hists *hists,
 					  struct hist_entry *he)
 {
@@ -1502,25 +1483,6 @@ static bool hists__filter_entry_by_thread(struct hists *hists,
 	return false;
 }
 
-void hists__filter_by_thread(struct hists *hists)
-{
-	struct rb_node *nd;
-
-	hists->stats.nr_non_filtered_samples = 0;
-
-	hists__reset_filter_stats(hists);
-	hists__reset_col_len(hists);
-
-	for (nd = rb_first(&hists->entries); nd; nd = rb_next(nd)) {
-		struct hist_entry *h = rb_entry(nd, struct hist_entry, rb_node);
-
-		if (hists__filter_entry_by_thread(hists, h))
-			continue;
-
-		hists__remove_entry_filter(hists, h, HIST_FILTER__THREAD);
-	}
-}
-
 static bool hists__filter_entry_by_symbol(struct hists *hists,
 					  struct hist_entry *he)
 {
@@ -1534,25 +1496,6 @@ static bool hists__filter_entry_by_symbol(struct hists *hists,
 	return false;
 }
 
-void hists__filter_by_symbol(struct hists *hists)
-{
-	struct rb_node *nd;
-
-	hists->stats.nr_non_filtered_samples = 0;
-
-	hists__reset_filter_stats(hists);
-	hists__reset_col_len(hists);
-
-	for (nd = rb_first(&hists->entries); nd; nd = rb_next(nd)) {
-		struct hist_entry *h = rb_entry(nd, struct hist_entry, rb_node);
-
-		if (hists__filter_entry_by_symbol(hists, h))
-			continue;
-
-		hists__remove_entry_filter(hists, h, HIST_FILTER__SYMBOL);
-	}
-}
-
 static bool hists__filter_entry_by_socket(struct hists *hists,
 					  struct hist_entry *he)
 {
@@ -1565,7 +1508,9 @@ static bool hists__filter_entry_by_socket(struct hists *hists,
 	return false;
 }
 
-void hists__filter_by_socket(struct hists *hists)
+typedef bool (*filter_fn_t)(struct hists *hists, struct hist_entry *he);
+
+static void hists__filter_by_type(struct hists *hists, int type, filter_fn_t filter)
 {
 	struct rb_node *nd;
 
@@ -1577,13 +1522,37 @@ void hists__filter_by_socket(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);
 
-		if (hists__filter_entry_by_socket(hists, h))
+		if (filter(hists, h))
 			continue;
 
-		hists__remove_entry_filter(hists, h, HIST_FILTER__SOCKET);
+		hists__remove_entry_filter(hists, h, type);
 	}
 }
 
+void hists__filter_by_thread(struct hists *hists)
+{
+	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);
+}
+
+void hists__filter_by_symbol(struct hists *hists)
+{
+	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);
+}
+
 void events_stats__inc(struct events_stats *stats, u32 type)
 {
 	++stats->nr_events[0];
-- 
2.7.0

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


#1314144 — Re: [PATCH v2 04.2/17] perf hists: Cleanup filtering functions

FromJiri Olsa <jolsa@redhat.com>
Date2016-01-21 13:10 +0100
SubjectRe: [PATCH v2 04.2/17] perf hists: Cleanup filtering functions
Message-ID<qTmdR-545-43@gated-at.bofh.it>
In reply to#1312699
On Wed, Jan 20, 2016 at 10:15:21AM +0900, Namhyung Kim wrote:
> The hists__filter_by_xxx functions share same logic with different
> filters.  Factor out the common code into the hists__filter_by_type.
> 
> Signed-off-by: Namhyung Kim <namhyung@kernel.org>

Acked-by: Jiri Olsa <jolsa@kernel.org>

jirka

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


#1314140 — Re: [PATCH v2 04.1/17] perf hists: Remove parent filter check in DSO filter function

FromJiri Olsa <jolsa@redhat.com>
Date2016-01-21 13:10 +0100
SubjectRe: [PATCH v2 04.1/17] perf hists: Remove parent filter check in DSO filter function
Message-ID<qTmdQ-545-17@gated-at.bofh.it>
In reply to#1312695
On Wed, Jan 20, 2016 at 10:15:20AM +0900, Namhyung Kim wrote:
> The --exclude-other option sets HIST_FILTER__PARENT bit and it's only
> set when a hist entry was created.  DSO filters don't change this so
> no need to have the check in hists__filter_by_dso() IMHO.
> 
> Signed-off-by: Namhyung Kim <namhyung@kernel.org>

Acked-by: Jiri Olsa <jolsa@kernel.org>

jirka

> ---
>  tools/perf/util/hist.c | 3 ---
>  1 file changed, 3 deletions(-)
> 
> diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c
> index 9354455aec5b..7c9af05726ad 100644
> --- a/tools/perf/util/hist.c
> +++ b/tools/perf/util/hist.c
> @@ -1483,9 +1483,6 @@ void hists__filter_by_dso(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);
>  
> -		if (symbol_conf.exclude_other && !h->parent)
> -			continue;
> -
>  		if (hists__filter_entry_by_dso(hists, h))
>  			continue;
>  
> -- 
> 2.7.0
> 

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


#1310980 — [PATCH 02/17] perf hists: Resort hist entries with hierarchy

FromNamhyung Kim <namhyung@kernel.org>
Date2016-01-16 17:10 +0100
Subject[PATCH 02/17] perf hists: Resort hist entries with hierarchy
Message-ID<qRBAn-6Ad-25@gated-at.bofh.it>
In reply to#1310972
For hierarchical output, each entries should be sorted in their
rbtree (hroot) properly.  Add hists__hierarchy_output_resort() to do the
job.  Note that those hierarchy entries share the period counts, it'd be
important to update the hists->stats only once (for leaves).

Signed-off-by: Namhyung Kim <namhyung@kernel.org>
---
 tools/perf/util/hist.c | 82 ++++++++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 79 insertions(+), 3 deletions(-)

diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c
index 70293eb70430..931353f49c72 100644
--- a/tools/perf/util/hist.c
+++ b/tools/perf/util/hist.c
@@ -1245,6 +1245,74 @@ void hists__inc_stats(struct hists *hists, struct hist_entry *h)
 	hists->stats.total_period += h->stat.period;
 }
 
+static void hierarchy_insert_output_entry(struct rb_root *root,
+					  struct hist_entry *he)
+{
+	struct rb_node **p = &root->rb_node;
+	struct rb_node *parent = NULL;
+	struct hist_entry *iter;
+
+	while (*p != NULL) {
+		parent = *p;
+		iter = rb_entry(parent, struct hist_entry, rb_node);
+
+		if (hist_entry__sort(he, iter) > 0)
+			p = &parent->rb_left;
+		else
+			p = &parent->rb_right;
+	}
+
+	rb_link_node(&he->rb_node, parent, p);
+	rb_insert_color(&he->rb_node, root);
+}
+
+static void hists__hierarchy_output_resort(struct hists *hists,
+					   struct ui_progress *prog,
+					   struct rb_root *root_in,
+					   struct rb_root *root_out,
+					   u64 min_callchain_hits,
+					   bool use_callchain)
+{
+	struct rb_node *node;
+	struct hist_entry *he;
+
+	*root_out = RB_ROOT;
+	node = rb_first(root_in);
+
+	while (node) {
+		he = rb_entry(node, struct hist_entry, rb_node_in);
+		node = rb_next(node);
+
+		hierarchy_insert_output_entry(root_out, he);
+
+		if (prog)
+			ui_progress__update(prog, 1);
+
+		if (!he->leaf) {
+			hists__hierarchy_output_resort(hists, prog,
+						       &he->hroot_in,
+						       &he->hroot_out,
+						       min_callchain_hits,
+						       use_callchain);
+			hists->nr_entries++;
+			if (!he->filtered)
+				hists->nr_non_filtered_entries++;
+
+			continue;
+		}
+
+		/* only update stat for leaf entries to avoid duplication */
+		hists__inc_stats(hists, he);
+		if (!he->filtered)
+			hists__calc_col_len(hists, he);
+
+		if (use_callchain)
+			callchain_param.sort(&he->sorted_chain, he->callchain,
+					     min_callchain_hits,
+					     &callchain_param);
+	}
+}
+
 static void __hists__insert_output_entry(struct rb_root *entries,
 					 struct hist_entry *he,
 					 u64 min_callchain_hits,
@@ -1288,6 +1356,17 @@ void hists__output_resort(struct hists *hists, struct ui_progress *prog)
 
 	min_callchain_hits = hists->stats.total_period * (callchain_param.min_percent / 100);
 
+	hists__reset_stats(hists);
+	hists__reset_col_len(hists);
+
+	if (symbol_conf.report_hierarchy) {
+		return hists__hierarchy_output_resort(hists, prog,
+						      &hists->entries_collapsed,
+						      &hists->entries,
+						      min_callchain_hits,
+						      use_callchain);
+	}
+
 	if (sort__need_collapse)
 		root = &hists->entries_collapsed;
 	else
@@ -1296,9 +1375,6 @@ void hists__output_resort(struct hists *hists, struct ui_progress *prog)
 	next = rb_first(root);
 	hists->entries = RB_ROOT;
 
-	hists__reset_stats(hists);
-	hists__reset_col_len(hists);
-
 	while (next) {
 		n = rb_entry(next, struct hist_entry, rb_node_in);
 		next = rb_next(&n->rb_node_in);
-- 
2.6.4

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


#1314131 — Re: [PATCH 02/17] perf hists: Resort hist entries with hierarchy

FromJiri Olsa <jolsa@redhat.com>
Date2016-01-21 12:50 +0100
SubjectRe: [PATCH 02/17] perf hists: Resort hist entries with hierarchy
Message-ID<qTlUt-4G5-11@gated-at.bofh.it>
In reply to#1310980
On Sun, Jan 17, 2016 at 01:03:02AM +0900, Namhyung Kim wrote:

SNIP

> +					     min_callchain_hits,
> +					     &callchain_param);
> +	}
> +}
> +
>  static void __hists__insert_output_entry(struct rb_root *entries,
>  					 struct hist_entry *he,
>  					 u64 min_callchain_hits,
> @@ -1288,6 +1356,17 @@ void hists__output_resort(struct hists *hists, struct ui_progress *prog)
>  
>  	min_callchain_hits = hists->stats.total_period * (callchain_param.min_percent / 100);
>  
> +	hists__reset_stats(hists);
> +	hists__reset_col_len(hists);
> +
> +	if (symbol_conf.report_hierarchy) {
> +		return hists__hierarchy_output_resort(hists, prog,
> +						      &hists->entries_collapsed,

is the 'in-root' always hists->entries_collapsed in here?

should you use the 'root' var from the condition below?

thanks,
jirka

> +						      &hists->entries,
> +						      min_callchain_hits,
> +						      use_callchain);
> +	}
> +
>  	if (sort__need_collapse)
>  		root = &hists->entries_collapsed;
>  	else
> @@ -1296,9 +1375,6 @@ void hists__output_resort(struct hists *hists, struct ui_progress *prog)
>  	next = rb_first(root);
>  	hists->entries = RB_ROOT;
>  
> -	hists__reset_stats(hists);
> -	hists__reset_col_len(hists);
> -
>  	while (next) {
>  		n = rb_entry(next, struct hist_entry, rb_node_in);
>  		next = rb_next(&n->rb_node_in);
> -- 
> 2.6.4
> 

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


#1314187 — Re: [PATCH 02/17] perf hists: Resort hist entries with hierarchy

FromNamhyung Kim <namhyung@kernel.org>
Date2016-01-21 14:10 +0100
SubjectRe: [PATCH 02/17] perf hists: Resort hist entries with hierarchy
Message-ID<qTn9U-5Gc-5@gated-at.bofh.it>
In reply to#1314131
On Thu, Jan 21, 2016 at 12:41:49PM +0100, Jiri Olsa wrote:
> On Sun, Jan 17, 2016 at 01:03:02AM +0900, Namhyung Kim wrote:
> 
> SNIP
> 
> > +					     min_callchain_hits,
> > +					     &callchain_param);
> > +	}
> > +}
> > +
> >  static void __hists__insert_output_entry(struct rb_root *entries,
> >  					 struct hist_entry *he,
> >  					 u64 min_callchain_hits,
> > @@ -1288,6 +1356,17 @@ void hists__output_resort(struct hists *hists, struct ui_progress *prog)
> >  
> >  	min_callchain_hits = hists->stats.total_period * (callchain_param.min_percent / 100);
> >  
> > +	hists__reset_stats(hists);
> > +	hists__reset_col_len(hists);
> > +
> > +	if (symbol_conf.report_hierarchy) {
> > +		return hists__hierarchy_output_resort(hists, prog,
> > +						      &hists->entries_collapsed,
> 
> is the 'in-root' always hists->entries_collapsed in here?
> 
> should you use the 'root' var from the condition below?

The symbol_conf.report_hierarchy imples sort__need_collapse since it
needs to build the hierarchy during 'collapse' stage.  So yes, it's
always hists->entries_collapsed.

Thanks,
Namhyung


> 
> > +						      &hists->entries,
> > +						      min_callchain_hits,
> > +						      use_callchain);
> > +	}
> > +
> >  	if (sort__need_collapse)
> >  		root = &hists->entries_collapsed;
> >  	else
> > @@ -1296,9 +1375,6 @@ void hists__output_resort(struct hists *hists, struct ui_progress *prog)
> >  	next = rb_first(root);
> >  	hists->entries = RB_ROOT;
> >  
> > -	hists__reset_stats(hists);
> > -	hists__reset_col_len(hists);
> > -
> >  	while (next) {
> >  		n = rb_entry(next, struct hist_entry, rb_node_in);
> >  		next = rb_next(&n->rb_node_in);
> > -- 
> > 2.6.4
> > 

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


#1310981 — [PATCH 10/17] perf hists browser: Support collapsing/expanding whole entries in hierarchy

FromNamhyung Kim <namhyung@kernel.org>
Date2016-01-16 17:10 +0100
Subject[PATCH 10/17] perf hists browser: Support collapsing/expanding whole entries in hierarchy
Message-ID<qRBAn-6Ad-33@gated-at.bofh.it>
In reply to#1310972
The 'C' and 'E' keys are to collapse/expand all hist entries.  Update
nr_hierarchy_entries properly in this case.

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

diff --git a/tools/perf/ui/browsers/hists.c b/tools/perf/ui/browsers/hists.c
index ae9e6407ea3c..8452528fa29b 100644
--- a/tools/perf/ui/browsers/hists.c
+++ b/tools/perf/ui/browsers/hists.c
@@ -487,13 +487,37 @@ static int callchain__set_folding(struct rb_root *chain, bool unfold)
 	return n;
 }
 
-static void hist_entry__set_folding(struct hist_entry *he, bool unfold)
+static int hierarchy_set_folding(struct hist_browser *hb, struct hist_entry *he,
+				 bool unfold __maybe_unused)
+{
+	float percent;
+	struct rb_node *nd;
+	struct hist_entry *child;
+	int n = 0;
+
+	for (nd = rb_first(&he->hroot_out); nd; nd = rb_next(nd)) {
+		child = rb_entry(nd, struct hist_entry, rb_node);
+		percent = hist_entry__get_percent_limit(child);
+		if (!child->filtered && percent >= hb->min_pcnt)
+			n++;
+	}
+
+	return n;
+}
+
+static void hist_entry__set_folding(struct hist_entry *he, struct hist_browser *hb,
+				    bool unfold)
 {
-	hist_entry__init_have_children(he);
 	he->unfolded = unfold ? he->has_children : false;
 
 	if (he->has_children) {
-		int n = callchain__set_folding(&he->sorted_chain, unfold);
+		int n;
+
+		if (he->leaf)
+			n = callchain__set_folding(&he->sorted_chain, unfold);
+		else
+			n = hierarchy_set_folding(hb, he, unfold);
+
 		he->nr_rows = unfold ? n : 0;
 	} else
 		he->nr_rows = 0;
@@ -505,17 +529,36 @@ __hist_browser__set_folding(struct hist_browser *browser, bool unfold)
 	struct rb_node *nd;
 	struct hists *hists = browser->hists;
 
-	for (nd = rb_first(&hists->entries);
-	     (nd = hists__filter_entries(nd, browser->min_pcnt)) != NULL;
-	     nd = rb_next(nd)) {
+	nd = rb_first(&hists->entries);
+	while (nd) {
 		struct hist_entry *he = rb_entry(nd, struct hist_entry, rb_node);
-		hist_entry__set_folding(he, unfold);
-		browser->nr_callchain_rows += he->nr_rows;
+		float percent;
+
+		hist_entry__init_have_children(he);
+
+		/*
+		 * Tentatively set unfolded so that the rb_hierarchy_next()
+		 * can toggle children of folded entries too.
+		 */
+		he->unfolded = he->has_children;
+		nd = rb_hierarchy_next(nd);
+
+		hist_entry__set_folding(he, browser, unfold);
+
+		percent = hist_entry__get_percent_limit(he);
+		if (he->filtered || percent < browser->min_pcnt)
+			continue;
+
+		if (!he->depth || unfold)
+			browser->nr_hierarchy_entries++;
+		if (he->leaf)
+			browser->nr_callchain_rows += he->nr_rows;
 	}
 }
 
 static void hist_browser__set_folding(struct hist_browser *browser, bool unfold)
 {
+	browser->nr_hierarchy_entries = 0;
 	browser->nr_callchain_rows = 0;
 	__hist_browser__set_folding(browser, unfold);
 
-- 
2.6.4

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


#1310982 — [PATCH 07/17] perf ui/stdio: Align column header for hierarchy output

FromNamhyung Kim <namhyung@kernel.org>
Date2016-01-16 17:10 +0100
Subject[PATCH 07/17] perf ui/stdio: Align column header for hierarchy output
Message-ID<qRBAn-6Ad-41@gated-at.bofh.it>
In reply to#1310972
The hierarchy output mode is to group entries so the existing columns
won't fit to the new output.  Treat all sort keys as a single column and
separate headers by "/".

  #    Overhead  Command / Shared Object
  # ...........  ................................
  #
      15.11%     swapper
         14.97%     [kernel.vmlinux]
          0.09%     [libahci]
          0.05%     [iwlwifi]
  ...

Signed-off-by: Namhyung Kim <namhyung@kernel.org>
---
 tools/perf/ui/stdio/hist.c | 107 +++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 107 insertions(+)

diff --git a/tools/perf/ui/stdio/hist.c b/tools/perf/ui/stdio/hist.c
index 0cd7c651a0e8..38279478a06d 100644
--- a/tools/perf/ui/stdio/hist.c
+++ b/tools/perf/ui/stdio/hist.c
@@ -502,6 +502,108 @@ static int hist_entry__fprintf(struct hist_entry *he, size_t size,
 	return ret;
 }
 
+static int print_hierarchy_indent(const char *sep, int nr_sort,
+				  const char *line, FILE *fp)
+{
+	if (sep != NULL || nr_sort < 1)
+		return 0;
+
+	return fprintf(fp, "%-.*s", (nr_sort - 1) * HIERARCHY_INDENT, line);
+}
+
+static int print_hierarchy_header(struct hists *hists, struct perf_hpp *hpp,
+				  const char *sep, FILE *fp)
+{
+	bool first = true;
+	int nr_sort;
+	unsigned width = 0;
+	unsigned header_width = 0;
+	struct perf_hpp_fmt *fmt;
+	const char spaces[] = "                                               "
+	"                                                                     "
+	"                                                                     ";
+	const char dots[] = "................................................."
+	"....................................................................."
+	".....................................................................";
+
+	nr_sort = perf_hpp__count_sort_keys();
+
+	/* preserve max indent depth for column headers */
+	print_hierarchy_indent(sep, nr_sort, spaces, fp);
+
+	perf_hpp__for_each_format(fmt) {
+		if (perf_hpp__is_sort_entry(fmt) || perf_hpp__is_dynamic_entry(fmt))
+			break;
+
+		if (!first)
+			fprintf(fp, "%s", sep ?: "  ");
+		else
+			first = false;
+
+		fmt->header(fmt, hpp, hists_to_evsel(hists));
+		fprintf(fp, "%s", hpp->buf);
+	}
+
+	/* combine sort headers with ' / ' */
+	first = true;
+	perf_hpp__for_each_format(fmt) {
+		if (!perf_hpp__is_sort_entry(fmt) && !perf_hpp__is_dynamic_entry(fmt))
+			continue;
+
+		if (!first)
+			header_width += fprintf(fp, " / ");
+		else {
+			header_width += fprintf(fp, "%s", sep ?: "  ");
+			first = false;
+		}
+
+		fmt->header(fmt, hpp, hists_to_evsel(hists));
+		rtrim(hpp->buf);
+
+		header_width += fprintf(fp, "%s", hpp->buf);
+	}
+
+	/* preserve max indent depth for combined sort headers */
+	print_hierarchy_indent(sep, nr_sort, spaces, fp);
+
+	fprintf(fp, "\n# ");
+
+	/* preserve max indent depth for initial dots */
+	print_hierarchy_indent(sep, nr_sort, dots, fp);
+
+	first = true;
+	perf_hpp__for_each_format(fmt) {
+		if (perf_hpp__is_sort_entry(fmt) || perf_hpp__is_dynamic_entry(fmt))
+			break;
+
+		if (!first)
+			fprintf(fp, "%s", sep ?: "  ");
+		else
+			first = false;
+
+		width = fmt->width(fmt, hpp, hists_to_evsel(hists));
+		fprintf(fp, "%.*s", width, dots);
+	}
+
+	perf_hpp__for_each_format(fmt) {
+		if (!perf_hpp__is_sort_entry(fmt) && !perf_hpp__is_dynamic_entry(fmt))
+			continue;
+
+		width = fmt->width(fmt, hpp, hists_to_evsel(hists));
+		if (width > header_width)
+			header_width = width;
+	}
+
+	fprintf(fp, "%s%-.*s", sep ?: "  ", header_width, dots);
+
+	/* preserve max indent depth for dots under sort headers */
+	print_hierarchy_indent(sep, nr_sort, dots, fp);
+
+	fprintf(fp, "\n#\n");
+
+	return 2;
+}
+
 size_t hists__fprintf(struct hists *hists, bool show_header, int max_rows,
 		      int max_cols, float min_pcnt, FILE *fp)
 {
@@ -533,6 +635,11 @@ size_t hists__fprintf(struct hists *hists, bool show_header, int max_rows,
 
 	fprintf(fp, "# ");
 
+	if (symbol_conf.report_hierarchy) {
+		nr_rows += print_hierarchy_header(hists, &dummy_hpp, sep, fp);
+		goto print_entries;
+	}
+
 	perf_hpp__for_each_format(fmt) {
 		if (perf_hpp__should_skip(fmt, hists))
 			continue;
-- 
2.6.4

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


#1313636 — Re: [PATCH 07/17] perf ui/stdio: Align column header for hierarchy output

FromArnaldo Carvalho de Melo <acme@kernel.org>
Date2016-01-20 23:50 +0100
SubjectRe: [PATCH 07/17] perf ui/stdio: Align column header for hierarchy output
Message-ID<qT9JE-4ys-1@gated-at.bofh.it>
In reply to#1310982
Em Sun, Jan 17, 2016 at 01:03:07AM +0900, Namhyung Kim escreveu:
> The hierarchy output mode is to group entries so the existing columns
> won't fit to the new output.  Treat all sort keys as a single column and
> separate headers by "/".
> 
>   #    Overhead  Command / Shared Object
>   # ...........  ................................
>   #
>       15.11%     swapper
>          14.97%     [kernel.vmlinux]
>           0.09%     [libahci]
>           0.05%     [iwlwifi]
>   ...
> 
> Signed-off-by: Namhyung Kim <namhyung@kernel.org>
> ---
>  tools/perf/ui/stdio/hist.c | 107 +++++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 107 insertions(+)
> 
> diff --git a/tools/perf/ui/stdio/hist.c b/tools/perf/ui/stdio/hist.c
> index 0cd7c651a0e8..38279478a06d 100644
> --- a/tools/perf/ui/stdio/hist.c
> +++ b/tools/perf/ui/stdio/hist.c
> @@ -502,6 +502,108 @@ static int hist_entry__fprintf(struct hist_entry *he, size_t size,
>  	return ret;
>  }
>  
> +static int print_hierarchy_indent(const char *sep, int nr_sort,
> +				  const char *line, FILE *fp)
> +{
> +	if (sep != NULL || nr_sort < 1)
> +		return 0;
> +
> +	return fprintf(fp, "%-.*s", (nr_sort - 1) * HIERARCHY_INDENT, line);
> +}
> +
> +static int print_hierarchy_header(struct hists *hists, struct perf_hpp *hpp,
> +				  const char *sep, FILE *fp)
> +{
> +	bool first = true;
> +	int nr_sort;
> +	unsigned width = 0;
> +	unsigned header_width = 0;
> +	struct perf_hpp_fmt *fmt;
> +	const char spaces[] = "                                               "
> +	"                                                                     "
> +	"                                                                     ";
> +	const char dots[] = "................................................."
> +	"....................................................................."
> +	".....................................................................";
> +
> +	nr_sort = perf_hpp__count_sort_keys();
> +
> +	/* preserve max indent depth for column headers */
> +	print_hierarchy_indent(sep, nr_sort, spaces, fp);
> +
> +	perf_hpp__for_each_format(fmt) {
> +		if (perf_hpp__is_sort_entry(fmt) || perf_hpp__is_dynamic_entry(fmt))
> +			break;
> +
> +		if (!first)
> +			fprintf(fp, "%s", sep ?: "  ");
> +		else
> +			first = false;
> +
> +		fmt->header(fmt, hpp, hists_to_evsel(hists));
> +		fprintf(fp, "%s", hpp->buf);

We already have code that prints dots or spaces according to a given
width, but in tools/perf/ui/stdio/hist.c hists__fprintf() it does it
using a fprintf loop, gack, would be better to settle in one way.

Can be done later, sure, processing as-is.

- Arnaldo

> +	}
> +
> +	/* combine sort headers with ' / ' */
> +	first = true;
> +	perf_hpp__for_each_format(fmt) {
> +		if (!perf_hpp__is_sort_entry(fmt) && !perf_hpp__is_dynamic_entry(fmt))
> +			continue;
> +
> +		if (!first)
> +			header_width += fprintf(fp, " / ");
> +		else {
> +			header_width += fprintf(fp, "%s", sep ?: "  ");
> +			first = false;
> +		}
> +
> +		fmt->header(fmt, hpp, hists_to_evsel(hists));
> +		rtrim(hpp->buf);
> +
> +		header_width += fprintf(fp, "%s", hpp->buf);
> +	}
> +
> +	/* preserve max indent depth for combined sort headers */
> +	print_hierarchy_indent(sep, nr_sort, spaces, fp);
> +
> +	fprintf(fp, "\n# ");
> +
> +	/* preserve max indent depth for initial dots */
> +	print_hierarchy_indent(sep, nr_sort, dots, fp);
> +
> +	first = true;
> +	perf_hpp__for_each_format(fmt) {
> +		if (perf_hpp__is_sort_entry(fmt) || perf_hpp__is_dynamic_entry(fmt))
> +			break;
> +
> +		if (!first)
> +			fprintf(fp, "%s", sep ?: "  ");
> +		else
> +			first = false;
> +
> +		width = fmt->width(fmt, hpp, hists_to_evsel(hists));
> +		fprintf(fp, "%.*s", width, dots);
> +	}
> +
> +	perf_hpp__for_each_format(fmt) {
> +		if (!perf_hpp__is_sort_entry(fmt) && !perf_hpp__is_dynamic_entry(fmt))
> +			continue;
> +
> +		width = fmt->width(fmt, hpp, hists_to_evsel(hists));
> +		if (width > header_width)
> +			header_width = width;
> +	}
> +
> +	fprintf(fp, "%s%-.*s", sep ?: "  ", header_width, dots);
> +
> +	/* preserve max indent depth for dots under sort headers */
> +	print_hierarchy_indent(sep, nr_sort, dots, fp);
> +
> +	fprintf(fp, "\n#\n");
> +
> +	return 2;
> +}
> +
>  size_t hists__fprintf(struct hists *hists, bool show_header, int max_rows,
>  		      int max_cols, float min_pcnt, FILE *fp)
>  {
> @@ -533,6 +635,11 @@ size_t hists__fprintf(struct hists *hists, bool show_header, int max_rows,
>  
>  	fprintf(fp, "# ");
>  
> +	if (symbol_conf.report_hierarchy) {
> +		nr_rows += print_hierarchy_header(hists, &dummy_hpp, sep, fp);
> +		goto print_entries;
> +	}
> +
>  	perf_hpp__for_each_format(fmt) {
>  		if (perf_hpp__should_skip(fmt, hists))
>  			continue;
> -- 
> 2.6.4

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


#1313852 — Re: [PATCH 07/17] perf ui/stdio: Align column header for hierarchy output

FromNamhyung Kim <namhyung@kernel.org>
Date2016-01-21 05:10 +0100
SubjectRe: [PATCH 07/17] perf ui/stdio: Align column header for hierarchy output
Message-ID<qTeJk-8hS-13@gated-at.bofh.it>
In reply to#1313636
On Wed, Jan 20, 2016 at 07:40:43PM -0300, Arnaldo Carvalho de Melo wrote:
> Em Sun, Jan 17, 2016 at 01:03:07AM +0900, Namhyung Kim escreveu:
> > The hierarchy output mode is to group entries so the existing columns
> > won't fit to the new output.  Treat all sort keys as a single column and
> > separate headers by "/".

[SNIP]
> > +static int print_hierarchy_header(struct hists *hists, struct perf_hpp *hpp,
> > +				  const char *sep, FILE *fp)
> > +{
> > +	bool first = true;
> > +	int nr_sort;
> > +	unsigned width = 0;
> > +	unsigned header_width = 0;
> > +	struct perf_hpp_fmt *fmt;
> > +	const char spaces[] = "                                               "
> > +	"                                                                     "
> > +	"                                                                     ";
> > +	const char dots[] = "................................................."
> > +	"....................................................................."
> > +	".....................................................................";
> > +
> > +	nr_sort = perf_hpp__count_sort_keys();
> > +
> > +	/* preserve max indent depth for column headers */
> > +	print_hierarchy_indent(sep, nr_sort, spaces, fp);
> > +
> > +	perf_hpp__for_each_format(fmt) {
> > +		if (perf_hpp__is_sort_entry(fmt) || perf_hpp__is_dynamic_entry(fmt))
> > +			break;
> > +
> > +		if (!first)
> > +			fprintf(fp, "%s", sep ?: "  ");
> > +		else
> > +			first = false;
> > +
> > +		fmt->header(fmt, hpp, hists_to_evsel(hists));
> > +		fprintf(fp, "%s", hpp->buf);
> 
> We already have code that prints dots or spaces according to a given
> width, but in tools/perf/ui/stdio/hist.c hists__fprintf() it does it
> using a fprintf loop, gack, would be better to settle in one way.

Agreed.

> 
> Can be done later, sure, processing as-is.

Thanks!
Namhyung


> 
> > +	}
> > +
> > +	/* combine sort headers with ' / ' */
> > +	first = true;
> > +	perf_hpp__for_each_format(fmt) {
> > +		if (!perf_hpp__is_sort_entry(fmt) && !perf_hpp__is_dynamic_entry(fmt))
> > +			continue;
> > +
> > +		if (!first)
> > +			header_width += fprintf(fp, " / ");
> > +		else {
> > +			header_width += fprintf(fp, "%s", sep ?: "  ");
> > +			first = false;
> > +		}
> > +
> > +		fmt->header(fmt, hpp, hists_to_evsel(hists));
> > +		rtrim(hpp->buf);
> > +
> > +		header_width += fprintf(fp, "%s", hpp->buf);
> > +	}
> > +
> > +	/* preserve max indent depth for combined sort headers */
> > +	print_hierarchy_indent(sep, nr_sort, spaces, fp);
> > +
> > +	fprintf(fp, "\n# ");
> > +
> > +	/* preserve max indent depth for initial dots */
> > +	print_hierarchy_indent(sep, nr_sort, dots, fp);
> > +
> > +	first = true;
> > +	perf_hpp__for_each_format(fmt) {
> > +		if (perf_hpp__is_sort_entry(fmt) || perf_hpp__is_dynamic_entry(fmt))
> > +			break;
> > +
> > +		if (!first)
> > +			fprintf(fp, "%s", sep ?: "  ");
> > +		else
> > +			first = false;
> > +
> > +		width = fmt->width(fmt, hpp, hists_to_evsel(hists));
> > +		fprintf(fp, "%.*s", width, dots);
> > +	}
> > +
> > +	perf_hpp__for_each_format(fmt) {
> > +		if (!perf_hpp__is_sort_entry(fmt) && !perf_hpp__is_dynamic_entry(fmt))
> > +			continue;
> > +
> > +		width = fmt->width(fmt, hpp, hists_to_evsel(hists));
> > +		if (width > header_width)
> > +			header_width = width;
> > +	}
> > +
> > +	fprintf(fp, "%s%-.*s", sep ?: "  ", header_width, dots);
> > +
> > +	/* preserve max indent depth for dots under sort headers */
> > +	print_hierarchy_indent(sep, nr_sort, dots, fp);
> > +
> > +	fprintf(fp, "\n#\n");
> > +
> > +	return 2;
> > +}
> > +
> >  size_t hists__fprintf(struct hists *hists, bool show_header, int max_rows,
> >  		      int max_cols, float min_pcnt, FILE *fp)
> >  {
> > @@ -533,6 +635,11 @@ size_t hists__fprintf(struct hists *hists, bool show_header, int max_rows,
> >  
> >  	fprintf(fp, "# ");
> >  
> > +	if (symbol_conf.report_hierarchy) {
> > +		nr_rows += print_hierarchy_header(hists, &dummy_hpp, sep, fp);
> > +		goto print_entries;
> > +	}
> > +
> >  	perf_hpp__for_each_format(fmt) {
> >  		if (perf_hpp__should_skip(fmt, hists))
> >  			continue;
> > -- 
> > 2.6.4

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


#1310983 — [PATCH 12/17] perf hists browser: Implement hierarchy output

FromNamhyung Kim <namhyung@kernel.org>
Date2016-01-16 17:10 +0100
Subject[PATCH 12/17] perf hists browser: Implement hierarchy output
Message-ID<qRBAn-6Ad-49@gated-at.bofh.it>
In reply to#1310972
Implement hierarchy mode in TUI.  The output is look like stdio but it
also supports to fold/unfold children dynamically.

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

diff --git a/tools/perf/ui/browsers/hists.c b/tools/perf/ui/browsers/hists.c
index 353e0477c1f5..ded026e213cc 100644
--- a/tools/perf/ui/browsers/hists.c
+++ b/tools/perf/ui/browsers/hists.c
@@ -1242,6 +1242,137 @@ static int hist_browser__show_entry(struct hist_browser *browser,
 	return printed;
 }
 
+static int hist_browser__show_hierarchy_entry(struct hist_browser *browser,
+					      struct hist_entry *entry,
+					      unsigned short row,
+					      int level, int nr_sort_keys)
+{
+	char s[256];
+	int printed = 0;
+	int width = browser->b.width;
+	char folded_sign = ' ';
+	bool current_entry = ui_browser__is_current_entry(&browser->b, row);
+	off_t row_offset = entry->row_offset;
+	bool first = true;
+	struct perf_hpp_fmt *fmt;
+	struct hpp_arg arg = {
+		.b		= &browser->b,
+		.current_entry	= current_entry,
+	};
+	struct perf_hpp hpp = {
+		.buf		= s,
+		.size		= sizeof(s),
+		.ptr		= &arg,
+	};
+	int column = 0;
+	int hierarchy_indent = (nr_sort_keys - 1) * HIERARCHY_INDENT;
+
+	if (current_entry) {
+		browser->he_selection = entry;
+		browser->selection = &entry->ms;
+	}
+
+	hist_entry__init_have_children(entry);
+	folded_sign = hist_entry__folded(entry);
+	arg.folded_sign = folded_sign;
+
+	if (entry->leaf && row_offset) {
+		row_offset--;
+		goto show_callchain;
+	}
+
+	hist_browser__gotorc(browser, row, 0);
+
+	if (current_entry && browser->b.navkeypressed)
+		ui_browser__set_color(&browser->b, HE_COLORSET_SELECTED);
+	else
+		ui_browser__set_color(&browser->b, HE_COLORSET_NORMAL);
+
+	ui_browser__write_nstring(&browser->b, "", level * HIERARCHY_INDENT);
+	width -= level * HIERARCHY_INDENT;
+
+	perf_hpp__for_each_format(fmt) {
+		if (perf_hpp__should_skip(fmt, entry->hists) ||
+		    column++ < browser->b.horiz_scroll)
+			continue;
+
+		if (perf_hpp__is_sort_entry(fmt) ||
+		    perf_hpp__is_dynamic_entry(fmt))
+			break;
+
+		if (current_entry && browser->b.navkeypressed) {
+			ui_browser__set_color(&browser->b,
+					      HE_COLORSET_SELECTED);
+		} else {
+			ui_browser__set_color(&browser->b,
+					      HE_COLORSET_NORMAL);
+		}
+
+		if (first) {
+			ui_browser__printf(&browser->b, "%c", folded_sign);
+			width--;
+			first = false;
+		} else {
+			ui_browser__printf(&browser->b, "  ");
+			width -= 2;
+		}
+
+		if (fmt->color) {
+			width -= fmt->color(fmt, &hpp, entry);
+		} else {
+			width -= fmt->entry(fmt, &hpp, entry);
+			ui_browser__printf(&browser->b, "%s", s);
+		}
+	}
+
+	ui_browser__write_nstring(&browser->b, "", hierarchy_indent);
+	width -= hierarchy_indent;
+
+	if (column >= browser->b.horiz_scroll) {
+		if (current_entry && browser->b.navkeypressed) {
+			ui_browser__set_color(&browser->b,
+					      HE_COLORSET_SELECTED);
+		} else {
+			ui_browser__set_color(&browser->b,
+					      HE_COLORSET_NORMAL);
+		}
+
+		ui_browser__write_nstring(&browser->b, "", 2);
+		width -= 2;
+
+		fmt = entry->fmt;
+		if (fmt->color) {
+			width -= fmt->color(fmt, &hpp, entry);
+		} else {
+			width -= fmt->entry(fmt, &hpp, entry);
+			ui_browser__printf(&browser->b, "%s", s);
+		}
+	}
+
+	/* The scroll bar isn't being used */
+	if (!browser->b.navkeypressed)
+		width += 1;
+
+	ui_browser__write_nstring(&browser->b, "", width);
+
+	++row;
+	++printed;
+
+show_callchain:
+	if (entry->leaf && folded_sign == '-' && row != browser->b.rows) {
+		struct callchain_print_arg carg = {
+			.row_offset = row_offset,
+		};
+
+		printed += hist_browser__show_callchain(browser, entry,
+					level + 1, row,
+					hist_browser__show_callchain_entry, &carg,
+					hist_browser__check_output_full);
+	}
+
+	return printed;
+}
+
 static int advance_hpp_check(struct perf_hpp *hpp, int inc)
 {
 	advance_hpp(hpp, inc);
@@ -1307,6 +1438,7 @@ static unsigned int hist_browser__refresh(struct ui_browser *browser)
 	u16 header_offset = 0;
 	struct rb_node *nd;
 	struct hist_browser *hb = container_of(browser, struct hist_browser, b);
+	int nr_sort = perf_hpp__count_sort_keys();
 
 	if (hb->show_headers) {
 		hist_browser__show_headers(hb);
@@ -1317,18 +1449,28 @@ static unsigned int hist_browser__refresh(struct ui_browser *browser)
 	hb->he_selection = NULL;
 	hb->selection = NULL;
 
-	for (nd = browser->top; nd; nd = rb_next(nd)) {
+	for (nd = browser->top; nd; nd = rb_hierarchy_next(nd)) {
 		struct hist_entry *h = rb_entry(nd, struct hist_entry, rb_node);
 		float percent;
 
-		if (h->filtered)
+		if (h->filtered) {
+			/* let it move to sibling */
+			h->unfolded = false;
 			continue;
+		}
 
 		percent = hist_entry__get_percent_limit(h);
 		if (percent < hb->min_pcnt)
 			continue;
 
-		row += hist_browser__show_entry(hb, h, row);
+		if (symbol_conf.report_hierarchy) {
+			row += hist_browser__show_hierarchy_entry(hb, h, row,
+								  h->depth,
+								  nr_sort);
+		} else {
+			row += hist_browser__show_entry(hb, h, row);
+		}
+
 		if (row == browser->rows)
 			break;
 	}
@@ -1346,7 +1488,14 @@ static struct rb_node *hists__filter_entries(struct rb_node *nd,
 		if (!h->filtered && percent >= min_pcnt)
 			return nd;
 
-		nd = rb_next(nd);
+		/*
+		 * If it's filtered, its all children also were filtered.
+		 * So move to sibling node.
+		 */
+		if (rb_next(nd))
+			nd = rb_next(nd);
+		else
+			nd = rb_hierarchy_next(nd);
 	}
 
 	return NULL;
@@ -1362,7 +1511,7 @@ static struct rb_node *hists__filter_prev_entries(struct rb_node *nd,
 		if (!h->filtered && percent >= min_pcnt)
 			return nd;
 
-		nd = rb_prev(nd);
+		nd = rb_hierarchy_prev(nd);
 	}
 
 	return NULL;
@@ -1392,8 +1541,8 @@ static void ui_browser__hists_seek(struct ui_browser *browser,
 		nd = browser->top;
 		goto do_offset;
 	case SEEK_END:
-		nd = hists__filter_prev_entries(rb_last(browser->entries),
-						hb->min_pcnt);
+		nd = rb_hierarchy_last(rb_last(browser->entries));
+		nd = hists__filter_prev_entries(nd, hb->min_pcnt);
 		first = false;
 		break;
 	default:
@@ -1427,7 +1576,7 @@ do_offset:
 	if (offset > 0) {
 		do {
 			h = rb_entry(nd, struct hist_entry, rb_node);
-			if (h->unfolded) {
+			if (h->unfolded && h->leaf) {
 				u16 remaining = h->nr_rows - h->row_offset;
 				if (offset > remaining) {
 					offset -= remaining;
@@ -1439,7 +1588,8 @@ do_offset:
 					break;
 				}
 			}
-			nd = hists__filter_entries(rb_next(nd), hb->min_pcnt);
+			nd = hists__filter_entries(rb_hierarchy_next(nd),
+						   hb->min_pcnt);
 			if (nd == NULL)
 				break;
 			--offset;
@@ -1448,7 +1598,7 @@ do_offset:
 	} else if (offset < 0) {
 		while (1) {
 			h = rb_entry(nd, struct hist_entry, rb_node);
-			if (h->unfolded) {
+			if (h->unfolded && h->leaf) {
 				if (first) {
 					if (-offset > h->row_offset) {
 						offset += h->row_offset;
@@ -1472,7 +1622,7 @@ do_offset:
 				}
 			}
 
-			nd = hists__filter_prev_entries(rb_prev(nd),
+			nd = hists__filter_prev_entries(rb_hierarchy_prev(nd),
 							hb->min_pcnt);
 			if (nd == NULL)
 				break;
@@ -1485,7 +1635,7 @@ do_offset:
 				 * row_offset at its last entry.
 				 */
 				h = rb_entry(nd, struct hist_entry, rb_node);
-				if (h->unfolded)
+				if (h->unfolded && h->leaf)
 					h->row_offset = h->nr_rows;
 				break;
 			}
@@ -1499,13 +1649,14 @@ do_offset:
 }
 
 static int hist_browser__fprintf_callchain(struct hist_browser *browser,
-					   struct hist_entry *he, FILE *fp)
+					   struct hist_entry *he, FILE *fp,
+					   int level)
 {
 	struct callchain_print_arg arg  = {
 		.fp = fp,
 	};
 
-	hist_browser__show_callchain(browser, he, 1, 0,
+	hist_browser__show_callchain(browser, he, level, 0,
 				     hist_browser__fprintf_callchain_entry, &arg,
 				     hist_browser__check_dump_full);
 	return arg.printed;
@@ -1547,7 +1698,65 @@ static int hist_browser__fprintf_entry(struct hist_browser *browser,
 	printed += fprintf(fp, "%s\n", rtrim(s));
 
 	if (folded_sign == '-')
-		printed += hist_browser__fprintf_callchain(browser, he, fp);
+		printed += hist_browser__fprintf_callchain(browser, he, fp, 1);
+
+	return printed;
+}
+
+
+static int hist_browser__fprintf_hierarchy_entry(struct hist_browser *browser,
+						 struct hist_entry *he,
+						 FILE *fp, int level,
+						 int nr_sort_keys)
+{
+	char s[8192];
+	int printed = 0;
+	char folded_sign = ' ';
+	struct perf_hpp hpp = {
+		.buf = s,
+		.size = sizeof(s),
+	};
+	struct perf_hpp_fmt *fmt;
+	bool first = true;
+	int ret;
+	int hierarchy_indent = (nr_sort_keys + 1) * HIERARCHY_INDENT;
+
+	printed = fprintf(fp, "%*s", level * HIERARCHY_INDENT, "");
+
+	folded_sign = hist_entry__folded(he);
+	printed += fprintf(fp, "%c", folded_sign);
+
+	perf_hpp__for_each_format(fmt) {
+		if (perf_hpp__should_skip(fmt, he->hists))
+			continue;
+
+		if (perf_hpp__is_sort_entry(fmt) ||
+		    perf_hpp__is_dynamic_entry(fmt))
+			break;
+
+		if (!first) {
+			ret = scnprintf(hpp.buf, hpp.size, "  ");
+			advance_hpp(&hpp, ret);
+		} else
+			first = false;
+
+		ret = fmt->entry(fmt, &hpp, he);
+		advance_hpp(&hpp, ret);
+	}
+
+	ret = scnprintf(hpp.buf, hpp.size, "%*s", hierarchy_indent, "");
+	advance_hpp(&hpp, ret);
+
+	fmt = he->fmt;
+	ret = fmt->entry(fmt, &hpp, he);
+	advance_hpp(&hpp, ret);
+
+	printed += fprintf(fp, "%s\n", rtrim(s));
+
+	if (he->leaf && folded_sign == '-') {
+		printed += hist_browser__fprintf_callchain(browser, he, fp,
+							   he->depth + 1);
+	}
 
 	return printed;
 }
@@ -1557,12 +1766,22 @@ static int hist_browser__fprintf(struct hist_browser *browser, FILE *fp)
 	struct rb_node *nd = hists__filter_entries(rb_first(browser->b.entries),
 						   browser->min_pcnt);
 	int printed = 0;
+	int nr_sort = perf_hpp__count_sort_keys();
 
 	while (nd) {
 		struct hist_entry *h = rb_entry(nd, struct hist_entry, rb_node);
 
-		printed += hist_browser__fprintf_entry(browser, h, fp);
-		nd = hists__filter_entries(rb_next(nd), browser->min_pcnt);
+		if (symbol_conf.report_hierarchy) {
+			printed += hist_browser__fprintf_hierarchy_entry(browser,
+									 h, fp,
+									 h->depth,
+									 nr_sort);
+		} else {
+			printed += hist_browser__fprintf_entry(browser, h, fp);
+		}
+
+		nd = hists__filter_entries(rb_hierarchy_next(nd),
+					   browser->min_pcnt);
 	}
 
 	return printed;
-- 
2.6.4

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


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

Back to top | Article view | linux.kernel


csiph-web