aboutsummaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
authorJiri Olsa <jolsa@redhat.com>2012-11-09 19:46:46 -0500
committerArnaldo Carvalho de Melo <acme@redhat.com>2012-11-14 14:49:50 -0500
commitbacf7e5d4055b65506292cf6412ec71e7948a9cf (patch)
treeb911c762c553e59f185aead53cfe279f0d8269cc /tools
parent16d00fee703866c61c9006eff097952289335479 (diff)
perf tests: Move test__rdpmc into separate object
Separating test__rdpmc test from the builtin-test into rdpmc object. Signed-off-by: Jiri Olsa <jolsa@redhat.com> Cc: Corey Ashford <cjashfor@linux.vnet.ibm.com> Cc: Frederic Weisbecker <fweisbec@gmail.com> Cc: Ingo Molnar <mingo@elte.hu> Cc: Paul Mackerras <paulus@samba.org> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Link: http://lkml.kernel.org/r/1352508412-16914-7-git-send-email-jolsa@redhat.com Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Diffstat (limited to 'tools')
-rw-r--r--tools/perf/Makefile1
-rw-r--r--tools/perf/tests/builtin-test.c168
-rw-r--r--tools/perf/tests/rdpmc.c175
-rw-r--r--tools/perf/tests/tests.h1
4 files changed, 177 insertions, 168 deletions
diff --git a/tools/perf/Makefile b/tools/perf/Makefile
index a2d6153a6d06..2e5197a0ad6e 100644
--- a/tools/perf/Makefile
+++ b/tools/perf/Makefile
@@ -436,6 +436,7 @@ LIB_OBJS += $(OUTPUT)tests/open-syscall.o
436LIB_OBJS += $(OUTPUT)tests/open-syscall-all-cpus.o 436LIB_OBJS += $(OUTPUT)tests/open-syscall-all-cpus.o
437LIB_OBJS += $(OUTPUT)tests/mmap-basic.o 437LIB_OBJS += $(OUTPUT)tests/mmap-basic.o
438LIB_OBJS += $(OUTPUT)tests/perf-record.o 438LIB_OBJS += $(OUTPUT)tests/perf-record.o
439LIB_OBJS += $(OUTPUT)tests/rdpmc.o
439LIB_OBJS += $(OUTPUT)tests/util.o 440LIB_OBJS += $(OUTPUT)tests/util.o
440 441
441BUILTIN_OBJS += $(OUTPUT)builtin-annotate.o 442BUILTIN_OBJS += $(OUTPUT)builtin-annotate.o
diff --git a/tools/perf/tests/builtin-test.c b/tools/perf/tests/builtin-test.c
index 7cb3928d896a..1e9a0ea68fb2 100644
--- a/tools/perf/tests/builtin-test.c
+++ b/tools/perf/tests/builtin-test.c
@@ -30,174 +30,6 @@
30#include <sched.h> 30#include <sched.h>
31 31
32 32
33
34#if defined(__x86_64__) || defined(__i386__)
35
36#define barrier() asm volatile("" ::: "memory")
37
38static u64 rdpmc(unsigned int counter)
39{
40 unsigned int low, high;
41
42 asm volatile("rdpmc" : "=a" (low), "=d" (high) : "c" (counter));
43
44 return low | ((u64)high) << 32;
45}
46
47static u64 rdtsc(void)
48{
49 unsigned int low, high;
50
51 asm volatile("rdtsc" : "=a" (low), "=d" (high));
52
53 return low | ((u64)high) << 32;
54}
55
56static u64 mmap_read_self(void *addr)
57{
58 struct perf_event_mmap_page *pc = addr;
59 u32 seq, idx, time_mult = 0, time_shift = 0;
60 u64 count, cyc = 0, time_offset = 0, enabled, running, delta;
61
62 do {
63 seq = pc->lock;
64 barrier();
65
66 enabled = pc->time_enabled;
67 running = pc->time_running;
68
69 if (enabled != running) {
70 cyc = rdtsc();
71 time_mult = pc->time_mult;
72 time_shift = pc->time_shift;
73 time_offset = pc->time_offset;
74 }
75
76 idx = pc->index;
77 count = pc->offset;
78 if (idx)
79 count += rdpmc(idx - 1);
80
81 barrier();
82 } while (pc->lock != seq);
83
84 if (enabled != running) {
85 u64 quot, rem;
86
87 quot = (cyc >> time_shift);
88 rem = cyc & ((1 << time_shift) - 1);
89 delta = time_offset + quot * time_mult +
90 ((rem * time_mult) >> time_shift);
91
92 enabled += delta;
93 if (idx)
94 running += delta;
95
96 quot = count / running;
97 rem = count % running;
98 count = quot * enabled + (rem * enabled) / running;
99 }
100
101 return count;
102}
103
104/*
105 * If the RDPMC instruction faults then signal this back to the test parent task:
106 */
107static void segfault_handler(int sig __maybe_unused,
108 siginfo_t *info __maybe_unused,
109 void *uc __maybe_unused)
110{
111 exit(-1);
112}
113
114static int __test__rdpmc(void)
115{
116 volatile int tmp = 0;
117 u64 i, loops = 1000;
118 int n;
119 int fd;
120 void *addr;
121 struct perf_event_attr attr = {
122 .type = PERF_TYPE_HARDWARE,
123 .config = PERF_COUNT_HW_INSTRUCTIONS,
124 .exclude_kernel = 1,
125 };
126 u64 delta_sum = 0;
127 struct sigaction sa;
128
129 sigfillset(&sa.sa_mask);
130 sa.sa_sigaction = segfault_handler;
131 sigaction(SIGSEGV, &sa, NULL);
132
133 fd = sys_perf_event_open(&attr, 0, -1, -1, 0);
134 if (fd < 0) {
135 pr_err("Error: sys_perf_event_open() syscall returned "
136 "with %d (%s)\n", fd, strerror(errno));
137 return -1;
138 }
139
140 addr = mmap(NULL, page_size, PROT_READ, MAP_SHARED, fd, 0);
141 if (addr == (void *)(-1)) {
142 pr_err("Error: mmap() syscall returned with (%s)\n",
143 strerror(errno));
144 goto out_close;
145 }
146
147 for (n = 0; n < 6; n++) {
148 u64 stamp, now, delta;
149
150 stamp = mmap_read_self(addr);
151
152 for (i = 0; i < loops; i++)
153 tmp++;
154
155 now = mmap_read_self(addr);
156 loops *= 10;
157
158 delta = now - stamp;
159 pr_debug("%14d: %14Lu\n", n, (long long)delta);
160
161 delta_sum += delta;
162 }
163
164 munmap(addr, page_size);
165 pr_debug(" ");
166out_close:
167 close(fd);
168
169 if (!delta_sum)
170 return -1;
171
172 return 0;
173}
174
175static int test__rdpmc(void)
176{
177 int status = 0;
178 int wret = 0;
179 int ret;
180 int pid;
181
182 pid = fork();
183 if (pid < 0)
184 return -1;
185
186 if (!pid) {
187 ret = __test__rdpmc();
188
189 exit(ret);
190 }
191
192 wret = waitpid(pid, &status, 0);
193 if (wret < 0 || status)
194 return -1;
195
196 return 0;
197}
198
199#endif
200
201static int test__perf_pmu(void) 33static int test__perf_pmu(void)
202{ 34{
203 return perf_pmu__test(); 35 return perf_pmu__test();
diff --git a/tools/perf/tests/rdpmc.c b/tools/perf/tests/rdpmc.c
new file mode 100644
index 000000000000..ff94886aad99
--- /dev/null
+++ b/tools/perf/tests/rdpmc.c
@@ -0,0 +1,175 @@
1#include <unistd.h>
2#include <stdlib.h>
3#include <signal.h>
4#include <sys/mman.h>
5#include "types.h"
6#include "perf.h"
7#include "debug.h"
8#include "tests.h"
9
10#if defined(__x86_64__) || defined(__i386__)
11
12#define barrier() asm volatile("" ::: "memory")
13
14static u64 rdpmc(unsigned int counter)
15{
16 unsigned int low, high;
17
18 asm volatile("rdpmc" : "=a" (low), "=d" (high) : "c" (counter));
19
20 return low | ((u64)high) << 32;
21}
22
23static u64 rdtsc(void)
24{
25 unsigned int low, high;
26
27 asm volatile("rdtsc" : "=a" (low), "=d" (high));
28
29 return low | ((u64)high) << 32;
30}
31
32static u64 mmap_read_self(void *addr)
33{
34 struct perf_event_mmap_page *pc = addr;
35 u32 seq, idx, time_mult = 0, time_shift = 0;
36 u64 count, cyc = 0, time_offset = 0, enabled, running, delta;
37
38 do {
39 seq = pc->lock;
40 barrier();
41
42 enabled = pc->time_enabled;
43 running = pc->time_running;
44
45 if (enabled != running) {
46 cyc = rdtsc();
47 time_mult = pc->time_mult;
48 time_shift = pc->time_shift;
49 time_offset = pc->time_offset;
50 }
51
52 idx = pc->index;
53 count = pc->offset;
54 if (idx)
55 count += rdpmc(idx - 1);
56
57 barrier();
58 } while (pc->lock != seq);
59
60 if (enabled != running) {
61 u64 quot, rem;
62
63 quot = (cyc >> time_shift);
64 rem = cyc & ((1 << time_shift) - 1);
65 delta = time_offset + quot * time_mult +
66 ((rem * time_mult) >> time_shift);
67
68 enabled += delta;
69 if (idx)
70 running += delta;
71
72 quot = count / running;
73 rem = count % running;
74 count = quot * enabled + (rem * enabled) / running;
75 }
76
77 return count;
78}
79
80/*
81 * If the RDPMC instruction faults then signal this back to the test parent task:
82 */
83static void segfault_handler(int sig __maybe_unused,
84 siginfo_t *info __maybe_unused,
85 void *uc __maybe_unused)
86{
87 exit(-1);
88}
89
90static int __test__rdpmc(void)
91{
92 volatile int tmp = 0;
93 u64 i, loops = 1000;
94 int n;
95 int fd;
96 void *addr;
97 struct perf_event_attr attr = {
98 .type = PERF_TYPE_HARDWARE,
99 .config = PERF_COUNT_HW_INSTRUCTIONS,
100 .exclude_kernel = 1,
101 };
102 u64 delta_sum = 0;
103 struct sigaction sa;
104
105 sigfillset(&sa.sa_mask);
106 sa.sa_sigaction = segfault_handler;
107 sigaction(SIGSEGV, &sa, NULL);
108
109 fd = sys_perf_event_open(&attr, 0, -1, -1, 0);
110 if (fd < 0) {
111 pr_err("Error: sys_perf_event_open() syscall returned "
112 "with %d (%s)\n", fd, strerror(errno));
113 return -1;
114 }
115
116 addr = mmap(NULL, page_size, PROT_READ, MAP_SHARED, fd, 0);
117 if (addr == (void *)(-1)) {
118 pr_err("Error: mmap() syscall returned with (%s)\n",
119 strerror(errno));
120 goto out_close;
121 }
122
123 for (n = 0; n < 6; n++) {
124 u64 stamp, now, delta;
125
126 stamp = mmap_read_self(addr);
127
128 for (i = 0; i < loops; i++)
129 tmp++;
130
131 now = mmap_read_self(addr);
132 loops *= 10;
133
134 delta = now - stamp;
135 pr_debug("%14d: %14Lu\n", n, (long long)delta);
136
137 delta_sum += delta;
138 }
139
140 munmap(addr, page_size);
141 pr_debug(" ");
142out_close:
143 close(fd);
144
145 if (!delta_sum)
146 return -1;
147
148 return 0;
149}
150
151int test__rdpmc(void)
152{
153 int status = 0;
154 int wret = 0;
155 int ret;
156 int pid;
157
158 pid = fork();
159 if (pid < 0)
160 return -1;
161
162 if (!pid) {
163 ret = __test__rdpmc();
164
165 exit(ret);
166 }
167
168 wret = waitpid(pid, &status, 0);
169 if (wret < 0 || status)
170 return -1;
171
172 return 0;
173}
174
175#endif
diff --git a/tools/perf/tests/tests.h b/tools/perf/tests/tests.h
index 374b039dd22c..03d428d72432 100644
--- a/tools/perf/tests/tests.h
+++ b/tools/perf/tests/tests.h
@@ -7,6 +7,7 @@ int test__open_syscall_event(void);
7int test__open_syscall_event_on_all_cpus(void); 7int test__open_syscall_event_on_all_cpus(void);
8int test__basic_mmap(void); 8int test__basic_mmap(void);
9int test__PERF_RECORD(void); 9int test__PERF_RECORD(void);
10int test__rdpmc(void);
10 11
11/* Util */ 12/* Util */
12int trace_event__id(const char *evname); 13int trace_event__id(const char *evname);