root/tools/perf/tests/backward-ring-buffer.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. testcase
  2. count_samples
  3. do_test
  4. test__backward_ring_buffer

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

/* [<][>][^][v][top][bottom][index][help] */