eBPF Loop
source link: https://yanhang.me/post/2021-ebpf-loop/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
eBPF Loop 是个老大难问题,只要实际开发大概率都会遇到。Kernel 版本越高,loop 的支持也越多。最近在 LWN 上又看到一篇关于 bpf loop 的新实现,如果能合并进去,那么就有三种 loop 得方式了:
- bounded loop: 跟传统编程模式很像,但loop的count必须是已知的
- map iterator: 针对 bpf map 的迭代器,可以用来遍历 map
- bpf_loop 函数: 最新的提议,能让 verifier 处理的更快
目前的 verifier 的策略是比较激进的,因为它没法验证所有的场景,所以有可能会对一些实际正确的程序验证不通过。bpf_loop
主要就是从这个角度来考虑问题,相当于对最开始的 bounded loop 做的一个优化。下面将详细介绍。
Bounded Loop
Kernel 5.3 之前, eBPF 不支持 loop. 要想实现类似功能,而且前提是明确 loop 的次数,那么基本上只能靠 unroll
来实现。示例如下:
#pragma clang loop unroll(full)
for (i = 0; i < 4; i++) {
/* Do stuff ... */
}
相当于把 loop 展开。5.3 及之后,就不用这样了。
MAP Iterator
Bounded Loop 只能解决一部分的问题。总会有 unbounded loop 的场景。5.13 引入了 map iterator, 支持对 bpf map做遍历。考虑到 bpf map 在 eBPF 程序中的普遍性,算是一个比较好的解决方案了.
具体可参考: https://lwn.net/Articles/826058/
bpf_loop
bpf_loop 仍然是 bounded loop 范畴。但从 verifier 的角度考虑,大大简化了 verify 的逻辑。相当于把 loop 从普通的函数流程里抽取了出来,单独用一个 bpf 函数来实现:
long bpf_loop(u32 iterations, long (*loop_fn)(u32 index, void *ctx),
void *ctx, u64 flags);
这个 patch 还没合并。
Links:
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK