diff options
author | Arnaldo Carvalho de Melo <acme@redhat.com> | 2018-05-29 12:59:24 -0400 |
---|---|---|
committer | Arnaldo Carvalho de Melo <acme@redhat.com> | 2018-06-06 11:52:03 -0400 |
commit | fabd37b837f6e80aedba9ad706b517f5eeea9a50 (patch) | |
tree | 23e664564b7e09b0ee6f52e34f1ef76b618aed3c | |
parent | 0b5d6ece5e6a8b45c4ebbaaf831675b5b605850f (diff) |
perf hists: Check if a hist_entry has callchains before using them
So far if we use 'perf record -g' this will make
symbol_conf.use_callchain 'true' and logic will assume that all events
have callchains enabled, but ever since we added the possibility of
setting up callchains for some events (e.g.: -e
cycles/call-graph=dwarf/) while not for others, we limit usage scenarios
by looking at that symbol_conf.use_callchain global boolean, we better
look at each event attributes.
On the road to that we need to look if a hist_entry has callchains, that
is, to go from hist_entry->hists to the evsel that contains it, to then
look at evsel->sample_type for PERF_SAMPLE_CALLCHAIN.
The next step is to add a symbol_conf.ignore_callchains global, to use
in the places where what we really want to know is if callchains should
be ignored, even if present.
Then -g will mean just to select a callchain mode to be applied to all
events not explicitely setting some other callchain mode, i.e. a default
callchain mode, and --no-call-graph will set
symbol_conf.ignore_callchains with that clear intention.
That too will at some point become a per evsel thing, that tools can set
for all or just a few of its evsels.
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Wang Nan <wangnan0@huawei.com>
Link: https://lkml.kernel.org/n/tip-0sas5cm4dsw2obn75g7ruz69@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
-rw-r--r-- | tools/perf/ui/browsers/hists.c | 11 | ||||
-rw-r--r-- | tools/perf/ui/gtk/hists.c | 5 | ||||
-rw-r--r-- | tools/perf/ui/hist.c | 2 | ||||
-rw-r--r-- | tools/perf/ui/stdio/hist.c | 4 | ||||
-rw-r--r-- | tools/perf/util/hist.c | 11 | ||||
-rw-r--r-- | tools/perf/util/hist.h | 6 | ||||
-rw-r--r-- | tools/perf/util/sort.h | 3 |
7 files changed, 25 insertions, 17 deletions
diff --git a/tools/perf/ui/browsers/hists.c b/tools/perf/ui/browsers/hists.c index 22054107f1af..a96f62ca984a 100644 --- a/tools/perf/ui/browsers/hists.c +++ b/tools/perf/ui/browsers/hists.c | |||
@@ -1231,6 +1231,7 @@ static int hist_browser__show_entry(struct hist_browser *browser, | |||
1231 | int width = browser->b.width; | 1231 | int width = browser->b.width; |
1232 | char folded_sign = ' '; | 1232 | char folded_sign = ' '; |
1233 | bool current_entry = ui_browser__is_current_entry(&browser->b, row); | 1233 | bool current_entry = ui_browser__is_current_entry(&browser->b, row); |
1234 | bool use_callchain = hist_entry__has_callchains(entry) && symbol_conf.use_callchain; | ||
1234 | off_t row_offset = entry->row_offset; | 1235 | off_t row_offset = entry->row_offset; |
1235 | bool first = true; | 1236 | bool first = true; |
1236 | struct perf_hpp_fmt *fmt; | 1237 | struct perf_hpp_fmt *fmt; |
@@ -1240,7 +1241,7 @@ static int hist_browser__show_entry(struct hist_browser *browser, | |||
1240 | browser->selection = &entry->ms; | 1241 | browser->selection = &entry->ms; |
1241 | } | 1242 | } |
1242 | 1243 | ||
1243 | if (symbol_conf.use_callchain) { | 1244 | if (use_callchain) { |
1244 | hist_entry__init_have_children(entry); | 1245 | hist_entry__init_have_children(entry); |
1245 | folded_sign = hist_entry__folded(entry); | 1246 | folded_sign = hist_entry__folded(entry); |
1246 | } | 1247 | } |
@@ -1276,7 +1277,7 @@ static int hist_browser__show_entry(struct hist_browser *browser, | |||
1276 | } | 1277 | } |
1277 | 1278 | ||
1278 | if (first) { | 1279 | if (first) { |
1279 | if (symbol_conf.use_callchain) { | 1280 | if (use_callchain) { |
1280 | ui_browser__printf(&browser->b, "%c ", folded_sign); | 1281 | ui_browser__printf(&browser->b, "%c ", folded_sign); |
1281 | width -= 2; | 1282 | width -= 2; |
1282 | } | 1283 | } |
@@ -1583,7 +1584,7 @@ hists_browser__scnprintf_headers(struct hist_browser *browser, char *buf, | |||
1583 | int column = 0; | 1584 | int column = 0; |
1584 | int span = 0; | 1585 | int span = 0; |
1585 | 1586 | ||
1586 | if (symbol_conf.use_callchain) { | 1587 | if (hists__has_callchains(hists) && symbol_conf.use_callchain) { |
1587 | ret = scnprintf(buf, size, " "); | 1588 | ret = scnprintf(buf, size, " "); |
1588 | if (advance_hpp_check(&dummy_hpp, ret)) | 1589 | if (advance_hpp_check(&dummy_hpp, ret)) |
1589 | return ret; | 1590 | return ret; |
@@ -1987,7 +1988,7 @@ static int hist_browser__fprintf_entry(struct hist_browser *browser, | |||
1987 | bool first = true; | 1988 | bool first = true; |
1988 | int ret; | 1989 | int ret; |
1989 | 1990 | ||
1990 | if (symbol_conf.use_callchain) { | 1991 | if (hist_entry__has_callchains(he) && symbol_conf.use_callchain) { |
1991 | folded_sign = hist_entry__folded(he); | 1992 | folded_sign = hist_entry__folded(he); |
1992 | printed += fprintf(fp, "%c ", folded_sign); | 1993 | printed += fprintf(fp, "%c ", folded_sign); |
1993 | } | 1994 | } |
@@ -2671,7 +2672,7 @@ static void hist_browser__update_percent_limit(struct hist_browser *hb, | |||
2671 | he->nr_rows = 0; | 2672 | he->nr_rows = 0; |
2672 | } | 2673 | } |
2673 | 2674 | ||
2674 | if (!he->leaf || !symbol_conf.use_callchain) | 2675 | if (!he->leaf || !hist_entry__has_callchains(he) || !symbol_conf.use_callchain) |
2675 | goto next; | 2676 | goto next; |
2676 | 2677 | ||
2677 | if (callchain_param.mode == CHAIN_GRAPH_REL) { | 2678 | if (callchain_param.mode == CHAIN_GRAPH_REL) { |
diff --git a/tools/perf/ui/gtk/hists.c b/tools/perf/ui/gtk/hists.c index 24e1ec201ffd..b085f1b3e34d 100644 --- a/tools/perf/ui/gtk/hists.c +++ b/tools/perf/ui/gtk/hists.c | |||
@@ -382,7 +382,8 @@ static void perf_gtk__show_hists(GtkWidget *window, struct hists *hists, | |||
382 | gtk_tree_store_set(store, &iter, col_idx++, s, -1); | 382 | gtk_tree_store_set(store, &iter, col_idx++, s, -1); |
383 | } | 383 | } |
384 | 384 | ||
385 | if (symbol_conf.use_callchain && hists__has(hists, sym)) { | 385 | if (hists__has_callchains(hists) && |
386 | symbol_conf.use_callchain && hists__has(hists, sym)) { | ||
386 | if (callchain_param.mode == CHAIN_GRAPH_REL) | 387 | if (callchain_param.mode == CHAIN_GRAPH_REL) |
387 | total = symbol_conf.cumulate_callchain ? | 388 | total = symbol_conf.cumulate_callchain ? |
388 | h->stat_acc->period : h->stat.period; | 389 | h->stat_acc->period : h->stat.period; |
@@ -479,7 +480,7 @@ static void perf_gtk__add_hierarchy_entries(struct hists *hists, | |||
479 | } | 480 | } |
480 | } | 481 | } |
481 | 482 | ||
482 | if (symbol_conf.use_callchain && he->leaf) { | 483 | if (he->leaf && hist_entry__has_callchains(he) && symbol_conf.use_callchain) { |
483 | if (callchain_param.mode == CHAIN_GRAPH_REL) | 484 | if (callchain_param.mode == CHAIN_GRAPH_REL) |
484 | total = symbol_conf.cumulate_callchain ? | 485 | total = symbol_conf.cumulate_callchain ? |
485 | he->stat_acc->period : he->stat.period; | 486 | he->stat_acc->period : he->stat.period; |
diff --git a/tools/perf/ui/hist.c b/tools/perf/ui/hist.c index 706f6f1e9c7d..fe3dfaa64a91 100644 --- a/tools/perf/ui/hist.c +++ b/tools/perf/ui/hist.c | |||
@@ -207,7 +207,7 @@ static int __hpp__sort_acc(struct hist_entry *a, struct hist_entry *b, | |||
207 | if (ret) | 207 | if (ret) |
208 | return ret; | 208 | return ret; |
209 | 209 | ||
210 | if (a->thread != b->thread || !symbol_conf.use_callchain) | 210 | if (a->thread != b->thread || !hist_entry__has_callchains(a) || !symbol_conf.use_callchain) |
211 | return 0; | 211 | return 0; |
212 | 212 | ||
213 | ret = b->callchain->max_depth - a->callchain->max_depth; | 213 | ret = b->callchain->max_depth - a->callchain->max_depth; |
diff --git a/tools/perf/ui/stdio/hist.c b/tools/perf/ui/stdio/hist.c index c1eb476da91b..69b7a28f7a1c 100644 --- a/tools/perf/ui/stdio/hist.c +++ b/tools/perf/ui/stdio/hist.c | |||
@@ -516,7 +516,7 @@ static int hist_entry__hierarchy_fprintf(struct hist_entry *he, | |||
516 | } | 516 | } |
517 | printed += putc('\n', fp); | 517 | printed += putc('\n', fp); |
518 | 518 | ||
519 | if (symbol_conf.use_callchain && he->leaf) { | 519 | if (he->leaf && hist_entry__has_callchains(he) && symbol_conf.use_callchain) { |
520 | u64 total = hists__total_period(hists); | 520 | u64 total = hists__total_period(hists); |
521 | 521 | ||
522 | printed += hist_entry_callchain__fprintf(he, total, 0, fp); | 522 | printed += hist_entry_callchain__fprintf(he, total, 0, fp); |
@@ -550,7 +550,7 @@ static int hist_entry__fprintf(struct hist_entry *he, size_t size, | |||
550 | 550 | ||
551 | ret = fprintf(fp, "%s\n", bf); | 551 | ret = fprintf(fp, "%s\n", bf); |
552 | 552 | ||
553 | if (use_callchain) | 553 | if (hist_entry__has_callchains(he) && use_callchain) |
554 | callchain_ret = hist_entry_callchain__fprintf(he, total_period, | 554 | callchain_ret = hist_entry_callchain__fprintf(he, total_period, |
555 | 0, fp); | 555 | 0, fp); |
556 | 556 | ||
diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c index 34864c87cd3c..52e8fda93a47 100644 --- a/tools/perf/util/hist.c +++ b/tools/perf/util/hist.c | |||
@@ -410,7 +410,7 @@ static int hist_entry__init(struct hist_entry *he, | |||
410 | map__get(he->mem_info->daddr.map); | 410 | map__get(he->mem_info->daddr.map); |
411 | } | 411 | } |
412 | 412 | ||
413 | if (symbol_conf.use_callchain) | 413 | if (hist_entry__has_callchains(he) && symbol_conf.use_callchain) |
414 | callchain_init(he->callchain); | 414 | callchain_init(he->callchain); |
415 | 415 | ||
416 | if (he->raw_data) { | 416 | if (he->raw_data) { |
@@ -492,7 +492,7 @@ static u8 symbol__parent_filter(const struct symbol *parent) | |||
492 | 492 | ||
493 | static void hist_entry__add_callchain_period(struct hist_entry *he, u64 period) | 493 | static void hist_entry__add_callchain_period(struct hist_entry *he, u64 period) |
494 | { | 494 | { |
495 | if (!symbol_conf.use_callchain) | 495 | if (!hist_entry__has_callchains(he) || !symbol_conf.use_callchain) |
496 | return; | 496 | return; |
497 | 497 | ||
498 | he->hists->callchain_period += period; | 498 | he->hists->callchain_period += period; |
@@ -986,7 +986,7 @@ iter_add_next_cumulative_entry(struct hist_entry_iter *iter, | |||
986 | iter->he = he; | 986 | iter->he = he; |
987 | he_cache[iter->curr++] = he; | 987 | he_cache[iter->curr++] = he; |
988 | 988 | ||
989 | if (symbol_conf.use_callchain) | 989 | if (hist_entry__has_callchains(he) && symbol_conf.use_callchain) |
990 | callchain_append(he->callchain, &cursor, sample->period); | 990 | callchain_append(he->callchain, &cursor, sample->period); |
991 | return 0; | 991 | return 0; |
992 | } | 992 | } |
@@ -1373,7 +1373,8 @@ static int hists__hierarchy_insert_entry(struct hists *hists, | |||
1373 | if (new_he) { | 1373 | if (new_he) { |
1374 | new_he->leaf = true; | 1374 | new_he->leaf = true; |
1375 | 1375 | ||
1376 | if (symbol_conf.use_callchain) { | 1376 | if (hist_entry__has_callchains(new_he) && |
1377 | symbol_conf.use_callchain) { | ||
1377 | callchain_cursor_reset(&callchain_cursor); | 1378 | callchain_cursor_reset(&callchain_cursor); |
1378 | if (callchain_merge(&callchain_cursor, | 1379 | if (callchain_merge(&callchain_cursor, |
1379 | new_he->callchain, | 1380 | new_he->callchain, |
@@ -1414,7 +1415,7 @@ static int hists__collapse_insert_entry(struct hists *hists, | |||
1414 | if (symbol_conf.cumulate_callchain) | 1415 | if (symbol_conf.cumulate_callchain) |
1415 | he_stat__add_stat(iter->stat_acc, he->stat_acc); | 1416 | he_stat__add_stat(iter->stat_acc, he->stat_acc); |
1416 | 1417 | ||
1417 | if (symbol_conf.use_callchain) { | 1418 | if (hist_entry__has_callchains(he) && symbol_conf.use_callchain) { |
1418 | callchain_cursor_reset(&callchain_cursor); | 1419 | callchain_cursor_reset(&callchain_cursor); |
1419 | if (callchain_merge(&callchain_cursor, | 1420 | if (callchain_merge(&callchain_cursor, |
1420 | iter->callchain, | 1421 | iter->callchain, |
diff --git a/tools/perf/util/hist.h b/tools/perf/util/hist.h index cafafbf2aa9f..06607c434949 100644 --- a/tools/perf/util/hist.h +++ b/tools/perf/util/hist.h | |||
@@ -220,6 +220,12 @@ static inline struct hists *evsel__hists(struct perf_evsel *evsel) | |||
220 | return &hevsel->hists; | 220 | return &hevsel->hists; |
221 | } | 221 | } |
222 | 222 | ||
223 | static __pure inline bool hists__has_callchains(struct hists *hists) | ||
224 | { | ||
225 | const struct perf_evsel *evsel = hists_to_evsel(hists); | ||
226 | return evsel__has_callchain(evsel); | ||
227 | } | ||
228 | |||
223 | int hists__init(void); | 229 | int hists__init(void); |
224 | int __hists__init(struct hists *hists, struct perf_hpp_list *hpp_list); | 230 | int __hists__init(struct hists *hists, struct perf_hpp_list *hpp_list); |
225 | 231 | ||
diff --git a/tools/perf/util/sort.h b/tools/perf/util/sort.h index 1a046157bfef..7cf2d5cc038e 100644 --- a/tools/perf/util/sort.h +++ b/tools/perf/util/sort.h | |||
@@ -153,8 +153,7 @@ struct hist_entry { | |||
153 | 153 | ||
154 | static __pure inline bool hist_entry__has_callchains(struct hist_entry *he) | 154 | static __pure inline bool hist_entry__has_callchains(struct hist_entry *he) |
155 | { | 155 | { |
156 | const struct perf_evsel *evsel = hists_to_evsel(he->hists); | 156 | return hists__has_callchains(he->hists); |
157 | return evsel__has_callchain(evsel); | ||
158 | } | 157 | } |
159 | 158 | ||
160 | static inline bool hist_entry__has_pairs(struct hist_entry *he) | 159 | static inline bool hist_entry__has_pairs(struct hist_entry *he) |