Skip to content

feat(starry-perf): add O_NONBLOCK support for perf event fd#1403

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

feat(starry-perf): add O_NONBLOCK support for perf event fd#1403
CN-TangLin wants to merge 5 commits into
rcore-os:devfrom
CN-TangLin:feat/starry-perf-nonblocking

Conversation

@CN-TangLin

Copy link
Copy Markdown
Contributor

问题

PerfEvent 不支持 O_NONBLOCK 文件标志。PerfEvent::read 总是阻塞等待数据,无法在非阻塞模式下立即返回 EAGAIN。

变更

  • PerfEvent 新增 nonblocking: AtomicBool 字段
  • 实现 FileLike::nonblocking()FileLike::set_nonblocking()
  • read 路径通过 poll_ionon_blocking 参数在 O_NONBLOCK 时立即返回 EAGAIN

逻辑

遵循 StarryOS 其他文件类型(signalfd/eventfd/pipe)的模式:使用 AtomicBool 存储标志,通过 poll_io 的 non_blocking 参数控制行为。

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 作为栈缓冲区尺寸常量
将 PerfEvent::read 从轮询式非阻塞读重构为基于 block_on(poll_io(...))
的阻塞读模式,匹配 Linux read(perf_fd) 语义。当 ringbuf 无数据时
返回 WouldBlock 让 poll_io 等待,数据到达后由已有的
BpfPerfEventWrapper poll 基础设施(poll_ready/poll_notify/IrqNotify)
唤醒任务继续读取。

重构要点:
- 使用 block_on(poll_io(...)) 替代简单轮询,复用已有的 Pollable 实现
- read 闭包在返回 WouldBlock 前释放 SpinNoPreempt 锁
- 通过 PerfEvent::poll → BpfPerfEventWrapper::poll 获取可读性状态
- 通过 PerfEvent::register → BpfPerfEventWrapper::register 注册 waker
消除 perf 模块中的两处硬编码:
- BPF_JIT_MEM_PAGES = 4:x86_64 JIT 可执行内存页数
- KRETPROBE_MAX_ACTIVE = 10:kretprobe 最大并发实例数

使用命名常量替代字面量,提高代码可读性和可维护性。
为 PerfEvent 添加 nonblocking 标志支持:
- PerfEvent 新增 AtomicBool 字段存储 O_NONBLOCK 状态
- 实现 FileLike::nonblocking() / set_nonblocking()
- read(2) 在 nonblocking 模式下,ringbuf 为空时立即返回 EAGAIN
  而非阻塞等待(通过 poll_io 的 non_blocking 参数传递)
@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 已关闭 — 作者已将本 PR 合并入 #1414(整合 perf event fd 的 read/poll/nonblock 支持)。以下为代码质量审阅。

变更概要

本 PR 为 PerfEvent 添加 O_NONBLOCK 支持,同时实现 read(2) 读取 perf ringbuf 记录:

  1. bpf.rs:新增 try_read_record() 从 perf ringbuf 读取记录(含 wrapping_add/copy_ring 处理环形缓冲区环绕),新增 mmap_kvirt 字段保存内核虚拟地址,BPF_JIT_MEM_PAGES 常量替代硬编码
  2. kprobe.rsPROBE_CONFIG_ENTRY/PROBE_CONFIG_RETURN/KRETPROBE_MAX_ACTIVE 命名常量替代魔法数,重构为 const-pattern match
  3. mod.rsAtomicBool 实现 nonblocking()/set_nonblocking()(匹配 eventfd/signalfd 模式),FileLike::read 使用 block_on(poll_io(...)) 支持阻塞/非阻塞读
  4. uprobe.rs:使用 kprobe.rs 共享常量

代码质量

  • cargo fmt --check 通过
  • cargo clippy --all-features -D warnings 通过
  • nonblocking 实现与 eventfd/signalfd/timerfd 等现有模式完全一致
  • try_read_record 的 SAFETY 注解详尽,ring buffer 环绕逻辑正确
  • copy_ring/wrapping_add 辅助函数实现正确
  • ✅ read 闭包中正确释放 spin lock 后再返回 WouldBlock,避免死锁
  • ✅ 无 crates.io patch 引入

注意事项

  • ⚠️ 缺少 test-suit 回归测试:O_NONBLOCK + perf event fd read 是新增行为,但没有对应的 test-suit 用例覆盖。建议在 #1414 中补充最小化 perf event read/nonblocking 回归测试
  • ℹ️ CI check runs 全部 skipped(PR 关闭过快,CI 未运行),#1414 应验证 CI
  • ℹ️ 当前仅 BPF perf event(BpfPerfEventWrapper)支持 read,其他类型(kprobe/tracepoint)返回 Unsupported,符合 Linux perf_event 惯例

相关 PR

Powered by mimo-v2.5-pro

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