perf tools: Skip dynamic fields not defined for current event
When there are multiple events, each dynamic sort key is defined just
for one event. In this case other events will always show "N/A" for
those fields. But they are meaningless and consume precious screen
width.
Let's skip those undefined dynamic fields.
$ perf record -e kmem:kmalloc,kmem:kfree -a sleep 1
$ perf report -s 'comm,kmalloc.*' --stdio
# To display the perf.data header info, please use --header/--header-only options.
#
#
# Total Lost Samples: 0
#
# Samples: 20K of event 'kmem:kmalloc'
# Event count (approx.): 20533
#
# Overhead Command call_site ptr bytes_req bytes_alloc gfp_flags
# ........ ....... .................. .................. ......... ........... ...................
#
99.89% perf ffffffffa01d4396 0xffff8803ffb79720 96 96 GFP_NOFS|GFP_ZERO
0.06% sleep ffffffff8114e1cd 0xffff8803d228a000 4096 4096 GFP_KERNEL
0.03% perf ffffffff811d6ae6 0xffff8803f7678f00 240 256 GFP_KERNEL|GFP_ZERO
0.00% perf ffffffff812263c1 0xffff880406172380 128 128 GFP_KERNEL
0.00% perf ffffffff812264b9 0xffff8803ffac1600 504 512 GFP_KERNEL
0.00% perf ffffffff81226634 0xffff880401dc5280 28 32 GFP_KERNEL
0.00% sleep ffffffff81226da9 0xffff8803ffac3a00 392 512 GFP_KERNEL
# Samples: 20K of event 'kmem:kfree'
# Event count (approx.): 20597
#
# Overhead Command
# ........ ..............
#
99.63% perf
0.14% sleep
0.11% irq/36-iwlwifi
0.11% kworker/u16:0
0.01% Xorg
0.00% firefox
Signed-off-by: Namhyung Kim <namhyung@kernel.org>
Acked-by: Jiri Olsa <jolsa@kernel.org>
Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Andi Kleen <andi@firstfloor.org>
Cc: David Ahern <dsahern@gmail.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Steven Rostedt <rostedt@goodmis.org>
Cc: Wang Nan <wangnan0@huawei.com>
Link: http://lkml.kernel.org/r/1450804030-29193-12-git-send-email-namhyung@kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
diff --git a/tools/perf/ui/browsers/hists.c b/tools/perf/ui/browsers/hists.c
index ec33196..901d481 100644
--- a/tools/perf/ui/browsers/hists.c
+++ b/tools/perf/ui/browsers/hists.c
@@ -1041,7 +1041,8 @@
hist_browser__gotorc(browser, row, 0);
perf_hpp__for_each_format(fmt) {
- if (perf_hpp__should_skip(fmt) || column++ < browser->b.horiz_scroll)
+ if (perf_hpp__should_skip(fmt, entry->hists) ||
+ column++ < browser->b.horiz_scroll)
continue;
if (current_entry && browser->b.navkeypressed) {
@@ -1144,7 +1145,7 @@
}
perf_hpp__for_each_format(fmt) {
- if (perf_hpp__should_skip(fmt) || column++ < browser->b.horiz_scroll)
+ if (perf_hpp__should_skip(fmt, hists) || column++ < browser->b.horiz_scroll)
continue;
ret = fmt->header(fmt, &dummy_hpp, hists_to_evsel(hists));
@@ -1414,7 +1415,7 @@
printed += fprintf(fp, "%c ", folded_sign);
perf_hpp__for_each_format(fmt) {
- if (perf_hpp__should_skip(fmt))
+ if (perf_hpp__should_skip(fmt, he->hists))
continue;
if (!first) {
diff --git a/tools/perf/ui/gtk/hists.c b/tools/perf/ui/gtk/hists.c
index 4677172..0f8dcfd 100644
--- a/tools/perf/ui/gtk/hists.c
+++ b/tools/perf/ui/gtk/hists.c
@@ -318,7 +318,7 @@
col_idx = 0;
perf_hpp__for_each_format(fmt) {
- if (perf_hpp__should_skip(fmt))
+ if (perf_hpp__should_skip(fmt, hists))
continue;
/*
@@ -368,7 +368,7 @@
col_idx = 0;
perf_hpp__for_each_format(fmt) {
- if (perf_hpp__should_skip(fmt))
+ if (perf_hpp__should_skip(fmt, h->hists))
continue;
if (fmt->color)
diff --git a/tools/perf/ui/hist.c b/tools/perf/ui/hist.c
index 5029ba2..8263c0e 100644
--- a/tools/perf/ui/hist.c
+++ b/tools/perf/ui/hist.c
@@ -619,7 +619,7 @@
struct perf_hpp dummy_hpp;
perf_hpp__for_each_format(fmt) {
- if (perf_hpp__should_skip(fmt))
+ if (perf_hpp__should_skip(fmt, hists))
continue;
if (first)
diff --git a/tools/perf/ui/stdio/hist.c b/tools/perf/ui/stdio/hist.c
index 7ebc661..387110d 100644
--- a/tools/perf/ui/stdio/hist.c
+++ b/tools/perf/ui/stdio/hist.c
@@ -385,7 +385,7 @@
return 0;
perf_hpp__for_each_format(fmt) {
- if (perf_hpp__should_skip(fmt))
+ if (perf_hpp__should_skip(fmt, he->hists))
continue;
/*
@@ -464,7 +464,7 @@
fprintf(fp, "# ");
perf_hpp__for_each_format(fmt) {
- if (perf_hpp__should_skip(fmt))
+ if (perf_hpp__should_skip(fmt, hists))
continue;
if (!first)
@@ -490,7 +490,7 @@
perf_hpp__for_each_format(fmt) {
unsigned int i;
- if (perf_hpp__should_skip(fmt))
+ if (perf_hpp__should_skip(fmt, hists))
continue;
if (!first)
diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c
index fdb97e1..afc9b8f 100644
--- a/tools/perf/util/hist.c
+++ b/tools/perf/util/hist.c
@@ -1112,7 +1112,7 @@
int64_t cmp = 0;
perf_hpp__for_each_sort_list(fmt) {
- if (perf_hpp__should_skip(fmt))
+ if (perf_hpp__should_skip(fmt, a->hists))
continue;
cmp = fmt->sort(fmt, a, b);
diff --git a/tools/perf/util/hist.h b/tools/perf/util/hist.h
index 15b22c5..cb8f373 100644
--- a/tools/perf/util/hist.h
+++ b/tools/perf/util/hist.h
@@ -262,10 +262,20 @@
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__is_dynamic_entry(struct perf_hpp_fmt *format);
+bool perf_hpp__defined_dynamic_entry(struct perf_hpp_fmt *fmt, struct hists *hists);
-static inline bool perf_hpp__should_skip(struct perf_hpp_fmt *format)
+static inline bool perf_hpp__should_skip(struct perf_hpp_fmt *format,
+ struct hists *hists)
{
- return format->elide;
+ if (format->elide)
+ return true;
+
+ if (perf_hpp__is_dynamic_entry(format) &&
+ !perf_hpp__defined_dynamic_entry(format, hists))
+ return true;
+
+ return false;
}
void perf_hpp__reset_width(struct perf_hpp_fmt *fmt, struct hists *hists);
diff --git a/tools/perf/util/sort.c b/tools/perf/util/sort.c
index f6aef15..fd56223 100644
--- a/tools/perf/util/sort.c
+++ b/tools/perf/util/sort.c
@@ -1698,6 +1698,15 @@
return len;
}
+bool perf_hpp__defined_dynamic_entry(struct perf_hpp_fmt *fmt, struct hists *hists)
+{
+ struct hpp_dynamic_entry *hde;
+
+ hde = container_of(fmt, struct hpp_dynamic_entry, hpp);
+
+ return hists_to_evsel(hists) == hde->evsel;
+}
+
static int __sort__hde_entry(struct perf_hpp_fmt *fmt, struct perf_hpp *hpp,
struct hist_entry *he)
{
@@ -1714,9 +1723,6 @@
if (!len)
len = hde_width(hde);
- if (hists_to_evsel(he->hists) != hde->evsel)
- return scnprintf(hpp->buf, hpp->size, "%*.*s", len, len, "N/A");
-
if (hde->raw_trace)
goto raw_field;
@@ -1769,9 +1775,6 @@
hde = container_of(fmt, struct hpp_dynamic_entry, hpp);
- if (hists_to_evsel(a->hists) != hde->evsel)
- return 0;
-
field = hde->field;
if (field->flags & FIELD_IS_DYNAMIC) {
unsigned long long dyn;
@@ -1794,6 +1797,11 @@
return memcmp(a->raw_data + offset, b->raw_data + offset, size);
}
+bool perf_hpp__is_dynamic_entry(struct perf_hpp_fmt *fmt)
+{
+ return fmt->cmp == __sort__hde_cmp;
+}
+
static struct hpp_dynamic_entry *
__alloc_dynamic_entry(struct perf_evsel *evsel, struct format_field *field)
{