From 512ae1bd6acb811c72e44e2540099eccd31f773d Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Tue, 18 Mar 2014 11:31:39 +0900 Subject: 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. Signed-off-by: Namhyung Kim Cc: Stephane Eranian Link: http://lkml.kernel.org/r/1400480762-22852-10-git-send-email-namhyung@kernel.org Signed-off-by: Jiri Olsa --- tools/perf/util/sort.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'tools/perf/util/sort.h') diff --git a/tools/perf/util/sort.h b/tools/perf/util/sort.h index 43e5ff42a609..1a7295255dc9 100644 --- a/tools/perf/util/sort.h +++ b/tools/perf/util/sort.h @@ -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 { -- cgit v1.2.3 From a7d945bc91602f916d2d0c794c179d9a784859e7 Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Tue, 4 Mar 2014 10:46:34 +0900 Subject: 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. Requested-by: Ingo Molnar Signed-off-by: Namhyung Kim Acked-by: Ingo Molnar Link: http://lkml.kernel.org/r/1400480762-22852-12-git-send-email-namhyung@kernel.org Signed-off-by: Jiri Olsa --- 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(-) (limited to 'tools/perf/util/sort.h') diff --git a/tools/perf/Documentation/perf-report.txt b/tools/perf/Documentation/perf-report.txt index 9babe915b6c4..a1b5185402d5 100644 --- a/tools/perf/Documentation/perf-report.txt +++ b/tools/perf/Documentation/perf-report.txt @@ -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=:: A regex filter to identify parent. The parent is a caller of this diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c index c4dab7acbdbb..bc0eec1ce4be 100644 --- a/tools/perf/builtin-report.c +++ b/tools/perf/builtin-report.c @@ -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; diff --git a/tools/perf/ui/hist.c b/tools/perf/ui/hist.c index 24116a48298f..b114c6668865 100644 --- a/tools/perf/ui/hist.c +++ b/tools/perf/ui/hist.c @@ -355,6 +355,12 @@ void perf_hpp__init(void) INIT_LIST_HEAD(&fmt->sort_list); } + /* + * If user specified field order, no need to setup default fields. + */ + if (field_order) + return; + perf_hpp__column_enable(PERF_HPP__OVERHEAD); if (symbol_conf.show_cpu_utilization) { @@ -377,8 +383,6 @@ void perf_hpp__init(void) 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) @@ -403,8 +407,55 @@ void perf_hpp__setup_output_field(void) /* append sort keys to output field */ perf_hpp__for_each_sort_list(fmt) { - if (list_empty(&fmt->list)) - perf_hpp__column_register(fmt); + if (!list_empty(&fmt->list)) + continue; + + /* + * sort entry fields are dynamically created, + * so they can share a same sort key even though + * the list is empty. + */ + if (perf_hpp__is_sort_entry(fmt)) { + struct perf_hpp_fmt *pos; + + perf_hpp__for_each_format(pos) { + if (perf_hpp__same_sort_entry(pos, fmt)) + goto next; + } + } + + perf_hpp__column_register(fmt); +next: + continue; + } +} + +void perf_hpp__append_sort_keys(void) +{ + struct perf_hpp_fmt *fmt; + + /* append output fields to sort keys */ + perf_hpp__for_each_format(fmt) { + if (!list_empty(&fmt->sort_list)) + continue; + + /* + * sort entry fields are dynamically created, + * so they can share a same sort key even though + * the list is empty. + */ + if (perf_hpp__is_sort_entry(fmt)) { + struct perf_hpp_fmt *pos; + + perf_hpp__for_each_sort_list(pos) { + if (perf_hpp__same_sort_entry(pos, fmt)) + goto next; + } + } + + perf_hpp__register_sort_field(fmt); +next: + continue; } } diff --git a/tools/perf/util/hist.h b/tools/perf/util/hist.h index 76bb72e4302b..f3713b79742d 100644 --- a/tools/perf/util/hist.h +++ b/tools/perf/util/hist.h @@ -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); diff --git a/tools/perf/util/sort.c b/tools/perf/util/sort.c index d64c1e58f1b1..b748b02fcb78 100644 --- a/tools/perf/util/sort.c +++ b/tools/perf/util/sort.c @@ -13,6 +13,7 @@ const char default_mem_sort_order[] = "local_weight,mem,sym,dso,symbol_daddr,dso const char default_top_sort_order[] = "dso,symbol"; const char default_diff_sort_order[] = "dso,symbol"; const char *sort_order; +const char *field_order; regex_t ignore_callees_regex; int have_ignore_callees = 0; int sort__need_collapse = 0; @@ -1057,6 +1058,20 @@ struct hpp_sort_entry { struct sort_entry *se; }; +bool perf_hpp__same_sort_entry(struct perf_hpp_fmt *a, struct perf_hpp_fmt *b) +{ + struct hpp_sort_entry *hse_a; + struct hpp_sort_entry *hse_b; + + if (!perf_hpp__is_sort_entry(a) || !perf_hpp__is_sort_entry(b)) + return false; + + hse_a = container_of(a, struct hpp_sort_entry, hpp); + hse_b = container_of(b, struct hpp_sort_entry, hpp); + + return hse_a->se == hse_b->se; +} + static int __sort__hpp_header(struct perf_hpp_fmt *fmt, struct perf_hpp *hpp, struct perf_evsel *evsel) { @@ -1092,14 +1107,15 @@ static int __sort__hpp_entry(struct perf_hpp_fmt *fmt, struct perf_hpp *hpp, return hse->se->se_snprintf(he, hpp->buf, hpp->size, len); } -static int __sort_dimension__add_hpp(struct sort_dimension *sd) +static struct hpp_sort_entry * +__sort_dimension__alloc_hpp(struct sort_dimension *sd) { struct hpp_sort_entry *hse; hse = malloc(sizeof(*hse)); if (hse == NULL) { pr_err("Memory allocation failed\n"); - return -1; + return NULL; } hse->se = sd->entry; @@ -1115,16 +1131,42 @@ static int __sort_dimension__add_hpp(struct sort_dimension *sd) INIT_LIST_HEAD(&hse->hpp.list); INIT_LIST_HEAD(&hse->hpp.sort_list); + return hse; +} + +bool perf_hpp__is_sort_entry(struct perf_hpp_fmt *format) +{ + return format->header == __sort__hpp_header; +} + +static int __sort_dimension__add_hpp_sort(struct sort_dimension *sd) +{ + struct hpp_sort_entry *hse = __sort_dimension__alloc_hpp(sd); + + if (hse == NULL) + return -1; + perf_hpp__register_sort_field(&hse->hpp); return 0; } +static int __sort_dimension__add_hpp_output(struct sort_dimension *sd) +{ + struct hpp_sort_entry *hse = __sort_dimension__alloc_hpp(sd); + + if (hse == NULL) + return -1; + + perf_hpp__column_register(&hse->hpp); + return 0; +} + static int __sort_dimension__add(struct sort_dimension *sd, enum sort_type idx) { if (sd->taken) return 0; - if (__sort_dimension__add_hpp(sd) < 0) + if (__sort_dimension__add_hpp_sort(sd) < 0) return -1; if (sd->entry->se_collapse) @@ -1149,6 +1191,28 @@ static int __hpp_dimension__add(struct hpp_dimension *hd) return 0; } +static int __sort_dimension__add_output(struct sort_dimension *sd) +{ + if (sd->taken) + return 0; + + if (__sort_dimension__add_hpp_output(sd) < 0) + return -1; + + sd->taken = 1; + return 0; +} + +static int __hpp_dimension__add_output(struct hpp_dimension *hd) +{ + if (!hd->taken) { + hd->taken = 1; + + perf_hpp__column_register(hd->fmt); + } + return 0; +} + int sort_dimension__add(const char *tok) { unsigned int i; @@ -1237,14 +1301,23 @@ static const char *get_default_sort_order(void) return default_sort_orders[sort__mode]; } -int setup_sorting(void) +static int __setup_sorting(void) { char *tmp, *tok, *str; const char *sort_keys = sort_order; int ret = 0; - if (sort_keys == NULL) + if (sort_keys == NULL) { + if (field_order) { + /* + * If user specified field order but no sort order, + * we'll honor it and not add default sort orders. + */ + return 0; + } + sort_keys = get_default_sort_order(); + } str = strdup(sort_keys); if (str == NULL) { @@ -1331,3 +1404,129 @@ void sort__setup_elide(FILE *output) list_for_each_entry(se, &hist_entry__sort_list, list) se->elide = false; } + +static int output_field_add(char *tok) +{ + unsigned int i; + + for (i = 0; i < ARRAY_SIZE(common_sort_dimensions); i++) { + struct sort_dimension *sd = &common_sort_dimensions[i]; + + if (strncasecmp(tok, sd->name, strlen(tok))) + continue; + + return __sort_dimension__add_output(sd); + } + + 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_output(hd); + } + + for (i = 0; i < ARRAY_SIZE(bstack_sort_dimensions); i++) { + struct sort_dimension *sd = &bstack_sort_dimensions[i]; + + if (strncasecmp(tok, sd->name, strlen(tok))) + continue; + + return __sort_dimension__add_output(sd); + } + + for (i = 0; i < ARRAY_SIZE(memory_sort_dimensions); i++) { + struct sort_dimension *sd = &memory_sort_dimensions[i]; + + if (strncasecmp(tok, sd->name, strlen(tok))) + continue; + + return __sort_dimension__add_output(sd); + } + + return -ESRCH; +} + +static void reset_dimensions(void) +{ + unsigned int i; + + for (i = 0; i < ARRAY_SIZE(common_sort_dimensions); i++) + common_sort_dimensions[i].taken = 0; + + for (i = 0; i < ARRAY_SIZE(hpp_sort_dimensions); i++) + hpp_sort_dimensions[i].taken = 0; + + for (i = 0; i < ARRAY_SIZE(bstack_sort_dimensions); i++) + bstack_sort_dimensions[i].taken = 0; + + for (i = 0; i < ARRAY_SIZE(memory_sort_dimensions); i++) + memory_sort_dimensions[i].taken = 0; +} + +static int __setup_output_field(void) +{ + char *tmp, *tok, *str; + int ret = 0; + + if (field_order == NULL) + return 0; + + reset_dimensions(); + + str = strdup(field_order); + if (str == NULL) { + error("Not enough memory to setup output fields"); + return -ENOMEM; + } + + for (tok = strtok_r(str, ", ", &tmp); + tok; tok = strtok_r(NULL, ", ", &tmp)) { + ret = output_field_add(tok); + if (ret == -EINVAL) { + error("Invalid --fields key: `%s'", tok); + break; + } else if (ret == -ESRCH) { + error("Unknown --fields key: `%s'", tok); + break; + } + } + + free(str); + return ret; +} + +int setup_sorting(void) +{ + int err; + + err = __setup_sorting(); + if (err < 0) + return err; + + if (parent_pattern != default_parent_pattern) { + err = sort_dimension__add("parent"); + if (err < 0) + return err; + } + + reset_dimensions(); + + /* + * perf diff doesn't use default hpp output fields. + */ + if (sort__mode != SORT_MODE__DIFF) + perf_hpp__init(); + + err = __setup_output_field(); + if (err < 0) + return err; + + /* copy sort keys to output fields */ + perf_hpp__setup_output_field(); + /* and then copy output fields to sort keys */ + perf_hpp__append_sort_keys(); + + return 0; +} diff --git a/tools/perf/util/sort.h b/tools/perf/util/sort.h index 1a7295255dc9..89e5057ca378 100644 --- a/tools/perf/util/sort.h +++ b/tools/perf/util/sort.h @@ -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); -- cgit v1.2.3 From 202e7a6d16127323d03e912d7844aa0d614c315e Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Tue, 4 Mar 2014 11:01:41 +0900 Subject: 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. Signed-off-by: Namhyung Kim Acked-by: Ingo Molnar Link: http://lkml.kernel.org/r/1400480762-22852-13-git-send-email-namhyung@kernel.org Signed-off-by: Jiri Olsa --- tools/perf/util/sort.c | 27 ++++++++++++++++++++++----- tools/perf/util/sort.h | 1 + 2 files changed, 23 insertions(+), 5 deletions(-) (limited to 'tools/perf/util/sort.h') diff --git a/tools/perf/util/sort.c b/tools/perf/util/sort.c index b748b02fcb78..5414ba541e47 100644 --- a/tools/perf/util/sort.c +++ b/tools/perf/util/sort.c @@ -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); diff --git a/tools/perf/util/sort.h b/tools/perf/util/sort.h index 89e5057ca378..f5a831c3d0fb 100644 --- a/tools/perf/util/sort.h +++ b/tools/perf/util/sort.h @@ -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; -- cgit v1.2.3 From 1c89fe9b0447f0ce393325e51911f8073432b7b4 Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Wed, 7 May 2014 18:42:24 +0900 Subject: 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. Signed-off-by: Namhyung Kim Link: http://lkml.kernel.org/r/1400480762-22852-19-git-send-email-namhyung@kernel.org Signed-off-by: Jiri Olsa --- 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(+) (limited to 'tools/perf/util/sort.h') diff --git a/tools/perf/ui/hist.c b/tools/perf/ui/hist.c index 61cf31e094f3..4484f5bd1b14 100644 --- a/tools/perf/ui/hist.c +++ b/tools/perf/ui/hist.c @@ -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 */ diff --git a/tools/perf/util/hist.h b/tools/perf/util/hist.h index 034db761630e..a8418d19808d 100644 --- a/tools/perf/util/hist.h +++ b/tools/perf/util/hist.h @@ -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); diff --git a/tools/perf/util/sort.c b/tools/perf/util/sort.c index d9132069d3b1..901b9bece2ee 100644 --- a/tools/perf/util/sort.c +++ b/tools/perf/util/sort.c @@ -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(); +} diff --git a/tools/perf/util/sort.h b/tools/perf/util/sort.h index f5a831c3d0fb..5f38d925e92f 100644 --- a/tools/perf/util/sort.h +++ b/tools/perf/util/sort.h @@ -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); -- cgit v1.2.3