perf report: Add -F option for specifying output fields (v6)
Namhyung Kim
maintainercover perf report: Add -F option for specifying output fields (v6)
Hello,
This is a patchset implementing -F/--fields option to setup output field/column as Ingo requested.
The -F option can receive any sort keys that -s option recognize, plus following fields (name can be changed):
overhead, overhead_sys, overhead_us, sample, period
The overhead_guest_sys and overhead_guest_us might be avaiable when you profile guest machines.
Output will be sorted by in order of fields and sort keys passed by -s option will be added to the output field list automatically. If you want to change the order of sorting you can give -s option in addition to -F option. To support old behavior, it'll also prepend 'overhead' field to the sort keys unless you give -F option explicitly.
$ perf report -s dso,sym
...
# Overhead Shared Object Symbol
# ........ ............. ..........................
#
13.75% ld-2.17.so [.] strcmp
10.00% abc [.] a
10.00% abc [.] b
10.00% abc [.] c
8.75% abc [.] main
7.50% libc-2.17.so [.] _setjmp
6.25% abc [.] _init
6.25% abc [.] frame_dummy
5.00% abc [.] __libc_csu_init
5.00% ld-2.17.so [.] _dl_name_match_p
3.75% libc-2.17.so [.] __new_exitfn
2.50% libc-2.17.so [.] __cxa_atexit
1.25% ld-2.17.so [.] _dl_check_map_versions
1.25% ld-2.17.so [.] _dl_setup_hash
1.25% ld-2.17.so [.] _dl_sysdep_start
1.25% ld-2.17.so [.] brk
1.25% ld-2.17.so [.] calloc@plt
1.25% ld-2.17.so [.] dl_main
1.25% ld-2.17.so [.] match_symbol
1.25% ld-2.17.so [.] sbrk
1.25% ld-2.17.so [.] strlen $ perf report -F sym,sample,overhead
...
# Symbol Samples Overhead
# .......................... ............ ........
#
[.] __cxa_atexit 2 2.50%
[.] __libc_csu_init 4 5.00%
[.] __new_exitfn 3 3.75%
[.] _dl_check_map_versions 1 1.25%
[.] _dl_name_match_p 4 5.00%
[.] _dl_setup_hash 1 1.25%
[.] _dl_sysdep_start 1 1.25%
[.] _init 5 6.25%
[.] _setjmp 6 7.50%
[.] a 8 10.00%
[.] b 8 10.00%
[.] brk 1 1.25%
[.] c 8 10.00%
[.] calloc@plt 1 1.25%
[.] dl_main 1 1.25%
[.] frame_dummy 5 6.25%
[.] main 7 8.75%
[.] match_symbol 1 1.25%
[.] sbrk 1 1.25%
[.] strcmp 11 13.75%
[.] strlen 1 1.25% $ perf report -F sym,sample -s overhead
...
# Symbol Samples Overhead
# .......................... ............ ........
#
[.] strcmp 11 13.75%
[.] a 8 10.00%
[.] b 8 10.00%
[.] c 8 10.00%
[.] main 7 8.75%
[.] _setjmp 6 7.50%
[.] _init 5 6.25%
[.] frame_dummy 5 6.25%
[.] __libc_csu_init 4 5.00%
[.] _dl_name_match_p 4 5.00%
[.] __new_exitfn 3 3.75%
[.] __cxa_atexit 2 2.50%
[.] _dl_check_map_versions 1 1.25%
[.] _dl_setup_hash 1 1.25%
[.] _dl_sysdep_start 1 1.25%
[.] brk 1 1.25%
[.] calloc@plt 1 1.25%
[.] dl_main 1 1.25%
[.] match_symbol 1 1.25%
[.] sbrk 1 1.25%
[.] strlen 1 1.25% * changes in v6:
- rename hist_entry__snprintf() (Jiri)
- update documentation of new sort keys (Jiri)
- improve sort/field order initialization (Jiri)
- reset output field after each hist tests
- get rid of unused old sort code/data
* changes in v5:
- add a testcase for hist output sorting
* changes in v4:
- fix a tui navigation bug
- fix a bug in output change of perf diff
- move call to perf_hpp__init() out of setup_browser()
- fix alignment of some output fields on stdio
* changes in v3:
- rename to --fields option for consistency (David)
- prevent to add same keys multiple times
- change dso sorting to show unknown dsos last
- fix minor bugs
* changes in v2:
- add a cleanup patch using ui__has_annotation()
- cleanup default sort order managment
- support perf top also
- handle elided sort entries properly
- add Acked-by's from Ingo
I pushed the patch series on the 'perf/field-v6' branch in my tree
git://git.kernel.org/pub/scm/linux/kernel/git/namhyung/linux-perf.git
Any comments are welcome, please test!
Thanks,
Namhyung
Namhyung Kim (20):
perf tools: Add ->cmp(), ->collapse() and ->sort() to perf_hpp_fmt perf tools: Convert sort entries to hpp formats
perf tools: Use hpp formats to sort hist entries
perf tools: Support event grouping in hpp ->sort()
perf tools: Use hpp formats to sort final output
perf tools: Consolidate output field handling to hpp format routines perf ui: Get rid of callback from __hpp__fmt()
perf tools: Allow hpp fields to be sort keys
perf tools: Consolidate management of default sort orders perf tools: Call perf_hpp__init() before setting up GUI browsers perf report: Add -F option to specify output fields
perf tools: Add ->sort() member to struct sort_entry
perf report/tui: Fix a bug when --fields/sort is given perf top: Add --fields option to specify output fields perf tools: Skip elided sort entries
perf hists: Reset width of output fields with header length perf tools: Get rid of obsolete hist_entry__sort_list perf tools: Introduce reset_output_field()
perf tests: Factor out print_hists_*()
perf tests: Add a testcase for histogram output sorting
tools/perf/Documentation/perf-diff.txt | 5 +- tools/perf/Documentation/perf-report.txt | 19 + tools/perf/Documentation/perf-top.txt | 14 +- tools/perf/Makefile.perf | 1 + tools/perf/builtin-diff.c | 7 +- tools/perf/builtin-report.c | 41 +- tools/perf/builtin-top.c | 20 +- tools/perf/tests/builtin-test.c | 4 + tools/perf/tests/hists_common.c | 57 +++ tools/perf/tests/hists_common.h | 3 + tools/perf/tests/hists_filter.c | 38 +- tools/perf/tests/hists_link.c | 30 +- tools/perf/tests/hists_output.c | 618 +++++++++++++++++++++++++++++++ tools/perf/tests/tests.h | 1 + tools/perf/ui/browsers/hists.c | 104 +++--- tools/perf/ui/gtk/hists.c | 41 +- tools/perf/ui/hist.c | 244 +++++++++--- tools/perf/ui/setup.c | 2 - tools/perf/ui/stdio/hist.c | 79 ++-- tools/perf/util/hist.c | 83 ++--- tools/perf/util/hist.h | 27 +- tools/perf/util/sort.c | 436 ++++++++++++++++++++-- tools/perf/util/sort.h | 6 + 23 files changed, 1501 insertions(+), 379 deletions(-) create mode 100644 tools/perf/tests/hists_output.c
Signature · 1 line
1.9.2
Namhyung Kim
maintainerPATCH 1/20 perf tools: Add ->cmp(), ->collapse() and ->sort() to perf_hpp_fmt
Those function pointers will be used to sort report output based on the selected fields. This is a preparation of later change.
--- tools/perf/ui/hist.c | 39 +++++++++++++++++++++++++++++++++++---- tools/perf/util/hist.h | 3 +++ 2 files changed, 38 insertions(+), 4 deletions(-)
tools/perf/ui/hist.c +35 -4
@@ -192,6 +192,14 @@ static int hpp__entry_##_type(struct perf_hpp_fmt *_fmt __maybe_unused, \ hpp_entry_scnprintf, true); \ } +#define __HPP_SORT_FN (_type, _field) \ +static int64_t hpp__sort_##_type(struct hist_entry *a, struct hist_entry *b) \ +{ \ + s64 __a = he_get_##_field(a); \ + s64 __b = he_get_##_field(b); \ + return __a - __b; \ +} +#define __HPP_ENTRY_RAW_FN (_type, _field) \ static u64 he_get_raw_##_field(struct hist_entry *he) \ { \
@@ -206,16 +214,27 @@ static int hpp__entry_##_type(struct perf_hpp_fmt *_fmt __maybe_unused, \ hpp_entry_scnprintf, false); \ } +#define __HPP_SORT_RAW_FN (_type, _field) \ +static int64_t hpp__sort_##_type(struct hist_entry *a, struct hist_entry *b) \ +{ \ + s64 __a = he_get_raw_##_field(a); \ + s64 __b = he_get_raw_##_field(b); \ + return __a - __b; \ +} + +#define HPP_PERCENT_FNS (_type, _str, _field, _min_width, _unit_width) \ __HPP_HEADER_FN(_type, _str, _min_width, _unit_width) \ __HPP_WIDTH_FN(_type, _min_width, _unit_width) \ __HPP_COLOR_PERCENT_FN(_type, _field) \ -__HPP_ENTRY_PERCENT_FN(_type, _field) +__HPP_ENTRY_PERCENT_FN(_type, _field) \ +__HPP_SORT_FN(_type, _field)#define HPP_RAW_FNS (_type, _str, _field, _min_width, _unit_width) \ __HPP_HEADER_FN(_type, _str, _min_width, _unit_width) \ __HPP_WIDTH_FN(_type, _min_width, _unit_width) \ -__HPP_ENTRY_RAW_FN(_type, _field) +__HPP_ENTRY_RAW_FN(_type, _field) \ +__HPP_SORT_RAW_FN(_type, _field)HPP_PERCENT_FNS (overhead,"Overhead" , period,8 ,8 )
@@ -227,19 +246,31 @@ HPP_PERCENT_FNS(overhead_guest_us, "guest usr", period_guest_us, 9, 8) HPP_RAW_FNS(samples, "Samples", nr_events, 12, 12) HPP_RAW_FNS(period, "Period", period, 12, 12) +static int64_t hpp__nop_cmp (struct hist_entry *a__maybe_unused , +struct hist_entry *b__maybe_unused ) +{ +return 0 ; +} +#define HPP__COLOR_PRINT_FNS (_name) \ { \ .header = hpp__header_ ## _name, \ .width = hpp__width_ ## _name, \ .color = hpp__color_ ## _name, \ - .entry = hpp__entry_ ## _name \ + .entry = hpp__entry_ ## _name, \ + .cmp = hpp__nop_cmp, \ + .collapse = hpp__nop_cmp, \ + .sort = hpp__sort_ ## _name, \ }#define HPP__PRINT_FNS (_name) \ { \ .header = hpp__header_ ## _name, \ .width = hpp__width_ ## _name, \ - .entry = hpp__entry_ ## _name \ + .entry = hpp__entry_ ## _name, \ + .cmp = hpp__nop_cmp, \ + .collapse = hpp__nop_cmp, \ + .sort = hpp__sort_ ## _name, \ }struct perf_hpp_fmt perf_hpp__format[] = {
tools/perf/util/hist.h +3 -0
@@ -160,6 +160,9 @@ struct perf_hpp_fmt { struct hist_entry *he);int (*entry)(struct perf_hpp_fmt *fmt,struct perf_hpp *hpp,struct hist_entry *he); +int64_t (*cmp)(struct hist_entry *a,struct hist_entry *b); +int64_t (*collapse)(struct hist_entry *a,struct hist_entry *b); +int64_t (*sort)(struct hist_entry *a,struct hist_entry *b);struct list_head list; };
Signature · 1 line
1.9.2
tip-bot for Namhyung Kim
merge bot[tip:perf/core] perf tools: Add ->cmp(), ->collapse() and ->sort( ) to perf_hpp_fmt
perf tools: Add ->cmp(), ->collapse() and ->sort() to perf_hpp_fmt
Commit-ID: bc18b7f2e3ca09b360b26c25a7541ba6f170111b Gitweb: http://git.kernel.org/tip/bc18b7f2e3ca09b360b26c25a7541ba6f170111b Author: Namhyung Kim <[email protected]> AuthorDate: Mon, 3 Mar 2014 10:59:57 +0900 Committer: Jiri Olsa <[email protected]> CommitDate: Wed, 21 May 2014 11:45:33 +0200
perf tools: Add ->cmp(), ->collapse() and ->sort() to perf_hpp_fmt
Those function pointers will be used to sort report output based on the selected fields. This is a preparation of later change.
--- tools/perf/ui/hist.c | 39 +++++++++++++++++++++++++++++++++++---- tools/perf/util/hist.h | 3 +++ 2 files changed, 38 insertions(+), 4 deletions(-)
tools/perf/ui/hist.c +35 -4
@@ -192,6 +192,14 @@ static int hpp__entry_##_type(struct perf_hpp_fmt *_fmt __maybe_unused, \ hpp_entry_scnprintf, true); \ } +#define __HPP_SORT_FN (_type, _field) \ +static int64_t hpp__sort_##_type(struct hist_entry *a, struct hist_entry *b) \ +{ \ + s64 __a = he_get_##_field(a); \ + s64 __b = he_get_##_field(b); \ + return __a - __b; \ +} +#define __HPP_ENTRY_RAW_FN (_type, _field) \ static u64 he_get_raw_##_field(struct hist_entry *he) \ { \
@@ -206,16 +214,27 @@ static int hpp__entry_##_type(struct perf_hpp_fmt *_fmt __maybe_unused, \ hpp_entry_scnprintf, false); \ } +#define __HPP_SORT_RAW_FN (_type, _field) \ +static int64_t hpp__sort_##_type(struct hist_entry *a, struct hist_entry *b) \ +{ \ + s64 __a = he_get_raw_##_field(a); \ + s64 __b = he_get_raw_##_field(b); \ + return __a - __b; \ +} + +#define HPP_PERCENT_FNS (_type, _str, _field, _min_width, _unit_width) \ __HPP_HEADER_FN(_type, _str, _min_width, _unit_width) \ __HPP_WIDTH_FN(_type, _min_width, _unit_width) \ __HPP_COLOR_PERCENT_FN(_type, _field) \ -__HPP_ENTRY_PERCENT_FN(_type, _field) +__HPP_ENTRY_PERCENT_FN(_type, _field) \ +__HPP_SORT_FN(_type, _field)#define HPP_RAW_FNS (_type, _str, _field, _min_width, _unit_width) \ __HPP_HEADER_FN(_type, _str, _min_width, _unit_width) \ __HPP_WIDTH_FN(_type, _min_width, _unit_width) \ -__HPP_ENTRY_RAW_FN(_type, _field) +__HPP_ENTRY_RAW_FN(_type, _field) \ +__HPP_SORT_RAW_FN(_type, _field)HPP_PERCENT_FNS (overhead,"Overhead" , period,8 ,8 )
@@ -227,19 +246,31 @@ HPP_PERCENT_FNS(overhead_guest_us, "guest usr", period_guest_us, 9, 8) HPP_RAW_FNS(samples, "Samples", nr_events, 12, 12) HPP_RAW_FNS(period, "Period", period, 12, 12) +static int64_t hpp__nop_cmp (struct hist_entry *a__maybe_unused , +struct hist_entry *b__maybe_unused ) +{ +return 0 ; +} +#define HPP__COLOR_PRINT_FNS (_name) \ { \ .header = hpp__header_ ## _name, \ .width = hpp__width_ ## _name, \ .color = hpp__color_ ## _name, \ - .entry = hpp__entry_ ## _name \ + .entry = hpp__entry_ ## _name, \ + .cmp = hpp__nop_cmp, \ + .collapse = hpp__nop_cmp, \ + .sort = hpp__sort_ ## _name, \ }#define HPP__PRINT_FNS (_name) \ { \ .header = hpp__header_ ## _name, \ .width = hpp__width_ ## _name, \ - .entry = hpp__entry_ ## _name \ + .entry = hpp__entry_ ## _name, \ + .cmp = hpp__nop_cmp, \ + .collapse = hpp__nop_cmp, \ + .sort = hpp__sort_ ## _name, \ }struct perf_hpp_fmt perf_hpp__format[] = {
tools/perf/util/hist.h +3 -0
@@ -160,6 +160,9 @@ struct perf_hpp_fmt { struct hist_entry *he);int (*entry)(struct perf_hpp_fmt *fmt,struct perf_hpp *hpp,struct hist_entry *he); +int64_t (*cmp)(struct hist_entry *a,struct hist_entry *b); +int64_t (*collapse)(struct hist_entry *a,struct hist_entry *b); +int64_t (*sort)(struct hist_entry *a,struct hist_entry *b);struct list_head list; };
Namhyung Kim
maintainerPATCH 2/20 perf tools: Convert sort entries to hpp formats
In reply to Namhyung KimThis is a preparation of consolidating management of output field and sort keys.
--- tools/perf/ui/hist.c | 6 ++++ tools/perf/util/hist.h | 6 ++++ tools/perf/util/sort.c | 80 +++++++++++++++++++++++++++++++++++++++++++++++--- 3 files changed, 88 insertions(+), 4 deletions(-)
tools/perf/ui/hist.c +6 -0
@@ -284,6 +284,7 @@ struct perf_hpp_fmt perf_hpp__format[] = { };LIST_HEAD (perf_hpp__list); +LIST_HEAD (perf_hpp__sort_list);#undef HPP__COLOR_PRINT_FNS
@@ -325,6 +326,11 @@ void perf_hpp__column_register(struct perf_hpp_fmt *format)list_add_tail (&format->list, &perf_hpp__list); } +void perf_hpp__register_sort_field (struct perf_hpp_fmt *format) +{ +list_add_tail (&format->sort_list, &perf_hpp__sort_list); +} +void perf_hpp__column_enable (unsigned col) {BUG_ON (col >=PERF_HPP__MAX_INDEX );
tools/perf/util/hist.h +6 -0
@@ -165,13 +165,18 @@ struct perf_hpp_fmt {int64_t (*sort)(struct hist_entry *a,struct hist_entry *b);struct list_head list; +struct list_head sort_list; };extern struct list_head perf_hpp__list; +extern struct list_head perf_hpp__sort_list;#define perf_hpp__for_each_format (format) \ list_for_each_entry(format, &perf_hpp__list, list) +#define perf_hpp__for_each_sort_list (format) \ + list_for_each_entry(format, &perf_hpp__sort_list, sort_list) +extern struct perf_hpp_fmt perf_hpp__format[];enum {
@@ -190,6 +195,7 @@ enum {void perf_hpp__init (void );void perf_hpp__column_register (struct perf_hpp_fmt *format);void perf_hpp__column_enable (unsigned col); +void perf_hpp__register_sort_field (struct perf_hpp_fmt *format);typedef u64 (*hpp_field_fn )(struct hist_entry *he);typedef int (*hpp_callback_fn )(struct perf_hpp *hpp,bool front);
tools/perf/util/sort.c +76 -4
106 lines not on this page · raw message
Signature · 1 line
1.9.2
tip-bot for Namhyung Kim
merge bot[tip:perf/core] perf tools: Convert sort entries to hpp formats
perf tools: Convert sort entries to hpp formats
Commit-ID: 8b536999cd75e565125c74b2cf2a746d4f053a92 Gitweb: http://git.kernel.org/tip/8b536999cd75e565125c74b2cf2a746d4f053a92 Author: Namhyung Kim <[email protected]> AuthorDate: Mon, 3 Mar 2014 11:46:55 +0900 Committer: Jiri Olsa <[email protected]> CommitDate: Wed, 21 May 2014 11:45:34 +0200
perf tools: Convert sort entries to hpp formats
This is a preparation of consolidating management of output field and sort keys.
--- tools/perf/ui/hist.c | 6 ++++ tools/perf/util/hist.h | 6 ++++ tools/perf/util/sort.c | 80 +++++++++++++++++++++++++++++++++++++++++++++++--- 3 files changed, 88 insertions(+), 4 deletions(-)
tools/perf/ui/hist.c +6 -0
@@ -284,6 +284,7 @@ struct perf_hpp_fmt perf_hpp__format[] = { };LIST_HEAD (perf_hpp__list); +LIST_HEAD (perf_hpp__sort_list);#undef HPP__COLOR_PRINT_FNS
@@ -325,6 +326,11 @@ void perf_hpp__column_register(struct perf_hpp_fmt *format)list_add_tail (&format->list, &perf_hpp__list); } +void perf_hpp__register_sort_field (struct perf_hpp_fmt *format) +{ +list_add_tail (&format->sort_list, &perf_hpp__sort_list); +} +void perf_hpp__column_enable (unsigned col) {BUG_ON (col >=PERF_HPP__MAX_INDEX );
tools/perf/util/hist.h +6 -0
@@ -165,13 +165,18 @@ struct perf_hpp_fmt {int64_t (*sort)(struct hist_entry *a,struct hist_entry *b);struct list_head list; +struct list_head sort_list; };extern struct list_head perf_hpp__list; +extern struct list_head perf_hpp__sort_list;#define perf_hpp__for_each_format (format) \ list_for_each_entry(format, &perf_hpp__list, list) +#define perf_hpp__for_each_sort_list (format) \ + list_for_each_entry(format, &perf_hpp__sort_list, sort_list) +extern struct perf_hpp_fmt perf_hpp__format[];enum {
@@ -190,6 +195,7 @@ enum {void perf_hpp__init (void );void perf_hpp__column_register (struct perf_hpp_fmt *format);void perf_hpp__column_enable (unsigned col); +void perf_hpp__register_sort_field (struct perf_hpp_fmt *format);typedef u64 (*hpp_field_fn )(struct hist_entry *he);typedef int (*hpp_callback_fn )(struct perf_hpp *hpp,bool front);
tools/perf/util/sort.c +76 -4
106 lines not on this page · raw message
Namhyung Kim
maintainerPATCH 3/20 perf tools: Use hpp formats to sort hist entries
In reply to Namhyung KimIt wrapped sort entries to hpp functions, so using the hpp sort list to sort entries.
--- tools/perf/util/hist.c | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-)
tools/perf/util/hist.c +6 -10
@@ -432,11 +432,11 @@ struct hist_entry *__hists__add_entry(struct hists *hists,int64_t hist_entry__cmp (struct hist_entry *left,struct hist_entry *right) { -struct sort_entry *se; +struct perf_hpp_fmt *fmt;int64_t cmp =0 ; -list_for_each_entry (se, &hist_entry__sort_list, list) { - cmp = se->se_cmp (left, right); +perf_hpp__for_each_sort_list (fmt) { + cmp = fmt->cmp (left, right);if (cmp)break ; }
@@ -447,15 +447,11 @@ hist_entry__cmp(struct hist_entry *left, struct hist_entry *right)int64_t hist_entry__collapse (struct hist_entry *left,struct hist_entry *right) { -struct sort_entry *se; +struct perf_hpp_fmt *fmt;int64_t cmp =0 ; -list_for_each_entry (se, &hist_entry__sort_list, list) { -int64_t (*f)(struct hist_entry *,struct hist_entry *); - - f = se->se_collapse ?: se->se_cmp; - - cmp =f (left, right); +perf_hpp__for_each_sort_list (fmt) { + cmp = fmt->collapse (left, right);if (cmp)break ; }
Signature · 1 line
1.9.2
tip-bot for Namhyung Kim
merge bot[tip:perf/core] perf tools: Use hpp formats to sort hist entries
perf tools: Use hpp formats to sort hist entries
Commit-ID: 093f0ef34c50ff5cca41c1e18e258ff688e915b6 Gitweb: http://git.kernel.org/tip/093f0ef34c50ff5cca41c1e18e258ff688e915b6 Author: Namhyung Kim <[email protected]> AuthorDate: Mon, 3 Mar 2014 12:07:47 +0900 Committer: Jiri Olsa <[email protected]> CommitDate: Wed, 21 May 2014 11:45:34 +0200
perf tools: Use hpp formats to sort hist entries
It wrapped sort entries to hpp functions, so using the hpp sort list to sort entries.
--- tools/perf/util/hist.c | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-)
tools/perf/util/hist.c +6 -10
@@ -432,11 +432,11 @@ struct hist_entry *__hists__add_entry(struct hists *hists,int64_t hist_entry__cmp (struct hist_entry *left,struct hist_entry *right) { -struct sort_entry *se; +struct perf_hpp_fmt *fmt;int64_t cmp =0 ; -list_for_each_entry (se, &hist_entry__sort_list, list) { - cmp = se->se_cmp (left, right); +perf_hpp__for_each_sort_list (fmt) { + cmp = fmt->cmp (left, right);if (cmp)break ; }
@@ -447,15 +447,11 @@ hist_entry__cmp(struct hist_entry *left, struct hist_entry *right)int64_t hist_entry__collapse (struct hist_entry *left,struct hist_entry *right) { -struct sort_entry *se; +struct perf_hpp_fmt *fmt;int64_t cmp =0 ; -list_for_each_entry (se, &hist_entry__sort_list, list) { -int64_t (*f)(struct hist_entry *,struct hist_entry *); - - f = se->se_collapse ?: se->se_cmp; - - cmp =f (left, right); +perf_hpp__for_each_sort_list (fmt) { + cmp = fmt->collapse (left, right);if (cmp)break ; }
Namhyung Kim
maintainerPATCH 4/20 perf tools: Support event grouping in hpp ->sort()
In reply to Namhyung KimMove logic of hist_entry__sort_on_period to __hpp__sort() in order to support event group report.
--- tools/perf/ui/hist.c | 64 +++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 58 insertions(+), 6 deletions(-)
tools/perf/ui/hist.c +58 -6
@@ -116,6 +116,62 @@ int __hpp__fmt(struct perf_hpp *hpp, struct hist_entry *he,return ret; } +static int field_cmp (u64 field_a,u64 field_b) +{ +if (field_a > field_b) +return 1 ; +if (field_a < field_b) +return -1 ; +return 0 ; +} + +static int __hpp__sort (struct hist_entry *a,struct hist_entry *b, +hpp_field_fn get_field) +{ +s64 ret; +int i, nr_members; +struct perf_evsel *evsel; +struct hist_entry *pair; +u64 *fields_a, *fields_b; + + ret =field_cmp (get_field (a),get_field (b)); +if (ret || !symbol_conf.event_group) +return ret; + + evsel =hists_to_evsel (a->hists); +if (!perf_evsel__is_group_event (evsel)) +return ret; + + nr_members = evsel->nr_members; + fields_a =calloc (sizeof (*fields_a), nr_members); + fields_b =calloc (sizeof (*fields_b), nr_members); + +if (!fields_a || !fields_b) + goto out; + +list_for_each_entry (pair, &a->pairs.head, pairs.node) { + evsel =hists_to_evsel (pair->hists); + fields_a[perf_evsel__group_idx (evsel)] =get_field (pair); + } + +list_for_each_entry (pair, &b->pairs.head, pairs.node) { + evsel =hists_to_evsel (pair->hists); + fields_b[perf_evsel__group_idx (evsel)] =get_field (pair); + } + +for (i =1 ; i < nr_members; i++) { + ret =field_cmp (fields_a[i], fields_b[i]); +if (ret) +break ; + } + +out: +free (fields_a); +free (fields_b); + +return ret; +} +#define __HPP_HEADER_FN (_type, _str, _min_width, _unit_width) \ static int hpp__header_##_type(struct perf_hpp_fmt *fmt __maybe_unused, \ struct perf_hpp *hpp, \
@@ -195,9 +251,7 @@ static int hpp__entry_##_type(struct perf_hpp_fmt *_fmt __maybe_unused, \#define __HPP_SORT_FN (_type, _field) \ static int64_t hpp__sort_##_type(struct hist_entry *a, struct hist_entry *b) \ { \ - s64 __a = he_get_##_field(a); \ - s64 __b = he_get_##_field(b); \ - return __a - __b; \ + return __hpp__sort(a, b, he_get_##_field); \ }#define __HPP_ENTRY_RAW_FN (_type, _field) \
@@ -217,9 +271,7 @@ static int hpp__entry_##_type(struct perf_hpp_fmt *_fmt __maybe_unused, \#define __HPP_SORT_RAW_FN (_type, _field) \ static int64_t hpp__sort_##_type(struct hist_entry *a, struct hist_entry *b) \ { \ - s64 __a = he_get_raw_##_field(a); \ - s64 __b = he_get_raw_##_field(b); \ - return __a - __b; \ + return __hpp__sort(a, b, he_get_raw_##_field); \ }
Signature · 1 line
1.9.2
tip-bot for Namhyung Kim
merge bot[tip:perf/core] perf tools: Support event grouping in hpp ->sort( )
perf tools: Support event grouping in hpp ->sort()
Commit-ID: f156d84e427c9e1a855a4bb41156c7d82d87fb47 Gitweb: http://git.kernel.org/tip/f156d84e427c9e1a855a4bb41156c7d82d87fb47 Author: Namhyung Kim <[email protected]> AuthorDate: Mon, 3 Mar 2014 14:14:03 +0900 Committer: Jiri Olsa <[email protected]> CommitDate: Wed, 21 May 2014 11:45:34 +0200
perf tools: Support event grouping in hpp ->sort()
Move logic of hist_entry__sort_on_period to __hpp__sort() in order to support event group report.
--- tools/perf/ui/hist.c | 64 +++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 58 insertions(+), 6 deletions(-)
tools/perf/ui/hist.c +58 -6
@@ -116,6 +116,62 @@ int __hpp__fmt(struct perf_hpp *hpp, struct hist_entry *he,return ret; } +static int field_cmp (u64 field_a,u64 field_b) +{ +if (field_a > field_b) +return 1 ; +if (field_a < field_b) +return -1 ; +return 0 ; +} + +static int __hpp__sort (struct hist_entry *a,struct hist_entry *b, +hpp_field_fn get_field) +{ +s64 ret; +int i, nr_members; +struct perf_evsel *evsel; +struct hist_entry *pair; +u64 *fields_a, *fields_b; + + ret =field_cmp (get_field (a),get_field (b)); +if (ret || !symbol_conf.event_group) +return ret; + + evsel =hists_to_evsel (a->hists); +if (!perf_evsel__is_group_event (evsel)) +return ret; + + nr_members = evsel->nr_members; + fields_a =calloc (sizeof (*fields_a), nr_members); + fields_b =calloc (sizeof (*fields_b), nr_members); + +if (!fields_a || !fields_b) + goto out; + +list_for_each_entry (pair, &a->pairs.head, pairs.node) { + evsel =hists_to_evsel (pair->hists); + fields_a[perf_evsel__group_idx (evsel)] =get_field (pair); + } + +list_for_each_entry (pair, &b->pairs.head, pairs.node) { + evsel =hists_to_evsel (pair->hists); + fields_b[perf_evsel__group_idx (evsel)] =get_field (pair); + } + +for (i =1 ; i < nr_members; i++) { + ret =field_cmp (fields_a[i], fields_b[i]); +if (ret) +break ; + } + +out: +free (fields_a); +free (fields_b); + +return ret; +} +#define __HPP_HEADER_FN (_type, _str, _min_width, _unit_width) \ static int hpp__header_##_type(struct perf_hpp_fmt *fmt __maybe_unused, \ struct perf_hpp *hpp, \
@@ -195,9 +251,7 @@ static int hpp__entry_##_type(struct perf_hpp_fmt *_fmt __maybe_unused, \#define __HPP_SORT_FN (_type, _field) \ static int64_t hpp__sort_##_type(struct hist_entry *a, struct hist_entry *b) \ { \ - s64 __a = he_get_##_field(a); \ - s64 __b = he_get_##_field(b); \ - return __a - __b; \ + return __hpp__sort(a, b, he_get_##_field); \ }#define __HPP_ENTRY_RAW_FN (_type, _field) \
@@ -217,9 +271,7 @@ static int hpp__entry_##_type(struct perf_hpp_fmt *_fmt __maybe_unused, \#define __HPP_SORT_RAW_FN (_type, _field) \ static int64_t hpp__sort_##_type(struct hist_entry *a, struct hist_entry *b) \ { \ - s64 __a = he_get_raw_##_field(a); \ - s64 __b = he_get_raw_##_field(b); \ - return __a - __b; \ + return __hpp__sort(a, b, he_get_raw_##_field); \ }
Namhyung Kim
maintainerPATCH 5/20 perf tools: Use hpp formats to sort final output
In reply to Namhyung KimConvert output sorting function to use ->sort hpp functions.
--- tools/perf/util/hist.c | 62 +++++++------------------------------------------- 1 file changed, 8 insertions(+), 54 deletions(-)
tools/perf/util/hist.c +8 -54
@@ -564,64 +564,18 @@ void hists__collapse_resort(struct hists *hists, struct ui_progress *prog) } } -/* -* reverse the map, sort on period. -*/ - -static int period_cmp (u64 period_a,u64 period_b) +static int hist_entry__sort (struct hist_entry *a,struct hist_entry *b) { -if (period_a > period_b) -return 1 ; -if (period_a < period_b) -return -1 ; -return 0 ; -} - -static int hist_entry__sort_on_period (struct hist_entry *a, -struct hist_entry *b) -{ -int ret; -int i, nr_members; -struct perf_evsel *evsel; -struct hist_entry *pair; -u64 *periods_a, *periods_b; - - ret =period_cmp (a->stat.period, b->stat.period); -if (ret || !symbol_conf.event_group) -return ret; - - evsel =hists_to_evsel (a->hists); - nr_members = evsel->nr_members; -if (nr_members <=1 ) -return ret; - - periods_a =zalloc (sizeof (periods_a) * nr_members); - periods_b =zalloc (sizeof (periods_b) * nr_members); - -if (!periods_a || !periods_b) - goto out; - -list_for_each_entry (pair, &a->pairs.head, pairs.node) { - evsel =hists_to_evsel (pair->hists); - periods_a[perf_evsel__group_idx (evsel)] = pair->stat.period; - } - -list_for_each_entry (pair, &b->pairs.head, pairs.node) { - evsel =hists_to_evsel (pair->hists); - periods_b[perf_evsel__group_idx (evsel)] = pair->stat.period; - } +struct perf_hpp_fmt *fmt; +int64_t cmp =0 ; -for (i =1 ; i < nr_members; i++) { - ret =period_cmp (periods_a[i], periods_b[i]); -if (ret) +perf_hpp__for_each_format (fmt) { + cmp = fmt->sort (a, b); +if (cmp)break ; } -out: -free (periods_a); -free (periods_b); - -return ret; +return cmp; }static void hists__reset_filter_stats (struct hists *hists)
@@ -669,7 +623,7 @@ static void __hists__insert_output_entry(struct rb_root *entries, parent = *p; iter = rb_entry(parent, struct hist_entry, rb_node); -if (hist_entry__sort_on_period (he, iter) >0 ) +if (hist_entry__sort (he, iter) >0 ) p = &(*p)->rb_left;else p = &(*p)->rb_right;
Signature · 1 line
1.9.2
tip-bot for Namhyung Kim
merge bot[tip:perf/core] perf tools: Use hpp formats to sort final output
perf tools: Use hpp formats to sort final output
Commit-ID: 043ca389a3181565b5c19d43a55eae111977d13d Gitweb: http://git.kernel.org/tip/043ca389a3181565b5c19d43a55eae111977d13d Author: Namhyung Kim <[email protected]> AuthorDate: Mon, 3 Mar 2014 14:18:00 +0900 Committer: Jiri Olsa <[email protected]> CommitDate: Wed, 21 May 2014 11:45:34 +0200
perf tools: Use hpp formats to sort final output
Convert output sorting function to use ->sort hpp functions.
--- tools/perf/util/hist.c | 62 +++++++------------------------------------------- 1 file changed, 8 insertions(+), 54 deletions(-)
tools/perf/util/hist.c +8 -54
@@ -564,64 +564,18 @@ void hists__collapse_resort(struct hists *hists, struct ui_progress *prog) } } -/* -* reverse the map, sort on period. -*/ - -static int period_cmp (u64 period_a,u64 period_b) +static int hist_entry__sort (struct hist_entry *a,struct hist_entry *b) { -if (period_a > period_b) -return 1 ; -if (period_a < period_b) -return -1 ; -return 0 ; -} - -static int hist_entry__sort_on_period (struct hist_entry *a, -struct hist_entry *b) -{ -int ret; -int i, nr_members; -struct perf_evsel *evsel; -struct hist_entry *pair; -u64 *periods_a, *periods_b; - - ret =period_cmp (a->stat.period, b->stat.period); -if (ret || !symbol_conf.event_group) -return ret; - - evsel =hists_to_evsel (a->hists); - nr_members = evsel->nr_members; -if (nr_members <=1 ) -return ret; - - periods_a =zalloc (sizeof (periods_a) * nr_members); - periods_b =zalloc (sizeof (periods_b) * nr_members); - -if (!periods_a || !periods_b) - goto out; - -list_for_each_entry (pair, &a->pairs.head, pairs.node) { - evsel =hists_to_evsel (pair->hists); - periods_a[perf_evsel__group_idx (evsel)] = pair->stat.period; - } - -list_for_each_entry (pair, &b->pairs.head, pairs.node) { - evsel =hists_to_evsel (pair->hists); - periods_b[perf_evsel__group_idx (evsel)] = pair->stat.period; - } +struct perf_hpp_fmt *fmt; +int64_t cmp =0 ; -for (i =1 ; i < nr_members; i++) { - ret =period_cmp (periods_a[i], periods_b[i]); -if (ret) +perf_hpp__for_each_format (fmt) { + cmp = fmt->sort (a, b); +if (cmp)break ; } -out: -free (periods_a); -free (periods_b); - -return ret; +return cmp; }static void hists__reset_filter_stats (struct hists *hists)
@@ -669,7 +623,7 @@ static void __hists__insert_output_entry(struct rb_root *entries, parent = *p; iter = rb_entry(parent, struct hist_entry, rb_node); -if (hist_entry__sort_on_period (he, iter) >0 ) +if (hist_entry__sort (he, iter) >0 ) p = &(*p)->rb_left;else p = &(*p)->rb_right;
Namhyung Kim
maintainerPATCH 6/20 perf tools: Consolidate output field handling to hpp format routines
In reply to Namhyung KimUntil now the hpp and sort functions do similar jobs different ways. Since the sort functions converted/wrapped to hpp formats it can do the job in a uniform way.
The perf_hpp__sort_list has a list of hpp formats to sort entries and the perf_hpp__list has a list of hpp formats to print output result.
To have a backward compatiblity, it automatically adds 'overhead' field in front of sort list. And then all of fields in sort list added to the output list (if it's not already there).
--- tools/perf/ui/browsers/hists.c | 32 +++++++++++++++--------- tools/perf/ui/gtk/hists.c | 31 ------------------------ tools/perf/ui/hist.c | 26 ++++++++++++++++++++ tools/perf/ui/stdio/hist.c | 55 +++++++++++++----------------------------- tools/perf/util/hist.c | 2 +- tools/perf/util/hist.h | 1 + 6 files changed, 65 insertions(+), 82 deletions(-)
tools/perf/ui/browsers/hists.c +20 -12
@@ -760,8 +760,8 @@ static int hist_browser__show_entry(struct hist_browser *browser,if (!browser->b.navkeypressed) width +=1 ; -hist_entry__sort_snprintf (entry, s,sizeof (s), browser->hists); -slsmg_write_nstring (s, width); +slsmg_write_nstring ("" , width); + ++row; ++printed; }else
@@ -1104,27 +1104,35 @@ static int hist_browser__fprintf_entry(struct hist_browser *browser, struct hist_entry *he, FILE *fp) { char s[8192]; -double percent;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;if (symbol_conf.use_callchain) folded_sign =hist_entry__folded (he); -hist_entry__sort_snprintf (he, s,sizeof (s), browser->hists); - percent = (he->stat.period *100.0 ) / browser->hists->stats.total_period; -if (symbol_conf.use_callchain) printed +=fprintf (fp,"%c " , folded_sign); - printed +=fprintf (fp," %5.2f%%" , percent); - -if (symbol_conf.show_nr_samples) - printed +=fprintf (fp," %11u" , he->stat.nr_events); +perf_hpp__for_each_format (fmt) { +if (perf_hpp__should_skip (fmt)) +continue ; -if (symbol_conf.show_total_period) - printed +=fprintf (fp," %12" PRIu64, he->stat.period); +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); + } printed +=fprintf (fp,"%s\n" ,rtrim (s));if (folded_sign =='-' )
tools/perf/ui/gtk/hists.c +0 -31
@@ -153,7 +153,6 @@ static void perf_gtk__show_hists(GtkWidget *window, struct hists *hists,struct perf_hpp_fmt *fmt;GType col_types[MAX_COLUMNS ];GtkCellRenderer *renderer; -struct sort_entry *se;GtkTreeStore *store;struct rb_node *nd;GtkWidget *view;
@@ -172,16 +171,6 @@ static void perf_gtk__show_hists(GtkWidget *window, struct hists *hists,perf_hpp__for_each_format (fmt) col_types[nr_cols++] =G_TYPE_STRING ; -list_for_each_entry (se, &hist_entry__sort_list, list) { -if (se->elide) -continue ; - -if (se == &sort_sym) - sym_col = nr_cols; - - col_types[nr_cols++] =G_TYPE_STRING ; - } - store =gtk_tree_store_newv (nr_cols, col_types); view =gtk_tree_view_new ();
@@ -199,16 +188,6 @@ static void perf_gtk__show_hists(GtkWidget *window, struct hists *hists, col_idx++, NULL); } -list_for_each_entry (se, &hist_entry__sort_list, list) { -if (se->elide) -continue ; - -gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (view), --1 , se->se_header, - renderer,"text" , - col_idx++,NULL ); - } -for (col_idx =0 ; col_idx < nr_cols; col_idx++) {GtkTreeViewColumn *column;
@@ -253,16 +232,6 @@ static void perf_gtk__show_hists(GtkWidget *window, struct hists *hists,gtk_tree_store_set (store, &iter, col_idx++, s,-1 ); } -list_for_each_entry (se, &hist_entry__sort_list, list) { -if (se->elide) -continue ; - - se->se_snprintf (h, s,ARRAY_SIZE (s), -hists__col_len (hists, se->se_width_idx)); - -gtk_tree_store_set (store, &iter, col_idx++, s,-1 ); - } -if (symbol_conf.use_callchain && sort__has_sym) {if (callchain_param.mode ==CHAIN_GRAPH_REL ) total = h->stat.period;
tools/perf/ui/hist.c +26 -0
@@ -354,6 +354,14 @@ LIST_HEAD(perf_hpp__sort_list);void perf_hpp__init (void ) { +struct list_head *list; +int i; + +for (i =0 ; i <PERF_HPP__MAX_INDEX ; i++) { +INIT_LIST_HEAD (&perf_hpp__format[i].list); +INIT_LIST_HEAD (&perf_hpp__format[i].sort_list); + } +perf_hpp__column_enable (PERF_HPP__OVERHEAD );if (symbol_conf.show_cpu_utilization) {
@@ -371,6 +379,13 @@ void perf_hpp__init(void)if (symbol_conf.show_total_period)perf_hpp__column_enable (PERF_HPP__PERIOD ); + +/* prepend overhead field for backward compatiblity. */ + list = &perf_hpp__format[PERF_HPP__OVERHEAD ].sort_list; +if (list_empty (list)) +list_add (list, &perf_hpp__sort_list); + +perf_hpp__setup_output_field (); }void perf_hpp__column_register (struct perf_hpp_fmt *format)
@@ -389,6 +404,17 @@ void perf_hpp__column_enable(unsigned col)perf_hpp__column_register (&perf_hpp__format[col]); } +void perf_hpp__setup_output_field (void ) +{ +struct perf_hpp_fmt *fmt; + +/* append sort keys to output field */ +perf_hpp__for_each_sort_list (fmt) { +if (list_empty (&fmt->list)) +perf_hpp__column_register (fmt); + } +} +int hist_entry__sort_snprintf (struct hist_entry *he,char *s,size_t size,struct hists *hists) {
tools/perf/ui/stdio/hist.c +17 -38
88 lines not on this page · raw message
tools/perf/util/hist.c +1 -1
@@ -569,7 +569,7 @@ static int hist_entry__sort(struct hist_entry *a, struct hist_entry *b)struct perf_hpp_fmt *fmt;int64_t cmp =0 ; -perf_hpp__for_each_format (fmt) { +perf_hpp__for_each_sort_list (fmt) { cmp = fmt->sort (a, b);if (cmp)break ;
tools/perf/util/hist.h +1 -0
@@ -196,6 +196,7 @@ void perf_hpp__init(void);void perf_hpp__column_register (struct perf_hpp_fmt *format);void perf_hpp__column_enable (unsigned col);void perf_hpp__register_sort_field (struct perf_hpp_fmt *format); +void perf_hpp__setup_output_field (void );typedef u64 (*hpp_field_fn )(struct hist_entry *he);typedef int (*hpp_callback_fn )(struct perf_hpp *hpp,bool front);
Signature · 1 line
1.9.2
Re: [PATCH 06/20] perf tools: Consolidate output field handling to hpp format routines
On Mon, May 19, 2014 at 03:25:48PM +0900, Namhyung Kim wrote:
SNIP
Quoted 21 lines
tools/perf/ui/browsers/hists.c +7
-4@@ -1104,27 +1104,35 @@ static int hist_browser__fprintf_entry(struct hist_browser *browser, struct hist_entry *he, FILE *fp) { char s[8192]; -double percent;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;if (symbol_conf.use_callchain) folded_sign =hist_entry__folded (he); -hist_entry__sort_snprintf (he, s,sizeof (s), browser->hists); - percent = (he->stat.period *100.0 ) / browser->hists->stats.total_period; -
tools/perf/ui/browsers/hists.c static int hist_browser__fprintf_entry(struct hist_browser *browser, · line 1125
Quoted 10 lines
tools/perf/ui/browsers/hists.c +3
-4if (symbol_conf.use_callchain) printed +=fprintf (fp,"%c " , folded_sign); - printed +=fprintf (fp," %5.2f%%" , percent); - -if (symbol_conf.show_nr_samples) - printed +=fprintf (fp," %11u" , he->stat.nr_events); +perf_hpp__for_each_format (fmt) { +if (perf_hpp__should_skip (fmt)) +continue ;
this one is defined in later patch, so it breaks build in this one
jirka
Namhyung Kim
maintainerRe: [PATCH 06/20] perf tools: Consolidate output field handling to hpp format routines
2014-05-19 (월), 15:12 +0200, Jiri Olsa:
Quoted 28 lines · Namhyung Kim
SNIP
Quoted 24 lines
tools/perf/ui/browsers/hists.c +7
-4@@ -1104,27 +1104,35 @@ static int hist_browser__fprintf_entry(struct hist_browser *browser, struct hist_entry *he, FILE *fp) { char s[8192]; -double percent;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;if (symbol_conf.use_callchain) folded_sign =hist_entry__folded (he); -hist_entry__sort_snprintf (he, s,sizeof (s), browser->hists); - percent = (he->stat.period *100.0 ) / browser->hists->stats.total_period; -if (symbol_conf.use_callchain) printed +=fprintf (fp,"%c " , folded_sign);
Quoted 9 lines
tools/perf/ui/browsers/hists.c static int hist_browser__fprintf_entry(struct hist_browser *browser, · line 1125
Quoted 7 lines
tools/perf/ui/browsers/hists.c +3
-4- printed +=fprintf (fp," %5.2f%%" , percent); - -if (symbol_conf.show_nr_samples) - printed +=fprintf (fp," %11u" , he->stat.nr_events); +perf_hpp__for_each_format (fmt) { +if (perf_hpp__should_skip (fmt)) +continue ;this one is defined in later patch, so it breaks build in this one
Argh, right. This one came from a later fixup with interactive rebase and missed test.. I'll fix and resend, sorry about that.
Thanks,
Namhyung
Namhyung Kim
maintainerRe: [PATCH 06/20] perf tools: Consolidate output field handling to hpp format routines
Jiri,
I updated my -v6 branch to fix the breakage - move the hunk to 15/20. Do you want me to resend or would you review with this thread directly? Either way would be find to me.
Thanks,
Namhyung
Quoted 44 lines · Namhyung Kim
2014-05-19 (월), 15:12 +0200, Jiri Olsa:
Quoted 28 lines · Namhyung Kim
SNIP
Quoted 24 lines
tools/perf/ui/browsers/hists.c +7
-4@@ -1104,27 +1104,35 @@ static int hist_browser__fprintf_entry(struct hist_browser *browser, struct hist_entry *he, FILE *fp) { char s[8192]; -double percent;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;if (symbol_conf.use_callchain) folded_sign =hist_entry__folded (he); -hist_entry__sort_snprintf (he, s,sizeof (s), browser->hists); - percent = (he->stat.period *100.0 ) / browser->hists->stats.total_period; -if (symbol_conf.use_callchain) printed +=fprintf (fp,"%c " , folded_sign);Quoted 9 lines
tools/perf/ui/browsers/hists.c static int hist_browser__fprintf_entry(struct hist_browser *browser, · line 1125
Quoted 7 lines
tools/perf/ui/browsers/hists.c +3
-4- printed +=fprintf (fp," %5.2f%%" , percent); - -if (symbol_conf.show_nr_samples) - printed +=fprintf (fp," %11u" , he->stat.nr_events); +perf_hpp__for_each_format (fmt) { +if (perf_hpp__should_skip (fmt)) +continue ;this one is defined in later patch, so it breaks build in this one
Argh, right. This one came from a later fixup with interactive rebase and missed test.. I'll fix and resend, sorry about that.
Thanks,
Namhyung
Re: [PATCH 06/20] perf tools: Consolidate output field handling to hpp format routines
Quoted 5 lines · Namhyung Kim
Jiri,
I updated my -v6 branch to fix the breakage - move the hunk to 15/20. Do you want me to resend or would you review with this thread directly? Either way would be find to me.
np, I can take it from branch
jirka
Namhyung Kim
maintainerPATCH 7/20 perf ui: Get rid of callback from __hpp__fmt()
In reply to Namhyung KimThe callback was used by TUI for determining color of folded sign using percent of first field/column. But it cannot be used anymore since it now support dynamic reording of output field.
So move the logic to the hist_browser__show_entry().
--- tools/perf/ui/browsers/hists.c | 62 ++++++++++++++++-------------------------- tools/perf/ui/gtk/hists.c | 2 +- tools/perf/ui/hist.c | 28 ++++++------------- tools/perf/util/hist.h | 4 +-- 4 files changed, 34 insertions(+), 62 deletions(-)
tools/perf/ui/browsers/hists.c +23 -39
@@ -616,35 +616,6 @@ struct hpp_arg {bool current_entry; }; -static int __hpp__overhead_callback (struct perf_hpp *hpp,bool front) -{ -struct hpp_arg *arg = hpp->ptr; - -if (arg->current_entry && arg->b->navkeypressed) -ui_browser__set_color (arg->b,HE_COLORSET_SELECTED ); -else -ui_browser__set_color (arg->b,HE_COLORSET_NORMAL ); - -if (front) { -if (!symbol_conf.use_callchain) -return 0 ; - -slsmg_printf ("%c " , arg->folded_sign); -return 2 ; - } - -return 0 ; -} - -static int __hpp__color_callback (struct perf_hpp *hpp,bool front__maybe_unused ) -{ -struct hpp_arg *arg = hpp->ptr; - -if (!arg->current_entry || !arg->b->navkeypressed) -ui_browser__set_color (arg->b,HE_COLORSET_NORMAL ); -return 0 ; -} -static int __hpp__slsmg_color_printf (struct perf_hpp *hpp,const char *fmt, ...) {struct hpp_arg *arg = hpp->ptr;
@@ -665,7 +636,7 @@ static int __hpp__slsmg_color_printf(struct perf_hpp *hpp, const char *fmt, ...)return ret; } -#define __HPP_COLOR_PERCENT_FN (_type, _field, _cb) \ +#define __HPP_COLOR_PERCENT_FN (_type, _field) \ static u64 __hpp_get_##_field(struct hist_entry *he) \ { \ return he->stat._field; \
@@ -676,15 +647,15 @@ hist_browser__hpp_color_##_type(struct perf_hpp_fmt *fmt __maybe_unused,\struct perf_hpp *hpp, \ struct hist_entry *he) \ { \ - return __hpp__fmt(hpp, he, __hpp_get_##_field, _cb, " %6.2f%%", \ + return __hpp__fmt(hpp, he, __hpp_get_##_field, " %6.2f%%", \__hpp__slsmg_color_printf ,true ); \ } -__HPP_COLOR_PERCENT_FN(overhead, period, __hpp__overhead_callback) -__HPP_COLOR_PERCENT_FN(overhead_sys, period_sys, __hpp__color_callback) -__HPP_COLOR_PERCENT_FN(overhead_us, period_us, __hpp__color_callback) -__HPP_COLOR_PERCENT_FN(overhead_guest_sys, period_guest_sys, __hpp__color_callback) -__HPP_COLOR_PERCENT_FN(overhead_guest_us, period_guest_us, __hpp__color_callback) +__HPP_COLOR_PERCENT_FN(overhead, period) +__HPP_COLOR_PERCENT_FN(overhead_sys, period_sys) +__HPP_COLOR_PERCENT_FN(overhead_us, period_us) +__HPP_COLOR_PERCENT_FN(overhead_guest_sys, period_guest_sys) +__HPP_COLOR_PERCENT_FN(overhead_guest_us, period_guest_us)#undef __HPP_COLOR_PERCENT_FN
@@ -729,7 +700,7 @@ static int hist_browser__show_entry(struct hist_browser *browser,if (row_offset ==0 ) {struct hpp_arg arg = { - .b = &browser->b, + .b = &browser->b, .folded_sign = folded_sign, .current_entry = current_entry, };
@@ -742,11 +713,24 @@ static int hist_browser__show_entry(struct hist_browser *browser,ui_browser__gotorc (&browser->b, row,0 );perf_hpp__for_each_format (fmt) { -if (!first) { +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) { +if (symbol_conf.use_callchain) { +slsmg_printf ("%c " , folded_sign); + width -=2 ; + } + first = false; + }else {slsmg_printf (" " ); width -=2 ; } - first = false;if (fmt->color) { width -= fmt->color (fmt, &hpp, entry);
tools/perf/ui/gtk/hists.c +1 -1
@@ -43,7 +43,7 @@ static int perf_gtk__hpp_color_##_type(struct perf_hpp_fmt *fmt __maybe_unused,struct perf_hpp *hpp, \ struct hist_entry *he) \ { \ - return __hpp__fmt(hpp, he, he_get_##_field, NULL, " %6.2f%%", \ + return __hpp__fmt(hpp, he, he_get_##_field, " %6.2f%%", \__percent_color_snprintf ,true ); \ }
tools/perf/ui/hist.c +8 -20
@@ -16,20 +16,15 @@ })int __hpp__fmt (struct perf_hpp *hpp,struct hist_entry *he, -hpp_field_fn get_field,hpp_callback_fn callback, -const char *fmt,hpp_snprint_fn print_fn,bool fmt_percent) +hpp_field_fn get_field,const char *fmt, +hpp_snprint_fn print_fn,bool fmt_percent) { -int ret =0 ; +int ret;struct hists *hists = he->hists;struct perf_evsel *evsel =hists_to_evsel (hists);char *buf = hpp->buf;size_t size = hpp->size; -if (callback) { - ret =callback (hpp, true); -advance_hpp (hpp, ret); - } -if (fmt_percent) {double percent =0.0 ;u64 total =hists__total_period (hists);
@@ -37,9 +32,9 @@ int __hpp__fmt(struct perf_hpp *hpp, struct hist_entry *he,if (total) percent =100.0 *get_field (he) / total; - ret +=hpp__call_print_fn (hpp, print_fn, fmt, percent); + ret =hpp__call_print_fn (hpp, print_fn, fmt, percent); }else - ret +=hpp__call_print_fn (hpp, print_fn, fmt,get_field (he)); + ret =hpp__call_print_fn (hpp, print_fn, fmt,get_field (he));if (perf_evsel__is_group_event (evsel)) {int prev_idx, idx_delta;
@@ -99,13 +94,6 @@ int __hpp__fmt(struct perf_hpp *hpp, struct hist_entry *he, } } -if (callback) { -int __ret =callback (hpp, false); - -advance_hpp (hpp, __ret); - ret += __ret; - } -/* * Restore original buf and size as it's where caller expects * the result will be saved.
@@ -235,7 +223,7 @@ static u64 he_get_##_field(struct hist_entry *he) \ static int hpp__color_##_type(struct perf_hpp_fmt *fmt __maybe_unused, \struct perf_hpp *hpp,struct hist_entry *he) \ { \ - return __hpp__fmt(hpp, he, he_get_##_field, NULL, " %6.2f%%", \ + return __hpp__fmt(hpp, he, he_get_##_field, " %6.2f%%", \ hpp_color_scnprintf, true); \ }
@@ -244,7 +232,7 @@ static int hpp__entry_##_type(struct perf_hpp_fmt *_fmt __maybe_unused, \ struct perf_hpp *hpp, struct hist_entry *he) \ { \const char *fmt = symbol_conf.field_sep ?" %.2f" :" %6.2f%%" ; \ - return __hpp__fmt(hpp, he, he_get_##_field, NULL, fmt, \ + return __hpp__fmt(hpp, he, he_get_##_field, fmt, \ hpp_entry_scnprintf, true); \ }
@@ -264,7 +252,7 @@ static int hpp__entry_##_type(struct perf_hpp_fmt *_fmt __maybe_unused, \ struct perf_hpp *hpp, struct hist_entry *he) \ { \const char *fmt = symbol_conf.field_sep ?" %" PRIu64 :" %11" PRIu64; \ - return __hpp__fmt(hpp, he, he_get_raw_##_field, NULL, fmt, \ + return __hpp__fmt(hpp, he, he_get_raw_##_field, fmt, \ hpp_entry_scnprintf, false); \ }
tools/perf/util/hist.h +2 -2
@@ -203,8 +203,8 @@ typedef int (*hpp_callback_fn)(struct perf_hpp *hpp, bool front);typedef int (*hpp_snprint_fn )(struct perf_hpp *hpp,const char *fmt, ...);int __hpp__fmt (struct perf_hpp *hpp,struct hist_entry *he, -hpp_field_fn get_field,hpp_callback_fn callback, -const char *fmt,hpp_snprint_fn print_fn,bool fmt_percent); +hpp_field_fn get_field,const char *fmt, +hpp_snprint_fn print_fn,bool fmt_percent);static inline void advance_hpp (struct perf_hpp *hpp,int inc) {
Signature · 1 line
1.9.2
tip-bot for Namhyung Kim
merge bot[tip:perf/core] perf ui: Get rid of callback from __hpp__fmt()
perf ui: Get rid of callback from __hpp__fmt()
Commit-ID: fb821c9e7135e324ff6d50d030352718a80364b4 Gitweb: http://git.kernel.org/tip/fb821c9e7135e324ff6d50d030352718a80364b4 Author: Namhyung Kim <[email protected]> AuthorDate: Mon, 3 Mar 2014 17:05:19 +0900 Committer: Jiri Olsa <[email protected]> CommitDate: Wed, 21 May 2014 11:45:34 +0200
perf ui: Get rid of callback from __hpp__fmt()
The callback was used by TUI for determining color of folded sign using percent of first field/column. But it cannot be used anymore since it now support dynamic reordering of output field.
So move the logic to the hist_browser__show_entry().
--- tools/perf/ui/browsers/hists.c | 62 ++++++++++++++++-------------------------- tools/perf/ui/gtk/hists.c | 2 +- tools/perf/ui/hist.c | 28 ++++++------------- tools/perf/util/hist.h | 4 +-- 4 files changed, 34 insertions(+), 62 deletions(-)
tools/perf/ui/browsers/hists.c +23 -39
@@ -616,35 +616,6 @@ struct hpp_arg {bool current_entry; }; -static int __hpp__overhead_callback (struct perf_hpp *hpp,bool front) -{ -struct hpp_arg *arg = hpp->ptr; - -if (arg->current_entry && arg->b->navkeypressed) -ui_browser__set_color (arg->b,HE_COLORSET_SELECTED ); -else -ui_browser__set_color (arg->b,HE_COLORSET_NORMAL ); - -if (front) { -if (!symbol_conf.use_callchain) -return 0 ; - -slsmg_printf ("%c " , arg->folded_sign); -return 2 ; - } - -return 0 ; -} - -static int __hpp__color_callback (struct perf_hpp *hpp,bool front__maybe_unused ) -{ -struct hpp_arg *arg = hpp->ptr; - -if (!arg->current_entry || !arg->b->navkeypressed) -ui_browser__set_color (arg->b,HE_COLORSET_NORMAL ); -return 0 ; -} -static int __hpp__slsmg_color_printf (struct perf_hpp *hpp,const char *fmt, ...) {struct hpp_arg *arg = hpp->ptr;
@@ -665,7 +636,7 @@ static int __hpp__slsmg_color_printf(struct perf_hpp *hpp, const char *fmt, ...)return ret; } -#define __HPP_COLOR_PERCENT_FN (_type, _field, _cb) \ +#define __HPP_COLOR_PERCENT_FN (_type, _field) \ static u64 __hpp_get_##_field(struct hist_entry *he) \ { \ return he->stat._field; \
@@ -676,15 +647,15 @@ hist_browser__hpp_color_##_type(struct perf_hpp_fmt *fmt __maybe_unused,\struct perf_hpp *hpp, \ struct hist_entry *he) \ { \ - return __hpp__fmt(hpp, he, __hpp_get_##_field, _cb, " %6.2f%%", \ + return __hpp__fmt(hpp, he, __hpp_get_##_field, " %6.2f%%", \__hpp__slsmg_color_printf ,true ); \ } -__HPP_COLOR_PERCENT_FN(overhead, period, __hpp__overhead_callback) -__HPP_COLOR_PERCENT_FN(overhead_sys, period_sys, __hpp__color_callback) -__HPP_COLOR_PERCENT_FN(overhead_us, period_us, __hpp__color_callback) -__HPP_COLOR_PERCENT_FN(overhead_guest_sys, period_guest_sys, __hpp__color_callback) -__HPP_COLOR_PERCENT_FN(overhead_guest_us, period_guest_us, __hpp__color_callback) +__HPP_COLOR_PERCENT_FN(overhead, period) +__HPP_COLOR_PERCENT_FN(overhead_sys, period_sys) +__HPP_COLOR_PERCENT_FN(overhead_us, period_us) +__HPP_COLOR_PERCENT_FN(overhead_guest_sys, period_guest_sys) +__HPP_COLOR_PERCENT_FN(overhead_guest_us, period_guest_us)#undef __HPP_COLOR_PERCENT_FN
@@ -729,7 +700,7 @@ static int hist_browser__show_entry(struct hist_browser *browser,if (row_offset ==0 ) {struct hpp_arg arg = { - .b = &browser->b, + .b = &browser->b, .folded_sign = folded_sign, .current_entry = current_entry, };
@@ -742,11 +713,24 @@ static int hist_browser__show_entry(struct hist_browser *browser,ui_browser__gotorc (&browser->b, row,0 );perf_hpp__for_each_format (fmt) { -if (!first) { +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) { +if (symbol_conf.use_callchain) { +slsmg_printf ("%c " , folded_sign); + width -=2 ; + } + first = false; + }else {slsmg_printf (" " ); width -=2 ; } - first = false;if (fmt->color) { width -= fmt->color (fmt, &hpp, entry);
tools/perf/ui/gtk/hists.c +1 -1
@@ -43,7 +43,7 @@ static int perf_gtk__hpp_color_##_type(struct perf_hpp_fmt *fmt __maybe_unused,struct perf_hpp *hpp, \ struct hist_entry *he) \ { \ - return __hpp__fmt(hpp, he, he_get_##_field, NULL, " %6.2f%%", \ + return __hpp__fmt(hpp, he, he_get_##_field, " %6.2f%%", \__percent_color_snprintf ,true ); \ }
tools/perf/ui/hist.c +8 -20
@@ -16,20 +16,15 @@ })int __hpp__fmt (struct perf_hpp *hpp,struct hist_entry *he, -hpp_field_fn get_field,hpp_callback_fn callback, -const char *fmt,hpp_snprint_fn print_fn,bool fmt_percent) +hpp_field_fn get_field,const char *fmt, +hpp_snprint_fn print_fn,bool fmt_percent) { -int ret =0 ; +int ret;struct hists *hists = he->hists;struct perf_evsel *evsel =hists_to_evsel (hists);char *buf = hpp->buf;size_t size = hpp->size; -if (callback) { - ret =callback (hpp, true); -advance_hpp (hpp, ret); - } -if (fmt_percent) {double percent =0.0 ;u64 total =hists__total_period (hists);
@@ -37,9 +32,9 @@ int __hpp__fmt(struct perf_hpp *hpp, struct hist_entry *he,if (total) percent =100.0 *get_field (he) / total; - ret +=hpp__call_print_fn (hpp, print_fn, fmt, percent); + ret =hpp__call_print_fn (hpp, print_fn, fmt, percent); }else - ret +=hpp__call_print_fn (hpp, print_fn, fmt,get_field (he)); + ret =hpp__call_print_fn (hpp, print_fn, fmt,get_field (he));if (perf_evsel__is_group_event (evsel)) {int prev_idx, idx_delta;
@@ -99,13 +94,6 @@ int __hpp__fmt(struct perf_hpp *hpp, struct hist_entry *he, } } -if (callback) { -int __ret =callback (hpp, false); - -advance_hpp (hpp, __ret); - ret += __ret; - } -/* * Restore original buf and size as it's where caller expects * the result will be saved.
@@ -235,7 +223,7 @@ static u64 he_get_##_field(struct hist_entry *he) \ static int hpp__color_##_type(struct perf_hpp_fmt *fmt __maybe_unused, \struct perf_hpp *hpp,struct hist_entry *he) \ { \ - return __hpp__fmt(hpp, he, he_get_##_field, NULL, " %6.2f%%", \ + return __hpp__fmt(hpp, he, he_get_##_field, " %6.2f%%", \ hpp_color_scnprintf, true); \ }
@@ -244,7 +232,7 @@ static int hpp__entry_##_type(struct perf_hpp_fmt *_fmt __maybe_unused, \ struct perf_hpp *hpp, struct hist_entry *he) \ { \const char *fmt = symbol_conf.field_sep ?" %.2f" :" %6.2f%%" ; \ - return __hpp__fmt(hpp, he, he_get_##_field, NULL, fmt, \ + return __hpp__fmt(hpp, he, he_get_##_field, fmt, \ hpp_entry_scnprintf, true); \ }
@@ -264,7 +252,7 @@ static int hpp__entry_##_type(struct perf_hpp_fmt *_fmt __maybe_unused, \ struct perf_hpp *hpp, struct hist_entry *he) \ { \const char *fmt = symbol_conf.field_sep ?" %" PRIu64 :" %11" PRIu64; \ - return __hpp__fmt(hpp, he, he_get_raw_##_field, NULL, fmt, \ + return __hpp__fmt(hpp, he, he_get_raw_##_field, fmt, \ hpp_entry_scnprintf, false); \ }
tools/perf/util/hist.h +2 -2
@@ -203,8 +203,8 @@ typedef int (*hpp_callback_fn)(struct perf_hpp *hpp, bool front);typedef int (*hpp_snprint_fn )(struct perf_hpp *hpp,const char *fmt, ...);int __hpp__fmt (struct perf_hpp *hpp,struct hist_entry *he, -hpp_field_fn get_field,hpp_callback_fn callback, -const char *fmt,hpp_snprint_fn print_fn,bool fmt_percent); +hpp_field_fn get_field,const char *fmt, +hpp_snprint_fn print_fn,bool fmt_percent);static inline void advance_hpp (struct perf_hpp *hpp,int inc) {
Namhyung Kim
maintainerPATCH 8/20 perf tools: Allow hpp fields to be sort keys
In reply to Namhyung KimAdd overhead{,_sys,_us,_guest_sys,_guest_us}, sample and period sort keys so that they can be selected with --sort/-s option.
$ perf report -s period,comm --stdio
...
# Overhead Period Command
# ........ ............ ...............
#
47.06% 152 swapper
13.93% 45 qemu-system-arm
12.38% 40 synergys
3.72% 12 firefox
2.48% 8 xchat--- tools/perf/Documentation/perf-diff.txt | 5 ++-- tools/perf/Documentation/perf-report.txt | 9 ++++++++ tools/perf/Documentation/perf-top.txt | 5 ++-- tools/perf/builtin-diff.c | 3 ++- tools/perf/builtin-report.c | 6 ++--- tools/perf/builtin-top.c | 4 ++-- tools/perf/ui/hist.c | 9 ++++++-- tools/perf/util/sort.c | 39 ++++++++++++++++++++++++++++++++ 8 files changed, 67 insertions(+), 13 deletions(-)
tools/perf/Documentation/perf-diff.txt +3 -2
@@ -50,7 +50,8 @@ OPTIONS -s:: --sort=:: - Sort by key(s): pid, comm, dso, symbol. + Sort by key(s): pid, comm, dso, symbol, cpu, parent, srcline. + Please see description of --sort in the perf-report man page. -t:: --field-separator=::
@@ -202,4 +203,4 @@ If specified the 'Weighted diff' column is displayed with value 'd' computed as: SEE ALSO -------- -linkperf:perf-record[1] +linkperf:perf-record[1], linkperf:perf-report[1]
tools/perf/Documentation/perf-report.txt +9 -0
@@ -79,6 +79,15 @@ OPTIONS abort cost. This is the global weight. - local_weight: Local weight version of the weight above. - transaction: Transaction abort flags. + - overhead: Overhead percentage of sample + - overhead_sys: Overhead percentage of sample running in system mode + - overhead_us: Overhead percentage of sample running in user mode + - overhead_guest_sys: Overhead percentage of sample running in system mode + on guest machine + - overhead_guest_us: Overhead percentage of sample running in user mode on + guest machine + - sample: Number of sample + - period: Raw number of event count of sample By default, comm, dso and symbol keys are used. (i.e. --sort comm,dso,symbol)
tools/perf/Documentation/perf-top.txt +3 -2
@@ -113,7 +113,8 @@ Default is to monitor all CPUS. -s:: --sort:: Sort by key(s): pid, comm, dso, symbol, parent, srcline, weight, - local_weight, abort, in_tx, transaction + local_weight, abort, in_tx, transaction, overhead, sample, period. + Please see description of --sort in the perf-report man page. -n:: --show-nr-samples::
@@ -212,4 +213,4 @@ Pressing any unmapped key displays a menu, and prompts for input. SEE ALSO -------- -linkperf:perf-stat[1], linkperf:perf-list[1] +linkperf:perf-stat[1], linkperf:perf-list[1], linkperf:perf-report[1]
tools/perf/builtin-diff.c +2 -1
@@ -741,7 +741,8 @@ static const struct option options[] = {OPT_STRING ('S' ,"symbols" , &symbol_conf.sym_list_str,"symbol[,symbol...]" ,"only consider these symbols" ),OPT_STRING ('s' ,"sort" , &sort_order,"key[,key2...]" , -"sort by key(s): pid, comm, dso, symbol, parent" ), +"sort by key(s): pid, comm, dso, symbol, parent, cpu, srcline, ..." +" Please refer the man page for the complete list." ),OPT_STRING ('t' ,"field-separator" , &symbol_conf.field_sep,"separator" ,"separator for columns, no spaces will be added between " "columns '.' is reserved."),
tools/perf/builtin-report.c +2 -4
@@ -699,10 +699,8 @@ int cmd_report(int argc, const char **argv, const char *prefix __maybe_unused)OPT_BOOLEAN (0 ,"header-only" , &report.header_only,"Show only data header." ),OPT_STRING ('s' ,"sort" , &sort_order,"key[,key2...]" , -"sort by key(s): pid, comm, dso, symbol, parent, cpu, srcline," -" dso_to, dso_from, symbol_to, symbol_from, mispredict," -" weight, local_weight, mem, symbol_daddr, dso_daddr, tlb, " -"snoop, locked, abort, in_tx, transaction" ), +"sort by key(s): pid, comm, dso, symbol, parent, cpu, srcline, ..." +" Please refer the man page for the complete list." ),OPT_BOOLEAN (0 ,"showcpuutilization" , &symbol_conf.show_cpu_utilization,"Show sample percentage for different cpu modes" ), OPT_STRING('p', "parent", &parent_pattern, "regex",
tools/perf/builtin-top.c +2 -2
@@ -1083,8 +1083,8 @@ int cmd_top(int argc, const char **argv, const char *prefix __maybe_unused)OPT_INCR ('v' ,"verbose" , &verbose,"be more verbose (show counter open errors, etc)" ),OPT_STRING ('s' ,"sort" , &sort_order,"key[,key2...]" , -"sort by key(s): pid, comm, dso, symbol, parent, weight, local_weight," -" abort, in_tx, transaction" ), +"sort by key(s): pid, comm, dso, symbol, parent, cpu, srcline, ..." +" Please refer the man page for the complete list." ),OPT_BOOLEAN ('n' ,"show-nr-samples" , &symbol_conf.show_nr_samples,"Show a column with the number of samples" ), OPT_CALLBACK_NOOPT('g', NULL, &top.record_opts,
tools/perf/ui/hist.c +7 -2
@@ -346,8 +346,13 @@ void perf_hpp__init(void)int i;for (i =0 ; i <PERF_HPP__MAX_INDEX ; i++) { -INIT_LIST_HEAD (&perf_hpp__format[i].list); -INIT_LIST_HEAD (&perf_hpp__format[i].sort_list); +struct perf_hpp_fmt *fmt = &perf_hpp__format[i]; + +INIT_LIST_HEAD (&fmt->list); + +/* sort_list may be linked by setup_sorting() */ +if (fmt->sort_list.next ==NULL ) +INIT_LIST_HEAD (&fmt->sort_list); }perf_hpp__column_enable (PERF_HPP__OVERHEAD );
tools/perf/util/sort.c +39 -0
@@ -1028,6 +1028,26 @@ static struct sort_dimension memory_sort_dimensions[] = {#undef DIM +struct hpp_dimension { +const char *name; +struct perf_hpp_fmt *fmt; +int taken; +}; + +#define DIM (d, n) { .name = n, .fmt = &perf_hpp__format[d], } + +static struct hpp_dimension hpp_sort_dimensions[] = { +DIM (PERF_HPP__OVERHEAD ,"overhead" ), +DIM (PERF_HPP__OVERHEAD_SYS ,"overhead_sys" ), +DIM (PERF_HPP__OVERHEAD_US ,"overhead_us" ), +DIM (PERF_HPP__OVERHEAD_GUEST_SYS ,"overhead_guest_sys" ), +DIM (PERF_HPP__OVERHEAD_GUEST_US ,"overhead_guest_us" ), +DIM (PERF_HPP__SAMPLES ,"sample" ), +DIM (PERF_HPP__PERIOD ,"period" ), +}; + +#undef DIM +struct hpp_sort_entry {struct perf_hpp_fmt hpp;struct sort_entry *se;
@@ -1115,6 +1135,16 @@ static int __sort_dimension__add(struct sort_dimension *sd, enum sort_type idx)return 0 ; } +static int __hpp_dimension__add (struct hpp_dimension *hd) +{ +if (!hd->taken) { + hd->taken =1 ; + +perf_hpp__register_sort_field (hd->fmt); + } +return 0 ; +} +int sort_dimension__add (const char *tok) {unsigned int i;
@@ -1144,6 +1174,15 @@ int sort_dimension__add(const char *tok)return __sort_dimension__add (sd, i); } +for (i =0 ; i <ARRAY_SIZE (hpp_sort_dimensions); i++) { +struct hpp_dimension *hd = &hpp_sort_dimensions[i]; + +if (strncasecmp (tok, hd->name,strlen (tok))) +continue ; + +return __hpp_dimension__add (hd); + } +for (i =0 ; i <ARRAY_SIZE (bstack_sort_dimensions); i++) {struct sort_dimension *sd = &bstack_sort_dimensions[i];
Signature · 1 line
1.9.2
tip-bot for Namhyung Kim
merge bot[tip:perf/core] perf tools: Allow hpp fields to be sort keys
perf tools: Allow hpp fields to be sort keys
Commit-ID: a2ce067e55e328f1a6fe3dddf77a173381ffdfe1 Gitweb: http://git.kernel.org/tip/a2ce067e55e328f1a6fe3dddf77a173381ffdfe1 Author: Namhyung Kim <[email protected]> AuthorDate: Tue, 4 Mar 2014 09:06:42 +0900 Committer: Jiri Olsa <[email protected]> CommitDate: Wed, 21 May 2014 11:45:34 +0200
perf tools: Allow hpp fields to be sort keys
Add overhead{,_sys,_us,_guest_sys,_guest_us}, sample and period sort keys so that they can be selected with --sort/-s option.
$ perf report -s period,comm --stdio
...
# Overhead Period Command
# ........ ............ ...............
#
47.06% 152 swapper
13.93% 45 qemu-system-arm
12.38% 40 synergys
3.72% 12 firefox
2.48% 8 xchat--- tools/perf/Documentation/perf-diff.txt | 5 ++-- tools/perf/Documentation/perf-report.txt | 9 ++++++++ tools/perf/Documentation/perf-top.txt | 5 ++-- tools/perf/builtin-diff.c | 3 ++- tools/perf/builtin-report.c | 6 ++--- tools/perf/builtin-top.c | 4 ++-- tools/perf/ui/hist.c | 9 ++++++-- tools/perf/util/sort.c | 39 ++++++++++++++++++++++++++++++++ 8 files changed, 67 insertions(+), 13 deletions(-)
tools/perf/Documentation/perf-diff.txt +3 -2
@@ -50,7 +50,8 @@ OPTIONS -s:: --sort=:: - Sort by key(s): pid, comm, dso, symbol. + Sort by key(s): pid, comm, dso, symbol, cpu, parent, srcline. + Please see description of --sort in the perf-report man page. -t:: --field-separator=::
@@ -202,4 +203,4 @@ If specified the 'Weighted diff' column is displayed with value 'd' computed as: SEE ALSO -------- -linkperf:perf-record[1] +linkperf:perf-record[1], linkperf:perf-report[1]
tools/perf/Documentation/perf-report.txt +9 -0
@@ -79,6 +79,15 @@ OPTIONS abort cost. This is the global weight. - local_weight: Local weight version of the weight above. - transaction: Transaction abort flags. + - overhead: Overhead percentage of sample + - overhead_sys: Overhead percentage of sample running in system mode + - overhead_us: Overhead percentage of sample running in user mode + - overhead_guest_sys: Overhead percentage of sample running in system mode + on guest machine + - overhead_guest_us: Overhead percentage of sample running in user mode on + guest machine + - sample: Number of sample + - period: Raw number of event count of sample By default, comm, dso and symbol keys are used. (i.e. --sort comm,dso,symbol)
tools/perf/Documentation/perf-top.txt +3 -2
@@ -113,7 +113,8 @@ Default is to monitor all CPUS. -s:: --sort:: Sort by key(s): pid, comm, dso, symbol, parent, srcline, weight, - local_weight, abort, in_tx, transaction + local_weight, abort, in_tx, transaction, overhead, sample, period. + Please see description of --sort in the perf-report man page. -n:: --show-nr-samples::
@@ -212,4 +213,4 @@ Pressing any unmapped key displays a menu, and prompts for input. SEE ALSO -------- -linkperf:perf-stat[1], linkperf:perf-list[1] +linkperf:perf-stat[1], linkperf:perf-list[1], linkperf:perf-report[1]
tools/perf/builtin-diff.c +2 -1
@@ -741,7 +741,8 @@ static const struct option options[] = {OPT_STRING ('S' ,"symbols" , &symbol_conf.sym_list_str,"symbol[,symbol...]" ,"only consider these symbols" ),OPT_STRING ('s' ,"sort" , &sort_order,"key[,key2...]" , -"sort by key(s): pid, comm, dso, symbol, parent" ), +"sort by key(s): pid, comm, dso, symbol, parent, cpu, srcline, ..." +" Please refer the man page for the complete list." ),OPT_STRING ('t' ,"field-separator" , &symbol_conf.field_sep,"separator" ,"separator for columns, no spaces will be added between " "columns '.' is reserved."),
tools/perf/builtin-report.c +2 -4
@@ -699,10 +699,8 @@ int cmd_report(int argc, const char **argv, const char *prefix __maybe_unused)OPT_BOOLEAN (0 ,"header-only" , &report.header_only,"Show only data header." ),OPT_STRING ('s' ,"sort" , &sort_order,"key[,key2...]" , -"sort by key(s): pid, comm, dso, symbol, parent, cpu, srcline," -" dso_to, dso_from, symbol_to, symbol_from, mispredict," -" weight, local_weight, mem, symbol_daddr, dso_daddr, tlb, " -"snoop, locked, abort, in_tx, transaction" ), +"sort by key(s): pid, comm, dso, symbol, parent, cpu, srcline, ..." +" Please refer the man page for the complete list." ),OPT_BOOLEAN (0 ,"showcpuutilization" , &symbol_conf.show_cpu_utilization,"Show sample percentage for different cpu modes" ), OPT_STRING('p', "parent", &parent_pattern, "regex",
tools/perf/builtin-top.c +2 -2
@@ -1083,8 +1083,8 @@ int cmd_top(int argc, const char **argv, const char *prefix __maybe_unused)OPT_INCR ('v' ,"verbose" , &verbose,"be more verbose (show counter open errors, etc)" ),OPT_STRING ('s' ,"sort" , &sort_order,"key[,key2...]" , -"sort by key(s): pid, comm, dso, symbol, parent, weight, local_weight," -" abort, in_tx, transaction" ), +"sort by key(s): pid, comm, dso, symbol, parent, cpu, srcline, ..." +" Please refer the man page for the complete list." ),OPT_BOOLEAN ('n' ,"show-nr-samples" , &symbol_conf.show_nr_samples,"Show a column with the number of samples" ), OPT_CALLBACK_NOOPT('g', NULL, &top.record_opts,
tools/perf/ui/hist.c +7 -2
@@ -346,8 +346,13 @@ void perf_hpp__init(void)int i;for (i =0 ; i <PERF_HPP__MAX_INDEX ; i++) { -INIT_LIST_HEAD (&perf_hpp__format[i].list); -INIT_LIST_HEAD (&perf_hpp__format[i].sort_list); +struct perf_hpp_fmt *fmt = &perf_hpp__format[i]; + +INIT_LIST_HEAD (&fmt->list); + +/* sort_list may be linked by setup_sorting() */ +if (fmt->sort_list.next ==NULL ) +INIT_LIST_HEAD (&fmt->sort_list); }perf_hpp__column_enable (PERF_HPP__OVERHEAD );
tools/perf/util/sort.c +39 -0
@@ -1028,6 +1028,26 @@ static struct sort_dimension memory_sort_dimensions[] = {#undef DIM +struct hpp_dimension { +const char *name; +struct perf_hpp_fmt *fmt; +int taken; +}; + +#define DIM (d, n) { .name = n, .fmt = &perf_hpp__format[d], } + +static struct hpp_dimension hpp_sort_dimensions[] = { +DIM (PERF_HPP__OVERHEAD ,"overhead" ), +DIM (PERF_HPP__OVERHEAD_SYS ,"overhead_sys" ), +DIM (PERF_HPP__OVERHEAD_US ,"overhead_us" ), +DIM (PERF_HPP__OVERHEAD_GUEST_SYS ,"overhead_guest_sys" ), +DIM (PERF_HPP__OVERHEAD_GUEST_US ,"overhead_guest_us" ), +DIM (PERF_HPP__SAMPLES ,"sample" ), +DIM (PERF_HPP__PERIOD ,"period" ), +}; + +#undef DIM +struct hpp_sort_entry {struct perf_hpp_fmt hpp;struct sort_entry *se;
@@ -1115,6 +1135,16 @@ static int __sort_dimension__add(struct sort_dimension *sd, enum sort_type idx)return 0 ; } +static int __hpp_dimension__add (struct hpp_dimension *hd) +{ +if (!hd->taken) { + hd->taken =1 ; + +perf_hpp__register_sort_field (hd->fmt); + } +return 0 ; +} +int sort_dimension__add (const char *tok) {unsigned int i;
@@ -1144,6 +1174,15 @@ int sort_dimension__add(const char *tok)return __sort_dimension__add (sd, i); } +for (i =0 ; i <ARRAY_SIZE (hpp_sort_dimensions); i++) { +struct hpp_dimension *hd = &hpp_sort_dimensions[i]; + +if (strncasecmp (tok, hd->name,strlen (tok))) +continue ; + +return __hpp_dimension__add (hd); + } +for (i =0 ; i <ARRAY_SIZE (bstack_sort_dimensions); i++) {struct sort_dimension *sd = &bstack_sort_dimensions[i];
Namhyung Kim
maintainerPATCH 9/20 perf tools: Consolidate management of default sort orders
In reply to Namhyung KimThe perf uses different default sort orders for different use-cases, and this was scattered throughout the code. Add get_default_sort_ order() function to handle this and change initial value of sort_order to NULL to distinguish it from user-given one.
--- tools/perf/builtin-diff.c | 4 ++-- tools/perf/builtin-report.c | 18 ------------------ tools/perf/builtin-top.c | 3 +-- tools/perf/util/sort.c | 28 ++++++++++++++++++++++++++-- tools/perf/util/sort.h | 2 ++ 5 files changed, 31 insertions(+), 24 deletions(-)
tools/perf/builtin-diff.c +2 -2
@@ -60,7 +60,6 @@ static int data__files_cnt;#define data__for_each_file (i, d) data__for_each_file_start(i, d, 0)#define data__for_each_file_new (i, d) data__for_each_file_start(i, d, 1) -static char diff__default_sort_order[] ="dso,symbol" ;static bool force;static bool show_period;static bool show_formula;
@@ -1142,7 +1141,6 @@ int cmd_diff(int argc, const char **argv, const char *prefix __maybe_unused) {perf_config (perf_default_config,NULL ); - sort_order = diff__default_sort_order; argc =parse_options (argc, argv, options, diff_usage,0 );if (symbol__init () <0 )
@@ -1153,6 +1151,8 @@ int cmd_diff(int argc, const char **argv, const char *prefix __maybe_unused)ui_init (); + sort__mode =SORT_MODE__DIFF ; +if (setup_sorting () <0 )usage_with_options (diff_usage, options);
tools/perf/builtin-report.c +0 -18
@@ -805,30 +805,12 @@ repeat:if (branch_mode ==-1 && has_br_stack) sort__mode =SORT_MODE__BRANCH ; -/* sort__mode could be NORMAL if --no-branch-stack */ -if (sort__mode ==SORT_MODE__BRANCH ) { -/* -* if no sort_order is provided, then specify -* branch-mode specific order -*/ -if (sort_order == default_sort_order) - sort_order ="comm,dso_from,symbol_from," -"dso_to,symbol_to" ; - - }if (report.mem_mode) {if (sort__mode ==SORT_MODE__BRANCH ) {pr_err ("branch and mem mode incompatible\n" ); goto error; } sort__mode =SORT_MODE__MEMORY ; - -/* -* if no sort_order is provided, then specify -* branch-mode specific order -*/ -if (sort_order == default_sort_order) - sort_order ="local_weight,mem,sym,dso,symbol_daddr,dso_daddr,snoop,tlb,locked" ; }if (setup_sorting () <0 ) {
tools/perf/builtin-top.c +1 -2
@@ -1137,8 +1137,7 @@ int cmd_top(int argc, const char **argv, const char *prefix __maybe_unused)if (argc)usage_with_options (top_usage, options); -if (sort_order == default_sort_order) - sort_order ="dso,symbol" ; + sort__mode =SORT_MODE__TOP ;if (setup_sorting () <0 ) {parse_options_usage (top_usage, options,"s" ,1 );
tools/perf/util/sort.c +26 -2
@@ -8,7 +8,11 @@ regex_t parent_regex;const char default_parent_pattern[] ="^sys_|^do_page_fault" ;const char *parent_pattern = default_parent_pattern;const char default_sort_order[] ="comm,dso,symbol" ; -const char *sort_order = default_sort_order; +const char default_branch_sort_order[] ="comm,dso_from,symbol_from,dso_to,symbol_to" ; +const char default_mem_sort_order[] ="local_weight,mem,sym,dso,symbol_daddr,dso_daddr,snoop,tlb,locked" ; +const char default_top_sort_order[] ="dso,symbol" ; +const char default_diff_sort_order[] ="dso,symbol" ; +const char *sort_order;regex_t ignore_callees_regex;int have_ignore_callees =0 ;int sort__need_collapse =0 ;
@@ -1218,11 +1222,31 @@ int sort_dimension__add(const char *tok)return -ESRCH ; } +static const char *get_default_sort_order (void ) +{ +const char *default_sort_orders[] = { + default_sort_order, + default_branch_sort_order, + default_mem_sort_order, + default_top_sort_order, + default_diff_sort_order, + }; + +BUG_ON (sort__mode >=ARRAY_SIZE (default_sort_orders)); + +return default_sort_orders[sort__mode]; +} +int setup_sorting (void ) { -char *tmp, *tok, *str =strdup (sort_order); +char *tmp, *tok, *str; +const char *sort_keys = sort_order;int ret =0 ; +if (sort_keys ==NULL ) + sort_keys =get_default_sort_order (); + + str =strdup (sort_keys);if (str ==NULL ) {error ("Not enough memory to setup sort keys" );return -ENOMEM ;
tools/perf/util/sort.h +2 -0
@@ -133,6 +133,8 @@ enum sort_mode {SORT_MODE__NORMAL ,SORT_MODE__BRANCH ,SORT_MODE__MEMORY , +SORT_MODE__TOP , + SORT_MODE__DIFF, }; enum sort_type {
Signature · 1 line
1.9.2
tip-bot for Namhyung Kim
merge bot[tip:perf/core] perf tools: Consolidate management of default sort orders
perf tools: Consolidate management of default sort orders
Commit-ID: 512ae1bd6acb811c72e44e2540099eccd31f773d Gitweb: http://git.kernel.org/tip/512ae1bd6acb811c72e44e2540099eccd31f773d Author: Namhyung Kim <[email protected]> AuthorDate: Tue, 18 Mar 2014 11:31:39 +0900 Committer: Jiri Olsa <[email protected]> CommitDate: Wed, 21 May 2014 11:45:35 +0200
perf tools: Consolidate management of default sort orders
The perf uses different default sort orders for different use-cases, and this was scattered throughout the code. Add get_default_sort_ order() function to handle this and change initial value of sort_order to NULL to distinguish it from user-given one.
--- tools/perf/builtin-diff.c | 4 ++-- tools/perf/builtin-report.c | 18 ------------------ tools/perf/builtin-top.c | 3 +-- tools/perf/util/sort.c | 28 ++++++++++++++++++++++++++-- tools/perf/util/sort.h | 2 ++ 5 files changed, 31 insertions(+), 24 deletions(-)
tools/perf/builtin-diff.c +2 -2
@@ -60,7 +60,6 @@ static int data__files_cnt;#define data__for_each_file (i, d) data__for_each_file_start(i, d, 0)#define data__for_each_file_new (i, d) data__for_each_file_start(i, d, 1) -static char diff__default_sort_order[] ="dso,symbol" ;static bool force;static bool show_period;static bool show_formula;
@@ -1142,7 +1141,6 @@ int cmd_diff(int argc, const char **argv, const char *prefix __maybe_unused) {perf_config (perf_default_config,NULL ); - sort_order = diff__default_sort_order; argc =parse_options (argc, argv, options, diff_usage,0 );if (symbol__init () <0 )
@@ -1153,6 +1151,8 @@ int cmd_diff(int argc, const char **argv, const char *prefix __maybe_unused)ui_init (); + sort__mode =SORT_MODE__DIFF ; +if (setup_sorting () <0 )usage_with_options (diff_usage, options);
tools/perf/builtin-report.c +0 -18
@@ -805,30 +805,12 @@ repeat:if (branch_mode ==-1 && has_br_stack) sort__mode =SORT_MODE__BRANCH ; -/* sort__mode could be NORMAL if --no-branch-stack */ -if (sort__mode ==SORT_MODE__BRANCH ) { -/* -* if no sort_order is provided, then specify -* branch-mode specific order -*/ -if (sort_order == default_sort_order) - sort_order ="comm,dso_from,symbol_from," -"dso_to,symbol_to" ; - - }if (report.mem_mode) {if (sort__mode ==SORT_MODE__BRANCH ) {pr_err ("branch and mem mode incompatible\n" ); goto error; } sort__mode =SORT_MODE__MEMORY ; - -/* -* if no sort_order is provided, then specify -* branch-mode specific order -*/ -if (sort_order == default_sort_order) - sort_order ="local_weight,mem,sym,dso,symbol_daddr,dso_daddr,snoop,tlb,locked" ; }if (setup_sorting () <0 ) {
tools/perf/builtin-top.c +1 -2
@@ -1137,8 +1137,7 @@ int cmd_top(int argc, const char **argv, const char *prefix __maybe_unused)if (argc)usage_with_options (top_usage, options); -if (sort_order == default_sort_order) - sort_order ="dso,symbol" ; + sort__mode =SORT_MODE__TOP ;if (setup_sorting () <0 ) {parse_options_usage (top_usage, options,"s" ,1 );
tools/perf/util/sort.c +26 -2
@@ -8,7 +8,11 @@ regex_t parent_regex;const char default_parent_pattern[] ="^sys_|^do_page_fault" ;const char *parent_pattern = default_parent_pattern;const char default_sort_order[] ="comm,dso,symbol" ; -const char *sort_order = default_sort_order; +const char default_branch_sort_order[] ="comm,dso_from,symbol_from,dso_to,symbol_to" ; +const char default_mem_sort_order[] ="local_weight,mem,sym,dso,symbol_daddr,dso_daddr,snoop,tlb,locked" ; +const char default_top_sort_order[] ="dso,symbol" ; +const char default_diff_sort_order[] ="dso,symbol" ; +const char *sort_order;regex_t ignore_callees_regex;int have_ignore_callees =0 ;int sort__need_collapse =0 ;
@@ -1218,11 +1222,31 @@ int sort_dimension__add(const char *tok)return -ESRCH ; } +static const char *get_default_sort_order (void ) +{ +const char *default_sort_orders[] = { + default_sort_order, + default_branch_sort_order, + default_mem_sort_order, + default_top_sort_order, + default_diff_sort_order, + }; + +BUG_ON (sort__mode >=ARRAY_SIZE (default_sort_orders)); + +return default_sort_orders[sort__mode]; +} +int setup_sorting (void ) { -char *tmp, *tok, *str =strdup (sort_order); +char *tmp, *tok, *str; +const char *sort_keys = sort_order;int ret =0 ; +if (sort_keys ==NULL ) + sort_keys =get_default_sort_order (); + + str =strdup (sort_keys);if (str ==NULL ) {error ("Not enough memory to setup sort keys" );return -ENOMEM ;
tools/perf/util/sort.h +2 -0
@@ -133,6 +133,8 @@ enum sort_mode {SORT_MODE__NORMAL ,SORT_MODE__BRANCH ,SORT_MODE__MEMORY , +SORT_MODE__TOP , + SORT_MODE__DIFF, }; enum sort_type {
Namhyung Kim
maintainerPATCH 10/20 perf tools: Call perf_hpp__init() before setting up GUI browsers
In reply to Namhyung KimSo that it can be set properly prior to set up output fields. That makes easy to handle/warn errors during the setup since it doesn't need to be bothered with the GUI.
--- tools/perf/builtin-report.c | 6 +++--- tools/perf/builtin-top.c | 2 ++ tools/perf/ui/browsers/hists.c | 2 -- tools/perf/ui/gtk/hists.c | 2 -- tools/perf/ui/setup.c | 2 -- 5 files changed, 5 insertions(+), 9 deletions(-)
tools/perf/builtin-report.c +3 -3
@@ -823,16 +823,16 @@ repeat: goto error; } +perf_hpp__init (); +/* Force tty output for header output. */ if (report.header || report.header_only) use_browser =0 ;if (strcmp (input_name,"-" ) !=0 )setup_browser (true); -else { +else use_browser =0 ; -perf_hpp__init (); - }if (report.header || report.header_only) { perf_session__fprintf_info(session, stdout,
tools/perf/builtin-top.c +2 -0
@@ -1147,6 +1147,8 @@ int cmd_top(int argc, const char **argv, const char *prefix __maybe_unused)/* display thread wants entries to be collapsed in a different tree */ sort__need_collapse =1 ; +perf_hpp__init (); +if (top.use_stdio) use_browser =0 ;else if (top.use_tui)
tools/perf/ui/browsers/hists.c +0 -2
@@ -661,8 +661,6 @@ __HPP_COLOR_PERCENT_FN(overhead_guest_us, period_guest_us)void hist_browser__init_hpp (void ) { -perf_hpp__init (); - perf_hpp__format[PERF_HPP__OVERHEAD ].color = hist_browser__hpp_color_overhead; perf_hpp__format[PERF_HPP__OVERHEAD_SYS].color =
tools/perf/ui/gtk/hists.c +0 -2
@@ -58,8 +58,6 @@ __HPP_COLOR_PERCENT_FN(overhead_guest_us, period_guest_us)void perf_gtk__init_hpp (void ) { -perf_hpp__init (); - perf_hpp__format[PERF_HPP__OVERHEAD ].color = perf_gtk__hpp_color_overhead; perf_hpp__format[PERF_HPP__OVERHEAD_SYS].color =
tools/perf/ui/setup.c +0 -2
@@ -86,8 +86,6 @@ void setup_browser(bool fallback_to_pager) use_browser =0 ;if (fallback_to_pager)setup_pager (); - -perf_hpp__init ();break ; } }
Signature · 1 line
1.9.2
tip-bot for Namhyung Kim
merge bot[tip:perf/core] perf tools: Call perf_hpp__init() before setting up GUI browsers
perf tools: Call perf_hpp__init() before setting up GUI browsers
Commit-ID: 22af969e8cfc6ea46d3e1a774a16d7e19b8cf4db Gitweb: http://git.kernel.org/tip/22af969e8cfc6ea46d3e1a774a16d7e19b8cf4db Author: Namhyung Kim <[email protected]> AuthorDate: Wed, 16 Apr 2014 11:04:51 +0900 Committer: Jiri Olsa <[email protected]> CommitDate: Wed, 21 May 2014 11:45:35 +0200
perf tools: Call perf_hpp__init() before setting up GUI browsers
So that it can be set properly prior to set up output fields. That makes easy to handle/warn errors during the setup since it doesn't need to be bothered with the GUI.
--- tools/perf/builtin-report.c | 6 +++--- tools/perf/builtin-top.c | 2 ++ tools/perf/ui/browsers/hists.c | 2 -- tools/perf/ui/gtk/hists.c | 2 -- tools/perf/ui/setup.c | 2 -- 5 files changed, 5 insertions(+), 9 deletions(-)
tools/perf/builtin-report.c +3 -3
@@ -823,16 +823,16 @@ repeat: goto error; } +perf_hpp__init (); +/* Force tty output for header output. */ if (report.header || report.header_only) use_browser =0 ;if (strcmp (input_name,"-" ) !=0 )setup_browser (true); -else { +else use_browser =0 ; -perf_hpp__init (); - }if (report.header || report.header_only) { perf_session__fprintf_info(session, stdout,
tools/perf/builtin-top.c +2 -0
@@ -1147,6 +1147,8 @@ int cmd_top(int argc, const char **argv, const char *prefix __maybe_unused)/* display thread wants entries to be collapsed in a different tree */ sort__need_collapse =1 ; +perf_hpp__init (); +if (top.use_stdio) use_browser =0 ;else if (top.use_tui)
tools/perf/ui/browsers/hists.c +0 -2
@@ -661,8 +661,6 @@ __HPP_COLOR_PERCENT_FN(overhead_guest_us, period_guest_us)void hist_browser__init_hpp (void ) { -perf_hpp__init (); - perf_hpp__format[PERF_HPP__OVERHEAD ].color = hist_browser__hpp_color_overhead; perf_hpp__format[PERF_HPP__OVERHEAD_SYS].color =
tools/perf/ui/gtk/hists.c +0 -2
@@ -58,8 +58,6 @@ __HPP_COLOR_PERCENT_FN(overhead_guest_us, period_guest_us)void perf_gtk__init_hpp (void ) { -perf_hpp__init (); - perf_hpp__format[PERF_HPP__OVERHEAD ].color = perf_gtk__hpp_color_overhead; perf_hpp__format[PERF_HPP__OVERHEAD_SYS].color =
tools/perf/ui/setup.c +0 -2
@@ -86,8 +86,6 @@ void setup_browser(bool fallback_to_pager) use_browser =0 ;if (fallback_to_pager)setup_pager (); - -perf_hpp__init ();break ; } }
Namhyung Kim
maintainerPATCH 11/20 perf report: Add -F option to specify output fields
In reply to Namhyung KimThe -F/--fields option is to allow user setup output field in any order. It can recieve any sort keys and following (hpp) fields:
overhead, overhead_sys, overhead_us, sample and period
If guest profiling is enabled, overhead_guest_{sys,us} will be available too.
The output fields also affect sort order unless you give -s/--sort option. And any keys specified on -s option, will also be added to the output field list automatically.
$ perf report -F sym,sample,overhead
...
# Symbol Samples Overhead
# .......................... ............ ........
#
[.] __cxa_atexit 2 2.50%
[.] __libc_csu_init 4 5.00%
[.] __new_exitfn 3 3.75%
[.] _dl_check_map_versions 1 1.25%
[.] _dl_name_match_p 4 5.00%
[.] _dl_setup_hash 1 1.25%
[.] _dl_sysdep_start 1 1.25%
[.] _init 5 6.25%
[.] _setjmp 6 7.50%
[.] a 8 10.00%
[.] b 8 10.00%
[.] brk 1 1.25%
[.] c 8 10.00%Note that, the example output above is captured after applying next patch which fixes sort/comparing behavior.
--- tools/perf/Documentation/perf-report.txt | 10 ++ tools/perf/builtin-report.c | 15 ++- tools/perf/ui/hist.c | 59 ++++++++- tools/perf/util/hist.h | 4 + tools/perf/util/sort.c | 209 ++++++++++++++++++++++++++++++- tools/perf/util/sort.h | 2 + 6 files changed, 282 insertions(+), 17 deletions(-)
tools/perf/Documentation/perf-report.txt +10 -0
@@ -107,6 +107,16 @@ OPTIONS And default sort keys are changed to comm, dso_from, symbol_from, dso_to and symbol_to, see '--branch-stack'. +-F:: +--fields=:: + Specify output field - multiple keys can be specified in CSV format. + Following fields are available: + overhead, overhead_sys, overhead_us, sample and period. + Also it can contain any sort key(s). + + By default, every sort keys not specified in -F will be appended + automatically. + -p:: --parent=<regex>:: A regex filter to identify parent. The parent is a caller of this
tools/perf/builtin-report.c +7 -8
@@ -701,6 +701,8 @@ int cmd_report(int argc, const char **argv, const char *prefix __maybe_unused)OPT_STRING ('s' ,"sort" , &sort_order,"key[,key2...]" ,"sort by key(s): pid, comm, dso, symbol, parent, cpu, srcline, ..." " Please refer the man page for the complete list." ), +OPT_STRING ('F' ,"fields" , &field_order,"key[,keys...]" , +"output field(s): overhead, period, sample plus all of sort keys" ),OPT_BOOLEAN (0 ,"showcpuutilization" , &symbol_conf.show_cpu_utilization,"Show sample percentage for different cpu modes" ), OPT_STRING('p', "parent", &parent_pattern, "regex",
@@ -814,17 +816,14 @@ repeat: }if (setup_sorting () <0 ) { -parse_options_usage (report_usage, options,"s" ,1 ); +if (sort_order) +parse_options_usage (report_usage, options,"s" ,1 ); +if (field_order) +parse_options_usage (sort_order ?NULL : report_usage, + options,"F" ,1 ); goto error; } -if (parent_pattern != default_parent_pattern) { -if (sort_dimension__add ("parent" ) <0 ) - goto error; - } - -perf_hpp__init (); -/* Force tty output for header output. */ if (report.header || report.header_only) use_browser =0 ;
tools/perf/ui/hist.c +55 -4
77 lines not on this page · raw message
tools/perf/util/hist.h +4 -0
@@ -197,6 +197,10 @@ void perf_hpp__column_register(struct perf_hpp_fmt *format);void perf_hpp__column_enable (unsigned col);void perf_hpp__register_sort_field (struct perf_hpp_fmt *format);void perf_hpp__setup_output_field (void ); +void perf_hpp__append_sort_keys (void ); + +bool perf_hpp__is_sort_entry (struct perf_hpp_fmt *format); +bool perf_hpp__same_sort_entry (struct perf_hpp_fmt *a,struct perf_hpp_fmt *b);typedef u64 (*hpp_field_fn )(struct hist_entry *he);typedef int (*hpp_callback_fn )(struct perf_hpp *hpp,bool front);
tools/perf/util/sort.c +204 -5
269 lines not on this page · raw message
tools/perf/util/sort.h +2 -0
@@ -25,6 +25,7 @@extern regex_t parent_regex;extern const char *sort_order; +extern const char *field_order;extern const char default_parent_pattern[];extern const char *parent_pattern;extern const char default_sort_order[];
@@ -191,6 +192,7 @@ extern struct sort_entry sort_thread;extern struct list_head hist_entry__sort_list;int setup_sorting (void ); +int setup_output_field (void );extern int sort_dimension__add (const char *);void sort__setup_elide (FILE *fp);
Signature · 1 line
1.9.2
tip-bot for Namhyung Kim
merge bot[tip:perf/core] perf report: Add -F option to specify output fields
perf report: Add -F option to specify output fields
Commit-ID: a7d945bc91602f916d2d0c794c179d9a784859e7 Gitweb: http://git.kernel.org/tip/a7d945bc91602f916d2d0c794c179d9a784859e7 Author: Namhyung Kim <[email protected]> AuthorDate: Tue, 4 Mar 2014 10:46:34 +0900 Committer: Jiri Olsa <[email protected]> CommitDate: Wed, 21 May 2014 11:45:35 +0200
perf report: Add -F option to specify output fields
The -F/--fields option is to allow user setup output field in any order. It can receive any sort keys and following (hpp) fields:
overhead, overhead_sys, overhead_us, sample and period
If guest profiling is enabled, overhead_guest_{sys,us} will be available too.
The output fields also affect sort order unless you give -s/--sort option. And any keys specified on -s option, will also be added to the output field list automatically.
$ perf report -F sym,sample,overhead
...
# Symbol Samples Overhead
# .......................... ............ ........
#
[.] __cxa_atexit 2 2.50%
[.] __libc_csu_init 4 5.00%
[.] __new_exitfn 3 3.75%
[.] _dl_check_map_versions 1 1.25%
[.] _dl_name_match_p 4 5.00%
[.] _dl_setup_hash 1 1.25%
[.] _dl_sysdep_start 1 1.25%
[.] _init 5 6.25%
[.] _setjmp 6 7.50%
[.] a 8 10.00%
[.] b 8 10.00%
[.] brk 1 1.25%
[.] c 8 10.00%Note that, the example output above is captured after applying next patch which fixes sort/comparing behavior.
--- tools/perf/Documentation/perf-report.txt | 10 ++ tools/perf/builtin-report.c | 15 ++- tools/perf/ui/hist.c | 59 ++++++++- tools/perf/util/hist.h | 4 + tools/perf/util/sort.c | 209 ++++++++++++++++++++++++++++++- tools/perf/util/sort.h | 2 + 6 files changed, 282 insertions(+), 17 deletions(-)
tools/perf/Documentation/perf-report.txt +10 -0
@@ -107,6 +107,16 @@ OPTIONS And default sort keys are changed to comm, dso_from, symbol_from, dso_to and symbol_to, see '--branch-stack'. +-F:: +--fields=:: + Specify output field - multiple keys can be specified in CSV format. + Following fields are available: + overhead, overhead_sys, overhead_us, sample and period. + Also it can contain any sort key(s). + + By default, every sort keys not specified in -F will be appended + automatically. + -p:: --parent=<regex>:: A regex filter to identify parent. The parent is a caller of this
tools/perf/builtin-report.c +7 -8
@@ -701,6 +701,8 @@ int cmd_report(int argc, const char **argv, const char *prefix __maybe_unused)OPT_STRING ('s' ,"sort" , &sort_order,"key[,key2...]" ,"sort by key(s): pid, comm, dso, symbol, parent, cpu, srcline, ..." " Please refer the man page for the complete list." ), +OPT_STRING ('F' ,"fields" , &field_order,"key[,keys...]" , +"output field(s): overhead, period, sample plus all of sort keys" ),OPT_BOOLEAN (0 ,"showcpuutilization" , &symbol_conf.show_cpu_utilization,"Show sample percentage for different cpu modes" ), OPT_STRING('p', "parent", &parent_pattern, "regex",
@@ -814,17 +816,14 @@ repeat: }if (setup_sorting () <0 ) { -parse_options_usage (report_usage, options,"s" ,1 ); +if (sort_order) +parse_options_usage (report_usage, options,"s" ,1 ); +if (field_order) +parse_options_usage (sort_order ?NULL : report_usage, + options,"F" ,1 ); goto error; } -if (parent_pattern != default_parent_pattern) { -if (sort_dimension__add ("parent" ) <0 ) - goto error; - } - -perf_hpp__init (); -/* Force tty output for header output. */ if (report.header || report.header_only) use_browser =0 ;
tools/perf/ui/hist.c +55 -4
77 lines not on this page · raw message
tools/perf/util/hist.h +4 -0
@@ -197,6 +197,10 @@ void perf_hpp__column_register(struct perf_hpp_fmt *format);void perf_hpp__column_enable (unsigned col);void perf_hpp__register_sort_field (struct perf_hpp_fmt *format);void perf_hpp__setup_output_field (void ); +void perf_hpp__append_sort_keys (void ); + +bool perf_hpp__is_sort_entry (struct perf_hpp_fmt *format); +bool perf_hpp__same_sort_entry (struct perf_hpp_fmt *a,struct perf_hpp_fmt *b);typedef u64 (*hpp_field_fn )(struct hist_entry *he);typedef int (*hpp_callback_fn )(struct perf_hpp *hpp,bool front);
tools/perf/util/sort.c +204 -5
269 lines not on this page · raw message
tools/perf/util/sort.h +2 -0
@@ -25,6 +25,7 @@extern regex_t parent_regex;extern const char *sort_order; +extern const char *field_order;extern const char default_parent_pattern[];extern const char *parent_pattern;extern const char default_sort_order[];
@@ -191,6 +192,7 @@ extern struct sort_entry sort_thread;extern struct list_head hist_entry__sort_list;int setup_sorting (void ); +int setup_output_field (void );extern int sort_dimension__add (const char *);void sort__setup_elide (FILE *fp);
Namhyung Kim
maintainerPATCH 12/20 perf tools: Add ->sort() member to struct sort_entry
In reply to Namhyung KimCurrently, what the sort_entry does is just identifying hist entries so that they can be grouped properly. However, with -F option support, it indeed needs to sort entries appropriately to be shown to users. So add ->sort() member to do it.
--- tools/perf/util/sort.c | 27 ++++++++++++++++++++++----- tools/perf/util/sort.h | 1 + 2 files changed, 23 insertions(+), 5 deletions(-)
tools/perf/util/sort.c +22 -5
@@ -99,6 +99,12 @@ sort__comm_collapse(struct hist_entry *left, struct hist_entry *right)return comm__str (right->comm) -comm__str (left->comm); } +static int64_t +sort__comm_sort (struct hist_entry *left,struct hist_entry *right) +{ +return strcmp (comm__str (right->comm),comm__str (left->comm)); +} +static int hist_entry__comm_snprintf (struct hist_entry *he,char *bf,size_t size,unsigned int width) {
@@ -109,6 +115,7 @@ struct sort_entry sort_comm = { .se_header = "Command", .se_cmp = sort__comm_cmp, .se_collapse = sort__comm_collapse, + .se_sort = sort__comm_sort, .se_snprintf = hist_entry__comm_snprintf, .se_width_idx = HISTC_COMM, };
@@ -122,7 +129,7 @@ static int64_t _sort__dso_cmp(struct map *map_l, struct map *map_r)const char *dso_name_l, *dso_name_r;if (!dso_l || !dso_r) -return cmp_null (dso_l, dso_r); +return cmp_null (dso_r, dso_l);if (verbose) { dso_name_l = dso_l->long_name;
@@ -138,7 +145,7 @@ static int64_t _sort__dso_cmp(struct map *map_l, struct map *map_r)static int64_t sort__dso_cmp (struct hist_entry *left,struct hist_entry *right) { -return _sort__dso_cmp (left->ms.map, right->ms.map); +return _sort__dso_cmp (right->ms.map, left->ms.map); } static int _hist_entry__dso_snprintf(struct map *map, char *bf,
@@ -210,6 +217,15 @@ sort__sym_cmp(struct hist_entry *left, struct hist_entry *right)return _sort__sym_cmp (left->ms.sym, right->ms.sym); } +static int64_t +sort__sym_sort (struct hist_entry *left,struct hist_entry *right) +{ +if (!left->ms.sym || !right->ms.sym) +return cmp_null (left->ms.sym, right->ms.sym); + +return strcmp (right->ms.sym->name, left->ms.sym->name); +} +static int _hist_entry__sym_snprintf (struct map *map,struct symbol *sym,u64 ip,char level,char *bf,size_t size,unsigned int width)
@@ -256,6 +272,7 @@ static int hist_entry__sym_snprintf(struct hist_entry *he, char *bf,struct sort_entry sort_sym = { .se_header ="Symbol" , .se_cmp = sort__sym_cmp, + .se_sort = sort__sym_sort, .se_snprintf = hist_entry__sym_snprintf, .se_width_idx =HISTC_SYMBOL , };
@@ -283,7 +300,7 @@ sort__srcline_cmp(struct hist_entry *left, struct hist_entry *right) map__rip_2objdump(map, right->ip)); } } -return strcmp (left->srcline, right->srcline); +return strcmp (right->srcline, left->srcline); } static int hist_entry__srcline_snprintf(struct hist_entry *he, char *bf,
@@ -311,7 +328,7 @@ sort__parent_cmp(struct hist_entry *left, struct hist_entry *right)if (!sym_l || !sym_r)return cmp_null (sym_l, sym_r); -return strcmp (sym_l->name, sym_r->name); +return strcmp (sym_r->name, sym_l->name); } static int hist_entry__parent_snprintf(struct hist_entry *he, char *bf,
@@ -1126,7 +1143,7 @@ __sort_dimension__alloc_hpp(struct sort_dimension *sd) hse->hpp.cmp = sd->entry->se_cmp; hse->hpp.collapse = sd->entry->se_collapse ? : sd->entry->se_cmp; - hse->hpp.sort = hse->hpp.collapse; + hse->hpp.sort = sd->entry->se_sort ? : hse->hpp.collapse;INIT_LIST_HEAD (&hse->hpp.list);INIT_LIST_HEAD (&hse->hpp.sort_list);
tools/perf/util/sort.h +1 -0
@@ -182,6 +182,7 @@ struct sort_entry {int64_t (*se_cmp)(struct hist_entry *,struct hist_entry *);int64_t (*se_collapse)(struct hist_entry *,struct hist_entry *); +int64_t (*se_sort)(struct hist_entry *,struct hist_entry *);int (*se_snprintf)(struct hist_entry *he,char *bf,size_t size,unsigned int width);u8 se_width_idx;
Signature · 1 line
1.9.2
tip-bot for Namhyung Kim
merge bot[tip:perf/core] perf tools: Add ->sort() member to struct sort_entry
perf tools: Add ->sort() member to struct sort_entry
Commit-ID: 202e7a6d16127323d03e912d7844aa0d614c315e Gitweb: http://git.kernel.org/tip/202e7a6d16127323d03e912d7844aa0d614c315e Author: Namhyung Kim <[email protected]> AuthorDate: Tue, 4 Mar 2014 11:01:41 +0900 Committer: Jiri Olsa <[email protected]> CommitDate: Wed, 21 May 2014 11:45:35 +0200
perf tools: Add ->sort() member to struct sort_entry
Currently, what the sort_entry does is just identifying hist entries so that they can be grouped properly. However, with -F option support, it indeed needs to sort entries appropriately to be shown to users. So add ->sort() member to do it.
--- tools/perf/util/sort.c | 27 ++++++++++++++++++++++----- tools/perf/util/sort.h | 1 + 2 files changed, 23 insertions(+), 5 deletions(-)
tools/perf/util/sort.c +22 -5
@@ -99,6 +99,12 @@ sort__comm_collapse(struct hist_entry *left, struct hist_entry *right)return comm__str (right->comm) -comm__str (left->comm); } +static int64_t +sort__comm_sort (struct hist_entry *left,struct hist_entry *right) +{ +return strcmp (comm__str (right->comm),comm__str (left->comm)); +} +static int hist_entry__comm_snprintf (struct hist_entry *he,char *bf,size_t size,unsigned int width) {
@@ -109,6 +115,7 @@ struct sort_entry sort_comm = { .se_header = "Command", .se_cmp = sort__comm_cmp, .se_collapse = sort__comm_collapse, + .se_sort = sort__comm_sort, .se_snprintf = hist_entry__comm_snprintf, .se_width_idx = HISTC_COMM, };
@@ -122,7 +129,7 @@ static int64_t _sort__dso_cmp(struct map *map_l, struct map *map_r)const char *dso_name_l, *dso_name_r;if (!dso_l || !dso_r) -return cmp_null (dso_l, dso_r); +return cmp_null (dso_r, dso_l);if (verbose) { dso_name_l = dso_l->long_name;
@@ -138,7 +145,7 @@ static int64_t _sort__dso_cmp(struct map *map_l, struct map *map_r)static int64_t sort__dso_cmp (struct hist_entry *left,struct hist_entry *right) { -return _sort__dso_cmp (left->ms.map, right->ms.map); +return _sort__dso_cmp (right->ms.map, left->ms.map); } static int _hist_entry__dso_snprintf(struct map *map, char *bf,
@@ -210,6 +217,15 @@ sort__sym_cmp(struct hist_entry *left, struct hist_entry *right)return _sort__sym_cmp (left->ms.sym, right->ms.sym); } +static int64_t +sort__sym_sort (struct hist_entry *left,struct hist_entry *right) +{ +if (!left->ms.sym || !right->ms.sym) +return cmp_null (left->ms.sym, right->ms.sym); + +return strcmp (right->ms.sym->name, left->ms.sym->name); +} +static int _hist_entry__sym_snprintf (struct map *map,struct symbol *sym,u64 ip,char level,char *bf,size_t size,unsigned int width)
@@ -256,6 +272,7 @@ static int hist_entry__sym_snprintf(struct hist_entry *he, char *bf,struct sort_entry sort_sym = { .se_header ="Symbol" , .se_cmp = sort__sym_cmp, + .se_sort = sort__sym_sort, .se_snprintf = hist_entry__sym_snprintf, .se_width_idx =HISTC_SYMBOL , };
@@ -283,7 +300,7 @@ sort__srcline_cmp(struct hist_entry *left, struct hist_entry *right) map__rip_2objdump(map, right->ip)); } } -return strcmp (left->srcline, right->srcline); +return strcmp (right->srcline, left->srcline); } static int hist_entry__srcline_snprintf(struct hist_entry *he, char *bf,
@@ -311,7 +328,7 @@ sort__parent_cmp(struct hist_entry *left, struct hist_entry *right)if (!sym_l || !sym_r)return cmp_null (sym_l, sym_r); -return strcmp (sym_l->name, sym_r->name); +return strcmp (sym_r->name, sym_l->name); } static int hist_entry__parent_snprintf(struct hist_entry *he, char *bf,
@@ -1126,7 +1143,7 @@ __sort_dimension__alloc_hpp(struct sort_dimension *sd) hse->hpp.cmp = sd->entry->se_cmp; hse->hpp.collapse = sd->entry->se_collapse ? : sd->entry->se_cmp; - hse->hpp.sort = hse->hpp.collapse; + hse->hpp.sort = sd->entry->se_sort ? : hse->hpp.collapse;INIT_LIST_HEAD (&hse->hpp.list);INIT_LIST_HEAD (&hse->hpp.sort_list);
tools/perf/util/sort.h +1 -0
@@ -182,6 +182,7 @@ struct sort_entry {int64_t (*se_cmp)(struct hist_entry *,struct hist_entry *);int64_t (*se_collapse)(struct hist_entry *,struct hist_entry *); +int64_t (*se_sort)(struct hist_entry *,struct hist_entry *);int (*se_snprintf)(struct hist_entry *he,char *bf,size_t size,unsigned int width);u8 se_width_idx;
Namhyung Kim
maintainerPATCH 13/20 perf report/tui: Fix a bug when --fields/sort is given
In reply to Namhyung KimThe hists__filter_entries() function is called when down arrow key is pressed for navigating through the entries in TUI. It has a check for filtering out entries that have very small overhead (under min_pcnt).
However it just assumed the entries are sorted by the overhead so when it saw such a small overheaded entry, it just stopped navigating as an optimization. But it's not true anymore due to new --fields and --sort optoin behavior and this case users cannot go down to a next entry if ther's an entry with small overhead in-between.
--- tools/perf/ui/browsers/hists.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-)
tools/perf/ui/browsers/hists.c +1 -4
@@ -812,10 +812,7 @@ static struct rb_node *hists__filter_entries(struct rb_node *nd,if (total) percent = h->stat.period *100.0 / total; -if (percent < min_pcnt) -return NULL ; - -if (!h->filtered) +if (!h->filtered && percent >= min_pcnt)return nd; nd =rb_next (nd);
Signature · 1 line
1.9.2
tip-bot for Namhyung Kim
merge bot[tip:perf/core] perf report/tui: Fix a bug when --fields/ sort is given
perf report/tui: Fix a bug when --fields/sort is given
Commit-ID: c0f1527b7e004f9a91e488f05c251213d16ad7ac Gitweb: http://git.kernel.org/tip/c0f1527b7e004f9a91e488f05c251213d16ad7ac Author: Namhyung Kim <[email protected]> AuthorDate: Wed, 16 Apr 2014 11:16:33 +0900 Committer: Jiri Olsa <[email protected]> CommitDate: Wed, 21 May 2014 11:45:36 +0200
perf report/tui: Fix a bug when --fields/sort is given
The hists__filter_entries() function is called when down arrow key is pressed for navigating through the entries in TUI. It has a check for filtering out entries that have very small overhead (under min_pcnt).
However it just assumed the entries are sorted by the overhead so when it saw such a small overheaded entry, it just stopped navigating as an optimization. But it's not true anymore due to new --fields and --sort optoin behavior and this case users cannot go down to a next entry if ther's an entry with small overhead in-between.
--- tools/perf/ui/browsers/hists.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-)
tools/perf/ui/browsers/hists.c +1 -4
@@ -812,10 +812,7 @@ static struct rb_node *hists__filter_entries(struct rb_node *nd,if (total) percent = h->stat.period *100.0 / total; -if (percent < min_pcnt) -return NULL ; - -if (!h->filtered) +if (!h->filtered && percent >= min_pcnt)return nd; nd =rb_next (nd);
Namhyung Kim
maintainerPATCH 14/20 perf top: Add --fields option to specify output fields
In reply to Namhyung KimThe --fields option is to allow user setup output field in any order. It can recieve any sort keys and following (hpp) fields:
overhead, overhead_sys, overhead_us, sample and period
If guest profiling is enabled, overhead_guest_{sys,us} will be available too.
More more information, please see previous patch "perf report:
Add -F option to specify output fields"
--- tools/perf/Documentation/perf-top.txt | 9 +++++++++ tools/perf/builtin-top.c | 15 +++++++++------ 2 files changed, 18 insertions(+), 6 deletions(-)
tools/perf/Documentation/perf-top.txt +9 -0
@@ -116,6 +116,15 @@ Default is to monitor all CPUS. local_weight, abort, in_tx, transaction, overhead, sample, period. Please see description of --sort in the perf-report man page. +--fields=:: + Specify output field - multiple keys can be specified in CSV format. + Following fields are available: + overhead, overhead_sys, overhead_us, sample and period. + Also it can contain any sort key(s). + + By default, every sort keys not specified in --field will be appended + automatically. + -n:: --show-nr-samples:: Show a column with the number of samples.
tools/perf/builtin-top.c +9 -6
@@ -1085,6 +1085,8 @@ int cmd_top(int argc, const char **argv, const char *prefix __maybe_unused)OPT_STRING ('s' ,"sort" , &sort_order,"key[,key2...]" ,"sort by key(s): pid, comm, dso, symbol, parent, cpu, srcline, ..." " Please refer the man page for the complete list." ), +OPT_STRING (0 ,"fields" , &field_order,"key[,keys...]" , +"output field(s): overhead, period, sample plus all of sort keys" ),OPT_BOOLEAN ('n' ,"show-nr-samples" , &symbol_conf.show_nr_samples,"Show a column with the number of samples" ), OPT_CALLBACK_NOOPT('g', NULL, &top.record_opts,
@@ -1138,17 +1140,18 @@ int cmd_top(int argc, const char **argv, const char *prefix __maybe_unused)usage_with_options (top_usage, options); sort__mode =SORT_MODE__TOP ; +/* display thread wants entries to be collapsed in a different tree */ + sort__need_collapse =1 ;if (setup_sorting () <0 ) { -parse_options_usage (top_usage, options,"s" ,1 ); +if (sort_order) +parse_options_usage (top_usage, options,"s" ,1 ); +if (field_order) +parse_options_usage (sort_order ?NULL : top_usage, + options,"fields" ,0 ); goto out_delete_evlist; } -/* display thread wants entries to be collapsed in a different tree */ - sort__need_collapse =1 ; - -perf_hpp__init (); -if (top.use_stdio) use_browser =0 ;else if (top.use_tui)
Signature · 1 line
1.9.2
tip-bot for Namhyung Kim
merge bot[tip:perf/core] perf top: Add --fields option to specify output fields
perf top: Add --fields option to specify output fields
Commit-ID: 6fe8c26d7ab9fbd6748fc40ca5fea1e3131e7236 Gitweb: http://git.kernel.org/tip/6fe8c26d7ab9fbd6748fc40ca5fea1e3131e7236 Author: Namhyung Kim <[email protected]> AuthorDate: Tue, 4 Mar 2014 11:01:41 +0900 Committer: Jiri Olsa <[email protected]> CommitDate: Wed, 21 May 2014 11:45:36 +0200
perf top: Add --fields option to specify output fields
The --fields option is to allow user setup output field in any order. It can receive any sort keys and following (hpp) fields:
overhead, overhead_sys, overhead_us, sample and period
If guest profiling is enabled, overhead_guest_{sys,us} will be available too.
More more information, please see previous patch "perf report:
Add -F option to specify output fields"
--- tools/perf/Documentation/perf-top.txt | 9 +++++++++ tools/perf/builtin-top.c | 15 +++++++++------ 2 files changed, 18 insertions(+), 6 deletions(-)
tools/perf/Documentation/perf-top.txt +9 -0
@@ -116,6 +116,15 @@ Default is to monitor all CPUS. local_weight, abort, in_tx, transaction, overhead, sample, period. Please see description of --sort in the perf-report man page. +--fields=:: + Specify output field - multiple keys can be specified in CSV format. + Following fields are available: + overhead, overhead_sys, overhead_us, sample and period. + Also it can contain any sort key(s). + + By default, every sort keys not specified in --field will be appended + automatically. + -n:: --show-nr-samples:: Show a column with the number of samples.
tools/perf/builtin-top.c +9 -6
@@ -1085,6 +1085,8 @@ int cmd_top(int argc, const char **argv, const char *prefix __maybe_unused)OPT_STRING ('s' ,"sort" , &sort_order,"key[,key2...]" ,"sort by key(s): pid, comm, dso, symbol, parent, cpu, srcline, ..." " Please refer the man page for the complete list." ), +OPT_STRING (0 ,"fields" , &field_order,"key[,keys...]" , +"output field(s): overhead, period, sample plus all of sort keys" ),OPT_BOOLEAN ('n' ,"show-nr-samples" , &symbol_conf.show_nr_samples,"Show a column with the number of samples" ), OPT_CALLBACK_NOOPT('g', NULL, &top.record_opts,
@@ -1138,17 +1140,18 @@ int cmd_top(int argc, const char **argv, const char *prefix __maybe_unused)usage_with_options (top_usage, options); sort__mode =SORT_MODE__TOP ; +/* display thread wants entries to be collapsed in a different tree */ + sort__need_collapse =1 ;if (setup_sorting () <0 ) { -parse_options_usage (top_usage, options,"s" ,1 ); +if (sort_order) +parse_options_usage (top_usage, options,"s" ,1 ); +if (field_order) +parse_options_usage (sort_order ?NULL : top_usage, + options,"fields" ,0 ); goto out_delete_evlist; } -/* display thread wants entries to be collapsed in a different tree */ - sort__need_collapse =1 ; - -perf_hpp__init (); -if (top.use_stdio) use_browser =0 ;else if (top.use_tui)
Namhyung Kim
maintainerPATCH 15/20 perf tools: Skip elided sort entries
In reply to Namhyung KimWhen it converted sort entries to hpp formats, it missed se->elide handling, so add it for compatibility.
--- tools/perf/ui/browsers/hists.c | 3 +++ tools/perf/ui/gtk/hists.c | 6 ++++++ tools/perf/ui/stdio/hist.c | 9 +++++++++ tools/perf/util/hist.c | 9 +++++++++ tools/perf/util/hist.h | 1 + tools/perf/util/sort.c | 11 +++++++++++ 6 files changed, 39 insertions(+)
tools/perf/ui/browsers/hists.c +3 -0
@@ -711,6 +711,9 @@ static int hist_browser__show_entry(struct hist_browser *browser,ui_browser__gotorc (&browser->b, row,0 );perf_hpp__for_each_format (fmt) { +if (perf_hpp__should_skip (fmt)) +continue ; +if (current_entry && browser->b.navkeypressed) {ui_browser__set_color (&browser->b,HE_COLORSET_SELECTED );
tools/perf/ui/gtk/hists.c +6 -0
@@ -178,6 +178,9 @@ static void perf_gtk__show_hists(GtkWidget *window, struct hists *hists, col_idx =0 ;perf_hpp__for_each_format (fmt) { +if (perf_hpp__should_skip (fmt)) +continue ; + fmt->header (fmt, &hpp,hists_to_evsel (hists)); gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(view),
@@ -222,6 +225,9 @@ static void perf_gtk__show_hists(GtkWidget *window, struct hists *hists, col_idx =0 ;perf_hpp__for_each_format (fmt) { +if (perf_hpp__should_skip (fmt)) +continue ; +if (fmt->color) fmt->color (fmt, &hpp, h);else
tools/perf/ui/stdio/hist.c +9 -0
@@ -318,6 +318,9 @@ static int hist_entry__snprintf(struct hist_entry *he, struct perf_hpp *hpp)return 0 ;perf_hpp__for_each_format (fmt) { +if (perf_hpp__should_skip (fmt)) +continue ; +/* * If there's no field_sep, we still need * to display initial ' '.
@@ -407,6 +410,9 @@ size_t hists__fprintf(struct hists *hists, bool show_header, int max_rows,fprintf (fp,"# " );perf_hpp__for_each_format (fmt) { +if (perf_hpp__should_skip (fmt)) +continue ; +if (!first)fprintf (fp,"%s" , sep ?:" " );else
@@ -430,6 +436,9 @@ size_t hists__fprintf(struct hists *hists, bool show_header, int max_rows,perf_hpp__for_each_format (fmt) {unsigned int i; +if (perf_hpp__should_skip (fmt)) +continue ; +if (!first)fprintf (fp,"%s" , sep ?:" " );else
tools/perf/util/hist.c +9 -0
@@ -436,6 +436,9 @@ hist_entry__cmp(struct hist_entry *left, struct hist_entry *right)int64_t cmp =0 ;perf_hpp__for_each_sort_list (fmt) { +if (perf_hpp__should_skip (fmt)) +continue ; + cmp = fmt->cmp (left, right);if (cmp)break ;
@@ -451,6 +454,9 @@ hist_entry__collapse(struct hist_entry *left, struct hist_entry *right)int64_t cmp =0 ;perf_hpp__for_each_sort_list (fmt) { +if (perf_hpp__should_skip (fmt)) +continue ; + cmp = fmt->collapse (left, right);if (cmp)break ;
@@ -570,6 +576,9 @@ static int hist_entry__sort(struct hist_entry *a, struct hist_entry *b)int64_t cmp =0 ;perf_hpp__for_each_sort_list (fmt) { +if (perf_hpp__should_skip (fmt)) +continue ; + cmp = fmt->sort (a, b);if (cmp)break ;
tools/perf/util/hist.h +1 -0
@@ -201,6 +201,7 @@ void perf_hpp__append_sort_keys(void);bool perf_hpp__is_sort_entry (struct perf_hpp_fmt *format);bool perf_hpp__same_sort_entry (struct perf_hpp_fmt *a,struct perf_hpp_fmt *b); +bool perf_hpp__should_skip (struct perf_hpp_fmt *format);typedef u64 (*hpp_field_fn )(struct hist_entry *he);typedef int (*hpp_callback_fn )(struct perf_hpp *hpp,bool front);
tools/perf/util/sort.c +11 -0
@@ -1358,6 +1358,17 @@ static int __setup_sorting(void)return ret; } +bool perf_hpp__should_skip (struct perf_hpp_fmt *format) +{ +if (perf_hpp__is_sort_entry (format)) { +struct hpp_sort_entry *hse; + + hse = container_of(format, struct hpp_sort_entry, hpp); +return hse->se->elide; + } +return false; +} +static void sort_entry__setup_elide (struct sort_entry *se,struct strlist *list,const char *list_name,FILE *fp)
Signature · 1 line
1.9.2
tip-bot for Namhyung Kim
merge bot[tip:perf/core] perf tools: Skip elided sort entries
perf tools: Skip elided sort entries
Commit-ID: e67d49a72df9aa50841ad400f7a99405e4980ee4 Gitweb: http://git.kernel.org/tip/e67d49a72df9aa50841ad400f7a99405e4980ee4 Author: Namhyung Kim <[email protected]> AuthorDate: Tue, 18 Mar 2014 13:00:59 +0900 Committer: Jiri Olsa <[email protected]> CommitDate: Wed, 21 May 2014 11:45:36 +0200
perf tools: Skip elided sort entries
When it converted sort entries to hpp formats, it missed se->elide handling, so add it for compatibility.
--- tools/perf/ui/browsers/hists.c | 6 ++++++ tools/perf/ui/gtk/hists.c | 6 ++++++ tools/perf/ui/stdio/hist.c | 9 +++++++++ tools/perf/util/hist.c | 9 +++++++++ tools/perf/util/hist.h | 1 + tools/perf/util/sort.c | 11 +++++++++++ 6 files changed, 42 insertions(+)
tools/perf/ui/browsers/hists.c +6 -0
@@ -711,6 +711,9 @@ static int hist_browser__show_entry(struct hist_browser *browser,ui_browser__gotorc (&browser->b, row,0 );perf_hpp__for_each_format (fmt) { +if (perf_hpp__should_skip (fmt)) +continue ; +if (current_entry && browser->b.navkeypressed) {ui_browser__set_color (&browser->b,HE_COLORSET_SELECTED );
@@ -1100,6 +1103,9 @@ static int hist_browser__fprintf_entry(struct hist_browser *browser, printed +=fprintf (fp,"%c " , folded_sign);perf_hpp__for_each_format (fmt) { +if (perf_hpp__should_skip (fmt)) +continue ; +if (!first) { ret =scnprintf (hpp.buf, hpp.size," " );advance_hpp (&hpp, ret);
tools/perf/ui/gtk/hists.c +6 -0
@@ -178,6 +178,9 @@ static void perf_gtk__show_hists(GtkWidget *window, struct hists *hists, col_idx =0 ;perf_hpp__for_each_format (fmt) { +if (perf_hpp__should_skip (fmt)) +continue ; + fmt->header (fmt, &hpp,hists_to_evsel (hists)); gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(view),
@@ -222,6 +225,9 @@ static void perf_gtk__show_hists(GtkWidget *window, struct hists *hists, col_idx =0 ;perf_hpp__for_each_format (fmt) { +if (perf_hpp__should_skip (fmt)) +continue ; +if (fmt->color) fmt->color (fmt, &hpp, h);else
tools/perf/ui/stdio/hist.c +9 -0
@@ -318,6 +318,9 @@ static int hist_entry__snprintf(struct hist_entry *he, struct perf_hpp *hpp)return 0 ;perf_hpp__for_each_format (fmt) { +if (perf_hpp__should_skip (fmt)) +continue ; +/* * If there's no field_sep, we still need * to display initial ' '.
@@ -407,6 +410,9 @@ size_t hists__fprintf(struct hists *hists, bool show_header, int max_rows,fprintf (fp,"# " );perf_hpp__for_each_format (fmt) { +if (perf_hpp__should_skip (fmt)) +continue ; +if (!first)fprintf (fp,"%s" , sep ?:" " );else
@@ -430,6 +436,9 @@ size_t hists__fprintf(struct hists *hists, bool show_header, int max_rows,perf_hpp__for_each_format (fmt) {unsigned int i; +if (perf_hpp__should_skip (fmt)) +continue ; +if (!first)fprintf (fp,"%s" , sep ?:" " );else
tools/perf/util/hist.c +9 -0
@@ -436,6 +436,9 @@ hist_entry__cmp(struct hist_entry *left, struct hist_entry *right)int64_t cmp =0 ;perf_hpp__for_each_sort_list (fmt) { +if (perf_hpp__should_skip (fmt)) +continue ; + cmp = fmt->cmp (left, right);if (cmp)break ;
@@ -451,6 +454,9 @@ hist_entry__collapse(struct hist_entry *left, struct hist_entry *right)int64_t cmp =0 ;perf_hpp__for_each_sort_list (fmt) { +if (perf_hpp__should_skip (fmt)) +continue ; + cmp = fmt->collapse (left, right);if (cmp)break ;
@@ -570,6 +576,9 @@ static int hist_entry__sort(struct hist_entry *a, struct hist_entry *b)int64_t cmp =0 ;perf_hpp__for_each_sort_list (fmt) { +if (perf_hpp__should_skip (fmt)) +continue ; + cmp = fmt->sort (a, b);if (cmp)break ;
tools/perf/util/hist.h +1 -0
@@ -201,6 +201,7 @@ void perf_hpp__append_sort_keys(void);bool perf_hpp__is_sort_entry (struct perf_hpp_fmt *format);bool perf_hpp__same_sort_entry (struct perf_hpp_fmt *a,struct perf_hpp_fmt *b); +bool perf_hpp__should_skip (struct perf_hpp_fmt *format);typedef u64 (*hpp_field_fn )(struct hist_entry *he);typedef int (*hpp_callback_fn )(struct perf_hpp *hpp,bool front);
tools/perf/util/sort.c +11 -0
@@ -1358,6 +1358,17 @@ static int __setup_sorting(void)return ret; } +bool perf_hpp__should_skip (struct perf_hpp_fmt *format) +{ +if (perf_hpp__is_sort_entry (format)) { +struct hpp_sort_entry *hse; + + hse = container_of(format, struct hpp_sort_entry, hpp); +return hse->se->elide; + } +return false; +} +static void sort_entry__setup_elide (struct sort_entry *se,struct strlist *list,const char *list_name,FILE *fp)
Namhyung Kim
maintainerPATCH 16/20 perf hists: Reset width of output fields with header length
In reply to Namhyung KimSome fields missed to set default column length so it broke align in --stdio output. Add perf_hpp__reset_width() to set it to a sane default value.
Note that this change will ignore -w/--column-widths option for now.
Before:
$ perf report -F cpu,comm,overhead --stdio
...
# CPU Command Overhead
# ............... ........
#
0 firefox 2.65%
0 kworker/0:0 1.45%
0 swapper 5.52%
0 synergys 0.92%
1 firefox 4.54%After:
# CPU Command Overhead
# ... ............... ........
#
0 firefox 2.65%
0 kworker/0:0 1.45%
0 swapper 5.52%
0 synergys 0.92%
1 firefox 4.54%--- tools/perf/ui/stdio/hist.c | 21 +++------------------ tools/perf/util/hist.h | 1 + tools/perf/util/sort.c | 12 ++++++++++++ 3 files changed, 16 insertions(+), 18 deletions(-)
tools/perf/ui/stdio/hist.c +3 -18
@@ -369,12 +369,10 @@ size_t hists__fprintf(struct hists *hists, bool show_header, int max_rows, int max_cols, float min_pcnt, FILE *fp) { struct perf_hpp_fmt *fmt; -struct sort_entry *se;struct rb_node *nd;size_t ret =0 ;unsigned int width;const char *sep = symbol_conf.field_sep; -const char *col_width = symbol_conf.col_width_list_str;int nr_rows =0 ;char bf[96 ]; struct perf_hpp dummy_hpp = {
@@ -387,22 +385,9 @@ size_t hists__fprintf(struct hists *hists, bool show_header, int max_rows,init_rem_hits (); -list_for_each_entry (se, &hist_entry__sort_list, list) { -if (se->elide) -continue ; - width =strlen (se->se_header); -if (symbol_conf.col_width_list_str) { -if (col_width) { -hists__set_col_len (hists, se->se_width_idx, -atoi (col_width)); - col_width =strchr (col_width,',' ); -if (col_width) - ++col_width; - } - } -if (!hists__new_col_len (hists, se->se_width_idx, width)) - width =hists__col_len (hists, se->se_width_idx); - } + +perf_hpp__for_each_format (fmt) +perf_hpp__reset_width (fmt, hists);if (!show_header) goto print_entries;
tools/perf/util/hist.h +1 -0
@@ -202,6 +202,7 @@ void perf_hpp__append_sort_keys(void);bool perf_hpp__is_sort_entry (struct perf_hpp_fmt *format);bool perf_hpp__same_sort_entry (struct perf_hpp_fmt *a,struct perf_hpp_fmt *b);bool perf_hpp__should_skip (struct perf_hpp_fmt *format); +void perf_hpp__reset_width (struct perf_hpp_fmt *fmt,struct hists *hists);typedef u64 (*hpp_field_fn )(struct hist_entry *he);typedef int (*hpp_callback_fn )(struct perf_hpp *hpp,bool front);
tools/perf/util/sort.c +12 -0
@@ -1089,6 +1089,18 @@ bool perf_hpp__same_sort_entry(struct perf_hpp_fmt *a, struct perf_hpp_fmt *b)return hse_a->se == hse_b->se; } +void perf_hpp__reset_width (struct perf_hpp_fmt *fmt,struct hists *hists) +{ +struct hpp_sort_entry *hse; + +if (!perf_hpp__is_sort_entry (fmt)) +return ; + + hse = container_of(fmt, struct hpp_sort_entry, hpp); +hists__new_col_len (hists, hse->se->se_width_idx, +strlen (hse->se->se_header)); +} +static int __sort__hpp_header (struct perf_hpp_fmt *fmt,struct perf_hpp *hpp,struct perf_evsel *evsel) {
Signature · 1 line
1.9.2
tip-bot for Namhyung Kim
merge bot[tip:perf/core] perf hists: Reset width of output fields with header length
perf hists: Reset width of output fields with header length
Commit-ID: 678a500d076ec873b8809041c6b718653db2a75f Gitweb: http://git.kernel.org/tip/678a500d076ec873b8809041c6b718653db2a75f Author: Namhyung Kim <[email protected]> AuthorDate: Thu, 20 Mar 2014 11:18:54 +0900 Committer: Jiri Olsa <[email protected]> CommitDate: Wed, 21 May 2014 11:45:36 +0200
perf hists: Reset width of output fields with header length
Some fields missed to set default column length so it broke align in --stdio output. Add perf_hpp__reset_width() to set it to a sane default value.
Note that this change will ignore -w/--column-widths option for now.
Before:
$ perf report -F cpu,comm,overhead --stdio
...
# CPU Command Overhead
# ............... ........
#
0 firefox 2.65%
0 kworker/0:0 1.45%
0 swapper 5.52%
0 synergys 0.92%
1 firefox 4.54%After:
# CPU Command Overhead
# ... ............... ........
#
0 firefox 2.65%
0 kworker/0:0 1.45%
0 swapper 5.52%
0 synergys 0.92%
1 firefox 4.54%--- tools/perf/ui/stdio/hist.c | 21 +++------------------ tools/perf/util/hist.h | 1 + tools/perf/util/sort.c | 12 ++++++++++++ 3 files changed, 16 insertions(+), 18 deletions(-)
tools/perf/ui/stdio/hist.c +3 -18
@@ -369,12 +369,10 @@ size_t hists__fprintf(struct hists *hists, bool show_header, int max_rows, int max_cols, float min_pcnt, FILE *fp) { struct perf_hpp_fmt *fmt; -struct sort_entry *se;struct rb_node *nd;size_t ret =0 ;unsigned int width;const char *sep = symbol_conf.field_sep; -const char *col_width = symbol_conf.col_width_list_str;int nr_rows =0 ;char bf[96 ]; struct perf_hpp dummy_hpp = {
@@ -387,22 +385,9 @@ size_t hists__fprintf(struct hists *hists, bool show_header, int max_rows,init_rem_hits (); -list_for_each_entry (se, &hist_entry__sort_list, list) { -if (se->elide) -continue ; - width =strlen (se->se_header); -if (symbol_conf.col_width_list_str) { -if (col_width) { -hists__set_col_len (hists, se->se_width_idx, -atoi (col_width)); - col_width =strchr (col_width,',' ); -if (col_width) - ++col_width; - } - } -if (!hists__new_col_len (hists, se->se_width_idx, width)) - width =hists__col_len (hists, se->se_width_idx); - } + +perf_hpp__for_each_format (fmt) +perf_hpp__reset_width (fmt, hists);if (!show_header) goto print_entries;
tools/perf/util/hist.h +1 -0
@@ -202,6 +202,7 @@ void perf_hpp__append_sort_keys(void);bool perf_hpp__is_sort_entry (struct perf_hpp_fmt *format);bool perf_hpp__same_sort_entry (struct perf_hpp_fmt *a,struct perf_hpp_fmt *b);bool perf_hpp__should_skip (struct perf_hpp_fmt *format); +void perf_hpp__reset_width (struct perf_hpp_fmt *fmt,struct hists *hists);typedef u64 (*hpp_field_fn )(struct hist_entry *he);typedef int (*hpp_callback_fn )(struct perf_hpp *hpp,bool front);
tools/perf/util/sort.c +12 -0
@@ -1089,6 +1089,18 @@ bool perf_hpp__same_sort_entry(struct perf_hpp_fmt *a, struct perf_hpp_fmt *b)return hse_a->se == hse_b->se; } +void perf_hpp__reset_width (struct perf_hpp_fmt *fmt,struct hists *hists) +{ +struct hpp_sort_entry *hse; + +if (!perf_hpp__is_sort_entry (fmt)) +return ; + + hse = container_of(fmt, struct hpp_sort_entry, hpp); +hists__new_col_len (hists, hse->se->se_width_idx, +strlen (hse->se->se_header)); +} +static int __sort__hpp_header (struct perf_hpp_fmt *fmt,struct perf_hpp *hpp,struct perf_evsel *evsel) {
Namhyung Kim
maintainerPATCH 17/20 perf tools: Get rid of obsolete hist_entry__sort_list
In reply to Namhyung KimNow we moved to the perf_hpp_[_sort]_list so no need to keep the old hist_entry__sort_list and sort__first_dimension. Also the hist_entry__sort_snprintf() can be gone as hist_entry__snprintf() provides the functionality.
--- tools/perf/ui/hist.c | 36 +++++++++--------------------------- tools/perf/ui/stdio/hist.c | 22 +++++++++++++++------- tools/perf/util/sort.c | 35 +++++++++++++++++++---------------- 3 files changed, 43 insertions(+), 50 deletions(-)
tools/perf/ui/hist.c +9 -27
@@ -459,47 +459,29 @@ next: } } -int hist_entry__sort_snprintf (struct hist_entry *he,char *s,size_t size, -struct hists *hists) -{ -const char *sep = symbol_conf.field_sep; -struct sort_entry *se; -int ret =0 ; - -list_for_each_entry (se, &hist_entry__sort_list, list) { -if (se->elide) -continue ; - - ret +=scnprintf (s + ret, size - ret,"%s" , sep ?:" " ); - ret += se->se_snprintf (he, s + ret, size - ret, -hists__col_len (hists, se->se_width_idx)); - } - -return ret; -} -/* * See hists__fprintf to match the column widths */ unsigned int hists__sort_list_width (struct hists *hists) {struct perf_hpp_fmt *fmt; -struct sort_entry *se; -int i =0 , ret =0 ; +int ret =0 ; +bool first = true;struct perf_hpp dummy_hpp;perf_hpp__for_each_format (fmt) { -if (i) +if (perf_hpp__should_skip (fmt)) +continue ; + +if (first) + first = false; +else ret +=2 ; ret += fmt->width (fmt, &dummy_hpp,hists_to_evsel (hists)); } -list_for_each_entry (se, &hist_entry__sort_list, list) -if (!se->elide) - ret +=2 +hists__col_len (hists, se->se_width_idx); - -if (verbose)/* Addr + origin */ +if (verbose && sort__has_sym)/* Addr + origin */ ret +=3 +BITS_PER_LONG /4 ;return ret;
tools/perf/ui/stdio/hist.c +15 -7
@@ -183,7 +183,8 @@ static size_t callchain__fprintf_graph(FILE *fp, struct rb_root *root,* the symbol. No need to print it otherwise it appears as * displayed twice. */ -if (!i++ && sort__first_dimension ==SORT_SYM ) +if (!i++ && field_order ==NULL && + sort_order && !prefixcmp (sort_order,"sym" ))continue ;if (!printed) { ret +=callchain__fprintf_left_margin (fp, left_margin);
@@ -296,13 +297,20 @@ static size_t hist_entry__callchain_fprintf(struct hist_entry *he,int left_margin =0 ;u64 total_period = hists->stats.total_period; -if (sort__first_dimension ==SORT_COMM ) { -struct sort_entry *se =list_first_entry (&hist_entry__sort_list, -typeof (*se), list); - left_margin =hists__col_len (hists, se->se_width_idx); - left_margin -=thread__comm_len (he->thread); - } +if (field_order ==NULL && (sort_order ==NULL || + !prefixcmp (sort_order,"comm" ))) { +struct perf_hpp_fmt *fmt; + +perf_hpp__for_each_format (fmt) { +if (!perf_hpp__is_sort_entry (fmt)) +continue ; +/* must be 'comm' sort entry */ + left_margin = fmt->width (fmt,NULL ,hists_to_evsel (hists)); + left_margin -=thread__comm_len (he->thread); +break ; + } + }return hist_entry_callchain__fprintf (he, total_period, left_margin, fp); }
tools/perf/util/sort.c +19 -16
@@ -22,9 +22,6 @@ int sort__has_sym = 0;int sort__has_dso =0 ;enum sort_mode sort__mode =SORT_MODE__NORMAL ; -enum sort_type sort__first_dimension; - -LIST_HEAD (hist_entry__sort_list);static int repsep_snprintf (char *bf,size_t size,const char *fmt, ...) {
@@ -1190,7 +1187,7 @@ static int __sort_dimension__add_hpp_output(struct sort_dimension *sd)return 0 ; } -static int __sort_dimension__add (struct sort_dimension *sd,enum sort_type idx) +static int __sort_dimension__add (struct sort_dimension *sd) {if (sd->taken)return 0 ;
@@ -1201,10 +1198,6 @@ static int __sort_dimension__add(struct sort_dimension *sd, enum sort_type idx)if (sd->entry->se_collapse) sort__need_collapse =1 ; -if (list_empty (&hist_entry__sort_list)) - sort__first_dimension = idx; - -list_add_tail (&sd->entry->list, &hist_entry__sort_list); sd->taken =1 ;return 0 ;
@@ -1268,7 +1261,7 @@ int sort_dimension__add(const char *tok) sort__has_dso =1 ; } -return __sort_dimension__add (sd, i); +return __sort_dimension__add (sd); }for (i =0 ; i <ARRAY_SIZE (hpp_sort_dimensions); i++) {
@@ -1292,7 +1285,7 @@ int sort_dimension__add(const char *tok)if (sd->entry == &sort_sym_from || sd->entry == &sort_sym_to) sort__has_sym =1 ; -__sort_dimension__add (sd, i + __SORT_BRANCH_STACK); +__sort_dimension__add (sd);return 0 ; }
@@ -1308,7 +1301,7 @@ int sort_dimension__add(const char *tok)if (sd->entry == &sort_mem_daddr_sym) sort__has_sym =1 ; -__sort_dimension__add (sd, i + __SORT_MEMORY_MODE); +__sort_dimension__add (sd);return 0 ; }
@@ -1395,7 +1388,8 @@ static void sort_entry__setup_elide(struct sort_entry *se,void sort__setup_elide (FILE *output) { -struct sort_entry *se; +struct perf_hpp_fmt *fmt; +struct hpp_sort_entry *hse;sort_entry__setup_elide (&sort_dso, symbol_conf.dso_list,"dso" , output);
@@ -1436,13 +1430,22 @@ void sort__setup_elide(FILE *output)* It makes no sense to elide all of sort entries. * Just revert them to show up again. */ -list_for_each_entry (se, &hist_entry__sort_list, list) { -if (!se->elide) +perf_hpp__for_each_format (fmt) { +if (!perf_hpp__is_sort_entry (fmt)) +continue ; + + hse = container_of(fmt, struct hpp_sort_entry, hpp); +if (!hse->se->elide)return ; } -list_for_each_entry (se, &hist_entry__sort_list, list) - se->elide = false; +perf_hpp__for_each_format (fmt) { +if (!perf_hpp__is_sort_entry (fmt)) +continue ; + + hse = container_of(fmt, struct hpp_sort_entry, hpp); + hse->se->elide = false; + } }static int output_field_add (char *tok)
Signature · 1 line
1.9.2
tip-bot for Namhyung Kim
merge bot[tip:perf/core] perf tools: Get rid of obsolete hist_entry__sort_list
perf tools: Get rid of obsolete hist_entry__sort_list
Commit-ID: cfaa154b2335d4c8efdfcb65d9b12e944d1b74a6 Gitweb: http://git.kernel.org/tip/cfaa154b2335d4c8efdfcb65d9b12e944d1b74a6 Author: Namhyung Kim <[email protected]> AuthorDate: Mon, 19 May 2014 14:19:30 +0900 Committer: Jiri Olsa <[email protected]> CommitDate: Wed, 21 May 2014 11:45:37 +0200
perf tools: Get rid of obsolete hist_entry__sort_list
Now we moved to the perf_hpp_[_sort]_list so no need to keep the old hist_entry__sort_list and sort__first_dimension. Also the hist_entry__sort_snprintf() can be gone as hist_entry__snprintf() provides the functionality.
--- tools/perf/ui/hist.c | 36 +++++++++--------------------------- tools/perf/ui/stdio/hist.c | 22 +++++++++++++++------- tools/perf/util/sort.c | 35 +++++++++++++++++++---------------- 3 files changed, 43 insertions(+), 50 deletions(-)
tools/perf/ui/hist.c +9 -27
@@ -459,47 +459,29 @@ next: } } -int hist_entry__sort_snprintf (struct hist_entry *he,char *s,size_t size, -struct hists *hists) -{ -const char *sep = symbol_conf.field_sep; -struct sort_entry *se; -int ret =0 ; - -list_for_each_entry (se, &hist_entry__sort_list, list) { -if (se->elide) -continue ; - - ret +=scnprintf (s + ret, size - ret,"%s" , sep ?:" " ); - ret += se->se_snprintf (he, s + ret, size - ret, -hists__col_len (hists, se->se_width_idx)); - } - -return ret; -} -/* * See hists__fprintf to match the column widths */ unsigned int hists__sort_list_width (struct hists *hists) {struct perf_hpp_fmt *fmt; -struct sort_entry *se; -int i =0 , ret =0 ; +int ret =0 ; +bool first = true;struct perf_hpp dummy_hpp;perf_hpp__for_each_format (fmt) { -if (i) +if (perf_hpp__should_skip (fmt)) +continue ; + +if (first) + first = false; +else ret +=2 ; ret += fmt->width (fmt, &dummy_hpp,hists_to_evsel (hists)); } -list_for_each_entry (se, &hist_entry__sort_list, list) -if (!se->elide) - ret +=2 +hists__col_len (hists, se->se_width_idx); - -if (verbose)/* Addr + origin */ +if (verbose && sort__has_sym)/* Addr + origin */ ret +=3 +BITS_PER_LONG /4 ;return ret;
tools/perf/ui/stdio/hist.c +15 -7
@@ -183,7 +183,8 @@ static size_t callchain__fprintf_graph(FILE *fp, struct rb_root *root,* the symbol. No need to print it otherwise it appears as * displayed twice. */ -if (!i++ && sort__first_dimension ==SORT_SYM ) +if (!i++ && field_order ==NULL && + sort_order && !prefixcmp (sort_order,"sym" ))continue ;if (!printed) { ret +=callchain__fprintf_left_margin (fp, left_margin);
@@ -296,13 +297,20 @@ static size_t hist_entry__callchain_fprintf(struct hist_entry *he,int left_margin =0 ;u64 total_period = hists->stats.total_period; -if (sort__first_dimension ==SORT_COMM ) { -struct sort_entry *se =list_first_entry (&hist_entry__sort_list, -typeof (*se), list); - left_margin =hists__col_len (hists, se->se_width_idx); - left_margin -=thread__comm_len (he->thread); - } +if (field_order ==NULL && (sort_order ==NULL || + !prefixcmp (sort_order,"comm" ))) { +struct perf_hpp_fmt *fmt; + +perf_hpp__for_each_format (fmt) { +if (!perf_hpp__is_sort_entry (fmt)) +continue ; +/* must be 'comm' sort entry */ + left_margin = fmt->width (fmt,NULL ,hists_to_evsel (hists)); + left_margin -=thread__comm_len (he->thread); +break ; + } + }return hist_entry_callchain__fprintf (he, total_period, left_margin, fp); }
tools/perf/util/sort.c +19 -16
@@ -22,9 +22,6 @@ int sort__has_sym = 0;int sort__has_dso =0 ;enum sort_mode sort__mode =SORT_MODE__NORMAL ; -enum sort_type sort__first_dimension; - -LIST_HEAD (hist_entry__sort_list);static int repsep_snprintf (char *bf,size_t size,const char *fmt, ...) {
@@ -1190,7 +1187,7 @@ static int __sort_dimension__add_hpp_output(struct sort_dimension *sd)return 0 ; } -static int __sort_dimension__add (struct sort_dimension *sd,enum sort_type idx) +static int __sort_dimension__add (struct sort_dimension *sd) {if (sd->taken)return 0 ;
@@ -1201,10 +1198,6 @@ static int __sort_dimension__add(struct sort_dimension *sd, enum sort_type idx)if (sd->entry->se_collapse) sort__need_collapse =1 ; -if (list_empty (&hist_entry__sort_list)) - sort__first_dimension = idx; - -list_add_tail (&sd->entry->list, &hist_entry__sort_list); sd->taken =1 ;return 0 ;
@@ -1268,7 +1261,7 @@ int sort_dimension__add(const char *tok) sort__has_dso =1 ; } -return __sort_dimension__add (sd, i); +return __sort_dimension__add (sd); }for (i =0 ; i <ARRAY_SIZE (hpp_sort_dimensions); i++) {
@@ -1292,7 +1285,7 @@ int sort_dimension__add(const char *tok)if (sd->entry == &sort_sym_from || sd->entry == &sort_sym_to) sort__has_sym =1 ; -__sort_dimension__add (sd, i + __SORT_BRANCH_STACK); +__sort_dimension__add (sd);return 0 ; }
@@ -1308,7 +1301,7 @@ int sort_dimension__add(const char *tok)if (sd->entry == &sort_mem_daddr_sym) sort__has_sym =1 ; -__sort_dimension__add (sd, i + __SORT_MEMORY_MODE); +__sort_dimension__add (sd);return 0 ; }
@@ -1395,7 +1388,8 @@ static void sort_entry__setup_elide(struct sort_entry *se,void sort__setup_elide (FILE *output) { -struct sort_entry *se; +struct perf_hpp_fmt *fmt; +struct hpp_sort_entry *hse;sort_entry__setup_elide (&sort_dso, symbol_conf.dso_list,"dso" , output);
@@ -1436,13 +1430,22 @@ void sort__setup_elide(FILE *output)* It makes no sense to elide all of sort entries. * Just revert them to show up again. */ -list_for_each_entry (se, &hist_entry__sort_list, list) { -if (!se->elide) +perf_hpp__for_each_format (fmt) { +if (!perf_hpp__is_sort_entry (fmt)) +continue ; + + hse = container_of(fmt, struct hpp_sort_entry, hpp); +if (!hse->se->elide)return ; } -list_for_each_entry (se, &hist_entry__sort_list, list) - se->elide = false; +perf_hpp__for_each_format (fmt) { +if (!perf_hpp__is_sort_entry (fmt)) +continue ; + + hse = container_of(fmt, struct hpp_sort_entry, hpp); + hse->se->elide = false; + } }static int output_field_add (char *tok)
Namhyung Kim
maintainerPATCH 18/20 perf tools: Introduce reset_output_field()
In reply to Namhyung KimThe reset_output_field() function is for clearing output field settings and will be used for test code in later patch.
--- tools/perf/ui/hist.c | 17 +++++++++++++++++ tools/perf/util/hist.h | 7 +++++++ tools/perf/util/sort.c | 11 +++++++++++ tools/perf/util/sort.h | 1 + 4 files changed, 36 insertions(+)
tools/perf/ui/hist.c +17 -0
@@ -459,6 +459,23 @@ next: } } +void perf_hpp__reset_output_field (void ) +{ +struct perf_hpp_fmt *fmt, *tmp; + +/* reset output fields */ +perf_hpp__for_each_format_safe (fmt, tmp) { +list_del_init (&fmt->list); +list_del_init (&fmt->sort_list); + } + +/* reset sort keys */ +perf_hpp__for_each_sort_list_safe (fmt, tmp) { +list_del_init (&fmt->list); +list_del_init (&fmt->sort_list); + } +} +/* * See hists__fprintf to match the column widths */
tools/perf/util/hist.h +7 -0
@@ -174,9 +174,15 @@ extern struct list_head perf_hpp__sort_list;#define perf_hpp__for_each_format (format) \ list_for_each_entry(format, &perf_hpp__list, list) +#define perf_hpp__for_each_format_safe (format, tmp) \ + list_for_each_entry_safe(format, tmp, &perf_hpp__list, list) +#define perf_hpp__for_each_sort_list (format) \ list_for_each_entry(format, &perf_hpp__sort_list, sort_list) +#define perf_hpp__for_each_sort_list_safe (format, tmp) \ + list_for_each_entry_safe(format, tmp, &perf_hpp__sort_list, sort_list) +extern struct perf_hpp_fmt perf_hpp__format[];enum {
@@ -197,6 +203,7 @@ void perf_hpp__column_register(struct perf_hpp_fmt *format);void perf_hpp__column_enable (unsigned col);void perf_hpp__register_sort_field (struct perf_hpp_fmt *format);void perf_hpp__setup_output_field (void ); +void perf_hpp__reset_output_field (void );void perf_hpp__append_sort_keys (void );bool perf_hpp__is_sort_entry (struct perf_hpp_fmt *format);
tools/perf/util/sort.c +11 -0
@@ -1573,3 +1573,14 @@ int setup_sorting(void)return 0 ; } + +void reset_output_field (void ) +{ + sort__need_collapse =0 ; + sort__has_parent =0 ; + sort__has_sym =0 ; + sort__has_dso =0 ; + +reset_dimensions (); +perf_hpp__reset_output_field (); +}
tools/perf/util/sort.h +1 -0
@@ -194,6 +194,7 @@ extern struct list_head hist_entry__sort_list;int setup_sorting (void );int setup_output_field (void ); +void reset_output_field (void );extern int sort_dimension__add (const char *);void sort__setup_elide (FILE *fp);
Signature · 1 line
1.9.2
tip-bot for Namhyung Kim
merge bot[tip:perf/core] perf tools: Introduce reset_output_field()
perf tools: Introduce reset_output_field()
Commit-ID: 1c89fe9b0447f0ce393325e51911f8073432b7b4 Gitweb: http://git.kernel.org/tip/1c89fe9b0447f0ce393325e51911f8073432b7b4 Author: Namhyung Kim <[email protected]> AuthorDate: Wed, 7 May 2014 18:42:24 +0900 Committer: Jiri Olsa <[email protected]> CommitDate: Wed, 21 May 2014 11:45:37 +0200
perf tools: Introduce reset_output_field()
The reset_output_field() function is for clearing output field settings and will be used for test code in later patch.
--- tools/perf/ui/hist.c | 17 +++++++++++++++++ tools/perf/util/hist.h | 7 +++++++ tools/perf/util/sort.c | 11 +++++++++++ tools/perf/util/sort.h | 1 + 4 files changed, 36 insertions(+)
tools/perf/ui/hist.c +17 -0
@@ -459,6 +459,23 @@ next: } } +void perf_hpp__reset_output_field (void ) +{ +struct perf_hpp_fmt *fmt, *tmp; + +/* reset output fields */ +perf_hpp__for_each_format_safe (fmt, tmp) { +list_del_init (&fmt->list); +list_del_init (&fmt->sort_list); + } + +/* reset sort keys */ +perf_hpp__for_each_sort_list_safe (fmt, tmp) { +list_del_init (&fmt->list); +list_del_init (&fmt->sort_list); + } +} +/* * See hists__fprintf to match the column widths */
tools/perf/util/hist.h +7 -0
@@ -174,9 +174,15 @@ extern struct list_head perf_hpp__sort_list;#define perf_hpp__for_each_format (format) \ list_for_each_entry(format, &perf_hpp__list, list) +#define perf_hpp__for_each_format_safe (format, tmp) \ + list_for_each_entry_safe(format, tmp, &perf_hpp__list, list) +#define perf_hpp__for_each_sort_list (format) \ list_for_each_entry(format, &perf_hpp__sort_list, sort_list) +#define perf_hpp__for_each_sort_list_safe (format, tmp) \ + list_for_each_entry_safe(format, tmp, &perf_hpp__sort_list, sort_list) +extern struct perf_hpp_fmt perf_hpp__format[];enum {
@@ -197,6 +203,7 @@ void perf_hpp__column_register(struct perf_hpp_fmt *format);void perf_hpp__column_enable (unsigned col);void perf_hpp__register_sort_field (struct perf_hpp_fmt *format);void perf_hpp__setup_output_field (void ); +void perf_hpp__reset_output_field (void );void perf_hpp__append_sort_keys (void );bool perf_hpp__is_sort_entry (struct perf_hpp_fmt *format);
tools/perf/util/sort.c +11 -0
@@ -1573,3 +1573,14 @@ int setup_sorting(void)return 0 ; } + +void reset_output_field (void ) +{ + sort__need_collapse =0 ; + sort__has_parent =0 ; + sort__has_sym =0 ; + sort__has_dso =0 ; + +reset_dimensions (); +perf_hpp__reset_output_field (); +}
tools/perf/util/sort.h +1 -0
@@ -194,6 +194,7 @@ extern struct list_head hist_entry__sort_list;int setup_sorting (void );int setup_output_field (void ); +void reset_output_field (void );extern int sort_dimension__add (const char *);void sort__setup_elide (FILE *fp);
Namhyung Kim
maintainerPATCH 19/20 perf tests: Factor out print_hists_*()
In reply to Namhyung KimThose print helper functions can be reused by later hist test cases so factor them out to a common location.
--- tools/perf/tests/hists_common.c | 57 +++++++++++++++++++++++++++++++++++++++++ tools/perf/tests/hists_common.h | 3 +++ tools/perf/tests/hists_filter.c | 37 ++++---------------------- tools/perf/tests/hists_link.c | 29 +-------------------- 4 files changed, 66 insertions(+), 60 deletions(-)
tools/perf/tests/hists_common.c +57 -0
@@ -146,3 +146,60 @@ out:machine__delete (machine);return NULL ; } + +void print_hists_in (struct hists *hists) +{ +int i =0 ; +struct rb_root *root; +struct rb_node *node; + +if (sort__need_collapse) + root = &hists->entries_collapsed; +else + root = hists->entries_in; + +pr_info ("----- %s --------\n" , __func__); + node =rb_first (root); +while (node) { +struct hist_entry *he; + + he = rb_entry(node, struct hist_entry, rb_node_in); + +if (!he->filtered) { +pr_info ("%2d: entry: %-8s [%-8s] %20s: period = %" PRIu64"\n" , + i,thread__comm_str (he->thread), + he->ms.map->dso->short_name, + he->ms.sym->name, he->stat.period); + } + + i++; + node =rb_next (node); + } +} + +void print_hists_out (struct hists *hists) +{ +int i =0 ; +struct rb_root *root; +struct rb_node *node; + + root = &hists->entries; + +pr_info ("----- %s --------\n" , __func__); + node =rb_first (root); +while (node) { +struct hist_entry *he; + + he = rb_entry(node, struct hist_entry, rb_node); + +if (!he->filtered) { +pr_info ("%2d: entry: %-8s [%-8s] %20s: period = %" PRIu64"\n" , + i,thread__comm_str (he->thread), + he->ms.map->dso->short_name, + he->ms.sym->name, he->stat.period); + } + + i++; + node =rb_next (node); + } +}
tools/perf/tests/hists_common.h +3 -0
@@ -41,4 +41,7 @@ struct machines;*/ struct machine *setup_fake_machine (struct machines *machines); +void print_hists_in (struct hists *hists); +void print_hists_out (struct hists *hists); +#endif /* __PERF_TESTS__HISTS_COMMON_H__ */
tools/perf/tests/hists_filter.c +5 -32
@@ -98,33 +98,6 @@ out:return TEST_FAIL ; } -static void print_hists (struct hists *hists) -{ -int i =0 ; -struct rb_root *root; -struct rb_node *node; - - root = &hists->entries; - -pr_info ("----- %s --------\n" , __func__); - node =rb_first (root); -while (node) { -struct hist_entry *he; - - he = rb_entry(node, struct hist_entry, rb_node); - -if (!he->filtered) { -pr_info ("%2d: entry: %-8s [%-8s] %20s: period = %" PRIu64"\n" , - i,thread__comm_str (he->thread), - he->ms.map->dso->short_name, - he->ms.sym->name, he->stat.period); - } - - i++; - node =rb_next (node); - } -} -int test__hists_filter (void ) {int err =TEST_FAIL ;
@@ -169,7 +142,7 @@ int test__hists_filter(void)if (verbose >2 ) {pr_info ("Normal histogram\n" ); -print_hists (hists); +print_hists_out (hists); } TEST_ASSERT_VAL("Invalid nr samples",
@@ -193,7 +166,7 @@ int test__hists_filter(void)if (verbose >2 ) {pr_info ("Histogram for thread filter\n" ); -print_hists (hists); +print_hists_out (hists); }/* normal stats should be invariant */
@@ -222,7 +195,7 @@ int test__hists_filter(void)if (verbose >2 ) {pr_info ("Histogram for dso filter\n" ); -print_hists (hists); +print_hists_out (hists); }/* normal stats should be invariant */
@@ -257,7 +230,7 @@ int test__hists_filter(void)if (verbose >2 ) {pr_info ("Histogram for symbol filter\n" ); -print_hists (hists); +print_hists_out (hists); }/* normal stats should be invariant */
@@ -284,7 +257,7 @@ int test__hists_filter(void)if (verbose >2 ) {pr_info ("Histogram for all filters\n" ); -print_hists (hists); +print_hists_out (hists); }/* normal stats should be invariant */
tools/perf/tests/hists_link.c +1 -28
@@ -268,33 +268,6 @@ static int validate_link(struct hists *leader, struct hists *other)return __validate_link (leader,0 ) ||__validate_link (other,1 ); } -static void print_hists (struct hists *hists) -{ -int i =0 ; -struct rb_root *root; -struct rb_node *node; - -if (sort__need_collapse) - root = &hists->entries_collapsed; -else - root = hists->entries_in; - -pr_info ("----- %s --------\n" , __func__); - node =rb_first (root); -while (node) { -struct hist_entry *he; - - he = rb_entry(node, struct hist_entry, rb_node_in); - -pr_info ("%2d: entry: %-8s [%-8s] %20s: period = %" PRIu64"\n" , - i,thread__comm_str (he->thread), he->ms.map->dso->short_name, - he->ms.sym->name, he->stat.period); - - i++; - node =rb_next (node); - } -} -int test__hists_link (void ) {int err =-1 ;
@@ -336,7 +309,7 @@ int test__hists_link(void)hists__collapse_resort (&evsel->hists,NULL );if (verbose >2 ) -print_hists (&evsel->hists); +print_hists_in (&evsel->hists); } first =perf_evlist__first (evlist);
Signature · 1 line
1.9.2
tip-bot for Namhyung Kim
merge bot[tip:perf/core] perf tests: Factor out print_hists_*()
perf tests: Factor out print_hists_*()
Commit-ID: 4e754e1c7fe02e6b104e61f7e06e9895527e8ad3 Gitweb: http://git.kernel.org/tip/4e754e1c7fe02e6b104e61f7e06e9895527e8ad3 Author: Namhyung Kim <[email protected]> AuthorDate: Mon, 12 May 2014 10:06:18 +0900 Committer: Jiri Olsa <[email protected]> CommitDate: Wed, 21 May 2014 11:45:37 +0200
perf tests: Factor out print_hists_*()
Those print helper functions can be reused by later hist test cases so factor them out to a common location.
--- tools/perf/tests/hists_common.c | 57 +++++++++++++++++++++++++++++++++++++++++ tools/perf/tests/hists_common.h | 3 +++ tools/perf/tests/hists_filter.c | 37 ++++---------------------- tools/perf/tests/hists_link.c | 29 +-------------------- 4 files changed, 66 insertions(+), 60 deletions(-)
tools/perf/tests/hists_common.c +57 -0
@@ -146,3 +146,60 @@ out:machine__delete (machine);return NULL ; } + +void print_hists_in (struct hists *hists) +{ +int i =0 ; +struct rb_root *root; +struct rb_node *node; + +if (sort__need_collapse) + root = &hists->entries_collapsed; +else + root = hists->entries_in; + +pr_info ("----- %s --------\n" , __func__); + node =rb_first (root); +while (node) { +struct hist_entry *he; + + he = rb_entry(node, struct hist_entry, rb_node_in); + +if (!he->filtered) { +pr_info ("%2d: entry: %-8s [%-8s] %20s: period = %" PRIu64"\n" , + i,thread__comm_str (he->thread), + he->ms.map->dso->short_name, + he->ms.sym->name, he->stat.period); + } + + i++; + node =rb_next (node); + } +} + +void print_hists_out (struct hists *hists) +{ +int i =0 ; +struct rb_root *root; +struct rb_node *node; + + root = &hists->entries; + +pr_info ("----- %s --------\n" , __func__); + node =rb_first (root); +while (node) { +struct hist_entry *he; + + he = rb_entry(node, struct hist_entry, rb_node); + +if (!he->filtered) { +pr_info ("%2d: entry: %-8s [%-8s] %20s: period = %" PRIu64"\n" , + i,thread__comm_str (he->thread), + he->ms.map->dso->short_name, + he->ms.sym->name, he->stat.period); + } + + i++; + node =rb_next (node); + } +}
tools/perf/tests/hists_common.h +3 -0
@@ -41,4 +41,7 @@ struct machines;*/ struct machine *setup_fake_machine (struct machines *machines); +void print_hists_in (struct hists *hists); +void print_hists_out (struct hists *hists); +#endif /* __PERF_TESTS__HISTS_COMMON_H__ */
tools/perf/tests/hists_filter.c +5 -32
@@ -98,33 +98,6 @@ out:return TEST_FAIL ; } -static void print_hists (struct hists *hists) -{ -int i =0 ; -struct rb_root *root; -struct rb_node *node; - - root = &hists->entries; - -pr_info ("----- %s --------\n" , __func__); - node =rb_first (root); -while (node) { -struct hist_entry *he; - - he = rb_entry(node, struct hist_entry, rb_node); - -if (!he->filtered) { -pr_info ("%2d: entry: %-8s [%-8s] %20s: period = %" PRIu64"\n" , - i,thread__comm_str (he->thread), - he->ms.map->dso->short_name, - he->ms.sym->name, he->stat.period); - } - - i++; - node =rb_next (node); - } -} -int test__hists_filter (void ) {int err =TEST_FAIL ;
@@ -169,7 +142,7 @@ int test__hists_filter(void)if (verbose >2 ) {pr_info ("Normal histogram\n" ); -print_hists (hists); +print_hists_out (hists); } TEST_ASSERT_VAL("Invalid nr samples",
@@ -193,7 +166,7 @@ int test__hists_filter(void)if (verbose >2 ) {pr_info ("Histogram for thread filter\n" ); -print_hists (hists); +print_hists_out (hists); }/* normal stats should be invariant */
@@ -222,7 +195,7 @@ int test__hists_filter(void)if (verbose >2 ) {pr_info ("Histogram for dso filter\n" ); -print_hists (hists); +print_hists_out (hists); }/* normal stats should be invariant */
@@ -257,7 +230,7 @@ int test__hists_filter(void)if (verbose >2 ) {pr_info ("Histogram for symbol filter\n" ); -print_hists (hists); +print_hists_out (hists); }/* normal stats should be invariant */
@@ -284,7 +257,7 @@ int test__hists_filter(void)if (verbose >2 ) {pr_info ("Histogram for all filters\n" ); -print_hists (hists); +print_hists_out (hists); }/* normal stats should be invariant */
tools/perf/tests/hists_link.c +1 -28
@@ -268,33 +268,6 @@ static int validate_link(struct hists *leader, struct hists *other)return __validate_link (leader,0 ) ||__validate_link (other,1 ); } -static void print_hists (struct hists *hists) -{ -int i =0 ; -struct rb_root *root; -struct rb_node *node; - -if (sort__need_collapse) - root = &hists->entries_collapsed; -else - root = hists->entries_in; - -pr_info ("----- %s --------\n" , __func__); - node =rb_first (root); -while (node) { -struct hist_entry *he; - - he = rb_entry(node, struct hist_entry, rb_node_in); - -pr_info ("%2d: entry: %-8s [%-8s] %20s: period = %" PRIu64"\n" , - i,thread__comm_str (he->thread), he->ms.map->dso->short_name, - he->ms.sym->name, he->stat.period); - - i++; - node =rb_next (node); - } -} -int test__hists_link (void ) {int err =-1 ;
@@ -336,7 +309,7 @@ int test__hists_link(void)hists__collapse_resort (&evsel->hists,NULL );if (verbose >2 ) -print_hists (&evsel->hists); +print_hists_in (&evsel->hists); } first =perf_evlist__first (evlist);
Namhyung Kim
maintainerPATCH 20/20 perf tests: Add a testcase for histogram output sorting
In reply to Namhyung KimWith new output fields option, its internal implementation was changed so add a new testcase to verify whether it breaks things.
--- tools/perf/Makefile.perf | 1 + tools/perf/tests/builtin-test.c | 4 + tools/perf/tests/hists_common.c | 4 +- tools/perf/tests/hists_filter.c | 1 + tools/perf/tests/hists_link.c | 1 + tools/perf/tests/hists_output.c | 618 ++++++++++++++++++++++++++++++++++++++++ tools/perf/tests/tests.h | 1 + 7 files changed, 628 insertions(+), 2 deletions(-) create mode 100644 tools/perf/tests/hists_output.c
tools/perf/Makefile.perf +1 -0
@@ -399,6 +399,7 @@ LIB_OBJS += $(OUTPUT)tests/pmu.o LIB_OBJS += $(OUTPUT)tests/hists_common.o LIB_OBJS += $(OUTPUT)tests/hists_link.o LIB_OBJS += $(OUTPUT)tests/hists_filter.o +LIB_OBJS += $(OUTPUT)tests/hists_output.o LIB_OBJS += $(OUTPUT)tests/python-use.o LIB_OBJS += $(OUTPUT)tests/bp_signal.o LIB_OBJS += $(OUTPUT)tests/bp_signal_overflow.o
tools/perf/tests/builtin-test.c +4 -0
@@ -136,6 +136,10 @@ static struct test { .func = test__thread_mg_share, }, { + .desc = "Test output sorting of hist entries", + .func = test__hists_output, + }, + { .func = NULL, }, };
tools/perf/tests/hists_common.c +2 -2
@@ -193,8 +193,8 @@ void print_hists_out(struct hists *hists) he = rb_entry(node, struct hist_entry, rb_node);if (!he->filtered) { -pr_info ("%2d: entry: %-8s [%-8s] %20s: period = %" PRIu64"\n" , - i,thread__comm_str (he->thread), +pr_info ("%2d: entry: %8s:%5d [%-8s] %20s: period = %" PRIu64"\n" , + i,thread__comm_str (he->thread), he->thread->tid, he->ms.map->dso->short_name, he->ms.sym->name, he->stat.period); }
tools/perf/tests/hists_filter.c +1 -0
@@ -283,6 +283,7 @@ int test__hists_filter(void) out:/* tear down everything */ perf_evlist__delete (evlist); +reset_output_field ();machines__exit (&machines);return err;
tools/perf/tests/hists_link.c +1 -0
@@ -332,6 +332,7 @@ int test__hists_link(void) out:/* tear down everything */ perf_evlist__delete (evlist); +reset_output_field ();machines__exit (&machines);return err;
tools/perf/tests/hists_output.c new file +618 -0
618 lines not on this page · raw message
tools/perf/tests/tests.h +1 -0
@@ -44,6 +44,7 @@ int test__dwarf_unwind(void);int test__hists_filter (void );int test__mmap_thread_lookup (void );int test__thread_mg_share (void ); +int test__hists_output (void );#if defined(__x86_64__) || defined(__i386__)#ifdef HAVE_DWARF_UNWIND_SUPPORT
Signature · 1 line
1.9.2
tip-bot for Namhyung Kim
merge bot[tip:perf/core] perf tests: Add a testcase for histogram output sorting
perf tests: Add a testcase for histogram output sorting
Commit-ID: f21d1815295ee79ce0767cb08d6f3ffa3a3b5cfe Gitweb: http://git.kernel.org/tip/f21d1815295ee79ce0767cb08d6f3ffa3a3b5cfe Author: Namhyung Kim <[email protected]> AuthorDate: Mon, 12 May 2014 14:43:18 +0900 Committer: Jiri Olsa <[email protected]> CommitDate: Wed, 21 May 2014 11:45:37 +0200
perf tests: Add a testcase for histogram output sorting
With new output fields option, its internal implementation was changed so add a new testcase to verify whether it breaks things.
--- tools/perf/Makefile.perf | 1 + tools/perf/tests/builtin-test.c | 4 + tools/perf/tests/hists_common.c | 4 +- tools/perf/tests/hists_filter.c | 1 + tools/perf/tests/hists_link.c | 1 + tools/perf/tests/hists_output.c | 618 ++++++++++++++++++++++++++++++++++++++++ tools/perf/tests/tests.h | 1 + 7 files changed, 628 insertions(+), 2 deletions(-)
tools/perf/Makefile.perf +1 -0
@@ -399,6 +399,7 @@ LIB_OBJS += $(OUTPUT)tests/pmu.o LIB_OBJS += $(OUTPUT)tests/hists_common.o LIB_OBJS += $(OUTPUT)tests/hists_link.o LIB_OBJS += $(OUTPUT)tests/hists_filter.o +LIB_OBJS += $(OUTPUT)tests/hists_output.o LIB_OBJS += $(OUTPUT)tests/python-use.o LIB_OBJS += $(OUTPUT)tests/bp_signal.o LIB_OBJS += $(OUTPUT)tests/bp_signal_overflow.o
tools/perf/tests/builtin-test.c +4 -0
@@ -136,6 +136,10 @@ static struct test { .func = test__thread_mg_share, }, { + .desc = "Test output sorting of hist entries", + .func = test__hists_output, + }, + { .func = NULL, }, };
tools/perf/tests/hists_common.c +2 -2
@@ -193,8 +193,8 @@ void print_hists_out(struct hists *hists) he = rb_entry(node, struct hist_entry, rb_node);if (!he->filtered) { -pr_info ("%2d: entry: %-8s [%-8s] %20s: period = %" PRIu64"\n" , - i,thread__comm_str (he->thread), +pr_info ("%2d: entry: %8s:%5d [%-8s] %20s: period = %" PRIu64"\n" , + i,thread__comm_str (he->thread), he->thread->tid, he->ms.map->dso->short_name, he->ms.sym->name, he->stat.period); }
tools/perf/tests/hists_filter.c +1 -0
@@ -283,6 +283,7 @@ int test__hists_filter(void) out:/* tear down everything */ perf_evlist__delete (evlist); +reset_output_field ();machines__exit (&machines);return err;
tools/perf/tests/hists_link.c +1 -0
@@ -332,6 +332,7 @@ int test__hists_link(void) out:/* tear down everything */ perf_evlist__delete (evlist); +reset_output_field ();machines__exit (&machines);return err;
tools/perf/tests/hists_output.c new file +618 -0
618 lines not on this page · raw message
tools/perf/tests/tests.h +1 -0
@@ -44,6 +44,7 @@ int test__dwarf_unwind(void);int test__hists_filter (void );int test__mmap_thread_lookup (void );int test__thread_mg_share (void ); +int test__hists_output (void );#if defined(__x86_64__) || defined(__i386__) || defined(__arm__)#ifdef HAVE_DWARF_UNWIND_SUPPORT