有没有一种方法可以从 eBPF 映射中读取数据,而无需支付内核调用 read / ppoll 添加的开销(因为它们是内核调用)。也许
mmap
传递了一些奇怪的参数?
是的,从内核 v5.5 [link] 开始,可以 mmap
BPF_MAP_TYPE_ARRAY
映射。此功能主要用于数组映射中的全局数据。 Libbpf 自动将全局数据映射到当前进程中,并在通过 bpf_map__set_initial_value
写入时使用此映射。您还可以通过 bpf_map__initial_value
访问整个地区。
请注意内核可能会施加一些限制。例如,最初不允许在数组映射值中包含自旋锁或计时器。此限制似乎已在 v5.5 和 v6.10 之间的某个位置取消,因此请记住在依赖全局数据以外的任何其他功能之前先在各种内核版本上进行测试。
v6.9 [link] 中引入了一个新功能,称为“BPF arena”,这是一个更通用的有用版本。本质上,您创建了一个类型为
BPF_MAP_TYPE_ARENA
的新映射,用户空间可以将其映射到内存中,从而允许用户空间和 BPF 程序访问内存区域。
一个主要区别是数组映射是预先分配的,而竞技场是动态分配的。因此,当您创建映射时,不会保留任何内存,每次您通过用户空间访问新的内存页面时,都会分配该页面。从 BPF 方面,您需要在使用页面之前使用特殊的 kfunc(
bpf_arena_alloc_pages
) 来分配页面。还可以使用 munmap 系统调用或 bpf_arena_free_pages
kfunc 来释放内存。
使用此功能需要最新的内核、clang 和 libbpf 版本。我建议阅读链接的补丁集以了解更多详细信息。