BPF_MAP_TYPE_QUEUE 和 BPF_MAP_TYPE_STACK¶
注意
BPF_MAP_TYPE_QUEUE
和BPF_MAP_TYPE_STACK
在内核版本 4.20 中引入
BPF_MAP_TYPE_QUEUE
为 BPF 程序提供 FIFO 存储,BPF_MAP_TYPE_STACK
为 BPF 程序提供 LIFO 存储。这些映射支持 peek、pop 和 push 操作,这些操作通过各自的助手暴露给 BPF 程序。这些操作通过以下方式使用现有的 bpf
系统调用暴露给用户空间应用程序
BPF_MAP_LOOKUP_ELEM
-> peekBPF_MAP_LOOKUP_AND_DELETE_ELEM
-> popBPF_MAP_UPDATE_ELEM
-> push
BPF_MAP_TYPE_QUEUE
和 BPF_MAP_TYPE_STACK
不支持 BPF_F_NO_PREALLOC
。
用法¶
内核 BPF¶
bpf_map_push_elem()¶
long bpf_map_push_elem(struct bpf_map *map, const void *value, u64 flags)
可以使用 bpf_map_push_elem
助手将元素 value
添加到队列或堆栈中。flags
参数必须设置为 BPF_ANY
或 BPF_EXIST
。如果 flags
设置为 BPF_EXIST
,则当队列或堆栈已满时,将删除最旧的元素,以便为要添加的 value
腾出空间。成功时返回 0
,失败时返回负错误。
bpf_map_peek_elem()¶
long bpf_map_peek_elem(struct bpf_map *map, void *value)
此助手从队列或堆栈中获取元素 value
而不将其删除。成功时返回 0
,失败时返回负错误。
bpf_map_pop_elem()¶
long bpf_map_pop_elem(struct bpf_map *map, void *value)
此助手将元素从队列或堆栈中移除到 value
中。成功时返回 0
,失败时返回负错误。
用户空间¶
bpf_map_update_elem()¶
int bpf_map_update_elem (int fd, const void *key, const void *value, __u64 flags)
用户空间程序可以使用 libbpf 的 bpf_map_update_elem
函数将 value
推入队列或堆栈。 key
参数必须设置为 NULL
,flags
必须设置为 BPF_ANY
或 BPF_EXIST
,其语义与 bpf_map_push_elem
内核助手相同。成功时返回 0
,失败时返回负错误。
bpf_map_lookup_elem()¶
int bpf_map_lookup_elem (int fd, const void *key, void *value)
用户空间程序可以使用 libbpf bpf_map_lookup_elem
函数查看队列或堆栈头部的 value
。 key
参数必须设置为 NULL
。成功时返回 0
,失败时返回负错误。
bpf_map_lookup_and_delete_elem()¶
int bpf_map_lookup_and_delete_elem (int fd, const void *key, void *value)
用户空间程序可以使用 libbpf bpf_map_lookup_and_delete_elem
函数从队列或堆栈的头部弹出 value
。 key
参数必须设置为 NULL
。成功时返回 0
,失败时返回负错误。
示例¶
内核 BPF¶
此代码段显示如何在 BPF 程序中声明队列
struct {
__uint(type, BPF_MAP_TYPE_QUEUE);
__type(value, __u32);
__uint(max_entries, 10);
} queue SEC(".maps");
用户空间¶
此代码段显示如何使用 libbpf 的低级 API 从用户空间创建队列
int create_queue()
{
return bpf_map_create(BPF_MAP_TYPE_QUEUE,
"sample_queue", /* name */
0, /* key size, must be zero */
sizeof(__u32), /* value size */
10, /* max entries */
NULL); /* create options */
}
参考资料¶
https://lwn.net/ml/netdev/153986858555.9127.14517764371945179514.stgit@kernel/