Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

perf bench: Add kallsyms parsing

Add a benchmark for kallsyms parsing. Example output:

Running 'internals/kallsyms-parse' benchmark:
Average kallsyms__parse took: 103.971 ms (+- 0.121 ms)

Committer testing:

Test Machine: AMD Ryzen 5 3600X 6-Core Processor

[root@five ~]# perf bench internals kallsyms-parse
# Running 'internals/kallsyms-parse' benchmark:
Average kallsyms__parse took: 79.692 ms (+- 0.101 ms)
[root@five ~]# perf stat -r5 perf bench internals kallsyms-parse
# Running 'internals/kallsyms-parse' benchmark:
Average kallsyms__parse took: 80.563 ms (+- 0.079 ms)
# Running 'internals/kallsyms-parse' benchmark:
Average kallsyms__parse took: 81.046 ms (+- 0.155 ms)
# Running 'internals/kallsyms-parse' benchmark:
Average kallsyms__parse took: 80.874 ms (+- 0.104 ms)
# Running 'internals/kallsyms-parse' benchmark:
Average kallsyms__parse took: 81.173 ms (+- 0.133 ms)
# Running 'internals/kallsyms-parse' benchmark:
Average kallsyms__parse took: 81.169 ms (+- 0.074 ms)

Performance counter stats for 'perf bench internals kallsyms-parse' (5 runs):

8,093.54 msec task-clock # 0.999 CPUs utilized ( +- 0.14% )
3,165 context-switches # 0.391 K/sec ( +- 0.18% )
10 cpu-migrations # 0.001 K/sec ( +- 23.13% )
744 page-faults # 0.092 K/sec ( +- 0.21% )
34,551,564,954 cycles # 4.269 GHz ( +- 0.05% ) (83.33%)
1,160,584,308 stalled-cycles-frontend # 3.36% frontend cycles idle ( +- 1.60% ) (83.33%)
14,974,323,985 stalled-cycles-backend # 43.34% backend cycles idle ( +- 0.24% ) (83.33%)
58,712,905,705 instructions # 1.70 insn per cycle
# 0.26 stalled cycles per insn ( +- 0.01% ) (83.34%)
14,136,433,778 branches # 1746.632 M/sec ( +- 0.01% ) (83.33%)
141,943,217 branch-misses # 1.00% of all branches ( +- 0.04% ) (83.33%)

8.1040 +- 0.0115 seconds time elapsed ( +- 0.14% )

[root@five ~]#

Signed-off-by: Ian Rogers <irogers@google.com>
Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Link: http://lore.kernel.org/lkml/20200501221315.54715-2-irogers@google.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>

authored by

Ian Rogers and committed by
Arnaldo Carvalho de Melo
51876bd4 29e2eb2a

+78
+1
tools/perf/bench/Build
··· 9 9 perf-y += epoll-wait.o 10 10 perf-y += epoll-ctl.o 11 11 perf-y += synthesize.o 12 + perf-y += kallsyms-parse.o 12 13 13 14 perf-$(CONFIG_X86_64) += mem-memcpy-x86-64-lib.o 14 15 perf-$(CONFIG_X86_64) += mem-memcpy-x86-64-asm.o
+1
tools/perf/bench/bench.h
··· 44 44 int bench_epoll_wait(int argc, const char **argv); 45 45 int bench_epoll_ctl(int argc, const char **argv); 46 46 int bench_synthesize(int argc, const char **argv); 47 + int bench_kallsyms_parse(int argc, const char **argv); 47 48 48 49 #define BENCH_FORMAT_DEFAULT_STR "default" 49 50 #define BENCH_FORMAT_DEFAULT 0
+75
tools/perf/bench/kallsyms-parse.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + /* 3 + * Benchmark of /proc/kallsyms parsing. 4 + * 5 + * Copyright 2020 Google LLC. 6 + */ 7 + #include <stdlib.h> 8 + #include "bench.h" 9 + #include "../util/stat.h" 10 + #include <linux/time64.h> 11 + #include <subcmd/parse-options.h> 12 + #include <symbol/kallsyms.h> 13 + 14 + static unsigned int iterations = 100; 15 + 16 + static const struct option options[] = { 17 + OPT_UINTEGER('i', "iterations", &iterations, 18 + "Number of iterations used to compute average"), 19 + OPT_END() 20 + }; 21 + 22 + static const char *const bench_usage[] = { 23 + "perf bench internals kallsyms-parse <options>", 24 + NULL 25 + }; 26 + 27 + static int bench_process_symbol(void *arg __maybe_unused, 28 + const char *name __maybe_unused, 29 + char type __maybe_unused, 30 + u64 start __maybe_unused) 31 + { 32 + return 0; 33 + } 34 + 35 + static int do_kallsyms_parse(void) 36 + { 37 + struct timeval start, end, diff; 38 + u64 runtime_us; 39 + unsigned int i; 40 + double time_average, time_stddev; 41 + int err; 42 + struct stats time_stats; 43 + 44 + init_stats(&time_stats); 45 + 46 + for (i = 0; i < iterations; i++) { 47 + gettimeofday(&start, NULL); 48 + err = kallsyms__parse("/proc/kallsyms", NULL, 49 + bench_process_symbol); 50 + if (err) 51 + return err; 52 + 53 + gettimeofday(&end, NULL); 54 + timersub(&end, &start, &diff); 55 + runtime_us = diff.tv_sec * USEC_PER_SEC + diff.tv_usec; 56 + update_stats(&time_stats, runtime_us); 57 + } 58 + 59 + time_average = avg_stats(&time_stats) / USEC_PER_MSEC; 60 + time_stddev = stddev_stats(&time_stats) / USEC_PER_MSEC; 61 + printf(" Average kallsyms__parse took: %.3f ms (+- %.3f ms)\n", 62 + time_average, time_stddev); 63 + return 0; 64 + } 65 + 66 + int bench_kallsyms_parse(int argc, const char **argv) 67 + { 68 + argc = parse_options(argc, argv, options, bench_usage, 0); 69 + if (argc) { 70 + usage_with_options(bench_usage, options); 71 + exit(EXIT_FAILURE); 72 + } 73 + 74 + return do_kallsyms_parse(); 75 + }
+1
tools/perf/builtin-bench.c
··· 78 78 79 79 static struct bench internals_benchmarks[] = { 80 80 { "synthesize", "Benchmark perf event synthesis", bench_synthesize }, 81 + { "kallsyms-parse", "Benchmark kallsyms parsing", bench_kallsyms_parse }, 81 82 { NULL, NULL, NULL } 82 83 }; 83 84