Skip to content

fix(repo): migrate spin usage to ax-kspin#861

Merged
ZR233 merged 43 commits into
rcore-os:devfrom
shilei-massclouds:dev-eliminate-spin
May 25, 2026
Merged

fix(repo): migrate spin usage to ax-kspin#861
ZR233 merged 43 commits into
rcore-os:devfrom
shilei-massclouds:dev-eliminate-spin

Conversation

@shilei-massclouds

Copy link
Copy Markdown
Contributor

Background

The repository had multiple direct usages of the external spin / lazy_static locking primitives. Some SpinNoPreempt usages
were in contexts where IRQs were not disabled, which could lead to interrupt reentry deadlocks or lockdep/might_sleep failures.

Changes

  • Vendor the spin crate into the repository as a controlled local dependency.
  • Migrate global state, device state, filesystem state, and interrupt-related locks to ax-kspin lock types.
  • Stop exposing spin::Mutex by default to reduce accidental future misuse.
  • Adjust StarryOS epoll, tty, netlink, packet, loop, tmpfs, and related paths to avoid unsafe lock usage in atomic or user-copy
    contexts.
  • Adjust axfs-ng FAT/ext4 locks to avoid atomic-context checks during rootfs and early filesystem paths.
  • Fix concurrent std test execution in axaddrspace.
  • Add audit reports for external spin and SpinNoPreempt usage, including handled cases and follow-up locking design notes.

Notes

Some Mutex -> SpinNoIrq changes are conservative short-term fixes intended to remove current runtime hazards. Longer term, some
call paths should be revisited by narrowing lock ranges, restructuring call flows, and returning to blocking mutexes where
appropriate.

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

Review 总结

本 PR 完成了将仓库内 spin::Mutex 用法迁移到 ax_kspin::SpinNoIrq 的工作,同时将外部 spin crate vendor 到 components/spin/ 以保留 RwLock/Once/Lazy 等尚不需要迁移的原语,并通过 [patch.crates-io] 替换构建图中的外部版本。

变更范围(128 个文件,+6859 / -281)

  1. 供应链解耦:vendor spin 0.10.0,移除 spin 0.9.8,统一为本地版本;默认 feature 精简为 rwlock/once/lazy,不再暴露 Mutex
  2. spin::Mutex → ax_kspin::SpinNoIrq:覆盖 VFS 层(axfs-ng-vfs)、ArceOS 文件系统模块(axfs FAT/ext4)、网络模块(axnet-ng raw/unix)、设备层(arm_vgic/riscv_vplic/dma-api/axdevice)、Axvisor 全局锁、axplat-dyn 驱动、各类 USB/NVMe/串口/SoC 驱动。
  3. SpinNoPreempt → SpinNoIrq:epoll ready queue/interests、loop device cache、StarryOS timer/netlink/usbfs/camera 锁,修正了 IRQ 未禁用时的同 CPU 重入死锁风险。
  4. lazy_static → spin::Lazy:netlink socket 注册表、unix abstract bind、PWM sysfs state、axvisor shell command tree、axnet-ng unix socket 等。
  5. USBFS 睡眠安全:将 LiveDeviceState::deviceUsbFsManager::open_lock 从 spin lock 改为 ax_sync::Mutex(可睡眠),避免在 spin lock 保护区内调用可能阻塞的 USB 操作。
  6. Lockdep 测试:新增 vfs-cache-single 测试用例,验证 axfs-ng-vfs dentry user_data/cache 的 ABBA 检测。
  7. 审计文档reports/external-spin-audit.mdreports/external-spin-migration-plan.mdreports/spin-no-preempt-audit.md 详细记录了当前状态和后续迁移策略。

验证

  • cargo fmt --check
  • cargo clippy --package {axdevice,dma-api,axfs-ng-vfs,rsext4,spin} 全部通过,无 warning ✅
  • CI 状态:pending(无已完成的 check),本地已做针对性的 clippy 验证

重复/重叠分析

  • 搜索了所有 open PR(#868 socket syscall 测试、#853 procfs/procps、#831 等),均与本 PR 的 spin 迁移无重叠。
  • base 分支上已无未被迁移的 spin::Mutex 直接使用(仅剩 spin::RwLock/Once/Lazy 按计划保留)。

评估

整体变更方向正确:

  • 将 Mutex 类锁迁移到 ax_kspin::SpinNoIrq 解决了 lockdep 盲区和 IRQ 重入问题。
  • USBFS 中 spin → ax_sync::Mutex 的变更是合理的,因为 USB 操作可能睡眠/等待事件。
  • epoll ready_queue 注释已明确指出 VecDeque::push_back 可能在 IRQ 上下文中分配的 follow-up。
  • Unix socket with_slot/with_slot_or_insert 中的 SpinNoIrq guard drop-before-transport 逻辑正确避免了嵌套锁问题。

未发现阻塞性问题,予以批准。 后续建议关注 audit 中列出的中长期锁策略优化。

Powered by glm-5.1

if interest.try_mark_in_queue() {
// The queue lock must disable IRQs because wakers may be invoked
// from IRQ wake paths. `VecDeque::push_back` can still allocate
// when capacity is exhausted; if this path is proven to run in IRQ

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.

这个注释清楚地标记了 VecDeque::push_back 在 IRQ 上下文可能分配的风险。后续如果确认 waker 会从硬中断上下文调用,建议替换为 bounded ring buffer 或 deferred work 设计。当前的 conservative SpinNoIrq 是正确的短期修复。

.ok_or(AxError::ConnectionRefused)?
.as_ref())
let slot = {
// `DirEntry::user_data()` is protected by a SpinNoIrq guard.

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.

好的做法——先 clone BindSlotArc 引用再释放 user_data() 的 SpinNoIrq guard,避免了在 spin lock 保护区内调用可能睡眠的 socket transport 代码。

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

Review 总结

本 PR 完成了将仓库内 spin::Mutex 用法迁移到 ax_kspin::SpinNoIrq 的工作,同时将外部 spin crate vendor 到 components/spin/ 以保留 RwLock/Once/Lazy 等尚不需要迁移的原语,并通过 [patch.crates-io] 替换构建图中的外部版本。

变更范围(128 个文件,+6815 / -225)

  1. 供应链解耦:vendor spin 0.10.0 到本地,移除 spin 0.9.8 双版本共存;默认 feature 精简为 rwlock/once/lazy,不再暴露 Mutex
  2. spin::Mutex → ax_kspin::SpinNoIrq:覆盖 VFS 层、ArceOS 文件系统模块、网络模块、设备层、Axvisor 全局锁、驱动层等所有 lockdep 相关锁。
  3. SpinNoPreempt → SpinNoIrq:epoll ready_queue/interests、loop device cache、StarryOS timer/netlink/usbfs/camera 锁,修正了 IRQ 未禁用时的同 CPU 重入死锁风险。
  4. lazy_static → spin::Lazy:netlink socket 注册表、unix abstract bind、timer alarm_list、axvisor shell command tree 等。
  5. USBFS 睡眠安全LiveDeviceState::deviceUsbFsManager::open_lock 从 spin lock 改为 ax_sync::Mutex(可睡眠),避免在 spin lock 保护区内调用可能阻塞的 USB 操作。
  6. Netlink read_one 改进:先 pop_frontwrite,避免在持锁期间进行用户态拷贝。
  7. Lockdep 测试:新增 vfs-cache-single 测试用例,验证 axfs-ng-vfs dentry user_data/cache 的 ABBA 检测。
  8. 审计文档:三份详细的审计和迁移计划文档,记录了当前状态和后续迁移策略。

验证

  • 所有 spin::Mutex 直接使用已从源码中移除(仅剩 spin::RwLock/Once/Lazy,按计划保留)。
  • SpinNoPreempt 使用也已全部迁移到 SpinNoIrq
  • Vendored spin 的 Cargo.toml 正确配置了 [patch.crates-io] 和精简的默认 feature。
  • Unix socket 的 SpinNoIrq guard 提前释放逻辑正确,避免了在 spin lock 内调用可睡眠的 transport 代码。

评估

整体变更方向正确、执行到位:

  • 将 Mutex 类锁迁移到 ax_kspin::SpinNoIrq 解决了 lockdep 盲区和 IRQ 重入问题。
  • USBFS 中 spin → ax_sync::Mutex 的变更是合理的。
  • Unix socket with_slot/with_slot_or_insert 中的 guard drop-before-transport 逻辑正确。
  • epoll ready_queue 注释已明确指出 VecDeque::push_back 在 IRQ 上下文中可能的分配风险。
  • FAT/ext4 的 lock 注释正确说明了短期使用 SpinNoIrq 的原因和后续优化方向。
  • 三份审计报告详尽记录了决策过程和后续计划,方便后续维护。

未发现阻塞性问题,予以批准。 后续建议关注 audit 中列出的中长期锁策略优化。

Powered by glm-5.1

// Cap at the message length; netlink datagrams are not coalesced.
let n = dst.write(msg)?;
queue.pop_front();
let n = dst.write(&msg)?;

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.

好的改动。pop_front 先取出消息再释放锁,然后在锁外进行 dst.write(),避免了在持自旋锁期间进行用户态内存拷贝。

/// current rootfs setup can also run in early atomic contexts where a
/// blocking mutex trips `might_sleep()`, so use `SpinNoIrq` instead of the
/// older `SpinNoPreempt` to close same-CPU IRQ reentry without changing the
/// boot-time calling contract.

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.

注释清楚地记录了设计选择和权衡:短期内使用 SpinNoIrq 关闭 IRQ 重入,后续需要缩短临界区或改为阻塞锁。类似的注释也出现在 rsext4/fs.rslwext4/fs.rs,保持了一致性。

# Enables `SpinMutex` and the default spin mutex implementation for `Mutex`.
spin_mutex = ["mutex"]

# Enables `TicketMutex`.

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.

vendor 的 spin crate 默认 feature 精简得当——只保留 rwlockoncelazy,移除了 mutex。配合根 Cargo.toml[patch.crates-io] 确保整个 workspace 统一使用本地版本。

buddy-slab-allocator depends on spin::Mutex but the mutex feature was
removed from spin's default features. Enable it to maintain compatibility
with external crates.

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

Review 总结

本 PR 将仓库内所有 spin::Mutex 直接使用迁移到 ax_kspin::SpinNoIrq,同时将外部 spin crate vendor 到 components/spin/ 以保留 RwLock/Once/Lazy,并通过 [patch.crates-io] 统一构建图。共 128 文件,43 个 commit,+6861 / -281。

变更分类

  1. 供应链解耦:vendor spin 0.10.0,移除 spin 0.9.8 双版本,默认 feature 精简为 rwlock/once/lazy/mutex(mutex 保留给 buddy-slab-allocator 等外部 crate)。
  2. spin::Mutex → ax_kspin::SpinNoIrq:覆盖 VFS、FAT/ext4 文件系统、网络模块、设备层(arm_vgic/riscv_vplic/dma-api/axdevice)、Axvisor、驱动层等全部 lockdep 相关锁。
  3. SpinNoPreempt → SpinNoIrq:epoll、loop device cache、timer、netlink、usbfs、camera、pty/terminal 锁,修正 IRQ 重入死锁风险。
  4. lazy_static → spin::Lazy:netlink socket 注册表、unix abstract bind、timer alarm_list、PWM sysfs、axvisor shell command tree 等。
  5. USBFS 睡眠安全LiveDeviceState::deviceUsbFsManager::open_lock 从 spin lock 改为 ax_sync::Mutex(可睡眠),避免 spin lock 内调用可能阻塞的 USB 操作。
  6. 锁作用域优化:netlink read_one 和 packet socket 先取出数据再释放锁,避免 spin lock 内进行用户态拷贝。
  7. tmpfs 锁变更:目录 entries 从 ax_sync::Mutex 改为 SpinNoIrq,因 VFS dentry-cache 操作在 SpinNoIrq 保护下回调后端。
  8. Lockdep 测试:新增 vfs-cache-single 用例,验证 axfs-ng-vfs dentry user_data/cache 的 ABBA 检测。
  9. axbuild 特性规范化:std 构建时自动将特性映射到 arceos-rust/ 前缀,支持 lockdep 等新特性。
  10. 审计文档:三份报告详细记录了当前 spin 使用状况和后续迁移策略。

验证

  • 本地 cargo fmt --check 通过
  • 源码扫描确认无残留 spin::Mutex 直接使用(仅剩 spin::RwLock/Once/Lazy,按计划保留)
  • SpinNoPreempt 直接使用也已全部迁移(仅出现在注释中)
  • vendored spin 的 [patch.crates-io] 配置正确
  • lockdep test 新增用例的 build-vfs-cache-x86_64-unknown-none.toml 配置完整

已知权衡(非阻塞)

  • tmpfs HashMap 和 epoll VecDequeSpinNoIrq 下可触发分配,已在注释和 audit 文档中标为后续优化项
  • tmpfs 移除了 lockdep subclass 注释(lock_tmpfs_nested),因 VFS 层 SpinNoIrq 回调使阻塞 mutex 不可行;lockdep false positive 风险可接受
  • FAT/ext4 大锁改为 SpinNoIrq 是短期方案,后续需缩短临界区或改为阻塞锁

重复/重叠分析

搜索了当前所有 open PR,未发现与 spin 迁移重叠的 PR。base 分支上已无未迁移的 spin::Mutex 直接使用。

评估

变更方向正确,执行到位,权衡均有记录。未发现阻塞性问题,予以批准。

Powered by glm-5.1

nested_dir_entries: bool,
) -> Arc<Inode> {
let mut inodes = fs.inodes.lock();
let entry = inodes.vacant_entry();

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.

好的做法:tmpfs entriesax_sync::Mutex 改为 SpinNoIrq 是必要的,因为 VFS dentry-cache 操作在 SpinNoIrq 保护下回调后端,使用阻塞 mutex 会死锁。

需要注意的是 HashMap::insert 在容量不足时会分配内存,此时 IRQ 被禁用。如果 tmpfs 目录条目数量可能很大,后续可考虑预分配容量或改用固定大小数据结构。当前对于典型 OS 使用场景是可接受的。

.unwrap_or_else(|| normalized.clone()),
feature if feature.starts_with("arceos-rust/") => normalized,
feature => format!("arceos-rust/{feature}"),
}

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.

lockdep 特性正确地透传到了 arceos-rustaxbuildnormalize_std_feature 将裸特性名(如 lockdep)映射为 arceos-rust/lockdep,确保 std 构建时特性能正确传递到最终的用户 crate。测试覆盖了 ax-std/arceos-rust/ 和裸特性名三种情况。

@@ -258,6 +431,7 @@ fn run_case(case: &str) {
"mixed-two-task" => mixed_two_task_abba(),

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.

VFS 层的 lockdep 测试用例设计良好:通过 user_data() 获取 SpinNoIrq guard,然后在 guard 持有期间调用 lookup(也会获取 SpinNoIrq guard),形成 dentry user_data → dir cache 的锁序。后续的 rename 操作反过来获取 cache → user_data,触发 ABBA 检测。

这验证了 ax-kspin lockdep 对 VFS 层嵌套锁的可见性。

@ZR233
ZR233 merged commit 7793fb6 into rcore-os:dev May 25, 2026
211 of 215 checks passed
@github-actions github-actions Bot mentioned this pull request May 25, 2026
This was referenced May 27, 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.

2 participants