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 */
7static struct trigger_ctx {
8	struct trigger_bench *skel;
9} ctx;
10
11static struct counter base_hits;
12
13static 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
21static 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
30static void trigger_base_measure(struct bench_res *res)
31{
32	res->hits = atomic_swap(&base_hits.value, 0);
33}
34
35static void *trigger_producer(void *input)
36{
37	while (true)
38		(void)syscall(__NR_getpgid);
39	return NULL;
40}
41
42static void trigger_measure(struct bench_res *res)
43{
44	res->hits = atomic_swap(&ctx.skel->bss->hits, 0);
45}
46
47static 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
58static 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
69static void trigger_tp_setup()
70{
71	setup_ctx();
72	attach_bpf(ctx.skel->progs.bench_trigger_tp);
73}
74
75static void trigger_rawtp_setup()
76{
77	setup_ctx();
78	attach_bpf(ctx.skel->progs.bench_trigger_raw_tp);
79}
80
81static void trigger_kprobe_setup()
82{
83	setup_ctx();
84	attach_bpf(ctx.skel->progs.bench_trigger_kprobe);
85}
86
87static void trigger_fentry_setup()
88{
89	setup_ctx();
90	attach_bpf(ctx.skel->progs.bench_trigger_fentry);
91}
92
93static void trigger_fentry_sleep_setup()
94{
95	setup_ctx();
96	attach_bpf(ctx.skel->progs.bench_trigger_fentry_sleep);
97}
98
99static void trigger_fmodret_setup()
100{
101	setup_ctx();
102	attach_bpf(ctx.skel->progs.bench_trigger_fmodret);
103}
104
105static void *trigger_consumer(void *input)
106{
107	return NULL;
108}
109
110const 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
120const 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
131const 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
142const 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
153const 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
164const 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
175const 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