162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * Benchmark of /proc/kallsyms parsing. 462306a36Sopenharmony_ci * 562306a36Sopenharmony_ci * Copyright 2020 Google LLC. 662306a36Sopenharmony_ci */ 762306a36Sopenharmony_ci#include <stdlib.h> 862306a36Sopenharmony_ci#include "bench.h" 962306a36Sopenharmony_ci#include "../util/stat.h" 1062306a36Sopenharmony_ci#include <linux/time64.h> 1162306a36Sopenharmony_ci#include <subcmd/parse-options.h> 1262306a36Sopenharmony_ci#include <symbol/kallsyms.h> 1362306a36Sopenharmony_ci 1462306a36Sopenharmony_cistatic unsigned int iterations = 100; 1562306a36Sopenharmony_ci 1662306a36Sopenharmony_cistatic const struct option options[] = { 1762306a36Sopenharmony_ci OPT_UINTEGER('i', "iterations", &iterations, 1862306a36Sopenharmony_ci "Number of iterations used to compute average"), 1962306a36Sopenharmony_ci OPT_END() 2062306a36Sopenharmony_ci}; 2162306a36Sopenharmony_ci 2262306a36Sopenharmony_cistatic const char *const bench_usage[] = { 2362306a36Sopenharmony_ci "perf bench internals kallsyms-parse <options>", 2462306a36Sopenharmony_ci NULL 2562306a36Sopenharmony_ci}; 2662306a36Sopenharmony_ci 2762306a36Sopenharmony_cistatic int bench_process_symbol(void *arg __maybe_unused, 2862306a36Sopenharmony_ci const char *name __maybe_unused, 2962306a36Sopenharmony_ci char type __maybe_unused, 3062306a36Sopenharmony_ci u64 start __maybe_unused) 3162306a36Sopenharmony_ci{ 3262306a36Sopenharmony_ci return 0; 3362306a36Sopenharmony_ci} 3462306a36Sopenharmony_ci 3562306a36Sopenharmony_cistatic int do_kallsyms_parse(void) 3662306a36Sopenharmony_ci{ 3762306a36Sopenharmony_ci struct timeval start, end, diff; 3862306a36Sopenharmony_ci u64 runtime_us; 3962306a36Sopenharmony_ci unsigned int i; 4062306a36Sopenharmony_ci double time_average, time_stddev; 4162306a36Sopenharmony_ci int err; 4262306a36Sopenharmony_ci struct stats time_stats; 4362306a36Sopenharmony_ci 4462306a36Sopenharmony_ci init_stats(&time_stats); 4562306a36Sopenharmony_ci 4662306a36Sopenharmony_ci for (i = 0; i < iterations; i++) { 4762306a36Sopenharmony_ci gettimeofday(&start, NULL); 4862306a36Sopenharmony_ci err = kallsyms__parse("/proc/kallsyms", NULL, 4962306a36Sopenharmony_ci bench_process_symbol); 5062306a36Sopenharmony_ci if (err) 5162306a36Sopenharmony_ci return err; 5262306a36Sopenharmony_ci 5362306a36Sopenharmony_ci gettimeofday(&end, NULL); 5462306a36Sopenharmony_ci timersub(&end, &start, &diff); 5562306a36Sopenharmony_ci runtime_us = diff.tv_sec * USEC_PER_SEC + diff.tv_usec; 5662306a36Sopenharmony_ci update_stats(&time_stats, runtime_us); 5762306a36Sopenharmony_ci } 5862306a36Sopenharmony_ci 5962306a36Sopenharmony_ci time_average = avg_stats(&time_stats) / USEC_PER_MSEC; 6062306a36Sopenharmony_ci time_stddev = stddev_stats(&time_stats) / USEC_PER_MSEC; 6162306a36Sopenharmony_ci printf(" Average kallsyms__parse took: %.3f ms (+- %.3f ms)\n", 6262306a36Sopenharmony_ci time_average, time_stddev); 6362306a36Sopenharmony_ci return 0; 6462306a36Sopenharmony_ci} 6562306a36Sopenharmony_ci 6662306a36Sopenharmony_ciint bench_kallsyms_parse(int argc, const char **argv) 6762306a36Sopenharmony_ci{ 6862306a36Sopenharmony_ci argc = parse_options(argc, argv, options, bench_usage, 0); 6962306a36Sopenharmony_ci if (argc) { 7062306a36Sopenharmony_ci usage_with_options(bench_usage, options); 7162306a36Sopenharmony_ci exit(EXIT_FAILURE); 7262306a36Sopenharmony_ci } 7362306a36Sopenharmony_ci 7462306a36Sopenharmony_ci return do_kallsyms_parse(); 7562306a36Sopenharmony_ci} 76