xref: /linux/tools/testing/selftests/bpf/benchs/bench_bpf_loop.c (revision 34dc1baba215b826e454b8d19e4f24adbeb7d00d)
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