Em Mon, May 09, 2016 at 01:47:51AM +0000, Wang Nan escreveu: > This test checks reading from backward ring buffer. > > Test result: > > # ~/perf test 'ring buffer' > 45: Test backward reading from ring buffer : Ok
Thanks, applied and also I added a patch to show that bit when using -vv, i.e.: # perf test -vv back 45: Test backward reading from ring buffer : --- start --- <SNIP> ------------------------------------------------------------ perf_event_attr: type 2 size 112 config 0x98 { sample_period, sample_freq } 1 sample_type IP|TID|TIME|CPU|PERIOD|RAW disabled 1 mmap 1 comm 1 task 1 sample_id_all 1 exclude_guest 1 mmap2 1 comm_exec 1 write_backward 1 ------------------------------------------------------------ <SNIP> > Test case is a while loop which calls prctl(PR_SET_NAME) multiple > times. Each prctl should issue 2 events: one PERF_RECORD_SAMPLE, > one PERF_RECORD_COMM. > > The first round creates a relative large ring buffer (256 pages). It > can afford all events. Read from it and check the count of each type of > events. > > The second round creates a small ring buffer (1 page) and makes it > overwritable. Check the correctness of the buffer. > > Signed-off-by: Wang Nan <wangn...@huawei.com> > Cc: Arnaldo Carvalho de Melo <a...@redhat.com> > Cc: Peter Zijlstra <pet...@infradead.org> > Cc: Zefan Li <lize...@huawei.com> > Cc: pi3or...@163.com > --- > tools/perf/tests/Build | 1 + > tools/perf/tests/backward-ring-buffer.c | 151 > ++++++++++++++++++++++++++++++++ > tools/perf/tests/builtin-test.c | 4 + > tools/perf/tests/tests.h | 1 + > 4 files changed, 157 insertions(+) > create mode 100644 tools/perf/tests/backward-ring-buffer.c > > diff --git a/tools/perf/tests/Build b/tools/perf/tests/Build > index 449fe97..66a2898 100644 > --- a/tools/perf/tests/Build > +++ b/tools/perf/tests/Build > @@ -38,6 +38,7 @@ perf-y += cpumap.o > perf-y += stat.o > perf-y += event_update.o > perf-y += event-times.o > +perf-y += backward-ring-buffer.o > > $(OUTPUT)tests/llvm-src-base.c: tests/bpf-script-example.c tests/Build > $(call rule_mkdir) > diff --git a/tools/perf/tests/backward-ring-buffer.c > b/tools/perf/tests/backward-ring-buffer.c > new file mode 100644 > index 0000000..d9ba991 > --- /dev/null > +++ b/tools/perf/tests/backward-ring-buffer.c > @@ -0,0 +1,151 @@ > +/* > + * Test backward bit in event attribute, read ring buffer from end to > + * beginning > + */ > + > +#include <perf.h> > +#include <evlist.h> > +#include <sys/prctl.h> > +#include "tests.h" > +#include "debug.h" > + > +#define NR_ITERS 111 > + > +static void testcase(void) > +{ > + int i; > + > + for (i = 0; i < NR_ITERS; i++) { > + char proc_name[10]; > + > + snprintf(proc_name, sizeof(proc_name), "p:%d\n", i); > + prctl(PR_SET_NAME, proc_name); > + } > +} > + > +static int count_samples(struct perf_evlist *evlist, int *sample_count, > + int *comm_count) > +{ > + int i; > + > + for (i = 0; i < evlist->nr_mmaps; i++) { > + union perf_event *event; > + > + perf_evlist__mmap_read_catchup(evlist, i); > + while ((event = perf_evlist__mmap_read_backward(evlist, i)) != > NULL) { > + const u32 type = event->header.type; > + > + switch (type) { > + case PERF_RECORD_SAMPLE: > + (*sample_count)++; > + break; > + case PERF_RECORD_COMM: > + (*comm_count)++; > + break; > + default: > + pr_err("Unexpected record of type %d\n", type); > + return TEST_FAIL; > + } > + } > + } > + return TEST_OK; > +} > + > +static int do_test(struct perf_evlist *evlist, int mmap_pages, > + int *sample_count, int *comm_count) > +{ > + int err; > + char sbuf[STRERR_BUFSIZE]; > + > + err = perf_evlist__mmap(evlist, mmap_pages, true); > + if (err < 0) { > + pr_debug("perf_evlist__mmap: %s\n", > + strerror_r(errno, sbuf, sizeof(sbuf))); > + return TEST_FAIL; > + } > + > + perf_evlist__enable(evlist); > + testcase(); > + perf_evlist__disable(evlist); > + > + err = count_samples(evlist, sample_count, comm_count); > + perf_evlist__munmap(evlist); > + return err; > +} > + > + > +int test__backward_ring_buffer(int subtest __maybe_unused) > +{ > + int ret = TEST_SKIP, err, sample_count = 0, comm_count = 0; > + char pid[16], sbuf[STRERR_BUFSIZE]; > + struct perf_evlist *evlist; > + struct perf_evsel *evsel __maybe_unused; > + struct parse_events_error parse_error; > + struct record_opts opts = { > + .target = { > + .uid = UINT_MAX, > + .uses_mmap = true, > + }, > + .freq = 0, > + .mmap_pages = 256, > + .default_interval = 1, > + }; > + > + snprintf(pid, sizeof(pid), "%d", getpid()); > + pid[sizeof(pid) - 1] = '\0'; > + opts.target.tid = opts.target.pid = pid; > + > + evlist = perf_evlist__new(); > + if (!evlist) { > + pr_debug("No ehough memory to create evlist\n"); > + return TEST_FAIL; > + } > + > + err = perf_evlist__create_maps(evlist, &opts.target); > + if (err < 0) { > + pr_debug("Not enough memory to create thread/cpu maps\n"); > + goto out_delete_evlist; > + } > + > + bzero(&parse_error, sizeof(parse_error)); > + err = parse_events(evlist, "syscalls:sys_enter_prctl", &parse_error); > + if (err) { > + pr_debug("Failed to parse tracepoint event, try use root\n"); > + ret = TEST_SKIP; > + goto out_delete_evlist; > + } > + > + perf_evlist__config(evlist, &opts, NULL); > + > + /* Set backward bit, ring buffer should be writing from end */ > + evlist__for_each(evlist, evsel) > + evsel->attr.write_backward = 1; > + > + err = perf_evlist__open(evlist); > + if (err < 0) { > + pr_debug("perf_evlist__open: %s\n", > + strerror_r(errno, sbuf, sizeof(sbuf))); > + goto out_delete_evlist; > + } > + > + ret = TEST_FAIL; > + err = do_test(evlist, opts.mmap_pages, &sample_count, > + &comm_count); > + if (err != TEST_OK) > + goto out_delete_evlist; > + > + if ((sample_count != NR_ITERS) || (comm_count != NR_ITERS)) { > + pr_err("Unexpected counter: sample_count=%d, comm_count=%d\n", > + sample_count, comm_count); > + goto out_delete_evlist; > + } > + > + err = do_test(evlist, 1, &sample_count, &comm_count); > + if (err != TEST_OK) > + goto out_delete_evlist; > + > + ret = TEST_OK; > +out_delete_evlist: > + perf_evlist__delete(evlist); > + return ret; > +} > diff --git a/tools/perf/tests/builtin-test.c b/tools/perf/tests/builtin-test.c > index 93c4670..0e95c20 100644 > --- a/tools/perf/tests/builtin-test.c > +++ b/tools/perf/tests/builtin-test.c > @@ -208,6 +208,10 @@ static struct test generic_tests[] = { > .func = test__event_times, > }, > { > + .desc = "Test backward reading from ring buffer", > + .func = test__backward_ring_buffer, > + }, > + { > .func = NULL, > }, > }; > diff --git a/tools/perf/tests/tests.h b/tools/perf/tests/tests.h > index 0fc9469..c57e72c 100644 > --- a/tools/perf/tests/tests.h > +++ b/tools/perf/tests/tests.h > @@ -86,6 +86,7 @@ int test__synthesize_stat(int subtest); > int test__synthesize_stat_round(int subtest); > int test__event_update(int subtest); > int test__event_times(int subtest); > +int test__backward_ring_buffer(int subtest); > > #if defined(__arm__) || defined(__aarch64__) > #ifdef HAVE_DWARF_UNWIND_SUPPORT > -- > 1.8.3.4