1 // SPDX-License-Identifier: GPL-2.0
2 /* Copyright (c) 2020 Facebook */
3 #include <fcntl.h>
4 #include "bench.h"
5 #include "test_overhead.skel.h"
6 
7 /* BPF triggering benchmarks */
8 static struct ctx {
9 	struct test_overhead *skel;
10 	struct counter hits;
11 	int fd;
12 } ctx;
13 
14 static void validate()
15 {
16 	if (env.producer_cnt != 1) {
17 		fprintf(stderr, "benchmark doesn't support multi-producer!\n");
18 		exit(1);
19 	}
20 	if (env.consumer_cnt != 1) {
21 		fprintf(stderr, "benchmark doesn't support multi-consumer!\n");
22 		exit(1);
23 	}
24 }
25 
26 static void *producer(void *input)
27 {
28 	char buf[] = "test_overhead";
29 	int err;
30 
31 	while (true) {
32 		err = write(ctx.fd, buf, sizeof(buf));
33 		if (err < 0) {
34 			fprintf(stderr, "write failed\n");
35 			exit(1);
36 		}
37 		atomic_inc(&ctx.hits.value);
38 	}
39 }
40 
41 static void measure(struct bench_res *res)
42 {
43 	res->hits = atomic_swap(&ctx.hits.value, 0);
44 }
45 
46 static void setup_ctx()
47 {
48 	setup_libbpf();
49 
50 	ctx.skel = test_overhead__open_and_load();
51 	if (!ctx.skel) {
52 		fprintf(stderr, "failed to open skeleton\n");
53 		exit(1);
54 	}
55 
56 	ctx.fd = open("/proc/self/comm", O_WRONLY|O_TRUNC);
57 	if (ctx.fd < 0) {
58 		fprintf(stderr, "failed to open /proc/self/comm: %d\n", -errno);
59 		exit(1);
60 	}
61 }
62 
63 static void attach_bpf(struct bpf_program *prog)
64 {
65 	struct bpf_link *link;
66 
67 	link = bpf_program__attach(prog);
68 	if (IS_ERR(link)) {
69 		fprintf(stderr, "failed to attach program!\n");
70 		exit(1);
71 	}
72 }
73 
74 static void setup_base()
75 {
76 	setup_ctx();
77 }
78 
79 static void setup_kprobe()
80 {
81 	setup_ctx();
82 	attach_bpf(ctx.skel->progs.prog1);
83 }
84 
85 static void setup_kretprobe()
86 {
87 	setup_ctx();
88 	attach_bpf(ctx.skel->progs.prog2);
89 }
90 
91 static void setup_rawtp()
92 {
93 	setup_ctx();
94 	attach_bpf(ctx.skel->progs.prog3);
95 }
96 
97 static void setup_fentry()
98 {
99 	setup_ctx();
100 	attach_bpf(ctx.skel->progs.prog4);
101 }
102 
103 static void setup_fexit()
104 {
105 	setup_ctx();
106 	attach_bpf(ctx.skel->progs.prog5);
107 }
108 
109 static void setup_fmodret()
110 {
111 	setup_ctx();
112 	attach_bpf(ctx.skel->progs.prog6);
113 }
114 
115 static void *consumer(void *input)
116 {
117 	return NULL;
118 }
119 
120 const struct bench bench_rename_base = {
121 	.name = "rename-base",
122 	.validate = validate,
123 	.setup = setup_base,
124 	.producer_thread = producer,
125 	.consumer_thread = consumer,
126 	.measure = measure,
127 	.report_progress = hits_drops_report_progress,
128 	.report_final = hits_drops_report_final,
129 };
130 
131 const struct bench bench_rename_kprobe = {
132 	.name = "rename-kprobe",
133 	.validate = validate,
134 	.setup = setup_kprobe,
135 	.producer_thread = producer,
136 	.consumer_thread = consumer,
137 	.measure = measure,
138 	.report_progress = hits_drops_report_progress,
139 	.report_final = hits_drops_report_final,
140 };
141 
142 const struct bench bench_rename_kretprobe = {
143 	.name = "rename-kretprobe",
144 	.validate = validate,
145 	.setup = setup_kretprobe,
146 	.producer_thread = producer,
147 	.consumer_thread = consumer,
148 	.measure = measure,
149 	.report_progress = hits_drops_report_progress,
150 	.report_final = hits_drops_report_final,
151 };
152 
153 const struct bench bench_rename_rawtp = {
154 	.name = "rename-rawtp",
155 	.validate = validate,
156 	.setup = setup_rawtp,
157 	.producer_thread = producer,
158 	.consumer_thread = consumer,
159 	.measure = measure,
160 	.report_progress = hits_drops_report_progress,
161 	.report_final = hits_drops_report_final,
162 };
163 
164 const struct bench bench_rename_fentry = {
165 	.name = "rename-fentry",
166 	.validate = validate,
167 	.setup = setup_fentry,
168 	.producer_thread = producer,
169 	.consumer_thread = consumer,
170 	.measure = measure,
171 	.report_progress = hits_drops_report_progress,
172 	.report_final = hits_drops_report_final,
173 };
174 
175 const struct bench bench_rename_fexit = {
176 	.name = "rename-fexit",
177 	.validate = validate,
178 	.setup = setup_fexit,
179 	.producer_thread = producer,
180 	.consumer_thread = consumer,
181 	.measure = measure,
182 	.report_progress = hits_drops_report_progress,
183 	.report_final = hits_drops_report_final,
184 };
185 
186 const struct bench bench_rename_fmodret = {
187 	.name = "rename-fmodret",
188 	.validate = validate,
189 	.setup = setup_fmodret,
190 	.producer_thread = producer,
191 	.consumer_thread = consumer,
192 	.measure = measure,
193 	.report_progress = hits_drops_report_progress,
194 	.report_final = hits_drops_report_final,
195 };
196