xref: /OK3568_Linux_fs/kernel/tools/perf/tests/backward-ring-buffer.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun  * Test backward bit in event attribute, read ring buffer from end to
4*4882a593Smuzhiyun  * beginning
5*4882a593Smuzhiyun  */
6*4882a593Smuzhiyun 
7*4882a593Smuzhiyun #include <evlist.h>
8*4882a593Smuzhiyun #include <sys/prctl.h>
9*4882a593Smuzhiyun #include "record.h"
10*4882a593Smuzhiyun #include "tests.h"
11*4882a593Smuzhiyun #include "debug.h"
12*4882a593Smuzhiyun #include "parse-events.h"
13*4882a593Smuzhiyun #include "util/mmap.h"
14*4882a593Smuzhiyun #include <errno.h>
15*4882a593Smuzhiyun #include <linux/string.h>
16*4882a593Smuzhiyun #include <perf/mmap.h>
17*4882a593Smuzhiyun 
18*4882a593Smuzhiyun #define NR_ITERS 111
19*4882a593Smuzhiyun 
testcase(void)20*4882a593Smuzhiyun static void testcase(void)
21*4882a593Smuzhiyun {
22*4882a593Smuzhiyun 	int i;
23*4882a593Smuzhiyun 
24*4882a593Smuzhiyun 	for (i = 0; i < NR_ITERS; i++) {
25*4882a593Smuzhiyun 		char proc_name[15];
26*4882a593Smuzhiyun 
27*4882a593Smuzhiyun 		snprintf(proc_name, sizeof(proc_name), "p:%d\n", i);
28*4882a593Smuzhiyun 		prctl(PR_SET_NAME, proc_name);
29*4882a593Smuzhiyun 	}
30*4882a593Smuzhiyun }
31*4882a593Smuzhiyun 
count_samples(struct evlist * evlist,int * sample_count,int * comm_count)32*4882a593Smuzhiyun static int count_samples(struct evlist *evlist, int *sample_count,
33*4882a593Smuzhiyun 			 int *comm_count)
34*4882a593Smuzhiyun {
35*4882a593Smuzhiyun 	int i;
36*4882a593Smuzhiyun 
37*4882a593Smuzhiyun 	for (i = 0; i < evlist->core.nr_mmaps; i++) {
38*4882a593Smuzhiyun 		struct mmap *map = &evlist->overwrite_mmap[i];
39*4882a593Smuzhiyun 		union perf_event *event;
40*4882a593Smuzhiyun 
41*4882a593Smuzhiyun 		perf_mmap__read_init(&map->core);
42*4882a593Smuzhiyun 		while ((event = perf_mmap__read_event(&map->core)) != NULL) {
43*4882a593Smuzhiyun 			const u32 type = event->header.type;
44*4882a593Smuzhiyun 
45*4882a593Smuzhiyun 			switch (type) {
46*4882a593Smuzhiyun 			case PERF_RECORD_SAMPLE:
47*4882a593Smuzhiyun 				(*sample_count)++;
48*4882a593Smuzhiyun 				break;
49*4882a593Smuzhiyun 			case PERF_RECORD_COMM:
50*4882a593Smuzhiyun 				(*comm_count)++;
51*4882a593Smuzhiyun 				break;
52*4882a593Smuzhiyun 			default:
53*4882a593Smuzhiyun 				pr_err("Unexpected record of type %d\n", type);
54*4882a593Smuzhiyun 				return TEST_FAIL;
55*4882a593Smuzhiyun 			}
56*4882a593Smuzhiyun 		}
57*4882a593Smuzhiyun 		perf_mmap__read_done(&map->core);
58*4882a593Smuzhiyun 	}
59*4882a593Smuzhiyun 	return TEST_OK;
60*4882a593Smuzhiyun }
61*4882a593Smuzhiyun 
do_test(struct evlist * evlist,int mmap_pages,int * sample_count,int * comm_count)62*4882a593Smuzhiyun static int do_test(struct evlist *evlist, int mmap_pages,
63*4882a593Smuzhiyun 		   int *sample_count, int *comm_count)
64*4882a593Smuzhiyun {
65*4882a593Smuzhiyun 	int err;
66*4882a593Smuzhiyun 	char sbuf[STRERR_BUFSIZE];
67*4882a593Smuzhiyun 
68*4882a593Smuzhiyun 	err = evlist__mmap(evlist, mmap_pages);
69*4882a593Smuzhiyun 	if (err < 0) {
70*4882a593Smuzhiyun 		pr_debug("evlist__mmap: %s\n",
71*4882a593Smuzhiyun 			 str_error_r(errno, sbuf, sizeof(sbuf)));
72*4882a593Smuzhiyun 		return TEST_FAIL;
73*4882a593Smuzhiyun 	}
74*4882a593Smuzhiyun 
75*4882a593Smuzhiyun 	evlist__enable(evlist);
76*4882a593Smuzhiyun 	testcase();
77*4882a593Smuzhiyun 	evlist__disable(evlist);
78*4882a593Smuzhiyun 
79*4882a593Smuzhiyun 	err = count_samples(evlist, sample_count, comm_count);
80*4882a593Smuzhiyun 	evlist__munmap(evlist);
81*4882a593Smuzhiyun 	return err;
82*4882a593Smuzhiyun }
83*4882a593Smuzhiyun 
84*4882a593Smuzhiyun 
test__backward_ring_buffer(struct test * test __maybe_unused,int subtest __maybe_unused)85*4882a593Smuzhiyun int test__backward_ring_buffer(struct test *test __maybe_unused, int subtest __maybe_unused)
86*4882a593Smuzhiyun {
87*4882a593Smuzhiyun 	int ret = TEST_SKIP, err, sample_count = 0, comm_count = 0;
88*4882a593Smuzhiyun 	char pid[16], sbuf[STRERR_BUFSIZE];
89*4882a593Smuzhiyun 	struct evlist *evlist;
90*4882a593Smuzhiyun 	struct evsel *evsel __maybe_unused;
91*4882a593Smuzhiyun 	struct parse_events_error parse_error;
92*4882a593Smuzhiyun 	struct record_opts opts = {
93*4882a593Smuzhiyun 		.target = {
94*4882a593Smuzhiyun 			.uid = UINT_MAX,
95*4882a593Smuzhiyun 			.uses_mmap = true,
96*4882a593Smuzhiyun 		},
97*4882a593Smuzhiyun 		.freq	      = 0,
98*4882a593Smuzhiyun 		.mmap_pages   = 256,
99*4882a593Smuzhiyun 		.default_interval = 1,
100*4882a593Smuzhiyun 	};
101*4882a593Smuzhiyun 
102*4882a593Smuzhiyun 	snprintf(pid, sizeof(pid), "%d", getpid());
103*4882a593Smuzhiyun 	pid[sizeof(pid) - 1] = '\0';
104*4882a593Smuzhiyun 	opts.target.tid = opts.target.pid = pid;
105*4882a593Smuzhiyun 
106*4882a593Smuzhiyun 	evlist = evlist__new();
107*4882a593Smuzhiyun 	if (!evlist) {
108*4882a593Smuzhiyun 		pr_debug("Not enough memory to create evlist\n");
109*4882a593Smuzhiyun 		return TEST_FAIL;
110*4882a593Smuzhiyun 	}
111*4882a593Smuzhiyun 
112*4882a593Smuzhiyun 	err = perf_evlist__create_maps(evlist, &opts.target);
113*4882a593Smuzhiyun 	if (err < 0) {
114*4882a593Smuzhiyun 		pr_debug("Not enough memory to create thread/cpu maps\n");
115*4882a593Smuzhiyun 		goto out_delete_evlist;
116*4882a593Smuzhiyun 	}
117*4882a593Smuzhiyun 
118*4882a593Smuzhiyun 	bzero(&parse_error, sizeof(parse_error));
119*4882a593Smuzhiyun 	/*
120*4882a593Smuzhiyun 	 * Set backward bit, ring buffer should be writing from end. Record
121*4882a593Smuzhiyun 	 * it in aux evlist
122*4882a593Smuzhiyun 	 */
123*4882a593Smuzhiyun 	err = parse_events(evlist, "syscalls:sys_enter_prctl/overwrite/", &parse_error);
124*4882a593Smuzhiyun 	if (err) {
125*4882a593Smuzhiyun 		pr_debug("Failed to parse tracepoint event, try use root\n");
126*4882a593Smuzhiyun 		ret = TEST_SKIP;
127*4882a593Smuzhiyun 		goto out_delete_evlist;
128*4882a593Smuzhiyun 	}
129*4882a593Smuzhiyun 
130*4882a593Smuzhiyun 	perf_evlist__config(evlist, &opts, NULL);
131*4882a593Smuzhiyun 
132*4882a593Smuzhiyun 	err = evlist__open(evlist);
133*4882a593Smuzhiyun 	if (err < 0) {
134*4882a593Smuzhiyun 		pr_debug("perf_evlist__open: %s\n",
135*4882a593Smuzhiyun 			 str_error_r(errno, sbuf, sizeof(sbuf)));
136*4882a593Smuzhiyun 		goto out_delete_evlist;
137*4882a593Smuzhiyun 	}
138*4882a593Smuzhiyun 
139*4882a593Smuzhiyun 	ret = TEST_FAIL;
140*4882a593Smuzhiyun 	err = do_test(evlist, opts.mmap_pages, &sample_count,
141*4882a593Smuzhiyun 		      &comm_count);
142*4882a593Smuzhiyun 	if (err != TEST_OK)
143*4882a593Smuzhiyun 		goto out_delete_evlist;
144*4882a593Smuzhiyun 
145*4882a593Smuzhiyun 	if ((sample_count != NR_ITERS) || (comm_count != NR_ITERS)) {
146*4882a593Smuzhiyun 		pr_err("Unexpected counter: sample_count=%d, comm_count=%d\n",
147*4882a593Smuzhiyun 		       sample_count, comm_count);
148*4882a593Smuzhiyun 		goto out_delete_evlist;
149*4882a593Smuzhiyun 	}
150*4882a593Smuzhiyun 
151*4882a593Smuzhiyun 	evlist__close(evlist);
152*4882a593Smuzhiyun 
153*4882a593Smuzhiyun 	err = evlist__open(evlist);
154*4882a593Smuzhiyun 	if (err < 0) {
155*4882a593Smuzhiyun 		pr_debug("perf_evlist__open: %s\n",
156*4882a593Smuzhiyun 			 str_error_r(errno, sbuf, sizeof(sbuf)));
157*4882a593Smuzhiyun 		goto out_delete_evlist;
158*4882a593Smuzhiyun 	}
159*4882a593Smuzhiyun 
160*4882a593Smuzhiyun 	err = do_test(evlist, 1, &sample_count, &comm_count);
161*4882a593Smuzhiyun 	if (err != TEST_OK)
162*4882a593Smuzhiyun 		goto out_delete_evlist;
163*4882a593Smuzhiyun 
164*4882a593Smuzhiyun 	ret = TEST_OK;
165*4882a593Smuzhiyun out_delete_evlist:
166*4882a593Smuzhiyun 	evlist__delete(evlist);
167*4882a593Smuzhiyun 	return ret;
168*4882a593Smuzhiyun }
169