libbpf 1.8 发布了什么:从 multi 挂接到 .percpu 一次看清
本文地址:https://www.ebpf.top/post/libbpf-1-8-multi-fentry-sleepable-tp
libbpf v1.8.0 于 2026-10-05 18:24:40 UTC(Asia/Shanghai 2026-10-06 02:24)发布。相对 1.7,它把一批已进内核、但用户态加载与挂接还不齐的能力,做成可调用的 SEC 名与 API。API/SEC 以 Release 为准,未在目标内核实测,故不贴可粘贴工程代码;完整 diff 见 v1.7.0…v1.8.0。
1. 开篇总览:1.8.0 五类能力总览
| 类别 | 能力(SEC / API) | 用途与限制 |
|---|---|---|
| 挂接 | fentry.multi / fexit.multi / fsession.multi + attach_tracing_multi() |
一个程序挂一组函数;仅 x86-64,需 tracing_multi |
| 挂接 | tp.s / raw_tp.s / tp_btf.s |
可睡眠 TP;目标点须允许 sleepable |
| 挂接 | uprobe_multi path_fd |
fd 锚定二进制;容器/多路径更稳 |
| 挂接 | bpf_map__attach_cgroup_opts() |
struct_ops 挂 cgroup;与内核同频 |
| 加载 | clone();add_flags / clear_flags |
单程序定制加载;加载前改 flags |
| 加载 | map log_opts;bpf_prog_stream_open() |
map 创建内核日志;可 poll 的 stream fd |
| BTF | layout / allowlist / decl_tag / loc / find_by_name_kind_own |
生成、裁剪、转储、定位;工具链侧 |
| BPF 侧 | SEC(".percpu");callx |
全局 per-CPU;间接调用;需较新内核 |
| USDT | 优化路径 nop; nop10 |
快路径需 Linux 7.3+;否则普通 uprobe |
2. 用户态挂接:multi 追踪与可睡眠 tracepoint
2.1 multi-function fentry / fexit / fsession
- SEC:
SEC("fentry.multi")、SEC("fexit.multi")、SEC("fsession.multi") - API:
bpf_program__attach_tracing_multi(prog, pattern, opts) opts可带ids/cookies/cnt(见bpf_tracing_multi_opts)
用途:同一套逻辑挂一批相关符号,挂接次数与失败点更集中。
限制:Release 标明 x86-64 only(ARM64 上不要假设能用);内核还需 tracing_multi 一类 multi attach。失败时先查架构与内核配置。请以官方 selftests(v1.8.0 标签)与本机核对为准。
2.2 可睡眠 tracepoint:tp.s / raw_tp.s / tp_btf.s
SEC("tp.s/...")/SEC("raw_tp.s/...")/SEC("tp_btf.s/...")
用途:告诉加载器按 sleepable 程序申请许可与校验,从而在允许的点上做原先做不了的阻塞类操作。
限制:验证器与运行时均按可睡眠程序处理;并非所有 TP 都开放 sleepable。热点路径上可能引入延迟,宜先在实验机量化。
2.3 uprobe_multi 可用 path_fd
除路径字符串外,还可通过 path_fd 指定目标二进制。容器、chroot 或同一 inode 多路径可见时,用 fd 锚定更稳。
2.4 struct_ops → cgroup:bpf_map__attach_cgroup_opts()
把 struct_ops map 挂到 cgroup,按 cgroup 作用域启用/约束行为(与内核经 bpf_link 挂接同频)。opts 字段与可挂类型以头文件与 Changelog 为准。
3. 加载与对象生命周期:clone、flags、日志与 stream
这类 API 改变怎么加载、排错与读出数据,不改变挂到哪个钩子。写加载器封装、CI 自测或排查 map/program 失败原因时往往立刻用得上。
bpf_program__clone() — 从已 prepare 的 object 按自定义 load options 单独加载某一个 program;适合同一份对象多种加载策略,或只加载子集。
bpf_program__add_flags() / bpf_program__clear_flags() — 加载前增减 program flags,不必直接改底层 opts;改错通常直接加载失败。
map log_opts(bpf_map_create_opts) — 创建 map 时可带与 program 加载类似的 log 选项,把内核侧创建失败原因打出来,优于只看 errno。
bpf_prog_stream_open() — 打开可 poll 的 fd 读 program stream,适合事件循环异步消费,而不是阻塞读死循环;stream 语义与内核绑定,可读格式以文档为准。
4. BTF:生成、裁剪、转储与定位
偏工具链与库 API,按需取用:
- kind layout 与 24-bit vlen:
btf__new_empty_opts()等,生成或合并大型 BTF 时相关。 btf_module_allowlist:限制 libbpf 加载哪些内核模块 BTF,缩小扫描面。- dumper 输出
btf_decl_tag为 C 属性:看 dump / 生成头文件时更接近可读 C。 - location kinds:
btf__add_loc*(),为类型/成员补充位置类信息。 btf__find_by_name_kind_own():在本 BTF 自有范围内按 name+kind 查找。
只消费系统 BTF、不自己拼类型时,多数可先记在升级笔记;做 CO-RE 工具或模块 BTF 裁剪时再点开对应 API。
5. BPF 侧:全局 .percpu 与间接调用 callx
5.1 SEC(".percpu") 全局 per-CPU 变量
BPF C 侧过去常用「只有 1 个 entry 的 percpu_array」代替全局 per-CPU 语义。1.8 正式支持 SEC(".percpu"):变量每 CPU 一份,程序里像普通全局变量读写,用户态经骨架读出各 CPU 值。
用途:少一张样板 map,语义更接近内核 DEFINE_PER_CPU()。
限制:libbpf 会探测内核是否支持;骨架生成需跟上。过旧 Clang 对极小宽度(如 1 字节)percpu 变量可能出问题。本文未实测具体 Clang 组合。
5.2 间接调用(callx)
支持 间接调用指令 callx,在验证器与运行时允许的前提下表达间接调用。能否用、用在哪些程序类型,仍受内核 verifier 与指令集约束,不要假设可任意函数指针。
6. USDT 门槛:nop; nop10 与 Linux 7.3+
USDT 优化路径期望探针点为 nop; nop10,并要求 Linux 7.3+。不满足时仍按普通 uprobe 挂接——功能通常还在,只是走不到优化路径。升级后若行为异常,先核:内核是否 ≥ 7.3、探针点是否已是 nop10、失败时是否静默落到普通 uprobe。
7. 升级核对(相对总表只补决策点)
§1 总表已列用途与限制。动手前再核这几条硬门槛即可:
| 场景 | 硬门槛 |
|---|---|
fentry.multi / fexit.multi / fsession.multi |
x86-64 + 内核 tracing_multi + libbpf ≥ 1.8 |
| 可睡眠 TP | 目标点允许 sleepable + tp.s 等 SEC + 1.8 |
全局 .percpu |
内核支持 + libbpf 探测成功 + 较新 Clang |
| USDT 快路径 | Linux 7.3+ 的 nop; nop10 + libbpf 1.8 |
其余(path_fd、cgroup struct_ops、map 日志、stream)见总表与对应小节。以 v1.8.0 Release 为准;Bug fixes 见 完整提交记录。
8. 总结
1.8 对实践者真正有用的,是分类后能对应到的几条路径(见 §1 总表),而不是把 Changelog 抄完。升级后先核实:头文件里能否找到要用的 API;目标架构与内核是否满足总表限制;用官方 selftests(v1.8.0 标签)跑通与业务相关的一类。
本人水平有限,如有错误欢迎批评指正。API 与 SEC 以 libbpf v1.8.0 Release 为准;内核行为以你运行的版本为准。
延伸阅读
若还想顺着读,可看这几篇:
- 原文作者:DavidDi
- 原文链接:https://www.ebpf.top/post/libbpf-1-8-multi-fentry-sleepable-tp/
- 版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 4.0 国际许可协议. 进行许可,非商业转载请注明出处(作者,原文链接),商业转载请联系作者获得授权。
- 最后更新时间:2026-11-01 03:35:33.499267743 +0000 UTC