lkml.org 
[lkml]   [2016]   [Mar]   [31]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    Subject[tip:perf/core] perf tests: Add test to check for event times
    Commit-ID:  b31d660df37c1701fd18d526faeb9a86f0fc7dd2
    Gitweb: http://git.kernel.org/tip/b31d660df37c1701fd18d526faeb9a86f0fc7dd2
    Author: Jiri Olsa <jolsa@kernel.org>
    AuthorDate: Thu, 24 Mar 2016 13:52:20 +0100
    Committer: Arnaldo Carvalho de Melo <acme@redhat.com>
    CommitDate: Wed, 30 Mar 2016 11:14:08 -0300

    perf tests: Add test to check for event times

    This test creates software event 'cpu-clock' attaches it in several ways
    and checks that enabled and running times match.

    Committer notes:

    Testing it:

    [acme@jouet linux]$ perf test -v times
    44: Test events times :
    --- start ---
    test child forked, pid 27170
    attaching to spawned child, enable on exec
    OK : ena 307328, run 307328
    attaching to current thread as enabled
    OK : ena 7826, run 7826
    attaching to current thread as disabled
    OK : ena 738, run 738
    attaching to CPU 0 as enabled
    SKIP : not enough rights
    attaching to CPU 0 as enabled
    SKIP : not enough rights
    test child finished with -2
    ---- end ----
    Test events times: Skip
    [acme@jouet linux]$

    [root@jouet ~]# perf test times
    44: Test events times : Ok
    [root@jouet ~]# perf test -v times
    44: Test events times :
    --- start ---
    test child forked, pid 27306
    attaching to spawned child, enable on exec
    OK : ena 479290, run 479290
    attaching to current thread as enabled
    OK : ena 11356, run 11356
    attaching to current thread as disabled
    OK : ena 987, run 987
    attaching to CPU 0 as enabled
    OK : ena 3717, run 3717
    attaching to CPU 0 as enabled
    OK : ena 2323, run 2323
    test child finished with 0
    ---- end ----
    Test events times: Ok
    [root@jouet ~]#

    Signed-off-by: Jiri Olsa <jolsa@kernel.org>
    Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com>
    Cc: Andi Kleen <ak@linux.intel.com>
    Cc: David Ahern <dsahern@gmail.com>
    Cc: Namhyung Kim <namhyung@kernel.org>
    Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
    Cc: Stephane Eranian <eranian@google.com>
    Link: http://lkml.kernel.org/r/1458823940-24583-7-git-send-email-jolsa@kernel.org
    Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
    ---
    tools/perf/tests/Build | 1 +
    tools/perf/tests/builtin-test.c | 4 +
    tools/perf/tests/event-times.c | 236 ++++++++++++++++++++++++++++++++++++++++
    tools/perf/tests/tests.h | 1 +
    4 files changed, 242 insertions(+)

    diff --git a/tools/perf/tests/Build b/tools/perf/tests/Build
    index 1ba628e..449fe97 100644
    --- a/tools/perf/tests/Build
    +++ b/tools/perf/tests/Build
    @@ -37,6 +37,7 @@ perf-y += topology.o
    perf-y += cpumap.o
    perf-y += stat.o
    perf-y += event_update.o
    +perf-y += event-times.o

    $(OUTPUT)tests/llvm-src-base.c: tests/bpf-script-example.c tests/Build
    $(call rule_mkdir)
    diff --git a/tools/perf/tests/builtin-test.c b/tools/perf/tests/builtin-test.c
    index f2b1dca..93c4670 100644
    --- a/tools/perf/tests/builtin-test.c
    +++ b/tools/perf/tests/builtin-test.c
    @@ -204,6 +204,10 @@ static struct test generic_tests[] = {
    .func = test__event_update,
    },
    {
    + .desc = "Test events times",
    + .func = test__event_times,
    + },
    + {
    .func = NULL,
    },
    };
    diff --git a/tools/perf/tests/event-times.c b/tools/perf/tests/event-times.c
    new file mode 100644
    index 0000000..95fb744
    --- /dev/null
    +++ b/tools/perf/tests/event-times.c
    @@ -0,0 +1,236 @@
    +#include <linux/compiler.h>
    +#include <string.h>
    +#include "tests.h"
    +#include "evlist.h"
    +#include "evsel.h"
    +#include "util.h"
    +#include "debug.h"
    +#include "thread_map.h"
    +#include "target.h"
    +
    +static int attach__enable_on_exec(struct perf_evlist *evlist)
    +{
    + struct perf_evsel *evsel = perf_evlist__last(evlist);
    + struct target target = {
    + .uid = UINT_MAX,
    + };
    + const char *argv[] = { "true", NULL, };
    + char sbuf[STRERR_BUFSIZE];
    + int err;
    +
    + pr_debug("attaching to spawned child, enable on exec\n");
    +
    + err = perf_evlist__create_maps(evlist, &target);
    + if (err < 0) {
    + pr_debug("Not enough memory to create thread/cpu maps\n");
    + return err;
    + }
    +
    + err = perf_evlist__prepare_workload(evlist, &target, argv, false, NULL);
    + if (err < 0) {
    + pr_debug("Couldn't run the workload!\n");
    + return err;
    + }
    +
    + evsel->attr.enable_on_exec = 1;
    +
    + err = perf_evlist__open(evlist);
    + if (err < 0) {
    + pr_debug("perf_evlist__open: %s\n",
    + strerror_r(errno, sbuf, sizeof(sbuf)));
    + return err;
    + }
    +
    + return perf_evlist__start_workload(evlist) == 1 ? TEST_OK : TEST_FAIL;
    +}
    +
    +static int detach__enable_on_exec(struct perf_evlist *evlist)
    +{
    + waitpid(evlist->workload.pid, NULL, 0);
    + return 0;
    +}
    +
    +static int attach__current_disabled(struct perf_evlist *evlist)
    +{
    + struct perf_evsel *evsel = perf_evlist__last(evlist);
    + struct thread_map *threads;
    + int err;
    +
    + pr_debug("attaching to current thread as disabled\n");
    +
    + threads = thread_map__new(-1, getpid(), UINT_MAX);
    + if (threads == NULL) {
    + pr_debug("thread_map__new\n");
    + return -1;
    + }
    +
    + evsel->attr.disabled = 1;
    +
    + err = perf_evsel__open_per_thread(evsel, threads);
    + if (err) {
    + pr_debug("Failed to open event cpu-clock:u\n");
    + return err;
    + }
    +
    + thread_map__put(threads);
    + return perf_evsel__enable(evsel) == 0 ? TEST_OK : TEST_FAIL;
    +}
    +
    +static int attach__current_enabled(struct perf_evlist *evlist)
    +{
    + struct perf_evsel *evsel = perf_evlist__last(evlist);
    + struct thread_map *threads;
    + int err;
    +
    + pr_debug("attaching to current thread as enabled\n");
    +
    + threads = thread_map__new(-1, getpid(), UINT_MAX);
    + if (threads == NULL) {
    + pr_debug("failed to call thread_map__new\n");
    + return -1;
    + }
    +
    + err = perf_evsel__open_per_thread(evsel, threads);
    +
    + thread_map__put(threads);
    + return err == 0 ? TEST_OK : TEST_FAIL;
    +}
    +
    +static int detach__disable(struct perf_evlist *evlist)
    +{
    + struct perf_evsel *evsel = perf_evlist__last(evlist);
    +
    + return perf_evsel__enable(evsel);
    +}
    +
    +static int attach__cpu_disabled(struct perf_evlist *evlist)
    +{
    + struct perf_evsel *evsel = perf_evlist__last(evlist);
    + struct cpu_map *cpus;
    + int err;
    +
    + pr_debug("attaching to CPU 0 as enabled\n");
    +
    + cpus = cpu_map__new("0");
    + if (cpus == NULL) {
    + pr_debug("failed to call cpu_map__new\n");
    + return -1;
    + }
    +
    + evsel->attr.disabled = 1;
    +
    + err = perf_evsel__open_per_cpu(evsel, cpus);
    + if (err) {
    + if (err == -EACCES)
    + return TEST_SKIP;
    +
    + pr_debug("Failed to open event cpu-clock:u\n");
    + return err;
    + }
    +
    + cpu_map__put(cpus);
    + return perf_evsel__enable(evsel);
    +}
    +
    +static int attach__cpu_enabled(struct perf_evlist *evlist)
    +{
    + struct perf_evsel *evsel = perf_evlist__last(evlist);
    + struct cpu_map *cpus;
    + int err;
    +
    + pr_debug("attaching to CPU 0 as enabled\n");
    +
    + cpus = cpu_map__new("0");
    + if (cpus == NULL) {
    + pr_debug("failed to call cpu_map__new\n");
    + return -1;
    + }
    +
    + err = perf_evsel__open_per_cpu(evsel, cpus);
    + if (err == -EACCES)
    + return TEST_SKIP;
    +
    + cpu_map__put(cpus);
    + return err ? TEST_FAIL : TEST_OK;
    +}
    +
    +static int test_times(int (attach)(struct perf_evlist *),
    + int (detach)(struct perf_evlist *))
    +{
    + struct perf_counts_values count;
    + struct perf_evlist *evlist = NULL;
    + struct perf_evsel *evsel;
    + int err = -1, i;
    +
    + evlist = perf_evlist__new();
    + if (!evlist) {
    + pr_debug("failed to create event list\n");
    + goto out_err;
    + }
    +
    + err = parse_events(evlist, "cpu-clock:u", NULL);
    + if (err) {
    + pr_debug("failed to parse event cpu-clock:u\n");
    + goto out_err;
    + }
    +
    + evsel = perf_evlist__last(evlist);
    + evsel->attr.read_format |=
    + PERF_FORMAT_TOTAL_TIME_ENABLED |
    + PERF_FORMAT_TOTAL_TIME_RUNNING;
    +
    + err = attach(evlist);
    + if (err == TEST_SKIP) {
    + pr_debug(" SKIP : not enough rights\n");
    + return err;
    + }
    +
    + TEST_ASSERT_VAL("failed to attach", !err);
    +
    + for (i = 0; i < 100000000; i++) { }
    +
    + TEST_ASSERT_VAL("failed to detach", !detach(evlist));
    +
    + perf_evsel__read(evsel, 0, 0, &count);
    +
    + err = !(count.ena == count.run);
    +
    + pr_debug(" %s: ena %" PRIu64", run %" PRIu64"\n",
    + !err ? "OK " : "FAILED",
    + count.ena, count.run);
    +
    +out_err:
    + if (evlist)
    + perf_evlist__delete(evlist);
    + return !err ? TEST_OK : TEST_FAIL;
    +}
    +
    +/*
    + * This test creates software event 'cpu-clock'
    + * attaches it in several ways (explained below)
    + * and checks that enabled and running times
    + * match.
    + */
    +int test__event_times(int subtest __maybe_unused)
    +{
    + int err, ret = 0;
    +
    +#define _T(attach, detach) \
    + err = test_times(attach, detach); \
    + if (err && (ret == TEST_OK || ret == TEST_SKIP)) \
    + ret = err;
    +
    + /* attach on newly spawned process after exec */
    + _T(attach__enable_on_exec, detach__enable_on_exec)
    + /* attach on current process as enabled */
    + _T(attach__current_enabled, detach__disable)
    + /* attach on current process as disabled */
    + _T(attach__current_disabled, detach__disable)
    + /* attach on cpu as disabled */
    + _T(attach__cpu_disabled, detach__disable)
    + /* attach on cpu as enabled */
    + _T(attach__cpu_enabled, detach__disable)
    +
    +#undef _T
    + return ret;
    +}
    diff --git a/tools/perf/tests/tests.h b/tools/perf/tests/tests.h
    index 82b2b5e..0fc9469 100644
    --- a/tools/perf/tests/tests.h
    +++ b/tools/perf/tests/tests.h
    @@ -85,6 +85,7 @@ int test__synthesize_stat_config(int subtest);
    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);

    #if defined(__arm__) || defined(__aarch64__)
    #ifdef HAVE_DWARF_UNWIND_SUPPORT
    \
     
     \ /
      Last update: 2016-03-31 09:01    [W:3.564 / U:0.096 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site