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; 36600a7cfeSKan Liang u64 start, end; 37ee74701eSWang Nan 38600a7cfeSKan Liang perf_mmap__read_init(map, true, &start, &end); 390019dc87SKan Liang while ((event = perf_mmap__read_event(map)) != NULL) { 40ee74701eSWang Nan const u32 type = event->header.type; 41ee74701eSWang Nan 42ee74701eSWang Nan switch (type) { 43ee74701eSWang Nan case PERF_RECORD_SAMPLE: 44ee74701eSWang Nan (*sample_count)++; 45ee74701eSWang Nan break; 46ee74701eSWang Nan case PERF_RECORD_COMM: 47ee74701eSWang Nan (*comm_count)++; 48ee74701eSWang Nan break; 49ee74701eSWang Nan default: 50ee74701eSWang Nan pr_err("Unexpected record of type %d\n", type); 51ee74701eSWang Nan return TEST_FAIL; 52ee74701eSWang Nan } 53ee74701eSWang Nan } 54600a7cfeSKan Liang perf_mmap__read_done(map); 55ee74701eSWang Nan } 56ee74701eSWang Nan return TEST_OK; 57ee74701eSWang Nan } 58ee74701eSWang Nan 59ee74701eSWang Nan static int do_test(struct perf_evlist *evlist, int mmap_pages, 60ee74701eSWang Nan int *sample_count, int *comm_count) 61ee74701eSWang Nan { 62ee74701eSWang Nan int err; 63ee74701eSWang Nan char sbuf[STRERR_BUFSIZE]; 64ee74701eSWang Nan 65f74b9d3aSWang Nan err = perf_evlist__mmap(evlist, mmap_pages); 66ee74701eSWang Nan if (err < 0) { 67ee74701eSWang Nan pr_debug("perf_evlist__mmap: %s\n", 68c8b5f2c9SArnaldo Carvalho de Melo str_error_r(errno, sbuf, sizeof(sbuf))); 69ee74701eSWang Nan return TEST_FAIL; 70ee74701eSWang Nan } 71ee74701eSWang Nan 72ee74701eSWang Nan perf_evlist__enable(evlist); 73ee74701eSWang Nan testcase(); 74ee74701eSWang Nan perf_evlist__disable(evlist); 75ee74701eSWang Nan 76ee74701eSWang Nan err = count_samples(evlist, sample_count, comm_count); 77ee74701eSWang Nan perf_evlist__munmap(evlist); 78ee74701eSWang Nan return err; 79ee74701eSWang Nan } 80ee74701eSWang Nan 81ee74701eSWang Nan 8281f17c90SArnaldo Carvalho de Melo int test__backward_ring_buffer(struct test *test __maybe_unused, int subtest __maybe_unused) 83ee74701eSWang Nan { 84ee74701eSWang Nan int ret = TEST_SKIP, err, sample_count = 0, comm_count = 0; 85ee74701eSWang Nan char pid[16], sbuf[STRERR_BUFSIZE]; 86ee74701eSWang Nan struct perf_evlist *evlist; 87ee74701eSWang Nan struct perf_evsel *evsel __maybe_unused; 88ee74701eSWang Nan struct parse_events_error parse_error; 89ee74701eSWang Nan struct record_opts opts = { 90ee74701eSWang Nan .target = { 91ee74701eSWang Nan .uid = UINT_MAX, 92ee74701eSWang Nan .uses_mmap = true, 93ee74701eSWang Nan }, 94ee74701eSWang Nan .freq = 0, 95ee74701eSWang Nan .mmap_pages = 256, 96ee74701eSWang Nan .default_interval = 1, 97ee74701eSWang Nan }; 98ee74701eSWang Nan 99ee74701eSWang Nan snprintf(pid, sizeof(pid), "%d", getpid()); 100ee74701eSWang Nan pid[sizeof(pid) - 1] = '\0'; 101ee74701eSWang Nan opts.target.tid = opts.target.pid = pid; 102ee74701eSWang Nan 103ee74701eSWang Nan evlist = perf_evlist__new(); 104ee74701eSWang Nan if (!evlist) { 105042cfb5fSAlexander Alemayhu pr_debug("Not enough memory to create evlist\n"); 106ee74701eSWang Nan return TEST_FAIL; 107ee74701eSWang Nan } 108ee74701eSWang Nan 109ee74701eSWang Nan err = perf_evlist__create_maps(evlist, &opts.target); 110ee74701eSWang Nan if (err < 0) { 111ee74701eSWang Nan pr_debug("Not enough memory to create thread/cpu maps\n"); 112ee74701eSWang Nan goto out_delete_evlist; 113ee74701eSWang Nan } 114ee74701eSWang Nan 115ee74701eSWang Nan bzero(&parse_error, sizeof(parse_error)); 116626a6b78SWang Nan /* 117626a6b78SWang Nan * Set backward bit, ring buffer should be writing from end. Record 118626a6b78SWang Nan * it in aux evlist 119626a6b78SWang Nan */ 120626a6b78SWang Nan err = parse_events(evlist, "syscalls:sys_enter_prctl/overwrite/", &parse_error); 121ee74701eSWang Nan if (err) { 122ee74701eSWang Nan pr_debug("Failed to parse tracepoint event, try use root\n"); 123ee74701eSWang Nan ret = TEST_SKIP; 124ee74701eSWang Nan goto out_delete_evlist; 125ee74701eSWang Nan } 126ee74701eSWang Nan 127ee74701eSWang Nan perf_evlist__config(evlist, &opts, NULL); 128ee74701eSWang Nan 129ee74701eSWang Nan err = perf_evlist__open(evlist); 130ee74701eSWang Nan if (err < 0) { 131ee74701eSWang Nan pr_debug("perf_evlist__open: %s\n", 132c8b5f2c9SArnaldo Carvalho de Melo str_error_r(errno, sbuf, sizeof(sbuf))); 133ee74701eSWang Nan goto out_delete_evlist; 134ee74701eSWang Nan } 135ee74701eSWang Nan 136ee74701eSWang Nan ret = TEST_FAIL; 137ee74701eSWang Nan err = do_test(evlist, opts.mmap_pages, &sample_count, 138ee74701eSWang Nan &comm_count); 139ee74701eSWang Nan if (err != TEST_OK) 140ee74701eSWang Nan goto out_delete_evlist; 141ee74701eSWang Nan 142ee74701eSWang Nan if ((sample_count != NR_ITERS) || (comm_count != NR_ITERS)) { 143ee74701eSWang Nan pr_err("Unexpected counter: sample_count=%d, comm_count=%d\n", 144ee74701eSWang Nan sample_count, comm_count); 145ee74701eSWang Nan goto out_delete_evlist; 146ee74701eSWang Nan } 147ee74701eSWang Nan 148ee74701eSWang Nan err = do_test(evlist, 1, &sample_count, &comm_count); 149ee74701eSWang Nan if (err != TEST_OK) 150ee74701eSWang Nan goto out_delete_evlist; 151ee74701eSWang Nan 152ee74701eSWang Nan ret = TEST_OK; 153ee74701eSWang Nan out_delete_evlist: 154ee74701eSWang Nan perf_evlist__delete(evlist); 155ee74701eSWang Nan return ret; 156ee74701eSWang Nan } 157