18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * Benchmark of /proc/kallsyms parsing. 48c2ecf20Sopenharmony_ci * 58c2ecf20Sopenharmony_ci * Copyright 2020 Google LLC. 68c2ecf20Sopenharmony_ci */ 78c2ecf20Sopenharmony_ci#include <stdlib.h> 88c2ecf20Sopenharmony_ci#include "bench.h" 98c2ecf20Sopenharmony_ci#include "../util/stat.h" 108c2ecf20Sopenharmony_ci#include <linux/time64.h> 118c2ecf20Sopenharmony_ci#include <subcmd/parse-options.h> 128c2ecf20Sopenharmony_ci#include <symbol/kallsyms.h> 138c2ecf20Sopenharmony_ci 148c2ecf20Sopenharmony_cistatic unsigned int iterations = 100; 158c2ecf20Sopenharmony_ci 168c2ecf20Sopenharmony_cistatic const struct option options[] = { 178c2ecf20Sopenharmony_ci OPT_UINTEGER('i', "iterations", &iterations, 188c2ecf20Sopenharmony_ci "Number of iterations used to compute average"), 198c2ecf20Sopenharmony_ci OPT_END() 208c2ecf20Sopenharmony_ci}; 218c2ecf20Sopenharmony_ci 228c2ecf20Sopenharmony_cistatic const char *const bench_usage[] = { 238c2ecf20Sopenharmony_ci "perf bench internals kallsyms-parse <options>", 248c2ecf20Sopenharmony_ci NULL 258c2ecf20Sopenharmony_ci}; 268c2ecf20Sopenharmony_ci 278c2ecf20Sopenharmony_cistatic int bench_process_symbol(void *arg __maybe_unused, 288c2ecf20Sopenharmony_ci const char *name __maybe_unused, 298c2ecf20Sopenharmony_ci char type __maybe_unused, 308c2ecf20Sopenharmony_ci u64 start __maybe_unused) 318c2ecf20Sopenharmony_ci{ 328c2ecf20Sopenharmony_ci return 0; 338c2ecf20Sopenharmony_ci} 348c2ecf20Sopenharmony_ci 358c2ecf20Sopenharmony_cistatic int do_kallsyms_parse(void) 368c2ecf20Sopenharmony_ci{ 378c2ecf20Sopenharmony_ci struct timeval start, end, diff; 388c2ecf20Sopenharmony_ci u64 runtime_us; 398c2ecf20Sopenharmony_ci unsigned int i; 408c2ecf20Sopenharmony_ci double time_average, time_stddev; 418c2ecf20Sopenharmony_ci int err; 428c2ecf20Sopenharmony_ci struct stats time_stats; 438c2ecf20Sopenharmony_ci 448c2ecf20Sopenharmony_ci init_stats(&time_stats); 458c2ecf20Sopenharmony_ci 468c2ecf20Sopenharmony_ci for (i = 0; i < iterations; i++) { 478c2ecf20Sopenharmony_ci gettimeofday(&start, NULL); 488c2ecf20Sopenharmony_ci err = kallsyms__parse("/proc/kallsyms", NULL, 498c2ecf20Sopenharmony_ci bench_process_symbol); 508c2ecf20Sopenharmony_ci if (err) 518c2ecf20Sopenharmony_ci return err; 528c2ecf20Sopenharmony_ci 538c2ecf20Sopenharmony_ci gettimeofday(&end, NULL); 548c2ecf20Sopenharmony_ci timersub(&end, &start, &diff); 558c2ecf20Sopenharmony_ci runtime_us = diff.tv_sec * USEC_PER_SEC + diff.tv_usec; 568c2ecf20Sopenharmony_ci update_stats(&time_stats, runtime_us); 578c2ecf20Sopenharmony_ci } 588c2ecf20Sopenharmony_ci 598c2ecf20Sopenharmony_ci time_average = avg_stats(&time_stats) / USEC_PER_MSEC; 608c2ecf20Sopenharmony_ci time_stddev = stddev_stats(&time_stats) / USEC_PER_MSEC; 618c2ecf20Sopenharmony_ci printf(" Average kallsyms__parse took: %.3f ms (+- %.3f ms)\n", 628c2ecf20Sopenharmony_ci time_average, time_stddev); 638c2ecf20Sopenharmony_ci return 0; 648c2ecf20Sopenharmony_ci} 658c2ecf20Sopenharmony_ci 668c2ecf20Sopenharmony_ciint bench_kallsyms_parse(int argc, const char **argv) 678c2ecf20Sopenharmony_ci{ 688c2ecf20Sopenharmony_ci argc = parse_options(argc, argv, options, bench_usage, 0); 698c2ecf20Sopenharmony_ci if (argc) { 708c2ecf20Sopenharmony_ci usage_with_options(bench_usage, options); 718c2ecf20Sopenharmony_ci exit(EXIT_FAILURE); 728c2ecf20Sopenharmony_ci } 738c2ecf20Sopenharmony_ci 748c2ecf20Sopenharmony_ci return do_kallsyms_parse(); 758c2ecf20Sopenharmony_ci} 76