^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) #include "tests.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) #include "debug.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) #include "symbol.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) #include "sort.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) #include "evsel.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) #include "evlist.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include "machine.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include "parse-events.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include "hists_common.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include "util/mmap.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <errno.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) struct sample {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) u32 pid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) u64 ip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) struct thread *thread;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) struct map *map;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) struct symbol *sym;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) /* For the numbers, see hists_common.c */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) static struct sample fake_common_samples[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) /* perf [kernel] schedule() */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) { .pid = FAKE_PID_PERF1, .ip = FAKE_IP_KERNEL_SCHEDULE, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) /* perf [perf] main() */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) { .pid = FAKE_PID_PERF2, .ip = FAKE_IP_PERF_MAIN, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) /* perf [perf] cmd_record() */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) { .pid = FAKE_PID_PERF2, .ip = FAKE_IP_PERF_CMD_RECORD, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) /* bash [bash] xmalloc() */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) { .pid = FAKE_PID_BASH, .ip = FAKE_IP_BASH_XMALLOC, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) /* bash [libc] malloc() */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) { .pid = FAKE_PID_BASH, .ip = FAKE_IP_LIBC_MALLOC, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) static struct sample fake_samples[][5] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) /* perf [perf] run_command() */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) { .pid = FAKE_PID_PERF1, .ip = FAKE_IP_PERF_RUN_COMMAND, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) /* perf [libc] malloc() */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) { .pid = FAKE_PID_PERF1, .ip = FAKE_IP_LIBC_MALLOC, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) /* perf [kernel] page_fault() */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) { .pid = FAKE_PID_PERF1, .ip = FAKE_IP_KERNEL_PAGE_FAULT, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) /* perf [kernel] sys_perf_event_open() */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) { .pid = FAKE_PID_PERF2, .ip = FAKE_IP_KERNEL_SYS_PERF_EVENT_OPEN, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) /* bash [libc] free() */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) { .pid = FAKE_PID_BASH, .ip = FAKE_IP_LIBC_FREE, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) /* perf [libc] free() */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) { .pid = FAKE_PID_PERF2, .ip = FAKE_IP_LIBC_FREE, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) /* bash [libc] malloc() */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) { .pid = FAKE_PID_BASH, .ip = FAKE_IP_LIBC_MALLOC, }, /* will be merged */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) /* bash [bash] xfee() */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) { .pid = FAKE_PID_BASH, .ip = FAKE_IP_BASH_XFREE, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) /* bash [libc] realloc() */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) { .pid = FAKE_PID_BASH, .ip = FAKE_IP_LIBC_REALLOC, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) /* bash [kernel] page_fault() */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) { .pid = FAKE_PID_BASH, .ip = FAKE_IP_KERNEL_PAGE_FAULT, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) static int add_hist_entries(struct evlist *evlist, struct machine *machine)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) struct evsel *evsel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) struct addr_location al;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) struct hist_entry *he;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) struct perf_sample sample = { .period = 1, .weight = 1, };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) size_t i = 0, k;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) * each evsel will have 10 samples - 5 common and 5 distinct.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) * However the second evsel also has a collapsed entry for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) * "bash [libc] malloc" so total 9 entries will be in the tree.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) evlist__for_each_entry(evlist, evsel) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) struct hists *hists = evsel__hists(evsel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) for (k = 0; k < ARRAY_SIZE(fake_common_samples); k++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) sample.cpumode = PERF_RECORD_MISC_USER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) sample.pid = fake_common_samples[k].pid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) sample.tid = fake_common_samples[k].pid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) sample.ip = fake_common_samples[k].ip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) if (machine__resolve(machine, &al, &sample) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) he = hists__add_entry(hists, &al, NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) NULL, NULL, &sample, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) if (he == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) addr_location__put(&al);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) fake_common_samples[k].thread = al.thread;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) fake_common_samples[k].map = al.map;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) fake_common_samples[k].sym = al.sym;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) for (k = 0; k < ARRAY_SIZE(fake_samples[i]); k++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) sample.pid = fake_samples[i][k].pid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) sample.tid = fake_samples[i][k].pid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) sample.ip = fake_samples[i][k].ip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) if (machine__resolve(machine, &al, &sample) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) he = hists__add_entry(hists, &al, NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) NULL, NULL, &sample, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) if (he == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) addr_location__put(&al);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) fake_samples[i][k].thread = al.thread;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) fake_samples[i][k].map = al.map;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) fake_samples[i][k].sym = al.sym;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) i++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) pr_debug("Not enough memory for adding a hist entry\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) static int find_sample(struct sample *samples, size_t nr_samples,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) struct thread *t, struct map *m, struct symbol *s)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) while (nr_samples--) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) if (samples->thread == t && samples->map == m &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) samples->sym == s)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) samples++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) static int __validate_match(struct hists *hists)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) size_t count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) struct rb_root_cached *root;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) struct rb_node *node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) * Only entries from fake_common_samples should have a pair.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) if (hists__has(hists, need_collapse))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) root = &hists->entries_collapsed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) root = hists->entries_in;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) node = rb_first_cached(root);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) while (node) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) struct hist_entry *he;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) he = rb_entry(node, struct hist_entry, rb_node_in);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) if (hist_entry__has_pairs(he)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) if (find_sample(fake_common_samples,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) ARRAY_SIZE(fake_common_samples),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) he->thread, he->ms.map, he->ms.sym)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) count++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) pr_debug("Can't find the matched entry\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) node = rb_next(node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) if (count != ARRAY_SIZE(fake_common_samples)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) pr_debug("Invalid count for matched entries: %zd of %zd\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) count, ARRAY_SIZE(fake_common_samples));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) static int validate_match(struct hists *leader, struct hists *other)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) return __validate_match(leader) || __validate_match(other);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) static int __validate_link(struct hists *hists, int idx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) size_t count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) size_t count_pair = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) size_t count_dummy = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) struct rb_root_cached *root;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) struct rb_node *node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) * Leader hists (idx = 0) will have dummy entries from other,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) * and some entries will have no pair. However every entry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) * in other hists should have (dummy) pair.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) if (hists__has(hists, need_collapse))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) root = &hists->entries_collapsed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) root = hists->entries_in;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) node = rb_first_cached(root);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) while (node) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) struct hist_entry *he;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) he = rb_entry(node, struct hist_entry, rb_node_in);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) if (hist_entry__has_pairs(he)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) if (!find_sample(fake_common_samples,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) ARRAY_SIZE(fake_common_samples),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) he->thread, he->ms.map, he->ms.sym) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) !find_sample(fake_samples[idx],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) ARRAY_SIZE(fake_samples[idx]),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) he->thread, he->ms.map, he->ms.sym)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) count_dummy++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) count_pair++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) } else if (idx) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) pr_debug("A entry from the other hists should have pair\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) count++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) node = rb_next(node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) * Note that we have a entry collapsed in the other (idx = 1) hists.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) if (idx == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) if (count_dummy != ARRAY_SIZE(fake_samples[1]) - 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) pr_debug("Invalid count of dummy entries: %zd of %zd\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) count_dummy, ARRAY_SIZE(fake_samples[1]) - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) if (count != count_pair + ARRAY_SIZE(fake_samples[0])) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) pr_debug("Invalid count of total leader entries: %zd of %zd\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) count, count_pair + ARRAY_SIZE(fake_samples[0]));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) if (count != count_pair) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) pr_debug("Invalid count of total other entries: %zd of %zd\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) count, count_pair);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) if (count_dummy > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) pr_debug("Other hists should not have dummy entries: %zd\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) count_dummy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) static int validate_link(struct hists *leader, struct hists *other)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) return __validate_link(leader, 0) || __validate_link(other, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) int test__hists_link(struct test *test __maybe_unused, int subtest __maybe_unused)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) int err = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) struct hists *hists, *first_hists;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) struct machines machines;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) struct machine *machine = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) struct evsel *evsel, *first;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) struct evlist *evlist = evlist__new();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) if (evlist == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) err = parse_events(evlist, "cpu-clock", NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) err = parse_events(evlist, "task-clock", NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) err = TEST_FAIL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) /* default sort order (comm,dso,sym) will be used */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) if (setup_sorting(NULL) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) machines__init(&machines);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) /* setup threads/dso/map/symbols also */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) machine = setup_fake_machine(&machines);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) if (!machine)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) if (verbose > 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) machine__fprintf(machine, stderr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) /* process sample events */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) err = add_hist_entries(evlist, machine);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) evlist__for_each_entry(evlist, evsel) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) hists = evsel__hists(evsel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) hists__collapse_resort(hists, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) if (verbose > 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) print_hists_in(hists);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) first = evlist__first(evlist);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) evsel = evlist__last(evlist);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) first_hists = evsel__hists(first);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) hists = evsel__hists(evsel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) /* match common entries */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) hists__match(first_hists, hists);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) err = validate_match(first_hists, hists);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) /* link common and/or dummy entries */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) hists__link(first_hists, hists);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) err = validate_link(first_hists, hists);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) /* tear down everything */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) evlist__delete(evlist);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) reset_output_field();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) machines__exit(&machines);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) }