diff options
author | Ingo Molnar <mingo@kernel.org> | 2015-10-20 03:31:22 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@kernel.org> | 2015-10-20 03:31:22 -0400 |
commit | 40d4f23f42b0e6997db5bbfba9dc6bf349e8ad81 (patch) | |
tree | 38daabe92501b668a1fe4bab9c2b1e310a39a3b2 /tools/perf | |
parent | e9363deeb286e916353f11b11d1f351c6ff54082 (diff) | |
parent | a4c6a3e8bbb675a601f529881c51ff226f83c3f1 (diff) |
Merge tag 'perf-core-for-mingo' of git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux into perf/core
Pull perf/core improvements and fixes:
User visible changes:
- 'perf bench mem' now prefaults unconditionally, no sense in
providing modes where page faults are measured. (Ingo Molnar)
- Harmonize -l/--nr_loops accross 'perf bench'. (Ingo Molnar)
- Various 'perf bench' consistency improvements. (Ingo Molnar)
- Suppress libtraceevent warnings in non-verbose 'perf test' mode.
(Namhyung Kim)
- Move some tracepoint event test error messages to the verbose mode
of 'perf test'. (Namhyung Kim)
- Make 'perf help' usage message consistent with other tools. (Yunlong Song)
Build fixes:
- Fix 'perf bench' build with gcc 4.4.7. (Arnaldo Carvalho de Melo)
Infrastructure changes:
- 'perf stat' prep work for the 'perf stat scripting' patchkit. (Jiri Olsa)
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Diffstat (limited to 'tools/perf')
-rw-r--r-- | tools/perf/Documentation/perf-bench.txt | 54 | ||||
-rw-r--r-- | tools/perf/bench/Build | 2 | ||||
-rw-r--r-- | tools/perf/bench/mem-functions.c | 379 | ||||
-rw-r--r-- | tools/perf/bench/mem-memcpy.c | 434 | ||||
-rw-r--r-- | tools/perf/bench/numa.c | 4 | ||||
-rw-r--r-- | tools/perf/bench/sched-messaging.c | 10 | ||||
-rw-r--r-- | tools/perf/builtin-bench.c | 14 | ||||
-rw-r--r-- | tools/perf/builtin-help.c | 2 | ||||
-rw-r--r-- | tools/perf/builtin-script.c | 5 | ||||
-rw-r--r-- | tools/perf/builtin-stat.c | 23 | ||||
-rw-r--r-- | tools/perf/tests/openat-syscall-all-cpus.c | 2 | ||||
-rw-r--r-- | tools/perf/tests/openat-syscall-tp-fields.c | 2 | ||||
-rw-r--r-- | tools/perf/tests/openat-syscall.c | 2 | ||||
-rw-r--r-- | tools/perf/tests/parse-events.c | 14 | ||||
-rw-r--r-- | tools/perf/tests/topology.c | 4 | ||||
-rw-r--r-- | tools/perf/util/cpumap.c | 17 | ||||
-rw-r--r-- | tools/perf/util/cpumap.h | 7 | ||||
-rw-r--r-- | tools/perf/util/parse-options.c | 4 | ||||
-rw-r--r-- | tools/perf/util/stat.c | 13 | ||||
-rw-r--r-- | tools/perf/util/stat.h | 3 | ||||
-rw-r--r-- | tools/perf/util/usage.c | 5 | ||||
-rw-r--r-- | tools/perf/util/util.h | 1 |
22 files changed, 487 insertions, 514 deletions
diff --git a/tools/perf/Documentation/perf-bench.txt b/tools/perf/Documentation/perf-bench.txt index ab632d9fbd7d..34750fc32714 100644 --- a/tools/perf/Documentation/perf-bench.txt +++ b/tools/perf/Documentation/perf-bench.txt | |||
@@ -82,7 +82,7 @@ Be multi thread instead of multi process | |||
82 | Specify number of groups | 82 | Specify number of groups |
83 | 83 | ||
84 | -l:: | 84 | -l:: |
85 | --loop=:: | 85 | --nr_loops=:: |
86 | Specify number of loops | 86 | Specify number of loops |
87 | 87 | ||
88 | Example of *messaging* | 88 | Example of *messaging* |
@@ -139,64 +139,48 @@ Suite for evaluating performance of simple memory copy in various ways. | |||
139 | Options of *memcpy* | 139 | Options of *memcpy* |
140 | ^^^^^^^^^^^^^^^^^^^ | 140 | ^^^^^^^^^^^^^^^^^^^ |
141 | -l:: | 141 | -l:: |
142 | --length:: | 142 | --size:: |
143 | Specify length of memory to copy (default: 1MB). | 143 | Specify size of memory to copy (default: 1MB). |
144 | Available units are B, KB, MB, GB and TB (case insensitive). | 144 | Available units are B, KB, MB, GB and TB (case insensitive). |
145 | 145 | ||
146 | -r:: | 146 | -f:: |
147 | --routine:: | 147 | --function:: |
148 | Specify routine to copy (default: default). | 148 | Specify function to copy (default: default). |
149 | Available routines are depend on the architecture. | 149 | Available functions are depend on the architecture. |
150 | On x86-64, x86-64-unrolled, x86-64-movsq and x86-64-movsb are supported. | 150 | On x86-64, x86-64-unrolled, x86-64-movsq and x86-64-movsb are supported. |
151 | 151 | ||
152 | -i:: | 152 | -l:: |
153 | --iterations:: | 153 | --nr_loops:: |
154 | Repeat memcpy invocation this number of times. | 154 | Repeat memcpy invocation this number of times. |
155 | 155 | ||
156 | -c:: | 156 | -c:: |
157 | --cycle:: | 157 | --cycles:: |
158 | Use perf's cpu-cycles event instead of gettimeofday syscall. | 158 | Use perf's cpu-cycles event instead of gettimeofday syscall. |
159 | 159 | ||
160 | -o:: | ||
161 | --only-prefault:: | ||
162 | Show only the result with page faults before memcpy. | ||
163 | |||
164 | -n:: | ||
165 | --no-prefault:: | ||
166 | Show only the result without page faults before memcpy. | ||
167 | |||
168 | *memset*:: | 160 | *memset*:: |
169 | Suite for evaluating performance of simple memory set in various ways. | 161 | Suite for evaluating performance of simple memory set in various ways. |
170 | 162 | ||
171 | Options of *memset* | 163 | Options of *memset* |
172 | ^^^^^^^^^^^^^^^^^^^ | 164 | ^^^^^^^^^^^^^^^^^^^ |
173 | -l:: | 165 | -l:: |
174 | --length:: | 166 | --size:: |
175 | Specify length of memory to set (default: 1MB). | 167 | Specify size of memory to set (default: 1MB). |
176 | Available units are B, KB, MB, GB and TB (case insensitive). | 168 | Available units are B, KB, MB, GB and TB (case insensitive). |
177 | 169 | ||
178 | -r:: | 170 | -f:: |
179 | --routine:: | 171 | --function:: |
180 | Specify routine to set (default: default). | 172 | Specify function to set (default: default). |
181 | Available routines are depend on the architecture. | 173 | Available functions are depend on the architecture. |
182 | On x86-64, x86-64-unrolled, x86-64-stosq and x86-64-stosb are supported. | 174 | On x86-64, x86-64-unrolled, x86-64-stosq and x86-64-stosb are supported. |
183 | 175 | ||
184 | -i:: | 176 | -l:: |
185 | --iterations:: | 177 | --nr_loops:: |
186 | Repeat memset invocation this number of times. | 178 | Repeat memset invocation this number of times. |
187 | 179 | ||
188 | -c:: | 180 | -c:: |
189 | --cycle:: | 181 | --cycles:: |
190 | Use perf's cpu-cycles event instead of gettimeofday syscall. | 182 | Use perf's cpu-cycles event instead of gettimeofday syscall. |
191 | 183 | ||
192 | -o:: | ||
193 | --only-prefault:: | ||
194 | Show only the result with page faults before memset. | ||
195 | |||
196 | -n:: | ||
197 | --no-prefault:: | ||
198 | Show only the result without page faults before memset. | ||
199 | |||
200 | SUITES FOR 'numa' | 184 | SUITES FOR 'numa' |
201 | ~~~~~~~~~~~~~~~~~ | 185 | ~~~~~~~~~~~~~~~~~ |
202 | *mem*:: | 186 | *mem*:: |
diff --git a/tools/perf/bench/Build b/tools/perf/bench/Build index 573e28896038..60bf11943047 100644 --- a/tools/perf/bench/Build +++ b/tools/perf/bench/Build | |||
@@ -1,6 +1,6 @@ | |||
1 | perf-y += sched-messaging.o | 1 | perf-y += sched-messaging.o |
2 | perf-y += sched-pipe.o | 2 | perf-y += sched-pipe.o |
3 | perf-y += mem-memcpy.o | 3 | perf-y += mem-functions.o |
4 | perf-y += futex-hash.o | 4 | perf-y += futex-hash.o |
5 | perf-y += futex-wake.o | 5 | perf-y += futex-wake.o |
6 | perf-y += futex-wake-parallel.o | 6 | perf-y += futex-wake-parallel.o |
diff --git a/tools/perf/bench/mem-functions.c b/tools/perf/bench/mem-functions.c new file mode 100644 index 000000000000..9419b944220f --- /dev/null +++ b/tools/perf/bench/mem-functions.c | |||
@@ -0,0 +1,379 @@ | |||
1 | /* | ||
2 | * mem-memcpy.c | ||
3 | * | ||
4 | * Simple memcpy() and memset() benchmarks | ||
5 | * | ||
6 | * Written by Hitoshi Mitake <mitake@dcl.info.waseda.ac.jp> | ||
7 | */ | ||
8 | |||
9 | #include "../perf.h" | ||
10 | #include "../util/util.h" | ||
11 | #include "../util/parse-options.h" | ||
12 | #include "../util/header.h" | ||
13 | #include "../util/cloexec.h" | ||
14 | #include "bench.h" | ||
15 | #include "mem-memcpy-arch.h" | ||
16 | #include "mem-memset-arch.h" | ||
17 | |||
18 | #include <stdio.h> | ||
19 | #include <stdlib.h> | ||
20 | #include <string.h> | ||
21 | #include <sys/time.h> | ||
22 | #include <errno.h> | ||
23 | |||
24 | #define K 1024 | ||
25 | |||
26 | static const char *size_str = "1MB"; | ||
27 | static const char *function_str = "all"; | ||
28 | static int nr_loops = 1; | ||
29 | static bool use_cycles; | ||
30 | static int cycles_fd; | ||
31 | |||
32 | static const struct option options[] = { | ||
33 | OPT_STRING('s', "size", &size_str, "1MB", | ||
34 | "Specify the size of the memory buffers. " | ||
35 | "Available units: B, KB, MB, GB and TB (case insensitive)"), | ||
36 | |||
37 | OPT_STRING('f', "function", &function_str, "all", | ||
38 | "Specify the function to run, \"all\" runs all available functions, \"help\" lists them"), | ||
39 | |||
40 | OPT_INTEGER('l', "nr_loops", &nr_loops, | ||
41 | "Specify the number of loops to run. (default: 1)"), | ||
42 | |||
43 | OPT_BOOLEAN('c', "cycles", &use_cycles, | ||
44 | "Use a cycles event instead of gettimeofday() to measure performance"), | ||
45 | |||
46 | OPT_END() | ||
47 | }; | ||
48 | |||
49 | typedef void *(*memcpy_t)(void *, const void *, size_t); | ||
50 | typedef void *(*memset_t)(void *, int, size_t); | ||
51 | |||
52 | struct function { | ||
53 | const char *name; | ||
54 | const char *desc; | ||
55 | union { | ||
56 | memcpy_t memcpy; | ||
57 | memset_t memset; | ||
58 | } fn; | ||
59 | }; | ||
60 | |||
61 | static struct perf_event_attr cycle_attr = { | ||
62 | .type = PERF_TYPE_HARDWARE, | ||
63 | .config = PERF_COUNT_HW_CPU_CYCLES | ||
64 | }; | ||
65 | |||
66 | static void init_cycles(void) | ||
67 | { | ||
68 | cycles_fd = sys_perf_event_open(&cycle_attr, getpid(), -1, -1, perf_event_open_cloexec_flag()); | ||
69 | |||
70 | if (cycles_fd < 0 && errno == ENOSYS) | ||
71 | die("No CONFIG_PERF_EVENTS=y kernel support configured?\n"); | ||
72 | else | ||
73 | BUG_ON(cycles_fd < 0); | ||
74 | } | ||
75 | |||
76 | static u64 get_cycles(void) | ||
77 | { | ||
78 | int ret; | ||
79 | u64 clk; | ||
80 | |||
81 | ret = read(cycles_fd, &clk, sizeof(u64)); | ||
82 | BUG_ON(ret != sizeof(u64)); | ||
83 | |||
84 | return clk; | ||
85 | } | ||
86 | |||
87 | static double timeval2double(struct timeval *ts) | ||
88 | { | ||
89 | return (double)ts->tv_sec + (double)ts->tv_usec / (double)1000000; | ||
90 | } | ||
91 | |||
92 | #define print_bps(x) do { \ | ||
93 | if (x < K) \ | ||
94 | printf(" %14lf bytes/sec\n", x); \ | ||
95 | else if (x < K * K) \ | ||
96 | printf(" %14lfd KB/sec\n", x / K); \ | ||
97 | else if (x < K * K * K) \ | ||
98 | printf(" %14lf MB/sec\n", x / K / K); \ | ||
99 | else \ | ||
100 | printf(" %14lf GB/sec\n", x / K / K / K); \ | ||
101 | } while (0) | ||
102 | |||
103 | struct bench_mem_info { | ||
104 | const struct function *functions; | ||
105 | u64 (*do_cycles)(const struct function *r, size_t size); | ||
106 | double (*do_gettimeofday)(const struct function *r, size_t size); | ||
107 | const char *const *usage; | ||
108 | }; | ||
109 | |||
110 | static void __bench_mem_function(struct bench_mem_info *info, int r_idx, size_t size, double size_total) | ||
111 | { | ||
112 | const struct function *r = &info->functions[r_idx]; | ||
113 | double result_bps = 0.0; | ||
114 | u64 result_cycles = 0; | ||
115 | |||
116 | printf("# function '%s' (%s)\n", r->name, r->desc); | ||
117 | |||
118 | if (bench_format == BENCH_FORMAT_DEFAULT) | ||
119 | printf("# Copying %s bytes ...\n\n", size_str); | ||
120 | |||
121 | if (use_cycles) { | ||
122 | result_cycles = info->do_cycles(r, size); | ||
123 | } else { | ||
124 | result_bps = info->do_gettimeofday(r, size); | ||
125 | } | ||
126 | |||
127 | switch (bench_format) { | ||
128 | case BENCH_FORMAT_DEFAULT: | ||
129 | if (use_cycles) { | ||
130 | printf(" %14lf cycles/byte\n", (double)result_cycles/size_total); | ||
131 | } else { | ||
132 | print_bps(result_bps); | ||
133 | } | ||
134 | break; | ||
135 | |||
136 | case BENCH_FORMAT_SIMPLE: | ||
137 | if (use_cycles) { | ||
138 | printf("%lf\n", (double)result_cycles/size_total); | ||
139 | } else { | ||
140 | printf("%lf\n", result_bps); | ||
141 | } | ||
142 | break; | ||
143 | |||
144 | default: | ||
145 | BUG_ON(1); | ||
146 | break; | ||
147 | } | ||
148 | } | ||
149 | |||
150 | static int bench_mem_common(int argc, const char **argv, struct bench_mem_info *info) | ||
151 | { | ||
152 | int i; | ||
153 | size_t size; | ||
154 | double size_total; | ||
155 | |||
156 | argc = parse_options(argc, argv, options, info->usage, 0); | ||
157 | |||
158 | if (use_cycles) | ||
159 | init_cycles(); | ||
160 | |||
161 | size = (size_t)perf_atoll((char *)size_str); | ||
162 | size_total = (double)size * nr_loops; | ||
163 | |||
164 | if ((s64)size <= 0) { | ||
165 | fprintf(stderr, "Invalid size:%s\n", size_str); | ||
166 | return 1; | ||
167 | } | ||
168 | |||
169 | if (!strncmp(function_str, "all", 3)) { | ||
170 | for (i = 0; info->functions[i].name; i++) | ||
171 | __bench_mem_function(info, i, size, size_total); | ||
172 | return 0; | ||
173 | } | ||
174 | |||
175 | for (i = 0; info->functions[i].name; i++) { | ||
176 | if (!strcmp(info->functions[i].name, function_str)) | ||
177 | break; | ||
178 | } | ||
179 | if (!info->functions[i].name) { | ||
180 | if (strcmp(function_str, "help") && strcmp(function_str, "h")) | ||
181 | printf("Unknown function: %s\n", function_str); | ||
182 | printf("Available functions:\n"); | ||
183 | for (i = 0; info->functions[i].name; i++) { | ||
184 | printf("\t%s ... %s\n", | ||
185 | info->functions[i].name, info->functions[i].desc); | ||
186 | } | ||
187 | return 1; | ||
188 | } | ||
189 | |||
190 | __bench_mem_function(info, i, size, size_total); | ||
191 | |||
192 | return 0; | ||
193 | } | ||
194 | |||
195 | static void memcpy_alloc_mem(void **dst, void **src, size_t size) | ||
196 | { | ||
197 | *dst = zalloc(size); | ||
198 | if (!*dst) | ||
199 | die("memory allocation failed - maybe size is too large?\n"); | ||
200 | |||
201 | *src = zalloc(size); | ||
202 | if (!*src) | ||
203 | die("memory allocation failed - maybe size is too large?\n"); | ||
204 | |||
205 | /* Make sure to always prefault zero pages even if MMAP_THRESH is crossed: */ | ||
206 | memset(*src, 0, size); | ||
207 | } | ||
208 | |||
209 | static u64 do_memcpy_cycles(const struct function *r, size_t size) | ||
210 | { | ||
211 | u64 cycle_start = 0ULL, cycle_end = 0ULL; | ||
212 | void *src = NULL, *dst = NULL; | ||
213 | memcpy_t fn = r->fn.memcpy; | ||
214 | int i; | ||
215 | |||
216 | memcpy_alloc_mem(&dst, &src, size); | ||
217 | |||
218 | /* | ||
219 | * We prefault the freshly allocated memory range here, | ||
220 | * to not measure page fault overhead: | ||
221 | */ | ||
222 | fn(dst, src, size); | ||
223 | |||
224 | cycle_start = get_cycles(); | ||
225 | for (i = 0; i < nr_loops; ++i) | ||
226 | fn(dst, src, size); | ||
227 | cycle_end = get_cycles(); | ||
228 | |||
229 | free(src); | ||
230 | free(dst); | ||
231 | return cycle_end - cycle_start; | ||
232 | } | ||
233 | |||
234 | static double do_memcpy_gettimeofday(const struct function *r, size_t size) | ||
235 | { | ||
236 | struct timeval tv_start, tv_end, tv_diff; | ||
237 | memcpy_t fn = r->fn.memcpy; | ||
238 | void *src = NULL, *dst = NULL; | ||
239 | int i; | ||
240 | |||
241 | memcpy_alloc_mem(&dst, &src, size); | ||
242 | |||
243 | /* | ||
244 | * We prefault the freshly allocated memory range here, | ||
245 | * to not measure page fault overhead: | ||
246 | */ | ||
247 | fn(dst, src, size); | ||
248 | |||
249 | BUG_ON(gettimeofday(&tv_start, NULL)); | ||
250 | for (i = 0; i < nr_loops; ++i) | ||
251 | fn(dst, src, size); | ||
252 | BUG_ON(gettimeofday(&tv_end, NULL)); | ||
253 | |||
254 | timersub(&tv_end, &tv_start, &tv_diff); | ||
255 | |||
256 | free(src); | ||
257 | free(dst); | ||
258 | |||
259 | return (double)(((double)size * nr_loops) / timeval2double(&tv_diff)); | ||
260 | } | ||
261 | |||
262 | struct function memcpy_functions[] = { | ||
263 | { .name = "default", | ||
264 | .desc = "Default memcpy() provided by glibc", | ||
265 | .fn.memcpy = memcpy }, | ||
266 | |||
267 | #ifdef HAVE_ARCH_X86_64_SUPPORT | ||
268 | # define MEMCPY_FN(_fn, _name, _desc) {.name = _name, .desc = _desc, .fn.memcpy = _fn}, | ||
269 | # include "mem-memcpy-x86-64-asm-def.h" | ||
270 | # undef MEMCPY_FN | ||
271 | #endif | ||
272 | |||
273 | { .name = NULL, } | ||
274 | }; | ||
275 | |||
276 | static const char * const bench_mem_memcpy_usage[] = { | ||
277 | "perf bench mem memcpy <options>", | ||
278 | NULL | ||
279 | }; | ||
280 | |||
281 | int bench_mem_memcpy(int argc, const char **argv, const char *prefix __maybe_unused) | ||
282 | { | ||
283 | struct bench_mem_info info = { | ||
284 | .functions = memcpy_functions, | ||
285 | .do_cycles = do_memcpy_cycles, | ||
286 | .do_gettimeofday = do_memcpy_gettimeofday, | ||
287 | .usage = bench_mem_memcpy_usage, | ||
288 | }; | ||
289 | |||
290 | return bench_mem_common(argc, argv, &info); | ||
291 | } | ||
292 | |||
293 | static void memset_alloc_mem(void **dst, size_t size) | ||
294 | { | ||
295 | *dst = zalloc(size); | ||
296 | if (!*dst) | ||
297 | die("memory allocation failed - maybe size is too large?\n"); | ||
298 | } | ||
299 | |||
300 | static u64 do_memset_cycles(const struct function *r, size_t size) | ||
301 | { | ||
302 | u64 cycle_start = 0ULL, cycle_end = 0ULL; | ||
303 | memset_t fn = r->fn.memset; | ||
304 | void *dst = NULL; | ||
305 | int i; | ||
306 | |||
307 | memset_alloc_mem(&dst, size); | ||
308 | |||
309 | /* | ||
310 | * We prefault the freshly allocated memory range here, | ||
311 | * to not measure page fault overhead: | ||
312 | */ | ||
313 | fn(dst, -1, size); | ||
314 | |||
315 | cycle_start = get_cycles(); | ||
316 | for (i = 0; i < nr_loops; ++i) | ||
317 | fn(dst, i, size); | ||
318 | cycle_end = get_cycles(); | ||
319 | |||
320 | free(dst); | ||
321 | return cycle_end - cycle_start; | ||
322 | } | ||
323 | |||
324 | static double do_memset_gettimeofday(const struct function *r, size_t size) | ||
325 | { | ||
326 | struct timeval tv_start, tv_end, tv_diff; | ||
327 | memset_t fn = r->fn.memset; | ||
328 | void *dst = NULL; | ||
329 | int i; | ||
330 | |||
331 | memset_alloc_mem(&dst, size); | ||
332 | |||
333 | /* | ||
334 | * We prefault the freshly allocated memory range here, | ||
335 | * to not measure page fault overhead: | ||
336 | */ | ||
337 | fn(dst, -1, size); | ||
338 | |||
339 | BUG_ON(gettimeofday(&tv_start, NULL)); | ||
340 | for (i = 0; i < nr_loops; ++i) | ||
341 | fn(dst, i, size); | ||
342 | BUG_ON(gettimeofday(&tv_end, NULL)); | ||
343 | |||
344 | timersub(&tv_end, &tv_start, &tv_diff); | ||
345 | |||
346 | free(dst); | ||
347 | return (double)(((double)size * nr_loops) / timeval2double(&tv_diff)); | ||
348 | } | ||
349 | |||
350 | static const char * const bench_mem_memset_usage[] = { | ||
351 | "perf bench mem memset <options>", | ||
352 | NULL | ||
353 | }; | ||
354 | |||
355 | static const struct function memset_functions[] = { | ||
356 | { .name = "default", | ||
357 | .desc = "Default memset() provided by glibc", | ||
358 | .fn.memset = memset }, | ||
359 | |||
360 | #ifdef HAVE_ARCH_X86_64_SUPPORT | ||
361 | # define MEMSET_FN(_fn, _name, _desc) { .name = _name, .desc = _desc, .fn.memset = _fn }, | ||
362 | # include "mem-memset-x86-64-asm-def.h" | ||
363 | # undef MEMSET_FN | ||
364 | #endif | ||
365 | |||
366 | { .name = NULL, } | ||
367 | }; | ||
368 | |||
369 | int bench_mem_memset(int argc, const char **argv, const char *prefix __maybe_unused) | ||
370 | { | ||
371 | struct bench_mem_info info = { | ||
372 | .functions = memset_functions, | ||
373 | .do_cycles = do_memset_cycles, | ||
374 | .do_gettimeofday = do_memset_gettimeofday, | ||
375 | .usage = bench_mem_memset_usage, | ||
376 | }; | ||
377 | |||
378 | return bench_mem_common(argc, argv, &info); | ||
379 | } | ||
diff --git a/tools/perf/bench/mem-memcpy.c b/tools/perf/bench/mem-memcpy.c deleted file mode 100644 index d3dfb7936dcd..000000000000 --- a/tools/perf/bench/mem-memcpy.c +++ /dev/null | |||
@@ -1,434 +0,0 @@ | |||
1 | /* | ||
2 | * mem-memcpy.c | ||
3 | * | ||
4 | * memcpy: Simple memory copy in various ways | ||
5 | * | ||
6 | * Written by Hitoshi Mitake <mitake@dcl.info.waseda.ac.jp> | ||
7 | */ | ||
8 | |||
9 | #include "../perf.h" | ||
10 | #include "../util/util.h" | ||
11 | #include "../util/parse-options.h" | ||
12 | #include "../util/header.h" | ||
13 | #include "../util/cloexec.h" | ||
14 | #include "bench.h" | ||
15 | #include "mem-memcpy-arch.h" | ||
16 | #include "mem-memset-arch.h" | ||
17 | |||
18 | #include <stdio.h> | ||
19 | #include <stdlib.h> | ||
20 | #include <string.h> | ||
21 | #include <sys/time.h> | ||
22 | #include <errno.h> | ||
23 | |||
24 | #define K 1024 | ||
25 | |||
26 | static const char *length_str = "1MB"; | ||
27 | static const char *routine = "default"; | ||
28 | static int iterations = 1; | ||
29 | static bool use_cycle; | ||
30 | static int cycle_fd; | ||
31 | static bool only_prefault; | ||
32 | static bool no_prefault; | ||
33 | |||
34 | static const struct option options[] = { | ||
35 | OPT_STRING('l', "length", &length_str, "1MB", | ||
36 | "Specify length of memory to copy. " | ||
37 | "Available units: B, KB, MB, GB and TB (upper and lower)"), | ||
38 | OPT_STRING('r', "routine", &routine, "default", | ||
39 | "Specify routine to copy, \"all\" runs all available routines"), | ||
40 | OPT_INTEGER('i', "iterations", &iterations, | ||
41 | "repeat memcpy() invocation this number of times"), | ||
42 | OPT_BOOLEAN('c', "cycle", &use_cycle, | ||
43 | "Use cycles event instead of gettimeofday() for measuring"), | ||
44 | OPT_BOOLEAN('o', "only-prefault", &only_prefault, | ||
45 | "Show only the result with page faults before memcpy()"), | ||
46 | OPT_BOOLEAN('n', "no-prefault", &no_prefault, | ||
47 | "Show only the result without page faults before memcpy()"), | ||
48 | OPT_END() | ||
49 | }; | ||
50 | |||
51 | typedef void *(*memcpy_t)(void *, const void *, size_t); | ||
52 | typedef void *(*memset_t)(void *, int, size_t); | ||
53 | |||
54 | struct routine { | ||
55 | const char *name; | ||
56 | const char *desc; | ||
57 | union { | ||
58 | memcpy_t memcpy; | ||
59 | memset_t memset; | ||
60 | } fn; | ||
61 | }; | ||
62 | |||
63 | struct routine memcpy_routines[] = { | ||
64 | { .name = "default", | ||
65 | .desc = "Default memcpy() provided by glibc", | ||
66 | .fn.memcpy = memcpy }, | ||
67 | #ifdef HAVE_ARCH_X86_64_SUPPORT | ||
68 | |||
69 | #define MEMCPY_FN(_fn, _name, _desc) {.name = _name, .desc = _desc, .fn.memcpy = _fn}, | ||
70 | #include "mem-memcpy-x86-64-asm-def.h" | ||
71 | #undef MEMCPY_FN | ||
72 | |||
73 | #endif | ||
74 | |||
75 | { NULL, | ||
76 | NULL, | ||
77 | {NULL} } | ||
78 | }; | ||
79 | |||
80 | static const char * const bench_mem_memcpy_usage[] = { | ||
81 | "perf bench mem memcpy <options>", | ||
82 | NULL | ||
83 | }; | ||
84 | |||
85 | static struct perf_event_attr cycle_attr = { | ||
86 | .type = PERF_TYPE_HARDWARE, | ||
87 | .config = PERF_COUNT_HW_CPU_CYCLES | ||
88 | }; | ||
89 | |||
90 | static void init_cycle(void) | ||
91 | { | ||
92 | cycle_fd = sys_perf_event_open(&cycle_attr, getpid(), -1, -1, | ||
93 | perf_event_open_cloexec_flag()); | ||
94 | |||
95 | if (cycle_fd < 0 && errno == ENOSYS) | ||
96 | die("No CONFIG_PERF_EVENTS=y kernel support configured?\n"); | ||
97 | else | ||
98 | BUG_ON(cycle_fd < 0); | ||
99 | } | ||
100 | |||
101 | static u64 get_cycle(void) | ||
102 | { | ||
103 | int ret; | ||
104 | u64 clk; | ||
105 | |||
106 | ret = read(cycle_fd, &clk, sizeof(u64)); | ||
107 | BUG_ON(ret != sizeof(u64)); | ||
108 | |||
109 | return clk; | ||
110 | } | ||
111 | |||
112 | static double timeval2double(struct timeval *ts) | ||
113 | { | ||
114 | return (double)ts->tv_sec + | ||
115 | (double)ts->tv_usec / (double)1000000; | ||
116 | } | ||
117 | |||
118 | #define pf (no_prefault ? 0 : 1) | ||
119 | |||
120 | #define print_bps(x) do { \ | ||
121 | if (x < K) \ | ||
122 | printf(" %14lf B/Sec", x); \ | ||
123 | else if (x < K * K) \ | ||
124 | printf(" %14lfd KB/Sec", x / K); \ | ||
125 | else if (x < K * K * K) \ | ||
126 | printf(" %14lf MB/Sec", x / K / K); \ | ||
127 | else \ | ||
128 | printf(" %14lf GB/Sec", x / K / K / K); \ | ||
129 | } while (0) | ||
130 | |||
131 | struct bench_mem_info { | ||
132 | const struct routine *routines; | ||
133 | u64 (*do_cycle)(const struct routine *r, size_t len, bool prefault); | ||
134 | double (*do_gettimeofday)(const struct routine *r, size_t len, bool prefault); | ||
135 | const char *const *usage; | ||
136 | }; | ||
137 | |||
138 | static void __bench_mem_routine(struct bench_mem_info *info, int r_idx, size_t len, double totallen) | ||
139 | { | ||
140 | const struct routine *r = &info->routines[r_idx]; | ||
141 | double result_bps[2]; | ||
142 | u64 result_cycle[2]; | ||
143 | |||
144 | result_cycle[0] = result_cycle[1] = 0ULL; | ||
145 | result_bps[0] = result_bps[1] = 0.0; | ||
146 | |||
147 | printf("Routine %s (%s)\n", r->name, r->desc); | ||
148 | |||
149 | if (bench_format == BENCH_FORMAT_DEFAULT) | ||
150 | printf("# Copying %s Bytes ...\n\n", length_str); | ||
151 | |||
152 | if (!only_prefault && !no_prefault) { | ||
153 | /* show both of results */ | ||
154 | if (use_cycle) { | ||
155 | result_cycle[0] = info->do_cycle(r, len, false); | ||
156 | result_cycle[1] = info->do_cycle(r, len, true); | ||
157 | } else { | ||
158 | result_bps[0] = info->do_gettimeofday(r, len, false); | ||
159 | result_bps[1] = info->do_gettimeofday(r, len, true); | ||
160 | } | ||
161 | } else { | ||
162 | if (use_cycle) | ||
163 | result_cycle[pf] = info->do_cycle(r, len, only_prefault); | ||
164 | else | ||
165 | result_bps[pf] = info->do_gettimeofday(r, len, only_prefault); | ||
166 | } | ||
167 | |||
168 | switch (bench_format) { | ||
169 | case BENCH_FORMAT_DEFAULT: | ||
170 | if (!only_prefault && !no_prefault) { | ||
171 | if (use_cycle) { | ||
172 | printf(" %14lf Cycle/Byte\n", | ||
173 | (double)result_cycle[0] | ||
174 | / totallen); | ||
175 | printf(" %14lf Cycle/Byte (with prefault)\n", | ||
176 | (double)result_cycle[1] | ||
177 | / totallen); | ||
178 | } else { | ||
179 | print_bps(result_bps[0]); | ||
180 | printf("\n"); | ||
181 | print_bps(result_bps[1]); | ||
182 | printf(" (with prefault)\n"); | ||
183 | } | ||
184 | } else { | ||
185 | if (use_cycle) { | ||
186 | printf(" %14lf Cycle/Byte", | ||
187 | (double)result_cycle[pf] | ||
188 | / totallen); | ||
189 | } else | ||
190 | print_bps(result_bps[pf]); | ||
191 | |||
192 | printf("%s\n", only_prefault ? " (with prefault)" : ""); | ||
193 | } | ||
194 | break; | ||
195 | case BENCH_FORMAT_SIMPLE: | ||
196 | if (!only_prefault && !no_prefault) { | ||
197 | if (use_cycle) { | ||
198 | printf("%lf %lf\n", | ||
199 | (double)result_cycle[0] / totallen, | ||
200 | (double)result_cycle[1] / totallen); | ||
201 | } else { | ||
202 | printf("%lf %lf\n", | ||
203 | result_bps[0], result_bps[1]); | ||
204 | } | ||
205 | } else { | ||
206 | if (use_cycle) { | ||
207 | printf("%lf\n", (double)result_cycle[pf] | ||
208 | / totallen); | ||
209 | } else | ||
210 | printf("%lf\n", result_bps[pf]); | ||
211 | } | ||
212 | break; | ||
213 | default: | ||
214 | /* reaching this means there's some disaster: */ | ||
215 | die("unknown format: %d\n", bench_format); | ||
216 | break; | ||
217 | } | ||
218 | } | ||
219 | |||
220 | static int bench_mem_common(int argc, const char **argv, | ||
221 | const char *prefix __maybe_unused, | ||
222 | struct bench_mem_info *info) | ||
223 | { | ||
224 | int i; | ||
225 | size_t len; | ||
226 | double totallen; | ||
227 | |||
228 | argc = parse_options(argc, argv, options, | ||
229 | info->usage, 0); | ||
230 | |||
231 | if (no_prefault && only_prefault) { | ||
232 | fprintf(stderr, "Invalid options: -o and -n are mutually exclusive\n"); | ||
233 | return 1; | ||
234 | } | ||
235 | |||
236 | if (use_cycle) | ||
237 | init_cycle(); | ||
238 | |||
239 | len = (size_t)perf_atoll((char *)length_str); | ||
240 | totallen = (double)len * iterations; | ||
241 | |||
242 | if ((s64)len <= 0) { | ||
243 | fprintf(stderr, "Invalid length:%s\n", length_str); | ||
244 | return 1; | ||
245 | } | ||
246 | |||
247 | /* same to without specifying either of prefault and no-prefault */ | ||
248 | if (only_prefault && no_prefault) | ||
249 | only_prefault = no_prefault = false; | ||
250 | |||
251 | if (!strncmp(routine, "all", 3)) { | ||
252 | for (i = 0; info->routines[i].name; i++) | ||
253 | __bench_mem_routine(info, i, len, totallen); | ||
254 | return 0; | ||
255 | } | ||
256 | |||
257 | for (i = 0; info->routines[i].name; i++) { | ||
258 | if (!strcmp(info->routines[i].name, routine)) | ||
259 | break; | ||
260 | } | ||
261 | if (!info->routines[i].name) { | ||
262 | printf("Unknown routine:%s\n", routine); | ||
263 | printf("Available routines...\n"); | ||
264 | for (i = 0; info->routines[i].name; i++) { | ||
265 | printf("\t%s ... %s\n", | ||
266 | info->routines[i].name, info->routines[i].desc); | ||
267 | } | ||
268 | return 1; | ||
269 | } | ||
270 | |||
271 | __bench_mem_routine(info, i, len, totallen); | ||
272 | |||
273 | return 0; | ||
274 | } | ||
275 | |||
276 | static void memcpy_alloc_mem(void **dst, void **src, size_t length) | ||
277 | { | ||
278 | *dst = zalloc(length); | ||
279 | if (!*dst) | ||
280 | die("memory allocation failed - maybe length is too large?\n"); | ||
281 | |||
282 | *src = zalloc(length); | ||
283 | if (!*src) | ||
284 | die("memory allocation failed - maybe length is too large?\n"); | ||
285 | /* Make sure to always replace the zero pages even if MMAP_THRESH is crossed */ | ||
286 | memset(*src, 0, length); | ||
287 | } | ||
288 | |||
289 | static u64 do_memcpy_cycle(const struct routine *r, size_t len, bool prefault) | ||
290 | { | ||
291 | u64 cycle_start = 0ULL, cycle_end = 0ULL; | ||
292 | void *src = NULL, *dst = NULL; | ||
293 | memcpy_t fn = r->fn.memcpy; | ||
294 | int i; | ||
295 | |||
296 | memcpy_alloc_mem(&dst, &src, len); | ||
297 | |||
298 | if (prefault) | ||
299 | fn(dst, src, len); | ||
300 | |||
301 | cycle_start = get_cycle(); | ||
302 | for (i = 0; i < iterations; ++i) | ||
303 | fn(dst, src, len); | ||
304 | cycle_end = get_cycle(); | ||
305 | |||
306 | free(src); | ||
307 | free(dst); | ||
308 | return cycle_end - cycle_start; | ||
309 | } | ||
310 | |||
311 | static double do_memcpy_gettimeofday(const struct routine *r, size_t len, | ||
312 | bool prefault) | ||
313 | { | ||
314 | struct timeval tv_start, tv_end, tv_diff; | ||
315 | memcpy_t fn = r->fn.memcpy; | ||
316 | void *src = NULL, *dst = NULL; | ||
317 | int i; | ||
318 | |||
319 | memcpy_alloc_mem(&dst, &src, len); | ||
320 | |||
321 | if (prefault) | ||
322 | fn(dst, src, len); | ||
323 | |||
324 | BUG_ON(gettimeofday(&tv_start, NULL)); | ||
325 | for (i = 0; i < iterations; ++i) | ||
326 | fn(dst, src, len); | ||
327 | BUG_ON(gettimeofday(&tv_end, NULL)); | ||
328 | |||
329 | timersub(&tv_end, &tv_start, &tv_diff); | ||
330 | |||
331 | free(src); | ||
332 | free(dst); | ||
333 | return (double)(((double)len * iterations) / timeval2double(&tv_diff)); | ||
334 | } | ||
335 | |||
336 | int bench_mem_memcpy(int argc, const char **argv, | ||
337 | const char *prefix __maybe_unused) | ||
338 | { | ||
339 | struct bench_mem_info info = { | ||
340 | .routines = memcpy_routines, | ||
341 | .do_cycle = do_memcpy_cycle, | ||
342 | .do_gettimeofday = do_memcpy_gettimeofday, | ||
343 | .usage = bench_mem_memcpy_usage, | ||
344 | }; | ||
345 | |||
346 | return bench_mem_common(argc, argv, prefix, &info); | ||
347 | } | ||
348 | |||
349 | static void memset_alloc_mem(void **dst, size_t length) | ||
350 | { | ||
351 | *dst = zalloc(length); | ||
352 | if (!*dst) | ||
353 | die("memory allocation failed - maybe length is too large?\n"); | ||
354 | } | ||
355 | |||
356 | static u64 do_memset_cycle(const struct routine *r, size_t len, bool prefault) | ||
357 | { | ||
358 | u64 cycle_start = 0ULL, cycle_end = 0ULL; | ||
359 | memset_t fn = r->fn.memset; | ||
360 | void *dst = NULL; | ||
361 | int i; | ||
362 | |||
363 | memset_alloc_mem(&dst, len); | ||
364 | |||
365 | if (prefault) | ||
366 | fn(dst, -1, len); | ||
367 | |||
368 | cycle_start = get_cycle(); | ||
369 | for (i = 0; i < iterations; ++i) | ||
370 | fn(dst, i, len); | ||
371 | cycle_end = get_cycle(); | ||
372 | |||
373 | free(dst); | ||
374 | return cycle_end - cycle_start; | ||
375 | } | ||
376 | |||
377 | static double do_memset_gettimeofday(const struct routine *r, size_t len, | ||
378 | bool prefault) | ||
379 | { | ||
380 | struct timeval tv_start, tv_end, tv_diff; | ||
381 | memset_t fn = r->fn.memset; | ||
382 | void *dst = NULL; | ||
383 | int i; | ||
384 | |||
385 | memset_alloc_mem(&dst, len); | ||
386 | |||
387 | if (prefault) | ||
388 | fn(dst, -1, len); | ||
389 | |||
390 | BUG_ON(gettimeofday(&tv_start, NULL)); | ||
391 | for (i = 0; i < iterations; ++i) | ||
392 | fn(dst, i, len); | ||
393 | BUG_ON(gettimeofday(&tv_end, NULL)); | ||
394 | |||
395 | timersub(&tv_end, &tv_start, &tv_diff); | ||
396 | |||
397 | free(dst); | ||
398 | return (double)(((double)len * iterations) / timeval2double(&tv_diff)); | ||
399 | } | ||
400 | |||
401 | static const char * const bench_mem_memset_usage[] = { | ||
402 | "perf bench mem memset <options>", | ||
403 | NULL | ||
404 | }; | ||
405 | |||
406 | static const struct routine memset_routines[] = { | ||
407 | { .name ="default", | ||
408 | .desc = "Default memset() provided by glibc", | ||
409 | .fn.memset = memset }, | ||
410 | #ifdef HAVE_ARCH_X86_64_SUPPORT | ||
411 | |||
412 | #define MEMSET_FN(_fn, _name, _desc) { .name = _name, .desc = _desc, .fn.memset = _fn }, | ||
413 | #include "mem-memset-x86-64-asm-def.h" | ||
414 | #undef MEMSET_FN | ||
415 | |||
416 | #endif | ||
417 | |||
418 | { .name = NULL, | ||
419 | .desc = NULL, | ||
420 | .fn.memset = NULL } | ||
421 | }; | ||
422 | |||
423 | int bench_mem_memset(int argc, const char **argv, | ||
424 | const char *prefix __maybe_unused) | ||
425 | { | ||
426 | struct bench_mem_info info = { | ||
427 | .routines = memset_routines, | ||
428 | .do_cycle = do_memset_cycle, | ||
429 | .do_gettimeofday = do_memset_gettimeofday, | ||
430 | .usage = bench_mem_memset_usage, | ||
431 | }; | ||
432 | |||
433 | return bench_mem_common(argc, argv, prefix, &info); | ||
434 | } | ||
diff --git a/tools/perf/bench/numa.c b/tools/perf/bench/numa.c index 870b7e665a20..492df2752a2d 100644 --- a/tools/perf/bench/numa.c +++ b/tools/perf/bench/numa.c | |||
@@ -164,8 +164,8 @@ static const struct option options[] = { | |||
164 | OPT_STRING('L', "mb_proc_locked", &p0.mb_proc_locked_str,"MB", "process serialized/locked memory access (MBs), <= process_memory"), | 164 | OPT_STRING('L', "mb_proc_locked", &p0.mb_proc_locked_str,"MB", "process serialized/locked memory access (MBs), <= process_memory"), |
165 | OPT_STRING('T', "mb_thread" , &p0.mb_thread_str, "MB", "thread memory (MBs)"), | 165 | OPT_STRING('T', "mb_thread" , &p0.mb_thread_str, "MB", "thread memory (MBs)"), |
166 | 166 | ||
167 | OPT_UINTEGER('l', "nr_loops" , &p0.nr_loops, "max number of loops to run"), | 167 | OPT_UINTEGER('l', "nr_loops" , &p0.nr_loops, "max number of loops to run (default: unlimited)"), |
168 | OPT_UINTEGER('s', "nr_secs" , &p0.nr_secs, "max number of seconds to run"), | 168 | OPT_UINTEGER('s', "nr_secs" , &p0.nr_secs, "max number of seconds to run (default: 5 secs)"), |
169 | OPT_UINTEGER('u', "usleep" , &p0.sleep_usecs, "usecs to sleep per loop iteration"), | 169 | OPT_UINTEGER('u', "usleep" , &p0.sleep_usecs, "usecs to sleep per loop iteration"), |
170 | 170 | ||
171 | OPT_BOOLEAN('R', "data_reads" , &p0.data_reads, "access the data via writes (can be mixed with -W)"), | 171 | OPT_BOOLEAN('R', "data_reads" , &p0.data_reads, "access the data via writes (can be mixed with -W)"), |
diff --git a/tools/perf/bench/sched-messaging.c b/tools/perf/bench/sched-messaging.c index d7f281c2828d..d4ff1b539cfd 100644 --- a/tools/perf/bench/sched-messaging.c +++ b/tools/perf/bench/sched-messaging.c | |||
@@ -33,7 +33,7 @@ | |||
33 | #define DATASIZE 100 | 33 | #define DATASIZE 100 |
34 | 34 | ||
35 | static bool use_pipes = false; | 35 | static bool use_pipes = false; |
36 | static unsigned int loops = 100; | 36 | static unsigned int nr_loops = 100; |
37 | static bool thread_mode = false; | 37 | static bool thread_mode = false; |
38 | static unsigned int num_groups = 10; | 38 | static unsigned int num_groups = 10; |
39 | 39 | ||
@@ -79,7 +79,7 @@ static void ready(int ready_out, int wakefd) | |||
79 | err(EXIT_FAILURE, "poll"); | 79 | err(EXIT_FAILURE, "poll"); |
80 | } | 80 | } |
81 | 81 | ||
82 | /* Sender sprays loops messages down each file descriptor */ | 82 | /* Sender sprays nr_loops messages down each file descriptor */ |
83 | static void *sender(struct sender_context *ctx) | 83 | static void *sender(struct sender_context *ctx) |
84 | { | 84 | { |
85 | char data[DATASIZE]; | 85 | char data[DATASIZE]; |
@@ -88,7 +88,7 @@ static void *sender(struct sender_context *ctx) | |||
88 | ready(ctx->ready_out, ctx->wakefd); | 88 | ready(ctx->ready_out, ctx->wakefd); |
89 | 89 | ||
90 | /* Now pump to every receiver. */ | 90 | /* Now pump to every receiver. */ |
91 | for (i = 0; i < loops; i++) { | 91 | for (i = 0; i < nr_loops; i++) { |
92 | for (j = 0; j < ctx->num_fds; j++) { | 92 | for (j = 0; j < ctx->num_fds; j++) { |
93 | int ret, done = 0; | 93 | int ret, done = 0; |
94 | 94 | ||
@@ -213,7 +213,7 @@ static unsigned int group(pthread_t *pth, | |||
213 | /* Create the pipe between client and server */ | 213 | /* Create the pipe between client and server */ |
214 | fdpair(fds); | 214 | fdpair(fds); |
215 | 215 | ||
216 | ctx->num_packets = num_fds * loops; | 216 | ctx->num_packets = num_fds * nr_loops; |
217 | ctx->in_fds[0] = fds[0]; | 217 | ctx->in_fds[0] = fds[0]; |
218 | ctx->in_fds[1] = fds[1]; | 218 | ctx->in_fds[1] = fds[1]; |
219 | ctx->ready_out = ready_out; | 219 | ctx->ready_out = ready_out; |
@@ -250,7 +250,7 @@ static const struct option options[] = { | |||
250 | OPT_BOOLEAN('t', "thread", &thread_mode, | 250 | OPT_BOOLEAN('t', "thread", &thread_mode, |
251 | "Be multi thread instead of multi process"), | 251 | "Be multi thread instead of multi process"), |
252 | OPT_UINTEGER('g', "group", &num_groups, "Specify number of groups"), | 252 | OPT_UINTEGER('g', "group", &num_groups, "Specify number of groups"), |
253 | OPT_UINTEGER('l', "loop", &loops, "Specify number of loops"), | 253 | OPT_UINTEGER('l', "nr_loops", &nr_loops, "Specify the number of loops to run (default: 100)"), |
254 | OPT_END() | 254 | OPT_END() |
255 | }; | 255 | }; |
256 | 256 | ||
diff --git a/tools/perf/builtin-bench.c b/tools/perf/builtin-bench.c index f67934d46d40..b17aed36ca16 100644 --- a/tools/perf/builtin-bench.c +++ b/tools/perf/builtin-bench.c | |||
@@ -36,7 +36,7 @@ struct bench { | |||
36 | #ifdef HAVE_LIBNUMA_SUPPORT | 36 | #ifdef HAVE_LIBNUMA_SUPPORT |
37 | static struct bench numa_benchmarks[] = { | 37 | static struct bench numa_benchmarks[] = { |
38 | { "mem", "Benchmark for NUMA workloads", bench_numa }, | 38 | { "mem", "Benchmark for NUMA workloads", bench_numa }, |
39 | { "all", "Test all NUMA benchmarks", NULL }, | 39 | { "all", "Run all NUMA benchmarks", NULL }, |
40 | { NULL, NULL, NULL } | 40 | { NULL, NULL, NULL } |
41 | }; | 41 | }; |
42 | #endif | 42 | #endif |
@@ -44,14 +44,14 @@ static struct bench numa_benchmarks[] = { | |||
44 | static struct bench sched_benchmarks[] = { | 44 | static struct bench sched_benchmarks[] = { |
45 | { "messaging", "Benchmark for scheduling and IPC", bench_sched_messaging }, | 45 | { "messaging", "Benchmark for scheduling and IPC", bench_sched_messaging }, |
46 | { "pipe", "Benchmark for pipe() between two processes", bench_sched_pipe }, | 46 | { "pipe", "Benchmark for pipe() between two processes", bench_sched_pipe }, |
47 | { "all", "Test all scheduler benchmarks", NULL }, | 47 | { "all", "Run all scheduler benchmarks", NULL }, |
48 | { NULL, NULL, NULL } | 48 | { NULL, NULL, NULL } |
49 | }; | 49 | }; |
50 | 50 | ||
51 | static struct bench mem_benchmarks[] = { | 51 | static struct bench mem_benchmarks[] = { |
52 | { "memcpy", "Benchmark for memcpy()", bench_mem_memcpy }, | 52 | { "memcpy", "Benchmark for memcpy() functions", bench_mem_memcpy }, |
53 | { "memset", "Benchmark for memset() tests", bench_mem_memset }, | 53 | { "memset", "Benchmark for memset() functions", bench_mem_memset }, |
54 | { "all", "Test all memory benchmarks", NULL }, | 54 | { "all", "Run all memory access benchmarks", NULL }, |
55 | { NULL, NULL, NULL } | 55 | { NULL, NULL, NULL } |
56 | }; | 56 | }; |
57 | 57 | ||
@@ -62,7 +62,7 @@ static struct bench futex_benchmarks[] = { | |||
62 | { "requeue", "Benchmark for futex requeue calls", bench_futex_requeue }, | 62 | { "requeue", "Benchmark for futex requeue calls", bench_futex_requeue }, |
63 | /* pi-futexes */ | 63 | /* pi-futexes */ |
64 | { "lock-pi", "Benchmark for futex lock_pi calls", bench_futex_lock_pi }, | 64 | { "lock-pi", "Benchmark for futex lock_pi calls", bench_futex_lock_pi }, |
65 | { "all", "Test all futex benchmarks", NULL }, | 65 | { "all", "Run all futex benchmarks", NULL }, |
66 | { NULL, NULL, NULL } | 66 | { NULL, NULL, NULL } |
67 | }; | 67 | }; |
68 | 68 | ||
@@ -110,7 +110,7 @@ int bench_format = BENCH_FORMAT_DEFAULT; | |||
110 | unsigned int bench_repeat = 10; /* default number of times to repeat the run */ | 110 | unsigned int bench_repeat = 10; /* default number of times to repeat the run */ |
111 | 111 | ||
112 | static const struct option bench_options[] = { | 112 | static const struct option bench_options[] = { |
113 | OPT_STRING('f', "format", &bench_format_str, "default", "Specify format style"), | 113 | OPT_STRING('f', "format", &bench_format_str, "default|simple", "Specify the output formatting style"), |
114 | OPT_UINTEGER('r', "repeat", &bench_repeat, "Specify amount of times to repeat the run"), | 114 | OPT_UINTEGER('r', "repeat", &bench_repeat, "Specify amount of times to repeat the run"), |
115 | OPT_END() | 115 | OPT_END() |
116 | }; | 116 | }; |
diff --git a/tools/perf/builtin-help.c b/tools/perf/builtin-help.c index 36486eade1ef..a7d588bf3cdd 100644 --- a/tools/perf/builtin-help.c +++ b/tools/perf/builtin-help.c | |||
@@ -463,7 +463,7 @@ int cmd_help(int argc, const char **argv, const char *prefix __maybe_unused) | |||
463 | builtin_help_subcommands, builtin_help_usage, 0); | 463 | builtin_help_subcommands, builtin_help_usage, 0); |
464 | 464 | ||
465 | if (show_all) { | 465 | if (show_all) { |
466 | printf("\n usage: %s\n\n", perf_usage_string); | 466 | printf("\n Usage: %s\n\n", perf_usage_string); |
467 | list_commands("perf commands", &main_cmds, &other_cmds); | 467 | list_commands("perf commands", &main_cmds, &other_cmds); |
468 | printf(" %s\n\n", perf_more_info_string); | 468 | printf(" %s\n\n", perf_more_info_string); |
469 | return 0; | 469 | return 0; |
diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c index 8ce1c6bbfa45..2653c0273b89 100644 --- a/tools/perf/builtin-script.c +++ b/tools/perf/builtin-script.c | |||
@@ -686,7 +686,10 @@ static int process_attr(struct perf_tool *tool, union perf_event *event, | |||
686 | 686 | ||
687 | set_print_ip_opts(&evsel->attr); | 687 | set_print_ip_opts(&evsel->attr); |
688 | 688 | ||
689 | return perf_evsel__check_attr(evsel, scr->session); | 689 | if (evsel->attr.sample_type) |
690 | err = perf_evsel__check_attr(evsel, scr->session); | ||
691 | |||
692 | return err; | ||
690 | } | 693 | } |
691 | 694 | ||
692 | static int process_comm_event(struct perf_tool *tool, | 695 | static int process_comm_event(struct perf_tool *tool, |
diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c index 5ef88f760b12..91e793a76929 100644 --- a/tools/perf/builtin-stat.c +++ b/tools/perf/builtin-stat.c | |||
@@ -434,7 +434,7 @@ static void print_noise_pct(double total, double avg) | |||
434 | 434 | ||
435 | static void print_noise(struct perf_evsel *evsel, double avg) | 435 | static void print_noise(struct perf_evsel *evsel, double avg) |
436 | { | 436 | { |
437 | struct perf_stat *ps; | 437 | struct perf_stat_evsel *ps; |
438 | 438 | ||
439 | if (run_count == 1) | 439 | if (run_count == 1) |
440 | return; | 440 | return; |
@@ -479,6 +479,7 @@ static void aggr_printout(struct perf_evsel *evsel, int id, int nr) | |||
479 | csv_sep); | 479 | csv_sep); |
480 | break; | 480 | break; |
481 | case AGGR_GLOBAL: | 481 | case AGGR_GLOBAL: |
482 | case AGGR_UNSET: | ||
482 | default: | 483 | default: |
483 | break; | 484 | break; |
484 | } | 485 | } |
@@ -671,7 +672,7 @@ static void print_aggr_thread(struct perf_evsel *counter, char *prefix) | |||
671 | static void print_counter_aggr(struct perf_evsel *counter, char *prefix) | 672 | static void print_counter_aggr(struct perf_evsel *counter, char *prefix) |
672 | { | 673 | { |
673 | FILE *output = stat_config.output; | 674 | FILE *output = stat_config.output; |
674 | struct perf_stat *ps = counter->priv; | 675 | struct perf_stat_evsel *ps = counter->priv; |
675 | double avg = avg_stats(&ps->res_stats[0]); | 676 | double avg = avg_stats(&ps->res_stats[0]); |
676 | int scaled = counter->counts->scaled; | 677 | int scaled = counter->counts->scaled; |
677 | double uval; | 678 | double uval; |
@@ -799,6 +800,8 @@ static void print_interval(char *prefix, struct timespec *ts) | |||
799 | case AGGR_GLOBAL: | 800 | case AGGR_GLOBAL: |
800 | default: | 801 | default: |
801 | fprintf(output, "# time counts %*s events\n", unit_width, "unit"); | 802 | fprintf(output, "# time counts %*s events\n", unit_width, "unit"); |
803 | case AGGR_UNSET: | ||
804 | break; | ||
802 | } | 805 | } |
803 | } | 806 | } |
804 | 807 | ||
@@ -880,6 +883,7 @@ static void print_counters(struct timespec *ts, int argc, const char **argv) | |||
880 | evlist__for_each(evsel_list, counter) | 883 | evlist__for_each(evsel_list, counter) |
881 | print_counter(counter, prefix); | 884 | print_counter(counter, prefix); |
882 | break; | 885 | break; |
886 | case AGGR_UNSET: | ||
883 | default: | 887 | default: |
884 | break; | 888 | break; |
885 | } | 889 | } |
@@ -940,6 +944,16 @@ static int stat__set_big_num(const struct option *opt __maybe_unused, | |||
940 | return 0; | 944 | return 0; |
941 | } | 945 | } |
942 | 946 | ||
947 | static int perf_stat__get_socket(struct cpu_map *map, int cpu) | ||
948 | { | ||
949 | return cpu_map__get_socket(map, cpu, NULL); | ||
950 | } | ||
951 | |||
952 | static int perf_stat__get_core(struct cpu_map *map, int cpu) | ||
953 | { | ||
954 | return cpu_map__get_core(map, cpu, NULL); | ||
955 | } | ||
956 | |||
943 | static int perf_stat_init_aggr_mode(void) | 957 | static int perf_stat_init_aggr_mode(void) |
944 | { | 958 | { |
945 | switch (stat_config.aggr_mode) { | 959 | switch (stat_config.aggr_mode) { |
@@ -948,18 +962,19 @@ static int perf_stat_init_aggr_mode(void) | |||
948 | perror("cannot build socket map"); | 962 | perror("cannot build socket map"); |
949 | return -1; | 963 | return -1; |
950 | } | 964 | } |
951 | aggr_get_id = cpu_map__get_socket; | 965 | aggr_get_id = perf_stat__get_socket; |
952 | break; | 966 | break; |
953 | case AGGR_CORE: | 967 | case AGGR_CORE: |
954 | if (cpu_map__build_core_map(evsel_list->cpus, &aggr_map)) { | 968 | if (cpu_map__build_core_map(evsel_list->cpus, &aggr_map)) { |
955 | perror("cannot build core map"); | 969 | perror("cannot build core map"); |
956 | return -1; | 970 | return -1; |
957 | } | 971 | } |
958 | aggr_get_id = cpu_map__get_core; | 972 | aggr_get_id = perf_stat__get_core; |
959 | break; | 973 | break; |
960 | case AGGR_NONE: | 974 | case AGGR_NONE: |
961 | case AGGR_GLOBAL: | 975 | case AGGR_GLOBAL: |
962 | case AGGR_THREAD: | 976 | case AGGR_THREAD: |
977 | case AGGR_UNSET: | ||
963 | default: | 978 | default: |
964 | break; | 979 | break; |
965 | } | 980 | } |
diff --git a/tools/perf/tests/openat-syscall-all-cpus.c b/tools/perf/tests/openat-syscall-all-cpus.c index 9e104a2e973d..2006485a2859 100644 --- a/tools/perf/tests/openat-syscall-all-cpus.c +++ b/tools/perf/tests/openat-syscall-all-cpus.c | |||
@@ -34,7 +34,7 @@ int test__openat_syscall_event_on_all_cpus(void) | |||
34 | evsel = perf_evsel__newtp("syscalls", "sys_enter_openat"); | 34 | evsel = perf_evsel__newtp("syscalls", "sys_enter_openat"); |
35 | if (IS_ERR(evsel)) { | 35 | if (IS_ERR(evsel)) { |
36 | tracing_path__strerror_open_tp(errno, errbuf, sizeof(errbuf), "syscalls", "sys_enter_openat"); | 36 | tracing_path__strerror_open_tp(errno, errbuf, sizeof(errbuf), "syscalls", "sys_enter_openat"); |
37 | pr_err("%s\n", errbuf); | 37 | pr_debug("%s\n", errbuf); |
38 | goto out_thread_map_delete; | 38 | goto out_thread_map_delete; |
39 | } | 39 | } |
40 | 40 | ||
diff --git a/tools/perf/tests/openat-syscall-tp-fields.c b/tools/perf/tests/openat-syscall-tp-fields.c index 473d3869727e..5e811cd8f1c3 100644 --- a/tools/perf/tests/openat-syscall-tp-fields.c +++ b/tools/perf/tests/openat-syscall-tp-fields.c | |||
@@ -89,7 +89,7 @@ int test__syscall_openat_tp_fields(void) | |||
89 | 89 | ||
90 | err = perf_evsel__parse_sample(evsel, event, &sample); | 90 | err = perf_evsel__parse_sample(evsel, event, &sample); |
91 | if (err) { | 91 | if (err) { |
92 | pr_err("Can't parse sample, err = %d\n", err); | 92 | pr_debug("Can't parse sample, err = %d\n", err); |
93 | goto out_delete_evlist; | 93 | goto out_delete_evlist; |
94 | } | 94 | } |
95 | 95 | ||
diff --git a/tools/perf/tests/openat-syscall.c b/tools/perf/tests/openat-syscall.c index 7b1db8306098..033b54797b8a 100644 --- a/tools/perf/tests/openat-syscall.c +++ b/tools/perf/tests/openat-syscall.c | |||
@@ -22,7 +22,7 @@ int test__openat_syscall_event(void) | |||
22 | evsel = perf_evsel__newtp("syscalls", "sys_enter_openat"); | 22 | evsel = perf_evsel__newtp("syscalls", "sys_enter_openat"); |
23 | if (IS_ERR(evsel)) { | 23 | if (IS_ERR(evsel)) { |
24 | tracing_path__strerror_open_tp(errno, errbuf, sizeof(errbuf), "syscalls", "sys_enter_openat"); | 24 | tracing_path__strerror_open_tp(errno, errbuf, sizeof(errbuf), "syscalls", "sys_enter_openat"); |
25 | pr_err("%s\n", errbuf); | 25 | pr_debug("%s\n", errbuf); |
26 | goto out_thread_map_delete; | 26 | goto out_thread_map_delete; |
27 | } | 27 | } |
28 | 28 | ||
diff --git a/tools/perf/tests/parse-events.c b/tools/perf/tests/parse-events.c index 0648b84a9171..636d7b42d844 100644 --- a/tools/perf/tests/parse-events.c +++ b/tools/perf/tests/parse-events.c | |||
@@ -5,6 +5,7 @@ | |||
5 | #include <api/fs/fs.h> | 5 | #include <api/fs/fs.h> |
6 | #include "tests.h" | 6 | #include "tests.h" |
7 | #include "debug.h" | 7 | #include "debug.h" |
8 | #include "util.h" | ||
8 | #include <linux/hw_breakpoint.h> | 9 | #include <linux/hw_breakpoint.h> |
9 | #include <api/fs/fs.h> | 10 | #include <api/fs/fs.h> |
10 | 11 | ||
@@ -1753,6 +1754,17 @@ static int test_pmu_events(void) | |||
1753 | return ret; | 1754 | return ret; |
1754 | } | 1755 | } |
1755 | 1756 | ||
1757 | static void debug_warn(const char *warn, va_list params) | ||
1758 | { | ||
1759 | char msg[1024]; | ||
1760 | |||
1761 | if (!verbose) | ||
1762 | return; | ||
1763 | |||
1764 | vsnprintf(msg, sizeof(msg), warn, params); | ||
1765 | fprintf(stderr, " Warning: %s\n", msg); | ||
1766 | } | ||
1767 | |||
1756 | int test__parse_events(void) | 1768 | int test__parse_events(void) |
1757 | { | 1769 | { |
1758 | int ret1, ret2 = 0; | 1770 | int ret1, ret2 = 0; |
@@ -1764,6 +1776,8 @@ do { \ | |||
1764 | ret2 = ret1; \ | 1776 | ret2 = ret1; \ |
1765 | } while (0) | 1777 | } while (0) |
1766 | 1778 | ||
1779 | set_warning_routine(debug_warn); | ||
1780 | |||
1767 | TEST_EVENTS(test__events); | 1781 | TEST_EVENTS(test__events); |
1768 | 1782 | ||
1769 | if (test_pmu()) | 1783 | if (test_pmu()) |
diff --git a/tools/perf/tests/topology.c b/tools/perf/tests/topology.c index c3aff53a976a..f5bb096c3bd9 100644 --- a/tools/perf/tests/topology.c +++ b/tools/perf/tests/topology.c | |||
@@ -73,10 +73,10 @@ static int check_cpu_topology(char *path, struct cpu_map *map) | |||
73 | 73 | ||
74 | for (i = 0; i < map->nr; i++) { | 74 | for (i = 0; i < map->nr; i++) { |
75 | TEST_ASSERT_VAL("Core ID doesn't match", | 75 | TEST_ASSERT_VAL("Core ID doesn't match", |
76 | (session->header.env.cpu[map->map[i]].core_id == (cpu_map__get_core(map, i) & 0xffff))); | 76 | (session->header.env.cpu[map->map[i]].core_id == (cpu_map__get_core(map, i, NULL) & 0xffff))); |
77 | 77 | ||
78 | TEST_ASSERT_VAL("Socket ID doesn't match", | 78 | TEST_ASSERT_VAL("Socket ID doesn't match", |
79 | (session->header.env.cpu[map->map[i]].socket_id == cpu_map__get_socket(map, i))); | 79 | (session->header.env.cpu[map->map[i]].socket_id == cpu_map__get_socket(map, i, NULL))); |
80 | } | 80 | } |
81 | 81 | ||
82 | perf_session__delete(session); | 82 | perf_session__delete(session); |
diff --git a/tools/perf/util/cpumap.c b/tools/perf/util/cpumap.c index c51c29fd0732..b36845347f01 100644 --- a/tools/perf/util/cpumap.c +++ b/tools/perf/util/cpumap.c | |||
@@ -241,7 +241,7 @@ int cpu_map__get_socket_id(int cpu) | |||
241 | return ret ?: value; | 241 | return ret ?: value; |
242 | } | 242 | } |
243 | 243 | ||
244 | int cpu_map__get_socket(struct cpu_map *map, int idx) | 244 | int cpu_map__get_socket(struct cpu_map *map, int idx, void *data __maybe_unused) |
245 | { | 245 | { |
246 | int cpu; | 246 | int cpu; |
247 | 247 | ||
@@ -258,8 +258,9 @@ static int cmp_ids(const void *a, const void *b) | |||
258 | return *(int *)a - *(int *)b; | 258 | return *(int *)a - *(int *)b; |
259 | } | 259 | } |
260 | 260 | ||
261 | static int cpu_map__build_map(struct cpu_map *cpus, struct cpu_map **res, | 261 | int cpu_map__build_map(struct cpu_map *cpus, struct cpu_map **res, |
262 | int (*f)(struct cpu_map *map, int cpu)) | 262 | int (*f)(struct cpu_map *map, int cpu, void *data), |
263 | void *data) | ||
263 | { | 264 | { |
264 | struct cpu_map *c; | 265 | struct cpu_map *c; |
265 | int nr = cpus->nr; | 266 | int nr = cpus->nr; |
@@ -271,7 +272,7 @@ static int cpu_map__build_map(struct cpu_map *cpus, struct cpu_map **res, | |||
271 | return -1; | 272 | return -1; |
272 | 273 | ||
273 | for (cpu = 0; cpu < nr; cpu++) { | 274 | for (cpu = 0; cpu < nr; cpu++) { |
274 | s1 = f(cpus, cpu); | 275 | s1 = f(cpus, cpu, data); |
275 | for (s2 = 0; s2 < c->nr; s2++) { | 276 | for (s2 = 0; s2 < c->nr; s2++) { |
276 | if (s1 == c->map[s2]) | 277 | if (s1 == c->map[s2]) |
277 | break; | 278 | break; |
@@ -295,7 +296,7 @@ int cpu_map__get_core_id(int cpu) | |||
295 | return ret ?: value; | 296 | return ret ?: value; |
296 | } | 297 | } |
297 | 298 | ||
298 | int cpu_map__get_core(struct cpu_map *map, int idx) | 299 | int cpu_map__get_core(struct cpu_map *map, int idx, void *data) |
299 | { | 300 | { |
300 | int cpu, s; | 301 | int cpu, s; |
301 | 302 | ||
@@ -306,7 +307,7 @@ int cpu_map__get_core(struct cpu_map *map, int idx) | |||
306 | 307 | ||
307 | cpu = cpu_map__get_core_id(cpu); | 308 | cpu = cpu_map__get_core_id(cpu); |
308 | 309 | ||
309 | s = cpu_map__get_socket(map, idx); | 310 | s = cpu_map__get_socket(map, idx, data); |
310 | if (s == -1) | 311 | if (s == -1) |
311 | return -1; | 312 | return -1; |
312 | 313 | ||
@@ -321,12 +322,12 @@ int cpu_map__get_core(struct cpu_map *map, int idx) | |||
321 | 322 | ||
322 | int cpu_map__build_socket_map(struct cpu_map *cpus, struct cpu_map **sockp) | 323 | int cpu_map__build_socket_map(struct cpu_map *cpus, struct cpu_map **sockp) |
323 | { | 324 | { |
324 | return cpu_map__build_map(cpus, sockp, cpu_map__get_socket); | 325 | return cpu_map__build_map(cpus, sockp, cpu_map__get_socket, NULL); |
325 | } | 326 | } |
326 | 327 | ||
327 | int cpu_map__build_core_map(struct cpu_map *cpus, struct cpu_map **corep) | 328 | int cpu_map__build_core_map(struct cpu_map *cpus, struct cpu_map **corep) |
328 | { | 329 | { |
329 | return cpu_map__build_map(cpus, corep, cpu_map__get_core); | 330 | return cpu_map__build_map(cpus, corep, cpu_map__get_core, NULL); |
330 | } | 331 | } |
331 | 332 | ||
332 | /* setup simple routines to easily access node numbers given a cpu number */ | 333 | /* setup simple routines to easily access node numbers given a cpu number */ |
diff --git a/tools/perf/util/cpumap.h b/tools/perf/util/cpumap.h index 8982d538da83..f1bcd2cfa164 100644 --- a/tools/perf/util/cpumap.h +++ b/tools/perf/util/cpumap.h | |||
@@ -19,9 +19,9 @@ struct cpu_map *cpu_map__dummy_new(void); | |||
19 | struct cpu_map *cpu_map__read(FILE *file); | 19 | struct cpu_map *cpu_map__read(FILE *file); |
20 | size_t cpu_map__fprintf(struct cpu_map *map, FILE *fp); | 20 | size_t cpu_map__fprintf(struct cpu_map *map, FILE *fp); |
21 | int cpu_map__get_socket_id(int cpu); | 21 | int cpu_map__get_socket_id(int cpu); |
22 | int cpu_map__get_socket(struct cpu_map *map, int idx); | 22 | int cpu_map__get_socket(struct cpu_map *map, int idx, void *data); |
23 | int cpu_map__get_core_id(int cpu); | 23 | int cpu_map__get_core_id(int cpu); |
24 | int cpu_map__get_core(struct cpu_map *map, int idx); | 24 | int cpu_map__get_core(struct cpu_map *map, int idx, void *data); |
25 | int cpu_map__build_socket_map(struct cpu_map *cpus, struct cpu_map **sockp); | 25 | int cpu_map__build_socket_map(struct cpu_map *cpus, struct cpu_map **sockp); |
26 | int cpu_map__build_core_map(struct cpu_map *cpus, struct cpu_map **corep); | 26 | int cpu_map__build_core_map(struct cpu_map *cpus, struct cpu_map **corep); |
27 | 27 | ||
@@ -87,4 +87,7 @@ static inline int cpu__get_node(int cpu) | |||
87 | return cpunode_map[cpu]; | 87 | return cpunode_map[cpu]; |
88 | } | 88 | } |
89 | 89 | ||
90 | int cpu_map__build_map(struct cpu_map *cpus, struct cpu_map **res, | ||
91 | int (*f)(struct cpu_map *map, int cpu, void *data), | ||
92 | void *data); | ||
90 | #endif /* __PERF_CPUMAP_H */ | 93 | #endif /* __PERF_CPUMAP_H */ |
diff --git a/tools/perf/util/parse-options.c b/tools/perf/util/parse-options.c index 9a38b05f0273..8aa7922397a9 100644 --- a/tools/perf/util/parse-options.c +++ b/tools/perf/util/parse-options.c | |||
@@ -648,7 +648,7 @@ int usage_with_options_internal(const char * const *usagestr, | |||
648 | if (!usagestr) | 648 | if (!usagestr) |
649 | return PARSE_OPT_HELP; | 649 | return PARSE_OPT_HELP; |
650 | 650 | ||
651 | fprintf(stderr, "\n usage: %s\n", *usagestr++); | 651 | fprintf(stderr, "\n Usage: %s\n", *usagestr++); |
652 | while (*usagestr && **usagestr) | 652 | while (*usagestr && **usagestr) |
653 | fprintf(stderr, " or: %s\n", *usagestr++); | 653 | fprintf(stderr, " or: %s\n", *usagestr++); |
654 | while (*usagestr) { | 654 | while (*usagestr) { |
@@ -684,7 +684,7 @@ int parse_options_usage(const char * const *usagestr, | |||
684 | if (!usagestr) | 684 | if (!usagestr) |
685 | goto opt; | 685 | goto opt; |
686 | 686 | ||
687 | fprintf(stderr, "\n usage: %s\n", *usagestr++); | 687 | fprintf(stderr, "\n Usage: %s\n", *usagestr++); |
688 | while (*usagestr && **usagestr) | 688 | while (*usagestr && **usagestr) |
689 | fprintf(stderr, " or: %s\n", *usagestr++); | 689 | fprintf(stderr, " or: %s\n", *usagestr++); |
690 | while (*usagestr) { | 690 | while (*usagestr) { |
diff --git a/tools/perf/util/stat.c b/tools/perf/util/stat.c index 2d065d065b67..2d9d8306dbd3 100644 --- a/tools/perf/util/stat.c +++ b/tools/perf/util/stat.c | |||
@@ -67,7 +67,7 @@ double rel_stddev_stats(double stddev, double avg) | |||
67 | bool __perf_evsel_stat__is(struct perf_evsel *evsel, | 67 | bool __perf_evsel_stat__is(struct perf_evsel *evsel, |
68 | enum perf_stat_evsel_id id) | 68 | enum perf_stat_evsel_id id) |
69 | { | 69 | { |
70 | struct perf_stat *ps = evsel->priv; | 70 | struct perf_stat_evsel *ps = evsel->priv; |
71 | 71 | ||
72 | return ps->id == id; | 72 | return ps->id == id; |
73 | } | 73 | } |
@@ -84,7 +84,7 @@ static const char *id_str[PERF_STAT_EVSEL_ID__MAX] = { | |||
84 | 84 | ||
85 | void perf_stat_evsel_id_init(struct perf_evsel *evsel) | 85 | void perf_stat_evsel_id_init(struct perf_evsel *evsel) |
86 | { | 86 | { |
87 | struct perf_stat *ps = evsel->priv; | 87 | struct perf_stat_evsel *ps = evsel->priv; |
88 | int i; | 88 | int i; |
89 | 89 | ||
90 | /* ps->id is 0 hence PERF_STAT_EVSEL_ID__NONE by default */ | 90 | /* ps->id is 0 hence PERF_STAT_EVSEL_ID__NONE by default */ |
@@ -100,7 +100,7 @@ void perf_stat_evsel_id_init(struct perf_evsel *evsel) | |||
100 | void perf_evsel__reset_stat_priv(struct perf_evsel *evsel) | 100 | void perf_evsel__reset_stat_priv(struct perf_evsel *evsel) |
101 | { | 101 | { |
102 | int i; | 102 | int i; |
103 | struct perf_stat *ps = evsel->priv; | 103 | struct perf_stat_evsel *ps = evsel->priv; |
104 | 104 | ||
105 | for (i = 0; i < 3; i++) | 105 | for (i = 0; i < 3; i++) |
106 | init_stats(&ps->res_stats[i]); | 106 | init_stats(&ps->res_stats[i]); |
@@ -110,7 +110,7 @@ void perf_evsel__reset_stat_priv(struct perf_evsel *evsel) | |||
110 | 110 | ||
111 | int perf_evsel__alloc_stat_priv(struct perf_evsel *evsel) | 111 | int perf_evsel__alloc_stat_priv(struct perf_evsel *evsel) |
112 | { | 112 | { |
113 | evsel->priv = zalloc(sizeof(struct perf_stat)); | 113 | evsel->priv = zalloc(sizeof(struct perf_stat_evsel)); |
114 | if (evsel->priv == NULL) | 114 | if (evsel->priv == NULL) |
115 | return -ENOMEM; | 115 | return -ENOMEM; |
116 | perf_evsel__reset_stat_priv(evsel); | 116 | perf_evsel__reset_stat_priv(evsel); |
@@ -230,7 +230,7 @@ static int check_per_pkg(struct perf_evsel *counter, | |||
230 | if (!(vals->run && vals->ena)) | 230 | if (!(vals->run && vals->ena)) |
231 | return 0; | 231 | return 0; |
232 | 232 | ||
233 | s = cpu_map__get_socket(cpus, cpu); | 233 | s = cpu_map__get_socket(cpus, cpu, NULL); |
234 | if (s < 0) | 234 | if (s < 0) |
235 | return -1; | 235 | return -1; |
236 | 236 | ||
@@ -272,6 +272,7 @@ process_counter_values(struct perf_stat_config *config, struct perf_evsel *evsel | |||
272 | aggr->ena += count->ena; | 272 | aggr->ena += count->ena; |
273 | aggr->run += count->run; | 273 | aggr->run += count->run; |
274 | } | 274 | } |
275 | case AGGR_UNSET: | ||
275 | default: | 276 | default: |
276 | break; | 277 | break; |
277 | } | 278 | } |
@@ -304,7 +305,7 @@ int perf_stat_process_counter(struct perf_stat_config *config, | |||
304 | struct perf_evsel *counter) | 305 | struct perf_evsel *counter) |
305 | { | 306 | { |
306 | struct perf_counts_values *aggr = &counter->counts->aggr; | 307 | struct perf_counts_values *aggr = &counter->counts->aggr; |
307 | struct perf_stat *ps = counter->priv; | 308 | struct perf_stat_evsel *ps = counter->priv; |
308 | u64 *count = counter->counts->aggr.values; | 309 | u64 *count = counter->counts->aggr.values; |
309 | int i, ret; | 310 | int i, ret; |
310 | 311 | ||
diff --git a/tools/perf/util/stat.h b/tools/perf/util/stat.h index 62448c8175d3..da1d11c4f8c1 100644 --- a/tools/perf/util/stat.h +++ b/tools/perf/util/stat.h | |||
@@ -20,7 +20,7 @@ enum perf_stat_evsel_id { | |||
20 | PERF_STAT_EVSEL_ID__MAX, | 20 | PERF_STAT_EVSEL_ID__MAX, |
21 | }; | 21 | }; |
22 | 22 | ||
23 | struct perf_stat { | 23 | struct perf_stat_evsel { |
24 | struct stats res_stats[3]; | 24 | struct stats res_stats[3]; |
25 | enum perf_stat_evsel_id id; | 25 | enum perf_stat_evsel_id id; |
26 | }; | 26 | }; |
@@ -31,6 +31,7 @@ enum aggr_mode { | |||
31 | AGGR_SOCKET, | 31 | AGGR_SOCKET, |
32 | AGGR_CORE, | 32 | AGGR_CORE, |
33 | AGGR_THREAD, | 33 | AGGR_THREAD, |
34 | AGGR_UNSET, | ||
34 | }; | 35 | }; |
35 | 36 | ||
36 | struct perf_stat_config { | 37 | struct perf_stat_config { |
diff --git a/tools/perf/util/usage.c b/tools/perf/util/usage.c index 4007aca8e0ca..6adfa18cdd4e 100644 --- a/tools/perf/util/usage.c +++ b/tools/perf/util/usage.c | |||
@@ -50,6 +50,11 @@ void set_die_routine(void (*routine)(const char *err, va_list params) NORETURN) | |||
50 | die_routine = routine; | 50 | die_routine = routine; |
51 | } | 51 | } |
52 | 52 | ||
53 | void set_warning_routine(void (*routine)(const char *err, va_list params)) | ||
54 | { | ||
55 | warn_routine = routine; | ||
56 | } | ||
57 | |||
53 | void usage(const char *err) | 58 | void usage(const char *err) |
54 | { | 59 | { |
55 | usage_routine(err); | 60 | usage_routine(err); |
diff --git a/tools/perf/util/util.h b/tools/perf/util/util.h index 3d5b01e8978f..4cfb913aa9e0 100644 --- a/tools/perf/util/util.h +++ b/tools/perf/util/util.h | |||
@@ -145,6 +145,7 @@ extern void warning(const char *err, ...) __attribute__((format (printf, 1, 2))) | |||
145 | 145 | ||
146 | 146 | ||
147 | extern void set_die_routine(void (*routine)(const char *err, va_list params) NORETURN); | 147 | extern void set_die_routine(void (*routine)(const char *err, va_list params) NORETURN); |
148 | extern void set_warning_routine(void (*routine)(const char *err, va_list params)); | ||
148 | 149 | ||
149 | extern int prefixcmp(const char *str, const char *prefix); | 150 | extern int prefixcmp(const char *str, const char *prefix); |
150 | extern void set_buildid_dir(const char *dir); | 151 | extern void set_buildid_dir(const char *dir); |