0001
0002
0003
0004
0005
0006
0007 #include <evlist.h>
0008 #include <sys/prctl.h>
0009 #include "record.h"
0010 #include "tests.h"
0011 #include "debug.h"
0012 #include "parse-events.h"
0013 #include "util/mmap.h"
0014 #include <errno.h>
0015 #include <linux/string.h>
0016 #include <perf/mmap.h>
0017
0018 #define NR_ITERS 111
0019
0020 static void testcase(void)
0021 {
0022 int i;
0023
0024 for (i = 0; i < NR_ITERS; i++) {
0025 char proc_name[15];
0026
0027 snprintf(proc_name, sizeof(proc_name), "p:%d\n", i);
0028 prctl(PR_SET_NAME, proc_name);
0029 }
0030 }
0031
0032 static int count_samples(struct evlist *evlist, int *sample_count,
0033 int *comm_count)
0034 {
0035 int i;
0036
0037 for (i = 0; i < evlist->core.nr_mmaps; i++) {
0038 struct mmap *map = &evlist->overwrite_mmap[i];
0039 union perf_event *event;
0040
0041 perf_mmap__read_init(&map->core);
0042 while ((event = perf_mmap__read_event(&map->core)) != NULL) {
0043 const u32 type = event->header.type;
0044
0045 switch (type) {
0046 case PERF_RECORD_SAMPLE:
0047 (*sample_count)++;
0048 break;
0049 case PERF_RECORD_COMM:
0050 (*comm_count)++;
0051 break;
0052 default:
0053 pr_err("Unexpected record of type %d\n", type);
0054 return TEST_FAIL;
0055 }
0056 }
0057 perf_mmap__read_done(&map->core);
0058 }
0059 return TEST_OK;
0060 }
0061
0062 static int do_test(struct evlist *evlist, int mmap_pages,
0063 int *sample_count, int *comm_count)
0064 {
0065 int err;
0066 char sbuf[STRERR_BUFSIZE];
0067
0068 err = evlist__mmap(evlist, mmap_pages);
0069 if (err < 0) {
0070 pr_debug("evlist__mmap: %s\n",
0071 str_error_r(errno, sbuf, sizeof(sbuf)));
0072 return TEST_FAIL;
0073 }
0074
0075 evlist__enable(evlist);
0076 testcase();
0077 evlist__disable(evlist);
0078
0079 err = count_samples(evlist, sample_count, comm_count);
0080 evlist__munmap(evlist);
0081 return err;
0082 }
0083
0084
0085 static int test__backward_ring_buffer(struct test_suite *test __maybe_unused, int subtest __maybe_unused)
0086 {
0087 int ret = TEST_SKIP, err, sample_count = 0, comm_count = 0;
0088 char pid[16], sbuf[STRERR_BUFSIZE];
0089 struct evlist *evlist;
0090 struct evsel *evsel __maybe_unused;
0091 struct parse_events_error parse_error;
0092 struct record_opts opts = {
0093 .target = {
0094 .uid = UINT_MAX,
0095 .uses_mmap = true,
0096 },
0097 .freq = 0,
0098 .mmap_pages = 256,
0099 .default_interval = 1,
0100 };
0101
0102 snprintf(pid, sizeof(pid), "%d", getpid());
0103 pid[sizeof(pid) - 1] = '\0';
0104 opts.target.tid = opts.target.pid = pid;
0105
0106 evlist = evlist__new();
0107 if (!evlist) {
0108 pr_debug("Not enough memory to create evlist\n");
0109 return TEST_FAIL;
0110 }
0111
0112 err = evlist__create_maps(evlist, &opts.target);
0113 if (err < 0) {
0114 pr_debug("Not enough memory to create thread/cpu maps\n");
0115 goto out_delete_evlist;
0116 }
0117
0118 parse_events_error__init(&parse_error);
0119
0120
0121
0122
0123 err = parse_events(evlist, "syscalls:sys_enter_prctl/overwrite/", &parse_error);
0124 parse_events_error__exit(&parse_error);
0125 if (err) {
0126 pr_debug("Failed to parse tracepoint event, try use root\n");
0127 ret = TEST_SKIP;
0128 goto out_delete_evlist;
0129 }
0130
0131 evlist__config(evlist, &opts, NULL);
0132
0133 err = evlist__open(evlist);
0134 if (err < 0) {
0135 pr_debug("perf_evlist__open: %s\n",
0136 str_error_r(errno, sbuf, sizeof(sbuf)));
0137 goto out_delete_evlist;
0138 }
0139
0140 ret = TEST_FAIL;
0141 err = do_test(evlist, opts.mmap_pages, &sample_count,
0142 &comm_count);
0143 if (err != TEST_OK)
0144 goto out_delete_evlist;
0145
0146 if ((sample_count != NR_ITERS) || (comm_count != NR_ITERS)) {
0147 pr_err("Unexpected counter: sample_count=%d, comm_count=%d\n",
0148 sample_count, comm_count);
0149 goto out_delete_evlist;
0150 }
0151
0152 evlist__close(evlist);
0153
0154 err = evlist__open(evlist);
0155 if (err < 0) {
0156 pr_debug("perf_evlist__open: %s\n",
0157 str_error_r(errno, sbuf, sizeof(sbuf)));
0158 goto out_delete_evlist;
0159 }
0160
0161 err = do_test(evlist, 1, &sample_count, &comm_count);
0162 if (err != TEST_OK)
0163 goto out_delete_evlist;
0164
0165 ret = TEST_OK;
0166 out_delete_evlist:
0167 evlist__delete(evlist);
0168 return ret;
0169 }
0170
0171 DEFINE_SUITE("Read backward ring buffer", backward_ring_buffer);