aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/tests/bp_signal_overflow.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/perf/tests/bp_signal_overflow.c')
-rw-r--r--tools/perf/tests/bp_signal_overflow.c126
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
22static int overflows;
23
24__attribute__ ((noinline))
25static int test_function(void)
26{
27 return time(NULL);
28}
29
30static void sig_handler(int signum __maybe_unused,
31 siginfo_t *oh __maybe_unused,
32 void *uc __maybe_unused)
33{
34 overflows++;
35}
36
37static 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
54int 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}