1 // SPDX-License-Identifier: GPL-2.0 2 #include <string.h> 3 #include "../../../util/evlist.h" 4 #include "../../../util/evsel.h" 5 #include "topdown.h" 6 #include "evsel.h" 7 8 int arch_evlist__cmp(const struct evsel *lhs, const struct evsel *rhs) 9 { 10 /* 11 * Currently the following topdown events sequence are supported to 12 * move and regroup correctly. 13 * 14 * a. all events in a group 15 * perf stat -e "{instructions,topdown-retiring,slots}" -C0 sleep 1 16 * WARNING: events were regrouped to match PMUs 17 * Performance counter stats for 'CPU(s) 0': 18 * 15,066,240 slots 19 * 1,899,760 instructions 20 * 2,126,998 topdown-retiring 21 * b. all events not in a group 22 * perf stat -e "instructions,topdown-retiring,slots" -C0 sleep 1 23 * WARNING: events were regrouped to match PMUs 24 * Performance counter stats for 'CPU(s) 0': 25 * 2,045,561 instructions 26 * 17,108,370 slots 27 * 2,281,116 topdown-retiring 28 * c. slots event in a group but topdown metrics events outside the group 29 * perf stat -e "{instructions,slots},topdown-retiring" -C0 sleep 1 30 * WARNING: events were regrouped to match PMUs 31 * Performance counter stats for 'CPU(s) 0': 32 * 20,323,878 slots 33 * 2,634,884 instructions 34 * 3,028,656 topdown-retiring 35 * d. slots event and topdown metrics events in two groups 36 * perf stat -e "{instructions,slots},{topdown-retiring}" -C0 sleep 1 37 * WARNING: events were regrouped to match PMUs 38 * Performance counter stats for 'CPU(s) 0': 39 * 26,319,024 slots 40 * 2,427,791 instructions 41 * 2,683,508 topdown-retiring 42 * 43 * If slots event and topdown metrics events are not in same group, the 44 * topdown metrics events must be first event after the slots event group, 45 * otherwise topdown metrics events can't be regrouped correctly, e.g. 46 * 47 * a. perf stat -e "{instructions,slots},cycles,topdown-retiring" -C0 sleep 1 48 * WARNING: events were regrouped to match PMUs 49 * Performance counter stats for 'CPU(s) 0': 50 * 17,923,134 slots 51 * 2,154,855 instructions 52 * 3,015,058 cycles 53 * <not supported> topdown-retiring 54 * 55 * If slots event and topdown metrics events are in two groups, the group which 56 * has topdown metrics events must contain only the topdown metrics event, 57 * otherwise topdown metrics event can't be regrouped correctly as well, e.g. 58 * 59 * a. perf stat -e "{instructions,slots},{topdown-retiring,cycles}" -C0 sleep 1 60 * WARNING: events were regrouped to match PMUs 61 * Error: 62 * The sys_perf_event_open() syscall returned with 22 (Invalid argument) for 63 * event (topdown-retiring) 64 */ 65 if (topdown_sys_has_perf_metrics() && 66 (arch_evsel__must_be_in_group(lhs) || arch_evsel__must_be_in_group(rhs))) { 67 /* Ensure the topdown slots comes first. */ 68 if (arch_is_topdown_slots(lhs)) 69 return -1; 70 if (arch_is_topdown_slots(rhs)) 71 return 1; 72 73 /* 74 * Move topdown metrics events forward only when topdown metrics 75 * events are not in same group with previous slots event. If 76 * topdown metrics events are already in same group with slots 77 * event, do nothing. 78 */ 79 if (arch_is_topdown_metrics(lhs) && !arch_is_topdown_metrics(rhs) && 80 lhs->core.leader != rhs->core.leader) 81 return -1; 82 if (!arch_is_topdown_metrics(lhs) && arch_is_topdown_metrics(rhs) && 83 lhs->core.leader != rhs->core.leader) 84 return 1; 85 } 86 87 /* Retire latency event should not be group leader*/ 88 if (lhs->retire_lat && !rhs->retire_lat) 89 return 1; 90 if (!lhs->retire_lat && rhs->retire_lat) 91 return -1; 92 93 /* Default ordering by insertion index. */ 94 return lhs->core.idx - rhs->core.idx; 95 } 96