eunomia-bpf / bpftime

Userspace eBPF runtime for Observability, Network & General Extensions Framework
https://eunomia.dev/bpftime/
MIT License
788 stars 74 forks source link
ebpf instrumentation jit llvm runtime syscall-tracing uprobes userspace

bpftime: Userspace eBPF runtime for Observability, Network & General extensions Framework

Build and Test VM Build and test runtime DOI

bpftime is a High-Performance userspace eBPF runtime and General Extension Framework designed for userspace. It enables faster Uprobe, USDT, Syscall hooks, XDP, and more event sources by bypassing the kernel and utilizing an optimized compiler like LLVM.

📦 Key Features \ 🔨 Quick Start \ 🔌 Examples & Use Cases \ ⌨️ Linux Plumbers 23 talk \ 📖 Slides \ 📚 Arxiv preprint

Checkout our documents in eunomia.dev!

bpftime is not userspace eBPF VM, it's a userspace runtime framework includes everything to run eBPF in userspace: loader, verifier, helpers, maps, ufunc and multiple events such as Observability, Network, Policy or Access Control. It has multiple VM backend options support. For eBPF VM only, please see llvmbpf.

⚠️ Note: bpftime is currently under active development and refactoring towards v2. It may contain bugs or unstable API. Please use it with caution. For more details, check our roadmap. We'd love to hear your feedback and suggestions! Feel free to open an issue or Contact us.

Why bpftime? What's the design Goal?

Key Features

Components

Quick Start: Uprobe

With bpftime, you can build eBPF applications using familiar tools like clang and libbpf, and execute them in userspace. For instance, the malloc eBPF program traces malloc calls using uprobe and aggregates the counts using a hash map.

You can refer to eunomia.dev/bpftime/documents/build-and-test for how to build the project, or using the container images from GitHub packages.

To get started, you can build and run a libbpf based eBPF program starts with bpftime cli:

make -C example/malloc # Build the eBPF program example
export PATH=$PATH:~/.bpftime/
bpftime load ./example/malloc/malloc

In another shell, Run the target program with eBPF inside:

$ bpftime start ./example/malloc/victim
Hello malloc!
malloc called from pid 250215
continue malloc...
malloc called from pid 250215

You can also dynamically attach the eBPF program with a running process:

$ ./example/malloc/victim & echo $! # The pid is 101771
[1] 101771
101771
continue malloc...
continue malloc...

And attach to it:

$ sudo bpftime attach 101771 # You may need to run make install in root
Inject: "/root/.bpftime/libbpftime-agent.so"
Successfully injected. ID: 1

You can see the output from original program:

$ bpftime load ./example/malloc/malloc
...
12:44:35 
        pid=247299      malloc calls: 10
        pid=247322      malloc calls: 10

Alternatively, you can also run our sample eBPF program directly in the kernel eBPF, to see the similar output. This can be an example of how bpftime can work compatibly with kernel eBPF.

$ sudo example/malloc/malloc
15:38:05
        pid=30415       malloc calls: 1079
        pid=30393       malloc calls: 203
        pid=29882       malloc calls: 1076
        pid=34809       malloc calls: 8

See eunomia.dev/bpftime/documents/usage for more details.

Examples & Use Cases

For more examples and details, please refer to eunomia.dev/bpftime/documents/examples/ webpage.

Examples including:

In-Depth

How it Works

bpftime supports two modes:

Running in userspace only

Left: original kernel eBPF | Right: bpftime

How it works

In this mode, bpftime can run eBPF programs in userspace without kernel, so it can be ported into low version of Linux or event other systems, and running without root permissions. It relies on a userspace verifier to ensure the safety of eBPF programs.

Run with kernel eBPF

documents/bpftime-kernel.png

In this mode, bpftime can run together with kernel eBPF. It can load eBPF programs from kernel, and using kernel eBPF maps to cooperate with kernel eBPF programs like kprobes and network filters.

Instrumentation implementation

Current hook implementation is based on binary rewriting and the underly technique is inspired by:

The hook can be easily replaced with other DBI methods or frameworks, or add more hook mechanisms in the future.

See our draft arxiv paper bpftime: userspace eBPF Runtime for Uprobe, Syscall and Kernel-User Interactions for details.

Performance Benchmarks

How is the performance of userspace uprobe compared to kernel uprobes?

Probe/Tracepoint Types Kernel (ns) Userspace (ns)
Uprobe 3224.172760 314.569110
Uretprobe 3996.799580 381.270270
Syscall Tracepoint 151.82801 232.57691
Manually Instrument Not avaliable 110.008430

It can be attached to functions in running process just like the kernel uprobe does.

How is the performance of LLVM JIT/AOT compared to other eBPF userspace runtimes, native code or wasm runtimes?

LLVM jit benchmark

Across all tests, the LLVM JIT for bpftime consistently showcased superior performance. Both demonstrated high efficiency in integer computations (as seen in log2_int), complex mathematical operations (as observed in prime), and memory operations (evident in memcpy and strcmp). While they lead in performance across the board, each runtime exhibits unique strengths and weaknesses. These insights can be invaluable for users when choosing the most appropriate runtime for their specific use-cases.

see github.com/eunomia-bpf/bpf-benchmark for how we evaluate and details.

Hash map or ring buffer compared to kernel(TODO)

See benchmark dir for detail performance benchmarks.

Comparing with Kernel eBPF Runtime

Refer to eunomia.dev/bpftime/documents/available-features for more details.

Build and test

See eunomia.dev/bpftime/documents/build-and-test for details.

Roadmap

bpftime is continuously evolving with more features in the pipeline:

Stay tuned for more developments from this promising project! You can find bpftime on GitHub.

License

This project is licensed under the MIT License.

Contact and citations

Have any questions or suggestions on future development? Free free to open an issue or contact yunwei356@gmail.com !

Our arxiv preprint: https://arxiv.org/abs/2311.07923

@misc{zheng2023bpftime,
      title={bpftime: userspace eBPF Runtime for Uprobe, Syscall and Kernel-User Interactions}, 
      author={Yusheng Zheng and Tong Yu and Yiwei Yang and Yanpeng Hu and XiaoZheng Lai and Andrew Quinn},
      year={2023},
      eprint={2311.07923},
      archivePrefix={arXiv},
      primaryClass={cs.OS}
}

Acknowledgement

eunomia-bpf community is sponsored by PLCT Lab from ISCAS.

Thanks for other sponsors and discussions help building this project: Prof. Marios Kogias from Imperial College London, Prof. Xiaozheng lai from SCUT, Prof lijun chen from XUPT, Prof. Qi Li from THU NISL Lab, and Linux eBPF maintainers in the LPC 23 eBPF track.