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 */
8static struct ctx {
9	struct test_overhead *skel;
10	struct counter hits;
11	int fd;
12} ctx;
13
14static 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
26static 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
41static void measure(struct bench_res *res)
42{
43	res->hits = atomic_swap(&ctx.hits.value, 0);
44}
45
46static 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
63static 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
74static void setup_base()
75{
76	setup_ctx();
77}
78
79static void setup_kprobe()
80{
81	setup_ctx();
82	attach_bpf(ctx.skel->progs.prog1);
83}
84
85static void setup_kretprobe()
86{
87	setup_ctx();
88	attach_bpf(ctx.skel->progs.prog2);
89}
90
91static void setup_rawtp()
92{
93	setup_ctx();
94	attach_bpf(ctx.skel->progs.prog3);
95}
96
97static void setup_fentry()
98{
99	setup_ctx();
100	attach_bpf(ctx.skel->progs.prog4);
101}
102
103static void setup_fexit()
104{
105	setup_ctx();
106	attach_bpf(ctx.skel->progs.prog5);
107}
108
109static void *consumer(void *input)
110{
111	return NULL;
112}
113
114const struct bench bench_rename_base = {
115	.name = "rename-base",
116	.validate = validate,
117	.setup = setup_base,
118	.producer_thread = producer,
119	.consumer_thread = consumer,
120	.measure = measure,
121	.report_progress = hits_drops_report_progress,
122	.report_final = hits_drops_report_final,
123};
124
125const struct bench bench_rename_kprobe = {
126	.name = "rename-kprobe",
127	.validate = validate,
128	.setup = setup_kprobe,
129	.producer_thread = producer,
130	.consumer_thread = consumer,
131	.measure = measure,
132	.report_progress = hits_drops_report_progress,
133	.report_final = hits_drops_report_final,
134};
135
136const struct bench bench_rename_kretprobe = {
137	.name = "rename-kretprobe",
138	.validate = validate,
139	.setup = setup_kretprobe,
140	.producer_thread = producer,
141	.consumer_thread = consumer,
142	.measure = measure,
143	.report_progress = hits_drops_report_progress,
144	.report_final = hits_drops_report_final,
145};
146
147const struct bench bench_rename_rawtp = {
148	.name = "rename-rawtp",
149	.validate = validate,
150	.setup = setup_rawtp,
151	.producer_thread = producer,
152	.consumer_thread = consumer,
153	.measure = measure,
154	.report_progress = hits_drops_report_progress,
155	.report_final = hits_drops_report_final,
156};
157
158const struct bench bench_rename_fentry = {
159	.name = "rename-fentry",
160	.validate = validate,
161	.setup = setup_fentry,
162	.producer_thread = producer,
163	.consumer_thread = consumer,
164	.measure = measure,
165	.report_progress = hits_drops_report_progress,
166	.report_final = hits_drops_report_final,
167};
168
169const struct bench bench_rename_fexit = {
170	.name = "rename-fexit",
171	.validate = validate,
172	.setup = setup_fexit,
173	.producer_thread = producer,
174	.consumer_thread = consumer,
175	.measure = measure,
176	.report_progress = hits_drops_report_progress,
177	.report_final = hits_drops_report_final,
178};
179