summaryrefslogtreecommitdiffstats
path: root/tools/perf/tests
diff options
context:
space:
mode:
authorWang Nan <wangnan0@huawei.com>2016-11-26 07:03:28 +0000
committerArnaldo Carvalho de Melo <acme@redhat.com>2016-11-29 12:13:27 -0300
commita074865e60edd762b99ec5dacec69b406f702e66 (patch)
tree774e0abac8cf015dad77638c3c79aa56609dbb82 /tools/perf/tests
parent5a6acad17d2e81765dd4c2fce7346a6f045eab25 (diff)
downloadlinux-a074865e60edd762b99ec5dacec69b406f702e66.tar.bz2
perf tools: Introduce perf hooks
Perf hooks allow hooking user code at perf events. They can be used for manipulation of BPF maps, taking snapshot and reporting results. In this patch two perf hook points are introduced: record_start and record_end. To avoid buggy user actions, a SIGSEGV signal handler is introduced into 'perf record'. It turns off perf hook if it causes a segfault and report an error to help debugging. A test case for perf hook is introduced. Test result: $ ./buildperf/perf test -v hook 50: Test perf hooks : --- start --- test child forked, pid 10311 SIGSEGV is observed as expected, try to recover. Fatal error (SEGFAULT) in perf hook 'test' test child finished with 0 ---- end ---- Test perf hooks: Ok Signed-off-by: Wang Nan <wangnan0@huawei.com> Cc: Alexei Starovoitov <ast@fb.com> Cc: He Kuang <hekuang@huawei.com> Cc: Jiri Olsa <jolsa@kernel.org> Cc: Joe Stringer <joe@ovn.org> Cc: Zefan Li <lizefan@huawei.com> Cc: pi3orama@163.com Link: http://lkml.kernel.org/r/20161126070354.141764-5-wangnan0@huawei.com Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Diffstat (limited to 'tools/perf/tests')
-rw-r--r--tools/perf/tests/Build1
-rw-r--r--tools/perf/tests/builtin-test.c4
-rw-r--r--tools/perf/tests/perf-hooks.c44
-rw-r--r--tools/perf/tests/tests.h1
4 files changed, 50 insertions, 0 deletions
diff --git a/tools/perf/tests/Build b/tools/perf/tests/Build
index 8a4ce492f7b2..af3ec94869aa 100644
--- a/tools/perf/tests/Build
+++ b/tools/perf/tests/Build
@@ -42,6 +42,7 @@ perf-y += backward-ring-buffer.o
perf-y += sdt.o
perf-y += is_printable_array.o
perf-y += bitmap.o
+perf-y += perf-hooks.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 778668a2a966..dab83f7042fa 100644
--- a/tools/perf/tests/builtin-test.c
+++ b/tools/perf/tests/builtin-test.c
@@ -230,6 +230,10 @@ static struct test generic_tests[] = {
.func = test__bitmap_print,
},
{
+ .desc = "Test perf hooks",
+ .func = test__perf_hooks,
+ },
+ {
.func = NULL,
},
};
diff --git a/tools/perf/tests/perf-hooks.c b/tools/perf/tests/perf-hooks.c
new file mode 100644
index 000000000000..9338cb2c25ab
--- /dev/null
+++ b/tools/perf/tests/perf-hooks.c
@@ -0,0 +1,44 @@
+#include <signal.h>
+#include <stdlib.h>
+
+#include "tests.h"
+#include "debug.h"
+#include "util.h"
+#include "perf-hooks.h"
+
+static void sigsegv_handler(int sig __maybe_unused)
+{
+ pr_debug("SIGSEGV is observed as expected, try to recover.\n");
+ perf_hooks__recover();
+ signal(SIGSEGV, SIG_DFL);
+ raise(SIGSEGV);
+ exit(-1);
+}
+
+static int hook_flags;
+
+static void the_hook(void)
+{
+ int *p = NULL;
+
+ hook_flags = 1234;
+
+ /* Generate a segfault, test perf_hooks__recover */
+ *p = 0;
+}
+
+int test__perf_hooks(int subtest __maybe_unused)
+{
+ signal(SIGSEGV, sigsegv_handler);
+ perf_hooks__set_hook("test", the_hook);
+ perf_hooks__invoke_test();
+
+ /* hook is triggered? */
+ if (hook_flags != 1234)
+ return TEST_FAIL;
+
+ /* the buggy hook is removed? */
+ if (perf_hooks__get_hook("test"))
+ return TEST_FAIL;
+ return TEST_OK;
+}
diff --git a/tools/perf/tests/tests.h b/tools/perf/tests/tests.h
index 7c196c585472..3a1f98f291ba 100644
--- a/tools/perf/tests/tests.h
+++ b/tools/perf/tests/tests.h
@@ -91,6 +91,7 @@ int test__cpu_map_print(int subtest);
int test__sdt_event(int subtest);
int test__is_printable_array(int subtest);
int test__bitmap_print(int subtest);
+int test__perf_hooks(int subtest);
#if defined(__arm__) || defined(__aarch64__)
#ifdef HAVE_DWARF_UNWIND_SUPPORT