18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0
28c2ecf20Sopenharmony_ci#include "tests.h"
38c2ecf20Sopenharmony_ci#include "debug.h"
48c2ecf20Sopenharmony_ci#include "symbol.h"
58c2ecf20Sopenharmony_ci#include "sort.h"
68c2ecf20Sopenharmony_ci#include "evsel.h"
78c2ecf20Sopenharmony_ci#include "evlist.h"
88c2ecf20Sopenharmony_ci#include "machine.h"
98c2ecf20Sopenharmony_ci#include "parse-events.h"
108c2ecf20Sopenharmony_ci#include "hists_common.h"
118c2ecf20Sopenharmony_ci#include "util/mmap.h"
128c2ecf20Sopenharmony_ci#include <errno.h>
138c2ecf20Sopenharmony_ci#include <linux/kernel.h>
148c2ecf20Sopenharmony_ci
158c2ecf20Sopenharmony_cistruct sample {
168c2ecf20Sopenharmony_ci	u32 pid;
178c2ecf20Sopenharmony_ci	u64 ip;
188c2ecf20Sopenharmony_ci	struct thread *thread;
198c2ecf20Sopenharmony_ci	struct map *map;
208c2ecf20Sopenharmony_ci	struct symbol *sym;
218c2ecf20Sopenharmony_ci};
228c2ecf20Sopenharmony_ci
238c2ecf20Sopenharmony_ci/* For the numbers, see hists_common.c */
248c2ecf20Sopenharmony_cistatic struct sample fake_common_samples[] = {
258c2ecf20Sopenharmony_ci	/* perf [kernel] schedule() */
268c2ecf20Sopenharmony_ci	{ .pid = FAKE_PID_PERF1, .ip = FAKE_IP_KERNEL_SCHEDULE, },
278c2ecf20Sopenharmony_ci	/* perf [perf]   main() */
288c2ecf20Sopenharmony_ci	{ .pid = FAKE_PID_PERF2, .ip = FAKE_IP_PERF_MAIN, },
298c2ecf20Sopenharmony_ci	/* perf [perf]   cmd_record() */
308c2ecf20Sopenharmony_ci	{ .pid = FAKE_PID_PERF2, .ip = FAKE_IP_PERF_CMD_RECORD, },
318c2ecf20Sopenharmony_ci	/* bash [bash]   xmalloc() */
328c2ecf20Sopenharmony_ci	{ .pid = FAKE_PID_BASH,  .ip = FAKE_IP_BASH_XMALLOC, },
338c2ecf20Sopenharmony_ci	/* bash [libc]   malloc() */
348c2ecf20Sopenharmony_ci	{ .pid = FAKE_PID_BASH,  .ip = FAKE_IP_LIBC_MALLOC, },
358c2ecf20Sopenharmony_ci};
368c2ecf20Sopenharmony_ci
378c2ecf20Sopenharmony_cistatic struct sample fake_samples[][5] = {
388c2ecf20Sopenharmony_ci	{
398c2ecf20Sopenharmony_ci		/* perf [perf]   run_command() */
408c2ecf20Sopenharmony_ci		{ .pid = FAKE_PID_PERF1, .ip = FAKE_IP_PERF_RUN_COMMAND, },
418c2ecf20Sopenharmony_ci		/* perf [libc]   malloc() */
428c2ecf20Sopenharmony_ci		{ .pid = FAKE_PID_PERF1, .ip = FAKE_IP_LIBC_MALLOC, },
438c2ecf20Sopenharmony_ci		/* perf [kernel] page_fault() */
448c2ecf20Sopenharmony_ci		{ .pid = FAKE_PID_PERF1, .ip = FAKE_IP_KERNEL_PAGE_FAULT, },
458c2ecf20Sopenharmony_ci		/* perf [kernel] sys_perf_event_open() */
468c2ecf20Sopenharmony_ci		{ .pid = FAKE_PID_PERF2, .ip = FAKE_IP_KERNEL_SYS_PERF_EVENT_OPEN, },
478c2ecf20Sopenharmony_ci		/* bash [libc]   free() */
488c2ecf20Sopenharmony_ci		{ .pid = FAKE_PID_BASH,  .ip = FAKE_IP_LIBC_FREE, },
498c2ecf20Sopenharmony_ci	},
508c2ecf20Sopenharmony_ci	{
518c2ecf20Sopenharmony_ci		/* perf [libc]   free() */
528c2ecf20Sopenharmony_ci		{ .pid = FAKE_PID_PERF2, .ip = FAKE_IP_LIBC_FREE, },
538c2ecf20Sopenharmony_ci		/* bash [libc]   malloc() */
548c2ecf20Sopenharmony_ci		{ .pid = FAKE_PID_BASH,  .ip = FAKE_IP_LIBC_MALLOC, }, /* will be merged */
558c2ecf20Sopenharmony_ci		/* bash [bash]   xfee() */
568c2ecf20Sopenharmony_ci		{ .pid = FAKE_PID_BASH,  .ip = FAKE_IP_BASH_XFREE, },
578c2ecf20Sopenharmony_ci		/* bash [libc]   realloc() */
588c2ecf20Sopenharmony_ci		{ .pid = FAKE_PID_BASH,  .ip = FAKE_IP_LIBC_REALLOC, },
598c2ecf20Sopenharmony_ci		/* bash [kernel] page_fault() */
608c2ecf20Sopenharmony_ci		{ .pid = FAKE_PID_BASH,  .ip = FAKE_IP_KERNEL_PAGE_FAULT, },
618c2ecf20Sopenharmony_ci	},
628c2ecf20Sopenharmony_ci};
638c2ecf20Sopenharmony_ci
648c2ecf20Sopenharmony_cistatic int add_hist_entries(struct evlist *evlist, struct machine *machine)
658c2ecf20Sopenharmony_ci{
668c2ecf20Sopenharmony_ci	struct evsel *evsel;
678c2ecf20Sopenharmony_ci	struct addr_location al;
688c2ecf20Sopenharmony_ci	struct hist_entry *he;
698c2ecf20Sopenharmony_ci	struct perf_sample sample = { .period = 1, .weight = 1, };
708c2ecf20Sopenharmony_ci	size_t i = 0, k;
718c2ecf20Sopenharmony_ci
728c2ecf20Sopenharmony_ci	/*
738c2ecf20Sopenharmony_ci	 * each evsel will have 10 samples - 5 common and 5 distinct.
748c2ecf20Sopenharmony_ci	 * However the second evsel also has a collapsed entry for
758c2ecf20Sopenharmony_ci	 * "bash [libc] malloc" so total 9 entries will be in the tree.
768c2ecf20Sopenharmony_ci	 */
778c2ecf20Sopenharmony_ci	evlist__for_each_entry(evlist, evsel) {
788c2ecf20Sopenharmony_ci		struct hists *hists = evsel__hists(evsel);
798c2ecf20Sopenharmony_ci
808c2ecf20Sopenharmony_ci		for (k = 0; k < ARRAY_SIZE(fake_common_samples); k++) {
818c2ecf20Sopenharmony_ci			sample.cpumode = PERF_RECORD_MISC_USER;
828c2ecf20Sopenharmony_ci			sample.pid = fake_common_samples[k].pid;
838c2ecf20Sopenharmony_ci			sample.tid = fake_common_samples[k].pid;
848c2ecf20Sopenharmony_ci			sample.ip = fake_common_samples[k].ip;
858c2ecf20Sopenharmony_ci
868c2ecf20Sopenharmony_ci			if (machine__resolve(machine, &al, &sample) < 0)
878c2ecf20Sopenharmony_ci				goto out;
888c2ecf20Sopenharmony_ci
898c2ecf20Sopenharmony_ci			he = hists__add_entry(hists, &al, NULL,
908c2ecf20Sopenharmony_ci						NULL, NULL, &sample, true);
918c2ecf20Sopenharmony_ci			if (he == NULL) {
928c2ecf20Sopenharmony_ci				addr_location__put(&al);
938c2ecf20Sopenharmony_ci				goto out;
948c2ecf20Sopenharmony_ci			}
958c2ecf20Sopenharmony_ci
968c2ecf20Sopenharmony_ci			fake_common_samples[k].thread = al.thread;
978c2ecf20Sopenharmony_ci			fake_common_samples[k].map = al.map;
988c2ecf20Sopenharmony_ci			fake_common_samples[k].sym = al.sym;
998c2ecf20Sopenharmony_ci		}
1008c2ecf20Sopenharmony_ci
1018c2ecf20Sopenharmony_ci		for (k = 0; k < ARRAY_SIZE(fake_samples[i]); k++) {
1028c2ecf20Sopenharmony_ci			sample.pid = fake_samples[i][k].pid;
1038c2ecf20Sopenharmony_ci			sample.tid = fake_samples[i][k].pid;
1048c2ecf20Sopenharmony_ci			sample.ip = fake_samples[i][k].ip;
1058c2ecf20Sopenharmony_ci			if (machine__resolve(machine, &al, &sample) < 0)
1068c2ecf20Sopenharmony_ci				goto out;
1078c2ecf20Sopenharmony_ci
1088c2ecf20Sopenharmony_ci			he = hists__add_entry(hists, &al, NULL,
1098c2ecf20Sopenharmony_ci						NULL, NULL, &sample, true);
1108c2ecf20Sopenharmony_ci			if (he == NULL) {
1118c2ecf20Sopenharmony_ci				addr_location__put(&al);
1128c2ecf20Sopenharmony_ci				goto out;
1138c2ecf20Sopenharmony_ci			}
1148c2ecf20Sopenharmony_ci
1158c2ecf20Sopenharmony_ci			fake_samples[i][k].thread = al.thread;
1168c2ecf20Sopenharmony_ci			fake_samples[i][k].map = al.map;
1178c2ecf20Sopenharmony_ci			fake_samples[i][k].sym = al.sym;
1188c2ecf20Sopenharmony_ci		}
1198c2ecf20Sopenharmony_ci		i++;
1208c2ecf20Sopenharmony_ci	}
1218c2ecf20Sopenharmony_ci
1228c2ecf20Sopenharmony_ci	return 0;
1238c2ecf20Sopenharmony_ci
1248c2ecf20Sopenharmony_ciout:
1258c2ecf20Sopenharmony_ci	pr_debug("Not enough memory for adding a hist entry\n");
1268c2ecf20Sopenharmony_ci	return -1;
1278c2ecf20Sopenharmony_ci}
1288c2ecf20Sopenharmony_ci
1298c2ecf20Sopenharmony_cistatic int find_sample(struct sample *samples, size_t nr_samples,
1308c2ecf20Sopenharmony_ci		       struct thread *t, struct map *m, struct symbol *s)
1318c2ecf20Sopenharmony_ci{
1328c2ecf20Sopenharmony_ci	while (nr_samples--) {
1338c2ecf20Sopenharmony_ci		if (samples->thread == t && samples->map == m &&
1348c2ecf20Sopenharmony_ci		    samples->sym == s)
1358c2ecf20Sopenharmony_ci			return 1;
1368c2ecf20Sopenharmony_ci		samples++;
1378c2ecf20Sopenharmony_ci	}
1388c2ecf20Sopenharmony_ci	return 0;
1398c2ecf20Sopenharmony_ci}
1408c2ecf20Sopenharmony_ci
1418c2ecf20Sopenharmony_cistatic int __validate_match(struct hists *hists)
1428c2ecf20Sopenharmony_ci{
1438c2ecf20Sopenharmony_ci	size_t count = 0;
1448c2ecf20Sopenharmony_ci	struct rb_root_cached *root;
1458c2ecf20Sopenharmony_ci	struct rb_node *node;
1468c2ecf20Sopenharmony_ci
1478c2ecf20Sopenharmony_ci	/*
1488c2ecf20Sopenharmony_ci	 * Only entries from fake_common_samples should have a pair.
1498c2ecf20Sopenharmony_ci	 */
1508c2ecf20Sopenharmony_ci	if (hists__has(hists, need_collapse))
1518c2ecf20Sopenharmony_ci		root = &hists->entries_collapsed;
1528c2ecf20Sopenharmony_ci	else
1538c2ecf20Sopenharmony_ci		root = hists->entries_in;
1548c2ecf20Sopenharmony_ci
1558c2ecf20Sopenharmony_ci	node = rb_first_cached(root);
1568c2ecf20Sopenharmony_ci	while (node) {
1578c2ecf20Sopenharmony_ci		struct hist_entry *he;
1588c2ecf20Sopenharmony_ci
1598c2ecf20Sopenharmony_ci		he = rb_entry(node, struct hist_entry, rb_node_in);
1608c2ecf20Sopenharmony_ci
1618c2ecf20Sopenharmony_ci		if (hist_entry__has_pairs(he)) {
1628c2ecf20Sopenharmony_ci			if (find_sample(fake_common_samples,
1638c2ecf20Sopenharmony_ci					ARRAY_SIZE(fake_common_samples),
1648c2ecf20Sopenharmony_ci					he->thread, he->ms.map, he->ms.sym)) {
1658c2ecf20Sopenharmony_ci				count++;
1668c2ecf20Sopenharmony_ci			} else {
1678c2ecf20Sopenharmony_ci				pr_debug("Can't find the matched entry\n");
1688c2ecf20Sopenharmony_ci				return -1;
1698c2ecf20Sopenharmony_ci			}
1708c2ecf20Sopenharmony_ci		}
1718c2ecf20Sopenharmony_ci
1728c2ecf20Sopenharmony_ci		node = rb_next(node);
1738c2ecf20Sopenharmony_ci	}
1748c2ecf20Sopenharmony_ci
1758c2ecf20Sopenharmony_ci	if (count != ARRAY_SIZE(fake_common_samples)) {
1768c2ecf20Sopenharmony_ci		pr_debug("Invalid count for matched entries: %zd of %zd\n",
1778c2ecf20Sopenharmony_ci			 count, ARRAY_SIZE(fake_common_samples));
1788c2ecf20Sopenharmony_ci		return -1;
1798c2ecf20Sopenharmony_ci	}
1808c2ecf20Sopenharmony_ci
1818c2ecf20Sopenharmony_ci	return 0;
1828c2ecf20Sopenharmony_ci}
1838c2ecf20Sopenharmony_ci
1848c2ecf20Sopenharmony_cistatic int validate_match(struct hists *leader, struct hists *other)
1858c2ecf20Sopenharmony_ci{
1868c2ecf20Sopenharmony_ci	return __validate_match(leader) || __validate_match(other);
1878c2ecf20Sopenharmony_ci}
1888c2ecf20Sopenharmony_ci
1898c2ecf20Sopenharmony_cistatic int __validate_link(struct hists *hists, int idx)
1908c2ecf20Sopenharmony_ci{
1918c2ecf20Sopenharmony_ci	size_t count = 0;
1928c2ecf20Sopenharmony_ci	size_t count_pair = 0;
1938c2ecf20Sopenharmony_ci	size_t count_dummy = 0;
1948c2ecf20Sopenharmony_ci	struct rb_root_cached *root;
1958c2ecf20Sopenharmony_ci	struct rb_node *node;
1968c2ecf20Sopenharmony_ci
1978c2ecf20Sopenharmony_ci	/*
1988c2ecf20Sopenharmony_ci	 * Leader hists (idx = 0) will have dummy entries from other,
1998c2ecf20Sopenharmony_ci	 * and some entries will have no pair.  However every entry
2008c2ecf20Sopenharmony_ci	 * in other hists should have (dummy) pair.
2018c2ecf20Sopenharmony_ci	 */
2028c2ecf20Sopenharmony_ci	if (hists__has(hists, need_collapse))
2038c2ecf20Sopenharmony_ci		root = &hists->entries_collapsed;
2048c2ecf20Sopenharmony_ci	else
2058c2ecf20Sopenharmony_ci		root = hists->entries_in;
2068c2ecf20Sopenharmony_ci
2078c2ecf20Sopenharmony_ci	node = rb_first_cached(root);
2088c2ecf20Sopenharmony_ci	while (node) {
2098c2ecf20Sopenharmony_ci		struct hist_entry *he;
2108c2ecf20Sopenharmony_ci
2118c2ecf20Sopenharmony_ci		he = rb_entry(node, struct hist_entry, rb_node_in);
2128c2ecf20Sopenharmony_ci
2138c2ecf20Sopenharmony_ci		if (hist_entry__has_pairs(he)) {
2148c2ecf20Sopenharmony_ci			if (!find_sample(fake_common_samples,
2158c2ecf20Sopenharmony_ci					 ARRAY_SIZE(fake_common_samples),
2168c2ecf20Sopenharmony_ci					 he->thread, he->ms.map, he->ms.sym) &&
2178c2ecf20Sopenharmony_ci			    !find_sample(fake_samples[idx],
2188c2ecf20Sopenharmony_ci					 ARRAY_SIZE(fake_samples[idx]),
2198c2ecf20Sopenharmony_ci					 he->thread, he->ms.map, he->ms.sym)) {
2208c2ecf20Sopenharmony_ci				count_dummy++;
2218c2ecf20Sopenharmony_ci			}
2228c2ecf20Sopenharmony_ci			count_pair++;
2238c2ecf20Sopenharmony_ci		} else if (idx) {
2248c2ecf20Sopenharmony_ci			pr_debug("A entry from the other hists should have pair\n");
2258c2ecf20Sopenharmony_ci			return -1;
2268c2ecf20Sopenharmony_ci		}
2278c2ecf20Sopenharmony_ci
2288c2ecf20Sopenharmony_ci		count++;
2298c2ecf20Sopenharmony_ci		node = rb_next(node);
2308c2ecf20Sopenharmony_ci	}
2318c2ecf20Sopenharmony_ci
2328c2ecf20Sopenharmony_ci	/*
2338c2ecf20Sopenharmony_ci	 * Note that we have a entry collapsed in the other (idx = 1) hists.
2348c2ecf20Sopenharmony_ci	 */
2358c2ecf20Sopenharmony_ci	if (idx == 0) {
2368c2ecf20Sopenharmony_ci		if (count_dummy != ARRAY_SIZE(fake_samples[1]) - 1) {
2378c2ecf20Sopenharmony_ci			pr_debug("Invalid count of dummy entries: %zd of %zd\n",
2388c2ecf20Sopenharmony_ci				 count_dummy, ARRAY_SIZE(fake_samples[1]) - 1);
2398c2ecf20Sopenharmony_ci			return -1;
2408c2ecf20Sopenharmony_ci		}
2418c2ecf20Sopenharmony_ci		if (count != count_pair + ARRAY_SIZE(fake_samples[0])) {
2428c2ecf20Sopenharmony_ci			pr_debug("Invalid count of total leader entries: %zd of %zd\n",
2438c2ecf20Sopenharmony_ci				 count, count_pair + ARRAY_SIZE(fake_samples[0]));
2448c2ecf20Sopenharmony_ci			return -1;
2458c2ecf20Sopenharmony_ci		}
2468c2ecf20Sopenharmony_ci	} else {
2478c2ecf20Sopenharmony_ci		if (count != count_pair) {
2488c2ecf20Sopenharmony_ci			pr_debug("Invalid count of total other entries: %zd of %zd\n",
2498c2ecf20Sopenharmony_ci				 count, count_pair);
2508c2ecf20Sopenharmony_ci			return -1;
2518c2ecf20Sopenharmony_ci		}
2528c2ecf20Sopenharmony_ci		if (count_dummy > 0) {
2538c2ecf20Sopenharmony_ci			pr_debug("Other hists should not have dummy entries: %zd\n",
2548c2ecf20Sopenharmony_ci				 count_dummy);
2558c2ecf20Sopenharmony_ci			return -1;
2568c2ecf20Sopenharmony_ci		}
2578c2ecf20Sopenharmony_ci	}
2588c2ecf20Sopenharmony_ci
2598c2ecf20Sopenharmony_ci	return 0;
2608c2ecf20Sopenharmony_ci}
2618c2ecf20Sopenharmony_ci
2628c2ecf20Sopenharmony_cistatic int validate_link(struct hists *leader, struct hists *other)
2638c2ecf20Sopenharmony_ci{
2648c2ecf20Sopenharmony_ci	return __validate_link(leader, 0) || __validate_link(other, 1);
2658c2ecf20Sopenharmony_ci}
2668c2ecf20Sopenharmony_ci
2678c2ecf20Sopenharmony_ciint test__hists_link(struct test *test __maybe_unused, int subtest __maybe_unused)
2688c2ecf20Sopenharmony_ci{
2698c2ecf20Sopenharmony_ci	int err = -1;
2708c2ecf20Sopenharmony_ci	struct hists *hists, *first_hists;
2718c2ecf20Sopenharmony_ci	struct machines machines;
2728c2ecf20Sopenharmony_ci	struct machine *machine = NULL;
2738c2ecf20Sopenharmony_ci	struct evsel *evsel, *first;
2748c2ecf20Sopenharmony_ci	struct evlist *evlist = evlist__new();
2758c2ecf20Sopenharmony_ci
2768c2ecf20Sopenharmony_ci	if (evlist == NULL)
2778c2ecf20Sopenharmony_ci                return -ENOMEM;
2788c2ecf20Sopenharmony_ci
2798c2ecf20Sopenharmony_ci	err = parse_events(evlist, "cpu-clock", NULL);
2808c2ecf20Sopenharmony_ci	if (err)
2818c2ecf20Sopenharmony_ci		goto out;
2828c2ecf20Sopenharmony_ci	err = parse_events(evlist, "task-clock", NULL);
2838c2ecf20Sopenharmony_ci	if (err)
2848c2ecf20Sopenharmony_ci		goto out;
2858c2ecf20Sopenharmony_ci
2868c2ecf20Sopenharmony_ci	err = TEST_FAIL;
2878c2ecf20Sopenharmony_ci	/* default sort order (comm,dso,sym) will be used */
2888c2ecf20Sopenharmony_ci	if (setup_sorting(NULL) < 0)
2898c2ecf20Sopenharmony_ci		goto out;
2908c2ecf20Sopenharmony_ci
2918c2ecf20Sopenharmony_ci	machines__init(&machines);
2928c2ecf20Sopenharmony_ci
2938c2ecf20Sopenharmony_ci	/* setup threads/dso/map/symbols also */
2948c2ecf20Sopenharmony_ci	machine = setup_fake_machine(&machines);
2958c2ecf20Sopenharmony_ci	if (!machine)
2968c2ecf20Sopenharmony_ci		goto out;
2978c2ecf20Sopenharmony_ci
2988c2ecf20Sopenharmony_ci	if (verbose > 1)
2998c2ecf20Sopenharmony_ci		machine__fprintf(machine, stderr);
3008c2ecf20Sopenharmony_ci
3018c2ecf20Sopenharmony_ci	/* process sample events */
3028c2ecf20Sopenharmony_ci	err = add_hist_entries(evlist, machine);
3038c2ecf20Sopenharmony_ci	if (err < 0)
3048c2ecf20Sopenharmony_ci		goto out;
3058c2ecf20Sopenharmony_ci
3068c2ecf20Sopenharmony_ci	evlist__for_each_entry(evlist, evsel) {
3078c2ecf20Sopenharmony_ci		hists = evsel__hists(evsel);
3088c2ecf20Sopenharmony_ci		hists__collapse_resort(hists, NULL);
3098c2ecf20Sopenharmony_ci
3108c2ecf20Sopenharmony_ci		if (verbose > 2)
3118c2ecf20Sopenharmony_ci			print_hists_in(hists);
3128c2ecf20Sopenharmony_ci	}
3138c2ecf20Sopenharmony_ci
3148c2ecf20Sopenharmony_ci	first = evlist__first(evlist);
3158c2ecf20Sopenharmony_ci	evsel = evlist__last(evlist);
3168c2ecf20Sopenharmony_ci
3178c2ecf20Sopenharmony_ci	first_hists = evsel__hists(first);
3188c2ecf20Sopenharmony_ci	hists = evsel__hists(evsel);
3198c2ecf20Sopenharmony_ci
3208c2ecf20Sopenharmony_ci	/* match common entries */
3218c2ecf20Sopenharmony_ci	hists__match(first_hists, hists);
3228c2ecf20Sopenharmony_ci	err = validate_match(first_hists, hists);
3238c2ecf20Sopenharmony_ci	if (err)
3248c2ecf20Sopenharmony_ci		goto out;
3258c2ecf20Sopenharmony_ci
3268c2ecf20Sopenharmony_ci	/* link common and/or dummy entries */
3278c2ecf20Sopenharmony_ci	hists__link(first_hists, hists);
3288c2ecf20Sopenharmony_ci	err = validate_link(first_hists, hists);
3298c2ecf20Sopenharmony_ci	if (err)
3308c2ecf20Sopenharmony_ci		goto out;
3318c2ecf20Sopenharmony_ci
3328c2ecf20Sopenharmony_ci	err = 0;
3338c2ecf20Sopenharmony_ci
3348c2ecf20Sopenharmony_ciout:
3358c2ecf20Sopenharmony_ci	/* tear down everything */
3368c2ecf20Sopenharmony_ci	evlist__delete(evlist);
3378c2ecf20Sopenharmony_ci	reset_output_field();
3388c2ecf20Sopenharmony_ci	machines__exit(&machines);
3398c2ecf20Sopenharmony_ci
3408c2ecf20Sopenharmony_ci	return err;
3418c2ecf20Sopenharmony_ci}
342