eBPF Talk: 学习经验之确认 kernel version
文章目录
当我们想要在项目特定版本内核中落地某个 eBPF 特性时,需要确认该版本内核是否支持该 eBPF 特性。
与此同时,也想知道,该 eBPF 特性最低要求哪个版本的内核。
前置条件
学习 eBPF 特性的有效方式是什么?
我觉得最有效的方式是在项目中落地,让代码在生产环境接受严酷的磨砺。
不过,在学习新特性时,有效的方式是编写 demo 代码、并且跑起来。
有效且靠谱的方式是,先学习该特性相关的理论知识、并且深入学习该特性的源代码,再编写 demo 代码、跑起来验证一下。
我现在正朝着有效且靠谱的方向迈进。
阅读内核源代码
我阅读内核源代码的方式比较朴素:
- 使用
ag
+fzf
搜索代码:快速找到代码位置。 - 使用 Sublime Text 阅读代码:满足基本的代码跳转需求。
- 使用的内核代码分支是
bpf-next
:保障有比较全面的 eBPF 特性。
经常阅读源代码后,可以在 Sublime Text 里使用 Cmd + P
的快捷方式打开对应的源代码文件:
syscall.c
:kernel/bpf/syscall.c
,BPF 系统调用入口。verifier.c
:kernel/bpf/verifier.c
,BPF 校验器。arraymap.c
:kernel/bpf/arraymap.c
,ARRAY bpf map、PROG ARRAY bpf map 等。dev.c
:net/core/dev.c
,内核协议栈设备层的核心代码,里面包含了 XDP generic 模式的代码。bpf.h
:include/uapi/linux/bpf.h
,BPF 帮助函数的声明及其函数的使用文档。bpf_types.h
:include/linux/bpf_types.h
,BPF 程序类型、map 类型等及其接口的对应关系。
快速打开代码文件后,便可在文件里搜索相关代码,然后就可以阅读相关代码了。
确认特定版本的内核是否支持某 eBPF 特性
首先,需要知道该 eBPF 特性的源代码在什么位置。比如直接搜索 bpf-next
分支的内核代码,找到相关源代码文件路径后,再去特定版本的内核里查看是否有相关的源代码。
不过,这仅限于学习用途。如果想要项目在运行的时候动态探测是否支持某特性,则可以参考 cilium/ebpf/features 进行特性探测。
比如,在网络上了解到较新版本的内核里支持 bpf_loop()
特性,想要确认 5.15 内核是否支持该特性:
bpf_loop()
是一个 BPF 帮助函数,就会在include/uapi/linux/bpf.h
中有声明。- 到特定版本的内核源代码的
include/uapi/linux/bpf.h
文件里搜索bpf_loop
:搜索到即支持,搜索不到即不支持。
确认某 eBPF 特性最低要求哪个版本的内核
BPF Features by Linux Kernel Version 该文档里整理了不少相关资料,不够全面。而对于文档里没有包含的(特别是较新的)特性,就需要自己去确认了。
这就不好确认了。不过,并非没有办法;下面就是我采用的办法:
下面以
bpf_loop()
为例。
1、在 bpf-next
分支里,确认该特性的源代码文件路径。
2、到 GitHub 的 linux 项目中打开该文件
3、blame 该文件
4、打开 commit
5、确认 kernel version
总结
为什么要那么费劲地阅读内核源代码呢?
因为我信奉 “Try hard to learn little things”。
当克服阅读内核源代码的恐惧后,便会逐步喜欢上阅读源代码的感觉、那种真正掌握知识的感觉。
文章作者 Leon Hwang
上次更新 2023-05-23