Skip to content

Commit 8b4799e

Browse files
dvyukovnamhyung
authored andcommitted
perf hist: Fix bogus profiles when filters are enabled
When a filtered column is not present in the sort order, profiles become arbitrary broken. Filtered and non-filtered entries are collapsed together, and the filtered-by field ends up with a random value (either from a filtered or non-filtered entry). If we end up with filtered entry/value, then the whole collapsed entry will be filtered out and will be missing in the profile. If we end up with non-filtered entry/value, then the overhead value will be wrongly larger (include some subset of filtered out samples). This leads to very confusing profiles. The problem is hard to notice, and if noticed hard to understand. If the filter is for a single value, then it can be fixed by adding the corresponding field to the sort order (provided user understood the problem). But if the filter is for multiple values, it's impossible to fix b/c there is no concept of binary sorting based on filter predicate (we want to group all non-filtered values in one bucket, and all filtered values in another). Examples of affected commands: perf report --tid=123 perf report --sort overhead,symbol --comm=foo,bar Fix this by considering filtered status as the highest priority sort/collapse predicate. As a side effect this effectively adds a new feature of showing profile where several lines are combined based on arbitrary filtering predicate. For example, showing symbols from binaries foo and bar combined together, but not from other binaries; or showing combined overhead of several particular threads. Signed-off-by: Dmitry Vyukov <dvyukov@google.com> Link: https://lore.kernel.org/r/359dc444ce94d20e59d3a9e360c36fbeac833a04.1736927981.git.dvyukov@google.com Signed-off-by: Namhyung Kim <namhyung@kernel.org>
1 parent cd57c04 commit 8b4799e

File tree

1 file changed

+10
-1
lines changed

1 file changed

+10
-1
lines changed

tools/perf/util/hist.c

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1303,7 +1303,16 @@ hist_entry__cmp_impl(struct perf_hpp_list *hpp_list, struct hist_entry *left,
13031303
struct hists *hists = left->hists;
13041304
struct perf_hpp_fmt *fmt;
13051305
perf_hpp_fmt_cmp_t *fn;
1306-
int64_t cmp = 0;
1306+
int64_t cmp;
1307+
1308+
/*
1309+
* Never collapse filtered and non-filtered entries.
1310+
* Note this is not the same as having an extra (invisible) fmt
1311+
* that corresponds to the filtered status.
1312+
*/
1313+
cmp = (int64_t)!!left->filtered - (int64_t)!!right->filtered;
1314+
if (cmp)
1315+
return cmp;
13071316

13081317
perf_hpp_list__for_each_sort_list(hpp_list, fmt) {
13091318
if (ignore_dynamic && perf_hpp__is_dynamic_entry(fmt) &&

0 commit comments

Comments
 (0)