问题描述
我想使用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
,并做了make
和make install
。我正在使用Linux 5.8.0内核。
更新:如果我将max_entries
更改为4096 * 64之类的问题,似乎可以解决,但我不知道为什么会这样。
解决方法
是的,问题出在BPF_MAP_TYPE_RINGBUF的大小(libbpf映射定义中的max_entries属性)。它必须是内存页的倍数(在大多数流行的平台上至少为4096字节)。因此,这说明了为什么当您指定64 * 4096时,它们都可以工作。
顺便说一句,如果您想看一些使用它的示例,我将从BPF自测开始: