BPF 环形缓冲区参数无效 (-22)?
BPF Ring Buffer Invalid Argument (-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
并做了 make
和 make install
。我正在使用 Linux 5.8.0 内核。
UPDATE:如果我把max_entries
改成4096 * 64之类的,问题似乎就解决了,但我不知道为什么会这样.
你是对的,问题出在 BPF_MAP_TYPE_RINGBUF 的大小(libbpf 映射定义中的 max_entries 属性)。它必须是内存页的倍数(在大多数流行平台上至少为 4096 字节)。所以这就解释了为什么当您指定 64 * 4096 时一切正常。
顺便说一句,如果你想看一些使用它的例子,我将从 BPF 自测开始:
我想使用 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 内核。
UPDATE:如果我把max_entries
改成4096 * 64之类的,问题似乎就解决了,但我不知道为什么会这样.
你是对的,问题出在 BPF_MAP_TYPE_RINGBUF 的大小(libbpf 映射定义中的 max_entries 属性)。它必须是内存页的倍数(在大多数流行平台上至少为 4096 字节)。所以这就解释了为什么当您指定 64 * 4096 时一切正常。
顺便说一句,如果你想看一些使用它的例子,我将从 BPF 自测开始: