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/