Skip to content

feat(starry-perf): implement read for perf event fd#1400

Closed
CN-TangLin wants to merge 2 commits into
rcore-os:devfrom
CN-TangLin:feat/starry-perf-read
Closed

feat(starry-perf): implement read for perf event fd#1400
CN-TangLin wants to merge 2 commits into
rcore-os:devfrom
CN-TangLin:feat/starry-perf-read

Conversation

@CN-TangLin

Copy link
Copy Markdown
Contributor

问题

perf event fd 不支持 read(2) 系统调用。当 eBPF program 通过 bpf_perf_event_output 写入 ringbuf 后,用户态无法读取输出记录,数据消费闭环不完整。

变更

  1. bpf.rs: BpfPerfEventWrapper 新增 mmap_kvirt 字段(在 device_mmap 时保存 ringbuf 内核虚拟地址),实现 try_read_record
    • 从 raw pointer 读取 perf_event_mmap_page metadata(data_head/data_tail)
    • 处理环缓冲区 wrapping,读取 perf_event_header 确定 record size
    • 推进 data_tail 完成消费
    • 辅助函数 wrapping_add/copy_ring 处理环形缓冲区操作
  2. mod.rs: 实现 FileLike::read,通过 downcast 获取 BpfPerfEventWrapper 后调用 try_read_record

逻辑

  • 复用 BpfPerfEventWrapper 已有的 pages 弱引用获取物理地址
  • 利用 device_mmap 建立的内核虚拟地址映射直接读取 ringbuf
  • 栈缓冲区使用 PAGE_SIZE_4K 常量

Replace raw config values 0/1 in kprobe/uprobe dispatch with named
constants PROBE_CONFIG_ENTRY / PROBE_CONFIG_RETURN, matching the
Linux PERF_TYPE_PROBE ABI.  Also refactor the kprobe config match
from a nested if/else chain into flat const-pattern match arms.
为 BpfPerfEventWrapper 实现 try_read_record 方法,使 perf event fd
支持 read(2) 系统调用读取 ringbuf 中的 eBPF 输出记录。

主要变更:
- bpf.rs: 添加 mmap_kvirt 字段保存 ringbuf 内核虚拟地址,实现
  try_read_record 从 perf_event_mmap_page 读取 data_head/data_tail,
  处理环缓冲区 wrapping,读取 perf_event_header 确定记录尺寸,
  推进 data_tail;添加 wrapping_add/copy_ring 辅助函数
- mod.rs: 实现 FileLike::read,通过 downcast 获取 BpfPerfEventWrapper
  并调用 try_read_record,使用 PAGE_SIZE_4K 作为栈缓冲区尺寸常量
@CN-TangLin

Copy link
Copy Markdown
Contributor Author

Merged into #1414 — consolidated perf event fd read/poll/nonblock support.

@CN-TangLin CN-TangLin closed this Jun 27, 2026

@mai-team-app mai-team-app Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PR #1400 Review: feat(starry-perf): implement read for perf event fd

总体评价

实现质量较好,代码结构清晰,SAFETY 注释充分。try_read_record 正确实现了 Linux perf ringbuf 语义,包括环形缓冲区 wrapping 处理和 data_tail 推进。

CI 状态

CI workflow run #7544 总体结论为 success。所有子 job 均为 skipped(fork PR + path filter,perf/ 下的改动不触发测试/axvisor/starry 等 job),符合预期。

代码分析

bpf.rs

  • mmap_kvirt 字段在 device_mmap 时正确保存,try_read_record 中通过 is_mapped() 校验页面生命周期
  • wrapping_add / copy_ring 辅助函数正确处理环形缓冲区零次/一次 wrapping
  • record_size 校验覆盖了 < hdr_size> dst.len() 两种非法情况
  • data_tail 单调递增符合 Linux perf 环形缓冲区语义

kprobe.rs / uprobe.rs

  • PROBE_CONFIG_ENTRY / PROBE_CONFIG_RETURN 常量替代魔数 0/1,提高可读性
  • pattern match 语法更简洁

mod.rs

  • FileLike::read 正确加锁、downcast 到 BpfPerfEventWrapper,非 BPF perf event 返回 Unsupported
  • 栈缓冲区 PERF_READ_BUF_SIZE = PAGE_SIZE_4K 合理

重复/重叠分析

  • base 分支上 PerfEvent::read 仍为 Err(AxError::Unsupported),本 PR 新增功能无重复
  • PR #1412(同作者)包含 PROBE_CONFIG_ENTRY/PROBE_CONFIG_RETURN 相同常量,属于 partial-overlap。#1412 body 已明确标注与 #1400 的关系,合并时需要处理冲突(trivial)。

小建议

见 inline comment 关于 perf_event_header 对齐和测试覆盖的建议。

结论

代码正确、CI 通过、无阻塞问题。APPROVE

Powered by mimo-v2.5-pro

let hdr_size = core::mem::size_of::<perf_event_header>();
if hdr_size > dst.len() {
return Err(AxError::InvalidInput);
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[nit] dst.as_ptr() as *const perf_event_header 假设了 4 字节对齐,但 dst&mut [u8] 仅保证 1 字节对齐。虽然栈上 4096 字节数组在实践中通常满足对齐要求,但严格来说这是 UB。

建议使用 core::ptr::read_unaligned 或确保缓冲区对齐:

let header: perf_event_header = core::ptr::read_unaligned(dst.as_ptr() as *const perf_event_header);
let record_size = header.size as usize;

}
}

/// Stack buffer size for reading a single perf ringbuf record. The

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[note] 当前没有针对 perf event fd read(2) 的测试用例。现有的 eBPF apps(apps/starry/ebpf/)均未使用 bpf_perf_event_output,因此没有现成的测试基础设施。

建议后续添加一个使用 bpf_perf_event_output 的 eBPF 测试程序,在 test-suit 中验证 read 路径的端到端闭环。这不阻塞当前 PR,但应作为 follow-up 跟踪。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant