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