diff options
| author | Ingo Molnar <mingo@kernel.org> | 2014-12-12 03:09:52 -0500 |
|---|---|---|
| committer | Ingo Molnar <mingo@kernel.org> | 2014-12-12 03:09:52 -0500 |
| commit | 41e950c033b7df997d4b38653efe6554be9b96a7 (patch) | |
| tree | b8ffe779d47c768a9652ce9166f4878cee41f2ca /tools/perf | |
| parent | 3459f0d78ffe27a1b341c22eb158b622eaaea3fc (diff) | |
| parent | e09b18d4907992d3d615b215c1abf585721b2810 (diff) | |
Merge tag 'perf-core-for-mingo' of git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux into perf/urgent
Pull perf/core improvements and fixes from Arnaldo Carvalho de Melo:
User visible changes:
- Mark events as (x86 only) in help output for 'perf kvm stat live" (Alexander Yarygin)
- Provide a better explanation when mmap fails in 'trace' (Arnaldo Carvalho de Melo)
- Add --buildid-dir option to set cache directory, i.e. use:
$ perf --buildid-dir /path/to/dir tool --tool-options
(Jiri Olsa)
- Fix memcpy/memset 'perf bench' output (Rabin Vicent)
- Fix 'perf test' attr tests size values to cope with machine state on
interrupt ABI changes (Jiri Olsa)
- Fixup callchain type parameter handling error message (Kan Liang)
Infrastructure changes and cleanups:
- calloc/xcalloc: Fix argument order (Arjun Sreedharan)
- Move filename__read_int from tools/perf/ to tools/lib, add sysctl__read_int
there and use it in place of ad-hoc copies (Arnaldo Carvalho de Melo)
- Use single strcmp call instead of two (Jiri Olsa)
- Remove extra debugdir variables in 'perf buildid-cache' (Jiri Olsa)
- Fix -a segfault related to kcore handling in 'perf buildid-cache' (Jiri Olsa)
- Move cpumode resolve code to add_callchain_ip (Kan Liang)
- Merge memset into memcpy 'perf bench' (Rabin Vincent)
- Change print format from %lu to %PRIu64 in the hists browser (Tom Huynh)
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.txt | 4 | ||||
| -rw-r--r-- | tools/perf/Makefile.perf | 1 | ||||
| -rw-r--r-- | tools/perf/bench/mem-memcpy.c | 286 | ||||
| -rw-r--r-- | tools/perf/bench/mem-memset.c | 304 | ||||
| -rw-r--r-- | tools/perf/builtin-buildid-cache.c | 13 | ||||
| -rw-r--r-- | tools/perf/builtin-kvm.c | 3 | ||||
| -rw-r--r-- | tools/perf/builtin-trace.c | 12 | ||||
| -rw-r--r-- | tools/perf/perf.c | 14 | ||||
| -rw-r--r-- | tools/perf/tests/attr/base-record | 2 | ||||
| -rw-r--r-- | tools/perf/tests/attr/base-stat | 2 | ||||
| -rw-r--r-- | tools/perf/ui/browsers/hists.c | 2 | ||||
| -rw-r--r-- | tools/perf/ui/hist.c | 4 | ||||
| -rw-r--r-- | tools/perf/util/build-id.c | 9 | ||||
| -rw-r--r-- | tools/perf/util/callchain.c | 2 | ||||
| -rw-r--r-- | tools/perf/util/config.c | 10 | ||||
| -rw-r--r-- | tools/perf/util/evlist.c | 23 | ||||
| -rw-r--r-- | tools/perf/util/evlist.h | 1 | ||||
| -rw-r--r-- | tools/perf/util/machine.c | 72 | ||||
| -rw-r--r-- | tools/perf/util/record.c | 11 | ||||
| -rw-r--r-- | tools/perf/util/util.c | 26 | ||||
| -rw-r--r-- | tools/perf/util/util.h | 3 |
21 files changed, 308 insertions, 496 deletions
diff --git a/tools/perf/Documentation/perf.txt b/tools/perf/Documentation/perf.txt index d240bb2e5b22..1e8e400b4493 100644 --- a/tools/perf/Documentation/perf.txt +++ b/tools/perf/Documentation/perf.txt | |||
| @@ -18,6 +18,10 @@ OPTIONS | |||
| 18 | --debug verbose # sets verbose = 1 | 18 | --debug verbose # sets verbose = 1 |
| 19 | --debug verbose=2 # sets verbose = 2 | 19 | --debug verbose=2 # sets verbose = 2 |
| 20 | 20 | ||
| 21 | --buildid-dir:: | ||
| 22 | Setup buildid cache directory. It has higher priority than | ||
| 23 | buildid.dir config file option. | ||
| 24 | |||
| 21 | DESCRIPTION | 25 | DESCRIPTION |
| 22 | ----------- | 26 | ----------- |
| 23 | Performance counters for Linux are a new kernel-based subsystem | 27 | Performance counters for Linux are a new kernel-based subsystem |
diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf index 478efa9b2364..763e68fb5767 100644 --- a/tools/perf/Makefile.perf +++ b/tools/perf/Makefile.perf | |||
| @@ -458,7 +458,6 @@ BUILTIN_OBJS += $(OUTPUT)bench/mem-memcpy-x86-64-asm.o | |||
| 458 | BUILTIN_OBJS += $(OUTPUT)bench/mem-memset-x86-64-asm.o | 458 | BUILTIN_OBJS += $(OUTPUT)bench/mem-memset-x86-64-asm.o |
| 459 | endif | 459 | endif |
| 460 | BUILTIN_OBJS += $(OUTPUT)bench/mem-memcpy.o | 460 | BUILTIN_OBJS += $(OUTPUT)bench/mem-memcpy.o |
| 461 | BUILTIN_OBJS += $(OUTPUT)bench/mem-memset.o | ||
| 462 | BUILTIN_OBJS += $(OUTPUT)bench/futex-hash.o | 461 | BUILTIN_OBJS += $(OUTPUT)bench/futex-hash.o |
| 463 | BUILTIN_OBJS += $(OUTPUT)bench/futex-wake.o | 462 | BUILTIN_OBJS += $(OUTPUT)bench/futex-wake.o |
| 464 | BUILTIN_OBJS += $(OUTPUT)bench/futex-requeue.o | 463 | BUILTIN_OBJS += $(OUTPUT)bench/futex-requeue.o |
diff --git a/tools/perf/bench/mem-memcpy.c b/tools/perf/bench/mem-memcpy.c index 2465141b554b..6c14afe8c1b1 100644 --- a/tools/perf/bench/mem-memcpy.c +++ b/tools/perf/bench/mem-memcpy.c | |||
| @@ -13,6 +13,7 @@ | |||
| 13 | #include "../util/cloexec.h" | 13 | #include "../util/cloexec.h" |
| 14 | #include "bench.h" | 14 | #include "bench.h" |
| 15 | #include "mem-memcpy-arch.h" | 15 | #include "mem-memcpy-arch.h" |
| 16 | #include "mem-memset-arch.h" | ||
| 16 | 17 | ||
| 17 | #include <stdio.h> | 18 | #include <stdio.h> |
| 18 | #include <stdlib.h> | 19 | #include <stdlib.h> |
| @@ -48,20 +49,24 @@ static const struct option options[] = { | |||
| 48 | }; | 49 | }; |
| 49 | 50 | ||
| 50 | typedef void *(*memcpy_t)(void *, const void *, size_t); | 51 | typedef void *(*memcpy_t)(void *, const void *, size_t); |
| 52 | typedef void *(*memset_t)(void *, int, size_t); | ||
| 51 | 53 | ||
| 52 | struct routine { | 54 | struct routine { |
| 53 | const char *name; | 55 | const char *name; |
| 54 | const char *desc; | 56 | const char *desc; |
| 55 | memcpy_t fn; | 57 | union { |
| 58 | memcpy_t memcpy; | ||
| 59 | memset_t memset; | ||
| 60 | } fn; | ||
| 56 | }; | 61 | }; |
| 57 | 62 | ||
| 58 | struct routine routines[] = { | 63 | struct routine memcpy_routines[] = { |
| 59 | { "default", | 64 | { .name = "default", |
| 60 | "Default memcpy() provided by glibc", | 65 | .desc = "Default memcpy() provided by glibc", |
| 61 | memcpy }, | 66 | .fn.memcpy = memcpy }, |
| 62 | #ifdef HAVE_ARCH_X86_64_SUPPORT | 67 | #ifdef HAVE_ARCH_X86_64_SUPPORT |
| 63 | 68 | ||
| 64 | #define MEMCPY_FN(fn, name, desc) { name, desc, fn }, | 69 | #define MEMCPY_FN(_fn, _name, _desc) {.name = _name, .desc = _desc, .fn.memcpy = _fn}, |
| 65 | #include "mem-memcpy-x86-64-asm-def.h" | 70 | #include "mem-memcpy-x86-64-asm-def.h" |
| 66 | #undef MEMCPY_FN | 71 | #undef MEMCPY_FN |
| 67 | 72 | ||
| @@ -69,7 +74,7 @@ struct routine routines[] = { | |||
| 69 | 74 | ||
| 70 | { NULL, | 75 | { NULL, |
| 71 | NULL, | 76 | NULL, |
| 72 | NULL } | 77 | {NULL} } |
| 73 | }; | 78 | }; |
| 74 | 79 | ||
| 75 | static const char * const bench_mem_memcpy_usage[] = { | 80 | static const char * const bench_mem_memcpy_usage[] = { |
| @@ -110,63 +115,6 @@ static double timeval2double(struct timeval *ts) | |||
| 110 | (double)ts->tv_usec / (double)1000000; | 115 | (double)ts->tv_usec / (double)1000000; |
| 111 | } | 116 | } |
| 112 | 117 | ||
| 113 | static void alloc_mem(void **dst, void **src, size_t length) | ||
| 114 | { | ||
| 115 | *dst = zalloc(length); | ||
| 116 | if (!*dst) | ||
| 117 | die("memory allocation failed - maybe length is too large?\n"); | ||
| 118 | |||
| 119 | *src = zalloc(length); | ||
| 120 | if (!*src) | ||
| 121 | die("memory allocation failed - maybe length is too large?\n"); | ||
| 122 | /* Make sure to always replace the zero pages even if MMAP_THRESH is crossed */ | ||
| 123 | memset(*src, 0, length); | ||
| 124 | } | ||
| 125 | |||
| 126 | static u64 do_memcpy_cycle(memcpy_t fn, size_t len, bool prefault) | ||
| 127 | { | ||
| 128 | u64 cycle_start = 0ULL, cycle_end = 0ULL; | ||
| 129 | void *src = NULL, *dst = NULL; | ||
| 130 | int i; | ||
| 131 | |||
| 132 | alloc_mem(&src, &dst, len); | ||
| 133 | |||
| 134 | if (prefault) | ||
| 135 | fn(dst, src, len); | ||
| 136 | |||
| 137 | cycle_start = get_cycle(); | ||
| 138 | for (i = 0; i < iterations; ++i) | ||
| 139 | fn(dst, src, len); | ||
| 140 | cycle_end = get_cycle(); | ||
| 141 | |||
| 142 | free(src); | ||
| 143 | free(dst); | ||
| 144 | return cycle_end - cycle_start; | ||
| 145 | } | ||
| 146 | |||
| 147 | static double do_memcpy_gettimeofday(memcpy_t fn, size_t len, bool prefault) | ||
| 148 | { | ||
| 149 | struct timeval tv_start, tv_end, tv_diff; | ||
| 150 | void *src = NULL, *dst = NULL; | ||
| 151 | int i; | ||
| 152 | |||
| 153 | alloc_mem(&src, &dst, len); | ||
| 154 | |||
| 155 | if (prefault) | ||
| 156 | fn(dst, src, len); | ||
| 157 | |||
| 158 | BUG_ON(gettimeofday(&tv_start, NULL)); | ||
| 159 | for (i = 0; i < iterations; ++i) | ||
| 160 | fn(dst, src, len); | ||
| 161 | BUG_ON(gettimeofday(&tv_end, NULL)); | ||
| 162 | |||
| 163 | timersub(&tv_end, &tv_start, &tv_diff); | ||
| 164 | |||
| 165 | free(src); | ||
| 166 | free(dst); | ||
| 167 | return (double)((double)len / timeval2double(&tv_diff)); | ||
| 168 | } | ||
| 169 | |||
| 170 | #define pf (no_prefault ? 0 : 1) | 118 | #define pf (no_prefault ? 0 : 1) |
| 171 | 119 | ||
| 172 | #define print_bps(x) do { \ | 120 | #define print_bps(x) do { \ |
| @@ -180,16 +128,25 @@ static double do_memcpy_gettimeofday(memcpy_t fn, size_t len, bool prefault) | |||
| 180 | printf(" %14lf GB/Sec", x / K / K / K); \ | 128 | printf(" %14lf GB/Sec", x / K / K / K); \ |
| 181 | } while (0) | 129 | } while (0) |
| 182 | 130 | ||
| 183 | int bench_mem_memcpy(int argc, const char **argv, | 131 | struct bench_mem_info { |
| 184 | const char *prefix __maybe_unused) | 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 int bench_mem_common(int argc, const char **argv, | ||
| 139 | const char *prefix __maybe_unused, | ||
| 140 | struct bench_mem_info *info) | ||
| 185 | { | 141 | { |
| 186 | int i; | 142 | int i; |
| 187 | size_t len; | 143 | size_t len; |
| 144 | double totallen; | ||
| 188 | double result_bps[2]; | 145 | double result_bps[2]; |
| 189 | u64 result_cycle[2]; | 146 | u64 result_cycle[2]; |
| 190 | 147 | ||
| 191 | argc = parse_options(argc, argv, options, | 148 | argc = parse_options(argc, argv, options, |
| 192 | bench_mem_memcpy_usage, 0); | 149 | info->usage, 0); |
| 193 | 150 | ||
| 194 | if (no_prefault && only_prefault) { | 151 | if (no_prefault && only_prefault) { |
| 195 | fprintf(stderr, "Invalid options: -o and -n are mutually exclusive\n"); | 152 | fprintf(stderr, "Invalid options: -o and -n are mutually exclusive\n"); |
| @@ -200,6 +157,7 @@ int bench_mem_memcpy(int argc, const char **argv, | |||
| 200 | init_cycle(); | 157 | init_cycle(); |
| 201 | 158 | ||
| 202 | len = (size_t)perf_atoll((char *)length_str); | 159 | len = (size_t)perf_atoll((char *)length_str); |
| 160 | totallen = (double)len * iterations; | ||
| 203 | 161 | ||
| 204 | result_cycle[0] = result_cycle[1] = 0ULL; | 162 | result_cycle[0] = result_cycle[1] = 0ULL; |
| 205 | result_bps[0] = result_bps[1] = 0.0; | 163 | result_bps[0] = result_bps[1] = 0.0; |
| @@ -213,16 +171,16 @@ int bench_mem_memcpy(int argc, const char **argv, | |||
| 213 | if (only_prefault && no_prefault) | 171 | if (only_prefault && no_prefault) |
| 214 | only_prefault = no_prefault = false; | 172 | only_prefault = no_prefault = false; |
| 215 | 173 | ||
| 216 | for (i = 0; routines[i].name; i++) { | 174 | for (i = 0; info->routines[i].name; i++) { |
| 217 | if (!strcmp(routines[i].name, routine)) | 175 | if (!strcmp(info->routines[i].name, routine)) |
| 218 | break; | 176 | break; |
| 219 | } | 177 | } |
| 220 | if (!routines[i].name) { | 178 | if (!info->routines[i].name) { |
| 221 | printf("Unknown routine:%s\n", routine); | 179 | printf("Unknown routine:%s\n", routine); |
| 222 | printf("Available routines...\n"); | 180 | printf("Available routines...\n"); |
| 223 | for (i = 0; routines[i].name; i++) { | 181 | for (i = 0; info->routines[i].name; i++) { |
| 224 | printf("\t%s ... %s\n", | 182 | printf("\t%s ... %s\n", |
| 225 | routines[i].name, routines[i].desc); | 183 | info->routines[i].name, info->routines[i].desc); |
| 226 | } | 184 | } |
| 227 | return 1; | 185 | return 1; |
| 228 | } | 186 | } |
| @@ -234,25 +192,25 @@ int bench_mem_memcpy(int argc, const char **argv, | |||
| 234 | /* show both of results */ | 192 | /* show both of results */ |
| 235 | if (use_cycle) { | 193 | if (use_cycle) { |
| 236 | result_cycle[0] = | 194 | result_cycle[0] = |
| 237 | do_memcpy_cycle(routines[i].fn, len, false); | 195 | info->do_cycle(&info->routines[i], len, false); |
| 238 | result_cycle[1] = | 196 | result_cycle[1] = |
| 239 | do_memcpy_cycle(routines[i].fn, len, true); | 197 | info->do_cycle(&info->routines[i], len, true); |
| 240 | } else { | 198 | } else { |
| 241 | result_bps[0] = | 199 | result_bps[0] = |
| 242 | do_memcpy_gettimeofday(routines[i].fn, | 200 | info->do_gettimeofday(&info->routines[i], |
| 243 | len, false); | 201 | len, false); |
| 244 | result_bps[1] = | 202 | result_bps[1] = |
| 245 | do_memcpy_gettimeofday(routines[i].fn, | 203 | info->do_gettimeofday(&info->routines[i], |
| 246 | len, true); | 204 | len, true); |
| 247 | } | 205 | } |
| 248 | } else { | 206 | } else { |
| 249 | if (use_cycle) { | 207 | if (use_cycle) { |
| 250 | result_cycle[pf] = | 208 | result_cycle[pf] = |
| 251 | do_memcpy_cycle(routines[i].fn, | 209 | info->do_cycle(&info->routines[i], |
| 252 | len, only_prefault); | 210 | len, only_prefault); |
| 253 | } else { | 211 | } else { |
| 254 | result_bps[pf] = | 212 | result_bps[pf] = |
| 255 | do_memcpy_gettimeofday(routines[i].fn, | 213 | info->do_gettimeofday(&info->routines[i], |
| 256 | len, only_prefault); | 214 | len, only_prefault); |
| 257 | } | 215 | } |
| 258 | } | 216 | } |
| @@ -263,10 +221,10 @@ int bench_mem_memcpy(int argc, const char **argv, | |||
| 263 | if (use_cycle) { | 221 | if (use_cycle) { |
| 264 | printf(" %14lf Cycle/Byte\n", | 222 | printf(" %14lf Cycle/Byte\n", |
| 265 | (double)result_cycle[0] | 223 | (double)result_cycle[0] |
| 266 | / (double)len); | 224 | / totallen); |
| 267 | printf(" %14lf Cycle/Byte (with prefault)\n", | 225 | printf(" %14lf Cycle/Byte (with prefault)\n", |
| 268 | (double)result_cycle[1] | 226 | (double)result_cycle[1] |
| 269 | / (double)len); | 227 | / totallen); |
| 270 | } else { | 228 | } else { |
| 271 | print_bps(result_bps[0]); | 229 | print_bps(result_bps[0]); |
| 272 | printf("\n"); | 230 | printf("\n"); |
| @@ -277,7 +235,7 @@ int bench_mem_memcpy(int argc, const char **argv, | |||
| 277 | if (use_cycle) { | 235 | if (use_cycle) { |
| 278 | printf(" %14lf Cycle/Byte", | 236 | printf(" %14lf Cycle/Byte", |
| 279 | (double)result_cycle[pf] | 237 | (double)result_cycle[pf] |
| 280 | / (double)len); | 238 | / totallen); |
| 281 | } else | 239 | } else |
| 282 | print_bps(result_bps[pf]); | 240 | print_bps(result_bps[pf]); |
| 283 | 241 | ||
| @@ -288,8 +246,8 @@ int bench_mem_memcpy(int argc, const char **argv, | |||
| 288 | if (!only_prefault && !no_prefault) { | 246 | if (!only_prefault && !no_prefault) { |
| 289 | if (use_cycle) { | 247 | if (use_cycle) { |
| 290 | printf("%lf %lf\n", | 248 | printf("%lf %lf\n", |
| 291 | (double)result_cycle[0] / (double)len, | 249 | (double)result_cycle[0] / totallen, |
| 292 | (double)result_cycle[1] / (double)len); | 250 | (double)result_cycle[1] / totallen); |
| 293 | } else { | 251 | } else { |
| 294 | printf("%lf %lf\n", | 252 | printf("%lf %lf\n", |
| 295 | result_bps[0], result_bps[1]); | 253 | result_bps[0], result_bps[1]); |
| @@ -297,7 +255,7 @@ int bench_mem_memcpy(int argc, const char **argv, | |||
| 297 | } else { | 255 | } else { |
| 298 | if (use_cycle) { | 256 | if (use_cycle) { |
| 299 | printf("%lf\n", (double)result_cycle[pf] | 257 | printf("%lf\n", (double)result_cycle[pf] |
| 300 | / (double)len); | 258 | / totallen); |
| 301 | } else | 259 | } else |
| 302 | printf("%lf\n", result_bps[pf]); | 260 | printf("%lf\n", result_bps[pf]); |
| 303 | } | 261 | } |
| @@ -310,3 +268,163 @@ int bench_mem_memcpy(int argc, const char **argv, | |||
| 310 | 268 | ||
| 311 | return 0; | 269 | return 0; |
| 312 | } | 270 | } |
| 271 | |||
| 272 | static void memcpy_alloc_mem(void **dst, void **src, size_t length) | ||
| 273 | { | ||
| 274 | *dst = zalloc(length); | ||
| 275 | if (!*dst) | ||
| 276 | die("memory allocation failed - maybe length is too large?\n"); | ||
| 277 | |||
| 278 | *src = zalloc(length); | ||
| 279 | if (!*src) | ||
| 280 | die("memory allocation failed - maybe length is too large?\n"); | ||
| 281 | /* Make sure to always replace the zero pages even if MMAP_THRESH is crossed */ | ||
| 282 | memset(*src, 0, length); | ||
| 283 | } | ||
| 284 | |||
| 285 | static u64 do_memcpy_cycle(const struct routine *r, size_t len, bool prefault) | ||
| 286 | { | ||
| 287 | u64 cycle_start = 0ULL, cycle_end = 0ULL; | ||
| 288 | void *src = NULL, *dst = NULL; | ||
| 289 | memcpy_t fn = r->fn.memcpy; | ||
| 290 | int i; | ||
| 291 | |||
| 292 | memcpy_alloc_mem(&src, &dst, len); | ||
| 293 | |||
| 294 | if (prefault) | ||
| 295 | fn(dst, src, len); | ||
| 296 | |||
| 297 | cycle_start = get_cycle(); | ||
| 298 | for (i = 0; i < iterations; ++i) | ||
| 299 | fn(dst, src, len); | ||
| 300 | cycle_end = get_cycle(); | ||
| 301 | |||
| 302 | free(src); | ||
| 303 | free(dst); | ||
| 304 | return cycle_end - cycle_start; | ||
| 305 | } | ||
| 306 | |||
| 307 | static double do_memcpy_gettimeofday(const struct routine *r, size_t len, | ||
| 308 | bool prefault) | ||
| 309 | { | ||
| 310 | struct timeval tv_start, tv_end, tv_diff; | ||
| 311 | memcpy_t fn = r->fn.memcpy; | ||
| 312 | void *src = NULL, *dst = NULL; | ||
| 313 | int i; | ||
| 314 | |||
| 315 | memcpy_alloc_mem(&src, &dst, len); | ||
| 316 | |||
| 317 | if (prefault) | ||
| 318 | fn(dst, src, len); | ||
| 319 | |||
| 320 | BUG_ON(gettimeofday(&tv_start, NULL)); | ||
| 321 | for (i = 0; i < iterations; ++i) | ||
| 322 | fn(dst, src, len); | ||
| 323 | BUG_ON(gettimeofday(&tv_end, NULL)); | ||
| 324 | |||
| 325 | timersub(&tv_end, &tv_start, &tv_diff); | ||
| 326 | |||
| 327 | free(src); | ||
| 328 | free(dst); | ||
| 329 | return (double)(((double)len * iterations) / timeval2double(&tv_diff)); | ||
| 330 | } | ||
| 331 | |||
| 332 | int bench_mem_memcpy(int argc, const char **argv, | ||
| 333 | const char *prefix __maybe_unused) | ||
| 334 | { | ||
| 335 | struct bench_mem_info info = { | ||
| 336 | .routines = memcpy_routines, | ||
| 337 | .do_cycle = do_memcpy_cycle, | ||
| 338 | .do_gettimeofday = do_memcpy_gettimeofday, | ||
| 339 | .usage = bench_mem_memcpy_usage, | ||
| 340 | }; | ||
| 341 | |||
| 342 | return bench_mem_common(argc, argv, prefix, &info); | ||
| 343 | } | ||
| 344 | |||
| 345 | static void memset_alloc_mem(void **dst, size_t length) | ||
| 346 | { | ||
| 347 | *dst = zalloc(length); | ||
| 348 | if (!*dst) | ||
| 349 | die("memory allocation failed - maybe length is too large?\n"); | ||
| 350 | } | ||
| 351 | |||
| 352 | static u64 do_memset_cycle(const struct routine *r, size_t len, bool prefault) | ||
| 353 | { | ||
| 354 | u64 cycle_start = 0ULL, cycle_end = 0ULL; | ||
| 355 | memset_t fn = r->fn.memset; | ||
| 356 | void *dst = NULL; | ||
| 357 | int i; | ||
| 358 | |||
| 359 | memset_alloc_mem(&dst, len); | ||
| 360 | |||
| 361 | if (prefault) | ||
| 362 | fn(dst, -1, len); | ||
| 363 | |||
| 364 | cycle_start = get_cycle(); | ||
| 365 | for (i = 0; i < iterations; ++i) | ||
| 366 | fn(dst, i, len); | ||
| 367 | cycle_end = get_cycle(); | ||
| 368 | |||
| 369 | free(dst); | ||
| 370 | return cycle_end - cycle_start; | ||
| 371 | } | ||
| 372 | |||
| 373 | static double do_memset_gettimeofday(const struct routine *r, size_t len, | ||
| 374 | bool prefault) | ||
| 375 | { | ||
| 376 | struct timeval tv_start, tv_end, tv_diff; | ||
| 377 | memset_t fn = r->fn.memset; | ||
| 378 | void *dst = NULL; | ||
| 379 | int i; | ||
| 380 | |||
| 381 | memset_alloc_mem(&dst, len); | ||
| 382 | |||
| 383 | if (prefault) | ||
| 384 | fn(dst, -1, len); | ||
| 385 | |||
| 386 | BUG_ON(gettimeofday(&tv_start, NULL)); | ||
| 387 | for (i = 0; i < iterations; ++i) | ||
| 388 | fn(dst, i, len); | ||
| 389 | BUG_ON(gettimeofday(&tv_end, NULL)); | ||
| 390 | |||
| 391 | timersub(&tv_end, &tv_start, &tv_diff); | ||
| 392 | |||
| 393 | free(dst); | ||
| 394 | return (double)(((double)len * iterations) / timeval2double(&tv_diff)); | ||
| 395 | } | ||
| 396 | |||
| 397 | static const char * const bench_mem_memset_usage[] = { | ||
| 398 | "perf bench mem memset <options>", | ||
| 399 | NULL | ||
| 400 | }; | ||
| 401 | |||
| 402 | static const struct routine memset_routines[] = { | ||
| 403 | { .name ="default", | ||
| 404 | .desc = "Default memset() provided by glibc", | ||
| 405 | .fn.memset = memset }, | ||
| 406 | #ifdef HAVE_ARCH_X86_64_SUPPORT | ||
| 407 | |||
| 408 | #define MEMSET_FN(_fn, _name, _desc) { .name = _name, .desc = _desc, .fn.memset = _fn }, | ||
| 409 | #include "mem-memset-x86-64-asm-def.h" | ||
| 410 | #undef MEMSET_FN | ||
| 411 | |||
| 412 | #endif | ||
| 413 | |||
| 414 | { .name = NULL, | ||
| 415 | .desc = NULL, | ||
| 416 | .fn.memset = NULL } | ||
| 417 | }; | ||
| 418 | |||
| 419 | int bench_mem_memset(int argc, const char **argv, | ||
| 420 | const char *prefix __maybe_unused) | ||
| 421 | { | ||
| 422 | struct bench_mem_info info = { | ||
| 423 | .routines = memset_routines, | ||
| 424 | .do_cycle = do_memset_cycle, | ||
| 425 | .do_gettimeofday = do_memset_gettimeofday, | ||
| 426 | .usage = bench_mem_memset_usage, | ||
| 427 | }; | ||
| 428 | |||
| 429 | return bench_mem_common(argc, argv, prefix, &info); | ||
| 430 | } | ||
diff --git a/tools/perf/bench/mem-memset.c b/tools/perf/bench/mem-memset.c deleted file mode 100644 index 75fc3e65fb2a..000000000000 --- a/tools/perf/bench/mem-memset.c +++ /dev/null | |||
| @@ -1,304 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * mem-memset.c | ||
| 3 | * | ||
| 4 | * memset: Simple memory set in various ways | ||
| 5 | * | ||
| 6 | * Trivial clone of mem-memcpy.c. | ||
| 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-memset-arch.h" | ||
| 16 | |||
| 17 | #include <stdio.h> | ||
| 18 | #include <stdlib.h> | ||
| 19 | #include <string.h> | ||
| 20 | #include <sys/time.h> | ||
| 21 | #include <errno.h> | ||
| 22 | |||
| 23 | #define K 1024 | ||
| 24 | |||
| 25 | static const char *length_str = "1MB"; | ||
| 26 | static const char *routine = "default"; | ||
| 27 | static int iterations = 1; | ||
| 28 | static bool use_cycle; | ||
| 29 | static int cycle_fd; | ||
| 30 | static bool only_prefault; | ||
| 31 | static bool no_prefault; | ||
| 32 | |||
| 33 | static const struct option options[] = { | ||
| 34 | OPT_STRING('l', "length", &length_str, "1MB", | ||
| 35 | "Specify length of memory to set. " | ||
| 36 | "Available units: B, KB, MB, GB and TB (upper and lower)"), | ||
| 37 | OPT_STRING('r', "routine", &routine, "default", | ||
| 38 | "Specify routine to set"), | ||
| 39 | OPT_INTEGER('i', "iterations", &iterations, | ||
| 40 | "repeat memset() invocation this number of times"), | ||
| 41 | OPT_BOOLEAN('c', "cycle", &use_cycle, | ||
| 42 | "Use cycles event instead of gettimeofday() for measuring"), | ||
| 43 | OPT_BOOLEAN('o', "only-prefault", &only_prefault, | ||
| 44 | "Show only the result with page faults before memset()"), | ||
| 45 | OPT_BOOLEAN('n', "no-prefault", &no_prefault, | ||
| 46 | "Show only the result without page faults before memset()"), | ||
| 47 | OPT_END() | ||
| 48 | }; | ||
| 49 | |||
| 50 | typedef void *(*memset_t)(void *, int, size_t); | ||
| 51 | |||
| 52 | struct routine { | ||
| 53 | const char *name; | ||
| 54 | const char *desc; | ||
| 55 | memset_t fn; | ||
| 56 | }; | ||
| 57 | |||
| 58 | static const struct routine routines[] = { | ||
| 59 | { "default", | ||
| 60 | "Default memset() provided by glibc", | ||
| 61 | memset }, | ||
| 62 | #ifdef HAVE_ARCH_X86_64_SUPPORT | ||
| 63 | |||
| 64 | #define MEMSET_FN(fn, name, desc) { name, desc, fn }, | ||
| 65 | #include "mem-memset-x86-64-asm-def.h" | ||
| 66 | #undef MEMSET_FN | ||
| 67 | |||
| 68 | #endif | ||
| 69 | |||
| 70 | { NULL, | ||
| 71 | NULL, | ||
| 72 | NULL } | ||
| 73 | }; | ||
| 74 | |||
| 75 | static const char * const bench_mem_memset_usage[] = { | ||
| 76 | "perf bench mem memset <options>", | ||
| 77 | NULL | ||
| 78 | }; | ||
| 79 | |||
| 80 | static struct perf_event_attr cycle_attr = { | ||
| 81 | .type = PERF_TYPE_HARDWARE, | ||
| 82 | .config = PERF_COUNT_HW_CPU_CYCLES | ||
| 83 | }; | ||
| 84 | |||
| 85 | static void init_cycle(void) | ||
| 86 | { | ||
| 87 | cycle_fd = sys_perf_event_open(&cycle_attr, getpid(), -1, -1, | ||
| 88 | perf_event_open_cloexec_flag()); | ||
| 89 | |||
| 90 | if (cycle_fd < 0 && errno == ENOSYS) | ||
| 91 | die("No CONFIG_PERF_EVENTS=y kernel support configured?\n"); | ||
| 92 | else | ||
| 93 | BUG_ON(cycle_fd < 0); | ||
| 94 | } | ||
| 95 | |||
| 96 | static u64 get_cycle(void) | ||
| 97 | { | ||
| 98 | int ret; | ||
| 99 | u64 clk; | ||
| 100 | |||
| 101 | ret = read(cycle_fd, &clk, sizeof(u64)); | ||
| 102 | BUG_ON(ret != sizeof(u64)); | ||
| 103 | |||
| 104 | return clk; | ||
| 105 | } | ||
| 106 | |||
| 107 | static double timeval2double(struct timeval *ts) | ||
| 108 | { | ||
| 109 | return (double)ts->tv_sec + | ||
| 110 | (double)ts->tv_usec / (double)1000000; | ||
| 111 | } | ||
| 112 | |||
| 113 | static void alloc_mem(void **dst, size_t length) | ||
| 114 | { | ||
| 115 | *dst = zalloc(length); | ||
| 116 | if (!*dst) | ||
| 117 | die("memory allocation failed - maybe length is too large?\n"); | ||
| 118 | } | ||
| 119 | |||
| 120 | static u64 do_memset_cycle(memset_t fn, size_t len, bool prefault) | ||
| 121 | { | ||
| 122 | u64 cycle_start = 0ULL, cycle_end = 0ULL; | ||
| 123 | void *dst = NULL; | ||
| 124 | int i; | ||
| 125 | |||
| 126 | alloc_mem(&dst, len); | ||
| 127 | |||
| 128 | if (prefault) | ||
| 129 | fn(dst, -1, len); | ||
| 130 | |||
| 131 | cycle_start = get_cycle(); | ||
| 132 | for (i = 0; i < iterations; ++i) | ||
| 133 | fn(dst, i, len); | ||
| 134 | cycle_end = get_cycle(); | ||
| 135 | |||
| 136 | free(dst); | ||
| 137 | return cycle_end - cycle_start; | ||
| 138 | } | ||
| 139 | |||
| 140 | static double do_memset_gettimeofday(memset_t fn, size_t len, bool prefault) | ||
| 141 | { | ||
| 142 | struct timeval tv_start, tv_end, tv_diff; | ||
| 143 | void *dst = NULL; | ||
| 144 | int i; | ||
| 145 | |||
| 146 | alloc_mem(&dst, len); | ||
| 147 | |||
| 148 | if (prefault) | ||
| 149 | fn(dst, -1, len); | ||
| 150 | |||
| 151 | BUG_ON(gettimeofday(&tv_start, NULL)); | ||
| 152 | for (i = 0; i < iterations; ++i) | ||
| 153 | fn(dst, i, len); | ||
| 154 | BUG_ON(gettimeofday(&tv_end, NULL)); | ||
| 155 | |||
| 156 | timersub(&tv_end, &tv_start, &tv_diff); | ||
| 157 | |||
| 158 | free(dst); | ||
| 159 | return (double)((double)len / timeval2double(&tv_diff)); | ||
| 160 | } | ||
| 161 | |||
| 162 | #define pf (no_prefault ? 0 : 1) | ||
| 163 | |||
| 164 | #define print_bps(x) do { \ | ||
| 165 | if (x < K) \ | ||
| 166 | printf(" %14lf B/Sec", x); \ | ||
| 167 | else if (x < K * K) \ | ||
| 168 | printf(" %14lfd KB/Sec", x / K); \ | ||
| 169 | else if (x < K * K * K) \ | ||
| 170 | printf(" %14lf MB/Sec", x / K / K); \ | ||
| 171 | else \ | ||
| 172 | printf(" %14lf GB/Sec", x / K / K / K); \ | ||
| 173 | } while (0) | ||
| 174 | |||
| 175 | int bench_mem_memset(int argc, const char **argv, | ||
| 176 | const char *prefix __maybe_unused) | ||
| 177 | { | ||
| 178 | int i; | ||
| 179 | size_t len; | ||
| 180 | double result_bps[2]; | ||
| 181 | u64 result_cycle[2]; | ||
| 182 | |||
| 183 | argc = parse_options(argc, argv, options, | ||
| 184 | bench_mem_memset_usage, 0); | ||
| 185 | |||
| 186 | if (no_prefault && only_prefault) { | ||
| 187 | fprintf(stderr, "Invalid options: -o and -n are mutually exclusive\n"); | ||
| 188 | return 1; | ||
| 189 | } | ||
| 190 | |||
| 191 | if (use_cycle) | ||
| 192 | init_cycle(); | ||
| 193 | |||
| 194 | len = (size_t)perf_atoll((char *)length_str); | ||
| 195 | |||
| 196 | result_cycle[0] = result_cycle[1] = 0ULL; | ||
| 197 | result_bps[0] = result_bps[1] = 0.0; | ||
| 198 | |||
| 199 | if ((s64)len <= 0) { | ||
| 200 | fprintf(stderr, "Invalid length:%s\n", length_str); | ||
| 201 | return 1; | ||
| 202 | } | ||
| 203 | |||
| 204 | /* same to without specifying either of prefault and no-prefault */ | ||
| 205 | if (only_prefault && no_prefault) | ||
| 206 | only_prefault = no_prefault = false; | ||
| 207 | |||
| 208 | for (i = 0; routines[i].name; i++) { | ||
| 209 | if (!strcmp(routines[i].name, routine)) | ||
| 210 | break; | ||
| 211 | } | ||
| 212 | if (!routines[i].name) { | ||
| 213 | printf("Unknown routine:%s\n", routine); | ||
| 214 | printf("Available routines...\n"); | ||
| 215 | for (i = 0; routines[i].name; i++) { | ||
| 216 | printf("\t%s ... %s\n", | ||
| 217 | routines[i].name, routines[i].desc); | ||
| 218 | } | ||
| 219 | return 1; | ||
| 220 | } | ||
| 221 | |||
| 222 | if (bench_format == BENCH_FORMAT_DEFAULT) | ||
| 223 | printf("# Copying %s Bytes ...\n\n", length_str); | ||
| 224 | |||
| 225 | if (!only_prefault && !no_prefault) { | ||
| 226 | /* show both of results */ | ||
| 227 | if (use_cycle) { | ||
| 228 | result_cycle[0] = | ||
| 229 | do_memset_cycle(routines[i].fn, len, false); | ||
| 230 | result_cycle[1] = | ||
| 231 | do_memset_cycle(routines[i].fn, len, true); | ||
| 232 | } else { | ||
| 233 | result_bps[0] = | ||
| 234 | do_memset_gettimeofday(routines[i].fn, | ||
| 235 | len, false); | ||
| 236 | result_bps[1] = | ||
| 237 | do_memset_gettimeofday(routines[i].fn, | ||
| 238 | len, true); | ||
| 239 | } | ||
| 240 | } else { | ||
| 241 | if (use_cycle) { | ||
| 242 | result_cycle[pf] = | ||
| 243 | do_memset_cycle(routines[i].fn, | ||
| 244 | len, only_prefault); | ||
| 245 | } else { | ||
| 246 | result_bps[pf] = | ||
| 247 | do_memset_gettimeofday(routines[i].fn, | ||
| 248 | len, only_prefault); | ||
| 249 | } | ||
| 250 | } | ||
| 251 | |||
| 252 | switch (bench_format) { | ||
| 253 | case BENCH_FORMAT_DEFAULT: | ||
| 254 | if (!only_prefault && !no_prefault) { | ||
| 255 | if (use_cycle) { | ||
| 256 | printf(" %14lf Cycle/Byte\n", | ||
| 257 | (double)result_cycle[0] | ||
| 258 | / (double)len); | ||
| 259 | printf(" %14lf Cycle/Byte (with prefault)\n ", | ||
| 260 | (double)result_cycle[1] | ||
| 261 | / (double)len); | ||
| 262 | } else { | ||
| 263 | print_bps(result_bps[0]); | ||
| 264 | printf("\n"); | ||
| 265 | print_bps(result_bps[1]); | ||
| 266 | printf(" (with prefault)\n"); | ||
| 267 | } | ||
| 268 | } else { | ||
| 269 | if (use_cycle) { | ||
| 270 | printf(" %14lf Cycle/Byte", | ||
| 271 | (double)result_cycle[pf] | ||
| 272 | / (double)len); | ||
| 273 | } else | ||
| 274 | print_bps(result_bps[pf]); | ||
| 275 | |||
| 276 | printf("%s\n", only_prefault ? " (with prefault)" : ""); | ||
| 277 | } | ||
| 278 | break; | ||
| 279 | case BENCH_FORMAT_SIMPLE: | ||
| 280 | if (!only_prefault && !no_prefault) { | ||
| 281 | if (use_cycle) { | ||
| 282 | printf("%lf %lf\n", | ||
| 283 | (double)result_cycle[0] / (double)len, | ||
| 284 | (double)result_cycle[1] / (double)len); | ||
| 285 | } else { | ||
| 286 | printf("%lf %lf\n", | ||
| 287 | result_bps[0], result_bps[1]); | ||
| 288 | } | ||
| 289 | } else { | ||
| 290 | if (use_cycle) { | ||
| 291 | printf("%lf\n", (double)result_cycle[pf] | ||
| 292 | / (double)len); | ||
| 293 | } else | ||
| 294 | printf("%lf\n", result_bps[pf]); | ||
| 295 | } | ||
| 296 | break; | ||
| 297 | default: | ||
| 298 | /* reaching this means there's some disaster: */ | ||
| 299 | die("unknown format: %d\n", bench_format); | ||
| 300 | break; | ||
| 301 | } | ||
| 302 | |||
| 303 | return 0; | ||
| 304 | } | ||
diff --git a/tools/perf/builtin-buildid-cache.c b/tools/perf/builtin-buildid-cache.c index 70385756da63..77d5cae54c6a 100644 --- a/tools/perf/builtin-buildid-cache.c +++ b/tools/perf/builtin-buildid-cache.c | |||
| @@ -285,12 +285,11 @@ int cmd_buildid_cache(int argc, const char **argv, | |||
| 285 | struct str_node *pos; | 285 | struct str_node *pos; |
| 286 | int ret = 0; | 286 | int ret = 0; |
| 287 | bool force = false; | 287 | bool force = false; |
| 288 | char debugdir[PATH_MAX]; | ||
| 289 | char const *add_name_list_str = NULL, | 288 | char const *add_name_list_str = NULL, |
| 290 | *remove_name_list_str = NULL, | 289 | *remove_name_list_str = NULL, |
| 291 | *missing_filename = NULL, | 290 | *missing_filename = NULL, |
| 292 | *update_name_list_str = NULL, | 291 | *update_name_list_str = NULL, |
| 293 | *kcore_filename; | 292 | *kcore_filename = NULL; |
| 294 | char sbuf[STRERR_BUFSIZE]; | 293 | char sbuf[STRERR_BUFSIZE]; |
| 295 | 294 | ||
| 296 | struct perf_data_file file = { | 295 | struct perf_data_file file = { |
| @@ -335,13 +334,11 @@ int cmd_buildid_cache(int argc, const char **argv, | |||
| 335 | 334 | ||
| 336 | setup_pager(); | 335 | setup_pager(); |
| 337 | 336 | ||
| 338 | snprintf(debugdir, sizeof(debugdir), "%s", buildid_dir); | ||
| 339 | |||
| 340 | if (add_name_list_str) { | 337 | if (add_name_list_str) { |
| 341 | list = strlist__new(true, add_name_list_str); | 338 | list = strlist__new(true, add_name_list_str); |
| 342 | if (list) { | 339 | if (list) { |
| 343 | strlist__for_each(pos, list) | 340 | strlist__for_each(pos, list) |
| 344 | if (build_id_cache__add_file(pos->s, debugdir)) { | 341 | if (build_id_cache__add_file(pos->s, buildid_dir)) { |
| 345 | if (errno == EEXIST) { | 342 | if (errno == EEXIST) { |
| 346 | pr_debug("%s already in the cache\n", | 343 | pr_debug("%s already in the cache\n", |
| 347 | pos->s); | 344 | pos->s); |
| @@ -359,7 +356,7 @@ int cmd_buildid_cache(int argc, const char **argv, | |||
| 359 | list = strlist__new(true, remove_name_list_str); | 356 | list = strlist__new(true, remove_name_list_str); |
| 360 | if (list) { | 357 | if (list) { |
| 361 | strlist__for_each(pos, list) | 358 | strlist__for_each(pos, list) |
| 362 | if (build_id_cache__remove_file(pos->s, debugdir)) { | 359 | if (build_id_cache__remove_file(pos->s, buildid_dir)) { |
| 363 | if (errno == ENOENT) { | 360 | if (errno == ENOENT) { |
| 364 | pr_debug("%s wasn't in the cache\n", | 361 | pr_debug("%s wasn't in the cache\n", |
| 365 | pos->s); | 362 | pos->s); |
| @@ -380,7 +377,7 @@ int cmd_buildid_cache(int argc, const char **argv, | |||
| 380 | list = strlist__new(true, update_name_list_str); | 377 | list = strlist__new(true, update_name_list_str); |
| 381 | if (list) { | 378 | if (list) { |
| 382 | strlist__for_each(pos, list) | 379 | strlist__for_each(pos, list) |
| 383 | if (build_id_cache__update_file(pos->s, debugdir)) { | 380 | if (build_id_cache__update_file(pos->s, buildid_dir)) { |
| 384 | if (errno == ENOENT) { | 381 | if (errno == ENOENT) { |
| 385 | pr_debug("%s wasn't in the cache\n", | 382 | pr_debug("%s wasn't in the cache\n", |
| 386 | pos->s); | 383 | pos->s); |
| @@ -395,7 +392,7 @@ int cmd_buildid_cache(int argc, const char **argv, | |||
| 395 | } | 392 | } |
| 396 | 393 | ||
| 397 | if (kcore_filename && | 394 | if (kcore_filename && |
| 398 | build_id_cache__add_kcore(kcore_filename, debugdir, force)) | 395 | build_id_cache__add_kcore(kcore_filename, buildid_dir, force)) |
| 399 | pr_warning("Couldn't add %s\n", kcore_filename); | 396 | pr_warning("Couldn't add %s\n", kcore_filename); |
| 400 | 397 | ||
| 401 | out: | 398 | out: |
diff --git a/tools/perf/builtin-kvm.c b/tools/perf/builtin-kvm.c index 3c0f3d4fb021..0894a817f67e 100644 --- a/tools/perf/builtin-kvm.c +++ b/tools/perf/builtin-kvm.c | |||
| @@ -1293,7 +1293,8 @@ static int kvm_events_live(struct perf_kvm_stat *kvm, | |||
| 1293 | OPT_UINTEGER('d', "display", &kvm->display_time, | 1293 | OPT_UINTEGER('d', "display", &kvm->display_time, |
| 1294 | "time in seconds between display updates"), | 1294 | "time in seconds between display updates"), |
| 1295 | OPT_STRING(0, "event", &kvm->report_event, "report event", | 1295 | OPT_STRING(0, "event", &kvm->report_event, "report event", |
| 1296 | "event for reporting: vmexit, mmio, ioport"), | 1296 | "event for reporting: " |
| 1297 | "vmexit, mmio (x86 only), ioport (x86 only)"), | ||
| 1297 | OPT_INTEGER(0, "vcpu", &kvm->trace_vcpu, | 1298 | OPT_INTEGER(0, "vcpu", &kvm->trace_vcpu, |
| 1298 | "vcpu id to report"), | 1299 | "vcpu id to report"), |
| 1299 | OPT_STRING('k', "key", &kvm->sort_key, "sort-key", | 1300 | OPT_STRING('k', "key", &kvm->sort_key, "sort-key", |
diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index 83a4835c8118..327541e43c7f 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c | |||
| @@ -2045,7 +2045,6 @@ static int trace__run(struct trace *trace, int argc, const char **argv) | |||
| 2045 | unsigned long before; | 2045 | unsigned long before; |
| 2046 | const bool forks = argc > 0; | 2046 | const bool forks = argc > 0; |
| 2047 | bool draining = false; | 2047 | bool draining = false; |
| 2048 | char sbuf[STRERR_BUFSIZE]; | ||
| 2049 | 2048 | ||
| 2050 | trace->live = true; | 2049 | trace->live = true; |
| 2051 | 2050 | ||
| @@ -2106,11 +2105,8 @@ static int trace__run(struct trace *trace, int argc, const char **argv) | |||
| 2106 | goto out_error_open; | 2105 | goto out_error_open; |
| 2107 | 2106 | ||
| 2108 | err = perf_evlist__mmap(evlist, trace->opts.mmap_pages, false); | 2107 | err = perf_evlist__mmap(evlist, trace->opts.mmap_pages, false); |
| 2109 | if (err < 0) { | 2108 | if (err < 0) |
| 2110 | fprintf(trace->output, "Couldn't mmap the events: %s\n", | 2109 | goto out_error_mmap; |
| 2111 | strerror_r(errno, sbuf, sizeof(sbuf))); | ||
| 2112 | goto out_delete_evlist; | ||
| 2113 | } | ||
| 2114 | 2110 | ||
| 2115 | perf_evlist__enable(evlist); | 2111 | perf_evlist__enable(evlist); |
| 2116 | 2112 | ||
| @@ -2210,6 +2206,10 @@ out_error_tp: | |||
| 2210 | perf_evlist__strerror_tp(evlist, errno, errbuf, sizeof(errbuf)); | 2206 | perf_evlist__strerror_tp(evlist, errno, errbuf, sizeof(errbuf)); |
| 2211 | goto out_error; | 2207 | goto out_error; |
| 2212 | 2208 | ||
| 2209 | out_error_mmap: | ||
| 2210 | perf_evlist__strerror_mmap(evlist, errno, errbuf, sizeof(errbuf)); | ||
| 2211 | goto out_error; | ||
| 2212 | |||
| 2213 | out_error_open: | 2213 | out_error_open: |
| 2214 | perf_evlist__strerror_open(evlist, errno, errbuf, sizeof(errbuf)); | 2214 | perf_evlist__strerror_open(evlist, errno, errbuf, sizeof(errbuf)); |
| 2215 | 2215 | ||
diff --git a/tools/perf/perf.c b/tools/perf/perf.c index 452a8474d29d..3700a7faca6c 100644 --- a/tools/perf/perf.c +++ b/tools/perf/perf.c | |||
| @@ -200,6 +200,16 @@ static int handle_options(const char ***argv, int *argc, int *envchanged) | |||
| 200 | *envchanged = 1; | 200 | *envchanged = 1; |
| 201 | (*argv)++; | 201 | (*argv)++; |
| 202 | (*argc)--; | 202 | (*argc)--; |
| 203 | } else if (!strcmp(cmd, "--buildid-dir")) { | ||
| 204 | if (*argc < 2) { | ||
| 205 | fprintf(stderr, "No directory given for --buildid-dir.\n"); | ||
| 206 | usage(perf_usage_string); | ||
| 207 | } | ||
| 208 | set_buildid_dir((*argv)[1]); | ||
| 209 | if (envchanged) | ||
| 210 | *envchanged = 1; | ||
| 211 | (*argv)++; | ||
| 212 | (*argc)--; | ||
| 203 | } else if (!prefixcmp(cmd, CMD_DEBUGFS_DIR)) { | 213 | } else if (!prefixcmp(cmd, CMD_DEBUGFS_DIR)) { |
| 204 | perf_debugfs_set_path(cmd + strlen(CMD_DEBUGFS_DIR)); | 214 | perf_debugfs_set_path(cmd + strlen(CMD_DEBUGFS_DIR)); |
| 205 | fprintf(stderr, "dir: %s\n", debugfs_mountpoint); | 215 | fprintf(stderr, "dir: %s\n", debugfs_mountpoint); |
| @@ -499,7 +509,7 @@ int main(int argc, const char **argv) | |||
| 499 | } | 509 | } |
| 500 | if (!prefixcmp(cmd, "trace")) { | 510 | if (!prefixcmp(cmd, "trace")) { |
| 501 | #ifdef HAVE_LIBAUDIT_SUPPORT | 511 | #ifdef HAVE_LIBAUDIT_SUPPORT |
| 502 | set_buildid_dir(); | 512 | set_buildid_dir(NULL); |
| 503 | setup_path(); | 513 | setup_path(); |
| 504 | argv[0] = "trace"; | 514 | argv[0] = "trace"; |
| 505 | return cmd_trace(argc, argv, NULL); | 515 | return cmd_trace(argc, argv, NULL); |
| @@ -514,7 +524,7 @@ int main(int argc, const char **argv) | |||
| 514 | argc--; | 524 | argc--; |
| 515 | handle_options(&argv, &argc, NULL); | 525 | handle_options(&argv, &argc, NULL); |
| 516 | commit_pager_choice(); | 526 | commit_pager_choice(); |
| 517 | set_buildid_dir(); | 527 | set_buildid_dir(NULL); |
| 518 | 528 | ||
| 519 | if (argc > 0) { | 529 | if (argc > 0) { |
| 520 | if (!prefixcmp(argv[0], "--")) | 530 | if (!prefixcmp(argv[0], "--")) |
diff --git a/tools/perf/tests/attr/base-record b/tools/perf/tests/attr/base-record index f710b92ccff6..d3095dafed36 100644 --- a/tools/perf/tests/attr/base-record +++ b/tools/perf/tests/attr/base-record | |||
| @@ -5,7 +5,7 @@ group_fd=-1 | |||
| 5 | flags=0|8 | 5 | flags=0|8 |
| 6 | cpu=* | 6 | cpu=* |
| 7 | type=0|1 | 7 | type=0|1 |
| 8 | size=96 | 8 | size=104 |
| 9 | config=0 | 9 | config=0 |
| 10 | sample_period=4000 | 10 | sample_period=4000 |
| 11 | sample_type=263 | 11 | sample_type=263 |
diff --git a/tools/perf/tests/attr/base-stat b/tools/perf/tests/attr/base-stat index dc3ada2470c0..872ed7e24c7c 100644 --- a/tools/perf/tests/attr/base-stat +++ b/tools/perf/tests/attr/base-stat | |||
| @@ -5,7 +5,7 @@ group_fd=-1 | |||
| 5 | flags=0|8 | 5 | flags=0|8 |
| 6 | cpu=* | 6 | cpu=* |
| 7 | type=0 | 7 | type=0 |
| 8 | size=96 | 8 | size=104 |
| 9 | config=0 | 9 | config=0 |
| 10 | sample_period=0 | 10 | sample_period=0 |
| 11 | sample_type=0 | 11 | sample_type=0 |
diff --git a/tools/perf/ui/browsers/hists.c b/tools/perf/ui/browsers/hists.c index 502daff76ceb..e6bb04b5b09b 100644 --- a/tools/perf/ui/browsers/hists.c +++ b/tools/perf/ui/browsers/hists.c | |||
| @@ -1252,7 +1252,7 @@ static int hists__browser_title(struct hists *hists, | |||
| 1252 | 1252 | ||
| 1253 | nr_samples = convert_unit(nr_samples, &unit); | 1253 | nr_samples = convert_unit(nr_samples, &unit); |
| 1254 | printed = scnprintf(bf, size, | 1254 | printed = scnprintf(bf, size, |
| 1255 | "Samples: %lu%c of event '%s', Event count (approx.): %lu", | 1255 | "Samples: %lu%c of event '%s', Event count (approx.): %" PRIu64, |
| 1256 | nr_samples, unit, ev_name, nr_events); | 1256 | nr_samples, unit, ev_name, nr_events); |
| 1257 | 1257 | ||
| 1258 | 1258 | ||
diff --git a/tools/perf/ui/hist.c b/tools/perf/ui/hist.c index 2af18376b077..dc0d095f318c 100644 --- a/tools/perf/ui/hist.c +++ b/tools/perf/ui/hist.c | |||
| @@ -162,8 +162,8 @@ static int __hpp__sort(struct hist_entry *a, struct hist_entry *b, | |||
| 162 | return ret; | 162 | return ret; |
| 163 | 163 | ||
| 164 | nr_members = evsel->nr_members; | 164 | nr_members = evsel->nr_members; |
| 165 | fields_a = calloc(sizeof(*fields_a), nr_members); | 165 | fields_a = calloc(nr_members, sizeof(*fields_a)); |
| 166 | fields_b = calloc(sizeof(*fields_b), nr_members); | 166 | fields_b = calloc(nr_members, sizeof(*fields_b)); |
| 167 | 167 | ||
| 168 | if (!fields_a || !fields_b) | 168 | if (!fields_a || !fields_b) |
| 169 | goto out; | 169 | goto out; |
diff --git a/tools/perf/util/build-id.c b/tools/perf/util/build-id.c index e8d79e5bfaf7..0c72680a977f 100644 --- a/tools/perf/util/build-id.c +++ b/tools/perf/util/build-id.c | |||
| @@ -410,21 +410,18 @@ int perf_session__cache_build_ids(struct perf_session *session) | |||
| 410 | { | 410 | { |
| 411 | struct rb_node *nd; | 411 | struct rb_node *nd; |
| 412 | int ret; | 412 | int ret; |
| 413 | char debugdir[PATH_MAX]; | ||
| 414 | 413 | ||
| 415 | if (no_buildid_cache) | 414 | if (no_buildid_cache) |
| 416 | return 0; | 415 | return 0; |
| 417 | 416 | ||
| 418 | snprintf(debugdir, sizeof(debugdir), "%s", buildid_dir); | 417 | if (mkdir(buildid_dir, 0755) != 0 && errno != EEXIST) |
| 419 | |||
| 420 | if (mkdir(debugdir, 0755) != 0 && errno != EEXIST) | ||
| 421 | return -1; | 418 | return -1; |
| 422 | 419 | ||
| 423 | ret = machine__cache_build_ids(&session->machines.host, debugdir); | 420 | ret = machine__cache_build_ids(&session->machines.host, buildid_dir); |
| 424 | 421 | ||
| 425 | for (nd = rb_first(&session->machines.guests); nd; nd = rb_next(nd)) { | 422 | for (nd = rb_first(&session->machines.guests); nd; nd = rb_next(nd)) { |
| 426 | struct machine *pos = rb_entry(nd, struct machine, rb_node); | 423 | struct machine *pos = rb_entry(nd, struct machine, rb_node); |
| 427 | ret |= machine__cache_build_ids(pos, debugdir); | 424 | ret |= machine__cache_build_ids(pos, buildid_dir); |
| 428 | } | 425 | } |
| 429 | return ret ? -1 : 0; | 426 | return ret ? -1 : 0; |
| 430 | } | 427 | } |
diff --git a/tools/perf/util/callchain.c b/tools/perf/util/callchain.c index cf524a35cc84..64b377e591e4 100644 --- a/tools/perf/util/callchain.c +++ b/tools/perf/util/callchain.c | |||
| @@ -77,7 +77,7 @@ int parse_callchain_record_opt(const char *arg) | |||
| 77 | ret = 0; | 77 | ret = 0; |
| 78 | } else | 78 | } else |
| 79 | pr_err("callchain: No more arguments " | 79 | pr_err("callchain: No more arguments " |
| 80 | "needed for -g fp\n"); | 80 | "needed for --call-graph fp\n"); |
| 81 | break; | 81 | break; |
| 82 | 82 | ||
| 83 | #ifdef HAVE_DWARF_UNWIND_SUPPORT | 83 | #ifdef HAVE_DWARF_UNWIND_SUPPORT |
diff --git a/tools/perf/util/config.c b/tools/perf/util/config.c index 57ff826f150b..e18f653cd7db 100644 --- a/tools/perf/util/config.c +++ b/tools/perf/util/config.c | |||
| @@ -522,7 +522,7 @@ static int buildid_dir_command_config(const char *var, const char *value, | |||
| 522 | const char *v; | 522 | const char *v; |
| 523 | 523 | ||
| 524 | /* same dir for all commands */ | 524 | /* same dir for all commands */ |
| 525 | if (!prefixcmp(var, "buildid.") && !strcmp(var + 8, "dir")) { | 525 | if (!strcmp(var, "buildid.dir")) { |
| 526 | v = perf_config_dirname(var, value); | 526 | v = perf_config_dirname(var, value); |
| 527 | if (!v) | 527 | if (!v) |
| 528 | return -1; | 528 | return -1; |
| @@ -539,12 +539,14 @@ static void check_buildid_dir_config(void) | |||
| 539 | perf_config(buildid_dir_command_config, &c); | 539 | perf_config(buildid_dir_command_config, &c); |
| 540 | } | 540 | } |
| 541 | 541 | ||
| 542 | void set_buildid_dir(void) | 542 | void set_buildid_dir(const char *dir) |
| 543 | { | 543 | { |
| 544 | buildid_dir[0] = '\0'; | 544 | if (dir) |
| 545 | scnprintf(buildid_dir, MAXPATHLEN-1, "%s", dir); | ||
| 545 | 546 | ||
| 546 | /* try config file */ | 547 | /* try config file */ |
| 547 | check_buildid_dir_config(); | 548 | if (buildid_dir[0] == '\0') |
| 549 | check_buildid_dir_config(); | ||
| 548 | 550 | ||
| 549 | /* default to $HOME/.debug */ | 551 | /* default to $HOME/.debug */ |
| 550 | if (buildid_dir[0] == '\0') { | 552 | if (buildid_dir[0] == '\0') { |
diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c index cfbe2b99b9aa..bb5dfc5d1e75 100644 --- a/tools/perf/util/evlist.c +++ b/tools/perf/util/evlist.c | |||
| @@ -8,6 +8,7 @@ | |||
| 8 | */ | 8 | */ |
| 9 | #include "util.h" | 9 | #include "util.h" |
| 10 | #include <api/fs/debugfs.h> | 10 | #include <api/fs/debugfs.h> |
| 11 | #include <api/fs/fs.h> | ||
| 11 | #include <poll.h> | 12 | #include <poll.h> |
| 12 | #include "cpumap.h" | 13 | #include "cpumap.h" |
| 13 | #include "thread_map.h" | 14 | #include "thread_map.h" |
| @@ -1483,6 +1484,28 @@ int perf_evlist__strerror_open(struct perf_evlist *evlist __maybe_unused, | |||
| 1483 | return 0; | 1484 | return 0; |
| 1484 | } | 1485 | } |
| 1485 | 1486 | ||
| 1487 | int perf_evlist__strerror_mmap(struct perf_evlist *evlist, int err, char *buf, size_t size) | ||
| 1488 | { | ||
| 1489 | char sbuf[STRERR_BUFSIZE], *emsg = strerror_r(err, sbuf, sizeof(sbuf)); | ||
| 1490 | int value; | ||
| 1491 | |||
| 1492 | switch (err) { | ||
| 1493 | case EPERM: | ||
| 1494 | sysctl__read_int("kernel/perf_event_mlock_kb", &value); | ||
| 1495 | scnprintf(buf, size, "Error:\t%s.\n" | ||
| 1496 | "Hint:\tCheck /proc/sys/kernel/perf_event_mlock_kb (%d kB) setting.\n" | ||
| 1497 | "Hint:\tTried using %zd kB.\n" | ||
| 1498 | "Hint:\tTry using a bigger -m/--mmap-pages value.", | ||
| 1499 | emsg, value, evlist->mmap_len / 1024); | ||
| 1500 | break; | ||
| 1501 | default: | ||
| 1502 | scnprintf(buf, size, "%s", emsg); | ||
| 1503 | break; | ||
| 1504 | } | ||
| 1505 | |||
| 1506 | return 0; | ||
| 1507 | } | ||
| 1508 | |||
| 1486 | void perf_evlist__to_front(struct perf_evlist *evlist, | 1509 | void perf_evlist__to_front(struct perf_evlist *evlist, |
| 1487 | struct perf_evsel *move_evsel) | 1510 | struct perf_evsel *move_evsel) |
| 1488 | { | 1511 | { |
diff --git a/tools/perf/util/evlist.h b/tools/perf/util/evlist.h index 649b0c597283..0ba93f67ab94 100644 --- a/tools/perf/util/evlist.h +++ b/tools/perf/util/evlist.h | |||
| @@ -185,6 +185,7 @@ size_t perf_evlist__fprintf(struct perf_evlist *evlist, FILE *fp); | |||
| 185 | 185 | ||
| 186 | int perf_evlist__strerror_tp(struct perf_evlist *evlist, int err, char *buf, size_t size); | 186 | int perf_evlist__strerror_tp(struct perf_evlist *evlist, int err, char *buf, size_t size); |
| 187 | int perf_evlist__strerror_open(struct perf_evlist *evlist, int err, char *buf, size_t size); | 187 | int perf_evlist__strerror_open(struct perf_evlist *evlist, int err, char *buf, size_t size); |
| 188 | int perf_evlist__strerror_mmap(struct perf_evlist *evlist, int err, char *buf, size_t size); | ||
| 188 | 189 | ||
| 189 | static inline unsigned int perf_mmap__read_head(struct perf_mmap *mm) | 190 | static inline unsigned int perf_mmap__read_head(struct perf_mmap *mm) |
| 190 | { | 191 | { |
diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c index 15dd0a9691ce..94de3e48b490 100644 --- a/tools/perf/util/machine.c +++ b/tools/perf/util/machine.c | |||
| @@ -1385,19 +1385,46 @@ struct mem_info *sample__resolve_mem(struct perf_sample *sample, | |||
| 1385 | static int add_callchain_ip(struct thread *thread, | 1385 | static int add_callchain_ip(struct thread *thread, |
| 1386 | struct symbol **parent, | 1386 | struct symbol **parent, |
| 1387 | struct addr_location *root_al, | 1387 | struct addr_location *root_al, |
| 1388 | int cpumode, | 1388 | bool branch_history, |
| 1389 | u64 ip) | 1389 | u64 ip) |
| 1390 | { | 1390 | { |
| 1391 | struct addr_location al; | 1391 | struct addr_location al; |
| 1392 | 1392 | ||
| 1393 | al.filtered = 0; | 1393 | al.filtered = 0; |
| 1394 | al.sym = NULL; | 1394 | al.sym = NULL; |
| 1395 | if (cpumode == -1) | 1395 | if (branch_history) |
| 1396 | thread__find_cpumode_addr_location(thread, MAP__FUNCTION, | 1396 | thread__find_cpumode_addr_location(thread, MAP__FUNCTION, |
| 1397 | ip, &al); | 1397 | ip, &al); |
| 1398 | else | 1398 | else { |
| 1399 | u8 cpumode = PERF_RECORD_MISC_USER; | ||
| 1400 | |||
| 1401 | if (ip >= PERF_CONTEXT_MAX) { | ||
| 1402 | switch (ip) { | ||
| 1403 | case PERF_CONTEXT_HV: | ||
| 1404 | cpumode = PERF_RECORD_MISC_HYPERVISOR; | ||
| 1405 | break; | ||
| 1406 | case PERF_CONTEXT_KERNEL: | ||
| 1407 | cpumode = PERF_RECORD_MISC_KERNEL; | ||
| 1408 | break; | ||
| 1409 | case PERF_CONTEXT_USER: | ||
| 1410 | cpumode = PERF_RECORD_MISC_USER; | ||
| 1411 | break; | ||
| 1412 | default: | ||
| 1413 | pr_debug("invalid callchain context: " | ||
| 1414 | "%"PRId64"\n", (s64) ip); | ||
| 1415 | /* | ||
| 1416 | * It seems the callchain is corrupted. | ||
| 1417 | * Discard all. | ||
| 1418 | */ | ||
| 1419 | callchain_cursor_reset(&callchain_cursor); | ||
| 1420 | return 1; | ||
| 1421 | } | ||
| 1422 | return 0; | ||
| 1423 | } | ||
| 1399 | thread__find_addr_location(thread, cpumode, MAP__FUNCTION, | 1424 | thread__find_addr_location(thread, cpumode, MAP__FUNCTION, |
| 1400 | ip, &al); | 1425 | ip, &al); |
| 1426 | } | ||
| 1427 | |||
| 1401 | if (al.sym != NULL) { | 1428 | if (al.sym != NULL) { |
| 1402 | if (sort__has_parent && !*parent && | 1429 | if (sort__has_parent && !*parent && |
| 1403 | symbol__match_regex(al.sym, &parent_regex)) | 1430 | symbol__match_regex(al.sym, &parent_regex)) |
| @@ -1480,11 +1507,8 @@ static int thread__resolve_callchain_sample(struct thread *thread, | |||
| 1480 | struct addr_location *root_al, | 1507 | struct addr_location *root_al, |
| 1481 | int max_stack) | 1508 | int max_stack) |
| 1482 | { | 1509 | { |
| 1483 | u8 cpumode = PERF_RECORD_MISC_USER; | ||
| 1484 | int chain_nr = min(max_stack, (int)chain->nr); | 1510 | int chain_nr = min(max_stack, (int)chain->nr); |
| 1485 | int i; | 1511 | int i, j, err; |
| 1486 | int j; | ||
| 1487 | int err; | ||
| 1488 | int skip_idx = -1; | 1512 | int skip_idx = -1; |
| 1489 | int first_call = 0; | 1513 | int first_call = 0; |
| 1490 | 1514 | ||
| @@ -1542,10 +1566,10 @@ static int thread__resolve_callchain_sample(struct thread *thread, | |||
| 1542 | 1566 | ||
| 1543 | for (i = 0; i < nr; i++) { | 1567 | for (i = 0; i < nr; i++) { |
| 1544 | err = add_callchain_ip(thread, parent, root_al, | 1568 | err = add_callchain_ip(thread, parent, root_al, |
| 1545 | -1, be[i].to); | 1569 | true, be[i].to); |
| 1546 | if (!err) | 1570 | if (!err) |
| 1547 | err = add_callchain_ip(thread, parent, root_al, | 1571 | err = add_callchain_ip(thread, parent, root_al, |
| 1548 | -1, be[i].from); | 1572 | true, be[i].from); |
| 1549 | if (err == -EINVAL) | 1573 | if (err == -EINVAL) |
| 1550 | break; | 1574 | break; |
| 1551 | if (err) | 1575 | if (err) |
| @@ -1574,36 +1598,10 @@ check_calls: | |||
| 1574 | #endif | 1598 | #endif |
| 1575 | ip = chain->ips[j]; | 1599 | ip = chain->ips[j]; |
| 1576 | 1600 | ||
| 1577 | if (ip >= PERF_CONTEXT_MAX) { | 1601 | err = add_callchain_ip(thread, parent, root_al, false, ip); |
| 1578 | switch (ip) { | ||
| 1579 | case PERF_CONTEXT_HV: | ||
| 1580 | cpumode = PERF_RECORD_MISC_HYPERVISOR; | ||
| 1581 | break; | ||
| 1582 | case PERF_CONTEXT_KERNEL: | ||
| 1583 | cpumode = PERF_RECORD_MISC_KERNEL; | ||
| 1584 | break; | ||
| 1585 | case PERF_CONTEXT_USER: | ||
| 1586 | cpumode = PERF_RECORD_MISC_USER; | ||
| 1587 | break; | ||
| 1588 | default: | ||
| 1589 | pr_debug("invalid callchain context: " | ||
| 1590 | "%"PRId64"\n", (s64) ip); | ||
| 1591 | /* | ||
| 1592 | * It seems the callchain is corrupted. | ||
| 1593 | * Discard all. | ||
| 1594 | */ | ||
| 1595 | callchain_cursor_reset(&callchain_cursor); | ||
| 1596 | return 0; | ||
| 1597 | } | ||
| 1598 | continue; | ||
| 1599 | } | ||
| 1600 | 1602 | ||
| 1601 | err = add_callchain_ip(thread, parent, root_al, | ||
| 1602 | cpumode, ip); | ||
| 1603 | if (err == -EINVAL) | ||
| 1604 | break; | ||
| 1605 | if (err) | 1603 | if (err) |
| 1606 | return err; | 1604 | return (err < 0) ? err : 0; |
| 1607 | } | 1605 | } |
| 1608 | 1606 | ||
| 1609 | return 0; | 1607 | return 0; |
diff --git a/tools/perf/util/record.c b/tools/perf/util/record.c index cf69325b985f..8acd0df88b5c 100644 --- a/tools/perf/util/record.c +++ b/tools/perf/util/record.c | |||
| @@ -137,16 +137,7 @@ void perf_evlist__config(struct perf_evlist *evlist, struct record_opts *opts) | |||
| 137 | 137 | ||
| 138 | static int get_max_rate(unsigned int *rate) | 138 | static int get_max_rate(unsigned int *rate) |
| 139 | { | 139 | { |
| 140 | char path[PATH_MAX]; | 140 | return sysctl__read_int("kernel/perf_event_max_sample_rate", (int *)rate); |
| 141 | const char *procfs = procfs__mountpoint(); | ||
| 142 | |||
| 143 | if (!procfs) | ||
| 144 | return -1; | ||
| 145 | |||
| 146 | snprintf(path, PATH_MAX, | ||
| 147 | "%s/sys/kernel/perf_event_max_sample_rate", procfs); | ||
| 148 | |||
| 149 | return filename__read_int(path, (int *) rate); | ||
| 150 | } | 141 | } |
| 151 | 142 | ||
| 152 | static int record_opts__config_freq(struct record_opts *opts) | 143 | static int record_opts__config_freq(struct record_opts *opts) |
diff --git a/tools/perf/util/util.c b/tools/perf/util/util.c index d5eab3f3323f..b86744f29eef 100644 --- a/tools/perf/util/util.c +++ b/tools/perf/util/util.c | |||
| @@ -442,23 +442,6 @@ unsigned long parse_tag_value(const char *str, struct parse_tag *tags) | |||
| 442 | return (unsigned long) -1; | 442 | return (unsigned long) -1; |
| 443 | } | 443 | } |
| 444 | 444 | ||
| 445 | int filename__read_int(const char *filename, int *value) | ||
| 446 | { | ||
| 447 | char line[64]; | ||
| 448 | int fd = open(filename, O_RDONLY), err = -1; | ||
| 449 | |||
| 450 | if (fd < 0) | ||
| 451 | return -1; | ||
| 452 | |||
| 453 | if (read(fd, line, sizeof(line)) > 0) { | ||
| 454 | *value = atoi(line); | ||
| 455 | err = 0; | ||
| 456 | } | ||
| 457 | |||
| 458 | close(fd); | ||
| 459 | return err; | ||
| 460 | } | ||
| 461 | |||
| 462 | int filename__read_str(const char *filename, char **buf, size_t *sizep) | 445 | int filename__read_str(const char *filename, char **buf, size_t *sizep) |
| 463 | { | 446 | { |
| 464 | size_t size = 0, alloc_size = 0; | 447 | size_t size = 0, alloc_size = 0; |
| @@ -523,16 +506,9 @@ const char *get_filename_for_perf_kvm(void) | |||
| 523 | 506 | ||
| 524 | int perf_event_paranoid(void) | 507 | int perf_event_paranoid(void) |
| 525 | { | 508 | { |
| 526 | char path[PATH_MAX]; | ||
| 527 | const char *procfs = procfs__mountpoint(); | ||
| 528 | int value; | 509 | int value; |
| 529 | 510 | ||
| 530 | if (!procfs) | 511 | if (sysctl__read_int("kernel/perf_event_paranoid", &value)) |
| 531 | return INT_MAX; | ||
| 532 | |||
| 533 | scnprintf(path, PATH_MAX, "%s/sys/kernel/perf_event_paranoid", procfs); | ||
| 534 | |||
| 535 | if (filename__read_int(path, &value)) | ||
| 536 | return INT_MAX; | 512 | return INT_MAX; |
| 537 | 513 | ||
| 538 | return value; | 514 | return value; |
diff --git a/tools/perf/util/util.h b/tools/perf/util/util.h index 419bee030f83..008b361b1758 100644 --- a/tools/perf/util/util.h +++ b/tools/perf/util/util.h | |||
| @@ -153,7 +153,7 @@ extern void warning(const char *err, ...) __attribute__((format (printf, 1, 2))) | |||
| 153 | extern void set_die_routine(void (*routine)(const char *err, va_list params) NORETURN); | 153 | extern void set_die_routine(void (*routine)(const char *err, va_list params) NORETURN); |
| 154 | 154 | ||
| 155 | extern int prefixcmp(const char *str, const char *prefix); | 155 | extern int prefixcmp(const char *str, const char *prefix); |
| 156 | extern void set_buildid_dir(void); | 156 | extern void set_buildid_dir(const char *dir); |
| 157 | 157 | ||
| 158 | static inline const char *skip_prefix(const char *str, const char *prefix) | 158 | static inline const char *skip_prefix(const char *str, const char *prefix) |
| 159 | { | 159 | { |
| @@ -343,7 +343,6 @@ char *get_srcline(struct dso *dso, unsigned long addr, struct symbol *sym, | |||
| 343 | bool show_sym); | 343 | bool show_sym); |
| 344 | void free_srcline(char *srcline); | 344 | void free_srcline(char *srcline); |
| 345 | 345 | ||
| 346 | int filename__read_int(const char *filename, int *value); | ||
| 347 | int filename__read_str(const char *filename, char **buf, size_t *sizep); | 346 | int filename__read_str(const char *filename, char **buf, size_t *sizep); |
| 348 | int perf_event_paranoid(void); | 347 | int perf_event_paranoid(void); |
| 349 | 348 | ||
