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 提供 LIFO(后进先出)存储。这些映射支持通过各自的辅助函数暴露给 BPF 程序的 peek(查看)、pop(弹出)和 push(压入)操作。这些操作通过以下方式使用现有的 bpf 系统调用暴露给用户空间应用程序:
BPF_MAP_LOOKUP_ELEM-> 查看BPF_MAP_LOOKUP_AND_DELETE_ELEM-> 弹出BPF_MAP_UPDATE_ELEM-> 压入
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/