// SPDX-License-Identifier: GPL-2.0 /* Copyright (c) 2021 Facebook */ #include <argp.h> #include "bench.h" #include "bpf_loop_bench.skel.h" /* BPF triggering benchmarks */ static struct ctx { struct bpf_loop_bench *skel; } ctx; static struct { __u32 nr_loops; } args = { .nr_loops = 10, }; enum { ARG_NR_LOOPS = 4000, }; static const struct argp_option opts[] = { { "nr_loops", ARG_NR_LOOPS, "nr_loops", 0, "Set number of loops for the bpf_loop helper"}, {}, }; static error_t parse_arg(int key, char *arg, struct argp_state *state) { switch (key) { case ARG_NR_LOOPS: args.nr_loops = strtol(arg, NULL, 10); break; default: return ARGP_ERR_UNKNOWN; } return 0; } /* exported into benchmark runner */ const struct argp bench_bpf_loop_argp = { .options = opts, .parser = parse_arg, }; static void validate(void) { if (env.consumer_cnt != 0) { fprintf(stderr, "benchmark doesn't support consumer!\n"); exit(1); } } static void *producer(void *input) { while (true) /* trigger the bpf program */ syscall(__NR_getpgid); return NULL; } static void measure(struct bench_res *res) { res->hits = atomic_swap(&ctx.skel->bss->hits, 0); } static void setup(void) { struct bpf_link *link; setup_libbpf(); ctx.skel = bpf_loop_bench__open_and_load(); if (!ctx.skel) { fprintf(stderr, "failed to open skeleton\n"); exit(1); } link = bpf_program__attach(ctx.skel->progs.benchmark); if (!link) { fprintf(stderr, "failed to attach program!\n"); exit(1); } ctx.skel->bss->nr_loops = args.nr_loops; } const struct bench bench_bpf_loop = { .name = "bpf-loop", .argp = &bench_bpf_loop_argp, .validate = validate, .setup = setup, .producer_thread = producer, .measure = measure, .report_progress = ops_report_progress, .report_final = ops_report_final, };