1 // SPDX-License-Identifier: GPL-2.0
2 /* Copyright (c) 2020 Facebook */
3 #include "bench.h"
4 #include "trigger_bench.skel.h"
5 
6 /* BPF triggering benchmarks */
7 static struct trigger_ctx {
8 	struct trigger_bench *skel;
9 } ctx;
10 
11 static struct counter base_hits;
12 
13 static void trigger_validate()
14 {
15 	if (env.consumer_cnt != 1) {
16 		fprintf(stderr, "benchmark doesn't support multi-consumer!\n");
17 		exit(1);
18 	}
19 }
20 
21 static void *trigger_base_producer(void *input)
22 {
23 	while (true) {
24 		(void)syscall(__NR_getpgid);
25 		atomic_inc(&base_hits.value);
26 	}
27 	return NULL;
28 }
29 
30 static void trigger_base_measure(struct bench_res *res)
31 {
32 	res->hits = atomic_swap(&base_hits.value, 0);
33 }
34 
35 static void *trigger_producer(void *input)
36 {
37 	while (true)
38 		(void)syscall(__NR_getpgid);
39 	return NULL;
40 }
41 
42 static void trigger_measure(struct bench_res *res)
43 {
44 	res->hits = atomic_swap(&ctx.skel->bss->hits, 0);
45 }
46 
47 static void setup_ctx()
48 {
49 	setup_libbpf();
50 
51 	ctx.skel = trigger_bench__open_and_load();
52 	if (!ctx.skel) {
53 		fprintf(stderr, "failed to open skeleton\n");
54 		exit(1);
55 	}
56 }
57 
58 static void attach_bpf(struct bpf_program *prog)
59 {
60 	struct bpf_link *link;
61 
62 	link = bpf_program__attach(prog);
63 	if (IS_ERR(link)) {
64 		fprintf(stderr, "failed to attach program!\n");
65 		exit(1);
66 	}
67 }
68 
69 static void trigger_tp_setup()
70 {
71 	setup_ctx();
72 	attach_bpf(ctx.skel->progs.bench_trigger_tp);
73 }
74 
75 static void trigger_rawtp_setup()
76 {
77 	setup_ctx();
78 	attach_bpf(ctx.skel->progs.bench_trigger_raw_tp);
79 }
80 
81 static void trigger_kprobe_setup()
82 {
83 	setup_ctx();
84 	attach_bpf(ctx.skel->progs.bench_trigger_kprobe);
85 }
86 
87 static void trigger_fentry_setup()
88 {
89 	setup_ctx();
90 	attach_bpf(ctx.skel->progs.bench_trigger_fentry);
91 }
92 
93 static void trigger_fmodret_setup()
94 {
95 	setup_ctx();
96 	attach_bpf(ctx.skel->progs.bench_trigger_fmodret);
97 }
98 
99 static void *trigger_consumer(void *input)
100 {
101 	return NULL;
102 }
103 
104 const struct bench bench_trig_base = {
105 	.name = "trig-base",
106 	.validate = trigger_validate,
107 	.producer_thread = trigger_base_producer,
108 	.consumer_thread = trigger_consumer,
109 	.measure = trigger_base_measure,
110 	.report_progress = hits_drops_report_progress,
111 	.report_final = hits_drops_report_final,
112 };
113 
114 const struct bench bench_trig_tp = {
115 	.name = "trig-tp",
116 	.validate = trigger_validate,
117 	.setup = trigger_tp_setup,
118 	.producer_thread = trigger_producer,
119 	.consumer_thread = trigger_consumer,
120 	.measure = trigger_measure,
121 	.report_progress = hits_drops_report_progress,
122 	.report_final = hits_drops_report_final,
123 };
124 
125 const struct bench bench_trig_rawtp = {
126 	.name = "trig-rawtp",
127 	.validate = trigger_validate,
128 	.setup = trigger_rawtp_setup,
129 	.producer_thread = trigger_producer,
130 	.consumer_thread = trigger_consumer,
131 	.measure = trigger_measure,
132 	.report_progress = hits_drops_report_progress,
133 	.report_final = hits_drops_report_final,
134 };
135 
136 const struct bench bench_trig_kprobe = {
137 	.name = "trig-kprobe",
138 	.validate = trigger_validate,
139 	.setup = trigger_kprobe_setup,
140 	.producer_thread = trigger_producer,
141 	.consumer_thread = trigger_consumer,
142 	.measure = trigger_measure,
143 	.report_progress = hits_drops_report_progress,
144 	.report_final = hits_drops_report_final,
145 };
146 
147 const struct bench bench_trig_fentry = {
148 	.name = "trig-fentry",
149 	.validate = trigger_validate,
150 	.setup = trigger_fentry_setup,
151 	.producer_thread = trigger_producer,
152 	.consumer_thread = trigger_consumer,
153 	.measure = trigger_measure,
154 	.report_progress = hits_drops_report_progress,
155 	.report_final = hits_drops_report_final,
156 };
157 
158 const struct bench bench_trig_fmodret = {
159 	.name = "trig-fmodret",
160 	.validate = trigger_validate,
161 	.setup = trigger_fmodret_setup,
162 	.producer_thread = trigger_producer,
163 	.consumer_thread = trigger_consumer,
164 	.measure = trigger_measure,
165 	.report_progress = hits_drops_report_progress,
166 	.report_final = hits_drops_report_final,
167 };
168