1 // SPDX-License-Identifier: GPL-2.0 2 /* Copyright (c) 2021 Facebook */ 3 4 #include <argp.h> 5 #include "bench.h" 6 #include "bpf_loop_bench.skel.h" 7 8 /* BPF triggering benchmarks */ 9 static struct ctx { 10 struct bpf_loop_bench *skel; 11 } ctx; 12 13 static struct { 14 __u32 nr_loops; 15 } args = { 16 .nr_loops = 10, 17 }; 18 19 enum { 20 ARG_NR_LOOPS = 4000, 21 }; 22 23 static const struct argp_option opts[] = { 24 { "nr_loops", ARG_NR_LOOPS, "nr_loops", 0, 25 "Set number of loops for the bpf_loop helper"}, 26 {}, 27 }; 28 29 static error_t parse_arg(int key, char *arg, struct argp_state *state) 30 { 31 switch (key) { 32 case ARG_NR_LOOPS: 33 args.nr_loops = strtol(arg, NULL, 10); 34 break; 35 default: 36 return ARGP_ERR_UNKNOWN; 37 } 38 39 return 0; 40 } 41 42 /* exported into benchmark runner */ 43 const struct argp bench_bpf_loop_argp = { 44 .options = opts, 45 .parser = parse_arg, 46 }; 47 48 static void validate(void) 49 { 50 if (env.consumer_cnt != 0) { 51 fprintf(stderr, "benchmark doesn't support consumer!\n"); 52 exit(1); 53 } 54 } 55 56 static void *producer(void *input) 57 { 58 while (true) 59 /* trigger the bpf program */ 60 syscall(__NR_getpgid); 61 62 return NULL; 63 } 64 65 static void measure(struct bench_res *res) 66 { 67 res->hits = atomic_swap(&ctx.skel->bss->hits, 0); 68 } 69 70 static void setup(void) 71 { 72 struct bpf_link *link; 73 74 setup_libbpf(); 75 76 ctx.skel = bpf_loop_bench__open_and_load(); 77 if (!ctx.skel) { 78 fprintf(stderr, "failed to open skeleton\n"); 79 exit(1); 80 } 81 82 link = bpf_program__attach(ctx.skel->progs.benchmark); 83 if (!link) { 84 fprintf(stderr, "failed to attach program!\n"); 85 exit(1); 86 } 87 88 ctx.skel->bss->nr_loops = args.nr_loops; 89 } 90 91 const struct bench bench_bpf_loop = { 92 .name = "bpf-loop", 93 .argp = &bench_bpf_loop_argp, 94 .validate = validate, 95 .setup = setup, 96 .producer_thread = producer, 97 .measure = measure, 98 .report_progress = ops_report_progress, 99 .report_final = ops_report_final, 100 }; 101