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 <perf.h> 8ee74701eSWang Nan #include <evlist.h> 9ee74701eSWang Nan #include <sys/prctl.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++) { 21ee74701eSWang Nan char proc_name[10]; 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 28ee74701eSWang Nan static int count_samples(struct perf_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 58ee74701eSWang Nan static int do_test(struct perf_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 71ee74701eSWang Nan perf_evlist__enable(evlist); 72ee74701eSWang Nan testcase(); 73ee74701eSWang Nan perf_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]; 85ee74701eSWang Nan struct perf_evlist *evlist; 86ee74701eSWang Nan struct perf_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 102ee74701eSWang Nan evlist = perf_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 128ee74701eSWang Nan err = perf_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: 153ee74701eSWang Nan perf_evlist__delete(evlist); 154ee74701eSWang Nan return ret; 155ee74701eSWang Nan } 156