xref: /openbmc/linux/tools/perf/tests/task-exit.c (revision c900529f3d9161bfde5cca0754f83b4d3c3e0220)
1b2441318SGreg Kroah-Hartman // SPDX-License-Identifier: GPL-2.0
2b4209025SArnaldo Carvalho de Melo #include "debug.h"
3d723a550SNamhyung Kim #include "evlist.h"
4d723a550SNamhyung Kim #include "evsel.h"
5aeb00b1aSArnaldo Carvalho de Melo #include "target.h"
6d723a550SNamhyung Kim #include "thread_map.h"
7d723a550SNamhyung Kim #include "tests.h"
8e0fcfb08SArnaldo Carvalho de Melo #include "util/mmap.h"
9d723a550SNamhyung Kim 
10a43783aeSArnaldo Carvalho de Melo #include <errno.h>
11d723a550SNamhyung Kim #include <signal.h>
128520a98dSArnaldo Carvalho de Melo #include <linux/string.h>
1387ffb6c6SArnaldo Carvalho de Melo #include <perf/cpumap.h>
14453fa030SJiri Olsa #include <perf/evlist.h>
157728fa0cSJiri Olsa #include <perf/mmap.h>
16d723a550SNamhyung Kim 
17d723a550SNamhyung Kim static int exited;
18d723a550SNamhyung Kim static int nr_exit;
19d723a550SNamhyung Kim 
sig_handler(int sig __maybe_unused)20735f7e0bSArnaldo Carvalho de Melo static void sig_handler(int sig __maybe_unused)
21d723a550SNamhyung Kim {
22d723a550SNamhyung Kim 	exited = 1;
23735f7e0bSArnaldo Carvalho de Melo }
24d723a550SNamhyung Kim 
25735f7e0bSArnaldo Carvalho de Melo /*
267b392ef0SArnaldo Carvalho de Melo  * evlist__prepare_workload will send a SIGUSR1 if the fork fails, since
27735f7e0bSArnaldo Carvalho de Melo  * we asked by setting its exec_error to this handler.
28735f7e0bSArnaldo Carvalho de Melo  */
workload_exec_failed_signal(int signo __maybe_unused,siginfo_t * info __maybe_unused,void * ucontext __maybe_unused)29735f7e0bSArnaldo Carvalho de Melo static void workload_exec_failed_signal(int signo __maybe_unused,
30735f7e0bSArnaldo Carvalho de Melo 					siginfo_t *info __maybe_unused,
31735f7e0bSArnaldo Carvalho de Melo 					void *ucontext __maybe_unused)
32735f7e0bSArnaldo Carvalho de Melo {
33735f7e0bSArnaldo Carvalho de Melo 	exited	= 1;
34d723a550SNamhyung Kim 	nr_exit = -1;
35d723a550SNamhyung Kim }
36d723a550SNamhyung Kim 
37d723a550SNamhyung Kim /*
38d723a550SNamhyung Kim  * This test will start a workload that does nothing then it checks
39d723a550SNamhyung Kim  * if the number of exit event reported by the kernel is 1 or not
40d723a550SNamhyung Kim  * in order to check the kernel returns correct number of event.
41d723a550SNamhyung Kim  */
test__task_exit(struct test_suite * test __maybe_unused,int subtest __maybe_unused)4233f44bfdSIan Rogers static int test__task_exit(struct test_suite *test __maybe_unused, int subtest __maybe_unused)
43d723a550SNamhyung Kim {
44d723a550SNamhyung Kim 	int err = -1;
45d723a550SNamhyung Kim 	union perf_event *event;
4632dcd021SJiri Olsa 	struct evsel *evsel;
4763503dbaSJiri Olsa 	struct evlist *evlist;
48602ad878SArnaldo Carvalho de Melo 	struct target target = {
49d723a550SNamhyung Kim 		.uid		= UINT_MAX,
50d723a550SNamhyung Kim 		.uses_mmap	= true,
51d723a550SNamhyung Kim 	};
52d723a550SNamhyung Kim 	const char *argv[] = { "true", NULL };
53ba3dfff8SMasami Hiramatsu 	char sbuf[STRERR_BUFSIZE];
54f854839bSJiri Olsa 	struct perf_cpu_map *cpus;
559749b90eSJiri Olsa 	struct perf_thread_map *threads;
56a5830532SJiri Olsa 	struct mmap *md;
57791ce9c4SLeo Yan 	int retry_count = 0;
58d723a550SNamhyung Kim 
59d723a550SNamhyung Kim 	signal(SIGCHLD, sig_handler);
60d723a550SNamhyung Kim 
61*2480232cSArnaldo Carvalho de Melo 	evlist = evlist__new_dummy();
62d723a550SNamhyung Kim 	if (evlist == NULL) {
63*2480232cSArnaldo Carvalho de Melo 		pr_debug("evlist__new_dummy\n");
64d723a550SNamhyung Kim 		return -1;
65d723a550SNamhyung Kim 	}
66d723a550SNamhyung Kim 
67d723a550SNamhyung Kim 	/*
68d723a550SNamhyung Kim 	 * Create maps of threads and cpus to monitor. In this case
69d723a550SNamhyung Kim 	 * we start with all threads and cpus (-1, -1) but then in
707b392ef0SArnaldo Carvalho de Melo 	 * evlist__prepare_workload we'll fill in the only thread
71d723a550SNamhyung Kim 	 * we're monitoring, the one forked there.
72d723a550SNamhyung Kim 	 */
73397721e0SJiri Olsa 	cpus = perf_cpu_map__dummy_new();
7429982722SAdrian Hunter 	threads = thread_map__new_by_tid(-1);
7529982722SAdrian Hunter 	if (!cpus || !threads) {
76d723a550SNamhyung Kim 		err = -ENOMEM;
77d723a550SNamhyung Kim 		pr_debug("Not enough memory to create thread/cpu maps\n");
7883d25ccdSNamhyung Kim 		goto out_delete_evlist;
79d723a550SNamhyung Kim 	}
80d723a550SNamhyung Kim 
81453fa030SJiri Olsa 	perf_evlist__set_maps(&evlist->core, cpus, threads);
8229982722SAdrian Hunter 
837b392ef0SArnaldo Carvalho de Melo 	err = evlist__prepare_workload(evlist, &target, argv, false, workload_exec_failed_signal);
84d723a550SNamhyung Kim 	if (err < 0) {
85d723a550SNamhyung Kim 		pr_debug("Couldn't run the workload!\n");
8603ad9747SArnaldo Carvalho de Melo 		goto out_delete_evlist;
87d723a550SNamhyung Kim 	}
88d723a550SNamhyung Kim 
89515dbe48SJiri Olsa 	evsel = evlist__first(evlist);
901fc632ceSJiri Olsa 	evsel->core.attr.task = 1;
9199654849SThomas Richter #ifdef __s390x__
921fc632ceSJiri Olsa 	evsel->core.attr.sample_freq = 1000000;
9399654849SThomas Richter #else
941fc632ceSJiri Olsa 	evsel->core.attr.sample_freq = 1;
9599654849SThomas Richter #endif
961fc632ceSJiri Olsa 	evsel->core.attr.inherit = 0;
971fc632ceSJiri Olsa 	evsel->core.attr.watermark = 0;
981fc632ceSJiri Olsa 	evsel->core.attr.wakeup_events = 1;
991fc632ceSJiri Olsa 	evsel->core.attr.exclude_kernel = 1;
100d723a550SNamhyung Kim 
101474ddc4cSJiri Olsa 	err = evlist__open(evlist);
102d723a550SNamhyung Kim 	if (err < 0) {
103ba3dfff8SMasami Hiramatsu 		pr_debug("Couldn't open the evlist: %s\n",
104c8b5f2c9SArnaldo Carvalho de Melo 			 str_error_r(-err, sbuf, sizeof(sbuf)));
10503ad9747SArnaldo Carvalho de Melo 		goto out_delete_evlist;
106d723a550SNamhyung Kim 	}
107d723a550SNamhyung Kim 
1089521b5f2SJiri Olsa 	if (evlist__mmap(evlist, 128) < 0) {
109d723a550SNamhyung Kim 		pr_debug("failed to mmap events: %d (%s)\n", errno,
110c8b5f2c9SArnaldo Carvalho de Melo 			 str_error_r(errno, sbuf, sizeof(sbuf)));
1116add129cSLeo Yan 		err = -1;
112f26e1c7cSArnaldo Carvalho de Melo 		goto out_delete_evlist;
113d723a550SNamhyung Kim 	}
114d723a550SNamhyung Kim 
1157b392ef0SArnaldo Carvalho de Melo 	evlist__start_workload(evlist);
116d723a550SNamhyung Kim 
117d723a550SNamhyung Kim retry:
11875948730SKan Liang 	md = &evlist->mmap[0];
1197c4d4182SJiri Olsa 	if (perf_mmap__read_init(&md->core) < 0)
12075948730SKan Liang 		goto out_init;
12175948730SKan Liang 
122151ed5d7SJiri Olsa 	while ((event = perf_mmap__read_event(&md->core)) != NULL) {
1238e50d384SZhouyi Zhou 		if (event->header.type == PERF_RECORD_EXIT)
124d723a550SNamhyung Kim 			nr_exit++;
1258e50d384SZhouyi Zhou 
1267728fa0cSJiri Olsa 		perf_mmap__consume(&md->core);
127d723a550SNamhyung Kim 	}
12832fdc2caSJiri Olsa 	perf_mmap__read_done(&md->core);
129d723a550SNamhyung Kim 
13075948730SKan Liang out_init:
131d723a550SNamhyung Kim 	if (!exited || !nr_exit) {
13280ab2987SJiri Olsa 		evlist__poll(evlist, -1);
133791ce9c4SLeo Yan 
134791ce9c4SLeo Yan 		if (retry_count++ > 1000) {
135791ce9c4SLeo Yan 			pr_debug("Failed after retrying 1000 times\n");
136791ce9c4SLeo Yan 			err = -1;
13783d25ccdSNamhyung Kim 			goto out_delete_evlist;
138791ce9c4SLeo Yan 		}
139791ce9c4SLeo Yan 
140d723a550SNamhyung Kim 		goto retry;
141d723a550SNamhyung Kim 	}
142d723a550SNamhyung Kim 
143d723a550SNamhyung Kim 	if (nr_exit != 1) {
144d723a550SNamhyung Kim 		pr_debug("received %d EXIT records\n", nr_exit);
145d723a550SNamhyung Kim 		err = -1;
146d723a550SNamhyung Kim 	}
147d723a550SNamhyung Kim 
14883d25ccdSNamhyung Kim out_delete_evlist:
14938f01d8dSJiri Olsa 	perf_cpu_map__put(cpus);
1507836e52eSJiri Olsa 	perf_thread_map__put(threads);
151c12995a5SJiri Olsa 	evlist__delete(evlist);
152d723a550SNamhyung Kim 	return err;
153d723a550SNamhyung Kim }
154d68f0365SIan Rogers 
155d68f0365SIan Rogers DEFINE_SUITE("Number of exit events of a simple workload", task_exit);
156