Skip to content

feat(rockchip-rga): add the RK3588 RGA2 2D accelerator driver with /dev/rga and dma-heap#1388

Merged
ZR233 merged 98 commits into
rcore-os:devfrom
oscomp-posad:feat/rk3588-rga-driver
Jul 21, 2026
Merged

feat(rockchip-rga): add the RK3588 RGA2 2D accelerator driver with /dev/rga and dma-heap#1388
ZR233 merged 98 commits into
rcore-os:devfrom
oscomp-posad:feat/rk3588-rga-driver

Conversation

@JosephJoshua

Copy link
Copy Markdown
Contributor

背景

StarryOS 在 RK3588 平台上尚无 RGA(Raster Graphic Acceleration,2D 图形加速器)驱动。RKNN、UVC 等数据通路所需的色彩空间转换(CSC)、缩放、letterbox 等 2D 操作只能由 CPU 完成,开销显著(基准测试中 CPU 解码约 5.7 ms,而 RGA 硬件路径约为 1 ms 量级)。仓库中既有的 rockchip-rga crate 仅为一个不下发命令、无法实际执行的 dry-run 编码器;/dev/rga 尚未提供,/dev/dma_heap 亦为桩实现。

本 PR 在真实 RK3588 硬件上完成 RGA2 的完整 bring-up,并通过 /dev/rga(兼容厂商 librga)向用户态开放。

改动

驱动核心(drivers/gpu/rockchip-rga#![no_std],与 OS 解耦)

  • RGA2 MMIO 后端:MMU-off 直接物理寻址、命令下发、轮询(polling)完成、超时复位;
  • 操作模型:Copy / Fill / Blit(裁剪、1/16–16× 缩放、定位、CSC);
  • 像素格式:RGBA8888 / RGBX8888 / RGB888 / BGR888 / RGB565、NV12 / NV21 / NV16、packed YUYV / UYVY;
  • RGA3 后端骨架(标记为 Unsupported,依赖 IOMMU,留待后续实现)。

平台接入(ax-driver / rockchip-soc / rdrive

  • FDT 探测、RGA2 时钟门控(clock gate)、软复位(soft reset)释放、电源域上电;
  • 设备树(DTB)暴露三个 RGA core,rdrive 对每个 core 分别注册;提交时选取实际承载 RGA2 core 的设备。

StarryOS 用户态接口

  • /dev/rga:实现 RGA_BLIT_SYNCRGA_IOC_IMPORT_BUFFER / RELEASE_BUFFER 句柄接口、版本查询与 RGA_IOC_REQUEST_SUBMIT;解析 librga 的 rga_req;句柄按 task 隔离,并在 fd 关闭时回收对应 task 的句柄与请求;
  • /dev/dma_heap/{system,cma}:物理连续 DMA 缓冲分配器,导出 dma-buf fd,支持 mmap 锚定与 cache 同步。

librga 互操作

此为在真实硬件上跑通的关键改动:

  • RGA_IOC_GET_HW_VERSION 上报 RK3588 RGA2 的分类键 (major, minor, revision) = (3, 2, 0x63318);librga 的 rga_get_info() 据此将其识别为 RGA_2_ENHANCE,从而放行 YUYV_422 输入与 CSC 能力;
  • parse() 仅在存在实际旋转(rotate_mode != 0)时拒绝请求。librga 对非旋转 blit 会以单位矩阵填充旋转参数(sina = 0cosa = 0x10000,即 16.16 定点表示的 cos 0°),此前以 cosa != 0 判定旋转会拒绝掉每一个 librga blit。

安全与健壮性

  • RGA_PHYSICAL_ADDRESS 方式导入缓冲需要 CAP_SYS_RAWIO:裸物理地址会使 MMU-off 的 RGA DMA 引擎访问任意物理内存(内核或其他进程),非特权进程应改用 dma-buf fd 导入(其物理范围由内核掌握);
  • 拒绝 RGA2 无法正确实现、若静默忽略将产生错误像素的 librga 特性(color-key、palette、Porter-Duff alpha 混合)。

验证

  • 主机单元测试 59 项:寄存器编码 golden 向量 20 项、librga ABI 结构布局与字段偏移断言 16 项、操作语义校验 13 项等;rockchip-rga 已纳入 std-test 白名单,随 CI 执行;
  • QEMU ABI 测试(test-suit/starryos/qemu-smp1/system/rga-abi):覆盖版本查询、句柄导入/释放、BLIT_SYNC,以及无设备时的优雅降级(返回 ENODEV 而非 EBADF,证明句柄解析与 parse 先于设备判定执行);
  • OrangePi-5-Plus 板级 selftest(test-suit/starryos/board-orangepi-5-plus/rga-selftest):fill / copy / resize / YUYV→RGB CSC 像素正确,采用 CRC 与 poison 哨兵分类,并在超时时 dump 引擎寄存器用于诊断;
  • cargo fmtsync-lint 均通过。

范围与限制

  • 本 PR 仅覆盖 RGA2;RGA3、IOMMU、旋转/镜像、alpha 混合 / ROP、多 core 调度、IRQ / fence 完成等均为后续工作,代码中已明确拒绝或注明;
  • RGA2 完成中断在该板上不会触发(已确认的 FDT→GIC 路由缺口,dwmmc 完成中断同样不触发),故采用轮询方式等待完成。

@JosephJoshua
JosephJoshua marked this pull request as draft June 26, 2026 06:45
@JosephJoshua
JosephJoshua force-pushed the feat/rk3588-rga-driver branch from 2ff62b8 to 5fe885e Compare June 26, 2026 06:52
@JosephJoshua
JosephJoshua marked this pull request as ready for review June 26, 2026 06:54
@JosephJoshua
JosephJoshua marked this pull request as draft June 26, 2026 07:27
@JosephJoshua
JosephJoshua marked this pull request as ready for review June 26, 2026 08: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.

PR Review Summary

改动内容

本 PR 将仓库中仅有的 rockchip-rga dry-run 编码器升级为完整的 RK3588 RGA2 2D 加速器驱动,涵盖 95 个文件、约 +5536/-2716 行。核心改动:

  1. 驱动核心 (drivers/gpu/rockchip-rga):重写为 OS 解耦的 #![no_std] crate,包含 RGA2 MMIO 后端(命令编码、轮询完成、超时复位)、Copy/Fill/Blit 操作模型、13 种像素格式、RGA3 骨架。
  2. 平台接入 (ax-driver/rga.rs, rockchip-soc):FDT 探测、时钟门控(hclk/aclk/clk)、CRU 软复位释放、电源域上电。正确跳过未验证的 RGA3 core,避免访问未时钟域的 MMIO 导致同步异常。
  3. 用户态接口/dev/rga 实现 librga MultiRGA v1.3.1 全套 ioctl(BLIT_SYNC、IMPORT/RELEASE_BUFFER、REQUEST_CREATE/CONFIG/SUBMIT/CANCEL、版本查询),句柄按 task 隔离并在 fd 关闭时回收;/dev/dma_heap/{system,cma} 提供真实物理连续 DMA 分配器,支持 mmap 锚定与 cache 同步。
  4. librga 互操作rga_req 结构布局经编译期 offset_of! + size_of 断言(504 字节)与 LP64 C probe 交叉验证;GET_HW_VERSION 上报 (3,2,0x63318) 让 librga 识别为 RGA_2_ENHANCE;旋转检测修正为 rotate_mode != 0(此前 cosa != 0 拒绝了所有 librga blit)。

实现逻辑评价

驱动架构清晰:

  • backend::RgaBackend trait 分离硬件代际,RGA2 后端实现完整的 MMU-off 命令编码,RGA3 标记为 Unsupported(IOMMU 依赖,合理延迟)。
  • 命令编码 (command.rs) 有详尽的注释,说明每个寄存器位域与 vendor 参考实现的对应关系,包括 SRC1 fill format 追踪 dst 格式、PAT_CON/FADING_CTRL 与 vendor 一致的无条件写入。
  • DMA coherency 正确处理:分配为 cached,提交前 sync_for_device(clean),完成后 sync_for_cpu(invalidate),避免 stale cache line 抢写引擎输出。
  • 安全性:RGA_PHYSICAL_ADDRESS 导入需 CAP_SYS_RAWIO;拒绝 color-key/palette/Porter-Duff 等 RGA2 无法正确实现的特性(静默忽略会产出错误像素)。

测试覆盖

  • 主机单元测试 59 项全部通过(本地 cargo test -p rockchip-rga 验证):寄存器编码 golden 向量 20 项、librga ABI 结构布局与字段偏移 16 项、操作语义校验 13 项、CRC-32 / 格式映射 / 解析路径测试 10 项。
  • QEMU ABI 测试 (test-suit/starryos/qemu-smp1/system/rga-abi):C grouped system test,覆盖版本查询、句柄导入/释放、BLIT_SYNC 返回 ENODEV(证明解析链完整运行后才到达设备检查),通过 CI Test starry aarch64 qemu / run_container SUCCESS。
  • QEMU dma-heap 测试 (test-suit/starryos/qemu-smp1/system/dma-heap-dmabuf):覆盖 alloc/mmap/sync/lifetime(fd 先于 munmap 关闭后内存仍可读),通过 CI。
  • 板级 selftest (apps/starry/rga-selftest, OrangePi-5-Plus):fill/copy/resize/YUYV→RGB CSC,CRC + poison 哨兵分类,超时时 dump 引擎寄存器。board-orangepi-5-plus 配置正确,success_regex 匹配终态 sentinel,fail_regex 仅匹配灾难性故障。
  • rockchip-rga 已纳入 scripts/test/std_crates.csv 白名单,随 CI Test with std 执行。

CI 状态

CI 全部通过(GraphQL statusCheckRollup.state = SUCCESS)。所有 run_host required checks 为 SUCCESS;run_container counterparts 为 SKIPPED(预期的 run_host/run_container 互斥矩阵行为)。本地 cargo fmt --check 无差异。

重复与重叠分析

  • base branch:现有 rockchip-rga 仅为 dry-run 编码器(仅 PixelFormat::Abgr8888、无提交路径、无 librga ABI)。本 PR 替换并扩展,不是重复实现。
  • open PRs:仅 #1390(lockdep RwLock 迁移)为不相关改动,无冲突风险。
  • [patch.crates-io]:所有依赖使用正常 workspace resolution。

测试放置

  • QEMU ABI 测试正确放在 test-suit/starryos/qemu-smp1/system/rga-abi,通过 CMake GLOB 自动发现,install 到 usr/bin/starry-test-suit,qemu-smp1 aarch64 构建配置已包含 starry-kernel/rga feature。
  • dma-heap 测试放在 test-suit/starryos/qemu-smp1/system/dma-heap-dmabuf,同样自动发现。
  • 板级 selftest 在 test-suit/starryos/board-orangepi-5-plus/rga-selftestapps/starry/rga-selftest,分层正确。

无阻塞问题

未发现任何阻塞问题。PR 实现完整、测试充分、CI 通过、无冲突/重复/补丁问题。

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.

本次改动把 rockchip-rga 从 dry-run 编码器扩展为 RK3588 RGA2 后端,并接入 ax-driver、Starry /dev/rgadma_heap。驱动核心本身的 host/std 覆盖和 rockchip-rga 分层方向我没有看到明显阻塞;当前 head 5dd485d37aa6361e2f91ad071311d3dc75b3e1ae 上 CI 也没有失败,cargo fmt --checkcargo xtask clippy --package rockchip-rga 在本地通过。

阻塞点是测试层级:PR 现在把 RGA2 硬件 bring-up 自测做成 starry-kernel/rga-selftest,并在 Starry initproc 前执行。这类测试覆盖的是可复用内核 RGA 驱动、DMA coherency、RK3588 power/clock/reset/platform 接入,不是 StarryOS 的 Linux 兼容行为。后续 RGA 继续增加 rotate/fence/IOMMU/multicore 等测试 feature 时,如果都按这个模式进 Starry kernel feature,会让 Starry 启动路径承载越来越多硬件驱动 bring-up 回归,维护边界会失控。

请把硬件驱动自测迁到 ArceOS app / test-suit/arceos 方向来做,参考现有 test-suit/arceos/{rust,c} 的 build/qemu 配置和 cargo xtask arceos test qemu 运行方式;或者提交一个真正的 RGA 用户态/librga 测试程序,放入 Starry 文件系统后通过 /dev/rga/dev/dma_heap 验证用户态 ABI。Starry 侧保留 /dev/rga 的 ABI/QEMU no-device 测试是合理的,但不应通过 Starry 内核启动钩子来测试内核 RGA 驱动本体。

重复/重叠方面:当前 base 已有 rockchip-rga crate 和 Starry RGA app 依赖背景,但没有等价 RGA2 驱动实现;open PR 搜索中也没有同类 RGA 驱动 PR。这个 review 因测试位置和验证入口设计请求修改。

Comment thread os/StarryOS/kernel/src/entry.rs Outdated
@ZR233
ZR233 requested review from ZCShou and elliott10 June 29, 2026 01:09

@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 Review — #1388 RGA2 驱动

改动内容

rockchip-rga 从 dry-run 编码器升级为完整的 RK3588 RGA2 2D 加速器驱动(+5257/-584 行,45 文件),涵盖:

  • 驱动核心:#![no_std]、OS 解耦,RGA2 MMIO 后端(命令编码、轮询完成、超时复位),Copy/Fill/Blit 操作,13 种像素格式,RGA3 骨架;
  • 平台接入:FDT 探测、时钟门控(hclk/aclk/clk)、CRU 软复位释放、电源域上电,RGA3 正确跳过;
  • 用户态接口:/dev/rga(librga MultiRGA v1.3.1 ioctl)、/dev/dma_heap/{system,cma}(物理连续 DMA 分配 + mmap + cache sync);
  • librga 互操作:rga_req 504 字节编译期断言、版本查询 (3,2,0x63318) 识别为 RGA_2_ENHANCE、旋转检测修正为 rotate_mode != 0
  • 安全性:RGA_PHYSICAL_ADDRESS 导入需 CAP_SYS_RAWIO;拒绝 color-key/palette/Porter-Duff 等 RGA2 无法正确实现的特性。

实现逻辑

架构设计清晰:backend::RgaBackend trait 分离硬件代际,RGA2 后端实现完整的 MMU-off 命令编码。命令编码有详尽的寄存器位域注释与 vendor 参考实现的对应关系。DMA coherency 正确处理(submit 前 sync_for_device clean,完成后 sync_for_cpu invalidate)。安全边界合理,解析链完整(resolve_buf → parse → validate → submit → poll)。

CI 状态

CI 全部通过(所有 run_host 必需检查为 SUCCESS,run_container 互斥对应为 SKIPPED,均为预期行为)。本地验证:cargo fmt --check 通过,cargo clippy -p rockchip-rga --all-features -- -D warnings 无警告,cargo test -p rockchip-rga 59 项测试全部通过。

先前 Review 处理

ZR233 在 commit 5dd485d37 上提出 CHANGES_REQUESTED,要求将 RGA2 硬件自测从 Starry 内核启动钩子迁出。作者在最新 commit b985b3032 中已响应:

  • 移除 entry.rsrga-selftest feature 和 rga_selftest::run() 钩子;
  • 硬件验证改为用户态 test-suit/starryos/qemu-smp1/system/rga-blit-hw,QEMU 无设备时返回 ENODEV/SKIP;
  • 保留 /dev/rga + /dev/dma_heap 的 QEMU ABI 测试(rga-abidma-heap-dmabuf)。

测试层级问题已解决,Starry 内核启动路径不再承载任何 RGA 驱动 bring-up。

重复与重叠

  • base branch:现有 rockchip-rga 仅为 dry-run 编码器,本 PR 替换并扩展,不是重复实现。
  • open PRs#1430(x86 IRQ 重构)、#1431(block IRQ 拆分)均不相关,无冲突风险。
  • [patch.crates-io]:所有依赖使用正常 workspace resolution。

结论

无阻塞问题。驱动实现完整,测试覆盖充分,CI 通过,先前 review 意见已解决。

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.

复审当前 head b985b303227981ed8ee0f86bce46409f2088ed9a,仍需修改。

这版已经把前一轮指出的 Starry 内核启动钩子移除了,这是正确方向;但测试边界还没有收敛。当前 diff 仍新增了:

  • test-suit/starryos/qemu-smp1/system/rga-abi/
  • test-suit/starryos/qemu-smp1/system/rga-blit-hw/
  • test-suit/starryos/qemu-smp1/system/dma-heap-dmabuf/
  • test-suit/starryos/board-orangepi-5-plus/rga-blit-hw/

这些仍然把 RGA / DMA heap 的硬件驱动 bring-up 和 ABI 覆盖放进 Starry test-suit。rga-blit-hw 尤其是在验证 RK3588 RGA2 驱动、DMA coherency、clock/reset/platform 接入,这不是 StarryOS Linux 兼容层本身的回归;后续如果继续增加 rotate/fence/IOMMU/multicore 等 feature,放在 Starry test-suit 会继续扩大 Starry 测试入口的职责。

请不要把这组 RGA 驱动测试继续放在 test-suit/starryos。建议改成以下二选一:

  1. 做成 ArceOS app / ArceOS 测试入口,按 test-suit/arceos 现有方式验证可复用内核驱动和 RK3588 平台接入;
  2. 提供真正的 RGA 用户态测试程序,通过 rootfs 放入 Starry 后只验证 /dev/rga/dev/dma_heap 的用户态 ABI,而不是把驱动 bring-up 作为 Starry test-suit case 维护。

当前 CI 里还有 Run clippy / run_host cancelled、Starry loongarch64 qemu failure,以及部分 Starry/self-hosted board cancelled;这些不作为本轮主要结论。主要阻塞仍是测试放置位置和验证入口设计。

@JosephJoshua

Copy link
Copy Markdown
Contributor Author

收到,已按这一轮的测试边界调整(最新 commit da66ca2)。

把 RGA 驱动硬件 bring-up 用例从 Starry test-suit 移除:

  • 删除 test-suit/starryos/qemu-smp1/system/rga-blit-hw
  • 删除 test-suit/starryos/board-orangepi-5-plus/rga-blit-hw

这两个用例做的是真实 RGA2 blit + 像素回读校验(驱动命令编码 / DMA coherency / clock-reset-platform 接入),确实属于可复用内核驱动的硬件回归,不应作为 Starry test-suit case 维护。

Starry 侧只保留纯用户态 ABI 覆盖——即上一轮 review 认可的「/dev/rga / dma_heap 的 ABI 覆盖」,不含任何硬件 blit:

  • rga-abi:/dev/rga 版本查询、句柄 import/release、无设备 ENODEV(证明 resolve+parse 链在设备检查前已完整运行);
  • dma-heap-dmabuf:/dev/dma_heap alloc / mmap / lifetime / sync。

RGA2 驱动核心的正确性仍由 rockchip-rga 的 host 单测覆盖(寄存器编码 golden 向量、librga ABI 布局断言、解析路径,共 60 项)。Starry 启动路径与 test-suit 都不再承载 RGA 驱动 bring-up。

若后续需要保留真实硬件回归,会单独走 ArceOS app / test-suit/arceos 方向(需补 ArceOS 板级测试入口),不在本 PR 内扩大 Starry test-suit 职责。

另:本次 push 一并带上两个与本轮 review 无关的驱动修复——dma-buf fd 上报 O_RDWR(使 librockchip_mpp 的 dma-heap allocator 以读写映射,避免首次写解码帧段错误)、单 fd NV12 半平面源的 chroma 基址推导(uv = yrgb + stride*height,附新增单测),均已过 host 单测。

@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 Review — #1388 RK3588 RGA2 驱动(round 3 复审)

改动概览

rockchip-rga 从 dry-run 编码器升级为完整的 RK3588 RGA2 2D 加速器驱动,涉及 40 个文件、+4919/-584 行、82 个 commit。涵盖:

  • 驱动核心drivers/gpu/rockchip-rga):#![no_std] OS 解耦 crate,RGA2 MMIO 后端(命令编码、轮询完成、超时复位),Copy/Fill/Blit 操作模型,13 种像素格式,RGA3 骨架;
  • 平台接入ax-driver/rga.rsrockchip-soc):FDT 探测、时钟门控(hclk/aclk/clk)、CRU 软复位释放、电源域上电,RGA3 正确跳过;
  • 用户态接口/dev/rga(librga MultiRGA v1.3.1 ioctl 全套),/dev/dma_heap/{system,cma}(物理连续 DMA 分配 + mmap + cache sync);
  • librga 互操作rga_req 504 字节编译期断言、版本查询 (3,2,0x63318)RGA_2_ENHANCE、旋转检测修正为 rotate_mode != 0
  • 安全性RGA_PHYSICAL_ADDRESS 导入需 CAP_SYS_RAWIO,拒绝 color-key/palette/Porter-Duff。

实现质量

代码架构清晰,分层合理:

  • backend::RgaBackend trait 分离硬件代际,RGA2 完整实现 MMU-off 命令编码,RGA3 标记 Unsupported(合理延迟);
  • 命令编码注释详尽,每个寄存器位域均标注 vendor 参考实现的对应关系;
  • DMA coherency 正确:submit 前 sync_for_device clean,完成后 sync_for_cpu invalidate;
  • 安全边界合理:解析链完整(resolve_buf → parse → validate → submit → poll),handle 按 task 隔离并在 fd 关闭时回收。

ZR233 review 反馈处理

  1. Round 1(commit 5dd485d37a):要求移除 Starry 内核启动钩子 → 作者在 b985b30322 响应,迁为用户态测试;
  2. Round 2(commit b985b30322):仍要求移除 rga-blit-hw 硬件 bring-up 测试 → 作者在最新 da66ca2d1b 完整响应:
    • 移除 test-suit/starryos/qemu-smp1/system/rga-blit-hw
    • 移除 test-suit/starryos/board-orangepi-5-plus/rga-blit-hw
    • 保留纯用户态 ABI 测试(rga-abi:版本查询/句柄 import/release/无设备 ENODEV;dma-heap-dmabuf:alloc/mmap/lifetime/sync),不含任何硬件 blit

当前 test-suit/starryos 下的 RGA 测试已收敛为纯 ABI 覆盖,不涉及驱动 bring-up。ZR233 提出的测试职责边界问题已在最新 commit 中解决。

本地验证

  • cargo fmt --check:通过
  • cargo clippy -p rockchip-rga --all-features -- -D warnings:无警告
  • cargo test -p rockchip-rga60 项全部通过(寄存器编码 golden 向量 20 项、librga ABI 结构布局与字段偏移 16 项、操作语义校验 13 项、CRC-32 / 格式映射 / 解析路径测试 11 项)

CI 状态

Fork CI 最新 run(da66ca2d1b)因 Docker pull 基础设施问题失败(Docker pull failed with exit code 1),非代码问题。rcore-os 上无 check runs 配置。

重复/重叠

  • base branch 现有 rockchip-rga 仅为 dry-run 编码器,本 PR 替换并扩展,非重复;
  • [patch.crates-io]
  • 无相关 open PR 冲突。

结论

驱动实现完整、测试覆盖充分、前三轮 review 意见均已响应解决。建议合入。

Powered by mimo-v2.5-pro

新增一个专用 build wrapper `test-suit/starryos/qemu-rga`(仅 aarch64,启用 `rga`,
从而同时带出 `/dev/dma_heap`),把 `/dev/rga` 的用户态 ABI 生命周期回归放在
`qemu-rga/system/rga-lifecycle`。共享的 `qemu/build-*.toml` 保持不含 `rga`;其他
架构在该 wrapper 下发现不到用例,不受影响。

QEMU virt 无 RGA2 硬件:handle 解析成功后 `RGA_BLIT_SYNC` 会走到设备检查返回
ENODEV,而 handle 查不到则在解析前就返回 EBADF——用 “ENODEV 而非 EBADF” 判定
lookup 是否命中,无需硬件即可验证。两个确定性用例:

- A(同一 fd 跨线程):主线程 import 得到 handle,兄弟线程用同一 fd 对该 handle
  做 blit(应 ENODEV)并 release(应成功),验证按 tgid 归属的 handle 在同进程各
  线程间可见。
- B(两个独立 open):同进程开 fd_a、fd_b 各自 import,关闭 fd_a 后 fd_b 的 handle
  仍应解析成功(ENODEV,而非 EBADF)。修复前 close 会回收整个进程的 handle,此用
  例即返回 EBADF;修复后仅在最后一个 open description 关闭时回收,用例通过。
@ZR233

ZR233 commented Jul 16, 2026

Copy link
Copy Markdown
Member

最新两项修改中,跨线程问题和“关闭一个 fd 误清理另一个 fd”的直接现象已经处理,专用测试配置也避免了影响通用 QEMU 构建。不过还需要继续调整以下两点。

1. 请实现真正的 per-open RGA session。

当前 tgid + open_counts 仍然是进程级状态,不是 open-file-description 语义。它虽然让同进程多个 /dev/rga fd 在关闭其中一个后暂时保留状态,但也会把不同 open() 的 handle/request 合并,并将已关闭 fd 的资源延迟到最后一个 RGA fd 才回收。

此外,fork 会暴露更明确的问题:Starry fork 复制的是同一个 Arc<FileLike>,不会再次调用 RgaDevice::open();子进程 tgid 与父进程不同,因此无法使用父进程通过继承 fd 创建的 handle。如果最后一个引用由子进程关闭,close() 又会按子 tgid 清理,父 tgid 下的 open_counts 和表项可能无法回收。

Orange Pi 6.1 RK35xx 的 RGA3 驱动是在每次 open() 时创建 rga_session 并放入 file->private_data,最后一次 release() 只清理对应 session。建议在 Starry 中采用同样的生命周期:

  • 节点级 RgaDevice 只保留硬件和全局执行状态;
  • 新增 per-open RgaSession,持有 handle/request 表和 ID 分配状态;
  • 新增 RgaFile 包装 KernelFile + RgaSession
  • fd_ops 中参照 USBFS 的 open_usbfs_file() 返回专用 FileLike
  • dup、fork、SCM_RIGHTS 通过共享同一个 Arc<RgaFile> 自然共享 session;
  • 独立 open() 创建独立 session;
  • 删除 current_id()open_counts(pid, id) 键。

这样不需要扩展通用 DeviceOps 接口,也能得到与 Linux file->private_data 一致的生命周期。

2. 不需要增加 RGA QEMU 测试,请删除本轮新增的 test-suit/starryos/qemu-rga

QEMU 没有 RGA 设备,通过 ENODEV/EBADF 间接推断 handle lookup 的意义有限,也不能验证 librga 到真实硬件的完整路径。本 PR 改为提供一个后续可放入真实板卡 rootfs 的 librga smoke 程序即可。

建议新增 apps/starry/rga-librga-smoke/,提交源码、构建脚本和部署文档,不提交构建产物,也暂时不增加 board TOML。程序应:

  • /dev/dma_heap/system 分配并 mmap src/dst;
  • 通过 librga 的 importbuffer_fdwrapbuffer_handle 导入;
  • 执行固定颜色 imfill 并逐像素验证;
  • 执行等尺寸 RGBA imcopy,用 memcmp 和 CRC32 验证;
  • 正确释放 librga handle、mmap 和 dma-buf fd;
  • 任意失败返回非零,不做 SKIP。

成功终态统一为:

RGA_LIBRGA_SMOKE_PASS fill_crc32=<hex> copy_crc32=<hex>

失败统一为:

RGA_LIBRGA_SMOKE_FAIL stage=<stage> status=<status> error=<message>

构建产物应是可整体复制到 rootfs 的 bundle:

rga-librga-smoke/
├── rga-librga-smoke
└── lib/
    └── librga.so

可执行文件使用 $ORIGIN/lib RPATH。提交后会有人把该目录放入 OrangePi 真机 rootfs,分别在 Linux 和 StarryOS 中运行并比较 PASS marker 与 CRC。

同时请顺带按 Orange Pi RGA3 1.3.1 UAPI 对齐当前 ioctl:

  • buffer pool 上限为 40;
  • request task 上限为 50;
  • CONFIG/SUBMIT/CANCEL 必须检查 request ID 已存在;
  • CANCEL 不存在的 ID 不能静默成功;
  • RGA_GET_VERSION 写回完整 16 字节;
  • 保留 EFAULT 写回失败时的 handle/request 回滚;
  • async/fence 未实现时明确返回 unsupported。

本轮无需执行真机测试,提交前完成 smoke 的 aarch64 交叉编译、RPATH/依赖检查,以及现有 fmt、host test 和 Starry clippy 即可。

… RGA3 UAPI

生命周期改为正确的 open-file-description 语义(对齐 Linux RGA 的 file->private_data
与 Starry 现有的 usbfs per-open FileLike):节点 RgaDevice 不再持有任何 per-open 状态;
每次 open("/dev/rga") 在 fd_ops 中改造成一个 per-open RgaFile,内含该 open 的 handle /
request 表与 id 分配。dup/fork/SCM_RIGHTS 共享同一个 Arc<RgaFile> 从而自然共享 session,
独立 open() 得到独立 session;session 在最后一个引用 drop 时释放(RAII,即 release()
语义)。删除了 current_id()、open_counts 与所有 (pid, id) 键。

这修复了 fork 下的生命周期错误:此前 handle 按 tgid 归属,fork 复制同一个
Arc<FileLike> 而不再调用 open(),子进程 tgid 不同即无法解析父进程用继承 fd 导入的
handle,且最后一个引用由子进程关闭时按子 tgid 清理会漏回收父进程的表项。

同时按 RGA3 UAPI 源码对齐 ioctl 行为:
- buffer pool 上限 40(RGA_BUFFER_POOL_SIZE_MAX)、request task 上限 256
  (RGA_TASK_NUM_MAX);
- CONFIG/SUBMIT/CANCEL 均要求 request id 已存在,否则返回 EINVAL;CANCEL 未知 id 不再
  静默成功;SUBMIT 原子地取走请求(并发同 id 只跑一次);
- RGA_GET_VERSION 写回完整 16 字节;SUBMIT 遇 async(sync_mode == RGA_BLIT_ASYNC)
  显式返回 unsupported;
- 保留 EFAULT 写回失败时的 handle/request 回滚;RELEASE 未知 handle 返回 ENOENT。
  (AxError 无 EFBIG,超限统一返回 EINVAL。)
新增回归 C(fork):父进程 import 得到 handle,fork 后子进程用继承的 fd 解析该 handle
应成功(ENODEV,而非查不到的 EBADF),证明子进程与父进程共享同一 per-open session;子
进程退出后父进程的 handle 仍有效,证明 session 仅在最后一个引用关闭时才回收。这正是按
tgid 归属时无法通过的场景。回归 B 的说明也相应更新为「两个独立 open = 两个独立 session」。
@JosephJoshua

Copy link
Copy Markdown
Contributor Author

第七轮的两点已处理(commit d39b67be12a5c142d0,已 push)。

1. 改为真正的 per-open session(不再用 tgid + open_counts)。 参照 Linux RGA 的 file->private_data 与 Starry 现有的 usbfs per-open FileLike:节点 RgaDevice 不再持有任何 per-open 状态;每次 open("/dev/rga")fd_ops 中改造成一个 per-open RgaFile(内含该 open 的 handle/request 表与 id 分配),与 open_usbfs_file 一致;dup/fork/SCM_RIGHTS 共享同一个 Arc<RgaFile> 故自然共享 session,独立 open() 得到独立 session,session 在最后一个引用 drop 时释放(RAII,即 release() 语义)。已删除 current_id()open_counts 与所有 (pid, id) 键。

您指出的 fork 问题据此修复:子进程通过继承 fd 共享父 session、可解析父进程导入的 handle;父/子中最后一个引用关闭时才回收。已补一条 fork 回归覆盖(子进程解析父 handle、子退出后父 handle 仍有效)。

2. ABI 对齐(按 RGA3 UAPI 源码核对)。

  • buffer pool 上限 40(RGA_BUFFER_POOL_SIZE_MAX);
  • request task 上限:源码里是 RGA_TASK_NUM_MAX = 256(不是 50),已按 256 对齐;
  • CONFIG/SUBMIT/CANCEL 均要求 request id 已存在,否则返回错误(对应 -EINVAL);CANCEL 未知 id 不再静默成功;
  • RGA_GET_VERSION 写回完整 16 字节;
  • SUBMIT 遇 async(sync_mode == RGA_BLIT_ASYNC)显式返回 unsupported;
  • 保留 EFAULT 写回失败时的 handle/request 回滚。
  • (注:AxError 无 EFBIG,超限统一返回 EINVAL,取最接近语义。)

3. 关于删除 qemu-rga,想先和您确认能否保留。 这几条确定性用户态 ABI 用例(同一 fd 跨线程 import + submit/release、两个独立 open 关闭其一另一 fd 仍有效、以及本轮新增的 fork)其实正是您上一轮复审(07-15 06:50)建议新增的——您当时明确建议以 system 小型 C subcase、用“handle 解析后返回 ENODEV、不提前返回 EBADF”来验证 lookup;我据此实现,并为不污染共享 qemu 构建而单独放在 qemu-rga wrapper(仅 aarch64、启用 rga)。它们很轻量,且正好在 CI 里守住本轮反复出问题的内核侧 handle/session 生命周期这一层。librga→真实硬件的完整路径确实是另一层,我很乐意按您的规格另外提供 apps/starry/rga-librga-smoke(源码 + 构建脚本 + 部署文档,$ORIGIN/lib RPATH,RGA_LIBRGA_SMOKE_PASS/FAIL marker + CRC)作为后续,在真机上跑 Linux vs StarryOS 对比。这样两层各自覆盖,就不必删掉这套您上轮要求、现已在 CI 守着回归的用例。若您仍坚持移除,我照做。

本地已验证:aarch64 构建、fmt、rockchip-rga host 单测、Starry clippy(21 组合),以及在 QEMU 跑通 qemu-rga/system(含 A/B/C 三条回归,18 项断言全过)。

@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 将现有 rockchip-rga dry-run 骨架扩展为 RK3588 RGA2 MMU-off 驱动,完成 FDT/power/clock/reset 接入,并在 Starry 提供 /dev/rga、dma-heap 与 librga ioctl;新增的 grouped QEMU 用例覆盖 ABI、导入/释放和 fd/open-file-description 生命周期。驱动核心与 OS glue 的分层方向清晰,但当前 dma-buf 导入缺少访问范围约束,暂不能合入。

影响与既有反馈

该功能大部分由 feature/platform 配置隔离,不改变未启用 RGA 的通用路径;启用 /dev/rga 后,导入缓冲、cache sync 和 MMU-off 物理 DMA 属于新的安全边界。此前关于 task/tgid 归属、独立 open 互相影响以及 dup/fork 生命周期的意见是合理的;当前 head 已改成 per-open RgaFile,并增加 sibling thread、独立 open、fork 共享 open-file-description 回归,原问题已解决。写回失败回滚等旧意见也已处理。当前仍有一项新的阻塞安全问题,见 inline 评论。

测试与验证

  • 组织仓库中当前 head 2a5c142d0244bde036048723454c8aa7d7049db9 的 Actions run 29490828041 为成功;格式、clippy、std test、Starry aarch64 QEMU 等相关 run_host/run_container 实际执行项成功,互斥 counterpart 与 publish 项的 skipped 属预期矩阵行为,未发现 PR 导致的 CI 失败。
  • 本地 cargo fmt --check:通过。
  • 本地 cargo test -p rockchip-rga --all-features:60 项通过。
  • 本地 cargo xtask clippy --package rockchip-rgacargo xtask clippy --package starry-kernel:通过。
  • 新测试位于当前 grouped system 结构下并由对应 QEMU 配置选择;current-head CI 已执行 Starry aarch64 QEMU,因此未重复本地运行完整 QEMU。现有测试尚未覆盖“小 dma-buf + 大几何”的拒绝路径,这正是本轮安全缺口。

重复、冲突与规范

origin/dev 仅有此前的 RGA dry-run 骨架,没有真实提交或 /dev/rga 等价实现,本 PR 不是重复实现;未确认到功能重复的开放 PR,也没有 [patch.crates-io]。基于准备好的 origin/dev 进行 merge-tree 检查无冲突。仓库当前 checkout 未提供 book/guideline/starry/syscall.md,所以无法直接按该文档复核 ioctl ABI;本轮按代码质量规范、驱动/DMA 边界及已有 ABI 测试检查。

修复 inline 的 dma-buf 边界校验并补充可在硬件提交前确定失败的负向回归后,可继续复审。

Powered by gpt-5.6-sol

let obj = resolve_contiguous_dmabuf(ext.memory as c_int)
.ok_or(VfsError::BadFileDescriptor)?;
ImportedBuf {
phys_addr: obj.phys_base() as u64,

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.

【阻塞|安全:DMA 越界】这里导入 dma-buf 时只保存了物理基址和生命周期引用,没有保存分配长度;后续 resolve_buf 也只返回基址,而 ImageDesc::validate 仅检查计算出的末地址不超过 4 GiB。用户可以导入一个 4 KiB dma-buf,再提交合法的 4096×4096 RGBA 几何,RGA2 在 MMU-off 模式下就会越过该 dma-buf 读写相邻物理内存,造成越权读取或内存破坏。当前 DmaBufFile 已持有 alloc.size,但 size() 仅在 rknpu feature 下开放,证明该边界信息存在却没有传到 RGA 路径。请让长度在 rga feature 下可用,把它保存在 ImportedBuf 并在提交前校验每个 RGB/Y/UV 平面的完整访问区间(含派生的 semiplanar UV 区间)都落在对应导入对象内;同时增加“小缓冲区 + 大几何必须在触发硬件前失败”的回归。

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

已修复此处的 DMA 越界(commit 42cf45dcb3c2ce4d3f,已 push)。

  • DmaBufFile::size() 现在在 rga feature 下可用;导入时把字节长度存进 ImportedBufRGA_DMA_BUFFER 记 dma-buf 长度;raw RGA_PHYSICAL_ADDRESS 已受 CAP_SYS_RAWIO 限制、由特权调用方担保,记为无界)。
  • 提交前、在 get_list / 触碰硬件之前,对每个平面做边界校验:新增 ImageDesc::plane_extents() 给出各平面从基址起的字节区间(luma/RGB 用 stride*height,semiplanar chroma 用 stride*chroma_rows),逐平面校验其落在对应导入缓冲 [base, base+len) 内;派生的 semiplanar UV(紧随 luma、同一缓冲)与单独导入的 chroma 分别处理。越界返回 EINVAL,不下发硬件。
  • 新增回归 D:导入 4 KiB 缓冲、提交 512×512 RGBA(需 1 MiB)在硬件前以 EINVAL 拒绝;同缓冲的 16×16 仍能到设备检查(ENODEV),证明仅拒绝越界项。另加 plane_extents host 单测。

本地验证:aarch64 构建、fmt、rockchip-rga host 单测 61、Starry clippy(22 检查),以及在 QEMU 跑通 qemu-rga/system(A/B/C/D 全过,23 断言)。

@mai-team-app
mai-team-app Bot requested review from ZCShou and ZR233 July 17, 2026 03:21
@ZR233

ZR233 commented Jul 17, 2026

Copy link
Copy Markdown
Member

可先不加测例,我会在稍后增加 rga smoke 测试,放到板子中

…re RGA submit

RGA2 runs MMU-off, so the engine DMAs the exact physical addresses it is programmed
with. The import path saved only a buffer's physical base and lifetime ref, not its
length, and `ImageDesc::validate` only bounded the end address against 4 GiB — so a small
imported dma-buf paired with a large geometry (e.g. a 4 KiB buffer and a 4096x4096 RGBA
blit) let the engine read/write past the buffer into adjacent physical memory.

- Expose `DmaBufFile::size()` under the `rga` feature (was `rknpu`-only), so the RGA path
  can see each imported buffer's byte length.
- Store the length in `ImportedBuf` (dma-buf length for `RGA_DMA_BUFFER`; `u64::MAX` for a
  raw `RGA_PHYSICAL_ADDRESS` import, which is already CAP_SYS_RAWIO-gated and owned by the
  privileged caller) and thread it through `resolve_buf`.
- Add `ImageDesc::plane_extents()` (luma/RGB `stride*height`, semiplanar chroma
  `stride*chroma_rows`) and, before touching hardware, verify every plane the engine will
  address — including a derived semiplanar UV plane inside the luma buffer and a separately
  imported chroma plane — stays within its imported buffer `[base, base+len)`. Out-of-range
  geometry is rejected with EINVAL before submit.
回归 D:导入一个 4 KiB dma-buf,提交 512x512 RGBA(需 1 MiB)必须在触碰硬件前以
EINVAL 拒绝;同一缓冲上 16x16 的几何仍能走到设备检查(QEMU 无 RGA2 → ENODEV),证明
只有越界项被拒绝、边界校验不误伤合法请求。

@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 将 rockchip-rga 从 dry-run 编码器扩展为 RK3588 RGA2 驱动,包含 RGA2 命令编码、操作/格式与 librga ABI 解析、ax-driver 的时钟/复位/电源域接入,以及 Starry /dev/rga 的句柄和请求 ioctl 路径;RGA3 明确保留为不支持的骨架。改动主要集中在 RGA 驱动及其 StarryOS glue,现有其他设备接口未见不兼容影响;RGA2 硬件 bring-up 自测已从 Starry 启动路径和 test-suit 移除,符合此前测试边界意见。

验证:cargo fmt --all -- --check 通过;cargo test -p rockchip-rga 通过(61 项);cargo clippy -p rockchip-rga --all-targets -- -D warnings 通过。当前 head 没有可用的 GitHub check runs,因此未将缺失的远程检查误判为通过或失败。已阅读此前 review/issue 评论:关于将硬件自测移出 Starry 启动钩子、共享 dma-heap/clock-reset 接入、写回 fault 回滚及与 dev 冲突的意见,当前 head 已相应处理;未发现仍然合理且未解决的阻塞问题。剩余硬件板级行为仍依赖真实 RK3588 验证,但 host 覆盖了寄存器编码、ABI 布局和操作校验,未见新的阻塞性测试缺口。

Powered by gpt-5.6-luna

@ZR233

ZR233 commented Jul 20, 2026

Copy link
Copy Markdown
Member

请处理冲突

@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 将现有 rockchip-rga dry-run 编码器扩展为 RK3588 RGA2 后端,并接入 ax-driver 的时钟/复位/电源域初始化,以及 StarryOS 的 /dev/rga、共享 /dev/dma_heap 和 librga ioctl/请求路径;RGA3 仍明确拒绝。它会改变用户可见的 RGA ioctl、dma-buf 生命周期与直接物理 DMA 的安全边界,因此并非孤立改动。

此前关于硬件自测不应绑在 Starry 启动路径、每个 open-file-description 应有独立 handle session、以及小 dma-buf 不能被大几何越界 DMA 的意见均合理;当前实现的 RgaFile、生命周期 C 回归和提交前 bounds check 已相应处理。qemu-rga/system 的根 CMake/subcase 布局也符合 grouped C 约定;本地交叉 CMake 构建确认 rga-lifecycle 被安装到 usr/bin/starry-test-suit

验证

  • cargo fmt --check:通过。
  • cargo test --manifest-path drivers/gpu/rockchip-rga/Cargo.toml --all-features:61 项通过。
  • cargo clippy --manifest-path drivers/soc/rockchip/rockchip-soc/Cargo.toml --all-features -- -D warnings 与对应 82 项单测:通过。
  • cargo clippy --manifest-path drivers/gpu/rockchip-rga/Cargo.toml --all-features -- -D warnings:失败,见行内评论;这是本 PR 引入 crate 的合并阻塞项。
  • 当前 head 的 check runs 为 success=29、skipped=29、cancelled=1;没有 failure。取消的是非本改动面的 AKA-00-SG2002 自托管板任务,相关 aarch64 QEMU 矩阵成功。由于本地 clippy 已失败,未将远程 CI 或仅 CMake 构建视为可合并证据。

基线仅有旧 RGA crate/编码器而没有等价 RGA2 驱动;以 rockchip-rga/dev/rgaqemu-rgadma_heap 搜索的开放 PR 未发现重复实现,命中的 RK3588 cpufreq 改动不重叠。

剩余两个阻塞问题:新增 crate 未通过项目要求的 -D warnings clippy,且 NV16(4:2:2 semiplanar)的非零 Y 裁剪会采用错误的 chroma 行偏移。修复并补齐 NV16 crop golden 覆盖后,请重新执行 clippy 与相应 QEMU case。

Powered by gpt-5.6-terra

// SAFETY: the mutable slice is not retained across the device submission below.
{
let dbytes = unsafe { dst.cpu_bytes_mut() };
for px in dbytes.chunks_exact_mut(4) {

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.

【阻塞|验证】项目要求新增/修改 crate 必须通过 cargo clippy ... -D warnings。当前 HEAD 执行 cargo clippy --manifest-path drivers/gpu/rockchip-rga/Cargo.toml --all-features -- -D warnings 在本行(以及 81、224)报出 clippy::chunks_exact_to_as_chunks,因而该 crate 不能通过要求的合并检查。请按诊断改用 as_chunks_mut::<4>() / as_chunks::<4>() 并以同一命令验证。

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

已修复(commit 7abc8dff7):selftest.rs 的 4 字节像素循环改用 as_chunks::<4>() / as_chunks_mut::<4>()cargo clippy --manifest-path drivers/gpu/rockchip-rga/Cargo.toml --all-features -- -D warnings 现已通过。

{
buf.set_register(
registers::DST_CB_BASE_ADDR,
rect_base(uv, dst_rect.x, dst_rect.y / 2, dst.stride_bytes, 1),

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.

【阻塞|RGA2 4:2:2 crop 地址】这里对所有 semiplanar 格式都用 dst_rect.y / 2 计算 CbCr 行偏移,但 NV16 是 4:2:2 SP,色度垂直采样率为 1;非零 Y crop 的偏移应为 dst_rect.y * stride,而不是一半。否则 NV16 目标 crop 会写入错误的 chroma 行并产生颜色错位;源平面 280 行同样受影响。请按格式的垂直 chroma subsampling(NV12/NV21 为 2,NV16 为 1)计算,并加入覆盖源和目标非零 Y 的 NV16 command golden 测试。

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

已修复(commit 58c1ab74e):新增 PixelFormat::chroma_v_subsampling()(NV12/NV21=2,NV16=1),src/dst 的 CbCr 行偏移改为 rect.y / chroma_v_subsampling(),NV16(4:2:2)因此使用完整 y、不再折半;ImageDesc::plane_extents/validate 也复用该 helper。补了覆盖 src 与 dst 非零 Y crop 的 NV16 command golden 测试(blit_nv16_cropped_src_uv_offsetblit_nv16_cropped_dst_uv_offset),host 单测 63 通过。

# Conflicts:
#	os/StarryOS/kernel/src/task/cred.rs
…iplanar crop

The RGA2 command encoder computed the CbCr row offset for a cropped/placed rect as
`rect.y / 2` for every semiplanar format. That is correct for 4:2:0 (NV12/NV21), whose
chroma is half-height, but wrong for NV16 (4:2:2), whose chroma is full-height — a non-zero
Y crop on an NV16 source or destination addressed the wrong chroma rows and produced a
color shift.

Add `PixelFormat::chroma_v_subsampling()` (2 for NV12/NV21, 1 for NV16) and divide the
chroma row by it at both the src and dst CB base computations. `ImageDesc::plane_extents`
and `validate` now use the same helper instead of open-coding the NV16 special case. Adds
NV16 command golden tests covering a non-zero Y crop on both the source and destination.
…ll-features

`cargo clippy --all-features -- -D warnings` (a required merge check) flagged
`clippy::chunks_exact_to_as_chunks` in the selftest's 4-byte pixel loops. Use
`as_chunks::<4>()` / `as_chunks_mut::<4>()`, which also lets the closures take the pixel as
`&[u8; 4]` directly.

@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 将 rockchip-rga 从 dry-run 编码器扩展为 RK3588 RGA2 后端,并接入 ax-driver 的电源/时钟/复位初始化和 StarryOS 的 /dev/rga、共享 dma-buf 生命周期及 librga ioctl 路径。它改变了用户可见 ioctl 的 errno、并发和缓冲区安全边界,并非孤立改动;RGA3 仍明确不支持。

此前评论均已审阅。硬件自测已移出 Starry 启动路径;写回 fault 的 handle/request 回滚、per-open-file-description session、dma-buf 平面边界检查,以及 NV16 非零 Y crop 的色度偏移和对应 golden 覆盖都已在当前 head 处理。当前没有发现重叠的开放 RGA 实现 PR。

验证:cargo fmt --checkrockchip-rgacargo clippy --all-features -- -D warnings、63 个单测、rockchip-soc 的 clippy 和 82 个单测,以及 ax-driver--no-default-features --features rga clippy 均通过;cargo check --manifest-path os/StarryOS/kernel/Cargo.toml --no-default-features --features rga 也通过。cargo xtask starry test qemu --target aarch64-unknown-none-softfloat --list 已发现 qemu-rga/system。完整 ax-driver --all-features clippy 被未改动的 rockchip-npu lint 阻塞,完整 host test 也受现有 axklib 链接符号限制,分别与本次 RGA 路径无关。

当前远程 checks 有一次 Axvisor self-hosted x86_64(VMX) failure,另外有预期的 skipped/cancelled matrix job;我没有将它们作为 RGA 通过的证据。当前阻塞问题是下方的 RGA 设备锁竞争被误报为 ENODEV。除真实 RK3588 板级像素结果仍需硬件验证外,修复后请增加竞争回归并重新运行专用 QEMU case。

Powered by gpt-5.6-terra

// core on this board and has no RGA2 core (-> NoSuchDevice, blit fails).
let mut guard = devs
.iter()
.filter_map(|d| d.try_lock().ok())

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.

这里会把 try_lock() 的所有失败静默跳过。rdrive 在另一个请求持有实际 RGA2 时返回 UsedByOthers,于是已注册但忙碌的 RGA2 会走到下面的 NoSuchDevice,使第二个同步 BLIT_SYNC 看到 ENODEV(设备不存在)而不是等待/串行化;librga 可能因此把正常的瞬时并发误判为 RGA 不可用。请先定位 RGA2,再用能串行化的 lock() 或显式队列等待;若以后为非阻塞调用设计了路径,则应返回 EBUSY 而不是 ENODEV。同时补一个并发提交或受控锁持有的回归,断言锁竞争不会报 ENODEV

@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 将 rockchip-rga 从 dry-run 编码器扩展为 RK3588 RGA2 后端,并接入 ax-driver 的电源/时钟/复位初始化,以及 StarryOS 的 /dev/rga、dma-buf 导入和 librga ioctl 路径;RGA3 仍明确不支持。这会改变用户态 ioctl 的 errno、并发行为与 MMU-off DMA 的安全边界,并非孤立改动。

已审阅此前反馈。硬件自检已移出 Starry 启动流程;写回 fault 回滚、per-open-file-description session(含跨线程/fork 生命周期回归)、dma-buf 各平面边界校验,以及 NV16 非零 Y crop 色度偏移和 golden 覆盖均已在当前 head 处理。未发现重叠的开放 RGA 实现 PR。

本地验证:cargo fmt --checkrockchip-rgacargo clippy --all-features -- -D warnings 和 63 个单测、rockchip-soc 的 clippy 和 82 个单测、ax-driver --no-default-features --features rga clippy,以及 starry-kernel --no-default-features --features rga clippy/check 均通过。cargo xtask starry test qemu --target aarch64-unknown-none-softfloat -c qemu-rga/system 已实际通过,--list 也发现该 case。辅助计划中的广泛 ax-driver/Starry all-features clippy 仍被未改动 rockchip-npu/src/task/op/matmul.rs:312needless_late_init 阻断,all-features ax-driver host test 也受既有重复 axklib DMA symbol 阻断;两者与新增 RGA 路径无关,已单独记录。

远程 checks 当前有 Axvisor self-hosted x86_64(VMX) failure,以及 cancelled/skipped matrix 项;该 x86 Axvisor 任务不由本 PR 的 RGA/Starry aarch64 改动引起,未将其作为 RGA 通过证据。剩余阻塞问题是行内所述的设备锁竞争被误报为 ENODEV。真实 RK3588 板级像素结果仍是残余硬件验证风险。

Powered by gpt-5.6-terra

// core on this board and has no RGA2 core (-> NoSuchDevice, blit fails).
let mut guard = devs
.iter()
.filter_map(|d| d.try_lock().ok())

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.

这里的 try_lock() 在另一条 BLIT_SYNC 正持有实际 RGA2 时会返回 UsedByOthers,但 .ok() 把该状态静默丢弃。若这是唯一的 RGA2,迭代随后落到 NoSuchDevice,使正常的并发同步提交返回 ENODEV、被用户态误判为硬件不存在。请先定位 RGA2 并用可串行化的 lock()/队列等待;若以后明确提供非阻塞语义,也应返回 EBUSY,而不是 ENODEV。同时增加受控锁竞争回归,断言竞争不会报设备不存在。

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

已修复(commit 7ae304376):设备选择不再用 try_lock().ok() 静默丢弃 UsedByOthers。现在先 try_lock() 走无竞争快路径(并顺带跳过空闲的 RGA3 skeleton 而不阻塞),繁忙则退回阻塞 lock() 等待,从而对 RGA2 设备上的并发 blit 串行化,而不是把「繁忙」当作「不存在」。NoSuchDevice(ENODEV)因此只在根本没有 RGA2 core 时返回;将来若新增非阻塞提交路径,应在此返回 EBUSY。

关于回归:该竞争路径仅在真机可达——QEMU virt 无 RGA2 设备,get_list::<RockchipRga>() 为空,ioctl 在进入锁选择之前就返回 ENODEV,所以「锁竞争不报 ENODEV」的断言无法在 QEMU CI 中触发。它属于您计划补的板级 rga smoke 的范畴(并发两个 BLIT_SYNC、断言两者都成功而非其一得到 ENODEV);如需要我可以在该 smoke 里补上这条。

本地验证:aarch64 构建、fmt、Starry clippy(21 检查)、QEMU qemu-rga/system(23 断言全过)均通过。

… ENODEV

The RGA2 device selection used `devs.iter().filter_map(|d| d.try_lock().ok())`, which
silently dropped rdrive's `UsedByOthers`. When a concurrent `BLIT_SYNC` already held the
single RGA2 device, it was skipped and the iterator fell through to `NoSuchDevice`, so a
normal concurrent submit saw ENODEV — as if the hardware were absent — for what is really
transient contention (librga can then wrongly conclude RGA is unavailable).

Acquire the RGA2 device with `try_lock()` for the fast, uncontended path (which also skips
idle RGA3 skeleton devices without blocking), then fall back to the blocking `lock()` to
wait our turn on a busy device, serialising concurrent blits. `NoSuchDevice` is now returned
only when no RGA2 core exists at all, never for a busy-but-present one. A future non-blocking
submit path should return EBUSY here instead.

The contention itself is board-only: on QEMU virt there is no RGA2 device, so `get_list`
is empty and the ioctl returns ENODEV before the lock selection — the "lock contention must
not report ENODEV" regression belongs in the on-board rga smoke.

@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 将 rockchip-rga 从 dry-run 编码器扩展为 RK3588 RGA2 后端,并接入 FDT 时钟/复位/电源域、Starry /dev/rga、共享 /dev/dma_heap 以及 aarch64 专用 QEMU 生命周期用例。RGA2/RGA3 后端边界、MMU-off 缓冲区范围检查和按 open-file-description 持有 RgaFile 会话的方向清晰;RGA3 仍显式拒绝,未把未验证路径伪装成可用功能。

该变更会影响 Starry 用户态可观察的 ioctl、fd 的 dup/fork 共享与关闭生命周期、dma-buf 导入以及 RK3588 DMA/时钟路径,因而不是孤立重构。Starry ABI 准则适用;结构布局和命令值已在代码中按 PR 所述的 Rockchip Linux 6.1 MultiRGA ABI 固定,并需由可执行的用户态回归持续保护。

验证情况:当前 head 的组织 CI 为 completed 59 项(success 30、skipped 29;后者是 run_host/run_container 互斥矩阵和发布分支条件的预期跳过),无失败;其中 Test starry aarch64 qemu / run_containerRun clippy / run_hostTest with std / run_host 均成功。当前工作区本地通过 cargo fmt --all --checkcargo test -p rockchip-rga --all-features(63 项)、cargo xtask clippy --package rockchip-rgacargo test --manifest-path drivers/soc/rockchip/rockchip-soc/Cargo.toml --all-features,以及 cargo check --manifest-path os/StarryOS/kernel/Cargo.toml --features rgacargo check --manifest-path drivers/ax-driver/Cargo.toml --features rga。专用 case 由 cargo xtask starry test qemu --arch aarch64 -l 发现为 qemu-rga/system,其 CMake 配置和构建也通过;因当前 CI 已覆盖 aarch64 QEMU,本轮未重复运行完整 QEMU。

测试放置方面,当前的独立 build wrapper 没有污染共享 qemu 配置,system/CMakeLists.txt 与子用例的 CMakeLists.txt/src 布局符合 runner 约定,且失败标记能够使 wrapper 失败。此前关于把硬件 bring-up 移出 Starry 启动路径、以及将 session 从 task/tgid 改为 open-file-description 的意见,当前实现已实质处理。不过此前已被修复的用户指针写回回滚问题,其当前可执行回归在测试迁移时丢失,见内联评论;这是本次阻塞项。

重复/重叠检查:基线的 rockchip-rga 仅有不下发命令的实现,未提供等价 RGA2 后端或 /dev/rga ABI;以 RGA、rockchip-rga/dev/rga 检索开放 PR,未发现需要依赖、重复或冲突的独立实现。未发现 [patch.crates-io] 覆盖。

请补充该 fault 回滚的确定性 QEMU 回归后重新请求审查。其余已知限制(RGA3、IOMMU、异步 fence 等)目前有显式拒绝或范围说明。

Powered by gpt-5.6-terra

TEST_DONE();
}

/* ---- Regression A: same fd, cross-thread handle visibility. ---- */

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.

阻塞|回归覆盖缺失。 这个专用 QEMU case 已覆盖跨线程、独立 open、fork 和缓冲区边界,但没有覆盖此前修复的 RGA_IOC_IMPORT_BUFFER / RGA_IOC_REQUEST_CREATE 写回用户指针失败回滚;当前 rga.rs 虽保留了 vm_write 失败后删除 handle/request 的代码,PR 讨论中也确认原先的只读页回归已在迁移时移除。这样该修复再次退化为“插入后不回滚”时,现有用例仍会全部通过,违反 bugfix 必须在未修复实现上失败的回归要求。

请在这里补回确定性负向用例:让 ioctl 输入仍可读、但输出字段所在页经 mprotect(..., PROT_READ) 变为不可写,断言返回 EFAULT;恢复页权限后,用预期的首个 handle 发起一次已验证请求(旧实现会解析到泄漏项并到达 ENODEV,修复后必须 EBADF),并对首个 request id 验证 CANCEL/SUBMIT 返回 EINVAL。这样才能同时证明两个表项确实被回滚,而不只是证明用户写回失败。

@mai-team-app
mai-team-app Bot requested a review from ZR233 July 21, 2026 05:34
mai-team-app[bot]
mai-team-app Bot previously requested changes Jul 21, 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 将 rockchip-rga 从 dry-run 编码器扩展为 RK3588 RGA2 后端,并接入 ax-driver 的电源/时钟/复位初始化,以及 StarryOS 的 /dev/rga、dma-buf 导入、librga ioctl 和每个 open-file-description 的 RgaFile 会话;RGA3 仍明确不支持。改动会影响用户可见 ioctl 的 errno、句柄生命周期和 MMU-off DMA 边界,因此不是孤立改动。

当前实现中,此前关于硬件自检移出 Starry 启动路径、per-open 会话(含跨线程/独立 open/fork)、dma-buf 平面边界、NV16 非零 Y crop 和设备锁竞争不得误报 ENODEV 的意见均已处理。qemu-rga/system 的根 CMake、子测例布局、安装目录和 success/fail 标记也符合当前 grouped C runner 约定。

验证:

  • 当前 head 的组织 CI 为 success=30, skipped=29, failure=0;aarch64 Starry QEMU 检查成功,跳过项为 host/container 互斥矩阵或非适用项,没有发现由本 PR 引起的失败。
  • 本地 cargo fmt --checkcargo clippy --manifest-path drivers/gpu/rockchip-rga/Cargo.toml --all-features -- -D warningscargo clippy --manifest-path drivers/ax-driver/Cargo.toml --no-default-features --features rga -- -D warningsgit diff --check 以及新增 C 子测例的 clang -fsyntax-only -Wall -Wextra -Werror -pthread 均通过。
  • helper 建议的 ax-driver --all-features clippy 会在未改动的 drivers/npu/rockchip-npu/src/task/op/matmul.rs:312 触发既有 needless_late_init;该路径不在本 PR diff 中,已与 RGA 定向检查分开记录。

既有评论与测试覆盖: 当前用例已覆盖跨线程、两个独立 open、fork 和小 dma-buf 大几何的边界拒绝;不过下方写回 fault 回滚的修复尚无能够在旧实现失败、在当前实现通过的回归。该问题是当前未解决的阻塞项。

重复/重叠: 已检索 base 的旧 RGA dry-run 实现以及以 RGA/dev/rgaqemu-rga 为关键词的开放 PR;没有发现等价或冲突的 RGA2 实现。未发现 [patch.crates-io]

请补齐行内所述的负向回归并重新运行专用 QEMU case。真实 RK3588 板级像素/并发行为仍是后续硬件验证风险,但不是本轮额外阻塞点。现有请求的 elliott10ZCShouZR233 已覆盖驱动和 test-suit 跟进,未改动 reviewer 元数据。

Powered by gpt-5.6-terra

TEST_DONE();
}

/* ---- Regression A: same fd, cross-thread handle visibility. ---- */

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.

【阻塞|bugfix 回归缺失】这里的 A–D 只覆盖会话生命周期和 DMA 范围,没有覆盖 RGA_IOC_IMPORT_BUFFERRGA_IOC_REQUEST_CREATE 的用户写回 fault 回滚。内核路径虽在 vm_write 失败后删除刚插入的 handle/request,但若回归为“不回滚”,这些用例仍会全部通过,违反 bug 修复必须有未修复版本会失败的确定性回归要求。请新增只读输出页用例:让输入仍可读、输出页经 mprotect(..., PROT_READ) 不可写,断言两个 ioctl 返回 EFAULT;恢复权限后验证预期的首个 handle 只能得到 EBADF、首个 request 的 CANCEL/SUBMIT 得到 EINVAL。旧实现会保留表项并分别到达 ENODEV/成功,从而能证明两条回滚路径而非仅证明写回失败。

@ZR233
ZR233 merged commit 08eca7d into rcore-os:dev Jul 21, 2026
59 checks passed
This was referenced Jul 21, 2026
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.

4 participants