第27周:eBPF Maps 与用户态交互
目标:深入掌握 BPF maps 的使用,实现用户态程序与内核 BPF 程序的高效数据交互。
1. BPF Maps 详解
1.1 Map 特性
1 | BPF Map = 内核态共享数据结构 |
1.2 主要 Map 类型
1 | ┌─────────────────────┬────────────────────────────────┐ |
2. BPF 程序中 Map 的使用
2.1 通用 BPF Map 操作
1 | // === 查找元素 === |
2.2 各种 Map 示例
1 | // === HASH MAP === |
2.3 LRU Hash(自动淘汰)
1 | // LRU_HASH:内存满时自动淘汰最近最少使用的元素 |
3. 用户态操作 Map
3.1 使用 bpftool
1 | # === 查看所有 map === |
3.2 使用 libbpf
1 | // === 简单读取(libbpf API)=== |
3.3 使用 Skeleton(推荐)
1 | // 自动生成的 skeleton(bpftool gen skeleton) |
4. Per-CPU Map 性能
4.1 为什么用 Per-CPU?
1 | 普通 hash map 的并发问题: |
4.2 Per-CPU 计数
1 | // BPF 端:每个 CPU 独立计数 |
5. Ring Buffer(推荐的事件传递机制)
5.1 Ring Buffer vs Perf Event
1 | Perf Event Array(旧): |
5.2 Ring Buffer 使用
1 | // === BPF 端 === |
1 | // === 用户态 === |
6. 实践:基于 XDP 的包计数器
6.1 BPF 程序
1 | // xdp_counter.bpf.c |
6.2 用户态加载器
1 | // xdp_counter.c |
6.3 编译与运行
1 | # 1. 编译 BPF 程序 |
7. Map 调试技巧
1 | # 实时查看 map 变化 |
8. 关键 API 速查
| 函数 | 用途 |
|---|---|
bpf_map_lookup_elem() |
查找元素 |
bpf_map_update_elem() |
更新/插入元素 |
bpf_map_delete_elem() |
删除元素 |
bpf_map_get_next_key() |
遍历元素 |
bpf_lookup_u32_elem() |
32 位 key 快速查找 |
bpf_ringbuf_reserve() |
RingBuf 预留空间 |
bpf_ringbuf_submit() |
RingBuf 提交 |
bpf_ringbuf_discard() |
RingBuf 丢弃 |
bpf_perf_event_output() |
Perf Event 发送 |
bpf_redirect_map() |
重定向到 DEVMAP/CPUMAP |
bpf_redirect() |
重定向到接口 |
bpf_xdp_adjust_head() |
调整 XDP 头部 |
bpf_xdp_adjust_tail() |
调整 XDP 尾部 |
- 本文作者: CoderSong
- 本文链接: https://jack-song-gif.github.io/2026/06/14/第27周:eBPF Maps 与用户态交互/
- 版权声明: 本博客所有文章除特别声明外,均采用 MIT 许可协议。转载请注明出处!