最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

c - Why can I not add the return value of __fetch_and_sync to a map in an eBPF program? - Stack Overflow

programmeradmin1浏览0评论

Title pretty much sums it up. I'm trying to run this eBPF program but I keep getting the following error when running:

libbpf: prog 'do_entry_point': BPF program load failed: Invalid argument
libbpf: prog 'do_entry_point': -- BEGIN PROG LOAD LOG --
BPF_STX uses reserved fields
processed 0 insns (limit 1000000) max_states_per_insn 0 total_states 0 peak_states 0 mark_read 0
-- END PROG LOAD LOG --
libbpf: prog 'do_entry_point': failed to load: -22
libbpf: failed to load object 'demo_bpf'
libbpf: failed to load BPF skeleton 'demo_bpf': -22
Failed to open and load BPF skeleton

I've narrowed it down that it does not like the when I add the return of __sync_fetch_and_add to the event struct and load it in the map but I can't figure out why or how to do this. I'm running on kernel 5.10.

Here is the repro code:

demo.bpf.c

#include <vmlinux.h>
#include <bpf/bpf_helpers.h>
#include <bpf/bpf_tracing.h>
#include <bpf/bpf_core_read.h>

#include "demo.h"

struct
{
    __uint(type, BPF_MAP_TYPE_RINGBUF);
    __uint(max_entries, 1024 * 1024);
} traceevents SEC(".maps");

struct
{
    __uint(type, BPF_MAP_TYPE_ARRAY);
    __uint(max_entries, 1);
    __type(key, u32);
    __type(value, u64);
} counters SEC(".maps");

static void fill_and_submit(struct pt_regs *ctx, u8 entry)
{
    struct event *e = bpf_ringbuf_reserve(&traceevents,
                                          sizeof(struct event),
                                          0);
    if (!e)
    {
        return;
    }

    u32 key = 0;
    u64 *count = bpf_map_lookup_elem(&counters, &key);
    e->id = 0;
    if (count)
    {
        e->id = __sync_fetch_and_add(count, 1);
    }

    e->timestamp = bpf_ktime_get_ns();
    e->entry = entry;
    bpf_ringbuf_submit(e, 0);
}

SEC("uprobe")
int do_entry_point(struct pt_regs *ctx)
{
    fill_and_submit(ctx, 1);
    return 0;
}

char LICENSE[] SEC("license") = "GPL";

demo.c

#include <stdio.h>
#include <unistd.h>
#include <signal.h>
#include <getopt.h>
#include <bpf/libbpf.h>
#include <bpf/bpf.h>
#include <sys/mman.h>

#include "demo.skel.h"
#include "demo.h"
#include <linux/limits.h>

static volatile bool exiting = false;

static void sig_handler(int sig)
{
    exiting = true;
}

static int handle_event(void *ctx, void *data, size_t data_sz)
{
    printf("Read event\n");
    return 0;
}

int main(int argc, char **argv)
{
    struct ring_buffer *rb_event = NULL;
    struct demo_bpf *skel;
    int err = 0;

    skel = demo_bpf__open_and_load();
    if (!skel)
    {
        fprintf(stderr, "Failed to open and load BPF skeleton\n");
        return 1;
    }

    LIBBPF_OPTS(bpf_uprobe_opts, uprobe_opts);
    uprobe_opts.func_name = "my_func";
    uprobe_opts.retprobe = false;

    skel->links.do_entry_point = bpf_program__attach_uprobe_opts(skel->progs.do_entry_point,
                                                                 -1,
                                                                 argv[1],
                                                                 0,
                                                                 &uprobe_opts);

    signal(SIGINT, sig_handler);
    signal(SIGTERM, sig_handler);

    rb_event = ring_buffer__new(bpf_map__fd(skel->maps.traceevents),
                                handle_event, NULL, NULL);
    if (!rb_event)
    {
        err = -1;
        fprintf(stderr, "Failed to create trace_event ring buffer\n");
        return -1;
    }

    printf("Successfully started! Tracing functions....\n");

    while (!exiting)
    {
        err = ring_buffer__poll(rb_event, 100);
        if (err < 0 && err != -EINTR)
        {
            fprintf(stderr, "Error polling ring buffer: %d\n", err);
            break;
        }
    }

    demo_bpf__destroy(skel);

    return 0;
}

demo.h

struct event
{
    // identity
    __u64 id;
    __u64 timestamp;
    __u8 entry;
};

Edit:

Build commands

clang -g -O2 -target bpf -D__TARGET_ARCH_x86 -I. -c demo/demo.bpf.c -o demo/demo.bpf.o
bpftool gen skeleton demo/demo.bpf.o > demo/demo.skel.h
clang -Wchar-subscripts -Wcomment -Wformat -Winit-self -Wmain -Wmissing-braces -Wno-pragmas -Wparentheses -Wreturn-type -Wsequence-point -Wstrict-aliasing -Wswitch -Wtrigraphs -Wuninitialized -Wunknown-pragmas -Wunused-label -Wunused-variable -Wunused-value -Wpointer-sign -Wimplicit -pthread -fdiagnostics-color=auto -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS -fuse-init-array -O3 -msse -mfpmath=sse -march=core2 -g -fPIC  -I./demo -o demo demo/demo.o -pthread -Wl,-lpthread -Wl,--enable-new-dtags -Wl,--as-needed -g -lelf -lz -lbpf -ldw
发布评论

评论列表(0)

  1. 暂无评论