diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2020-04-05 22:26:24 +0300 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2020-04-05 22:26:24 +0300 |
commit | c48b07226bd41f4053aa2024c5e347183c04deb5 (patch) | |
tree | 85d61650f345829fbb0f64861c463648265c20df /tools/perf/ui/hist.c | |
parent | d5ca32738f8fbd3632928929cccb5789d44be390 (diff) | |
parent | 7dc41b9b99cd0037a418ac47e342d56a438df649 (diff) | |
download | linux-c48b07226bd41f4053aa2024c5e347183c04deb5.tar.xz |
Merge tag 'perf-urgent-2020-04-05' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull more perf updates from Thomas Gleixner:
"Perf updates all over the place:
core:
- Support for cgroup tracking in samples to allow cgroup based
analysis
tools:
- Support for cgroup analysis
- Commandline option and hotkey for perf top to change the sort order
- A set of fixes all over the place
- Various build system related improvements
- Updates of the X86 pmu event JSON data
- Documentation updates"
* tag 'perf-urgent-2020-04-05' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (55 commits)
perf python: Fix clang detection to strip out options passed in $CC
perf tools: Support Python 3.8+ in Makefile
perf script: Fix invalid read of directory entry after closedir()
perf script report: Fix SEGFAULT when using DWARF mode
perf script: add -S/--symbols documentation
perf pmu-events x86: Use CPU_CLK_UNHALTED.THREAD in Kernel_Utilization metric
perf events parser: Add missing Intel CPU events to parser
perf script: Allow --symbol to accept hexadecimal addresses
perf report/top TUI: Fix title line formatting
perf top: Support hotkey to change sort order
perf top: Support --group-sort-idx to change the sort order
perf symbols: Fix arm64 gap between kernel start and module end
perf build-test: Honour JOBS to override detection of number of cores
perf script: Add --show-cgroup-events option
perf top: Add --all-cgroups option
perf record: Add --all-cgroups option
perf record: Support synthesizing cgroup events
perf report: Add 'cgroup' sort key
perf cgroup: Maintain cgroup hierarchy
perf tools: Basic support for CGROUP event
...
Diffstat (limited to 'tools/perf/ui/hist.c')
-rw-r--r-- | tools/perf/ui/hist.c | 93 |
1 files changed, 78 insertions, 15 deletions
diff --git a/tools/perf/ui/hist.c b/tools/perf/ui/hist.c index f73675500061..025f4c7f96bf 100644 --- a/tools/perf/ui/hist.c +++ b/tools/perf/ui/hist.c @@ -151,15 +151,90 @@ static int field_cmp(u64 field_a, u64 field_b) return 0; } +static int hist_entry__new_pair(struct hist_entry *a, struct hist_entry *b, + hpp_field_fn get_field, int nr_members, + u64 **fields_a, u64 **fields_b) +{ + u64 *fa = calloc(nr_members, sizeof(*fa)), + *fb = calloc(nr_members, sizeof(*fb)); + struct hist_entry *pair; + + if (!fa || !fb) + goto out_free; + + list_for_each_entry(pair, &a->pairs.head, pairs.node) { + struct evsel *evsel = hists_to_evsel(pair->hists); + fa[perf_evsel__group_idx(evsel)] = get_field(pair); + } + + list_for_each_entry(pair, &b->pairs.head, pairs.node) { + struct evsel *evsel = hists_to_evsel(pair->hists); + fb[perf_evsel__group_idx(evsel)] = get_field(pair); + } + + *fields_a = fa; + *fields_b = fb; + return 0; +out_free: + free(fa); + free(fb); + *fields_a = *fields_b = NULL; + return -1; +} + +static int __hpp__group_sort_idx(struct hist_entry *a, struct hist_entry *b, + hpp_field_fn get_field, int idx) +{ + struct evsel *evsel = hists_to_evsel(a->hists); + u64 *fields_a, *fields_b; + int cmp, nr_members, ret, i; + + cmp = field_cmp(get_field(a), get_field(b)); + if (!perf_evsel__is_group_event(evsel)) + return cmp; + + nr_members = evsel->core.nr_members; + if (idx < 1 || idx >= nr_members) + return cmp; + + ret = hist_entry__new_pair(a, b, get_field, nr_members, &fields_a, &fields_b); + if (ret) { + ret = cmp; + goto out; + } + + ret = field_cmp(fields_a[idx], fields_b[idx]); + if (ret) + goto out; + + for (i = 1; i < nr_members; i++) { + if (i != idx) { + ret = field_cmp(fields_a[i], fields_b[i]); + if (ret) + goto out; + } + } + +out: + free(fields_a); + free(fields_b); + + return ret; +} + static int __hpp__sort(struct hist_entry *a, struct hist_entry *b, hpp_field_fn get_field) { s64 ret; int i, nr_members; struct evsel *evsel; - struct hist_entry *pair; u64 *fields_a, *fields_b; + if (symbol_conf.group_sort_idx && symbol_conf.event_group) { + return __hpp__group_sort_idx(a, b, get_field, + symbol_conf.group_sort_idx); + } + ret = field_cmp(get_field(a), get_field(b)); if (ret || !symbol_conf.event_group) return ret; @@ -169,22 +244,10 @@ static int __hpp__sort(struct hist_entry *a, struct hist_entry *b, return ret; nr_members = evsel->core.nr_members; - fields_a = calloc(nr_members, sizeof(*fields_a)); - fields_b = calloc(nr_members, sizeof(*fields_b)); - - if (!fields_a || !fields_b) + i = hist_entry__new_pair(a, b, get_field, nr_members, &fields_a, &fields_b); + if (i) goto out; - list_for_each_entry(pair, &a->pairs.head, pairs.node) { - evsel = hists_to_evsel(pair->hists); - fields_a[perf_evsel__group_idx(evsel)] = get_field(pair); - } - - list_for_each_entry(pair, &b->pairs.head, pairs.node) { - evsel = hists_to_evsel(pair->hists); - fields_b[perf_evsel__group_idx(evsel)] = get_field(pair); - } - for (i = 1; i < nr_members; i++) { ret = field_cmp(fields_a[i], fields_b[i]); if (ret) |