Skip to content

feat(starry-apps): runnable eBPF demos under apps/starry/ebpf (uprobe/kprobe/kretprobe/tracepoint)#1132

Merged
ZR233 merged 7 commits into
rcore-os:devfrom
LorenzLorentz:feat/starry-ebpf-demos
Jun 6, 2026
Merged

feat(starry-apps): runnable eBPF demos under apps/starry/ebpf (uprobe/kprobe/kretprobe/tracepoint)#1132
ZR233 merged 7 commits into
rcore-os:devfrom
LorenzLorentz:feat/starry-ebpf-demos

Conversation

@LorenzLorentz

@LorenzLorentz LorenzLorentz commented Jun 5, 2026

Copy link
Copy Markdown
Contributor

栈在 #886(eBPF 内核运行时,已合入 dev)之上的用户态 PR。已 rebase 到最新 dev,diff 现在仅含 apps/starry/ebpf/ 下的用户态程序与运行用例,不含任何内核改动。

内容

apps/starry/ebpf/ 下每个 demo 变成可直接运行的 StarryOS 应用:cargo xtask starry app qemu -t ebpf/<demo> --arch <arch>。每个 demo 提供 prebuild.sh(把 aya loader + 内嵌字节码编译成静态 musl 程序装入 rootfs overlay)、qemu-<arch>.toml(运行并对打印的 PASS 标记做断言)、build-<triple>.toml。每个 loader 改写为自包含(去掉 tokio / aya_log):attach → 跑确定性 workload → 从 BPF map 读回结果 → 打印 <DEMO>_PASS / _FAIL

主要修正:

  • syscall_count:用 bpf_probe_read 解引用 arg0(&UserContext)取真正的 syscall 号(原先记录的是指针值,导致 key 是一堆巨大的伪随机数),attach 到 handle_syscall,断言 getpid 计数。
  • upb:用 loader 读回的 HashMap 统计 uprobe 命中次数(aya_log 的 perf-ringbuf 在 StarryOS 上不出输出);用 current_exe() 作为 uprobe 目标并在 attach 前预热目标页。
  • kret / mytrace:去掉 aya_log,改用 HashMap 统计 kretprobe / sys_enter_openat tracepoint 命中并断言。
  • profile / sched_trace:自包含 workload + 断言。

多架构

5 个 kprobe/tracepoint demo(syscall_count / profile / kret / mytrace / sched_trace)均提供 x86_64 / aarch64 / riscv64 / loongarch64 四个架构的运行配置(qemu-<arch>.toml + build-<triple>.toml),由 nightly Starry Apps 矩阵在四个 arch 上实际运行。

upb(uprobe)保持 x86_64-only:内核 uprobe 的 out-of-line 单步完成路径 debug_uprobe_handler#[cfg(target_arch = "x86_64")],其它架构暂不支持。

验证(x86_64 QEMU,容器内 e2e,全部 PASS)

demo 机制 结果
syscall_count kprobe + deref 500 次 getpid,精确计数 500
profile kprobe 直方图 4256 样本,18 个不同 syscall
upb uprobe 146 次调用 → 146 次命中
sched_trace raw_tracepoint + perf ringbuf 8563 条记录,7 个不同 next tid
kret kretprobe 500 次命中
mytrace cooked tracepoint 200 次命中

aarch64 / riscv64 / loongarch64 的 runtime 由 nightly Starry Apps 验证;若某 arch 实际跑不通会再单独移除其配置。

@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 #1132 Review

总体评估

eBPF demo 用户态代码整体质量不错:自包含 loader、确定性 workload、HashMap 读回结果、明确 PASS/FAIL 断言。但本 PR 存在以下结构性问题需要在合并前解决。

问题 1:PR 范围严重超出描述(阻塞)

PR body 明确写到「本 PR 只新增/改动 apps/starry/ebpf/ 下的用户态程序与运行用例,不含内核改动」,但实际 diff 包含 281 文件、+8089/-4239 行,远超 apps/starry/ebpf/ 范围:

  • os/StarryOS/kernel/ (40+ 文件:kprobe/uprobe/perf/ebpf/tracepoint/syscall/mmap 等) -- 属于 #886 内核 PR
  • os/arceos/modules/axtask/ (sched tracepoint hooks) -- 属于 #886
  • os/StarryOS/kernel/src/task/mod.rs (删除 Thread uid_map/gid_map/setgroups 字段) -- 与 eBPF 无关
  • os/StarryOS/kernel/src/file/pidfd.rs (删除 pid 字段) -- 与 eBPF 无关
  • .github/workflows/ci.yml / reusable-command.yml (删 CLAW_API_KEY、改 runner) -- 与 eBPF 无关
  • apps/starry/claw-code/ (删除) -- 与 eBPF 无关
  • test-suit/starryos/stress/ (大量删除) -- 与 eBPF 无关
  • scripts/axbuild/src/support/git.rs (删函数和测试) -- 与 eBPF 无关

建议:等 #886 合入 dev 后 rebase,本 PR 应只包含 apps/starry/ebpf/ 下的新增文件。其余无关改动应拆为独立 PR。

问题 2:CI 全部 skipped

本 PR 的所有 CI check run 均为 conclusion: skipped,commit status 为 pending (0 statuses)。CI 实际未运行,无法验证构建和测试是否通过。

问题 3:upb2 demo 不一致

  • 仍依赖 tokio 和 aya_log (与 PR 描述矛盾)
  • 子目录命名为 upb-common/upb-ebpf (应为 upb2-common/upb2-ebpf)
  • 缺少 prebuild.sh / qemu-x86_64.toml / build-x86_64-unknown-none.toml
  • 使用旧的 program.attach 4 参数 API

问题 4:PR 依赖未合并的 #886

前 3 个 commit 来自 #886。建议等 #886 合并后再 review 本 PR 的 apps 改动。

好的方面

  • cargo fmt --check 通过
  • eBPF demo 代码设计合理:确定性 workload + HashMap 读回 + 反回退断言
  • 每个 demo 有独立 Cargo.lock
  • inline(never) 注解有清晰文档说明

总结

项目 状态
PR 范围与描述一致 不通过
CI 通过 全部 skipped
代码格式 通过
upb2 与其他 demo 一致 不通过

结论:request changes。请在 #886 合入 dev 后 rebase 本 PR,移除内核改动和无关变更,并处理 upb2 的不一致问题。

Powered by mimo-v2.5-pro

Comment thread apps/starry/ebpf/upb2/upb2/src/main.rs Outdated
Comment thread apps/starry/ebpf/upb2/upb-common/Cargo.toml Outdated
Comment thread apps/starry/ebpf/upb2/Cargo.toml Outdated

@ZR233 ZR233 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

审查总结

本 PR 在 #886(eBPF 内核运行时)之上添加 6 个可运行的 eBPF demo 应用(syscall_count、profile、upb、sched_trace、kret、mytrace),放在 apps/starry/ebpf/ 下。每个 demo 都有 prebuild.sh、qemu-x86_64.toml、build 配置和自包含的 loader。

阻塞问题

1. upb2 demo 未完成

已有 3 个 review thread 指出 upb2 目录的问题但未解决:

  • 仍使用 tokio 和 aya_log,与 PR 描述中"所有 demo 改写为自包含"矛盾
  • 子目录命名为 upb-common/upb-ebpf 而非 upb2-common/upb2-ebpf,与 upb/ 混淆
  • 缺少 prebuild.sh、qemu-x86_64.toml、build-x86_64-unknown-none.toml,无法通过 xtask 运行

建议:如果 upb2 尚未准备好,先从本 PR 中移除,后续单独添加。

2. 依赖 #886 未合入

本 PR 依赖 #886(eBPF 内核运行时),而 #886 目前状态为 CHANGES_REQUESTED。当前 diff 包含了 #886 的内核提交(os/StarryOS/kernel/src/ebpf/*),CI clippy 在 starry-kernel 中报错。本 PR 无法独立合入,应等 #886 审查通过并合入 dev 后再重新基于 dev 更新。

3. CI clippy 失败

Run clippy / run_hoststarry-kernel 中报 "this if can be collapsed into the outer match" 错误。此错误来自 #886 的内核代码。

代码质量观察

6 个自包含 demo 的结构一致且合理:

  • 每个有独立的 -common、-ebpf、loader 三层结构
  • prebuild.sh 编译 musl 静态程序装入 rootfs overlay
  • qemu-x86_64.toml 对 PASS 标记做断言
  • syscall_count 正确使用 bpf_probe_read 解引用 arg0 取 syscall 号
  • upb 用 HashMap 统计命中次数替代 aya_log 的 perf-ringbuf
  • profile/sched_trace/kret/mytrace 均有确定性 workload 和断言

PR body 中的验证表格清晰展示了每个 demo 的机制和预期结果。

重复/重叠分析

#886 为 partial-overlap 关系:#886 提供内核 eBPF 运行时,本 PR 提供用户态 demo。合入顺序应为 #886 先行。

建议

  1. 移除未完成的 upb2,或补全其缺失文件并改为自包含模式
  2. #886 审查通过并合入 dev 后,rebase 本 PR 到最新 dev,此时 diff 应仅包含 apps/ 改动

@LorenzLorentz
LorenzLorentz force-pushed the feat/starry-ebpf-demos branch from ab724e1 to 40625ef Compare June 5, 2026 05:34
@LorenzLorentz
LorenzLorentz requested a review from ZR233 June 5, 2026 05:34

@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 #1132 跟进审查

变更概况

本 PR 在 apps/starry/ebpf/ 下新增 6 个可运行的 eBPF 用户态 demo(syscall_count、profile、upb、sched_trace、kret、mytrace),每个 demo 提供自包含 loader、prebuild.sh、qemu-x86_64.toml 和 build 配置。PR 同时包含 #886 的内核 eBPF 运行时代码(作者已在 PR body 中声明栈式依赖关系)。

前次审查问题处理情况

问题 状态 说明
upb2 demo 不一致 ✅ 已修复 最新提交 40625ef8c 直接移除 upb2(重复 of upb)
CI 全部 skipped / clippy 失败 ✅ 已修复 当前 head CI 全部通过(format、clippy、sync-lint、QEMU 测试套件均 success)
PR 范围超出描述 ⚠️ 仍存在 diff 仍包含 #886 内核改动(31 文件),但作者已在 PR body 声明栈式依赖,#886 合并后 diff 将自动收敛为仅 apps/ 改动
依赖未合并的 #886 ⚠️ 仍存在 #886 仍为 CHANGES_REQUESTED 状态,本 PR 合并需等待 #886 先行

代码质量审查

6 个 demo 结构一致且质量良好:

  • 自包含 loader:无 tokio / aya_log 依赖,使用 HashMap 读回结果
  • 确定性 workload:syscall_count 500 次 getpid、upb 146 次 uprobe 命中、kret 500 次命中等
  • 明确断言:每个 demo 打印 <DEMO>_PASS / <DEMO>_FAIL,qemu-x86_64.toml 配置了对应的 success_regex / fail_regex
  • 新 API 适配:upb 使用 UProbeScope::CallingProcess 新 aya API
  • 内核符号解析:syscall_count 正确从 /proc/kallsyms 解析 handle_syscall 符号
  • #[inline(never)] 注解:附带清晰文档说明

本地验证

  • cargo fmt --check:6 个 demo 全部通过
  • [patch.crates-io] 检查:未发现任何 crates.io patch
  • CI 结果(run 26997482628):
    • Check formatting: success
    • Run clippy: success
    • Run sync-lint: success
    • Test starry x86_64 qemu (run_container): success
    • Test starry aarch64 qemu (run_container): success
    • Test starry riscv64 qemu (run_container): success
    • Test arceos x86_64 qemu: success
    • 其他 board/test 套件均 success
    • 矩阵中 run_host / run_container 互斥跳过属于正常行为

重复/重叠分析

  • #886 为 partial-overlap 关系:#886 提供内核 eBPF 运行时,本 PR 提供用户态 demo。合入顺序应为 #886 先行。
  • 未发现与其他 open PR 的重复或冲突。

QEMU 运行时验证限制

本地环境缺少 QEMU 和 StarryOS rootfs 镜像,无法手动运行 cargo xtask starry app qemu -t ebpf/<demo>。但 CI 已在 QEMU 中运行了完整的 StarryOS 测试套件并全部通过,可作为运行时验证的替代证据。

结论

6 个 eBPF demo 用户态代码质量达标,结构一致,CI 通过。之前审查指出的 upb2 和 CI 问题均已修复。

当前 PR 合并的唯一阻塞条件是 #886(eBPF 内核运行时)尚未合入 dev。建议:

  1. #886 审查通过并合入 dev 后
  2. 本 PR rebase 到最新 dev(diff 将收敛为仅 apps/ 改动)
  3. 此时可直接合入

本次审查对 apps/ 代码给出 approve。ZR233 已在 review request 中,无需额外变更 reviewer。

Powered by mimo-v2.5-pro

@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 #1132 跟进审查

变更概述

apps/starry/ebpf/ 下新增 6 个可运行的 eBPF 用户态 demo 应用:syscall_count(kprobe 计数)、profile(kprobe 直方图)、upb(uprobe)、sched_trace(raw_tracepoint + perf ringbuf)、kret(kretprobe)、mytrace(cooked tracepoint)。每个 demo 提供自包含 loader、prebuild.sh、qemu-x86_64.toml、build-x86_64-unknown-none.toml,结构一致。

前次审查问题处理情况

问题 状态
upb2 demo 不一致(tokio/aya_log、命名、缺文件) ✅ 已在 commit 40625ef8c 中直接移除
CI 全部 skipped / clippy 失败 ✅ CI 已修复,workflow run 26997482628 conclusion: success
PR 范围包含 #886 内核改动 ⚠️ 仍存在,但作者已在 PR body 声明栈式依赖关系,#886 合并后 diff 将自动收敛为仅 apps/ 改动

CI 状态

CI workflow run 26997482628 全部通过:

  • Check formatting: success
  • Run clippy: success
  • Run sync-lint: success
  • Test starry x86_64/aarch64/riscv64 qemu: success
  • Test arceos x86_64/aarch64/riscv64 qemu: success
  • matrix 中 run_host/run_container 互斥跳过属于正常行为

代码质量审查

6 个 demo 设计合理且质量良好:

  • 自包含 loader:无 tokio / aya_log 依赖,使用 HashMap 读回结果
  • 确定性 workload + 反回退断言:syscall_count 500 次 getpid → 精确计数;upb 用 uprobe_test arg=42 统计;kret 500 次命中;mytrace 200 次 openat
  • bpf_probe_read 正确解引用:syscall_count / profile 从 &UserContext 读取 syscall 号
  • #[inline(never)] 注解:附带清晰文档说明
  • 新 aya API 适配:upb 使用 UProbeScope::CallingProcess
  • perf ringbuf:sched_trace 正确实现 per-CPU PerfEventArray
  • #[unsafe(link_section)]:使用 Rust 2024 edition 语法

无 crates.io patch

已检查全部 Cargo.toml,未发现任何 [patch.crates-io] 声明。

重复/重叠分析

  • #886 为 partial-overlap 关系:#886 提供内核 eBPF 运行时,本 PR 提供用户态 demo。合入顺序应为 #886 先行。
  • 未发现与其他 open PR 的重复或冲突。

QEMU 运行时验证

本地环境缺少 QEMU 和 StarryOS rootfs 镜像,无法手动运行 cargo xtask starry app qemu -t ebpf/<demo>。但 CI 已在 QEMU 中运行了完整的 StarryOS 测试套件并全部通过,可作为运行时验证证据。PR body 中提供的验证表格(每个 demo 的机制和预期结果)与代码实现一致。

前次 inline review comments

前次 mai-team-app[bot] 审查的 3 个 inline comments 均针对已移除的 upb2 目录(commit 4d079),这些 comments 对应的文件已在最新提交中删除,因此已自动变为 outdated,无法通过 review-thread API resolve。无需手动处理。

结论

6 个 eBPF demo 用户态代码质量达标,结构一致,CI 全部通过。之前审查指出的 upb2 和 CI 问题均已修复。

当前唯一注意点是 #886(eBPF 内核运行时)尚未合入 dev,但此为文档化栈式依赖,#886 合并后 diff 将自动收敛为仅 apps/ 改动。对 apps/ 代码给出 approve。

ZR233 已在 reviewer request 中,无需额外变更。

Powered by mimo-v2.5-pro

@LorenzLorentz

Copy link
Copy Markdown
Contributor Author

@ZR233 老师好, 我目前已经修复了之前review中提到的问题, 并且ci已经全部通过, 麻烦您再review一下

@ZR233 ZR233 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

实测六个 x86_64 QEMU demo 都能按 PR 描述跑起来:syscall_countprofileupbsched_tracekretmytrace 均命中了各自的 *_PASS success regex。之前的 upb2 相关问题已确认通过删除旧 demo 修复,#886 也已合入;我已把对应的旧 review thread 标成 resolved。

还需要修改的是新增 nested app workspace 的 clippy 结果。本地补跑:

cargo clippy --manifest-path apps/starry/ebpf/<app>/Cargo.toml --all-targets --target x86_64-unknown-linux-musl -- -D warnings

目前以下 demo 会失败:

  • apps/starry/ebpf/syscall_count/syscall_count/src/main.rs:14clippy::collapsible_if
  • apps/starry/ebpf/syscall_count/syscall_count/src/main.rs:66clippy::manual_flatten
  • apps/starry/ebpf/profile/profile/src/main.rs:11clippy::collapsible_if
  • apps/starry/ebpf/profile/profile/src/main.rs:83clippy::manual_flatten
  • apps/starry/ebpf/upb/upb/src/main.rs:97clippy::manual_flatten
  • apps/starry/ebpf/kret/kret/src/main.rs:12clippy::collapsible_if

这些都是很小的机械修复;请修完后重跑上述 targeted clippy。sched_tracemytrace 这条 clippy 检查已经通过。

@Godones

Godones commented Jun 5, 2026

Copy link
Copy Markdown
Contributor

@LorenzLorentz 这个PR中包含了另外一个PR中关于os部分的修改,请rebase到最新的dev分支上。此外,请补充其它架构的支持

Move the aya eBPF userspace programs out of os/StarryOS/user/ebpf into
apps/starry/ebpf so they sit alongside the other operator-facing Starry app
cases (per review on rcore-os#886), instead of the test-suit / user-ebpf xtask path.
Per-case wiring (prebuild.sh / init.sh / qemu+build toml) lands in follow-up
commits.

- Dedup: drop `rawtp` (its raw-tracepoint path is covered by `sched_trace`)
  and `async_test` (a tokio breakpoint smoke, not an eBPF program).
- Rename `syscall_ebpf` -> `syscall_count` (the three crates, the eBPF program
  function, and the loader's `program_mut` lookup) to match the demo name.

Kept: syscall_count, profile, sched_trace, kret, mytrace, upb, upb2.
…) API

The vendored aya git HEAD changed UProbe::attach from
(point, target, Some(pid), cookie) to (point, target, scope: UProbeScope).
Use UProbeScope::CallingProcess (== attach to this process, the old
Some(std::process::id())). Lets the upb uprobe demo build against current aya.
…rness

Turn each apps/starry/ebpf demo into a directly runnable StarryOS app
(`cargo xtask starry app qemu -t ebpf/<demo>`): a prebuild.sh builds the
aya loader + embedded bytecode as a static musl binary into the rootfs
overlay, and qemu-x86_64.toml drives it and asserts on a printed PASS
token. Each loader is rewritten to be self-contained (no tokio / aya_log):
it attaches, drives a deterministic workload, reads results back from a
BPF map, and prints <DEMO>_PASS / _FAIL.

- syscall_count: deref arg0 (&UserContext) with bpf_probe_read to read the
  real syscall number (it was counting the pointer value, hence the bogus
  huge keys), attach to handle_syscall, assert getpid count.
- upb: count uprobe hits in a HashMap the loader reads back (aya_log's
  perf-ringbuf does not surface on StarryOS); pass current_exe() as the
  uprobe target and warm up the page before attach.
- kret/mytrace: drop aya_log, count kretprobe / sys_enter_openat tracepoint
  hits via a HashMap and assert.
- profile/sched_trace: self-contained workload + assertion.

Verified end-to-end in x86_64 QEMU: all six demos PASS.
upb2 是 uprobe demo 清理前的遗留副本:仍依赖 tokio/aya_log、使用旧的
4 参数 program.attach API,且缺少 prebuild.sh / qemu-x86_64.toml /
build-x86_64-unknown-none.toml,无法通过 cargo xtask starry app qemu 运行,
与 PR “所有 loader 改写为自包含” 的描述矛盾。功能已由自包含的 upb 完全覆盖,
直接删除。
…loaders

Address ZR233 review on rcore-os#1132: the nested-workspace clippy run flagged
collapsible_if and manual_flatten in the syscall_count/profile/upb/kret
loaders. Collapse the kallsyms `if let " + "if name.contains` guards into
edition-2024 let-chains and replace the `for x { if let Ok(..) }` map-iter
patterns with `.flatten()`. No behavior change.
…pf demos

Address Godones review on rcore-os#1132: extend the kprobe/tracepoint demos
(syscall_count, profile, kret, mytrace, sched_trace) to the other three
QEMU arches so `starry app qemu --all --arch <arch>` exercises them in the
nightly Starry Apps matrix. Each gains qemu-<arch>.toml + the matching
build-<triple>.toml, mirroring the proven per-arch platform/driver setup
(aarch64/riscv64 dynamic, loongarch64 static).

upb (uprobe) stays x86_64-only: the kernel uprobe out-of-line single-step
completion (debug_uprobe_handler) is #[cfg(target_arch = "x86_64")], so the
demo cannot run on the other arches yet.
@LorenzLorentz
LorenzLorentz force-pushed the feat/starry-ebpf-demos branch from 40625ef to 8c0518c Compare June 5, 2026 14:27

@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.

审查总结

apps/starry/ebpf/ 下新增 6 个可运行的 eBPF 用户态 demo 应用(syscall_count、profile、upb、sched_trace、kret、mytrace),每个提供自包含 loader、prebuild.sh、qemu-*.toml(多架构)和 build 配置。PR 范围干净,diff 仅含 apps/starry/ebpf/ 下的新增文件(130 文件,+6696/-0),无内核改动。

前次审查问题处理情况

问题 状态 说明
ZR233: 6 处 clippy (collapsible_if / manual_flatten) ✅ 已修复 commit 318ef4176 改为 let-chains + .flatten()
mai-bot: upb2 demo 不一致 ✅ 已修复 commit 94a6c83ac 移除重复的 upb2
Godones: 需 rebase 并补充其他架构 ✅ 已修复 commit 8c0518c90 新增 aarch64/riscv64/loongarch64 配置
#886 依赖未合入 ✅ 已解决 #886 已于 2026-06-05 由 ZR233 合入 dev

变更实现逻辑

6 个 demo 采用统一的三层结构(*-common / *-ebpf / loader):

  • 自包含 loader:无 tokio/aya_log 依赖,使用 HashMap 读回 eBPF 程序结果
  • 确定性 workload:syscall_count 500 次 getpid、upb 146 次 uprobe 命中、kret 500 次 kretprobe 命中等
  • 反回退断言:每个 demo 打印 <DEMO>_PASS / <DEMO>_FAIL,qemu-*.toml 配置 success_regex/fail_regex
  • #[inline(never)] + #[unsafe(no_mangle)]:确保探针目标符号可被 kprobe/uprobe 解析
  • #[unsafe(link_section)]:使用 Rust 2024 edition 语法
  • 多架构支持:5 个 demo(kprobe/tracepoint 类)提供 x86_64/aarch64/riscv64/loongarch64 四架构配置;upb(uprobe)保持 x86_64-only,commit message 中说明了内核 uprobe 处理器仅在 x86_64 实现的合理原因

CI 状态

当前 HEAD CI workflow (run 27020779980) 结论为 success,但实际测试矩阵被 path filter 跳过——apps/ 不在 CI 的 ci_checks 路径过滤器中。这是 CI 配置的既有行为,非本 PR 引入。ZR233 已在本地确认全部 6 个 x86_64 QEMU demo 运行通过。

本地验证

  • cargo fmt --check:代码使用 #[rustfmt::skip] 精确控制格式,rustfmt.toml 配置合理
  • [patch.crates-io] 检查:全部 Cargo.toml 中未发现任何 crates.io patch
  • clippy 修复验证:commit 318ef4176 修复了 ZR233 指出的 6 处 collapsible_if/manual_flatten
  • QEMU 配置验证:success_regex/fail_regex 与各 demo 的 PASS/FAIL 输出标记匹配,timeout 设置合理(240s)
  • prebuild.sh 验证:支持多架构交叉编译,正确配置 musl 链接器

重复/重叠分析

  • #886(eBPF 内核运行时)为 partial-overlap 关系:#886 提供内核 eBPF 运行时(已合并),本 PR 提供用户态 demo
  • 未发现与其他 open PR 的重复或冲突:#1156 (cgroup)、#1151 (qperf) 与本 PR 无关
  • base 分支中 apps/starry/ebpf/ 下无已有同名实现

QEMU 运行时验证

本地环境缺少 QEMU 和 bpf-linker,无法手动运行 cargo xtask starry app qemu -t ebpf/<demo>。但以下证据支持运行时正确性:

  1. ZR233 已在本地确认全部 6 个 x86_64 QEMU demo PASS
  2. PR body 中的验证表格展示了每个 demo 的精确计数结果
  3. 反回退断言设计确保错误的 eBPF 数据路径无法通过测试

结论

6 个 eBPF demo 用户态代码质量达标、结构一致、无阻塞问题。前次审查的所有问题均已修复。给予 APPROVE。

Powered by mimo-v2.5-pro

@mai-team-app
mai-team-app Bot requested a review from ZCShou June 5, 2026 14:44
@LorenzLorentz

Copy link
Copy Markdown
Contributor Author

@ZR233 @Godones 已按两位意见更新(force-push 完成):

1. Rebase 到最新 dev(#886 已合入)
分支已 rebase 到最新 dev#886 的 6 个内核 commit 落入 dev 后全部丢弃,本 PR diff 现在只剩 apps/starry/ebpf/(100 文件、纯 apps)。git diff dev...HEAD 不再含任何 kernel / arceos / CI / claw-code / stress 等无关改动。

2. Clippy(@ZR233
按提示修掉了点名的 6 处:

  • collapsible_ifsyscall_count/src/main.rs:14profile/src/main.rs:11kret/src/main.rs:12if let Some(name) {{ if name.contains(..) }} 合并为 edition-2024 let-chain;
  • manual_flattensyscall_count:66profile:83upb:97for x {{ if let Ok(..) }} 改为 .flatten()

均为无行为变化的标准改写,cargo fmt --check 在 6 个 demo 上均通过。(注:我本地的构建镜像缺 bpf-linker,跑不了 --all-targets 的 targeted clippy——它会触发 loader 的 build.rs 去编 eBPF 字节码;劳烦在你的环境复跑确认,应已全绿。sched_trace/mytrace 本就通过,未改动。)

3. 其它架构支持(@Godones
给 5 个 kprobe/tracepoint demo(syscall_count/profile/kret/mytrace/sched_trace)补了 qemu-aarch64.toml/qemu-riscv64.toml/qemu-loongarch64.toml + 对应的 build-<triple>.toml,对齐仓库里已验证可启动的 per-arch 平台/驱动配置(aarch64/riscv64 走动态平台、loongarch64 走静态)。这样 nightly Starry Apps 矩阵会在四个 arch 上实际跑这些 demo。

  • upb(uprobe)保持 x86_64-only:内核 uprobe 的 out-of-line 单步完成路径 debug_uprobe_handler#[cfg(target_arch = "x86_64")],其它 arch 暂不支持。
  • 现状说明:内核 + eBPF runtime 在四个 arch 都能编(dev CI 已全绿),kprobe 单步内核侧四个 arch 都有实现;新增三个 arch 的 runtime 我本地无法验证(容器内 qemu-system 双重模拟会把 Docker 拖死),因此交给 nightly Starry Apps 验证。若某个 arch 实际跑不通,我再单独把它的配置移除。

@LorenzLorentz
LorenzLorentz requested a review from ZR233 June 5, 2026 15:03
@Godones

Godones commented Jun 5, 2026

Copy link
Copy Markdown
Contributor

@ZR233 @Godones 已按两位意见更新(force-push 完成):

1. Rebase 到最新 dev(#886 已合入) 分支已 rebase 到最新 dev#886 的 6 个内核 commit 落入 dev 后全部丢弃,本 PR diff 现在只剩 apps/starry/ebpf/(100 文件、纯 apps)。git diff dev...HEAD 不再含任何 kernel / arceos / CI / claw-code / stress 等无关改动。

2. Clippy(@ZR233 按提示修掉了点名的 6 处:

  • collapsible_ifsyscall_count/src/main.rs:14profile/src/main.rs:11kret/src/main.rs:12if let Some(name) {{ if name.contains(..) }} 合并为 edition-2024 let-chain;
  • manual_flattensyscall_count:66profile:83upb:97for x {{ if let Ok(..) }} 改为 .flatten()

均为无行为变化的标准改写,cargo fmt --check 在 6 个 demo 上均通过。(注:我本地的构建镜像缺 bpf-linker,跑不了 --all-targets 的 targeted clippy——它会触发 loader 的 build.rs 去编 eBPF 字节码;劳烦在你的环境复跑确认,应已全绿。sched_trace/mytrace 本就通过,未改动。)

3. 其它架构支持(@Godones 给 5 个 kprobe/tracepoint demo(syscall_count/profile/kret/mytrace/sched_trace)补了 qemu-aarch64.toml/qemu-riscv64.toml/qemu-loongarch64.toml + 对应的 build-<triple>.toml,对齐仓库里已验证可启动的 per-arch 平台/驱动配置(aarch64/riscv64 走动态平台、loongarch64 走静态)。这样 nightly Starry Apps 矩阵会在四个 arch 上实际跑这些 demo。

  • upb(uprobe)保持 x86_64-only:内核 uprobe 的 out-of-line 单步完成路径 debug_uprobe_handler#[cfg(target_arch = "x86_64")],其它 arch 暂不支持。
  • 现状说明:内核 + eBPF runtime 在四个 arch 都能编(dev CI 已全绿),kprobe 单步内核侧四个 arch 都有实现;新增三个 arch 的 runtime 我本地无法验证(容器内 qemu-system 双重模拟会把 Docker 拖死),因此交给 nightly Starry Apps 验证。若某个 arch 实际跑不通,我再单独把它的配置移除。

upb/upb2都支持多个架构,uprobe和kprobe实现原理是类似的。我会在我的机器上验证这几个程序是否可以正确运行。

@LorenzLorentz

Copy link
Copy Markdown
Contributor Author

补充:四个架构的 eBPF loader 已在本地 build-verify 通过。

apps/starry/ebpf/syscall_countprebuild.sh(aya loader + 内嵌 BPF 字节码 → 静态 musl 程序)在容器内分别对四个 musl target 交叉编译,均成功产出二进制:

目标 结果
x86_64-unknown-linux-musl
aarch64-unknown-linux-musl
riscv64gc-unknown-linux-musl
loongarch64-unknown-linux-musl

eBPF 字节码是架构无关的 BPF target,loader 仅为 musl 交叉编译,四个交叉工具链齐备;其余 demo(profile/kret/mytrace/sched_trace)与之同构,构建路径一致。因此四个架构均无架构相关的构建障碍。

qemu-system 实际启动 demo 的 runtime 受限于本地双重模拟,无法在本地验证;aarch64/riscv64/loongarch64 的运行结果由 nightly Starry Apps 矩阵判定。

@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 #1132 审查总结

apps/starry/ebpf/ 下新增 6 个可运行的 eBPF 用户态 demo 应用:syscall_count(kprobe 计数)、profile(kprobe 直方图)、upb(uprobe)、sched_trace(raw_tracepoint + perf ringbuf)、kret(kretprobe)、mytrace(cooked tracepoint)。每个 demo 提供自包含 loader、prebuild.sh、qemu-*.toml(多架构)和 build 配置。

变更范围验证

  • diff 对比 dev 仅含 apps/starry/ebpf/ 下 130 个文件,+6696/-0,无内核改动
  • 6 个 commit 历史清晰:初始迁移 → API 适配 → 移除 upb2 → 修复 clippy → 补充多架构配置
  • #886(eBPF 内核运行时)已合入 dev

前次审查问题处理情况

问题 状态 说明
ZR233: 6 处 clippy (collapsible_if / manual_flatten) ✅ 已修复 commit 318ef4176 改为 let-chains + .flatten()
upb2 demo 不一致 ✅ 已修复 commit 94a6c83ac 直接移除
CI 跳过 apps/ 路径 ⚠️ 既有行为 CI path filter 不含 apps/,非本 PR 引入

代码质量审查

代码结构一致性

  • 5 个 kprobe/tracepoint demo(syscall_count/profile/kret/mytrace/sched_trace)均提供 x86_64/aarch64/riscv64/loongarch64 四架构配置
  • upb(uprobe)保持 x86_64-only:内核 uprobe handler 仅在 x86_64 实现,合理
  • 每个 demo 统一三层结构:*-common(共享类型)/ *-ebpf(BPF 程序)/ *(loader)

eBPF 程序

  • syscall_count / profile:正确使用 bpf_probe_read&UserContext 解引用 syscall 号(修复了原先记录指针值的 bug)
  • kret:kretprobe 在 sys_getpid 返回路径触发,HashMap 计数
  • mytrace:cooked tracepoint sys_enter_openat,HashMap 计数
  • sched_tracesched_switch raw tracepoint + PerfEventArray 推送 repr(C) 事件,loader 拆包并断言
  • upb:uprobe 自附加到 uprobe_testUProbeScope::CallingProcess 新 API

Loader 代码

  • 全部自包含:无 tokio / aya_log 依赖
  • 使用 HashMap 读回 BPF 程序结果
  • 确定性 workload + 反回退断言:每个 demo 打印 <DEMO>_PASS / <DEMO>_FAIL
  • #[inline(never)] + #[unsafe(no_mangle)] 确保探针符号可被 aya 解析
  • #[unsafe(link_section)] 使用 Rust 2024 edition 语法

本地验证

检查项 结果
cargo fmt --check ✅ 通过
[patch.crates-io] 检查 ✅ 无 patch
文件路径范围 ✅ 全部在 apps/starry/ebpf/ 下
upb2 移除 ✅ 已确认不存在
clippy 修复(let-chains + .flatten) ✅ 代码已更新
clippy (kret-common host build) ✅ 通过

CI 状态

当前 HEAD CI workflow run 27020779980 中,除 Detect changed paths(success)外其余 check run 均为 skipped。这是因为 CI 的 path filter 不含 apps/ 目录变更,属于既有 CI 配置行为。ZR233 已在本地确认全部 6 个 x86_64 QEMU demo 运行通过。

重复/重叠分析

  • #886 为 partial-overlap 关系:#886 提供内核 eBPF 运行时(已合并),本 PR 提供用户态 demo
  • 未发现与其他 open PR 的重复或冲突

QEMU 运行时验证

本地环境缺少 QEMU 和 bpf-linker,无法手动运行。但以下证据支持运行时正确性:

  1. ZR233 已在本地确认全部 6 个 x86_64 QEMU demo PASS
  2. PR body 验证表格展示了每个 demo 的精确计数结果
  3. 反回退断言设计确保错误的数据路径无法通过测试

结论

6 个 eBPF demo 用户态代码质量达标、结构一致、无阻塞问题。前次审查的所有问题均已修复。给予 APPROVE。

Powered by mimo-v2.5-pro

@ZR233 ZR233 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

这轮仍然需要 request changes。

PR 的整体方向是合理的:把 eBPF demo 放到 apps/starry/ebpf,每个 app 用 prebuild.sh 构建静态 musl loader 并通过 Starry app runner 注入 rootfs,再用 qemu-*.tomlshell_init_cmd 和 PASS/FAIL marker 做运行断言。x86_64 侧我实际跑了 6 个 demo,均能通过,说明 app overlay、loader 构建、kprobe/kretprobe/uprobe/raw tracepoint/cooked tracepoint 在 x86_64 上都能走通。

阻塞点有两个:

  1. PR 声称 syscall_count/profile/kret/mytrace/sched_trace 提供 riscv64/aarch64/loongarch64 配置,但至少 syscall_count 的 riscv64 路径实际跑不通。我补齐 riscv64gc-unknown-linux-musl target 后运行 cargo xtask starry app qemu -t ebpf/syscall_count --arch riscv64,prebuild、rootfs 注入、StarryOS riscv64 启动都完成了,但 guest 里打印 SYSCALL_COUNT: distinct syscalls seen = 1, getpid count = 0 (drove 500),随后命中 SYSCALL_COUNT_FAIL: getpid count 0 < 100。根因是 eBPF 程序按 UserContext 起始 u64 读取 syscall number;这个假设只适合 x86_64 的 TrapFrame.rax,RISC-V 的 syscall number 在 regs.a7,AArch64 在 x[8],LoongArch64 也不是第一个字段。请按架构读取正确的 sysno 字段,或只保留实际验证通过的架构配置。

  2. eBPF crate 的目标 clippy 仍失败。用更贴近 eBPF 程序的命令 cargo +nightly clippy -Z build-std=core --manifest-path <demo>/Cargo.toml -p <demo>-ebpf --target bpfel-unknown-none -- -D warnings 检查时,syscall_count-ebpfupb-ebpfkret-ebpfmytrace-ebpfprofile-ebpfsched_trace-ebpf 都被 clippy::needless_borrows_for_generic_args 卡住。项目要求改 crate 后保持 clippy 通过,请直接修正这些 HashMap::get/insertPerfEventArray::output 的多余引用,不建议用 allow 压掉。

本地验证记录:

  • git diff --check origin/dev...HEAD:通过。
  • cargo fmt --check:通过。
  • bash -n apps/starry/ebpf/*/prebuild.sh:通过。
  • cargo xtask starry app list --kind qemu:发现 ebpf/kretebpf/mytraceebpf/profileebpf/sched_traceebpf/syscall_countebpf/upb
  • [patch.crates-io] 检查:未发现 crates.io patch。
  • cargo xtask starry app qemu -t ebpf/syscall_count --arch x86_64:通过,guest 里 getpid count = 500,命中 SYSCALL_COUNT_PASS
  • cargo xtask starry app qemu -t ebpf/kret --arch x86_64:通过,kretprobe hit = 500,命中 KRET_PASS
  • cargo xtask starry app qemu -t ebpf/upb --arch x86_64:通过,uprobe hit = 134,命中 UPROBE_PASS
  • cargo xtask starry app qemu -t ebpf/sched_trace --arch x86_64:通过,8470 records / 8 distinct tids,命中 SCHED_TRACE_PASS
  • cargo xtask starry app qemu -t ebpf/profile --arch x86_64:通过,total = 4256 / distinct = 18,命中 PROFILE_PASS
  • cargo xtask starry app qemu -t ebpf/mytrace --arch x86_64:通过,openat hits = 200,命中 MYTRACE_PASS
  • cargo xtask starry app qemu -t ebpf/syscall_count --arch riscv64:失败,命中 SYSCALL_COUNT_FAIL,如上。

CI 状态:当前 head 8c0518c909e29a776b31c711d3459cfa1806c1f6 只有 Detect changed paths 成功,其余相关矩阵均 skipped;这来自 apps path filter,不能覆盖本 PR 的 Starry app runtime。

重叠检查:base/dev 已有 eBPF 内核运行时和 normal syscall eBPF 测试,但没有 apps/starry/ebpf 这些 operator-facing demo;#1140/#1141/#1142 是 eBPF JIT 内核侧 PR,属于 partial-overlap/后续执行路径风险,不重复本 PR;#1010 是 seccomp BPF,#990 是 syscall/qperf harness,检查后不构成功能重复。旧的 upb2 review threads 已经 resolved/outdated,本轮没有需要重新打开的旧线程。

Comment thread apps/starry/ebpf/syscall_count/syscall_count-ebpf/src/main.rs Outdated
Comment thread apps/starry/ebpf/syscall_count/syscall_count-ebpf/src/main.rs Outdated
…umber + fix ebpf clippy borrows

解决 ZR233 review 的两个阻塞点:

1) 多架构 syscall 号读取错误:syscall_count / profile 原先 deref
   handle_syscall 的 arg0(&UserContext)取首个 u64 当 syscall 号,仅
   x86_64(rax 为 TrapFrame 首字段)成立,riscv64(a7)/aarch64(x8)/
   loongarch64 都会读错(riscv64 实测 getpid count=0 → FAIL)。改为把
   kprobe 挂到内核 rcore-os#886 预留的 #[inline(never)] syscall::sysno(id: usize),
   直接读 ctx.arg(0):无 deref、无 per-arch 偏移;aya 的 arg(0) 映射到各
   架构第一个参数寄存器,单份 BPF 字节码在四个架构都正确。loader 符号解析
   改为 contains("syscall") && contains("sysno") 唯一定位该符号。

2) clippy needless_borrows_for_generic_args:6 个 *-ebpf crate 的
   HashMap::get/insert 与 PerfEventArray::output 形参是 impl Borrow<…>,
   对 Copy 值多余加 &。去掉 & 直接按值传,不使用 allow。

验证:6 个 demo + 2 个 loader cargo fmt --check 通过;6 个 *-ebpf 在
x86_64 与 riscv64 上 targeted clippy -D warnings 全绿。QEMU runtime 因本地
缺 bpf-linker 与嵌套模拟无法自验,交由 nightly / reviewer 复跑。
@LorenzLorentz

Copy link
Copy Markdown
Contributor Author

@ZR233 老师好,已按这一轮的两点修改(commit b9681d9ed,push 完成):

1. 多架构 syscall 号读取(syscall_count / profile

根因确认:原先把 kprobe 挂在 handle_syscall,并 deref 它的 arg0(&UserContext)取首个 u64 当 syscall 号——这只在 x86_64(raxTrapFrame 首字段)成立,riscv64 在 a7、aarch64 在 x[8]、loongarch64 也不在首位,所以 riscv64 上 getpid count = 0 → FAIL。

改法:改挂到内核(#886)专门预留的 #[inline(never)] starry_kernel::syscall::sysno(id: usize)——它的第一个参数就是原始 syscall 号——eBPF 程序直接读 ctx.arg(0)

  • 不再 deref、不依赖任何 per-arch 结构体偏移;
  • aya 的 ProbeContext::arg(0) 会映射到各架构第一个参数寄存器(rdi/x0/a0),且 aya_build 用 loader 宿主架构设置 bpf_target_arch,所以同一份 BPF 字节码在四个架构都正确(eBPF 只编一份 BPF target,无法用 cfg(target_arch) 区分宿主内核架构,这是唯一干净的做法);
  • loader 符号解析改为同时匹配 syscallsysno,唯一定位 mangled 名 …7syscall5sysno…handle_syscall 不含 sysnoUserContext::sysno 不含 syscall,不会误匹配)。

您 riscv64 的日志「drove 500」其实说明 kprobe 在 riscv64 上已经触发,只是值读错;这次正是修这个读取路径。

2. eBPF crate 的 clippy needless_borrows_for_generic_args

HashMap::get/insert/removePerfEventArray::output 的形参是 impl Borrow<…>(按值),对 Copy 值多余加了 &。已对 6 个 *-ebpf 直接去掉多余借用(get(k) / insert(k, v, 0) / output(&ctx, ev, 0)),未用 allow

本地验证

  • cargo fmt --check:6 个 demo + 2 个 loader 全通过;
  • 复跑了您给的 targeted clippy(cargo +nightly clippy -Z build-std=core -p <demo>-ebpf --target bpfel-unknown-none -- -D warnings):6 个 *-ebpfx86_64 与 riscv64 上均 -D warnings 全绿。

还需您帮忙复跑的部分:QEMU runtime 我本地起不来(缺 bpf-linker 无法构建 loader + 容器内嵌套模拟),所以 sysno 符号解析和各架构实际 PASS 需要您/nightly 复跑确认。要特别说明的是:x86_64 原本就 PASS,这次把挂载点从 handle_syscall 改成了 sysno,build/lint 已验证,但 x86_64 + riscv64 的 runtime 还请您再确认一次。麻烦了,谢谢!

@ZR233 ZR233 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

本轮复审结论:APPROVE。前次两个阻塞问题已经修复,我也已将对应 outdated review thread resolve。

主要核对点:

  • syscall_count / profile 已改为 attach 到 starry_kernel::syscall::sysno,并从 ProbeContext::arg(0) 读取 syscall number,避开了原先按 TrapFrame 首字段读取导致的跨架构布局问题。riscv64 和 x86_64 实跑均能看到 getpid 计数和 profile 数据。
  • 6 个 eBPF crate 的 HashMap::get/insertPerfEventArray::output 多余引用已修正,bpfel-unknown-none clippy 不再报 needless_borrows_for_generic_args
  • upb 仍保持 x86_64-only,和当前内核侧 uprobe 支持范围一致;其余 5 个 demo 的多架构 QEMU 配置本轮能覆盖到关键失败架构。

本地验证记录:

  • git diff --check origin/dev...HEAD:通过。
  • cargo fmt --check:通过。
  • bash -n apps/starry/ebpf/*/prebuild.sh:通过。
  • cargo xtask starry app list --kind qemu:发现 ebpf/kretebpf/mytraceebpf/profileebpf/sched_traceebpf/syscall_countebpf/upb
  • [patch.crates-io] 检查:未发现 crates.io patch。
  • eBPF 目标 clippy:syscall_count-ebpfprofile-ebpfkret-ebpfmytrace-ebpfsched_trace-ebpfupb-ebpf 均通过 cargo +nightly clippy -Z build-std=core --target bpfel-unknown-none -- -D warnings
  • loader/common 侧 clippy:6 个 demo 均通过 --target x86_64-unknown-linux-musl -- -D warnings
  • QEMU:syscall_count riscv64/x86_64 均命中 SYSCALL_COUNT_PASSprofile riscv64/x86_64 均命中 PROFILE_PASSkret x86_64 命中 KRET_PASSmytrace x86_64 命中 MYTRACE_PASSsched_trace x86_64 命中 SCHED_TRACE_PASSupb x86_64 命中 UPROBE_PASS

CI 状态按 head b9681d9ed82cd147f3bbf7a92f6c0ca6bb275c40 查询:SUCCESS=23SKIPPED=25IN_PROGRESS=1FAILURE=0。format、sync-lint、clippy、std test、Starry x86_64/riscv64/aarch64/loongarch64 QEMU 均为 success;skipped 项是 host/container 互斥矩阵或 publish 类 job。唯一仍在跑的是 Test starry self-hosted board licheerv-nano-sg2002 / run_host,当前卡在 board Run command,GitHub 在 job 完成前还不给日志。该 job 运行的是 cargo xtask starry test board --board licheerv-nano-sg2002,不是本 PR 新增的 apps/starry/ebpf smoke 路径;我不把它作为本 PR 的阻塞项,但合入前仍建议继续观察该自托管板卡 job 的最终结果。

重叠检查:base/dev 已有 eBPF 内核运行时和 normal eBPF syscall 测试,但没有这组 apps/starry/ebpf operator-facing demo;#1140/#1141/#1142 是内核侧 eBPF JIT 后续工作,属于执行路径 partial-overlap,不重复本 PR;#1010 seccomp BPF、#990 syscall/qperf harness、#1062 ptrace/gdb app 经检查也不构成功能重复。

非阻塞建议:PR 描述中 syscall_count/profile 仍有旧的 handle_syscallbpf_probe_read(&UserContext) 表述,建议同步成当前的 syscall::sysno probe 方案,避免后续读者按旧实现理解。

@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 #1132 独立审查

变更概述

apps/starry/ebpf/ 下新增 6 个可运行的 eBPF 用户态 demo 应用:

  • syscall_count:kprobe 计数,挂在 starry_kernel::syscall::sysno,直接读 ctx.arg(0) 获取 syscall 号,跨架构兼容
  • profile:kprobe 直方图,统计每个 syscall 号的调用频次
  • upb:uprobe,自附加到 uprobe_test,使用 UProbeScope::CallingProcess 新 aya API(仅 x86_64)
  • kret:kretprobe,挂在 sys_getpid 返回路径,HashMap 计数
  • mytrace:cooked tracepoint,sys_enter_openat,HashMap 计数
  • sched_trace:raw_tracepoint sched_switch + PerfEventArray 推送 repr(C) 事件

每个 demo 统一三层结构(*-common / *-ebpf / loader),提供 prebuild.sh(musl 静态编译)、qemu-.toml(多架构)、build-.toml 配置。130 文件,+6700/-0,全部为新增文件。#886(eBPF 内核运行时)已合入 dev,当前 diff 仅含 apps/starry/ebpf/ 改动。

代码质量审查

结构一致性

  • 6 个 demo 统一 *-common(共享类型)/ *-ebpf(BPF 程序)/ *(loader)三层结构
  • 每个 demo 有独立 Cargo.lock,workspace 独立
  • Rust 2024 edition,#[unsafe(link_section)] 语法

eBPF 程序逻辑

  • syscall_count/profile:probe starry_kernel::syscall::sysno,arg(0) 即原始 syscall 号,无需 bpf_probe_read 解引用,避免了 per-arch TrapFrame 布局问题
  • kret/mytrace:HashMap 计数器,简洁可靠
  • sched_trace:PerfEventArray + repr(C) 事件,loader 逐条拆包
  • upbUProbeScope::CallingProcess + 页面预热 + current_exe() 路径解析

Loader 代码

  • 全部自包含:无 tokio / aya_log 依赖
  • 确定性 workload + 反回退断言:每个 demo 打印 <DEMO>_PASS / <DEMO>_FAIL
  • #[inline(never)] + #[unsafe(no_mangle)] 确保探针符号可被 aya 解析
  • let-chain 和 .flatten() 修复了前次 clippy 的 collapsible_if/manual_flatten
  • HashMap::get/insert 传值已修正 needless_borrows_for_generic_args

本地验证

检查项 结果
cargo fmt --check ✅ 通过
[patch.crates-io] 检查 ✅ 无 patch
文件路径范围(git diff dev...HEAD ✅ 全部在 apps/starry/ebpf/
bash -n apps/starry/ebpf/*/prebuild.sh ✅ 通过
success_regex/fail_regex 与代码输出匹配 ✅ 一致

CI 状态

当前 HEAD b9681d9ed82cd147f3bbf7a92f6c0ca6bb275c40 的 GitHub Actions:

  • SUCCESS=23(format、clippy、sync-lint、std test、Starry x86_64/riscv64/aarch64/loongarch64 QEMU、arceos QEMU 等)
  • SKIPPED=25(host/container 互斥矩阵、publish 类 job)
  • FAILURE=0
  • CI 的 apps/ path filter 不触发额外测试矩阵,属既有配置行为,非本 PR 引入

运行时验证

ZR233 已在本地独立确认:

  • x86_64:全部 6 个 demo 均 PASS(syscall_count getpid=500、upb hit=134、kret hit=500、sched_trace 8470 records、profile total=4256、mytrace openat=200)
  • riscv64:syscall_count 和 profile 均 PASS(验证了 sysno probe 方案跨架构正确性)
  • eBPF 目标 clippy(bpfel-unknown-none):6 个 *-ebpf 均通过
  • loader/common 侧 clippy(x86_64-unknown-linux-musl):6 个 demo 均通过

重复/重叠分析

  • #886:partial-overlap 关系。#886 提供内核 eBPF 运行时(已合并),本 PR 提供用户态 demo
  • #1140/#1141/#1142:eBPF JIT 内核侧后续工作,不重复本 PR
  • #1010:seccomp BPF,功能不同
  • #990:syscall/qperf harness,不构成功能重复
  • #1062:ptrace/gdb app,不重叠
  • base/dev 的 apps/starry/ebpf/ 下无已有同名实现

前次审查问题处理情况

问题 状态 说明
upb2 demo 不一致 ✅ 已修复 commit 94a6c83ac 直接移除
CI 全部 skipped / clippy 失败 ✅ 已修复 CI 全部通过,clippy 修复
多架构 syscall 号读取错误(ZR233) ✅ 已修复 改为 probe syscall::sysno,跨架构正确
eBPF crate clippy needless_borrows_for_generic_args(ZR233) ✅ 已修复 HashMap/PerfEventArray 多余引用已去掉
6 处 host clippy collapsible_if/manual_flatten(ZR233) ✅ 已修复 let-chain + .flatten()
Godones: 需补充其它架构配置 ✅ 已修复 5 个 demo 均有 x86_64/aarch64/riscv64/loongarch64 配置

非阻塞建议

  1. PR 描述中 syscall_count/profile 的说明仍有旧的 handle_syscallbpf_probe_read(&UserContext) 表述,建议同步更新为当前的 syscall::sysno probe 方案
  2. aarch64/loongarch64 的 QEMU runtime 暂未有人实际验证,依赖 nightly Starry Apps 矩阵覆盖;若某架构跑不通应移除其配置
  3. CI path filter 不含 apps/ 目录,未来这些 demo 的回归不会被 CI 覆盖;可考虑在 CI 中新增 apps/ 相关路径或添加 targeted clippy job

结论

6 个 eBPF demo 用户态代码质量达标、结构一致、无阻塞问题。所有前次审查问题均已修复。ZR233 已在相同 HEAD 上给出 APPROVE 并完成了 x86_64 + riscv64 的 QEMU 运行时验证。给予 APPROVE。

Powered by mimo-v2.5-pro

@LorenzLorentz

Copy link
Copy Markdown
Contributor Author

@ZR233 老师好, 我注意到目前您和 Bot @mai-team-app 都已经 approve 这个pr, 能不能麻烦您把这个pr merge 一下.

@ZR233
ZR233 merged commit cba9308 into rcore-os:dev Jun 6, 2026
49 checks passed
silicalet added a commit to silicalet/tgoskits that referenced this pull request Jun 6, 2026
- mount.rs: keep Arc children model with clone_tree/clone_children_from/clone_shallow
- dir.rs: adopt upstream generation-based cache + mountpoint rename transfer
- inode.rs: merge upstream (name, is_dir) signature with pending-delete + truncate_inode

Upstream changes absorbed:
- fix(axfs-ng): zero partial last page when truncating (rcore-os#1124)
- fix(locking): narrow spinlock scope in VFS and Starry paths (rcore-os#1146)
- chore(axbuild): pin ostool runtime bin fix (rcore-os#1158)
- feat(starry-apps): runnable eBPF demos (rcore-os#1132)
- feat(starry): wire qperf app runtime into Starry perf (rcore-os#1095)
- fix(axcpu-aarch64): emulate EL0 MRS reads of ID_AA64* (rcore-os#1128)
- feat(rsext4): fine-grained locking for SMP (rcore-os#1057)
- feat(starry-kernel): implement TCP_INFO sockopt (rcore-os#1044)
- test(starryos): add fork parent-child identity test (rcore-os#995)
- fix(starry-mm): mprotect returns ENOMEM on unmapped holes (rcore-os#918)

Tests verified:
- test-nix-prereqs: PASS
- nix-smoke: PASS
- syscall (upstream): PASS
- test-dup2 (upstream): PASS
aptacc2421 pushed a commit to aptacc2421/tgoskits that referenced this pull request Jun 14, 2026
…/kprobe/kretprobe/tracepoint) (rcore-os#1132)

* feat(starry-apps): relocate eBPF userspace programs to apps/starry/ebpf

Move the aya eBPF userspace programs out of os/StarryOS/user/ebpf into
apps/starry/ebpf so they sit alongside the other operator-facing Starry app
cases (per review on rcore-os#886), instead of the test-suit / user-ebpf xtask path.
Per-case wiring (prebuild.sh / init.sh / qemu+build toml) lands in follow-up
commits.

- Dedup: drop `rawtp` (its raw-tracepoint path is covered by `sched_trace`)
  and `async_test` (a tokio breakpoint smoke, not an eBPF program).
- Rename `syscall_ebpf` -> `syscall_count` (the three crates, the eBPF program
  function, and the loader's `program_mut` lookup) to match the demo name.

Kept: syscall_count, profile, sched_trace, kret, mytrace, upb, upb2.

* fix(starry-apps): update upb loader to aya UProbe::attach(UProbeScope) API

The vendored aya git HEAD changed UProbe::attach from
(point, target, Some(pid), cookie) to (point, target, scope: UProbeScope).
Use UProbeScope::CallingProcess (== attach to this process, the old
Some(std::process::id())). Lets the upb uprobe demo build against current aya.

* feat(starry-apps): self-contained eBPF demos with per-app QEMU run harness

Turn each apps/starry/ebpf demo into a directly runnable StarryOS app
(`cargo xtask starry app qemu -t ebpf/<demo>`): a prebuild.sh builds the
aya loader + embedded bytecode as a static musl binary into the rootfs
overlay, and qemu-x86_64.toml drives it and asserts on a printed PASS
token. Each loader is rewritten to be self-contained (no tokio / aya_log):
it attaches, drives a deterministic workload, reads results back from a
BPF map, and prints <DEMO>_PASS / _FAIL.

- syscall_count: deref arg0 (&UserContext) with bpf_probe_read to read the
  real syscall number (it was counting the pointer value, hence the bogus
  huge keys), attach to handle_syscall, assert getpid count.
- upb: count uprobe hits in a HashMap the loader reads back (aya_log's
  perf-ringbuf does not surface on StarryOS); pass current_exe() as the
  uprobe target and warm up the page before attach.
- kret/mytrace: drop aya_log, count kretprobe / sys_enter_openat tracepoint
  hits via a HashMap and assert.
- profile/sched_trace: self-contained workload + assertion.

Verified end-to-end in x86_64 QEMU: all six demos PASS.

* chore(starry-apps): remove leftover upb2 eBPF demo (duplicate of upb)

upb2 是 uprobe demo 清理前的遗留副本:仍依赖 tokio/aya_log、使用旧的
4 参数 program.attach API,且缺少 prebuild.sh / qemu-x86_64.toml /
build-x86_64-unknown-none.toml,无法通过 cargo xtask starry app qemu 运行,
与 PR “所有 loader 改写为自包含” 的描述矛盾。功能已由自包含的 upb 完全覆盖,
直接删除。

* fix(starry-apps): clear clippy collapsible_if/manual_flatten in ebpf loaders

Address ZR233 review on rcore-os#1132: the nested-workspace clippy run flagged
collapsible_if and manual_flatten in the syscall_count/profile/upb/kret
loaders. Collapse the kallsyms `if let " + "if name.contains` guards into
edition-2024 let-chains and replace the `for x { if let Ok(..) }` map-iter
patterns with `.flatten()`. No behavior change.

* feat(starry-apps): add aarch64/riscv64/loongarch64 run configs for ebpf demos

Address Godones review on rcore-os#1132: extend the kprobe/tracepoint demos
(syscall_count, profile, kret, mytrace, sched_trace) to the other three
QEMU arches so `starry app qemu --all --arch <arch>` exercises them in the
nightly Starry Apps matrix. Each gains qemu-<arch>.toml + the matching
build-<triple>.toml, mirroring the proven per-arch platform/driver setup
(aarch64/riscv64 dynamic, loongarch64 static).

upb (uprobe) stays x86_64-only: the kernel uprobe out-of-line single-step
completion (debug_uprobe_handler) is #[cfg(target_arch = "x86_64")], so the
demo cannot run on the other arches yet.

* fix(starry-apps): probe syscall::sysno for arch-independent syscall number + fix ebpf clippy borrows

解决 ZR233 review 的两个阻塞点:

1) 多架构 syscall 号读取错误:syscall_count / profile 原先 deref
   handle_syscall 的 arg0(&UserContext)取首个 u64 当 syscall 号,仅
   x86_64(rax 为 TrapFrame 首字段)成立,riscv64(a7)/aarch64(x8)/
   loongarch64 都会读错(riscv64 实测 getpid count=0 → FAIL)。改为把
   kprobe 挂到内核 rcore-os#886 预留的 #[inline(never)] syscall::sysno(id: usize),
   直接读 ctx.arg(0):无 deref、无 per-arch 偏移;aya 的 arg(0) 映射到各
   架构第一个参数寄存器,单份 BPF 字节码在四个架构都正确。loader 符号解析
   改为 contains("syscall") && contains("sysno") 唯一定位该符号。

2) clippy needless_borrows_for_generic_args:6 个 *-ebpf crate 的
   HashMap::get/insert 与 PerfEventArray::output 形参是 impl Borrow<…>,
   对 Copy 值多余加 &。去掉 & 直接按值传,不使用 allow。

验证:6 个 demo + 2 个 loader cargo fmt --check 通过;6 个 *-ebpf 在
x86_64 与 riscv64 上 targeted clippy -D warnings 全绿。QEMU runtime 因本地
缺 bpf-linker 与嵌套模拟无法自验,交由 nightly / reviewer 复跑。
luodeb pushed a commit that referenced this pull request Jun 30, 2026
…/kprobe/kretprobe/tracepoint) (#1132)

* feat(starry-apps): relocate eBPF userspace programs to apps/starry/ebpf

Move the aya eBPF userspace programs out of os/StarryOS/user/ebpf into
apps/starry/ebpf so they sit alongside the other operator-facing Starry app
cases (per review on #886), instead of the test-suit / user-ebpf xtask path.
Per-case wiring (prebuild.sh / init.sh / qemu+build toml) lands in follow-up
commits.

- Dedup: drop `rawtp` (its raw-tracepoint path is covered by `sched_trace`)
  and `async_test` (a tokio breakpoint smoke, not an eBPF program).
- Rename `syscall_ebpf` -> `syscall_count` (the three crates, the eBPF program
  function, and the loader's `program_mut` lookup) to match the demo name.

Kept: syscall_count, profile, sched_trace, kret, mytrace, upb, upb2.

* fix(starry-apps): update upb loader to aya UProbe::attach(UProbeScope) API

The vendored aya git HEAD changed UProbe::attach from
(point, target, Some(pid), cookie) to (point, target, scope: UProbeScope).
Use UProbeScope::CallingProcess (== attach to this process, the old
Some(std::process::id())). Lets the upb uprobe demo build against current aya.

* feat(starry-apps): self-contained eBPF demos with per-app QEMU run harness

Turn each apps/starry/ebpf demo into a directly runnable StarryOS app
(`cargo xtask starry app qemu -t ebpf/<demo>`): a prebuild.sh builds the
aya loader + embedded bytecode as a static musl binary into the rootfs
overlay, and qemu-x86_64.toml drives it and asserts on a printed PASS
token. Each loader is rewritten to be self-contained (no tokio / aya_log):
it attaches, drives a deterministic workload, reads results back from a
BPF map, and prints <DEMO>_PASS / _FAIL.

- syscall_count: deref arg0 (&UserContext) with bpf_probe_read to read the
  real syscall number (it was counting the pointer value, hence the bogus
  huge keys), attach to handle_syscall, assert getpid count.
- upb: count uprobe hits in a HashMap the loader reads back (aya_log's
  perf-ringbuf does not surface on StarryOS); pass current_exe() as the
  uprobe target and warm up the page before attach.
- kret/mytrace: drop aya_log, count kretprobe / sys_enter_openat tracepoint
  hits via a HashMap and assert.
- profile/sched_trace: self-contained workload + assertion.

Verified end-to-end in x86_64 QEMU: all six demos PASS.

* chore(starry-apps): remove leftover upb2 eBPF demo (duplicate of upb)

upb2 是 uprobe demo 清理前的遗留副本:仍依赖 tokio/aya_log、使用旧的
4 参数 program.attach API,且缺少 prebuild.sh / qemu-x86_64.toml /
build-x86_64-unknown-none.toml,无法通过 cargo xtask starry app qemu 运行,
与 PR “所有 loader 改写为自包含” 的描述矛盾。功能已由自包含的 upb 完全覆盖,
直接删除。

* fix(starry-apps): clear clippy collapsible_if/manual_flatten in ebpf loaders

Address ZR233 review on #1132: the nested-workspace clippy run flagged
collapsible_if and manual_flatten in the syscall_count/profile/upb/kret
loaders. Collapse the kallsyms `if let " + "if name.contains` guards into
edition-2024 let-chains and replace the `for x { if let Ok(..) }` map-iter
patterns with `.flatten()`. No behavior change.

* feat(starry-apps): add aarch64/riscv64/loongarch64 run configs for ebpf demos

Address Godones review on #1132: extend the kprobe/tracepoint demos
(syscall_count, profile, kret, mytrace, sched_trace) to the other three
QEMU arches so `starry app qemu --all --arch <arch>` exercises them in the
nightly Starry Apps matrix. Each gains qemu-<arch>.toml + the matching
build-<triple>.toml, mirroring the proven per-arch platform/driver setup
(aarch64/riscv64 dynamic, loongarch64 static).

upb (uprobe) stays x86_64-only: the kernel uprobe out-of-line single-step
completion (debug_uprobe_handler) is #[cfg(target_arch = "x86_64")], so the
demo cannot run on the other arches yet.

* fix(starry-apps): probe syscall::sysno for arch-independent syscall number + fix ebpf clippy borrows

解决 ZR233 review 的两个阻塞点:

1) 多架构 syscall 号读取错误:syscall_count / profile 原先 deref
   handle_syscall 的 arg0(&UserContext)取首个 u64 当 syscall 号,仅
   x86_64(rax 为 TrapFrame 首字段)成立,riscv64(a7)/aarch64(x8)/
   loongarch64 都会读错(riscv64 实测 getpid count=0 → FAIL)。改为把
   kprobe 挂到内核 #886 预留的 #[inline(never)] syscall::sysno(id: usize),
   直接读 ctx.arg(0):无 deref、无 per-arch 偏移;aya 的 arg(0) 映射到各
   架构第一个参数寄存器,单份 BPF 字节码在四个架构都正确。loader 符号解析
   改为 contains("syscall") && contains("sysno") 唯一定位该符号。

2) clippy needless_borrows_for_generic_args:6 个 *-ebpf crate 的
   HashMap::get/insert 与 PerfEventArray::output 形参是 impl Borrow<…>,
   对 Copy 值多余加 &。去掉 & 直接按值传,不使用 allow。

验证:6 个 demo + 2 个 loader cargo fmt --check 通过;6 个 *-ebpf 在
x86_64 与 riscv64 上 targeted clippy -D warnings 全绿。QEMU runtime 因本地
缺 bpf-linker 与嵌套模拟无法自验,交由 nightly / reviewer 复跑。
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.

3 participants