文献阅读: bpftime: userspace eBPF Runtime for Uprobe, Syscall and Kernel-User Interactions

bpftime: userspace eBPF Runtime for Uprobe, Syscall and Kernel-User Interactions

论文作者:Yusheng Zheng, Tong Yu, Yiwei Yang, Yanpeng Hu, Xiaozheng Lai, Andrew Quinn

发表期刊:arXiv preprint arXiv:2311.07923

发表时间:December 2023

What

本文提出了 bpftime,一个用户态的 eBPF 运行时环境,用于 uprobe,syscall hook 和内核-用户通信。基于 bpftime 的 uprobe 获得了 10 倍的性能提升。此外,bpftime 还充分考虑了和 eBPF 生态的兼容性,原有的 eBPF 工具链仍然可以在该项目中继续使用,为 eBPF 开发者带来的便利。

bpftime 的特点:

  • High-Performance, general-purpose Userspace eBPF Runtime compatibility with existing eBPF echosystem:在实现传统 eBPF 用户态功能的基础上实现与现有 eBPF 生态兼容
  • Programmatic attaching mechanism and Seamless Runtime Injection for userspace eBPF:ebftime 可以在无需重新编译、无需重新运行的条件下,实现动态插装、注入
  • Working together with kernel eBPF and Extensible Feature Set:实现了与 kernel eBPF 协同工作

Why

下图为 kernel eBPF 的工作流:

传统的 eBPF 面临着性能和安全的双挑战:

  • 性能上,与 Uprobe 相关的上下文切换开销降低了性能

    当使用 eBPF 挂载到 uprobe 事件时,若用户态程序执行到勘测函数,则将陷入内核,运行 eBPF 程序,发生第一次上下文切换

    eBPF 运行完毕后,从内核态返回,发生第二次上下文切换

  • 安全上,eBPF 所要求的特权访问增加了攻击面,如 container escapes、kernel exploits

    eBPF 运行需要 root 权限,且它的运行时建立在内核空间,因此增加了攻击面。如果 kernel eBPF 运行时出了问题,那么内核将处于一种危险状态,影响整个系统。

但 eBPF & uprobe 被广泛应用1

  • 用户空间协议追踪:SSL、TLS、HTTP2
  • 内存分配、泄露监控
  • 等等

How

下图为 user eBPF 的工作流2

bpftime 的核心机制是将没必要在 kernel space 执行的操作提取出来,放到 user space 执行,从而减少了上下文切换次数。实际上,减少上下文切换次数是操作系统性能优化的一个主要方法。

实现策略包括:

  • bpf 系统调用捕获:通过 bpftime-syscall.so 捕获传统 eBPF 程序中 bpf 相关系统调用,将其转换为用户空间操作
  • 共享内存:通过共享内存的方式将 eBPF 字节码载入并创建 eBPF maps,于内核实现交互
  • ptrace/LD_PRELOAD:实现动态注入,增强了 bpftime 使用的灵活性
  • 动态链接:bpftime 本质上实现了 2 个库 bpftime-syscall.so 和 bpftime-agent.so,动态链接技术为 bpftime 的无缝插装提供了可能
  • “JIT compilation”:即时翻译技术使得 bpftime 运行时可以动态修改进程代码,从而实现 function/syscall hook

对于 uprobe 而言,这种机制能够减少上下文切换次数,从而提升性能;而对于 syscall hook,由于 syscall 本身就需要陷入内核,因此对性能影响不大。这一点在后面的性能测试中也得到了体现。

Test

Performance

作者运行了 micro-benchmarks 用于性能测试:

从结果来看,uprobe 性能获得了 10x 的提升,而 syscall hook 的性能反而下降了,但是在可接受范围内。

结论:用户态 uprobe 性能获得了显著的提升,可以作为内核态 uprobe 的替代。

Runtime Efficiency

这一部分测试了在不同使用场景下 bpftime LLVM JIT 其他用户态 eBPF 运行时、本地代码以及 WASM 的效率,为不同场景下的运行时选择提供了参考。

测试表明,bpftime LLVM JIT 在整数运算和复杂数学操作场景下性能表现优异。

Compatibility

这一部分对 bpftime 进行了兼容性分析,方法为将真实世界采用 bcc 开发的 eBPF 程序运行时更换为 bpftime。

结果表明原有的 eBPF 程序可以将运行时无缝迁移到 bpftime 上,并且功能是等效的。


  1. 1.https://github.com/plctlab/PLCT-Open-Reports/blob/master/slides/20230929-yunwei-bpftime-userspace-ebpf.pdf ↩︎
  2. 2.文章中的图片标题有误,应为“The Workflow of user eBPF runtime” ↩︎