AxVisor eBPF 性能追踪 - 项目目标
结合 eBPF 技术,跟踪 Hypervisor 和内核的性能
1. 背景与研究基础
1.1 已有技术基础
基于个人 eBPF 项目经验,已具备以下技术栈能力:
| 技术领域 | 已实现能力 |
|---|---|
| eBPF 程序类型 | Kprobe/Kretprobe、Tracepoint、XDP、TC、sock_ops/sk_msg、Uprobe |
| eBPF Maps | HashMap、SockHash、PerCPU Maps |
| 用户态框架 | Aya (Rust eBPF 框架) |
| 内核追踪 | syscall 追踪 (connect/read/write/open/sendto/recvfrom) |
| 应用追踪 | Go runtime uprobe (goroutine 调度、channel 通信) |
| 故障注入 | L3/L4/L7/Syscall/Resource 多层故障注入 |
| TraceID 传播 | 跨进程、跨网络的全链路追踪 |
已有项目核心架构:
┌─────────────────────────────────────────────────────────┐
│ User Space (cli crate) │
│ ┌─────────┐ ┌──────────┐ ┌────────────┐ ┌───────────┐ │
│ │ Agent │ │ Proxy │ │ Controller │ │ Monitor │ │
│ └────┬────┘ └────┬─────┘ └─────┬──────┘ └─────┬─────┘ │
└───────┼───────────┼─────────────┼──────────────┼────────┘
│ │ │ │
┌───────┼───────────┼─────────────┼──────────────┼────────┐
│ ▼ ▼ ▼ ▼ │
│ ┌─────────────────────────────────────────────────┐ │
│ │ eBPF Maps (Shared Data) │ │
│ │ PID_GID_MAP | TRACE_FAULT_MAP | FAULT_STATS │ │
│ └─────────────────────────────────────────────────┘ │
│ Kernel Space (ebpf crate) │
│ ┌─────────┐ ┌──────────┐ ┌────────────┐ ┌───────────┐ │
│ │ Kprobes │ │ Uprobes │ │ XDP/TC │ │ sock_ops │ │
│ └─────────┘ └──────────┘ └────────────┘ └───────────┘ │
└─────────────────────────────────────────────────────────┘
1.2 AxVisor 现状分析
基于对 AxVisor 代码的分析,当前架构如下:
┌────────────────────────────────────────────────────────┐
│ AxVisor Hypervisor │
│ ┌──────────────────────────────────────────────────┐ │
│ │ kernel/ │ │
│ │ ┌─────────┐ ┌─────────┐ ┌─────────┐ │ │
│ │ │ vmm/ │ │ hal/ │ │ shell/ │ │ │
│ │ │ config │ │ arch/* │ │ command │ │ │
│ │ │ vcpus │ │ cache │ │ │ │ │
│ │ │ timer │ │ │ │ │ │ │
│ │ └────┬────┘ └────┬────┘ └─────────┘ │ │
│ └───────┼────────────┼─────────────────────────────┘ │
│ │ │ │
│ ┌───────▼────────────▼─────────────────────────────┐ │
│ │ modules/ (Hypervisor modules) │ │
│ │ axvm | axvcpu | axaddrspace | axdevice │ │
│ └──────────────────────────────────────────────────┘ │
│ │ │
│ ┌────────────────────────▼─────────────────────────┐ │
│ │ ArceOS Kernel (axstd, axhal, axtask) │ │
│ └──────────────────────────────────────────────────┘ │
└────────────────────────────────────────────────────────┘
│
┌────────────┼────────────┐
▼ ▼ ▼
┌────────┐ ┌────────┐ ┌────────┐
│ VM 1 │ │ VM 2 │ │ VM N │
│ (Guest)│ │ (Guest)│ │ (Guest)│
└────────┘ └────────┘ └────────┘
关键性能瓶颈点:
| 序号 | 瓶颈点 | 位置 | 性能敏感度 |
|---|---|---|---|
| 1 | VM Exit/Entry 处理 | AxVCpu::run() 循环 | 极高 |
| 2 | Hypercall 处理 | AxVCpuExitReason::Hypercall 分支 | 高 |
| 3 | 中断注入 | AxVCpu::inject_interrupt() | 高 |
| 4 | MMIO/SysReg 模拟 | AxVCpuExitReason::MmioRead/Write | 中 |
| 5 | 嵌套页表处理 | AxVCpuExitReason::NestedPageFault | 高 |
| 6 | vCPU 状态转换 | VCpuState 状态机 | 中 |
1.3 AxVisor 现有可观测性基础
AxVisor 当前已具备一定的可观测性能力,但均为硬编码采集方式,缺乏灵活的动态追踪机制:
1.3.1 日志追踪 (Log-based Tracing)
当前通过 trace!/debug!/info!/warn!/error! 宏在关键路径输出日志:
| 模块 | 追踪点 | 日志级别 | 采集内容 |
|---|---|---|---|
axvcpu/vcpu.rs | run() 方法 | debug | vCPU 状态转换 |
axvcpu/exit.rs | Exit 处理 | debug | Exit reason、参数 |
axvm/vm/mod.rs | VM 生命周期 | info | 创建、启动、停止 |
kernel/vmm/mod.rs | VMM 初始化 | info | 虚拟化启用状态 |
现有日志追踪示例(基于 AxVCpuExitReason):
When VM Exit occurs:
- Only records Exit type: Hypercall/MmioRead/ExternalInterrupt etc.
- Only records parameters: hypercall_nr, addr, vector etc.
- No latency stats, no frequency stats, no aggregation analysis
1.3.2 Shell 状态查询
通过 vm show 命令提供运行时状态查询:
| 命令 | 功能 | 数据来源 |
|---|---|---|
vm list | 列出所有 VM | vm_list 模块 |
vm show <id> | 显示 VM 详情 | Vm 结构体 |
支持的统计项:
- VM 状态 (Running/Stopped)
- vCPU 数量
- 内存大小
- VM 名称
1.3.3 现有方案的局限性
| 局限性 | 描述 | eBPF 解决方案 |
|---|---|---|
| 无延迟统计 | 仅记录事件发生,无处理时长 | Tracepoint + 时间戳采集 |
| 无频率统计 | 无法统计 VM Exit/Hypercall 频率 | eBPF Map 计数聚合 |
| 无直方图 | 无法分析延迟分布 | Histogram Map |
| 静态插桩 | 需重编译才能修改追踪点 | Kprobe 动态附加 |
| 高开销 | 日志 I/O 影响性能 | Ring buffer 异步采集 |
| 无跨 VM 关联 | 无法追踪 IVC 端到端延迟 | TraceID 传播 |
1.3.4 时间采集基础设施
AxVisor 已有时间获取 API,可复用于 eBPF 追踪:
| API | 位置 | 用途 |
|---|---|---|
axhal::time::monotonic_time_nanos() | ArceOS HAL | 高精度单调时钟 |
axhal::time::wall_time() | ArceOS HAL | 墙钟时间 |
可复用点: 在 eBPF tracepoint 中调用 monotonic_time_nanos() 计算事件延迟。
2. 研究目标对比分析
2.1 方向统一性
| 维度 | 已有 eBPF 项目 | AxVisor eBPF 目标 | 统一程度 |
|---|---|---|---|
| 技术栈 | Aya + Rust eBPF | Aya + Rust eBPF | ✅ 完全统一 |
| 追踪粒度 | 应用级 (Go runtime) | 系统级 (Hypervisor) | ✅ 互补 |
| 数据采集 | Uprobe + Kprobe | Tracepoint + Kprobe | ✅ 技术共享 |
| Map 设计 | TraceID 关联 | VM/VCpu 关联 | ✅ 模式相同 |
| 用户态交互 | CLI + K8s CRD | CLI + Shell 集成 | ✅ 架构复用 |
2.2 方向差异性
| 维度 | 已有 eBPF 项目 | AxVisor eBPF |
|---|---|---|
| 目标层级 | L7 应用层 | L0 Hypervisor 层 |
| 追踪对象 | Go 协程、HTTP/gRPC 请求 | VM Exit、Hypercall、中断 |
| 内核依赖 | 标准 Linux 内核 | ArceOS 自定义内核 |
| eBPF 加载 | 标准 bpf() syscall | 需要 ArceOS eBPF 支持 |
| 符号解析 | /proc/kallsyms | 需要 ArceOS ksym 支持 |
2.3 关键挑战
┌─────────────────────────────────────────────────────────────────────────┐
│ Challenges and Solutions │
├─────────────────────────────────────────────────────────────────────────┤
│ │
│ Challenge 1: ArceOS lacks standard Linux eBPF subsystem │
│ ──────────────────────────────────────────────── │
│ → Solution: Port rbpf eBPF VM based on Starry-OS approach │
│ → Reuse: kbpf-basic (Maps), tracepoint (tracing framework) │
│ │
│ Challenge 2: ArceOS lacks /proc/kallsyms │
│ ──────────────────────────────────────────────── │
│ → Solution: Use Starry-OS ksym module, generate symbol table at build │
│ → Method: Modify build process, extract symbols from ELF into kernel │
│ │
│ Challenge 3: ArceOS lacks tracepoint infrastructure │
│ ──────────────────────────────────────────────── │
│ → Solution: Port Starry-OS tracepoint implementation │
│ → Extend: Define Hypervisor-specific tracepoints (VM Exit, Hypercall) │
│ │
│ Challenge 4: Hypervisor runs in EL2/VMX Root, traditional eBPF in EL1 │
│ ──────────────────────────────────────────────── │
│ → Solution: Design Hypervisor-aware eBPF Helper functions │
│ → Add: bpf_get_current_vm_id(), bpf_get_current_vcpu_id(), etc. │
│ │
│ Challenge 5: #![no_std] environment restrictions │
│ ──────────────────────────────────────────────── │
│ → Solution: Choose no_std compatible components (rbpf, kbpf-basic) │
│ → Method: Fork and adapt if necessary, remove std library dependencies │
│ │
└─────────────────────────────────────────────────────────────────────────┘
3. 技术研究方案
3.1 整体架构设计
┌──────────────────────────────────────────────────────────────────────────┐
│ AxVisor eBPF Tracing Architecture │
├──────────────────────────────────────────────────────────────────────────┤
│ │
│ ┌────────────────────────────────────────────────────────────────────┐ │
│ │ User Space / Shell Layer │ │
│ │ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌────────────────────┐ │ │
│ │ │ Loader │ │ Analyzer │ │ Exporter │ │ Shell Commands │ │ │
│ │ │(BPF Load)│ │(Aggregate)│ │JSON/Table│ │ trace list/stat │ │ │
│ │ └────┬─────┘ └────┬─────┘ └────┬─────┘ └──────────┬─────────┘ │ │
│ └───────┼─────────────┼─────────────┼───────────────────┼────────────┘ │
│ │ │ │ │ │
│ ▼ ▼ ▼ ▼ │
│ ┌────────────────────────────────────────────────────────────────────┐ │
│ │ eBPF Maps Layer │ │
│ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌────────────┐ │ │
│ │ │VM_EXIT_STATS│ │HYPERCALL_LAT│ │ IRQ_STATS │ │VCPU_RUNTIME│ │ │
│ │ │ HashMap │ │ Histogram │ │ PerCPU Map │ │ HashMap │ │ │
│ │ └─────────────┘ └─────────────┘ └─────────────┘ └────────────┘ │ │
│ └────────────────────────────────────────────────────────────────────┘ │
│ ▲ │
│ │ Write Stats │
│ ┌───────────────────────────────────────────────────────────────────┐ │
│ │ eBPF Programs Layer │ │
│ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌───────────┐ │ │
│ │ │ Tracepoint │ │ Tracepoint │ │ Tracepoint │ │ Tracepoint│ │ │
│ │ │ vcpu_run_* │ │ hypercall │ │ mmio_access │ │ ept_viol │ │ │
│ │ └──────┬──────┘ └──────┬──────┘ └──────┬──────┘ └─────┬─────┘ │ │
│ └─────────┼────────────────┼────────────────┼───────────────┼───────┘ │
│ │ │ │ │ │
│ ▼ ▼ ▼ ▼ │
│ ┌───────────────────────────────────────────────────────────────────┐ │
│ │ axtracepoint Module │ │
│ │ Tracepoint definition, registration, trigger │ │
│ └───────────────────────────────────────────────────────────────────┘ │
│ ▲ │
│ │ Tracepoint Trigger │
│ ┌───────────────────────────────────────────────────────────────────┐ │
│ │ VMM Critical Path │ │
│ │ ┌───────────┐ ┌───────────┐ ┌───────────┐ ┌─────────────────┐ │ │
│ │ │AxVCpu:: │ │ Exit │ │ MMIO/ │ │ NestedPageFault │ │ │
│ │ │ run() │ │ Handling │ │ SysReg │ │ Handling │ │ │
│ │ └───────────┘ └───────────┘ └───────────┘ └─────────────────┘ │ │
│ └───────────────────────────────────────────────────────────────────┘ │
│ │
└──────────────────────────────────────────────────────────────────────────┘
3.2 追踪点设计
基于 AxVCpuExitReason 枚举和 VMM 关键路径,定义以下追踪点:
| 子系统 | 追踪点 | 触发位置 | 采集数据 |
|---|---|---|---|
| vmm | vcpu_run_enter | AxVCpu::run() 入口 | vm_id, vcpu_id, timestamp |
| vmm | vcpu_run_exit | AxVCpu::run() 返回 | vm_id, vcpu_id, exit_reason, duration_ns |
| vmm | hypercall | Hypercall 处理完成 | vm_id, vcpu_id, nr, args, duration_ns |
| vmm | mmio_read | MmioRead 处理 | vm_id, addr, width, duration_ns |
| vmm | mmio_write | MmioWrite 处理 | vm_id, addr, width, data, duration_ns |
| vmm | sysreg_access | SysReg 读写 | vm_id, addr, is_write, duration_ns |
| vmm | interrupt_inject | 中断注入 | vm_id, vcpu_id, vector |
| vmm | ept_violation | NestedPageFault 处理 | vm_id, gpa, access_flags, duration_ns |
| vmm | vcpu_state_change | VCpuState 转换 | vm_id, vcpu_id, from_state, to_state |
| vmm | vm_lifecycle | VM 创建/启动/停止 | vm_id, event_type |
3.3 性能指标定义
| 指标类别 | 指标名称 | 单位 | 采集方式 |
|---|---|---|---|
| 频率 | VM Exit 频率 | exits/sec | Map 计数 + 时间窗口 |
| 频率 | Hypercall 调用频率 | calls/sec | Map 计数 + 时间窗口 |
| 延迟 | VM Exit 处理延迟 | ns | 时间戳差值 |
| 延迟 | Hypercall 处理延迟 | ns | 时间戳差值 |
| 延迟 | 中断注入延迟 | ns | 时间戳差值 |
| 延迟 | MMIO 模拟延迟 | ns | 时间戳差值 |
| 延迟 | EPT Violation 处理延迟 | ns | 时间戳差值 |
| 分布 | Exit Reason 分布 | % | Map 聚合统计 |
| 分布 | Hypercall 号分布 | % | Map 聚合统计 |
| 分布 | 延迟直方图 | count/bucket | Histogram Map |
| 利用率 | vCPU 运行时间占比 | % | 累计运行时间 / 墙钟时间 |
3.4 组件复用策略
| 来源 | 组件 | 复用方式 | 工作量 |
|---|---|---|---|
| Starry-OS | ksym | 直接引用 | 低 |
| Starry-OS | kbpf-basic | 直接引用 | 低 |
| Starry-OS | tp-lexer | 直接引用 | 低 |
| Starry-OS | tracepoint | 适配后复用 | 中 |
| Starry-OS | kprobe | 后续扩展 | 高 |
| 社区 | rbpf | 适配 no_std | 低 |
4. 预期成果
4.1 技术产出
- axebpf 模块: ArceOS 兼容的 eBPF 运行时
- axksym 模块: 内核符号表生成与查找
- axtracepoint 模块: Tracepoint 定义与注册框架
- Shell trace 命令: 追踪点控制与统计数据展示
4.2 文档产出
- AxVisor eBPF 追踪使用指南
- ArceOS eBPF 子系统设计文档
- Hypervisor 性能分析最佳实践
4.3 对个人技术栈的扩展
- 技术深度扩展: 从应用层追踪扩展到 Hypervisor 层
- 跨层追踪能力: 可实现 Guest → Hypervisor → Host 全栈追踪
- 故障注入扩展: 可在 Hypervisor 层注入故障 (VM Exit 延迟、中断丢失等)
4.4 预期效果演示
axvisor:/$ trace list
Tracepoints:
vmm:vcpu_run_enter [disabled]
vmm:vcpu_run_exit [disabled]
vmm:hypercall [disabled]
vmm:mmio_read [disabled]
vmm:mmio_write [disabled]
vmm:interrupt_inject [disabled]
vmm:ept_violation [disabled]
axvisor:/$ trace enable vmm:vcpu_run_exit
Enabled: vmm:vcpu_run_exit
axvisor:/$ trace stat
┌──────────────────────────────────────────────────────────────┐
│ VM Exit Statistics │
├────────┬─────────┬──────────────┬─────────┬─────────┬────────┤
│ VM ID │ vCPU ID │ Exit Reason │ Count │ Avg(μs) │ Max(μs)│
├────────┼─────────┼──────────────┼─────────┼─────────┼────────┤
│ 1 │ 0 │ Hypercall │ 12345 │ 2.3 │ 15.7 │
│ 1 │ 0 │ ExtInterrupt │ 8901 │ 1.1 │ 8.2 │
│ 1 │ 0 │ Halt │ 567 │ 45.2 │ 102.1 │
│ 1 │ 0 │ MmioRead │ 3456 │ 1.8 │ 12.3 │
│ 2 │ 0 │ Hypercall │ 4567 │ 2.8 │ 12.3 │
└────────┴─────────┴──────────────┴─────────┴─────────┴────────┘
axvisor:/$ trace latency hypercall
Hypercall Latency Distribution:
0-1μs : ████████████████████████████████ 45.2%
1-2μs : ████████████████████ 28.1%
2-5μs : ██████████ 14.3%
5-10μs : ████ 6.8%
10-50μs : ██ 4.1%
50μs+ : █ 1.5%
附录 A: 时间线 (12 周)
策略: 移植 Starry-OS 的 eBPF 工作到 AxVisor。由于 Starry-OS 是基于 ArceOS 扩展的宏内核, AxVisor 是基于 ArceOS 扩展的 VMM,大部分组件可直接引用或稍作适配。
| 阶段 | 时间 | 里程碑 | 说明 |
|---|---|---|---|
| Phase 1 | Week 1-2 | 基础设施 | 依赖集成、符号表、追踪点框架 |
| Phase 2 | Week 3-4 | eBPF 运行时 | rbpf VM、Helper 函数、Map 支持 |
| Phase 3 | Week 5-6 | VMM 追踪点与 Shell | Hypervisor 追踪点、VMM 插桩、Shell 命令 |
| Phase 4 | Week 7-8 | Kprobe/Kretprobe | 动态探针、多架构适配 |
| Phase 5 | Week 9-10 | 验证器与 Uprobe | eBPF 验证器、Uprobe 可行性研究 |
| Phase 6 | Week 11-12 | 测试与文档 | 性能测试、多架构验证、文档 |
详细里程碑
Phase 1 - 基础设施 (Week 1-2)
- 依赖集成 (ksym, kbpf-basic, tp-lexer, tracepoint)
modules/axebpf模块创建xtask symbols符号表生成- 追踪点框架基础
Phase 2 - eBPF 运行时 (Week 3-4)
- rbpf VM 集成 (no_std 适配)
- 标准 Helper 函数实现
- Map 数据结构支持 (HashMap, Array, RingBuf)
Phase 3 - VMM 追踪点与 Shell (Week 5-6)
- 定义 VMM 核心追踪点 (7+ 个)
- VMM 关键路径插桩
- Shell
trace命令组 - Hypervisor 专用 Helper
Phase 4 - Kprobe/Kretprobe (Week 7-8)
- 移植 Starry-OS kprobe 库
- aarch64/x86_64 断点机制适配
- kretprobe 函数返回探针
- Shell kprobe 命令集成
Phase 5 - 验证器与 Uprobe (Week 9-10)
- eBPF 验证器 (PREVAIL 或轻量实现)
- 安全检查 (内存边界、程序终止性)
- Uprobe 可行性研究
- Uprobe 原型 (如可行)
Phase 6 - 测试与文档 (Week 11-12)
- 单元测试、集成测试
- 性能测试与优化
- 多架构验证
- 用户文档和 API 文档