惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

雷峰网
雷峰网
GbyAI
GbyAI
Stack Overflow Blog
Stack Overflow Blog
Apple Machine Learning Research
Apple Machine Learning Research
The Cloudflare Blog
WordPress大学
WordPress大学
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
F
Fortinet All Blogs
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
Microsoft Azure Blog
Microsoft Azure Blog
酷 壳 – CoolShell
酷 壳 – CoolShell
博客园 - 聂微东
L
LangChain Blog
云风的 BLOG
云风的 BLOG
Jina AI
Jina AI
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
I
InfoQ
大猫的无限游戏
大猫的无限游戏
MyScale Blog
MyScale Blog
人人都是产品经理
人人都是产品经理
小众软件
小众软件
量子位
The GitHub Blog
The GitHub Blog
博客园 - 【当耐特】

一派胡言

吉隆坡游记 | 一派胡言 春节观鸟记:罗定篇 | 一派胡言 春节观鸟记:广州篇 | 一派胡言 观鸟改变了我 | 一派胡言 个人春秋2025 | 一派胡言 观鸟记:20251214, 20251220, 20251221, 20251225 | 一派胡言 那是傻瓜的血脉使然啊 | 一派胡言 观鸟记:Sungei Buloh 20251101 | 一派胡言 观鸟记: Tampines Eco Green 20251011 | 一派胡言 涅磐 | 一派胡言 东京也无非是这样 | 一派胡言 回忆我的中学母校 | 一派胡言 2025年Q1 漫画月旦 | 一派胡言 个人春秋2024 | 一派胡言 ebpf 札记(5): bpftrace cgroup_path 无法用作 map key | 一派胡言 回顾21世纪 | 一派胡言 聊斋笔记若干 | 一派胡言 阅微草堂中的纪晓岚 | 一派胡言 Ipoh 游记 | 一派胡言 个人春秋2023 | 一派胡言 ebpf 札记(4): 用 ebpf 侦测函数内部的状态 | 一派胡言 ebpf 札记(3): 一个跟踪 kernel I/O request 生命周期的脚本 | 一派胡言 ebpf 札记(2): samples/bpf/cpustat(WIP) | 一派胡言 The Linux Kernel Module Programming Guide 读书笔记 | 一派胡言 彼岸人生 | 一派胡言 同光之间的罗定——《晚清官场镜像》读书笔记 | 一派胡言 个人春秋2022 | 一派胡言 再看 Ghost in the Shell | 一派胡言 不要偷懒 | 一派胡言 个人阅读史2020 | 一派胡言
ebpf 札记(1): bpf_types.h | 一派胡言
2023-09-16 · via 一派胡言

本文以 5.15 版本内核为例。

概述

include/linux/bpf_types.h 这个头文件有且仅有三种宏指令:

  1. BPF_PROG_TYPE;
  2. BPF_MAP_TYPE;
  3. BPF_LINK_TYPE;

BPF_PROG_TYPE 为例,查找它的定义,发现它出现在

  1. include/linux/bpf.h;
  2. kernel/bpf/btf.h;
  3. kernel/bpf/syscall.c;
  4. kernel/bpf/verifier.c;

bpf.h

这个文件里面定义了一系列的 bpf_prog_ops, bpf_verifier_opsbpf_map_ops:

#define BPF_PROG_TYPE(_id, _name, prog_ctx_type, kern_ctx_type) \
	extern const struct bpf_prog_ops _name ## _prog_ops; \
	extern const struct bpf_verifier_ops _name ## _verifier_ops;
#define BPF_MAP_TYPE(_id, _ops) \
	extern const struct bpf_map_ops _ops;
#define BPF_LINK_TYPE(_id, _name)
#include <linux/bpf_types.h>
#undef BPF_PROG_TYPE
#undef BPF_MAP_TYPE
#undef BPF_LINK_TYPE

这里用到先 #define#undefine 的技巧在 Using the TRACE_EVENT() macro (Part 3) 里面有介绍。

#define BPF_LINK_TYPE(_id, _name) 这种宏定义就是把 BPF_LINK_TYPE 定义为空, 后面 #include <linux/bpf_types.h> 时,~BPF_LINK_TYPE~ 部分就会被替换成空行。

btf.h

这个文件里面定义了几个不同的结构体:

  1. bpf_ctx_convert 这个 union 用到 BPF_PROG_TYPE 里面的 prog_ctx_typekern_ctx_type
  2. __ctx_convert##id 枚举;
  3. bpf_ctx_convert_map 这其实是一个数组,但是它的 index 就是 BPF_PROG_TYPE 里面的 _id 所以把它看作 map 也无不可;

syscall.c

这个文件用 linux/bpf_types.h 定义了: bpf_progs_types 。 和 bpf_ctx_convert_map 一样,这也是用 _id 作为 key,存储了所有的 bpf_prog_ops 跟 prog id 的对应关系。

verifier.c

这个文件用 linux/bpf_types.h 定义了 bpf_verifier_ops

总结

linux/bpf_types.h 本质上就是一个大列表,定义了所有的 bpf prog, map 和 link 。

通过定义这个大列表,内核开发者借助预处理的技巧避免了写 boilerplate code, 了解这些技巧方便会我们找一些函数的定义。 比如要找 BPF_PROG_TYPE_KPROBE 相关的 prog_ops, 我们应该搜 kprobe_prog_ops 。