Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > linux.kernel > #1310972 > unrolled thread
| Started by | Namhyung Kim <namhyung@kernel.org> |
|---|---|
| First post | 2016-01-16 17:10 +0100 |
| Last post | 2016-01-20 01:20 +0100 |
| Articles | 20 on this page of 77 — 6 participants |
Back to article view | Back to linux.kernel
[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 →
| From | Namhyung Kim <namhyung@kernel.org> |
|---|---|
| Date | 2016-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]
| From | Arnaldo Carvalho de Melo <acme@kernel.org> |
|---|---|
| Date | 2016-01-21 02:00 +0100 |
| Subject | Re: [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]
| From | Namhyung Kim <namhyung@kernel.org> |
|---|---|
| Date | 2016-01-21 05:10 +0100 |
| Subject | Re: [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]
| From | Arnaldo Carvalho de Melo <acme@kernel.org> |
|---|---|
| Date | 2016-01-22 01:00 +0100 |
| Subject | Re: [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]
| From | Namhyung Kim <namhyung@kernel.org> |
|---|---|
| Date | 2016-01-22 12:10 +0100 |
| Subject | Re: [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]
| From | Arnaldo Carvalho de Melo <acme@kernel.org> |
|---|---|
| Date | 2016-01-22 15:40 +0100 |
| Subject | Dynamicly 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]
| From | Namhyung Kim <namhyung@kernel.org> |
|---|---|
| Date | 2016-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]
| From | Arnaldo Carvalho de Melo <acme@kernel.org> |
|---|---|
| Date | 2016-01-19 21:40 +0100 |
| Subject | Re: [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]
| From | Namhyung Kim <namhyung@kernel.org> |
|---|---|
| Date | 2016-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]
| From | Namhyung Kim <namhyung@kernel.org> |
|---|---|
| Date | 2016-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]
| From | Jiri Olsa <jolsa@redhat.com> |
|---|---|
| Date | 2016-01-21 13:10 +0100 |
| Subject | Re: [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]
| From | Jiri Olsa <jolsa@redhat.com> |
|---|---|
| Date | 2016-01-21 13:10 +0100 |
| Subject | Re: [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]
| From | Namhyung Kim <namhyung@kernel.org> |
|---|---|
| Date | 2016-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]
| From | Jiri Olsa <jolsa@redhat.com> |
|---|---|
| Date | 2016-01-21 12:50 +0100 |
| Subject | Re: [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]
| From | Namhyung Kim <namhyung@kernel.org> |
|---|---|
| Date | 2016-01-21 14:10 +0100 |
| Subject | Re: [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]
| From | Namhyung Kim <namhyung@kernel.org> |
|---|---|
| Date | 2016-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]
| From | Namhyung Kim <namhyung@kernel.org> |
|---|---|
| Date | 2016-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]
| From | Arnaldo Carvalho de Melo <acme@kernel.org> |
|---|---|
| Date | 2016-01-20 23:50 +0100 |
| Subject | Re: [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]
| From | Namhyung Kim <namhyung@kernel.org> |
|---|---|
| Date | 2016-01-21 05:10 +0100 |
| Subject | Re: [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]
| From | Namhyung Kim <namhyung@kernel.org> |
|---|---|
| Date | 2016-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