eBPF 编程深入解析:函数调用与尾调用
1. eBPF 中的上下文信息获取
eBPF 程序不仅可以展示环形缓冲区映射的使用,还能通过一些辅助函数来获取触发程序运行的事件的上下文信息。例如,我们可以使用辅助函数获取用户 ID、进程 ID 以及当前命令的名称。这些上下文信息对于可观测性至关重要,当事件发生时,eBPF 程序不仅能报告事件本身,还能提供触发该事件的相关信息。而且,由于所有信息都能在内核中收集,无需同步切换到用户空间,因此性能非常高。
2. eBPF 中的函数调用
在软件开发中,将公共代码提取到一个函数中,以便从多个地方调用,是一种良好的实践,这一原则常被称为“DRY”(“Don’t Repeat Yourself”)。然而,在早期,eBPF 程序只能调用内核提供的辅助函数,不能调用其他函数。为了解决这个问题,程序员会指示编译器将函数“始终内联”,示例代码如下:
static __always_inline void my_function(void *ctx, int val)
通常,源代码中的函数会使编译器发出跳转指令,执行会跳转到被调用函数的指令集,函数完成后再跳转回来。而内联函数则不会发出跳转指令,而是将函数的指令直接复制到调用函数中。
从 Linux 内核 4.16 和 LLVM 6.0 开始,函数必须内联的限制被取消,eBPF 程序员可以更自然地编写函数调用。不过,“BPF 到 BPF 函数调用”或“BPF 子程序”这一特性目前还未得到 BCC 框架的支持。
下面是普通函数调用和内联函数调用的区别示意图:
超级会员免费看
订阅专栏 解锁全文
81

被折叠的 条评论
为什么被折叠?



