1b2441318SGreg Kroah-Hartman // SPDX-License-Identifier: GPL-2.0
2f8ebb0cdSNamhyung Kim #include "tests.h"
3f8ebb0cdSNamhyung Kim #include "debug.h"
4f8ebb0cdSNamhyung Kim #include "symbol.h"
5f8ebb0cdSNamhyung Kim #include "sort.h"
6f8ebb0cdSNamhyung Kim #include "evsel.h"
7f8ebb0cdSNamhyung Kim #include "evlist.h"
8f8ebb0cdSNamhyung Kim #include "machine.h"
9ec417ad4SIan Rogers #include "map.h"
10f8ebb0cdSNamhyung Kim #include "parse-events.h"
116e344a95SNamhyung Kim #include "thread.h"
12e0fcfb08SArnaldo Carvalho de Melo #include "hists_common.h"
13a43783aeSArnaldo Carvalho de Melo #include "util/mmap.h"
14877a7a11SArnaldo Carvalho de Melo #include <errno.h>
15f8ebb0cdSNamhyung Kim #include <linux/kernel.h>
16f8ebb0cdSNamhyung Kim
17f8ebb0cdSNamhyung Kim struct sample {
18f8ebb0cdSNamhyung Kim u32 pid;
19f8ebb0cdSNamhyung Kim u64 ip;
20f8ebb0cdSNamhyung Kim struct thread *thread;
21f8ebb0cdSNamhyung Kim struct map *map;
22f8ebb0cdSNamhyung Kim struct symbol *sym;
23f8ebb0cdSNamhyung Kim };
246e344a95SNamhyung Kim
25f8ebb0cdSNamhyung Kim /* For the numbers, see hists_common.c */
26f8ebb0cdSNamhyung Kim static struct sample fake_common_samples[] = {
27a1891aa4SNamhyung Kim /* perf [kernel] schedule() */
28f8ebb0cdSNamhyung Kim { .pid = FAKE_PID_PERF1, .ip = FAKE_IP_KERNEL_SCHEDULE, },
29a1891aa4SNamhyung Kim /* perf [perf] main() */
30f8ebb0cdSNamhyung Kim { .pid = FAKE_PID_PERF2, .ip = FAKE_IP_PERF_MAIN, },
31a1891aa4SNamhyung Kim /* perf [perf] cmd_record() */
32f8ebb0cdSNamhyung Kim { .pid = FAKE_PID_PERF2, .ip = FAKE_IP_PERF_CMD_RECORD, },
33a1891aa4SNamhyung Kim /* bash [bash] xmalloc() */
34f8ebb0cdSNamhyung Kim { .pid = FAKE_PID_BASH, .ip = FAKE_IP_BASH_XMALLOC, },
35a1891aa4SNamhyung Kim /* bash [libc] malloc() */
36f8ebb0cdSNamhyung Kim { .pid = FAKE_PID_BASH, .ip = FAKE_IP_LIBC_MALLOC, },
37f8ebb0cdSNamhyung Kim };
38f8ebb0cdSNamhyung Kim
39f8ebb0cdSNamhyung Kim static struct sample fake_samples[][5] = {
40f8ebb0cdSNamhyung Kim {
41a1891aa4SNamhyung Kim /* perf [perf] run_command() */
42f8ebb0cdSNamhyung Kim { .pid = FAKE_PID_PERF1, .ip = FAKE_IP_PERF_RUN_COMMAND, },
43a1891aa4SNamhyung Kim /* perf [libc] malloc() */
44f8ebb0cdSNamhyung Kim { .pid = FAKE_PID_PERF1, .ip = FAKE_IP_LIBC_MALLOC, },
45a1891aa4SNamhyung Kim /* perf [kernel] page_fault() */
46f8ebb0cdSNamhyung Kim { .pid = FAKE_PID_PERF1, .ip = FAKE_IP_KERNEL_PAGE_FAULT, },
47a1891aa4SNamhyung Kim /* perf [kernel] sys_perf_event_open() */
48f8ebb0cdSNamhyung Kim { .pid = FAKE_PID_PERF2, .ip = FAKE_IP_KERNEL_SYS_PERF_EVENT_OPEN, },
49a1891aa4SNamhyung Kim /* bash [libc] free() */
50f8ebb0cdSNamhyung Kim { .pid = FAKE_PID_BASH, .ip = FAKE_IP_LIBC_FREE, },
51f8ebb0cdSNamhyung Kim },
52f8ebb0cdSNamhyung Kim {
53a1891aa4SNamhyung Kim /* perf [libc] free() */
54f8ebb0cdSNamhyung Kim { .pid = FAKE_PID_PERF2, .ip = FAKE_IP_LIBC_FREE, },
55a1891aa4SNamhyung Kim /* bash [libc] malloc() */
56f8ebb0cdSNamhyung Kim { .pid = FAKE_PID_BASH, .ip = FAKE_IP_LIBC_MALLOC, }, /* will be merged */
57a1891aa4SNamhyung Kim /* bash [bash] xfee() */
58f8ebb0cdSNamhyung Kim { .pid = FAKE_PID_BASH, .ip = FAKE_IP_BASH_XFREE, },
59a1891aa4SNamhyung Kim /* bash [libc] realloc() */
60f8ebb0cdSNamhyung Kim { .pid = FAKE_PID_BASH, .ip = FAKE_IP_LIBC_REALLOC, },
61a1891aa4SNamhyung Kim /* bash [kernel] page_fault() */
62f8ebb0cdSNamhyung Kim { .pid = FAKE_PID_BASH, .ip = FAKE_IP_KERNEL_PAGE_FAULT, },
63f8ebb0cdSNamhyung Kim },
64f8ebb0cdSNamhyung Kim };
6563503dbaSJiri Olsa
add_hist_entries(struct evlist * evlist,struct machine * machine)66f8ebb0cdSNamhyung Kim static int add_hist_entries(struct evlist *evlist, struct machine *machine)
6732dcd021SJiri Olsa {
68f8ebb0cdSNamhyung Kim struct evsel *evsel;
69f8ebb0cdSNamhyung Kim struct addr_location al;
70fd36f3ddSNamhyung Kim struct hist_entry *he;
71f8ebb0cdSNamhyung Kim struct perf_sample sample = { .period = 1, .weight = 1, };
72f8ebb0cdSNamhyung Kim size_t i = 0, k;
73f8ebb0cdSNamhyung Kim
74f8ebb0cdSNamhyung Kim addr_location__init(&al);
75f8ebb0cdSNamhyung Kim /*
76f8ebb0cdSNamhyung Kim * each evsel will have 10 samples - 5 common and 5 distinct.
77f8ebb0cdSNamhyung Kim * However the second evsel also has a collapsed entry for
78e5cadb93SArnaldo Carvalho de Melo * "bash [libc] malloc" so total 9 entries will be in the tree.
794ea062edSArnaldo Carvalho de Melo */
804ea062edSArnaldo Carvalho de Melo evlist__for_each_entry(evlist, evsel) {
81f8ebb0cdSNamhyung Kim struct hists *hists = evsel__hists(evsel);
82473398a2SArnaldo Carvalho de Melo
83ef89325fSAdrian Hunter for (k = 0; k < ARRAY_SIZE(fake_common_samples); k++) {
8413ce34dfSNamhyung Kim sample.cpumode = PERF_RECORD_MISC_USER;
85ef89325fSAdrian Hunter sample.pid = fake_common_samples[k].pid;
86bb3eb566SArnaldo Carvalho de Melo sample.tid = fake_common_samples[k].pid;
87bb3eb566SArnaldo Carvalho de Melo sample.ip = fake_common_samples[k].ip;
88f8ebb0cdSNamhyung Kim
89f8ebb0cdSNamhyung Kim if (machine__resolve(machine, &al, &sample) < 0)
900102ef3eSJiri Olsa goto out;
91ebf39d29SLeo Yan
92b91fc39fSArnaldo Carvalho de Melo he = hists__add_entry(hists, &al, NULL,
93b91fc39fSArnaldo Carvalho de Melo NULL, NULL, NULL, &sample, true);
94f8ebb0cdSNamhyung Kim if (he == NULL) {
95b91fc39fSArnaldo Carvalho de Melo goto out;
96f8ebb0cdSNamhyung Kim }
97f8ebb0cdSNamhyung Kim
98ec417ad4SIan Rogers thread__put(fake_common_samples[k].thread);
99f8ebb0cdSNamhyung Kim fake_common_samples[k].thread = thread__get(al.thread);
100f8ebb0cdSNamhyung Kim map__put(fake_common_samples[k].map);
101f8ebb0cdSNamhyung Kim fake_common_samples[k].map = map__get(al.map);
102f8ebb0cdSNamhyung Kim fake_common_samples[k].sym = al.sym;
103f8ebb0cdSNamhyung Kim }
104ef89325fSAdrian Hunter
10513ce34dfSNamhyung Kim for (k = 0; k < ARRAY_SIZE(fake_samples[i]); k++) {
106ef89325fSAdrian Hunter sample.pid = fake_samples[i][k].pid;
107bb3eb566SArnaldo Carvalho de Melo sample.tid = fake_samples[i][k].pid;
108f8ebb0cdSNamhyung Kim sample.ip = fake_samples[i][k].ip;
109f8ebb0cdSNamhyung Kim if (machine__resolve(machine, &al, &sample) < 0)
1100102ef3eSJiri Olsa goto out;
111ebf39d29SLeo Yan
112b91fc39fSArnaldo Carvalho de Melo he = hists__add_entry(hists, &al, NULL,
113b91fc39fSArnaldo Carvalho de Melo NULL, NULL, NULL, &sample, true);
114f8ebb0cdSNamhyung Kim if (he == NULL) {
115b91fc39fSArnaldo Carvalho de Melo goto out;
116f8ebb0cdSNamhyung Kim }
117f8ebb0cdSNamhyung Kim
118f8ebb0cdSNamhyung Kim thread__put(fake_samples[i][k].thread);
119f8ebb0cdSNamhyung Kim fake_samples[i][k].thread = thread__get(al.thread);
120f8ebb0cdSNamhyung Kim map__put(fake_samples[i][k].map);
121f8ebb0cdSNamhyung Kim fake_samples[i][k].map = map__get(al.map);
122f8ebb0cdSNamhyung Kim fake_samples[i][k].sym = al.sym;
123f8ebb0cdSNamhyung Kim }
124f8ebb0cdSNamhyung Kim i++;
125f8ebb0cdSNamhyung Kim }
126f8ebb0cdSNamhyung Kim
127f8ebb0cdSNamhyung Kim addr_location__exit(&al);
128f8ebb0cdSNamhyung Kim return 0;
129f8ebb0cdSNamhyung Kim out:
130f8ebb0cdSNamhyung Kim addr_location__exit(&al);
131ec417ad4SIan Rogers pr_debug("Not enough memory for adding a hist entry\n");
132ec417ad4SIan Rogers return -1;
133ec417ad4SIan Rogers }
134ec417ad4SIan Rogers
put_fake_samples(void)135ec417ad4SIan Rogers static void put_fake_samples(void)
136ec417ad4SIan Rogers {
137ec417ad4SIan Rogers size_t i, j;
138ec417ad4SIan Rogers
139ec417ad4SIan Rogers for (i = 0; i < ARRAY_SIZE(fake_common_samples); i++)
140ec417ad4SIan Rogers map__put(fake_common_samples[i].map);
141ec417ad4SIan Rogers for (i = 0; i < ARRAY_SIZE(fake_samples); i++) {
142ec417ad4SIan Rogers for (j = 0; j < ARRAY_SIZE(fake_samples[0]); j++)
143f8ebb0cdSNamhyung Kim map__put(fake_samples[i][j].map);
144f8ebb0cdSNamhyung Kim }
145f8ebb0cdSNamhyung Kim }
146f8ebb0cdSNamhyung Kim
find_sample(struct sample * samples,size_t nr_samples,struct thread * t,struct map * m,struct symbol * s)147ec417ad4SIan Rogers static int find_sample(struct sample *samples, size_t nr_samples,
148*2832ef81SIan Rogers struct thread *t, struct map *m, struct symbol *s)
149f8ebb0cdSNamhyung Kim {
150f8ebb0cdSNamhyung Kim while (nr_samples--) {
151f8ebb0cdSNamhyung Kim if (RC_CHK_ACCESS(samples->thread) == RC_CHK_ACCESS(t) &&
152f8ebb0cdSNamhyung Kim RC_CHK_ACCESS(samples->map) == RC_CHK_ACCESS(m) &&
153f8ebb0cdSNamhyung Kim samples->sym == s)
154f8ebb0cdSNamhyung Kim return 1;
155f8ebb0cdSNamhyung Kim samples++;
156f8ebb0cdSNamhyung Kim }
157f8ebb0cdSNamhyung Kim return 0;
158f8ebb0cdSNamhyung Kim }
1592eb3d689SDavidlohr Bueso
__validate_match(struct hists * hists)160f8ebb0cdSNamhyung Kim static int __validate_match(struct hists *hists)
161f8ebb0cdSNamhyung Kim {
162f8ebb0cdSNamhyung Kim size_t count = 0;
163f8ebb0cdSNamhyung Kim struct rb_root_cached *root;
164f8ebb0cdSNamhyung Kim struct rb_node *node;
16552225036SJiri Olsa
166f8ebb0cdSNamhyung Kim /*
167f8ebb0cdSNamhyung Kim * Only entries from fake_common_samples should have a pair.
168f8ebb0cdSNamhyung Kim */
169f8ebb0cdSNamhyung Kim if (hists__has(hists, need_collapse))
1702eb3d689SDavidlohr Bueso root = &hists->entries_collapsed;
171f8ebb0cdSNamhyung Kim else
172f8ebb0cdSNamhyung Kim root = hists->entries_in;
173f8ebb0cdSNamhyung Kim
174f8ebb0cdSNamhyung Kim node = rb_first_cached(root);
175f8ebb0cdSNamhyung Kim while (node) {
176f8ebb0cdSNamhyung Kim struct hist_entry *he;
177f8ebb0cdSNamhyung Kim
178f8ebb0cdSNamhyung Kim he = rb_entry(node, struct hist_entry, rb_node_in);
179f8ebb0cdSNamhyung Kim
180f8ebb0cdSNamhyung Kim if (hist_entry__has_pairs(he)) {
181f8ebb0cdSNamhyung Kim if (find_sample(fake_common_samples,
182f8ebb0cdSNamhyung Kim ARRAY_SIZE(fake_common_samples),
183f8ebb0cdSNamhyung Kim he->thread, he->ms.map, he->ms.sym)) {
184f8ebb0cdSNamhyung Kim count++;
185f8ebb0cdSNamhyung Kim } else {
186f8ebb0cdSNamhyung Kim pr_debug("Can't find the matched entry\n");
187f8ebb0cdSNamhyung Kim return -1;
188f8ebb0cdSNamhyung Kim }
189f8ebb0cdSNamhyung Kim }
190f8ebb0cdSNamhyung Kim
191f8ebb0cdSNamhyung Kim node = rb_next(node);
192f8ebb0cdSNamhyung Kim }
193f8ebb0cdSNamhyung Kim
194f8ebb0cdSNamhyung Kim if (count != ARRAY_SIZE(fake_common_samples)) {
195f8ebb0cdSNamhyung Kim pr_debug("Invalid count for matched entries: %zd of %zd\n",
196f8ebb0cdSNamhyung Kim count, ARRAY_SIZE(fake_common_samples));
197f8ebb0cdSNamhyung Kim return -1;
198f8ebb0cdSNamhyung Kim }
199f8ebb0cdSNamhyung Kim
200f8ebb0cdSNamhyung Kim return 0;
201f8ebb0cdSNamhyung Kim }
202f8ebb0cdSNamhyung Kim
validate_match(struct hists * leader,struct hists * other)203f8ebb0cdSNamhyung Kim static int validate_match(struct hists *leader, struct hists *other)
204f8ebb0cdSNamhyung Kim {
205f8ebb0cdSNamhyung Kim return __validate_match(leader) || __validate_match(other);
206f8ebb0cdSNamhyung Kim }
207f8ebb0cdSNamhyung Kim
__validate_link(struct hists * hists,int idx)208f8ebb0cdSNamhyung Kim static int __validate_link(struct hists *hists, int idx)
2092eb3d689SDavidlohr Bueso {
210f8ebb0cdSNamhyung Kim size_t count = 0;
211f8ebb0cdSNamhyung Kim size_t count_pair = 0;
212f8ebb0cdSNamhyung Kim size_t count_dummy = 0;
213f8ebb0cdSNamhyung Kim struct rb_root_cached *root;
214f8ebb0cdSNamhyung Kim struct rb_node *node;
215f8ebb0cdSNamhyung Kim
216f8ebb0cdSNamhyung Kim /*
21752225036SJiri Olsa * Leader hists (idx = 0) will have dummy entries from other,
218f8ebb0cdSNamhyung Kim * and some entries will have no pair. However every entry
219f8ebb0cdSNamhyung Kim * in other hists should have (dummy) pair.
220f8ebb0cdSNamhyung Kim */
221f8ebb0cdSNamhyung Kim if (hists__has(hists, need_collapse))
2222eb3d689SDavidlohr Bueso root = &hists->entries_collapsed;
223f8ebb0cdSNamhyung Kim else
224f8ebb0cdSNamhyung Kim root = hists->entries_in;
225f8ebb0cdSNamhyung Kim
226f8ebb0cdSNamhyung Kim node = rb_first_cached(root);
227f8ebb0cdSNamhyung Kim while (node) {
228f8ebb0cdSNamhyung Kim struct hist_entry *he;
229f8ebb0cdSNamhyung Kim
230f8ebb0cdSNamhyung Kim he = rb_entry(node, struct hist_entry, rb_node_in);
231f8ebb0cdSNamhyung Kim
232f8ebb0cdSNamhyung Kim if (hist_entry__has_pairs(he)) {
233f8ebb0cdSNamhyung Kim if (!find_sample(fake_common_samples,
234f8ebb0cdSNamhyung Kim ARRAY_SIZE(fake_common_samples),
235f8ebb0cdSNamhyung Kim he->thread, he->ms.map, he->ms.sym) &&
236f8ebb0cdSNamhyung Kim !find_sample(fake_samples[idx],
237f8ebb0cdSNamhyung Kim ARRAY_SIZE(fake_samples[idx]),
238f8ebb0cdSNamhyung Kim he->thread, he->ms.map, he->ms.sym)) {
239f8ebb0cdSNamhyung Kim count_dummy++;
240f8ebb0cdSNamhyung Kim }
241f8ebb0cdSNamhyung Kim count_pair++;
242f8ebb0cdSNamhyung Kim } else if (idx) {
243f8ebb0cdSNamhyung Kim pr_debug("A entry from the other hists should have pair\n");
244f8ebb0cdSNamhyung Kim return -1;
245f8ebb0cdSNamhyung Kim }
246f8ebb0cdSNamhyung Kim
247f8ebb0cdSNamhyung Kim count++;
248f8ebb0cdSNamhyung Kim node = rb_next(node);
249f8ebb0cdSNamhyung Kim }
250f8ebb0cdSNamhyung Kim
251f8ebb0cdSNamhyung Kim /*
252f8ebb0cdSNamhyung Kim * Note that we have a entry collapsed in the other (idx = 1) hists.
253f8ebb0cdSNamhyung Kim */
254f8ebb0cdSNamhyung Kim if (idx == 0) {
255f8ebb0cdSNamhyung Kim if (count_dummy != ARRAY_SIZE(fake_samples[1]) - 1) {
256f8ebb0cdSNamhyung Kim pr_debug("Invalid count of dummy entries: %zd of %zd\n",
257f8ebb0cdSNamhyung Kim count_dummy, ARRAY_SIZE(fake_samples[1]) - 1);
258f8ebb0cdSNamhyung Kim return -1;
259f8ebb0cdSNamhyung Kim }
260f8ebb0cdSNamhyung Kim if (count != count_pair + ARRAY_SIZE(fake_samples[0])) {
261f8ebb0cdSNamhyung Kim pr_debug("Invalid count of total leader entries: %zd of %zd\n",
262f8ebb0cdSNamhyung Kim count, count_pair + ARRAY_SIZE(fake_samples[0]));
263f8ebb0cdSNamhyung Kim return -1;
264f8ebb0cdSNamhyung Kim }
265f8ebb0cdSNamhyung Kim } else {
266f8ebb0cdSNamhyung Kim if (count != count_pair) {
267f8ebb0cdSNamhyung Kim pr_debug("Invalid count of total other entries: %zd of %zd\n",
268f8ebb0cdSNamhyung Kim count, count_pair);
269f8ebb0cdSNamhyung Kim return -1;
270f8ebb0cdSNamhyung Kim }
271f8ebb0cdSNamhyung Kim if (count_dummy > 0) {
272f8ebb0cdSNamhyung Kim pr_debug("Other hists should not have dummy entries: %zd\n",
273f8ebb0cdSNamhyung Kim count_dummy);
274f8ebb0cdSNamhyung Kim return -1;
275f8ebb0cdSNamhyung Kim }
276f8ebb0cdSNamhyung Kim }
277f8ebb0cdSNamhyung Kim
278f8ebb0cdSNamhyung Kim return 0;
279f8ebb0cdSNamhyung Kim }
280f8ebb0cdSNamhyung Kim
validate_link(struct hists * leader,struct hists * other)281f8ebb0cdSNamhyung Kim static int validate_link(struct hists *leader, struct hists *other)
28233f44bfdSIan Rogers {
283f8ebb0cdSNamhyung Kim return __validate_link(leader, 0) || __validate_link(other, 1);
284f8ebb0cdSNamhyung Kim }
2854ea062edSArnaldo Carvalho de Melo
test__hists_link(struct test_suite * test __maybe_unused,int subtest __maybe_unused)286876650e6SArnaldo Carvalho de Melo static int test__hists_link(struct test_suite *test __maybe_unused, int subtest __maybe_unused)
287f8ebb0cdSNamhyung Kim {
28832dcd021SJiri Olsa int err = -1;
2890f98b11cSJiri Olsa struct hists *hists, *first_hists;
290f8ebb0cdSNamhyung Kim struct machines machines;
291f8ebb0cdSNamhyung Kim struct machine *machine = NULL;
292f8ebb0cdSNamhyung Kim struct evsel *evsel, *first;
293f8ebb0cdSNamhyung Kim struct evlist *evlist = evlist__new();
294806731a9SAdrian Hunter
295f8ebb0cdSNamhyung Kim if (evlist == NULL)
296f8ebb0cdSNamhyung Kim return -ENOMEM;
297806731a9SAdrian Hunter
298f8ebb0cdSNamhyung Kim err = parse_event(evlist, "cpu-clock");
299f8ebb0cdSNamhyung Kim if (err)
300f8ebb0cdSNamhyung Kim goto out;
301b0500c16SWang Nan err = parse_event(evlist, "task-clock");
302f8ebb0cdSNamhyung Kim if (err)
30340184c46SNamhyung Kim goto out;
30455309985SNamhyung Kim
305f8ebb0cdSNamhyung Kim err = TEST_FAIL;
306876650e6SArnaldo Carvalho de Melo /* default sort order (comm,dso,sym) will be used */
307876650e6SArnaldo Carvalho de Melo if (setup_sorting(NULL) < 0)
308f8ebb0cdSNamhyung Kim goto out;
309876650e6SArnaldo Carvalho de Melo
310f8ebb0cdSNamhyung Kim machines__init(&machines);
311f8ebb0cdSNamhyung Kim
312f8ebb0cdSNamhyung Kim /* setup threads/dso/map/symbols also */
313f8ebb0cdSNamhyung Kim machine = setup_fake_machine(&machines);
314f8ebb0cdSNamhyung Kim if (!machine)
315f8ebb0cdSNamhyung Kim goto out;
316f8ebb0cdSNamhyung Kim
317f8ebb0cdSNamhyung Kim if (verbose > 1)
318f8ebb0cdSNamhyung Kim machine__fprintf(machine, stderr);
319f8ebb0cdSNamhyung Kim
320f8ebb0cdSNamhyung Kim /* process sample events */
321e5cadb93SArnaldo Carvalho de Melo err = add_hist_entries(evlist, machine);
3224ea062edSArnaldo Carvalho de Melo if (err < 0)
3234ea062edSArnaldo Carvalho de Melo goto out;
324f8ebb0cdSNamhyung Kim
325f8ebb0cdSNamhyung Kim evlist__for_each_entry(evlist, evsel) {
3264ea062edSArnaldo Carvalho de Melo hists = evsel__hists(evsel);
327f8ebb0cdSNamhyung Kim hists__collapse_resort(hists, NULL);
328f8ebb0cdSNamhyung Kim
329515dbe48SJiri Olsa if (verbose > 2)
330515dbe48SJiri Olsa print_hists_in(hists);
331f8ebb0cdSNamhyung Kim }
3324ea062edSArnaldo Carvalho de Melo
3334ea062edSArnaldo Carvalho de Melo first = evlist__first(evlist);
3344ea062edSArnaldo Carvalho de Melo evsel = evlist__last(evlist);
335f8ebb0cdSNamhyung Kim
3364ea062edSArnaldo Carvalho de Melo first_hists = evsel__hists(first);
3374ea062edSArnaldo Carvalho de Melo hists = evsel__hists(evsel);
338f8ebb0cdSNamhyung Kim
339f8ebb0cdSNamhyung Kim /* match common entries */
340f8ebb0cdSNamhyung Kim hists__match(first_hists, hists);
341f8ebb0cdSNamhyung Kim err = validate_match(first_hists, hists);
3424ea062edSArnaldo Carvalho de Melo if (err)
3434ea062edSArnaldo Carvalho de Melo goto out;
344f8ebb0cdSNamhyung Kim
345f8ebb0cdSNamhyung Kim /* link common and/or dummy entries */
346f8ebb0cdSNamhyung Kim hists__link(first_hists, hists);
347f8ebb0cdSNamhyung Kim err = validate_link(first_hists, hists);
348f8ebb0cdSNamhyung Kim if (err)
349f8ebb0cdSNamhyung Kim goto out;
350f8ebb0cdSNamhyung Kim
351c12995a5SJiri Olsa err = 0;
352f21d1815SNamhyung Kim
353876650e6SArnaldo Carvalho de Melo out:
354ec417ad4SIan Rogers /* tear down everything */
355f8ebb0cdSNamhyung Kim evlist__delete(evlist);
356f8ebb0cdSNamhyung Kim reset_output_field();
357f8ebb0cdSNamhyung Kim machines__exit(&machines);
358d68f0365SIan Rogers put_fake_samples();
359d68f0365SIan Rogers
360 return err;
361 }
362
363 DEFINE_SUITE("Match and link multiple hists", hists_link);
364