暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

bpf架构 - Object Pinning和Tail Calls篇

囧囧妹 2022-07-29
181

点击上方蓝字【囧囧妹】一起学习,一起成长!

一、Object Pinning

BPF 映射和程序充当内核资源,只能通过文件描述符访问,并由内核中的匿名 inode 支持。优点,但也有一些缺点:
用户空间应用程序可以使用大多数与文件描述符相关的 API,为 Unix 域套接字传递的文件描述符透明地工作等,但同时,文件描述符仅限于进程的生命周期,这使得地图共享等选项相当麻烦执行。
因此,它为某些用例带来了许多复杂性,例如 iproute2,其中 tc 或 XDP 设置并将程序加载到内核中并最终自行终止。这样,从用户空间端也无法访问地图,否则它可能很有用,例如,当地图在数据路径的入口和出口位置之间共享时。此外,第三方应用程序可能希望在 BPF 程序运行期间监视或更新地图内容。
为了克服这个限制,实现了一个最小内核空间的 BPF 文件系统,其中 BPF 映射和程序可以被固定到,这个过程称为对象固定。因此,BPF 系统调用扩展了两个新命令,它们可以固定(BPF_OBJ_PIN
)或检索(BPF_OBJ_GET
)先前固定的对象。
例如,像 tc 这样的工具利用这个基础设施来共享入口和出口的地图。BPF 相关的文件系统不是单例的,它确实支持多个挂载实例、硬链接和软链接等。

二、Tail Calls

可以与 BPF 一起使用的另一个概念称为尾调用。尾调用可以看作是一种机制,它允许一个 BPF 程序调用另一个程序,而不返回到旧程序。这样的调用具有最小的开销,因为与函数调用不同,它被实现为长跳转,重用相同的堆栈帧。
这样的程序相互独立验证,因此对于传输状态,无论是作为暂存缓冲区的每个 CPU 映射还是在 tc 程序的情况下,都必须使用skb
 诸如区域之类的字段。cb[]
只有同类型的程序才能被尾调用,而且它们在JIT编译方面也需要匹配,这样既可以调用JIT编译的程序,也可以调用只有解释程序的程序,但不能混在一起调用。
执行尾调用涉及两个组件:第一部分需要设置一个称为程序数组BPF_MAP_TYPE_PROG_ARRAY
(第二部分是一个 bpf_tail_call()
帮助器,其中传递了上下文、对程序数组的引用和查找键。然后内核将这个助手调用直接内联到专门的 BPF 指令中。这种程序数组目前在用户空间端是只写的。
内核从传递的文件描述符中查找相关的 BPF 程序,并原子地替换给定映射槽处的程序指针。当在提供的键上没有找到映射条目时,内核将“失败”并继续执行旧程序,并使用bpf_tail_call()
尾调用是一个强大的实用程序,例如,可以通过尾调用来构造解析网络标头。在运行时,可以自动添加或替换功能,从而改变 BPF 程序的执行行为。


觉得不错,点击“分享”,“赞”,“在看”传播给更多热爱嵌入式的小伙伴吧!

文章转载自囧囧妹,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论