BPF环形缓冲区无效参数-22?

问题描述

我想使用eBPF的最新地图BPF_MAP_TYPE_RINGBUF,但是我在网上找不到太多有关如何使用它的信息,因此我只是在这里做一些反复试验。我这样定义和使用它:

struct bpf_map_def SEC("maps") r_buf = {
    .type = BPF_MAP_TYPE_RINGBUF,.max_entries = 1 << 2,};

SEC("lsm/task_alloc")
int BPF_PROG(task_alloc,struct task_struct *task,unsigned long clone_flags) {
    uint32_t pid  = task->pid;
    bpf_ringbuf_output(&r_buf,&pid,sizeof(uint32_t),0); //stores the pid value to the ring buffer
    return 0;
}

但是运行时出现以下错误

libbpf: map 'r_buf': Failed to create: Invalid argument(-22)
libbpf: Failed to load object 'bpf_example_kern'
libbpf: Failed to load BPF skeleton 'bpf_example_kern': -22

似乎libbpf无法识别BPF_MAP_TYPE_RINGBUF?我从GitHub克隆了最新的libbpf,并做了makemake install。我正在使用Linux 5.8.0内核。

更新:如果我将max_entries更改为4096 * 64之类的问题,似乎可以解决,但我不知道为什么会这样。

解决方法

是的,问题出在BPF_MAP_TYPE_RINGBUF的大小(libbpf映射定义中的max_entries属性)。它必须是内存页的倍数(在大多数流行的平台上至少为4096字节)。因此,这说明了为什么当您指定64 * 4096时,它们都可以工作。

顺便说一句,如果您想看一些使用它的示例,我将从BPF自测开始: