Merge git://github.com/davem330/sparc
[pandora-kernel.git] / tools / perf / builtin-test.c
index 2da9162..efe696f 100644 (file)
@@ -12,6 +12,7 @@
 #include "util/parse-events.h"
 #include "util/symbol.h"
 #include "util/thread_map.h"
+#include "../../include/linux/hw_breakpoint.h"
 
 static long page_size;
 
@@ -245,8 +246,8 @@ static int trace_event__id(const char *evname)
        int err = -1, fd;
 
        if (asprintf(&filename,
-                    "/sys/kernel/debug/tracing/events/syscalls/%s/id",
-                    evname) < 0)
+                    "%s/syscalls/%s/id",
+                    debugfs_path, evname) < 0)
                return -1;
 
        fd = open(filename, O_RDONLY);
@@ -560,7 +561,7 @@ static int test__basic_mmap(void)
                }
 
                err = perf_event__parse_sample(event, attr.sample_type, sample_size,
-                                              false, &sample);
+                                              false, &sample, false);
                if (err) {
                        pr_err("Can't parse sample, err = %d\n", err);
                        goto out_munmap;
@@ -600,6 +601,246 @@ out_free_threads:
 #undef nsyscalls
 }
 
+#define TEST_ASSERT_VAL(text, cond) \
+do { \
+       if (!cond) { \
+               pr_debug("FAILED %s:%d %s\n", __FILE__, __LINE__, text); \
+               return -1; \
+       } \
+} while (0)
+
+static int test__checkevent_tracepoint(struct perf_evlist *evlist)
+{
+       struct perf_evsel *evsel = list_entry(evlist->entries.next,
+                                             struct perf_evsel, node);
+
+       TEST_ASSERT_VAL("wrong number of entries", 1 == evlist->nr_entries);
+       TEST_ASSERT_VAL("wrong type", PERF_TYPE_TRACEPOINT == evsel->attr.type);
+       TEST_ASSERT_VAL("wrong sample_type",
+               (PERF_SAMPLE_RAW | PERF_SAMPLE_TIME | PERF_SAMPLE_CPU) ==
+               evsel->attr.sample_type);
+       TEST_ASSERT_VAL("wrong sample_period", 1 == evsel->attr.sample_period);
+       return 0;
+}
+
+static int test__checkevent_tracepoint_multi(struct perf_evlist *evlist)
+{
+       struct perf_evsel *evsel;
+
+       TEST_ASSERT_VAL("wrong number of entries", evlist->nr_entries > 1);
+
+       list_for_each_entry(evsel, &evlist->entries, node) {
+               TEST_ASSERT_VAL("wrong type",
+                       PERF_TYPE_TRACEPOINT == evsel->attr.type);
+               TEST_ASSERT_VAL("wrong sample_type",
+                       (PERF_SAMPLE_RAW | PERF_SAMPLE_TIME | PERF_SAMPLE_CPU)
+                       == evsel->attr.sample_type);
+               TEST_ASSERT_VAL("wrong sample_period",
+                       1 == evsel->attr.sample_period);
+       }
+       return 0;
+}
+
+static int test__checkevent_raw(struct perf_evlist *evlist)
+{
+       struct perf_evsel *evsel = list_entry(evlist->entries.next,
+                                             struct perf_evsel, node);
+
+       TEST_ASSERT_VAL("wrong number of entries", 1 == evlist->nr_entries);
+       TEST_ASSERT_VAL("wrong type", PERF_TYPE_RAW == evsel->attr.type);
+       TEST_ASSERT_VAL("wrong config", 1 == evsel->attr.config);
+       return 0;
+}
+
+static int test__checkevent_numeric(struct perf_evlist *evlist)
+{
+       struct perf_evsel *evsel = list_entry(evlist->entries.next,
+                                             struct perf_evsel, node);
+
+       TEST_ASSERT_VAL("wrong number of entries", 1 == evlist->nr_entries);
+       TEST_ASSERT_VAL("wrong type", 1 == evsel->attr.type);
+       TEST_ASSERT_VAL("wrong config", 1 == evsel->attr.config);
+       return 0;
+}
+
+static int test__checkevent_symbolic_name(struct perf_evlist *evlist)
+{
+       struct perf_evsel *evsel = list_entry(evlist->entries.next,
+                                             struct perf_evsel, node);
+
+       TEST_ASSERT_VAL("wrong number of entries", 1 == evlist->nr_entries);
+       TEST_ASSERT_VAL("wrong type", PERF_TYPE_HARDWARE == evsel->attr.type);
+       TEST_ASSERT_VAL("wrong config",
+                       PERF_COUNT_HW_INSTRUCTIONS == evsel->attr.config);
+       return 0;
+}
+
+static int test__checkevent_symbolic_alias(struct perf_evlist *evlist)
+{
+       struct perf_evsel *evsel = list_entry(evlist->entries.next,
+                                             struct perf_evsel, node);
+
+       TEST_ASSERT_VAL("wrong number of entries", 1 == evlist->nr_entries);
+       TEST_ASSERT_VAL("wrong type", PERF_TYPE_SOFTWARE == evsel->attr.type);
+       TEST_ASSERT_VAL("wrong config",
+                       PERF_COUNT_SW_PAGE_FAULTS == evsel->attr.config);
+       return 0;
+}
+
+static int test__checkevent_genhw(struct perf_evlist *evlist)
+{
+       struct perf_evsel *evsel = list_entry(evlist->entries.next,
+                                             struct perf_evsel, node);
+
+       TEST_ASSERT_VAL("wrong number of entries", 1 == evlist->nr_entries);
+       TEST_ASSERT_VAL("wrong type", PERF_TYPE_HW_CACHE == evsel->attr.type);
+       TEST_ASSERT_VAL("wrong config", (1 << 16) == evsel->attr.config);
+       return 0;
+}
+
+static int test__checkevent_breakpoint(struct perf_evlist *evlist)
+{
+       struct perf_evsel *evsel = list_entry(evlist->entries.next,
+                                             struct perf_evsel, node);
+
+       TEST_ASSERT_VAL("wrong number of entries", 1 == evlist->nr_entries);
+       TEST_ASSERT_VAL("wrong type", PERF_TYPE_BREAKPOINT == evsel->attr.type);
+       TEST_ASSERT_VAL("wrong config", 0 == evsel->attr.config);
+       TEST_ASSERT_VAL("wrong bp_type", (HW_BREAKPOINT_R | HW_BREAKPOINT_W) ==
+                                        evsel->attr.bp_type);
+       TEST_ASSERT_VAL("wrong bp_len", HW_BREAKPOINT_LEN_4 ==
+                                       evsel->attr.bp_len);
+       return 0;
+}
+
+static int test__checkevent_breakpoint_x(struct perf_evlist *evlist)
+{
+       struct perf_evsel *evsel = list_entry(evlist->entries.next,
+                                             struct perf_evsel, node);
+
+       TEST_ASSERT_VAL("wrong number of entries", 1 == evlist->nr_entries);
+       TEST_ASSERT_VAL("wrong type", PERF_TYPE_BREAKPOINT == evsel->attr.type);
+       TEST_ASSERT_VAL("wrong config", 0 == evsel->attr.config);
+       TEST_ASSERT_VAL("wrong bp_type",
+                       HW_BREAKPOINT_X == evsel->attr.bp_type);
+       TEST_ASSERT_VAL("wrong bp_len", sizeof(long) == evsel->attr.bp_len);
+       return 0;
+}
+
+static int test__checkevent_breakpoint_r(struct perf_evlist *evlist)
+{
+       struct perf_evsel *evsel = list_entry(evlist->entries.next,
+                                             struct perf_evsel, node);
+
+       TEST_ASSERT_VAL("wrong number of entries", 1 == evlist->nr_entries);
+       TEST_ASSERT_VAL("wrong type",
+                       PERF_TYPE_BREAKPOINT == evsel->attr.type);
+       TEST_ASSERT_VAL("wrong config", 0 == evsel->attr.config);
+       TEST_ASSERT_VAL("wrong bp_type",
+                       HW_BREAKPOINT_R == evsel->attr.bp_type);
+       TEST_ASSERT_VAL("wrong bp_len",
+                       HW_BREAKPOINT_LEN_4 == evsel->attr.bp_len);
+       return 0;
+}
+
+static int test__checkevent_breakpoint_w(struct perf_evlist *evlist)
+{
+       struct perf_evsel *evsel = list_entry(evlist->entries.next,
+                                             struct perf_evsel, node);
+
+       TEST_ASSERT_VAL("wrong number of entries", 1 == evlist->nr_entries);
+       TEST_ASSERT_VAL("wrong type",
+                       PERF_TYPE_BREAKPOINT == evsel->attr.type);
+       TEST_ASSERT_VAL("wrong config", 0 == evsel->attr.config);
+       TEST_ASSERT_VAL("wrong bp_type",
+                       HW_BREAKPOINT_W == evsel->attr.bp_type);
+       TEST_ASSERT_VAL("wrong bp_len",
+                       HW_BREAKPOINT_LEN_4 == evsel->attr.bp_len);
+       return 0;
+}
+
+static struct test__event_st {
+       const char *name;
+       __u32 type;
+       int (*check)(struct perf_evlist *evlist);
+} test__events[] = {
+       {
+               .name  = "syscalls:sys_enter_open",
+               .check = test__checkevent_tracepoint,
+       },
+       {
+               .name  = "syscalls:*",
+               .check = test__checkevent_tracepoint_multi,
+       },
+       {
+               .name  = "r1",
+               .check = test__checkevent_raw,
+       },
+       {
+               .name  = "1:1",
+               .check = test__checkevent_numeric,
+       },
+       {
+               .name  = "instructions",
+               .check = test__checkevent_symbolic_name,
+       },
+       {
+               .name  = "faults",
+               .check = test__checkevent_symbolic_alias,
+       },
+       {
+               .name  = "L1-dcache-load-miss",
+               .check = test__checkevent_genhw,
+       },
+       {
+               .name  = "mem:0",
+               .check = test__checkevent_breakpoint,
+       },
+       {
+               .name  = "mem:0:x",
+               .check = test__checkevent_breakpoint_x,
+       },
+       {
+               .name  = "mem:0:r",
+               .check = test__checkevent_breakpoint_r,
+       },
+       {
+               .name  = "mem:0:w",
+               .check = test__checkevent_breakpoint_w,
+       },
+};
+
+#define TEST__EVENTS_CNT (sizeof(test__events) / sizeof(struct test__event_st))
+
+static int test__parse_events(void)
+{
+       struct perf_evlist *evlist;
+       u_int i;
+       int ret = 0;
+
+       for (i = 0; i < TEST__EVENTS_CNT; i++) {
+               struct test__event_st *e = &test__events[i];
+
+               evlist = perf_evlist__new(NULL, NULL);
+               if (evlist == NULL)
+                       break;
+
+               ret = parse_events(evlist, e->name, 0);
+               if (ret) {
+                       pr_debug("failed to parse event '%s', err %d\n",
+                                e->name, ret);
+                       break;
+               }
+
+               ret = e->check(evlist);
+               if (ret)
+                       break;
+
+               perf_evlist__delete(evlist);
+       }
+
+       return ret;
+}
 static struct test {
        const char *desc;
        int (*func)(void);
@@ -620,6 +861,10 @@ static struct test {
                .desc = "read samples using the mmap interface",
                .func = test__basic_mmap,
        },
+       {
+               .desc = "parse events tests",
+               .func = test__parse_events,
+       },
        {
                .func = NULL,
        },