1b2441318SGreg Kroah-Hartman // SPDX-License-Identifier: GPL-2.0
2ee74701eSWang Nan /*
3ee74701eSWang Nan  * Test backward bit in event attribute, read ring buffer from end to
4ee74701eSWang Nan  * beginning
5ee74701eSWang Nan  */
6ee74701eSWang Nan 
7ee74701eSWang Nan #include <evlist.h>
8ee74701eSWang Nan #include <sys/prctl.h>
9aeb00b1aSArnaldo Carvalho de Melo #include "record.h"
10ee74701eSWang Nan #include "tests.h"
11ee74701eSWang Nan #include "debug.h"
12a43783aeSArnaldo Carvalho de Melo #include <errno.h>
13ee74701eSWang Nan 
14ee74701eSWang Nan #define NR_ITERS 111
15ee74701eSWang Nan 
16ee74701eSWang Nan static void testcase(void)
17ee74701eSWang Nan {
18ee74701eSWang Nan 	int i;
19ee74701eSWang Nan 
20ee74701eSWang Nan 	for (i = 0; i < NR_ITERS; i++) {
2111c1ea6fSChangbin Du 		char proc_name[15];
22ee74701eSWang Nan 
23ee74701eSWang Nan 		snprintf(proc_name, sizeof(proc_name), "p:%d\n", i);
24ee74701eSWang Nan 		prctl(PR_SET_NAME, proc_name);
25ee74701eSWang Nan 	}
26ee74701eSWang Nan }
27ee74701eSWang Nan 
2863503dbaSJiri Olsa static int count_samples(struct evlist *evlist, int *sample_count,
29ee74701eSWang Nan 			 int *comm_count)
30ee74701eSWang Nan {
31ee74701eSWang Nan 	int i;
32ee74701eSWang Nan 
33ee74701eSWang Nan 	for (i = 0; i < evlist->nr_mmaps; i++) {
34600a7cfeSKan Liang 		struct perf_mmap *map = &evlist->overwrite_mmap[i];
35ee74701eSWang Nan 		union perf_event *event;
36ee74701eSWang Nan 
37b9bae2c8SKan Liang 		perf_mmap__read_init(map);
380019dc87SKan Liang 		while ((event = perf_mmap__read_event(map)) != NULL) {
39ee74701eSWang Nan 			const u32 type = event->header.type;
40ee74701eSWang Nan 
41ee74701eSWang Nan 			switch (type) {
42ee74701eSWang Nan 			case PERF_RECORD_SAMPLE:
43ee74701eSWang Nan 				(*sample_count)++;
44ee74701eSWang Nan 				break;
45ee74701eSWang Nan 			case PERF_RECORD_COMM:
46ee74701eSWang Nan 				(*comm_count)++;
47ee74701eSWang Nan 				break;
48ee74701eSWang Nan 			default:
49ee74701eSWang Nan 				pr_err("Unexpected record of type %d\n", type);
50ee74701eSWang Nan 				return TEST_FAIL;
51ee74701eSWang Nan 			}
52ee74701eSWang Nan 		}
53600a7cfeSKan Liang 		perf_mmap__read_done(map);
54ee74701eSWang Nan 	}
55ee74701eSWang Nan 	return TEST_OK;
56ee74701eSWang Nan }
57ee74701eSWang Nan 
5863503dbaSJiri Olsa static int do_test(struct evlist *evlist, int mmap_pages,
59ee74701eSWang Nan 		   int *sample_count, int *comm_count)
60ee74701eSWang Nan {
61ee74701eSWang Nan 	int err;
62ee74701eSWang Nan 	char sbuf[STRERR_BUFSIZE];
63ee74701eSWang Nan 
64f74b9d3aSWang Nan 	err = perf_evlist__mmap(evlist, mmap_pages);
65ee74701eSWang Nan 	if (err < 0) {
66ee74701eSWang Nan 		pr_debug("perf_evlist__mmap: %s\n",
67c8b5f2c9SArnaldo Carvalho de Melo 			 str_error_r(errno, sbuf, sizeof(sbuf)));
68ee74701eSWang Nan 		return TEST_FAIL;
69ee74701eSWang Nan 	}
70ee74701eSWang Nan 
711c87f165SJiri Olsa 	evlist__enable(evlist);
72ee74701eSWang Nan 	testcase();
73e74676deSJiri Olsa 	evlist__disable(evlist);
74ee74701eSWang Nan 
75ee74701eSWang Nan 	err = count_samples(evlist, sample_count, comm_count);
76ee74701eSWang Nan 	perf_evlist__munmap(evlist);
77ee74701eSWang Nan 	return err;
78ee74701eSWang Nan }
79ee74701eSWang Nan 
80ee74701eSWang Nan 
8181f17c90SArnaldo Carvalho de Melo int test__backward_ring_buffer(struct test *test __maybe_unused, int subtest __maybe_unused)
82ee74701eSWang Nan {
83ee74701eSWang Nan 	int ret = TEST_SKIP, err, sample_count = 0, comm_count = 0;
84ee74701eSWang Nan 	char pid[16], sbuf[STRERR_BUFSIZE];
8563503dbaSJiri Olsa 	struct evlist *evlist;
8632dcd021SJiri Olsa 	struct evsel *evsel __maybe_unused;
87ee74701eSWang Nan 	struct parse_events_error parse_error;
88ee74701eSWang Nan 	struct record_opts opts = {
89ee74701eSWang Nan 		.target = {
90ee74701eSWang Nan 			.uid = UINT_MAX,
91ee74701eSWang Nan 			.uses_mmap = true,
92ee74701eSWang Nan 		},
93ee74701eSWang Nan 		.freq	      = 0,
94ee74701eSWang Nan 		.mmap_pages   = 256,
95ee74701eSWang Nan 		.default_interval = 1,
96ee74701eSWang Nan 	};
97ee74701eSWang Nan 
98ee74701eSWang Nan 	snprintf(pid, sizeof(pid), "%d", getpid());
99ee74701eSWang Nan 	pid[sizeof(pid) - 1] = '\0';
100ee74701eSWang Nan 	opts.target.tid = opts.target.pid = pid;
101ee74701eSWang Nan 
1020f98b11cSJiri Olsa 	evlist = evlist__new();
103ee74701eSWang Nan 	if (!evlist) {
104042cfb5fSAlexander Alemayhu 		pr_debug("Not enough memory to create evlist\n");
105ee74701eSWang Nan 		return TEST_FAIL;
106ee74701eSWang Nan 	}
107ee74701eSWang Nan 
108ee74701eSWang Nan 	err = perf_evlist__create_maps(evlist, &opts.target);
109ee74701eSWang Nan 	if (err < 0) {
110ee74701eSWang Nan 		pr_debug("Not enough memory to create thread/cpu maps\n");
111ee74701eSWang Nan 		goto out_delete_evlist;
112ee74701eSWang Nan 	}
113ee74701eSWang Nan 
114ee74701eSWang Nan 	bzero(&parse_error, sizeof(parse_error));
115626a6b78SWang Nan 	/*
116626a6b78SWang Nan 	 * Set backward bit, ring buffer should be writing from end. Record
117626a6b78SWang Nan 	 * it in aux evlist
118626a6b78SWang Nan 	 */
119626a6b78SWang Nan 	err = parse_events(evlist, "syscalls:sys_enter_prctl/overwrite/", &parse_error);
120ee74701eSWang Nan 	if (err) {
121ee74701eSWang Nan 		pr_debug("Failed to parse tracepoint event, try use root\n");
122ee74701eSWang Nan 		ret = TEST_SKIP;
123ee74701eSWang Nan 		goto out_delete_evlist;
124ee74701eSWang Nan 	}
125ee74701eSWang Nan 
126ee74701eSWang Nan 	perf_evlist__config(evlist, &opts, NULL);
127ee74701eSWang Nan 
128474ddc4cSJiri Olsa 	err = evlist__open(evlist);
129ee74701eSWang Nan 	if (err < 0) {
130ee74701eSWang Nan 		pr_debug("perf_evlist__open: %s\n",
131c8b5f2c9SArnaldo Carvalho de Melo 			 str_error_r(errno, sbuf, sizeof(sbuf)));
132ee74701eSWang Nan 		goto out_delete_evlist;
133ee74701eSWang Nan 	}
134ee74701eSWang Nan 
135ee74701eSWang Nan 	ret = TEST_FAIL;
136ee74701eSWang Nan 	err = do_test(evlist, opts.mmap_pages, &sample_count,
137ee74701eSWang Nan 		      &comm_count);
138ee74701eSWang Nan 	if (err != TEST_OK)
139ee74701eSWang Nan 		goto out_delete_evlist;
140ee74701eSWang Nan 
141ee74701eSWang Nan 	if ((sample_count != NR_ITERS) || (comm_count != NR_ITERS)) {
142ee74701eSWang Nan 		pr_err("Unexpected counter: sample_count=%d, comm_count=%d\n",
143ee74701eSWang Nan 		       sample_count, comm_count);
144ee74701eSWang Nan 		goto out_delete_evlist;
145ee74701eSWang Nan 	}
146ee74701eSWang Nan 
147ee74701eSWang Nan 	err = do_test(evlist, 1, &sample_count, &comm_count);
148ee74701eSWang Nan 	if (err != TEST_OK)
149ee74701eSWang Nan 		goto out_delete_evlist;
150ee74701eSWang Nan 
151ee74701eSWang Nan 	ret = TEST_OK;
152ee74701eSWang Nan out_delete_evlist:
153c12995a5SJiri Olsa 	evlist__delete(evlist);
154ee74701eSWang Nan 	return ret;
155ee74701eSWang Nan }
156