Commit d3a72fd8 authored by Namhyung Kim's avatar Namhyung Kim Committed by Arnaldo Carvalho de Melo

perf report: Fix indentation of dynamic entries in hierarchy

When dynamic entries are used in the hierarchy mode with multiple
events, the output might not be aligned properly.  In the hierarchy
mode, the each sort column is indented using total number of sort keys.
So it keeps track of number of sort keys when adding them.  However
a dynamic sort key can be added more than once when multiple events have
same field names.  This results in unnecessarily long indentation in the
output.

For example perf kmem records following events:

  $ perf evlist --trace-fields -i perf.data.kmem
  kmem:kmalloc: trace_fields: call_site,ptr,bytes_req,bytes_alloc,gfp_flags
  kmem:kmalloc_node: trace_fields: call_site,ptr,bytes_req,bytes_alloc,gfp_flags,node
  kmem:kfree: trace_fields: call_site,ptr
  kmem:kmem_cache_alloc: trace_fields: call_site,ptr,bytes_req,bytes_alloc,gfp_flags
  kmem:kmem_cache_alloc_node: trace_fields: call_site,ptr,bytes_req,bytes_alloc,gfp_flags,node
  kmem:kmem_cache_free: trace_fields: call_site,ptr
  kmem:mm_page_alloc: trace_fields: page,order,gfp_flags,migratetype
  kmem:mm_page_free: trace_fields: page,order

As you can see, many field names shared between kmem events.  So adding
'ptr' dynamic sort key alone will set nr_sort_keys to 6.  And this adds
many unnecessary spaces between columns.

Before:

  $ perf report -i perf.data.kmem --hierarchy -s ptr -g none --stdio
  ...
  #                Overhead                 ptr
  # .......................  ...................................
  #
      99.89%                 0xffff8803ffb79720
       0.06%                 0xffff8803d228a000
       0.03%                 0xffff8803f7678f00
       0.00%                 0xffff880401dc5280
       0.00%                 0xffff880406172380
       0.00%                 0xffff8803ffac3a00
       0.00%                 0xffff8803ffac1600

After:

  # Overhead                 ptr
  # ........  ....................
  #
      99.89%  0xffff8803ffb79720
       0.06%  0xffff8803d228a000
       0.03%  0xffff8803f7678f00
       0.00%  0xffff880401dc5280
       0.00%  0xffff880406172380
       0.00%  0xffff8803ffac3a00
       0.00%  0xffff8803ffac1600
Signed-off-by: default avatarNamhyung Kim <namhyung@kernel.org>
Tested-by: default avatarArnaldo Carvalho de Melo <acme@redhat.com>
Acked-by: default avatarJiri Olsa <jolsa@kernel.org>
Cc: Andi Kleen <andi@firstfloor.org>
Cc: David Ahern <dsahern@gmail.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Cc: Wang Nan <wangnan0@huawei.com>
Link: http://lkml.kernel.org/r/1456512767-1164-2-git-send-email-namhyung@kernel.orgSigned-off-by: default avatarArnaldo Carvalho de Melo <acme@redhat.com>
parent 84b6ee8e
...@@ -1547,7 +1547,7 @@ static int hists_browser__scnprintf_hierarchy_headers(struct hist_browser *brows ...@@ -1547,7 +1547,7 @@ static int hists_browser__scnprintf_hierarchy_headers(struct hist_browser *brows
struct perf_hpp_fmt *fmt; struct perf_hpp_fmt *fmt;
size_t ret = 0; size_t ret = 0;
int column = 0; int column = 0;
int nr_sort_keys = hists->hpp_list->nr_sort_keys; int nr_sort_keys = hists->nr_sort_keys;
bool first = true; bool first = true;
ret = scnprintf(buf, size, " "); ret = scnprintf(buf, size, " ");
...@@ -1632,7 +1632,7 @@ static unsigned int hist_browser__refresh(struct ui_browser *browser) ...@@ -1632,7 +1632,7 @@ static unsigned int hist_browser__refresh(struct ui_browser *browser)
u16 header_offset = 0; u16 header_offset = 0;
struct rb_node *nd; struct rb_node *nd;
struct hist_browser *hb = container_of(browser, struct hist_browser, b); struct hist_browser *hb = container_of(browser, struct hist_browser, b);
int nr_sort = hb->hists->hpp_list->nr_sort_keys; int nr_sort = hb->hists->nr_sort_keys;
if (hb->show_headers) { if (hb->show_headers) {
hist_browser__show_headers(hb); hist_browser__show_headers(hb);
...@@ -1969,7 +1969,7 @@ static int hist_browser__fprintf(struct hist_browser *browser, FILE *fp) ...@@ -1969,7 +1969,7 @@ static int hist_browser__fprintf(struct hist_browser *browser, FILE *fp)
struct rb_node *nd = hists__filter_entries(rb_first(browser->b.entries), struct rb_node *nd = hists__filter_entries(rb_first(browser->b.entries),
browser->min_pcnt); browser->min_pcnt);
int printed = 0; int printed = 0;
int nr_sort = browser->hists->hpp_list->nr_sort_keys; int nr_sort = browser->hists->nr_sort_keys;
while (nd) { while (nd) {
struct hist_entry *h = rb_entry(nd, struct hist_entry, rb_node); struct hist_entry *h = rb_entry(nd, struct hist_entry, rb_node);
......
...@@ -495,7 +495,7 @@ static int hist_entry__fprintf(struct hist_entry *he, size_t size, ...@@ -495,7 +495,7 @@ static int hist_entry__fprintf(struct hist_entry *he, size_t size,
size = hpp.size = bfsz; size = hpp.size = bfsz;
if (symbol_conf.report_hierarchy) { if (symbol_conf.report_hierarchy) {
int nr_sort = hists->hpp_list->nr_sort_keys; int nr_sort = hists->nr_sort_keys;
return hist_entry__hierarchy_fprintf(he, &hpp, nr_sort, return hist_entry__hierarchy_fprintf(he, &hpp, nr_sort,
hists, fp); hists, fp);
...@@ -529,7 +529,7 @@ static int print_hierarchy_header(struct hists *hists, struct perf_hpp *hpp, ...@@ -529,7 +529,7 @@ static int print_hierarchy_header(struct hists *hists, struct perf_hpp *hpp,
unsigned header_width = 0; unsigned header_width = 0;
struct perf_hpp_fmt *fmt; struct perf_hpp_fmt *fmt;
nr_sort = hists->hpp_list->nr_sort_keys; nr_sort = hists->nr_sort_keys;
/* preserve max indent depth for column headers */ /* preserve max indent depth for column headers */
print_hierarchy_indent(sep, nr_sort, spaces, fp); print_hierarchy_indent(sep, nr_sort, spaces, fp);
...@@ -728,7 +728,7 @@ size_t hists__fprintf(struct hists *hists, bool show_header, int max_rows, ...@@ -728,7 +728,7 @@ size_t hists__fprintf(struct hists *hists, bool show_header, int max_rows,
* display "no entry >= x.xx%" message. * display "no entry >= x.xx%" message.
*/ */
if (!h->leaf && !hist_entry__has_hierarchy_children(h, min_pcnt)) { if (!h->leaf && !hist_entry__has_hierarchy_children(h, min_pcnt)) {
int nr_sort = hists->hpp_list->nr_sort_keys; int nr_sort = hists->nr_sort_keys;
print_hierarchy_indent(sep, nr_sort + h->depth + 1, spaces, fp); print_hierarchy_indent(sep, nr_sort + h->depth + 1, spaces, fp);
fprintf(fp, "%*sno entry >= %.2f%%\n", indent, "", min_pcnt); fprintf(fp, "%*sno entry >= %.2f%%\n", indent, "", min_pcnt);
......
...@@ -78,6 +78,7 @@ struct hists { ...@@ -78,6 +78,7 @@ struct hists {
u16 col_len[HISTC_NR_COLS]; u16 col_len[HISTC_NR_COLS];
int socket_filter; int socket_filter;
struct perf_hpp_list *hpp_list; struct perf_hpp_list *hpp_list;
int nr_sort_keys;
}; };
struct hist_entry_iter; struct hist_entry_iter;
......
...@@ -2633,6 +2633,9 @@ static int __setup_output_field(void) ...@@ -2633,6 +2633,9 @@ static int __setup_output_field(void)
int setup_sorting(struct perf_evlist *evlist) int setup_sorting(struct perf_evlist *evlist)
{ {
int err; int err;
struct hists *hists;
struct perf_evsel *evsel;
struct perf_hpp_fmt *fmt;
err = __setup_sorting(evlist); err = __setup_sorting(evlist);
if (err < 0) if (err < 0)
...@@ -2644,6 +2647,22 @@ int setup_sorting(struct perf_evlist *evlist) ...@@ -2644,6 +2647,22 @@ int setup_sorting(struct perf_evlist *evlist)
return err; return err;
} }
evlist__for_each(evlist, evsel) {
hists = evsel__hists(evsel);
hists->nr_sort_keys = perf_hpp_list.nr_sort_keys;
/*
* If dynamic entries were used, it might add multiple
* entries to each evsel for a single field name. Set
* actual number of sort keys for each hists.
*/
perf_hpp_list__for_each_sort_list(&perf_hpp_list, fmt) {
if (perf_hpp__is_dynamic_entry(fmt) &&
!perf_hpp__defined_dynamic_entry(fmt, hists))
hists->nr_sort_keys--;
}
}
reset_dimensions(); reset_dimensions();
/* /*
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment