Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /*
0003  * Test backward bit in event attribute, read ring buffer from end to
0004  * beginning
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      * Set backward bit, ring buffer should be writing from end. Record
0121      * it in aux evlist
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);