eBPF Talk: 达成内核 bpf 子系统贡献者成就
文章目录
给 XDP 新增了一个 tracepoint;历时一个月,终不负所望。
年份:2023 年。
需求来源
说来惭愧,需求不来自公司、也不来自我自己,而是来自 Cilium 社区的一个讨论:
有人在使用 go-ebpf 库时,遇到了一个问题:当 MTU 设置为 9000 时,调用 AttachXDP()
会返回 invalid argument
错误;但却没有更详细的错误信息。
最后,在 7 月 3 日,我回复:“我觉得像 bpf verifier 一样报告错误信息会比较好”。
接着,在 7 月 4 日,我便完成了 POC,将错误信息通过 BPF 系统调用传递给用户空间。
提交第一个 patch
这是第一次提交正式的 patch,有许多社区行为需要注意;幸好有同事的帮助,才没有犯大错。
在 patch 的基本要求没问题后,厚着脸皮,在 7 月 5 日向 kernel bpf 社区发出了第一个 patch。
幸好,该主意得到了社区大佬 Daniel Borkmann 的肯定,并指出了我的 patch 中的一些问题:
- 破坏了 UAPI。
- 使用
bpf_log_once()
封装一下啰嗦的代码。
提交第二个 patch
根据 Daniel 的建议,我修正了 UAPI 的问题,并使用 bpf_log_once()
封装了代码。
并在 7 月 8 日提交了第二个 patch。
不过,该 patch 存在不少问题,被社区大佬 Alexei Starovoitov 指出:
- 缺失 libbpf 的更新。
- 缺失 selftest。
- 使用
bpf_vlog_finalize()
会更好。 - 考虑一下 Daniel Xu 提出的 tracepoint 的主意。
提交第三个 patch
接下来,当然是接纳社区大佬的建议,改用 tracepoint 的方式,并添加 selftest。
不过,在实现 selftest 的时候,遇到了困难:如何使用 bpf trace 该 tracepoint?
因为该 tracepoint 的 ctx
如下:
|
|
在 bpf 里,是无法直接通过 ctx->msg
来获取字符串的。
请教了社区大佬 Daniel Xu 后,得到具体的解决办法,请看:eBPF Talk: tracepoint __data_loc。
而后,在完成了基本的 selftest 后,便在 7 月 20 日提交了第三个 patch。
为什么该 patch 被拒绝呢?因为该 patch 的 selftest 在某些情况下 crashed 了:kernel-patches/bpf CI。
其实,我在提交 patch 之前就知道这个问题,但我罔顾问题就直接提交 patch 了,被狠狠地打脸。
提交第四个 patch
只能硬着头皮,修复 selftest 的问题。
此时,VirtualBox VM 不给力了,我只能使用 QEMU VM 来进行测试。
但没有学会使用 QEMU 通过 bzImage 来创建 VM,只能直接编译内核了。
给 QEMU VM 开 6 个 CPU 来编译内核,编译了 1 个小时。
而后,使用 gdb 调试 selftest 程序,发现是在 perf event callback 里复制字符串时复制多了 4 个字节,导致栈上的变量被破坏了。
修复了这个问题后,便在 7 月 30 日提交了第四个 patch。
提交第五个 patch
在 8 月 1 日,kernel net 社区大佬 Jakub Kicinski 指出 extack
变量没初始化,而且变量声明的代码行存在风格问题,这些行需要从长到短排列。
还好,这些问题都很容易修复,便在 8 月 1 日晚上提交了第五个 patch。
终于,在 8 月 3 日迎来了好消息:
|
|
小结
这是我第二次向 kernel bpf 社区提交 patch,历时一个月,终于达成了目标。第一次仅是修复了一个单词拼写问题,就略过吧。
向 kernel 社区提交 patch 时,有不少地方需要注意的:
即便如此,最好还是在有经验的同事的 review 下,再将 patch 提交到社区。
作为新人,厚着脸皮混个脸熟;但也要快速学习社区的行为约定,以免冒犯了社区大佬们。
祝好!
文章作者 Leon Hwang
上次更新 2024-05-15