mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git
synced 2025-01-16 21:35:07 +00:00
d4fffba4d0
Currently old compile rule (CLANG-bpf) doesn't contains VMLINUX_H define flag which is essential for the bpf program that includes "vmlinux.h". Also old compile rule doesn't directly specify the compile target as bpf, instead it uses bunch of extra options with clang followed by long chain of commands. (e.g. clang | opt | llvm-dis | llc) In Makefile, there is already new compile rule which is more simple and neat. And it also has -D__VMLINUX_H__ option. By just changing the _kern suffix to .bpf will inherit the benefit of the new CLANG-BPF compile target. Also, this commit adds dummy gnu/stub.h to the samples/bpf directory. As commit 1c2dd16add7e ("selftests/bpf: get rid of -D__x86_64__") noted, compiling with 'clang -target bpf' will raise an error with stubs.h unless workaround (-D__x86_64) is used. This commit solves this problem by adding dummy stub.h to make /usr/include/features.h to follow the expected path as the same way selftests/bpf dealt with. Signed-off-by: Daniel T. Lee <danieltimlee@gmail.com> Signed-off-by: Andrii Nakryiko <andrii@kernel.org> Link: https://lore.kernel.org/bpf/20221224071527.2292-4-danieltimlee@gmail.com
106 lines
2.2 KiB
C
106 lines
2.2 KiB
C
// SPDX-License-Identifier: GPL-2.0-only
|
|
#include <stdio.h>
|
|
#include <fcntl.h>
|
|
#include <poll.h>
|
|
#include <time.h>
|
|
#include <signal.h>
|
|
#include <bpf/libbpf.h>
|
|
|
|
static __u64 time_get_ns(void)
|
|
{
|
|
struct timespec ts;
|
|
|
|
clock_gettime(CLOCK_MONOTONIC, &ts);
|
|
return ts.tv_sec * 1000000000ull + ts.tv_nsec;
|
|
}
|
|
|
|
static __u64 start_time;
|
|
static __u64 cnt;
|
|
|
|
#define MAX_CNT 100000ll
|
|
|
|
static void print_bpf_output(void *ctx, int cpu, void *data, __u32 size)
|
|
{
|
|
struct {
|
|
__u64 pid;
|
|
__u64 cookie;
|
|
} *e = data;
|
|
|
|
if (e->cookie != 0x12345678) {
|
|
printf("BUG pid %llx cookie %llx sized %d\n",
|
|
e->pid, e->cookie, size);
|
|
return;
|
|
}
|
|
|
|
cnt++;
|
|
|
|
if (cnt == MAX_CNT) {
|
|
printf("recv %lld events per sec\n",
|
|
MAX_CNT * 1000000000ll / (time_get_ns() - start_time));
|
|
return;
|
|
}
|
|
}
|
|
|
|
int main(int argc, char **argv)
|
|
{
|
|
struct bpf_link *link = NULL;
|
|
struct bpf_program *prog;
|
|
struct perf_buffer *pb;
|
|
struct bpf_object *obj;
|
|
int map_fd, ret = 0;
|
|
char filename[256];
|
|
FILE *f;
|
|
|
|
snprintf(filename, sizeof(filename), "%s.bpf.o", argv[0]);
|
|
obj = bpf_object__open_file(filename, NULL);
|
|
if (libbpf_get_error(obj)) {
|
|
fprintf(stderr, "ERROR: opening BPF object file failed\n");
|
|
return 0;
|
|
}
|
|
|
|
/* load BPF program */
|
|
if (bpf_object__load(obj)) {
|
|
fprintf(stderr, "ERROR: loading BPF object file failed\n");
|
|
goto cleanup;
|
|
}
|
|
|
|
map_fd = bpf_object__find_map_fd_by_name(obj, "my_map");
|
|
if (map_fd < 0) {
|
|
fprintf(stderr, "ERROR: finding a map in obj file failed\n");
|
|
goto cleanup;
|
|
}
|
|
|
|
prog = bpf_object__find_program_by_name(obj, "bpf_prog1");
|
|
if (libbpf_get_error(prog)) {
|
|
fprintf(stderr, "ERROR: finding a prog in obj file failed\n");
|
|
goto cleanup;
|
|
}
|
|
|
|
link = bpf_program__attach(prog);
|
|
if (libbpf_get_error(link)) {
|
|
fprintf(stderr, "ERROR: bpf_program__attach failed\n");
|
|
link = NULL;
|
|
goto cleanup;
|
|
}
|
|
|
|
pb = perf_buffer__new(map_fd, 8, print_bpf_output, NULL, NULL, NULL);
|
|
ret = libbpf_get_error(pb);
|
|
if (ret) {
|
|
printf("failed to setup perf_buffer: %d\n", ret);
|
|
return 1;
|
|
}
|
|
|
|
f = popen("taskset 1 dd if=/dev/zero of=/dev/null", "r");
|
|
(void) f;
|
|
|
|
start_time = time_get_ns();
|
|
while ((ret = perf_buffer__poll(pb, 1000)) >= 0 && cnt < MAX_CNT) {
|
|
}
|
|
kill(0, SIGINT);
|
|
|
|
cleanup:
|
|
bpf_link__destroy(link);
|
|
bpf_object__close(obj);
|
|
return ret;
|
|
}
|