aboutsummaryrefslogtreecommitdiff
path: root/tools/perf/tests
diff options
context:
space:
mode:
Diffstat (limited to 'tools/perf/tests')
-rw-r--r--tools/perf/tests/Build3
-rw-r--r--tools/perf/tests/attr.c2
-rw-r--r--tools/perf/tests/backward-ring-buffer.c4
-rw-r--r--tools/perf/tests/bpf.c12
-rw-r--r--tools/perf/tests/builtin-test.c14
-rw-r--r--tools/perf/tests/code-reading.c8
-rw-r--r--tools/perf/tests/dwarf-unwind.c10
-rw-r--r--tools/perf/tests/event-times.c6
-rw-r--r--tools/perf/tests/event_update.c3
-rw-r--r--tools/perf/tests/evsel-tp-sched.c25
-rw-r--r--tools/perf/tests/expand-cgroup.c240
-rw-r--r--tools/perf/tests/keep-tracking.c2
-rw-r--r--tools/perf/tests/llvm.c30
-rw-r--r--tools/perf/tests/make2
-rw-r--r--tools/perf/tests/mmap-basic.c6
-rw-r--r--tools/perf/tests/openat-syscall-tp-fields.c6
-rw-r--r--tools/perf/tests/parse-events.c68
-rw-r--r--tools/perf/tests/parse-metric.c8
-rw-r--r--tools/perf/tests/parse-no-sample-id-all.c4
-rw-r--r--tools/perf/tests/pe-file-parsing.c98
-rw-r--r--tools/perf/tests/pe-file.c14
-rw-r--r--tools/perf/tests/pe-file.exebin0 -> 75595 bytes
-rw-r--r--tools/perf/tests/pe-file.exe.debugbin0 -> 141644 bytes
-rw-r--r--tools/perf/tests/perf-record.c18
-rw-r--r--tools/perf/tests/perf-time-to-tsc.c184
-rw-r--r--tools/perf/tests/pmu-events.c16
-rw-r--r--tools/perf/tests/python-use.c1
-rw-r--r--tools/perf/tests/sample-parsing.c6
-rw-r--r--tools/perf/tests/sdt.c6
-rwxr-xr-xtools/perf/tests/shell/buildid.sh101
-rwxr-xr-xtools/perf/tests/shell/stat+shadow_stat.sh78
-rwxr-xr-xtools/perf/tests/shell/test_arm_coresight.sh183
-rwxr-xr-xtools/perf/tests/shell/trace+probe_vfs_getname.sh2
-rw-r--r--tools/perf/tests/sw-clock.c2
-rw-r--r--tools/perf/tests/switch-tracking.c18
-rw-r--r--tools/perf/tests/task-exit.c13
-rw-r--r--tools/perf/tests/tests.h5
-rw-r--r--tools/perf/tests/topology.c66
-rw-r--r--tools/perf/tests/wp.c21
39 files changed, 1172 insertions, 113 deletions
diff --git a/tools/perf/tests/Build b/tools/perf/tests/Build
index 84352fc49a20..aa4dc4f5abde 100644
--- a/tools/perf/tests/Build
+++ b/tools/perf/tests/Build
@@ -60,6 +60,9 @@ perf-y += api-io.o
perf-y += demangle-java-test.o
perf-y += pfm.o
perf-y += parse-metric.o
+perf-y += pe-file-parsing.o
+perf-y += expand-cgroup.o
+perf-y += perf-time-to-tsc.o
$(OUTPUT)tests/llvm-src-base.c: tests/bpf-script-example.c tests/Build
$(call rule_mkdir)
diff --git a/tools/perf/tests/attr.c b/tools/perf/tests/attr.c
index a9599ab8c471..ec972e0892ab 100644
--- a/tools/perf/tests/attr.c
+++ b/tools/perf/tests/attr.c
@@ -30,9 +30,9 @@
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
-#include "../perf-sys.h"
#include <subcmd/exec-cmd.h>
#include "event.h"
+#include "util.h"
#include "tests.h"
#define ENV "PERF_TEST_ATTR"
diff --git a/tools/perf/tests/backward-ring-buffer.c b/tools/perf/tests/backward-ring-buffer.c
index 15cea518f5ad..b4b9a9488d51 100644
--- a/tools/perf/tests/backward-ring-buffer.c
+++ b/tools/perf/tests/backward-ring-buffer.c
@@ -109,7 +109,7 @@ int test__backward_ring_buffer(struct test *test __maybe_unused, int subtest __m
return TEST_FAIL;
}
- err = perf_evlist__create_maps(evlist, &opts.target);
+ err = evlist__create_maps(evlist, &opts.target);
if (err < 0) {
pr_debug("Not enough memory to create thread/cpu maps\n");
goto out_delete_evlist;
@@ -127,7 +127,7 @@ int test__backward_ring_buffer(struct test *test __maybe_unused, int subtest __m
goto out_delete_evlist;
}
- perf_evlist__config(evlist, &opts, NULL);
+ evlist__config(evlist, &opts, NULL);
err = evlist__open(evlist);
if (err < 0) {
diff --git a/tools/perf/tests/bpf.c b/tools/perf/tests/bpf.c
index cd77e334e577..f57e075b0ed2 100644
--- a/tools/perf/tests/bpf.c
+++ b/tools/perf/tests/bpf.c
@@ -9,12 +9,10 @@
#include <util/util.h>
#include <util/bpf-loader.h>
#include <util/evlist.h>
-#include <linux/bpf.h>
#include <linux/filter.h>
#include <linux/kernel.h>
#include <linux/string.h>
#include <api/fs/fs.h>
-#include <bpf/bpf.h>
#include <perf/mmap.h>
#include "tests.h"
#include "llvm.h"
@@ -25,6 +23,8 @@
#define PERF_TEST_BPF_PATH "/sys/fs/bpf/perf_test"
#ifdef HAVE_LIBBPF_SUPPORT
+#include <linux/bpf.h>
+#include <bpf/bpf.h>
static int epoll_pwait_loop(void)
{
@@ -144,23 +144,23 @@ static int do_test(struct bpf_object *obj, int (*func)(void),
pid[sizeof(pid) - 1] = '\0';
opts.target.tid = opts.target.pid = pid;
- /* Instead of perf_evlist__new_default, don't add default events */
+ /* Instead of evlist__new_default, don't add default events */
evlist = evlist__new();
if (!evlist) {
pr_debug("Not enough memory to create evlist\n");
return TEST_FAIL;
}
- err = perf_evlist__create_maps(evlist, &opts.target);
+ err = evlist__create_maps(evlist, &opts.target);
if (err < 0) {
pr_debug("Not enough memory to create thread/cpu maps\n");
goto out_delete_evlist;
}
- perf_evlist__splice_list_tail(evlist, &parse_state.list);
+ evlist__splice_list_tail(evlist, &parse_state.list);
evlist->nr_groups = parse_state.nr_groups;
- perf_evlist__config(evlist, &opts, NULL);
+ evlist__config(evlist, &opts, NULL);
err = evlist__open(evlist);
if (err < 0) {
diff --git a/tools/perf/tests/builtin-test.c b/tools/perf/tests/builtin-test.c
index d328caaba45d..7273823d0d02 100644
--- a/tools/perf/tests/builtin-test.c
+++ b/tools/perf/tests/builtin-test.c
@@ -142,6 +142,7 @@ static struct test generic_tests[] = {
.skip_if_fail = false,
.get_nr = test__wp_subtest_get_nr,
.get_desc = test__wp_subtest_get_desc,
+ .skip_reason = test__wp_subtest_skip_reason,
},
},
{
@@ -342,6 +343,19 @@ static struct test generic_tests[] = {
.func = test__parse_metric,
},
{
+ .desc = "PE file support",
+ .func = test__pe_file_parsing,
+ },
+ {
+ .desc = "Event expansion for cgroups",
+ .func = test__expand_cgroup_events,
+ },
+ {
+ .desc = "Convert perf time to TSC",
+ .func = test__perf_time_to_tsc,
+ .is_supported = test__tsc_is_supported,
+ },
+ {
.func = NULL,
},
};
diff --git a/tools/perf/tests/code-reading.c b/tools/perf/tests/code-reading.c
index 035c9123549a..7c098d49c77e 100644
--- a/tools/perf/tests/code-reading.c
+++ b/tools/perf/tests/code-reading.c
@@ -378,8 +378,8 @@ static int process_sample_event(struct machine *machine,
struct thread *thread;
int ret;
- if (perf_evlist__parse_sample(evlist, event, &sample)) {
- pr_debug("perf_evlist__parse_sample failed\n");
+ if (evlist__parse_sample(evlist, event, &sample)) {
+ pr_debug("evlist__parse_sample failed\n");
return -1;
}
@@ -637,7 +637,7 @@ static int do_test_code_reading(bool try_kcore)
evlist = evlist__new();
if (!evlist) {
- pr_debug("perf_evlist__new failed\n");
+ pr_debug("evlist__new failed\n");
goto out_put;
}
@@ -651,7 +651,7 @@ static int do_test_code_reading(bool try_kcore)
goto out_put;
}
- perf_evlist__config(evlist, &opts, NULL);
+ evlist__config(evlist, &opts, NULL);
evsel = evlist__first(evlist);
diff --git a/tools/perf/tests/dwarf-unwind.c b/tools/perf/tests/dwarf-unwind.c
index 2491d167bf76..83638097c3bc 100644
--- a/tools/perf/tests/dwarf-unwind.c
+++ b/tools/perf/tests/dwarf-unwind.c
@@ -95,7 +95,7 @@ static int unwind_entry(struct unwind_entry *entry, void *arg)
return strcmp((const char *) symbol, funcs[idx]);
}
-__no_tail_call noinline int test_dwarf_unwind__thread(struct thread *thread)
+noinline int test_dwarf_unwind__thread(struct thread *thread)
{
struct perf_sample sample;
unsigned long cnt = 0;
@@ -126,7 +126,7 @@ __no_tail_call noinline int test_dwarf_unwind__thread(struct thread *thread)
static int global_unwind_retval = -INT_MAX;
-__no_tail_call noinline int test_dwarf_unwind__compare(void *p1, void *p2)
+noinline int test_dwarf_unwind__compare(void *p1, void *p2)
{
/* Any possible value should be 'thread' */
struct thread *thread = *(struct thread **)p1;
@@ -145,7 +145,7 @@ __no_tail_call noinline int test_dwarf_unwind__compare(void *p1, void *p2)
return p1 - p2;
}
-__no_tail_call noinline int test_dwarf_unwind__krava_3(struct thread *thread)
+noinline int test_dwarf_unwind__krava_3(struct thread *thread)
{
struct thread *array[2] = {thread, thread};
void *fp = &bsearch;
@@ -164,12 +164,12 @@ __no_tail_call noinline int test_dwarf_unwind__krava_3(struct thread *thread)
return global_unwind_retval;
}
-__no_tail_call noinline int test_dwarf_unwind__krava_2(struct thread *thread)
+noinline int test_dwarf_unwind__krava_2(struct thread *thread)
{
return test_dwarf_unwind__krava_3(thread);
}
-__no_tail_call noinline int test_dwarf_unwind__krava_1(struct thread *thread)
+noinline int test_dwarf_unwind__krava_1(struct thread *thread)
{
return test_dwarf_unwind__krava_2(thread);
}
diff --git a/tools/perf/tests/event-times.c b/tools/perf/tests/event-times.c
index db68894a6f40..04ce4401f775 100644
--- a/tools/perf/tests/event-times.c
+++ b/tools/perf/tests/event-times.c
@@ -26,13 +26,13 @@ static int attach__enable_on_exec(struct evlist *evlist)
pr_debug("attaching to spawned child, enable on exec\n");
- err = perf_evlist__create_maps(evlist, &target);
+ err = 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);
+ err = evlist__prepare_workload(evlist, &target, argv, false, NULL);
if (err < 0) {
pr_debug("Couldn't run the workload!\n");
return err;
@@ -47,7 +47,7 @@ static int attach__enable_on_exec(struct evlist *evlist)
return err;
}
- return perf_evlist__start_workload(evlist) == 1 ? TEST_OK : TEST_FAIL;
+ return evlist__start_workload(evlist) == 1 ? TEST_OK : TEST_FAIL;
}
static int detach__enable_on_exec(struct evlist *evlist)
diff --git a/tools/perf/tests/event_update.c b/tools/perf/tests/event_update.c
index bdcf032f8516..656218179222 100644
--- a/tools/perf/tests/event_update.c
+++ b/tools/perf/tests/event_update.c
@@ -85,11 +85,10 @@ static int process_event_cpus(struct perf_tool *tool __maybe_unused,
int test__event_update(struct test *test __maybe_unused, int subtest __maybe_unused)
{
- struct evlist *evlist;
struct evsel *evsel;
struct event_name tmp;
+ struct evlist *evlist = evlist__new_default();
- evlist = perf_evlist__new_default();
TEST_ASSERT_VAL("failed to get evlist", evlist);
evsel = evlist__first(evlist);
diff --git a/tools/perf/tests/evsel-tp-sched.c b/tools/perf/tests/evsel-tp-sched.c
index 0e224a0a55d9..f9e34bd26cf3 100644
--- a/tools/perf/tests/evsel-tp-sched.c
+++ b/tools/perf/tests/evsel-tp-sched.c
@@ -5,8 +5,7 @@
#include "tests.h"
#include "debug.h"
-static int perf_evsel__test_field(struct evsel *evsel, const char *name,
- int size, bool should_be_signed)
+static int evsel__test_field(struct evsel *evsel, const char *name, int size, bool should_be_signed)
{
struct tep_format_field *field = evsel__field(evsel, name);
int is_signed;
@@ -43,25 +42,25 @@ int test__perf_evsel__tp_sched_test(struct test *test __maybe_unused, int subtes
return -1;
}
- if (perf_evsel__test_field(evsel, "prev_comm", 16, false))
+ if (evsel__test_field(evsel, "prev_comm", 16, false))
ret = -1;
- if (perf_evsel__test_field(evsel, "prev_pid", 4, true))
+ if (evsel__test_field(evsel, "prev_pid", 4, true))
ret = -1;
- if (perf_evsel__test_field(evsel, "prev_prio", 4, true))
+ if (evsel__test_field(evsel, "prev_prio", 4, true))
ret = -1;
- if (perf_evsel__test_field(evsel, "prev_state", sizeof(long), true))
+ if (evsel__test_field(evsel, "prev_state", sizeof(long), true))
ret = -1;
- if (perf_evsel__test_field(evsel, "next_comm", 16, false))
+ if (evsel__test_field(evsel, "next_comm", 16, false))
ret = -1;
- if (perf_evsel__test_field(evsel, "next_pid", 4, true))
+ if (evsel__test_field(evsel, "next_pid", 4, true))
ret = -1;
- if (perf_evsel__test_field(evsel, "next_prio", 4, true))
+ if (evsel__test_field(evsel, "next_prio", 4, true))
ret = -1;
evsel__delete(evsel);
@@ -73,16 +72,16 @@ int test__perf_evsel__tp_sched_test(struct test *test __maybe_unused, int subtes
return -1;
}
- if (perf_evsel__test_field(evsel, "comm", 16, false))
+ if (evsel__test_field(evsel, "comm", 16, false))
ret = -1;
- if (perf_evsel__test_field(evsel, "pid", 4, true))
+ if (evsel__test_field(evsel, "pid", 4, true))
ret = -1;
- if (perf_evsel__test_field(evsel, "prio", 4, true))
+ if (evsel__test_field(evsel, "prio", 4, true))
ret = -1;
- if (perf_evsel__test_field(evsel, "target_cpu", 4, true))
+ if (evsel__test_field(evsel, "target_cpu", 4, true))
ret = -1;
evsel__delete(evsel);
diff --git a/tools/perf/tests/expand-cgroup.c b/tools/perf/tests/expand-cgroup.c
new file mode 100644
index 000000000000..0e46aeb843ce
--- /dev/null
+++ b/tools/perf/tests/expand-cgroup.c
@@ -0,0 +1,240 @@
+// SPDX-License-Identifier: GPL-2.0
+#include "tests.h"
+#include "debug.h"
+#include "evlist.h"
+#include "cgroup.h"
+#include "rblist.h"
+#include "metricgroup.h"
+#include "parse-events.h"
+#include "pmu-events/pmu-events.h"
+#include "pfm.h"
+#include <subcmd/parse-options.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+static int test_expand_events(struct evlist *evlist,
+ struct rblist *metric_events)
+{
+ int i, ret = TEST_FAIL;
+ int nr_events;
+ bool was_group_event;
+ int nr_members; /* for the first evsel only */
+ const char cgrp_str[] = "A,B,C";
+ const char *cgrp_name[] = { "A", "B", "C" };
+ int nr_cgrps = ARRAY_SIZE(cgrp_name);
+ char **ev_name;
+ struct evsel *evsel;
+
+ TEST_ASSERT_VAL("evlist is empty", !evlist__empty(evlist));
+
+ nr_events = evlist->core.nr_entries;
+ ev_name = calloc(nr_events, sizeof(*ev_name));
+ if (ev_name == NULL) {
+ pr_debug("memory allocation failure\n");
+ return TEST_FAIL;
+ }
+ i = 0;
+ evlist__for_each_entry(evlist, evsel) {
+ ev_name[i] = strdup(evsel->name);
+ if (ev_name[i] == NULL) {
+ pr_debug("memory allocation failure\n");
+ goto out;
+ }
+ i++;
+ }
+ /* remember grouping info */
+ was_group_event = evsel__is_group_event(evlist__first(evlist));
+ nr_members = evlist__first(evlist)->core.nr_members;
+
+ ret = evlist__expand_cgroup(evlist, cgrp_str, metric_events, false);
+ if (ret < 0) {
+ pr_debug("failed to expand events for cgroups\n");
+ goto out;
+ }
+
+ ret = TEST_FAIL;
+ if (evlist->core.nr_entries != nr_events * nr_cgrps) {
+ pr_debug("event count doesn't match\n");
+ goto out;
+ }
+
+ i = 0;
+ evlist__for_each_entry(evlist, evsel) {
+ if (strcmp(evsel->name, ev_name[i % nr_events])) {
+ pr_debug("event name doesn't match:\n");
+ pr_debug(" evsel[%d]: %s\n expected: %s\n",
+ i, evsel->name, ev_name[i % nr_events]);
+ goto out;
+ }
+ if (strcmp(evsel->cgrp->name, cgrp_name[i / nr_events])) {
+ pr_debug("cgroup name doesn't match:\n");
+ pr_debug(" evsel[%d]: %s\n expected: %s\n",
+ i, evsel->cgrp->name, cgrp_name[i / nr_events]);
+ goto out;
+ }
+
+ if ((i % nr_events) == 0) {
+ if (evsel__is_group_event(evsel) != was_group_event) {
+ pr_debug("event group doesn't match: got %s, expect %s\n",
+ evsel__is_group_event(evsel) ? "true" : "false",
+ was_group_event ? "true" : "false");
+ goto out;
+ }
+ if (evsel->core.nr_members != nr_members) {
+ pr_debug("event group member doesn't match: %d vs %d\n",
+ evsel->core.nr_members, nr_members);
+ goto out;
+ }
+ }
+ i++;
+ }
+ ret = TEST_OK;
+
+out: for (i = 0; i < nr_events; i++)
+ free(ev_name[i]);
+ free(ev_name);
+ return ret;
+}
+
+static int expand_default_events(void)
+{
+ int ret;
+ struct rblist metric_events;
+ struct evlist *evlist = evlist__new_default();
+
+ TEST_ASSERT_VAL("failed to get evlist", evlist);
+
+ rblist__init(&metric_events);
+ ret = test_expand_events(evlist, &metric_events);
+ evlist__delete(evlist);
+ return ret;
+}
+
+static int expand_group_events(void)
+{
+ int ret;
+ struct evlist *evlist;
+ struct rblist metric_events;
+ struct parse_events_error err;
+ const char event_str[] = "{cycles,instructions}";
+
+ symbol_conf.event_group = true;
+
+ evlist = evlist__new();
+ TEST_ASSERT_VAL("failed to get evlist", evlist);
+
+ ret = parse_events(evlist, event_str, &err);
+ if (ret < 0) {
+ pr_debug("failed to parse event '%s', err %d, str '%s'\n",
+ event_str, ret, err.str);
+ parse_events_print_error(&err, event_str);
+ goto out;
+ }
+
+ rblist__init(&metric_events);
+ ret = test_expand_events(evlist, &metric_events);
+out:
+ evlist__delete(evlist);
+ return ret;
+}
+
+static int expand_libpfm_events(void)
+{
+ int ret;
+ struct evlist *evlist;
+ struct rblist metric_events;
+ const char event_str[] = "CYCLES";
+ struct option opt = {
+ .value = &evlist,
+ };
+
+ symbol_conf.event_group = true;
+
+ evlist = evlist__new();
+ TEST_ASSERT_VAL("failed to get evlist", evlist);
+
+ ret = parse_libpfm_events_option(&opt, event_str, 0);
+ if (ret < 0) {
+ pr_debug("failed to parse libpfm event '%s', err %d\n",
+ event_str, ret);
+ goto out;
+ }
+ if (evlist__empty(evlist)) {
+ pr_debug("libpfm was not enabled\n");
+ goto out;
+ }
+
+ rblist__init(&metric_events);
+ ret = test_expand_events(evlist, &metric_events);
+out:
+ evlist__delete(evlist);
+ return ret;
+}
+
+static int expand_metric_events(void)
+{
+ int ret;
+ struct evlist *evlist;
+ struct rblist metric_events;
+ const char metric_str[] = "CPI";
+
+ struct pmu_event pme_test[] = {
+ {
+ .metric_expr = "instructions / cycles",
+ .metric_name = "IPC",
+ },
+ {
+ .metric_expr = "1 / IPC",
+ .metric_name = "CPI",
+ },
+ {
+ .metric_expr = NULL,
+ .metric_name = NULL,
+ },
+ };
+ struct pmu_events_map ev_map = {
+ .cpuid = "test",
+ .version = "1",
+ .type = "core",
+ .table = pme_test,
+ };
+
+ evlist = evlist__new();
+ TEST_ASSERT_VAL("failed to get evlist", evlist);
+
+ rblist__init(&metric_events);
+ ret = metricgroup__parse_groups_test(evlist, &ev_map, metric_str,
+ false, false, &metric_events);
+ if (ret < 0) {
+ pr_debug("failed to parse '%s' metric\n", metric_str);
+ goto out;
+ }
+
+ ret = test_expand_events(evlist, &metric_events);
+
+out:
+ metricgroup__rblist_exit(&metric_events);
+ evlist__delete(evlist);
+ return ret;
+}
+
+int test__expand_cgroup_events(struct test *test __maybe_unused,
+ int subtest __maybe_unused)
+{
+ int ret;
+
+ ret = expand_default_events();
+ TEST_ASSERT_EQUAL("failed to expand default events", ret, 0);
+
+ ret = expand_group_events();
+ TEST_ASSERT_EQUAL("failed to expand event group", ret, 0);
+
+ ret = expand_libpfm_events();
+ TEST_ASSERT_EQUAL("failed to expand event group", ret, 0);
+
+ ret = expand_metric_events();
+ TEST_ASSERT_EQUAL("failed to expand metric events", ret, 0);
+
+ return ret;
+}
diff --git a/tools/perf/tests/keep-tracking.c b/tools/perf/tests/keep-tracking.c
index 50a0c9fcde7d..e6f1b2a38e03 100644
--- a/tools/perf/tests/keep-tracking.c
+++ b/tools/perf/tests/keep-tracking.c
@@ -92,7 +92,7 @@ int test__keep_tracking(struct test *test __maybe_unused, int subtest __maybe_un
CHECK__(parse_events(evlist, "dummy:u", NULL));
CHECK__(parse_events(evlist, "cycles:u", NULL));
- perf_evlist__config(evlist, &opts, NULL);
+ evlist__config(evlist, &opts, NULL);
evsel = evlist__first(evlist);
diff --git a/tools/perf/tests/llvm.c b/tools/perf/tests/llvm.c
index ae6cda81c209..98da8a8757ab 100644
--- a/tools/perf/tests/llvm.c
+++ b/tools/perf/tests/llvm.c
@@ -2,13 +2,13 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
-#include <bpf/libbpf.h>
-#include <util/llvm-utils.h>
-#include "llvm.h"
#include "tests.h"
#include "debug.h"
#ifdef HAVE_LIBBPF_SUPPORT
+#include <bpf/libbpf.h>
+#include <util/llvm-utils.h>
+#include "llvm.h"
static int test__bpf_parsing(void *obj_buf, size_t obj_buf_sz)
{
struct bpf_object *obj;
@@ -19,14 +19,6 @@ static int test__bpf_parsing(void *obj_buf, size_t obj_buf_sz)
bpf_object__close(obj);
return TEST_OK;
}
-#else
-static int test__bpf_parsing(void *obj_buf __maybe_unused,
- size_t obj_buf_sz __maybe_unused)
-{
- pr_debug("Skip bpf parsing\n");
- return TEST_OK;
-}
-#endif
static struct {
const char *source;
@@ -170,3 +162,19 @@ const char *test__llvm_subtest_get_desc(int subtest)
return bpf_source_table[subtest].desc;
}
+#else //HAVE_LIBBPF_SUPPORT
+int test__llvm(struct test *test __maybe_unused, int subtest __maybe_unused)
+{
+ return TEST_SKIP;
+}
+
+int test__llvm_subtest_get_nr(void)
+{
+ return 0;
+}
+
+const char *test__llvm_subtest_get_desc(int subtest __maybe_unused)
+{
+ return NULL;
+}
+#endif // HAVE_LIBBPF_SUPPORT
diff --git a/tools/perf/tests/make b/tools/perf/tests/make
index 9b651dfe0a6b..a90fa043c066 100644
--- a/tools/perf/tests/make
+++ b/tools/perf/tests/make
@@ -91,6 +91,7 @@ make_no_sdt := NO_SDT=1
make_no_syscall_tbl := NO_SYSCALL_TABLE=1
make_with_clangllvm := LIBCLANGLLVM=1
make_with_libpfm4 := LIBPFM4=1
+make_with_gtk2 := GTK2=1
make_tags := tags
make_cscope := cscope
make_help := help
@@ -154,6 +155,7 @@ run += make_no_syscall_tbl
run += make_with_babeltrace
run += make_with_clangllvm
run += make_with_libpfm4
+run += make_with_gtk2
run += make_help
run += make_doc
run += make_perf_o
diff --git a/tools/perf/tests/mmap-basic.c b/tools/perf/tests/mmap-basic.c
index 7b0dbfc0e17d..57093aeacc6f 100644
--- a/tools/perf/tests/mmap-basic.c
+++ b/tools/perf/tests/mmap-basic.c
@@ -69,7 +69,7 @@ int test__basic_mmap(struct test *test __maybe_unused, int subtest __maybe_unuse
evlist = evlist__new();
if (evlist == NULL) {
- pr_debug("perf_evlist__new\n");
+ pr_debug("evlist__new\n");
goto out_free_cpus;
}
@@ -126,14 +126,14 @@ int test__basic_mmap(struct test *test __maybe_unused, int subtest __maybe_unuse
goto out_delete_evlist;
}
- err = perf_evlist__parse_sample(evlist, event, &sample);
+ err = evlist__parse_sample(evlist, event, &sample);
if (err) {
pr_err("Can't parse sample, err = %d\n", err);
goto out_delete_evlist;
}
err = -1;
- evsel = perf_evlist__id2evsel(evlist, sample.id);
+ evsel = evlist__id2evsel(evlist, sample.id);
if (evsel == NULL) {
pr_debug("event with id %" PRIu64
" doesn't map to an evsel\n", sample.id);
diff --git a/tools/perf/tests/openat-syscall-tp-fields.c b/tools/perf/tests/openat-syscall-tp-fields.c
index 1f5f5e79ae25..5e4af2f0f14a 100644
--- a/tools/perf/tests/openat-syscall-tp-fields.c
+++ b/tools/perf/tests/openat-syscall-tp-fields.c
@@ -42,7 +42,7 @@ int test__syscall_openat_tp_fields(struct test *test __maybe_unused, int subtest
char sbuf[STRERR_BUFSIZE];
if (evlist == NULL) {
- pr_debug("%s: perf_evlist__new\n", __func__);
+ pr_debug("%s: evlist__new\n", __func__);
goto out;
}
@@ -54,9 +54,9 @@ int test__syscall_openat_tp_fields(struct test *test __maybe_unused, int subtest
evlist__add(evlist, evsel);
- err = perf_evlist__create_maps(evlist, &opts.target);
+ err = evlist__create_maps(evlist, &opts.target);
if (err < 0) {
- pr_debug("%s: perf_evlist__create_maps\n", __func__);
+ pr_debug("%s: evlist__create_maps\n", __func__);
goto out_delete_evlist;
}
diff --git a/tools/perf/tests/parse-events.c b/tools/perf/tests/parse-events.c
index aae0fd9045c1..a7f6661e6112 100644
--- a/tools/perf/tests/parse-events.c
+++ b/tools/perf/tests/parse-events.c
@@ -115,7 +115,7 @@ static int test__checkevent_symbolic_name_config(struct evlist *evlist)
TEST_ASSERT_VAL("wrong config",
PERF_COUNT_HW_CPU_CYCLES == evsel->core.attr.config);
/*
- * The period value gets configured within perf_evlist__config,
+ * The period value gets configured within evlist__config,
* while this test executes only parse events method.
*/
TEST_ASSERT_VAL("wrong period",
@@ -443,7 +443,7 @@ static int test__checkevent_pmu(struct evlist *evlist)
TEST_ASSERT_VAL("wrong config1", 1 == evsel->core.attr.config1);
TEST_ASSERT_VAL("wrong config2", 3 == evsel->core.attr.config2);
/*
- * The period value gets configured within perf_evlist__config,
+ * The period value gets configured within evlist__config,
* while this test executes only parse events method.
*/
TEST_ASSERT_VAL("wrong period", 0 == evsel->core.attr.sample_period);
@@ -520,8 +520,7 @@ static int test__checkevent_pmu_partial_time_callgraph(struct evlist *evlist)
TEST_ASSERT_VAL("wrong type", PERF_TYPE_RAW == evsel->core.attr.type);
TEST_ASSERT_VAL("wrong config", 1 == evsel->core.attr.config);
/*
- * The period, time and callgraph value gets configured
- * within perf_evlist__config,
+ * The period, time and callgraph value gets configured within evlist__config,
* while this test executes only parse events method.
*/
TEST_ASSERT_VAL("wrong period", 0 == evsel->core.attr.sample_period);
@@ -533,8 +532,7 @@ static int test__checkevent_pmu_partial_time_callgraph(struct evlist *evlist)
TEST_ASSERT_VAL("wrong type", PERF_TYPE_RAW == evsel->core.attr.type);
TEST_ASSERT_VAL("wrong config", 2 == evsel->core.attr.config);
/*
- * The period, time and callgraph value gets configured
- * within perf_evlist__config,
+ * The period, time and callgraph value gets configured within evlist__config,
* while this test executes only parse events method.
*/
TEST_ASSERT_VAL("wrong period", 0 == evsel->core.attr.sample_period);
@@ -557,6 +555,7 @@ static int test__checkevent_pmu_events(struct evlist *evlist)
TEST_ASSERT_VAL("wrong exclude_hv", evsel->core.attr.exclude_hv);
TEST_ASSERT_VAL("wrong precise_ip", !evsel->core.attr.precise_ip);
TEST_ASSERT_VAL("wrong pinned", !evsel->core.attr.pinned);
+ TEST_ASSERT_VAL("wrong exclusive", !evsel->core.attr.exclusive);
return 0;
}
@@ -575,6 +574,7 @@ static int test__checkevent_pmu_events_mix(struct evlist *evlist)
TEST_ASSERT_VAL("wrong exclude_hv", evsel->core.attr.exclude_hv);
TEST_ASSERT_VAL("wrong precise_ip", !evsel->core.attr.precise_ip);
TEST_ASSERT_VAL("wrong pinned", !evsel->core.attr.pinned);
+ TEST_ASSERT_VAL("wrong exclusive", !evsel->core.attr.exclusive);
/* cpu/pmu-event/u*/
evsel = evsel__next(evsel);
@@ -587,6 +587,7 @@ static int test__checkevent_pmu_events_mix(struct evlist *evlist)
TEST_ASSERT_VAL("wrong exclude_hv", evsel->core.attr.exclude_hv);
TEST_ASSERT_VAL("wrong precise_ip", !evsel->core.attr.precise_ip);
TEST_ASSERT_VAL("wrong pinned", !evsel->core.attr.pinned);
+ TEST_ASSERT_VAL("wrong exclusive", !evsel->core.attr.pinned);
return 0;
}
@@ -1277,6 +1278,49 @@ static int test__pinned_group(struct evlist *evlist)
return 0;
}
+static int test__checkevent_exclusive_modifier(struct evlist *evlist)
+{
+ struct evsel *evsel = evlist__first(evlist);
+
+ TEST_ASSERT_VAL("wrong exclude_user", !evsel->core.attr.exclude_user);
+ TEST_ASSERT_VAL("wrong exclude_kernel", evsel->core.attr.exclude_kernel);
+ TEST_ASSERT_VAL("wrong exclude_hv", evsel->core.attr.exclude_hv);
+ TEST_ASSERT_VAL("wrong precise_ip", evsel->core.attr.precise_ip);
+ TEST_ASSERT_VAL("wrong exclusive", evsel->core.attr.exclusive);
+
+ return test__checkevent_symbolic_name(evlist);
+}
+
+static int test__exclusive_group(struct evlist *evlist)
+{
+ struct evsel *evsel, *leader;
+
+ TEST_ASSERT_VAL("wrong number of entries", 3 == evlist->core.nr_entries);
+
+ /* cycles - group leader */
+ evsel = leader = evlist__first(evlist);
+ TEST_ASSERT_VAL("wrong type", PERF_TYPE_HARDWARE == evsel->core.attr.type);
+ TEST_ASSERT_VAL("wrong config",
+ PERF_COUNT_HW_CPU_CYCLES == evsel->core.attr.config);
+ TEST_ASSERT_VAL("wrong group name", !evsel->group_name);
+ TEST_ASSERT_VAL("wrong leader", evsel->leader == leader);
+ TEST_ASSERT_VAL("wrong exclusive", evsel->core.attr.exclusive);
+
+ /* cache-misses - can not be pinned, but will go on with the leader */
+ evsel = evsel__next(evsel);
+ TEST_ASSERT_VAL("wrong type", PERF_TYPE_HARDWARE == evsel->core.attr.type);
+ TEST_ASSERT_VAL("wrong config",
+ PERF_COUNT_HW_CACHE_MISSES == evsel->core.attr.config);
+ TEST_ASSERT_VAL("wrong exclusive", !evsel->core.attr.exclusive);
+
+ /* branch-misses - ditto */
+ evsel = evsel__next(evsel);
+ TEST_ASSERT_VAL("wrong config",
+ PERF_COUNT_HW_BRANCH_MISSES == evsel->core.attr.config);
+ TEST_ASSERT_VAL("wrong exclusive", !evsel->core.attr.exclusive);
+
+ return 0;
+}
static int test__checkevent_breakpoint_len(struct evlist *evlist)
{
struct evsel *evsel = evlist__first(evlist);
@@ -1765,7 +1809,17 @@ static struct evlist_test test__events[] = {
.name = "cycles:k",
.check = test__sym_event_dc,
.id = 55,
- }
+ },
+ {
+ .name = "instructions:uep",
+ .check = test__checkevent_exclusive_modifier,
+ .id = 56,
+ },
+ {
+ .name = "{cycles,cache-misses,branch-misses}:e",
+ .check = test__exclusive_group,
+ .id = 57,
+ },
};
static struct evlist_test test__events_pmu[] = {
diff --git a/tools/perf/tests/parse-metric.c b/tools/perf/tests/parse-metric.c
index cd7331aac3bd..ce7be37f0d88 100644
--- a/tools/perf/tests/parse-metric.c
+++ b/tools/perf/tests/parse-metric.c
@@ -11,8 +11,6 @@
#include "debug.h"
#include "expr.h"
#include "stat.h"
-#include <perf/cpumap.h>
-#include <perf/evlist.h>
static struct pmu_event pme_test[] = {
{
@@ -159,6 +157,7 @@ static int __compute_metric(const char *name, struct value *vals,
}
perf_evlist__set_maps(&evlist->core, cpus, NULL);
+ runtime_stat__init(&st);
/* Parse the metric into metric_events list. */
err = metricgroup__parse_groups_test(evlist, &map, name,
@@ -167,12 +166,11 @@ static int __compute_metric(const char *name, struct value *vals,
if (err)
goto out;
- err = perf_evlist__alloc_stats(evlist, false);
+ err = evlist__alloc_stats(evlist, false);
if (err)
goto out;
/* Load the runtime stats with given numbers for events. */
- runtime_stat__init(&st);
load_runtime_stat(&st, evlist, vals);
/* And execute the metric */
@@ -185,7 +183,7 @@ out:
/* ... clenup. */
metricgroup__rblist_exit(&metric_events);
runtime_stat__exit(&st);
- perf_evlist__free_stats(evlist);
+ evlist__free_stats(evlist);
perf_cpu_map__put(cpus);
evlist__delete(evlist);
return err;
diff --git a/tools/perf/tests/parse-no-sample-id-all.c b/tools/perf/tests/parse-no-sample-id-all.c
index adf3c9c4a416..471273676701 100644
--- a/tools/perf/tests/parse-no-sample-id-all.c
+++ b/tools/perf/tests/parse-no-sample-id-all.c
@@ -27,8 +27,8 @@ static int process_event(struct evlist **pevlist, union perf_event *event)
if (!*pevlist)
return -1;
- if (perf_evlist__parse_sample(*pevlist, event, &sample)) {
- pr_debug("perf_evlist__parse_sample failed\n");
+ if (evlist__parse_sample(*pevlist, event, &sample)) {
+ pr_debug("evlist__parse_sample failed\n");
return -1;
}
diff --git a/tools/perf/tests/pe-file-parsing.c b/tools/perf/tests/pe-file-parsing.c
new file mode 100644
index 000000000000..58b90c42eb38
--- /dev/null
+++ b/tools/perf/tests/pe-file-parsing.c
@@ -0,0 +1,98 @@
+// SPDX-License-Identifier: GPL-2.0
+#include <stdbool.h>
+#include <inttypes.h>
+#include <stdlib.h>
+#include <string.h>
+#include <linux/bitops.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <subcmd/exec-cmd.h>
+
+#include "debug.h"
+#include "util/build-id.h"
+#include "util/symbol.h"
+#include "util/dso.h"
+
+#include "tests.h"
+
+#ifdef HAVE_LIBBFD_SUPPORT
+
+static int run_dir(const char *d)
+{
+ char filename[PATH_MAX];
+ char debugfile[PATH_MAX];
+ struct build_id bid;
+ char debuglink[PATH_MAX];
+ char expect_build_id[] = {
+ 0x5a, 0x0f, 0xd8, 0x82, 0xb5, 0x30, 0x84, 0x22,
+ 0x4b, 0xa4, 0x7b, 0x62, 0x4c, 0x55, 0xa4, 0x69,
+ };
+ char expect_debuglink[PATH_MAX] = "pe-file.exe.debug";
+ struct dso *dso;
+ struct symbol *sym;
+ int ret;
+
+ scnprintf(filename, PATH_MAX, "%s/pe-file.exe", d);
+ ret = filename__read_build_id(filename, &bid);
+ TEST_ASSERT_VAL("Failed to read build_id",
+ ret == sizeof(expect_build_id));
+ TEST_ASSERT_VAL("Wrong build_id", !memcmp(bid.data, expect_build_id,
+ sizeof(expect_build_id)));
+
+ ret = filename__read_debuglink(filename, debuglink, PATH_MAX);
+ TEST_ASSERT_VAL("Failed to read debuglink", ret == 0);
+ TEST_ASSERT_VAL("Wrong debuglink",
+ !strcmp(debuglink, expect_debuglink));
+
+ scnprintf(debugfile, PATH_MAX, "%s/%s", d, debuglink);
+ ret = filename__read_build_id(debugfile, &bid);
+ TEST_ASSERT_VAL("Failed to read debug file build_id",
+ ret == sizeof(expect_build_id));
+ TEST_ASSERT_VAL("Wrong build_id", !memcmp(bid.data, expect_build_id,
+ sizeof(expect_build_id)));
+
+ dso = dso__new(filename);
+ TEST_ASSERT_VAL("Failed to get dso", dso);
+
+ ret = dso__load_bfd_symbols(dso, debugfile);
+ TEST_ASSERT_VAL("Failed to load symbols", ret == 0);
+
+ dso__sort_by_name(dso);
+ sym = dso__find_symbol_by_name(dso, "main");
+ TEST_ASSERT_VAL("Failed to find main", sym);
+ dso__delete(dso);
+
+ return TEST_OK;
+}
+
+int test__pe_file_parsing(struct test *test __maybe_unused,
+ int subtest __maybe_unused)
+{
+ struct stat st;
+ char path_dir[PATH_MAX];
+
+ /* First try development tree tests. */
+ if (!lstat("./tests", &st))
+ return run_dir("./tests");
+
+ /* Then installed path. */
+ snprintf(path_dir, PATH_MAX, "%s/tests", get_argv_exec_path());
+
+ if (!lstat(path_dir, &st))
+ return run_dir(path_dir);
+
+ return TEST_SKIP;
+}
+
+#else
+
+int test__pe_file_parsing(struct test *test __maybe_unused,
+ int subtest __maybe_unused)
+{
+ return TEST_SKIP;
+}
+
+#endif
diff --git a/tools/perf/tests/pe-file.c b/tools/perf/tests/pe-file.c
new file mode 100644
index 000000000000..eb3df5e9886f
--- /dev/null
+++ b/tools/perf/tests/pe-file.c
@@ -0,0 +1,14 @@
+// SPDX-License-Identifier: GPL-2.0
+
+// pe-file.exe and pe-file.exe.debug built with;
+// x86_64-w64-mingw32-gcc -o pe-file.exe pe-file.c
+// -Wl,--file-alignment,4096 -Wl,--build-id
+// x86_64-w64-mingw32-objcopy --only-keep-debug
+// --compress-debug-sections pe-file.exe pe-file.exe.debug
+// x86_64-w64-mingw32-objcopy --strip-debug
+// --add-gnu-debuglink=pe-file.exe.debug pe-file.exe
+
+int main(int argc, char const *argv[])
+{
+ return 0;
+}
diff --git a/tools/perf/tests/pe-file.exe b/tools/perf/tests/pe-file.exe
new file mode 100644
index 000000000000..838a46dae724
--- /dev/null
+++ b/tools/perf/tests/pe-file.exe
Binary files differ
diff --git a/tools/perf/tests/pe-file.exe.debug b/tools/perf/tests/pe-file.exe.debug
new file mode 100644
index 000000000000..287d6718d6c9
--- /dev/null
+++ b/tools/perf/tests/pe-file.exe.debug
Binary files differ
diff --git a/tools/perf/tests/perf-record.c b/tools/perf/tests/perf-record.c
index 67d3f5aad016..0df471bf1590 100644
--- a/tools/perf/tests/perf-record.c
+++ b/tools/perf/tests/perf-record.c
@@ -53,7 +53,7 @@ int test__PERF_RECORD(struct test *test __maybe_unused, int subtest __maybe_unus
};
cpu_set_t cpu_mask;
size_t cpu_mask_size = sizeof(cpu_mask);
- struct evlist *evlist = perf_evlist__new_dummy();
+ struct evlist *evlist = evlist__new_dummy();
struct evsel *evsel;
struct perf_sample sample;
const char *cmd = "sleep";
@@ -71,7 +71,7 @@ int test__PERF_RECORD(struct test *test __maybe_unused, int subtest __maybe_unus
char sbuf[STRERR_BUFSIZE];
if (evlist == NULL) /* Fallback for kernels lacking PERF_COUNT_SW_DUMMY */
- evlist = perf_evlist__new_default();
+ evlist = evlist__new_default();
if (evlist == NULL) {
pr_debug("Not enough memory to create evlist\n");
@@ -81,10 +81,10 @@ int test__PERF_RECORD(struct test *test __maybe_unused, int subtest __maybe_unus
/*
* Create maps of threads and cpus to monitor. In this case
* we start with all threads and cpus (-1, -1) but then in
- * perf_evlist__prepare_workload we'll fill in the only thread
+ * evlist__prepare_workload we'll fill in the only thread
* we're monitoring, the one forked there.
*/
- err = perf_evlist__create_maps(evlist, &opts.target);
+ err = evlist__create_maps(evlist, &opts.target);
if (err < 0) {
pr_debug("Not enough memory to create thread/cpu maps\n");
goto out_delete_evlist;
@@ -92,11 +92,11 @@ int test__PERF_RECORD(struct test *test __maybe_unused, int subtest __maybe_unus
/*
* Prepare the workload in argv[] to run, it'll fork it, and then wait
- * for perf_evlist__start_workload() to exec it. This is done this way
+ * for evlist__start_workload() to exec it. This is done this way
* so that we have time to open the evlist (calling sys_perf_event_open
* on all the fds) and then mmap them.
*/
- err = perf_evlist__prepare_workload(evlist, &opts.target, argv, false, NULL);
+ err = evlist__prepare_workload(evlist, &opts.target, argv, false, NULL);
if (err < 0) {
pr_debug("Couldn't run the workload!\n");
goto out_delete_evlist;
@@ -109,7 +109,7 @@ int test__PERF_RECORD(struct test *test __maybe_unused, int subtest __maybe_unus
evsel__set_sample_bit(evsel, CPU);
evsel__set_sample_bit(evsel, TID);
evsel__set_sample_bit(evsel, TIME);
- perf_evlist__config(evlist, &opts, NULL);
+ evlist__config(evlist, &opts, NULL);
err = sched__get_first_possible_cpu(evlist->workload.pid, &cpu_mask);
if (err < 0) {
@@ -161,7 +161,7 @@ int test__PERF_RECORD(struct test *test __maybe_unused, int subtest __maybe_unus
/*
* Now!
*/
- perf_evlist__start_workload(evlist);
+ evlist__start_workload(evlist);
while (1) {
int before = total_events;
@@ -182,7 +182,7 @@ int test__PERF_RECORD(struct test *test __maybe_unused, int subtest __maybe_unus
if (type < PERF_RECORD_MAX)
nr_events[type]++;
- err = perf_evlist__parse_sample(evlist, event, &sample);
+ err = evlist__parse_sample(evlist, event, &sample);
if (err < 0) {
if (verbose > 0)
perf_event__fprintf(event, NULL, stderr);
diff --git a/tools/perf/tests/perf-time-to-tsc.c b/tools/perf/tests/perf-time-to-tsc.c
new file mode 100644
index 000000000000..7cff02664d0e
--- /dev/null
+++ b/tools/perf/tests/perf-time-to-tsc.c
@@ -0,0 +1,184 @@
+// SPDX-License-Identifier: GPL-2.0
+#include <errno.h>
+#include <inttypes.h>
+#include <limits.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <linux/types.h>
+#include <sys/prctl.h>
+#include <perf/cpumap.h>
+#include <perf/evlist.h>
+#include <perf/mmap.h>
+
+#include "debug.h"
+#include "parse-events.h"
+#include "evlist.h"
+#include "evsel.h"
+#include "thread_map.h"
+#include "record.h"
+#include "tsc.h"
+#include "mmap.h"
+#include "tests.h"
+
+#define CHECK__(x) { \
+ while ((x) < 0) { \
+ pr_debug(#x " failed!\n"); \
+ goto out_err; \
+ } \
+}
+
+#define CHECK_NOT_NULL__(x) { \
+ while ((x) == NULL) { \
+ pr_debug(#x " failed!\n"); \
+ goto out_err; \
+ } \
+}
+
+/**
+ * test__perf_time_to_tsc - test converting perf time to TSC.
+ *
+ * This function implements a test that checks that the conversion of perf time
+ * to and from TSC is consistent with the order of events. If the test passes
+ * %0 is returned, otherwise %-1 is returned. If TSC conversion is not
+ * supported then then the test passes but " (not supported)" is printed.
+ */
+int test__perf_time_to_tsc(struct test *test __maybe_unused, int subtest __maybe_unused)
+{
+ struct record_opts opts = {
+ .mmap_pages = UINT_MAX,
+ .user_freq = UINT_MAX,
+ .user_interval = ULLONG_MAX,
+ .target = {
+ .uses_mmap = true,
+ },
+ .sample_time = true,
+ };
+ struct perf_thread_map *threads = NULL;
+ struct perf_cpu_map *cpus = NULL;
+ struct evlist *evlist = NULL;
+ struct evsel *evsel = NULL;
+ int err = -1, ret, i;
+ const char *comm1, *comm2;
+ struct perf_tsc_conversion tc;
+ struct perf_event_mmap_page *pc;
+ union perf_event *event;
+ u64 test_tsc, comm1_tsc, comm2_tsc;
+ u64 test_time, comm1_time = 0, comm2_time = 0;
+ struct mmap *md;
+
+ threads = thread_map__new(-1, getpid(), UINT_MAX);
+ CHECK_NOT_NULL__(threads);
+
+ cpus = perf_cpu_map__new(NULL);
+ CHECK_NOT_NULL__(cpus);
+
+ evlist = evlist__new();
+ CHECK_NOT_NULL__(evlist);
+
+ perf_evlist__set_maps(&evlist->core, cpus, threads);
+
+ CHECK__(parse_events(evlist, "cycles:u", NULL));
+
+ evlist__config(evlist, &opts, NULL);
+
+ evsel = evlist__first(evlist);
+
+ evsel->core.attr.comm = 1;
+ evsel->core.attr.disabled = 1;
+ evsel->core.attr.enable_on_exec = 0;
+
+ CHECK__(evlist__open(evlist));
+
+ CHECK__(evlist__mmap(evlist, UINT_MAX));
+
+ pc = evlist->mmap[0].core.base;
+ ret = perf_read_tsc_conversion(pc, &tc);
+ if (ret) {
+ if (ret == -EOPNOTSUPP) {
+ fprintf(stderr, " (not supported)");
+ return 0;
+ }
+ goto out_err;
+ }
+
+ evlist__enable(evlist);
+
+ comm1 = "Test COMM 1";
+ CHECK__(prctl(PR_SET_NAME, (unsigned long)comm1, 0, 0, 0));
+
+ test_tsc = rdtsc();
+
+ comm2 = "Test COMM 2";
+ CHECK__(prctl(PR_SET_NAME, (unsigned long)comm2, 0, 0, 0));
+
+ evlist__disable(evlist);
+
+ for (i = 0; i < evlist->core.nr_mmaps; i++) {
+ md = &evlist->mmap[i];
+ if (perf_mmap__read_init(&md->core) < 0)
+ continue;
+
+ while ((event = perf_mmap__read_event(&md->core)) != NULL) {
+ struct perf_sample sample;
+
+ if (event->header.type != PERF_RECORD_COMM ||
+ (pid_t)event->comm.pid != getpid() ||
+ (pid_t)event->comm.tid != getpid())
+ goto next_event;
+
+ if (strcmp(event->comm.comm, comm1) == 0) {
+ CHECK__(evsel__parse_sample(evsel, event, &sample));
+ comm1_time = sample.time;
+ }
+ if (strcmp(event->comm.comm, comm2) == 0) {
+ CHECK__(evsel__parse_sample(evsel, event, &sample));
+ comm2_time = sample.time;
+ }
+next_event:
+ perf_mmap__consume(&md->core);
+ }
+ perf_mmap__read_done(&md->core);
+ }
+
+ if (!comm1_time || !comm2_time)
+ goto out_err;
+
+ test_time = tsc_to_perf_time(test_tsc, &tc);
+ comm1_tsc = perf_time_to_tsc(comm1_time, &tc);
+ comm2_tsc = perf_time_to_tsc(comm2_time, &tc);
+
+ pr_debug("1st event perf time %"PRIu64" tsc %"PRIu64"\n",
+ comm1_time, comm1_tsc);
+ pr_debug("rdtsc time %"PRIu64" tsc %"PRIu64"\n",
+ test_time, test_tsc);
+ pr_debug("2nd event perf time %"PRIu64" tsc %"PRIu64"\n",
+ comm2_time, comm2_tsc);
+
+ if (test_time <= comm1_time ||
+ test_time >= comm2_time)
+ goto out_err;
+
+ if (test_tsc <= comm1_tsc ||
+ test_tsc >= comm2_tsc)
+ goto out_err;
+
+ err = 0;
+
+out_err:
+ evlist__delete(evlist);
+ return err;
+}
+
+bool test__tsc_is_supported(void)
+{
+ /*
+ * Except x86_64/i386 and Arm64, other archs don't support TSC in perf.
+ * Just enable the test for x86_64/i386 and Arm64 archs.
+ */
+#if defined(__x86_64__) || defined(__i386__) || defined(__aarch64__)
+ return true;
+#else
+ return false;
+#endif
+}
diff --git a/tools/perf/tests/pmu-events.c b/tools/perf/tests/pmu-events.c
index d3517a74d95e..0ca6a5a53523 100644
--- a/tools/perf/tests/pmu-events.c
+++ b/tools/perf/tests/pmu-events.c
@@ -14,8 +14,10 @@
#include "util/parse-events.h"
struct perf_pmu_test_event {
+ /* used for matching against events from generated pmu-events.c */
struct pmu_event event;
+ /* used for matching against event aliases */
/* extra events for aliases */
const char *alias_str;
@@ -78,6 +80,17 @@ static struct perf_pmu_test_event test_cpu_events[] = {
.alias_str = "umask=0,(null)=0x30d40,event=0x3a",
.alias_long_desc = "Number of Enhanced Intel SpeedStep(R) Technology (EIST) transitions",
},
+ {
+ .event = {
+ .name = "l3_cache_rd",
+ .event = "event=0x40",
+ .desc = "L3 cache access, read",
+ .long_desc = "Attributable Level 3 cache access, read",
+ .topic = "cache",
+ },
+ .alias_str = "event=0x40",
+ .alias_long_desc = "Attributable Level 3 cache access, read",
+ },
{ /* sentinel */
.event = {
.name = NULL,
@@ -357,6 +370,7 @@ static int __test__pmu_event_aliases(char *pmu_name, int *count)
}
+/* Test that aliases generated are as expected */
static int test_aliases(void)
{
struct perf_pmu *pmu = NULL;
@@ -561,7 +575,7 @@ static int metric_parse_fake(const char *str)
}
}
- if (expr__parse(&result, &ctx, str, 1))
+ if (expr__parse(&result, &ctx, str, 0))
pr_err("expr__parse failed\n");
else
ret = 0;
diff --git a/tools/perf/tests/python-use.c b/tools/perf/tests/python-use.c
index 40ab72149ce1..98c6d474aa6f 100644
--- a/tools/perf/tests/python-use.c
+++ b/tools/perf/tests/python-use.c
@@ -18,6 +18,7 @@ int test__python_use(struct test *test __maybe_unused, int subtest __maybe_unuse
PYTHONPATH, PYTHON, verbose > 0 ? "" : "2> /dev/null") < 0)
return -1;
+ pr_debug("python usage test: \"%s\"\n", cmd);
ret = system(cmd) ? -1 : 0;
free(cmd);
return ret;
diff --git a/tools/perf/tests/sample-parsing.c b/tools/perf/tests/sample-parsing.c
index a0bdaf390ac8..2393916f6128 100644
--- a/tools/perf/tests/sample-parsing.c
+++ b/tools/perf/tests/sample-parsing.c
@@ -154,6 +154,9 @@ static bool samples_same(const struct perf_sample *s1,
if (type & PERF_SAMPLE_CGROUP)
COMP(cgroup);
+ if (type & PERF_SAMPLE_DATA_PAGE_SIZE)
+ COMP(data_page_size);
+
if (type & PERF_SAMPLE_AUX) {
COMP(aux_sample.size);
if (memcmp(s1->aux_sample.data, s2->aux_sample.data,
@@ -234,6 +237,7 @@ static int do_test(u64 sample_type, u64 sample_regs, u64 read_format)
},
.phys_addr = 113,
.cgroup = 114,
+ .data_page_size = 115,
.aux_sample = {
.size = sizeof(aux_data),
.data = (void *)aux_data,
@@ -340,7 +344,7 @@ int test__sample_parsing(struct test *test __maybe_unused, int subtest __maybe_u
* were added. Please actually update the test rather than just change
* the condition below.
*/
- if (PERF_SAMPLE_MAX > PERF_SAMPLE_CGROUP << 1) {
+ if (PERF_SAMPLE_MAX > PERF_SAMPLE_CODE_PAGE_SIZE << 1) {
pr_debug("sample format has changed, some new PERF_SAMPLE_ bit was introduced - test needs updating\n");
return -1;
}
diff --git a/tools/perf/tests/sdt.c b/tools/perf/tests/sdt.c
index 60f0e9ee04fb..ed76c693f65e 100644
--- a/tools/perf/tests/sdt.c
+++ b/tools/perf/tests/sdt.c
@@ -28,16 +28,16 @@ static int target_function(void)
static int build_id_cache__add_file(const char *filename)
{
char sbuild_id[SBUILD_ID_SIZE];
- u8 build_id[BUILD_ID_SIZE];
+ struct build_id bid;
int err;
- err = filename__read_build_id(filename, &build_id, sizeof(build_id));
+ err = filename__read_build_id(filename, &bid);
if (err < 0) {
pr_debug("Failed to read build id of %s\n", filename);
return err;
}
- build_id__sprintf(build_id, sizeof(build_id), sbuild_id);
+ build_id__sprintf(&bid, sbuild_id);
err = build_id_cache__add_s(sbuild_id, filename, NULL, false, false);
if (err < 0)
pr_debug("Failed to add build id cache of %s\n", filename);
diff --git a/tools/perf/tests/shell/buildid.sh b/tools/perf/tests/shell/buildid.sh
new file mode 100755
index 000000000000..4861a20edee2
--- /dev/null
+++ b/tools/perf/tests/shell/buildid.sh
@@ -0,0 +1,101 @@
+#!/bin/sh
+# build id cache operations
+# SPDX-License-Identifier: GPL-2.0
+
+# skip if there's no readelf
+if ! [ -x "$(command -v readelf)" ]; then
+ echo "failed: no readelf, install binutils"
+ exit 2
+fi
+
+# skip if there's no compiler
+if ! [ -x "$(command -v cc)" ]; then
+ echo "failed: no compiler, install gcc"
+ exit 2
+fi
+
+ex_md5=$(mktemp /tmp/perf.ex.MD5.XXX)
+ex_sha1=$(mktemp /tmp/perf.ex.SHA1.XXX)
+
+echo 'int main(void) { return 0; }' | cc -Wl,--build-id=sha1 -o ${ex_sha1} -x c -
+echo 'int main(void) { return 0; }' | cc -Wl,--build-id=md5 -o ${ex_md5} -x c -
+
+echo "test binaries: ${ex_sha1} ${ex_md5}"
+
+check()
+{
+ id=`readelf -n ${1} 2>/dev/null | grep 'Build ID' | awk '{print $3}'`
+
+ echo "build id: ${id}"
+
+ link=${build_id_dir}/.build-id/${id:0:2}/${id:2}
+ echo "link: ${link}"
+
+ if [ ! -h $link ]; then
+ echo "failed: link ${link} does not exist"
+ exit 1
+ fi
+
+ file=${build_id_dir}/.build-id/${id:0:2}/`readlink ${link}`/elf
+ echo "file: ${file}"
+
+ if [ ! -x $file ]; then
+ echo "failed: file ${file} does not exist"
+ exit 1
+ fi
+
+ diff ${file} ${1}
+ if [ $? -ne 0 ]; then
+ echo "failed: ${file} do not match"
+ exit 1
+ fi
+
+ echo "OK for ${1}"
+}
+
+test_add()
+{
+ build_id_dir=$(mktemp -d /tmp/perf.debug.XXX)
+ perf="perf --buildid-dir ${build_id_dir}"
+
+ ${perf} buildid-cache -v -a ${1}
+ if [ $? -ne 0 ]; then
+ echo "failed: add ${1} to build id cache"
+ exit 1
+ fi
+
+ check ${1}
+
+ rm -rf ${build_id_dir}
+}
+
+test_record()
+{
+ data=$(mktemp /tmp/perf.data.XXX)
+ build_id_dir=$(mktemp -d /tmp/perf.debug.XXX)
+ perf="perf --buildid-dir ${build_id_dir}"
+
+ ${perf} record --buildid-all -o ${data} ${1}
+ if [ $? -ne 0 ]; then
+ echo "failed: record ${1}"
+ exit 1
+ fi
+
+ check ${1}
+
+ rm -rf ${build_id_dir}
+ rm -rf ${data}
+}
+
+# add binaries manual via perf buildid-cache -a
+test_add ${ex_sha1}
+test_add ${ex_md5}
+
+# add binaries via perf record post processing
+test_record ${ex_sha1}
+test_record ${ex_md5}
+
+# cleanup
+rm ${ex_sha1} ${ex_md5}
+
+exit ${err}
diff --git a/tools/perf/tests/shell/stat+shadow_stat.sh b/tools/perf/tests/shell/stat+shadow_stat.sh
new file mode 100755
index 000000000000..ebebd3596cf9
--- /dev/null
+++ b/tools/perf/tests/shell/stat+shadow_stat.sh
@@ -0,0 +1,78 @@
+#!/bin/sh
+# perf stat metrics (shadow stat) test
+# SPDX-License-Identifier: GPL-2.0
+
+set -e
+
+# skip if system-wide mode is forbidden
+perf stat -a true > /dev/null 2>&1 || exit 2
+
+test_global_aggr()
+{
+ perf stat -a --no-big-num -e cycles,instructions sleep 1 2>&1 | \
+ grep -e cycles -e instructions | \
+ while read num evt hash ipc rest
+ do
+ # skip not counted events
+ if [ "$num" = "<not" ]; then
+ continue
+ fi
+
+ # save cycles count
+ if [ "$evt" = "cycles" ]; then
+ cyc=$num
+ continue
+ fi
+
+ # skip if no cycles
+ if [ -z "$cyc" ]; then
+ continue
+ fi
+
+ # use printf for rounding and a leading zero
+ res=`printf "%.2f" $(echo "scale=6; $num / $cyc" | bc -q)`
+ if [ "$ipc" != "$res" ]; then
+ echo "IPC is different: $res != $ipc ($num / $cyc)"
+ exit 1
+ fi
+ done
+}
+
+test_no_aggr()
+{
+ perf stat -a -A --no-big-num -e cycles,instructions sleep 1 2>&1 | \
+ grep ^CPU | \
+ while read cpu num evt hash ipc rest
+ do
+ # skip not counted events
+ if [ "$num" = "<not" ]; then
+ continue
+ fi
+
+ # save cycles count
+ if [ "$evt" = "cycles" ]; then
+ results="$results $cpu:$num"
+ continue
+ fi
+
+ cyc=${results##* $cpu:}
+ cyc=${cyc%% *}
+
+ # skip if no cycles
+ if [ -z "$cyc" ]; then
+ continue
+ fi
+
+ # use printf for rounding and a leading zero
+ res=`printf "%.2f" $(echo "scale=6; $num / $cyc" | bc -q)`
+ if [ "$ipc" != "$res" ]; then
+ echo "IPC is different for $cpu: $res != $ipc ($num / $cyc)"
+ exit 1
+ fi
+ done
+}
+
+test_global_aggr
+test_no_aggr
+
+exit 0
diff --git a/tools/perf/tests/shell/test_arm_coresight.sh b/tools/perf/tests/shell/test_arm_coresight.sh
new file mode 100755
index 000000000000..18fde2f179cd
--- /dev/null
+++ b/tools/perf/tests/shell/test_arm_coresight.sh
@@ -0,0 +1,183 @@
+#!/bin/sh
+# Check Arm CoreSight trace data recording and synthesized samples
+
+# Uses the 'perf record' to record trace data with Arm CoreSight sinks;
+# then verify if there have any branch samples and instruction samples
+# are generated by CoreSight with 'perf script' and 'perf report'
+# commands.
+
+# SPDX-License-Identifier: GPL-2.0
+# Leo Yan <[email protected]>, 2020
+
+perfdata=$(mktemp /tmp/__perf_test.perf.data.XXXXX)
+file=$(mktemp /tmp/temporary_file.XXXXX)
+
+skip_if_no_cs_etm_event() {
+ perf list | grep -q 'cs_etm//' && return 0
+
+ # cs_etm event doesn't exist
+ return 2
+}
+
+skip_if_no_cs_etm_event || exit 2
+
+cleanup_files()
+{
+ rm -f ${perfdata}
+ rm -f ${file}
+}
+
+trap cleanup_files exit
+
+record_touch_file() {
+ echo "Recording trace (only user mode) with path: CPU$2 => $1"
+ rm -f $file
+ perf record -o ${perfdata} -e cs_etm/@$1/u --per-thread \
+ -- taskset -c $2 touch $file
+}
+
+perf_script_branch_samples() {
+ echo "Looking at perf.data file for dumping branch samples:"
+
+ # Below is an example of the branch samples dumping:
+ # touch 6512 1 branches:u: ffffb220824c strcmp+0xc (/lib/aarch64-linux-gnu/ld-2.27.so)
+ # touch 6512 1 branches:u: ffffb22082e0 strcmp+0xa0 (/lib/aarch64-linux-gnu/ld-2.27.so)
+ # touch 6512 1 branches:u: ffffb2208320 strcmp+0xe0 (/lib/aarch64-linux-gnu/ld-2.27.so)
+ perf script -F,-time -i ${perfdata} | \
+ egrep " +$1 +[0-9]+ .* +branches:(.*:)? +"
+}
+
+perf_report_branch_samples() {
+ echo "Looking at perf.data file for reporting branch samples:"
+
+ # Below is an example of the branch samples reporting:
+ # 73.04% 73.04% touch libc-2.27.so [.] _dl_addr
+ # 7.71% 7.71% touch libc-2.27.so [.] getenv
+ # 2.59% 2.59% touch ld-2.27.so [.] strcmp
+ perf report --stdio -i ${perfdata} | \
+ egrep " +[0-9]+\.[0-9]+% +[0-9]+\.[0-9]+% +$1 "
+}
+
+perf_report_instruction_samples() {
+ echo "Looking at perf.data file for instruction samples:"
+
+ # Below is an example of the instruction samples reporting:
+ # 68.12% touch libc-2.27.so [.] _dl_addr
+ # 5.80% touch libc-2.27.so [.] getenv
+ # 4.35% touch ld-2.27.so [.] _dl_fixup
+ perf report --itrace=i1000i --stdio -i ${perfdata} | \
+ egrep " +[0-9]+\.[0-9]+% +$1"
+}
+
+is_device_sink() {
+ # If the node of "enable_sink" is existed under the device path, this
+ # means the device is a sink device. Need to exclude 'tpiu' since it
+ # cannot support perf PMU.
+ echo "$1" | egrep -q -v "tpiu"
+
+ if [ $? -eq 0 -a -e "$1/enable_sink" ]; then
+
+ pmu_dev="/sys/bus/event_source/devices/cs_etm/sinks/$2"
+
+ # Warn if the device is not supported by PMU
+ if ! [ -f $pmu_dev ]; then
+ echo "PMU doesn't support $pmu_dev"
+ fi
+
+ return 0
+ fi
+
+ # Otherwise, it's not a sink device
+ return 1
+}
+
+arm_cs_iterate_devices() {
+ for dev in $1/connections/out\:*; do
+
+ # Skip testing if it's not a directory
+ ! [ -d $dev ] && continue;
+
+ # Read out its symbol link file name
+ path=`readlink -f $dev`
+
+ # Extract device name from path, e.g.
+ # path = '/sys/devices/platform/20010000.etf/tmc_etf0'
+ # `> device_name = 'tmc_etf0'
+ device_name=$(basename $path)
+
+ if is_device_sink $path $device_name; then
+
+ record_touch_file $device_name $2 &&
+ perf_script_branch_samples touch &&
+ perf_report_branch_samples touch &&
+ perf_report_instruction_samples touch
+
+ err=$?
+
+ # Exit when find failure
+ [ $err != 0 ] && exit $err
+ fi
+
+ arm_cs_iterate_devices $dev $2
+ done
+}
+
+arm_cs_etm_traverse_path_test() {
+ # Iterate for every ETM device
+ for dev in /sys/bus/coresight/devices/etm*; do
+
+ # Find the ETM device belonging to which CPU
+ cpu=`cat $dev/cpu`
+
+ echo $dev
+ echo $cpu
+
+ # Use depth-first search (DFS) to iterate outputs
+ arm_cs_iterate_devices $dev $cpu
+ done
+}
+
+arm_cs_etm_system_wide_test() {
+ echo "Recording trace with system wide mode"
+ perf record -o ${perfdata} -e cs_etm// -a -- ls
+
+ perf_script_branch_samples perf &&
+ perf_report_branch_samples perf &&
+ perf_report_instruction_samples perf
+
+ err=$?
+
+ # Exit when find failure
+ [ $err != 0 ] && exit $err
+}
+
+arm_cs_etm_snapshot_test() {
+ echo "Recording trace with snapshot mode"
+ perf record -o ${perfdata} -e cs_etm// -S \
+ -- dd if=/dev/zero of=/dev/null &
+ PERFPID=$!
+
+ # Wait for perf program
+ sleep 1
+
+ # Send signal to snapshot trace data
+ kill -USR2 $PERFPID
+
+ # Stop perf program
+ kill $PERFPID
+ wait $PERFPID
+
+ perf_script_branch_samples dd &&
+ perf_report_branch_samples dd &&
+ perf_report_instruction_samples dd
+
+ err=$?
+
+ # Exit when find failure
+ [ $err != 0 ] && exit $err
+}
+
+arm_cs_etm_traverse_path_test
+arm_cs_etm_system_wide_test
+arm_cs_etm_snapshot_test
+exit 0
diff --git a/tools/perf/tests/shell/trace+probe_vfs_getname.sh b/tools/perf/tests/shell/trace+probe_vfs_getname.sh
index 11cc2af13f2b..3d31c1d560d6 100755
--- a/tools/perf/tests/shell/trace+probe_vfs_getname.sh
+++ b/tools/perf/tests/shell/trace+probe_vfs_getname.sh
@@ -20,7 +20,7 @@ skip_if_no_perf_trace || exit 2
file=$(mktemp /tmp/temporary_file.XXXXX)
trace_open_vfs_getname() {
- evts=$(echo $(perf list syscalls:sys_enter_open* 2>&1 | egrep 'open(at)? ' | sed -r 's/.*sys_enter_([a-z]+) +\[.*$/\1/') | sed 's/ /,/')
+ evts=$(echo $(perf list syscalls:sys_enter_open* 2>/dev/null | egrep 'open(at)? ' | sed -r 's/.*sys_enter_([a-z]+) +\[.*$/\1/') | sed 's/ /,/')
perf trace -e $evts touch $file 2>&1 | \
egrep " +[0-9]+\.[0-9]+ +\( +[0-9]+\.[0-9]+ ms\): +touch\/[0-9]+ open(at)?\((dfd: +CWD, +)?filename: +${file}, +flags: CREAT\|NOCTTY\|NONBLOCK\|WRONLY, +mode: +IRUGO\|IWUGO\) += +[0-9]+$"
}
diff --git a/tools/perf/tests/sw-clock.c b/tools/perf/tests/sw-clock.c
index 4b9b731977c8..a49c9e23053b 100644
--- a/tools/perf/tests/sw-clock.c
+++ b/tools/perf/tests/sw-clock.c
@@ -109,7 +109,7 @@ static int __test__sw_clock_freq(enum perf_sw_ids clock_id)
if (event->header.type != PERF_RECORD_SAMPLE)
goto next_event;
- err = perf_evlist__parse_sample(evlist, event, &sample);
+ err = evlist__parse_sample(evlist, event, &sample);
if (err < 0) {
pr_debug("Error during parse sample\n");
goto out_delete_evlist;
diff --git a/tools/perf/tests/switch-tracking.c b/tools/perf/tests/switch-tracking.c
index db5e1f70053a..15a2ab765d89 100644
--- a/tools/perf/tests/switch-tracking.c
+++ b/tools/perf/tests/switch-tracking.c
@@ -128,12 +128,12 @@ static int process_sample_event(struct evlist *evlist,
pid_t next_tid, prev_tid;
int cpu, err;
- if (perf_evlist__parse_sample(evlist, event, &sample)) {
- pr_debug("perf_evlist__parse_sample failed\n");
+ if (evlist__parse_sample(evlist, event, &sample)) {
+ pr_debug("evlist__parse_sample failed\n");
return -1;
}
- evsel = perf_evlist__id2evsel(evlist, sample.id);
+ evsel = evlist__id2evsel(evlist, sample.id);
if (evsel == switch_tracking->switch_evsel) {
next_tid = evsel__intval(evsel, &sample, "next_pid");
prev_tid = evsel__intval(evsel, &sample, "prev_pid");
@@ -223,8 +223,8 @@ static int add_event(struct evlist *evlist, struct list_head *events,
node->event = event;
list_add(&node->list, events);
- if (perf_evlist__parse_sample(evlist, event, &sample)) {
- pr_debug("perf_evlist__parse_sample failed\n");
+ if (evlist__parse_sample(evlist, event, &sample)) {
+ pr_debug("evlist__parse_sample failed\n");
return -1;
}
@@ -380,7 +380,7 @@ int test__switch_tracking(struct test *test __maybe_unused, int subtest __maybe_
cycles_evsel = evlist__last(evlist);
/* Third event */
- if (!perf_evlist__can_select_event(evlist, sched_switch)) {
+ if (!evlist__can_select_event(evlist, sched_switch)) {
pr_debug("No sched_switch\n");
err = 0;
goto out;
@@ -406,7 +406,7 @@ int test__switch_tracking(struct test *test __maybe_unused, int subtest __maybe_
pr_debug("cycles event already at front");
goto out_err;
}
- perf_evlist__to_front(evlist, cycles_evsel);
+ evlist__to_front(evlist, cycles_evsel);
if (cycles_evsel != evlist__first(evlist)) {
pr_debug("Failed to move cycles event to front");
goto out_err;
@@ -424,7 +424,7 @@ int test__switch_tracking(struct test *test __maybe_unused, int subtest __maybe_
tracking_evsel = evlist__last(evlist);
- perf_evlist__set_tracking_event(evlist, tracking_evsel);
+ evlist__set_tracking_event(evlist, tracking_evsel);
tracking_evsel->core.attr.freq = 0;
tracking_evsel->core.attr.sample_period = 1;
@@ -432,7 +432,7 @@ int test__switch_tracking(struct test *test __maybe_unused, int subtest __maybe_
evsel__set_sample_bit(tracking_evsel, TIME);
/* Config events */
- perf_evlist__config(evlist, &opts, NULL);
+ evlist__config(evlist, &opts, NULL);
/* Check moved event is still at the front */
if (cycles_evsel != evlist__first(evlist)) {
diff --git a/tools/perf/tests/task-exit.c b/tools/perf/tests/task-exit.c
index adaff9044331..bbf94e4aa145 100644
--- a/tools/perf/tests/task-exit.c
+++ b/tools/perf/tests/task-exit.c
@@ -23,7 +23,7 @@ static void sig_handler(int sig __maybe_unused)
}
/*
- * perf_evlist__prepare_workload will send a SIGUSR1 if the fork fails, since
+ * evlist__prepare_workload will send a SIGUSR1 if the fork fails, since
* we asked by setting its exec_error to this handler.
*/
static void workload_exec_failed_signal(int signo __maybe_unused,
@@ -58,16 +58,16 @@ int test__task_exit(struct test *test __maybe_unused, int subtest __maybe_unused
signal(SIGCHLD, sig_handler);
- evlist = perf_evlist__new_default();
+ evlist = evlist__new_default();
if (evlist == NULL) {
- pr_debug("perf_evlist__new_default\n");
+ pr_debug("evlist__new_default\n");
return -1;
}
/*
* Create maps of threads and cpus to monitor. In this case
* we start with all threads and cpus (-1, -1) but then in
- * perf_evlist__prepare_workload we'll fill in the only thread
+ * evlist__prepare_workload we'll fill in the only thread
* we're monitoring, the one forked there.
*/
cpus = perf_cpu_map__dummy_new();
@@ -83,8 +83,7 @@ int test__task_exit(struct test *test __maybe_unused, int subtest __maybe_unused
cpus = NULL;
threads = NULL;
- err = perf_evlist__prepare_workload(evlist, &target, argv, false,
- workload_exec_failed_signal);
+ err = evlist__prepare_workload(evlist, &target, argv, false, workload_exec_failed_signal);
if (err < 0) {
pr_debug("Couldn't run the workload!\n");
goto out_delete_evlist;
@@ -116,7 +115,7 @@ int test__task_exit(struct test *test __maybe_unused, int subtest __maybe_unused
goto out_delete_evlist;
}
- perf_evlist__start_workload(evlist);
+ evlist__start_workload(evlist);
retry:
md = &evlist->mmap[0];
diff --git a/tools/perf/tests/tests.h b/tools/perf/tests/tests.h
index 4447a516c689..8e24a61fe4c2 100644
--- a/tools/perf/tests/tests.h
+++ b/tools/perf/tests/tests.h
@@ -66,6 +66,7 @@ int test__bp_signal_overflow(struct test *test, int subtest);
int test__bp_accounting(struct test *test, int subtest);
int test__wp(struct test *test, int subtest);
const char *test__wp_subtest_get_desc(int subtest);
+const char *test__wp_subtest_skip_reason(int subtest);
int test__wp_subtest_get_nr(void);
int test__task_exit(struct test *test, int subtest);
int test__mem(struct test *test, int subtest);
@@ -122,10 +123,14 @@ int test__pfm(struct test *test, int subtest);
const char *test__pfm_subtest_get_desc(int subtest);
int test__pfm_subtest_get_nr(void);
int test__parse_metric(struct test *test, int subtest);
+int test__pe_file_parsing(struct test *test, int subtest);
+int test__expand_cgroup_events(struct test *test, int subtest);
+int test__perf_time_to_tsc(struct test *test, int subtest);
bool test__bp_signal_is_supported(void);
bool test__bp_account_is_supported(void);
bool test__wp_is_supported(void);
+bool test__tsc_is_supported(void);
#if defined(__arm__) || defined(__aarch64__)
#ifdef HAVE_DWARF_UNWIND_SUPPORT
diff --git a/tools/perf/tests/topology.c b/tools/perf/tests/topology.c
index 22daf2bdf5fa..74748ed75b2c 100644
--- a/tools/perf/tests/topology.c
+++ b/tools/perf/tests/topology.c
@@ -40,7 +40,7 @@ static int session_write_header(char *path)
session = perf_session__new(&data, false, NULL);
TEST_ASSERT_VAL("can't get session", !IS_ERR(session));
- session->evlist = perf_evlist__new_default();
+ session->evlist = evlist__new_default();
TEST_ASSERT_VAL("can't get evlist", session->evlist);
perf_header__set_feat(&session->header, HEADER_CPU_TOPOLOGY);
@@ -65,9 +65,11 @@ static int check_cpu_topology(char *path, struct perf_cpu_map *map)
.mode = PERF_DATA_MODE_READ,
};
int i;
+ struct aggr_cpu_id id;
session = perf_session__new(&data, false, NULL);
TEST_ASSERT_VAL("can't get session", !IS_ERR(session));
+ cpu__setup_cpunode_map();
/* On platforms with large numbers of CPUs process_cpu_topology()
* might issue an error while reading the perf.data file section
@@ -85,11 +87,18 @@ static int check_cpu_topology(char *path, struct perf_cpu_map *map)
* "socket_id number is too big. You may need to upgrade the
* perf tool."
*
- * This is the reason why this test might be skipped.
+ * This is the reason why this test might be skipped. aarch64 and
+ * s390 always write this part of the header, even when the above
+ * condition is true (see do_core_id_test in header.c). So always
+ * run this test on those platforms.
*/
- if (!session->header.env.cpu)
+ if (!session->header.env.cpu
+ && strncmp(session->header.env.arch, "s390", 4)
+ && strncmp(session->header.env.arch, "aarch64", 7))
return TEST_SKIP;
+ TEST_ASSERT_VAL("Session header CPU map not set", session->header.env.cpu);
+
for (i = 0; i < session->header.env.nr_cpus_avail; i++) {
if (!cpu_map__has(map, i))
continue;
@@ -98,14 +107,57 @@ static int check_cpu_topology(char *path, struct perf_cpu_map *map)
session->header.env.cpu[i].socket_id);
}
+ // Test that core ID contains socket, die and core
+ for (i = 0; i < map->nr; i++) {
+ id = cpu_map__get_core(map, i, NULL);
+ TEST_ASSERT_VAL("Core map - Core ID doesn't match",
+ session->header.env.cpu[map->map[i]].core_id == id.core);
+
+ TEST_ASSERT_VAL("Core map - Socket ID doesn't match",
+ session->header.env.cpu[map->map[i]].socket_id == id.socket);
+
+ TEST_ASSERT_VAL("Core map - Die ID doesn't match",
+ session->header.env.cpu[map->map[i]].die_id == id.die);
+ TEST_ASSERT_VAL("Core map - Node ID is set", id.node == -1);
+ TEST_ASSERT_VAL("Core map - Thread is set", id.thread == -1);
+ }
+
+ // Test that die ID contains socket and die
for (i = 0; i < map->nr; i++) {
- TEST_ASSERT_VAL("Core ID doesn't match",
- (session->header.env.cpu[map->map[i]].core_id == (cpu_map__get_core(map, i, NULL) & 0xffff)));
+ id = cpu_map__get_die(map, i, NULL);
+ TEST_ASSERT_VAL("Die map - Socket ID doesn't match",
+ session->header.env.cpu[map->map[i]].socket_id == id.socket);
- TEST_ASSERT_VAL("Socket ID doesn't match",
- (session->header.env.cpu[map->map[i]].socket_id == cpu_map__get_socket(map, i, NULL)));
+ TEST_ASSERT_VAL("Die map - Die ID doesn't match",
+ session->header.env.cpu[map->map[i]].die_id == id.die);
+
+ TEST_ASSERT_VAL("Die map - Node ID is set", id.node == -1);
+ TEST_ASSERT_VAL("Die map - Core is set", id.core == -1);
+ TEST_ASSERT_VAL("Die map - Thread is set", id.thread == -1);
+ }
+
+ // Test that socket ID contains only socket
+ for (i = 0; i < map->nr; i++) {
+ id = cpu_map__get_socket(map, i, NULL);
+ TEST_ASSERT_VAL("Socket map - Socket ID doesn't match",
+ session->header.env.cpu[map->map[i]].socket_id == id.socket);
+
+ TEST_ASSERT_VAL("Socket map - Node ID is set", id.node == -1);
+ TEST_ASSERT_VAL("Socket map - Die ID is set", id.die == -1);
+ TEST_ASSERT_VAL("Socket map - Core is set", id.core == -1);
+ TEST_ASSERT_VAL("Socket map - Thread is set", id.thread == -1);
}
+ // Test that node ID contains only node
+ for (i = 0; i < map->nr; i++) {
+ id = cpu_map__get_node(map, i, NULL);
+ TEST_ASSERT_VAL("Node map - Node ID doesn't match",
+ cpu__get_node(map->map[i]) == id.node);
+ TEST_ASSERT_VAL("Node map - Socket is set", id.socket == -1);
+ TEST_ASSERT_VAL("Node map - Die ID is set", id.die == -1);
+ TEST_ASSERT_VAL("Node map - Core is set", id.core == -1);
+ TEST_ASSERT_VAL("Node map - Thread is set", id.thread == -1);
+ }
perf_session__delete(session);
return 0;
diff --git a/tools/perf/tests/wp.c b/tools/perf/tests/wp.c
index d262d6639829..9387fa76faa5 100644
--- a/tools/perf/tests/wp.c
+++ b/tools/perf/tests/wp.c
@@ -174,10 +174,12 @@ static bool wp_ro_supported(void)
#endif
}
-static void wp_ro_skip_msg(void)
+static const char *wp_ro_skip_msg(void)
{
#if defined (__x86_64__) || defined (__i386__)
- pr_debug("Hardware does not support read only watchpoints.\n");
+ return "missing hardware support";
+#else
+ return NULL;
#endif
}
@@ -185,7 +187,7 @@ static struct {
const char *desc;
int (*target_func)(void);
bool (*is_supported)(void);
- void (*skip_msg)(void);
+ const char *(*skip_msg)(void);
} wp_testcase_table[] = {
{
.desc = "Read Only Watchpoint",
@@ -219,16 +221,23 @@ const char *test__wp_subtest_get_desc(int i)
return wp_testcase_table[i].desc;
}
+const char *test__wp_subtest_skip_reason(int i)
+{
+ if (i < 0 || i >= (int)ARRAY_SIZE(wp_testcase_table))
+ return NULL;
+ if (!wp_testcase_table[i].skip_msg)
+ return NULL;
+ return wp_testcase_table[i].skip_msg();
+}
+
int test__wp(struct test *test __maybe_unused, int i)
{
if (i < 0 || i >= (int)ARRAY_SIZE(wp_testcase_table))
return TEST_FAIL;
if (wp_testcase_table[i].is_supported &&
- !wp_testcase_table[i].is_supported()) {
- wp_testcase_table[i].skip_msg();
+ !wp_testcase_table[i].is_supported())
return TEST_SKIP;
- }
return !wp_testcase_table[i].target_func() ? TEST_OK : TEST_FAIL;
}