diff options
author | Ingo Molnar <mingo@kernel.org> | 2013-03-21 06:06:12 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@kernel.org> | 2013-03-21 06:06:12 -0400 |
commit | 0a11953851213fd1d3eebcb68b4a537d458c70c2 (patch) | |
tree | 3f6f7cae25b8c1a81d6f37b1ecfff5a45bb9df40 /tools/perf/tests/bp_signal_overflow.c | |
parent | 3bf2391729822e591dcfbbd1e9dd2f450968cdcb (diff) | |
parent | bc96b361cbf90e61d2665b1305cd2c4ac1fd9cfc (diff) |
Merge tag 'perf-core-for-mingo' of git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux into perf/core
Conflicts:
tools/Makefile
Pull perf/core improvements and fixes from Arnaldo Carvalho de Melo:
. Honor parallel jobs, fix from Borislav Petkov
. Introduce tools/lib/lk library, initially just removing duplication
among tools/perf and tools/vm. from Borislav Petkov
. Fix build on non-glibc systems due to libio.h absence, from Cody P Schafer.
. Remove some perf_session and tracing dead code, from David Ahern.
. Introduce perf stat --repeat forever, from Frederik Deweerdt.
. Add perf test entries for checking --cpu in record and stat, from Jiri Olsa.
. Add perf test entries for checking breakpoint overflow signal handler issues,
from Jiri Olsa.
. Add perf test entry for for checking number of EXIT events, from Namhyung Kim.
. Simplify some perf_evlist methods and to allow 'stat' to share code with
'record' and 'trace'.
. Remove dead code in related to libtraceevent integration, from Namhyung Kim.
. Event group view for 'annotate' in --stdio, --tui and --gtk, from Namhyung Kim.
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
[ resolved the trivial merge conflict with upstream ]
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Diffstat (limited to 'tools/perf/tests/bp_signal_overflow.c')
-rw-r--r-- | tools/perf/tests/bp_signal_overflow.c | 126 |
1 files changed, 126 insertions, 0 deletions
diff --git a/tools/perf/tests/bp_signal_overflow.c b/tools/perf/tests/bp_signal_overflow.c new file mode 100644 index 000000000000..fe7ed28815f8 --- /dev/null +++ b/tools/perf/tests/bp_signal_overflow.c | |||
@@ -0,0 +1,126 @@ | |||
1 | /* | ||
2 | * Originally done by Vince Weaver <vincent.weaver@maine.edu> for | ||
3 | * perf_event_tests (git://github.com/deater/perf_event_tests) | ||
4 | */ | ||
5 | |||
6 | #include <stdlib.h> | ||
7 | #include <stdio.h> | ||
8 | #include <unistd.h> | ||
9 | #include <string.h> | ||
10 | #include <sys/ioctl.h> | ||
11 | #include <time.h> | ||
12 | #include <fcntl.h> | ||
13 | #include <signal.h> | ||
14 | #include <sys/mman.h> | ||
15 | #include <linux/compiler.h> | ||
16 | #include <linux/hw_breakpoint.h> | ||
17 | |||
18 | #include "tests.h" | ||
19 | #include "debug.h" | ||
20 | #include "perf.h" | ||
21 | |||
22 | static int overflows; | ||
23 | |||
24 | __attribute__ ((noinline)) | ||
25 | static int test_function(void) | ||
26 | { | ||
27 | return time(NULL); | ||
28 | } | ||
29 | |||
30 | static void sig_handler(int signum __maybe_unused, | ||
31 | siginfo_t *oh __maybe_unused, | ||
32 | void *uc __maybe_unused) | ||
33 | { | ||
34 | overflows++; | ||
35 | } | ||
36 | |||
37 | static long long bp_count(int fd) | ||
38 | { | ||
39 | long long count; | ||
40 | int ret; | ||
41 | |||
42 | ret = read(fd, &count, sizeof(long long)); | ||
43 | if (ret != sizeof(long long)) { | ||
44 | pr_debug("failed to read: %d\n", ret); | ||
45 | return TEST_FAIL; | ||
46 | } | ||
47 | |||
48 | return count; | ||
49 | } | ||
50 | |||
51 | #define EXECUTIONS 10000 | ||
52 | #define THRESHOLD 100 | ||
53 | |||
54 | int test__bp_signal_overflow(void) | ||
55 | { | ||
56 | struct perf_event_attr pe; | ||
57 | struct sigaction sa; | ||
58 | long long count; | ||
59 | int fd, i, fails = 0; | ||
60 | |||
61 | /* setup SIGIO signal handler */ | ||
62 | memset(&sa, 0, sizeof(struct sigaction)); | ||
63 | sa.sa_sigaction = (void *) sig_handler; | ||
64 | sa.sa_flags = SA_SIGINFO; | ||
65 | |||
66 | if (sigaction(SIGIO, &sa, NULL) < 0) { | ||
67 | pr_debug("failed setting up signal handler\n"); | ||
68 | return TEST_FAIL; | ||
69 | } | ||
70 | |||
71 | memset(&pe, 0, sizeof(struct perf_event_attr)); | ||
72 | pe.type = PERF_TYPE_BREAKPOINT; | ||
73 | pe.size = sizeof(struct perf_event_attr); | ||
74 | |||
75 | pe.config = 0; | ||
76 | pe.bp_type = HW_BREAKPOINT_X; | ||
77 | pe.bp_addr = (unsigned long) test_function; | ||
78 | pe.bp_len = sizeof(long); | ||
79 | |||
80 | pe.sample_period = THRESHOLD; | ||
81 | pe.sample_type = PERF_SAMPLE_IP; | ||
82 | pe.wakeup_events = 1; | ||
83 | |||
84 | pe.disabled = 1; | ||
85 | pe.exclude_kernel = 1; | ||
86 | pe.exclude_hv = 1; | ||
87 | |||
88 | fd = sys_perf_event_open(&pe, 0, -1, -1, 0); | ||
89 | if (fd < 0) { | ||
90 | pr_debug("failed opening event %llx\n", pe.config); | ||
91 | return TEST_FAIL; | ||
92 | } | ||
93 | |||
94 | fcntl(fd, F_SETFL, O_RDWR|O_NONBLOCK|O_ASYNC); | ||
95 | fcntl(fd, F_SETSIG, SIGIO); | ||
96 | fcntl(fd, F_SETOWN, getpid()); | ||
97 | |||
98 | ioctl(fd, PERF_EVENT_IOC_RESET, 0); | ||
99 | ioctl(fd, PERF_EVENT_IOC_ENABLE, 0); | ||
100 | |||
101 | for (i = 0; i < EXECUTIONS; i++) | ||
102 | test_function(); | ||
103 | |||
104 | ioctl(fd, PERF_EVENT_IOC_DISABLE, 0); | ||
105 | |||
106 | count = bp_count(fd); | ||
107 | |||
108 | close(fd); | ||
109 | |||
110 | pr_debug("count %lld, overflow %d\n", | ||
111 | count, overflows); | ||
112 | |||
113 | if (count != EXECUTIONS) { | ||
114 | pr_debug("\tWrong number of executions %lld != %d\n", | ||
115 | count, EXECUTIONS); | ||
116 | fails++; | ||
117 | } | ||
118 | |||
119 | if (overflows != EXECUTIONS / THRESHOLD) { | ||
120 | pr_debug("\tWrong number of overflows %d != %d\n", | ||
121 | overflows, EXECUTIONS / THRESHOLD); | ||
122 | fails++; | ||
123 | } | ||
124 | |||
125 | return fails ? TEST_FAIL : TEST_OK; | ||
126 | } | ||