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_fentry_sleep_setup()
94 {
95 	setup_ctx();
96 	attach_bpf(ctx.skel->progs.bench_trigger_fentry_sleep);
97 }
98 
99 static void trigger_fmodret_setup()
100 {
101 	setup_ctx();
102 	attach_bpf(ctx.skel->progs.bench_trigger_fmodret);
103 }
104 
105 static void *trigger_consumer(void *input)
106 {
107 	return NULL;
108 }
109 
110 const struct bench bench_trig_base = {
111 	.name = "trig-base",
112 	.validate = trigger_validate,
113 	.producer_thread = trigger_base_producer,
114 	.consumer_thread = trigger_consumer,
115 	.measure = trigger_base_measure,
116 	.report_progress = hits_drops_report_progress,
117 	.report_final = hits_drops_report_final,
118 };
119 
120 const struct bench bench_trig_tp = {
121 	.name = "trig-tp",
122 	.validate = trigger_validate,
123 	.setup = trigger_tp_setup,
124 	.producer_thread = trigger_producer,
125 	.consumer_thread = trigger_consumer,
126 	.measure = trigger_measure,
127 	.report_progress = hits_drops_report_progress,
128 	.report_final = hits_drops_report_final,
129 };
130 
131 const struct bench bench_trig_rawtp = {
132 	.name = "trig-rawtp",
133 	.validate = trigger_validate,
134 	.setup = trigger_rawtp_setup,
135 	.producer_thread = trigger_producer,
136 	.consumer_thread = trigger_consumer,
137 	.measure = trigger_measure,
138 	.report_progress = hits_drops_report_progress,
139 	.report_final = hits_drops_report_final,
140 };
141 
142 const struct bench bench_trig_kprobe = {
143 	.name = "trig-kprobe",
144 	.validate = trigger_validate,
145 	.setup = trigger_kprobe_setup,
146 	.producer_thread = trigger_producer,
147 	.consumer_thread = trigger_consumer,
148 	.measure = trigger_measure,
149 	.report_progress = hits_drops_report_progress,
150 	.report_final = hits_drops_report_final,
151 };
152 
153 const struct bench bench_trig_fentry = {
154 	.name = "trig-fentry",
155 	.validate = trigger_validate,
156 	.setup = trigger_fentry_setup,
157 	.producer_thread = trigger_producer,
158 	.consumer_thread = trigger_consumer,
159 	.measure = trigger_measure,
160 	.report_progress = hits_drops_report_progress,
161 	.report_final = hits_drops_report_final,
162 };
163 
164 const struct bench bench_trig_fentry_sleep = {
165 	.name = "trig-fentry-sleep",
166 	.validate = trigger_validate,
167 	.setup = trigger_fentry_sleep_setup,
168 	.producer_thread = trigger_producer,
169 	.consumer_thread = trigger_consumer,
170 	.measure = trigger_measure,
171 	.report_progress = hits_drops_report_progress,
172 	.report_final = hits_drops_report_final,
173 };
174 
175 const struct bench bench_trig_fmodret = {
176 	.name = "trig-fmodret",
177 	.validate = trigger_validate,
178 	.setup = trigger_fmodret_setup,
179 	.producer_thread = trigger_producer,
180 	.consumer_thread = trigger_consumer,
181 	.measure = trigger_measure,
182 	.report_progress = hits_drops_report_progress,
183 	.report_final = hits_drops_report_final,
184 };
185