Skip to content

refactor(ax-task): rebuild scheduler and runtime ownership - #1775

Draft
ZR233 wants to merge 196 commits into
devfrom
codex/refactor-ax-task-from-1596
Draft

refactor(ax-task): rebuild scheduler and runtime ownership#1775
ZR233 wants to merge 196 commits into
devfrom
codex/refactor-ax-task-from-1596

Conversation

@ZR233

@ZR233 ZR233 commented Jul 30, 2026

Copy link
Copy Markdown
Member

问题

旧任务系统把 OS 资源、调度状态、物理 clockevent 和中断唤醒生命周期耦合在一起。迁移与 Linux v7.1 CONFIG_PREEMPT_RT=y 对照审计中确认了以下系统性风险:

  • placement、迁移、on_cpu 和 switch-tail 由多套状态分别维护,线程可能被重复拥有或过早回收;
  • task deadline、periodic tick 和物理 oneshot timer 缺少唯一 owner,取消、重编程和 Firing 期间更新容易留下陈旧状态;
  • 远程 wake/IPI 的布尔门铃不能完整表达 publish、claim、drain 和并发重投递,存在丢唤醒窗口;
  • PI、park、IRQ waiter 和线程资源创建缺少统一的 generation 与事务式回滚边界;
  • Starry 的 CPU timer、perf、signal、PID/zombie 以及部分驱动 IRQ 路径仍依赖旧任务对象或跨上下文裸生命周期。

本 PR 以 #1596 的 OS 无关 ax-task 核心为迁移起点,并按 Linux v7.1 scheduler、rtmutex、hrtimer/clockevent、irq_work、task_work、perf 和 exit 生命周期重新审计和重构。完整设计、不变量、红绿测试与历史里程碑记录在 book/design/ax-task-linux-v7.1-rt-audit.md

主要改动

ax-task / ax-runtime

  • 新增 OS 无关 components/ax-task,提供 TaskSystem、每 CPU CpuLocal、generation-bearing ThreadId/ThreadHandle、运行时调度策略、PI、wait、executor 和 task-work;删除旧 os/arceos/modules/axtask
  • ax-runtime::task 成为 ArceOS/StarryOS 的任务入口,负责 bootstrap、stack/TLS/context/address-space、IPI、clockevent、switch-tail 和资源回收。
  • 用唯一 SchedulerPlacement 状态机表达 detached、queued、running、switching-out、migrating 和 exited-awaiting-tail;只有 switch tail 清除物理 on_cpu 后才允许迁移完成或回收。
  • scheduler baton 覆盖完整上下文切换;IRQ/preemption 只从唯一 tail 路径恢复。
  • 远程调度投递使用 generation/epoch:先发布 payload 与 sticky state,再发 IPI;handler 先 claim 旧投递,再 drain,并允许并发的新 epoch 重新响铃。
  • CPU online/offline 使用 producer admission、quiescence 校验和 clockevent 生命周期事务,上线数受 CPU_CAPACITY 约束。

Task deadline / clockevent

  • ax-task 只管理 sleep、park、wait timeout、调度策略和自身 deferred work deadline,不承载 VM/POSIX 任意 timer callback。
  • deadline heap 只保存 ThreadId + node identity + arm generation + typed kind;cancel/rearm 物理删除旧条目,不保存 tombstone 或裸 timer-node 指针。
  • ax-runtime::LocalClockEvent 是物理 oneshot timer 的唯一 owner,显式实现 Offline / Idle / Armed / Firing,统一选择 task deadline 与 periodic source 的最早期限。
  • timer IRQ 只做有界、无分配的到期记账和 publication;wake、expiry、signal 以及任意 OS 工作均在 scheduler safe point 或任务态 worker 推进。

PI、等待和资源生命周期

  • PI lock、waiter、park、IRQ registration 和 weak task identity 全部带 generation,防止 slot/地址复用 ABA。
  • PI handoff 在同一有界元数据事务内完成验证、deboost 和 grant,释放 gate 后才 wake。
  • IrqWaitCell 使用 generation-bearing registration;撤销后等待在途 notifier quiesce,IRQ 不保存裸 wake 指针。
  • stack、TLS、context、address space 和 extension 创建使用 move-only 事务 guard,失败按所有权逆序回滚。

StarryOS

  • Linux TID/PID 与核心 ThreadId 分离;保留最新 devProcessIdentity: Live -> Zombie -> Reaping -> Reaped 作为唯一 PID/zombie/reap authority。
  • task wait 返回 Ready / Interrupted / TimedOut,signal publication/acknowledgement 使用单调 generation。
  • perf 使用 PerfTarget::{Task, Cpu}、固定 owner-CPU worker、generation-checked sampling registration 和 owner fence。
  • CPU interval timer 使用进程 CPU accounting;ITIMER_REAL 仍由 wall-clock worker 驱动,ITIMER_VIRTUAL/PROF 不再按 wall time 轮询。

本分支涉及的 IRQ/驱动边界

  • serial 拆成 task/control、hard-IRQ 和 emergency-TX endpoint;IRQ 只做有界 status/ACK/FIFO drain/event publication。
  • vsock 将设备事件 publication 与 connection manager/socket wake 分离。
  • USB/xHCI 保留非睡眠的硬件 gate、interrupter masking 和稳定 registry;拓扑与 rearm 在线程上下文执行。

最新 dev rebase 与本轮修复

当前 HEAD 75db31f35 基于最新 origin/dev f1774c1f6。本轮刷新后无需新增 rebase 提交;dev 的 ProcessIdentity: Live -> Zombie -> Reaping -> Reaped、AxVM CPU lifecycle 与 LS2K IRQ 修复均保持不变。现有 stash 和两个 rustc ICE 日志未改动。

本轮新增五十八个阶段提交:

  1. fix(ax-runtime): adapt block runtime after dev rebase

    • 将最新 block-mq runtime 从已删除的旧 IrqNotify/AxTaskRef API 迁到 IrqWaitCell、固定 service-thread waiter、generation-bearing ThreadHandle 和 affinity spawn;
    • blocking join 在锁外执行;仅保护句柄 move-out 的短临界区使用 SpinNoPreempt,不无故屏蔽 IRQ;
    • readahead 纯任务态状态改用 PiMutex,IRQ 可达的 block runtime 元数据继续使用非睡眠 gate;
    • 修正 “without fs feature” 测试在启用 fs 时误执行的问题。
  2. fix(ax-task): serialize deferred scheduler tick accounting

    • 删除 hard IRQ 可调用任意 OS accounting callback 的接口;
    • timer IRQ 只发布 generation-bearing ThreadId 和单调 observed_ns watermark;
    • 该阶段先以 SpinNoPreempt writer gate 排除跨 CPU 双写并实现 Retry;第 31 项进一步删除这套过渡设计,恢复 Linux owner-CPU vtime 所有权;
    • ax-task 以 CAS 重新取得物理 publication ownership;若新 tick 已发布则由新 tick 独占 delivery,disable/re-enable epoch 会使旧 retry 失效;
    • ax-runtime wrapper 转发 timestamp 和 task-work disposition;Starry 当前只读采样始终返回 Complete
  3. fix(ax-task): yield between scheduler tick retries

    • 永久 Retry 的确定性红测在一个 64 项 service batch 中观察到 64 次 callback,证明原实现虽有总预算但会在同一 worker pass 内忙重试;
    • 现在每个 service pass 对发生冲突的 scheduler-tick record 最多尝试一次,保留 sticky pending 后由外层 worker 先 yield,再进入下一次尝试;
    • 该调度点对应 Linux v7.1 task_work_run() 在每个 callback 后执行 cond_resched() 的 RT 友好边界。
  4. fix(ax-task): publish coalesced scheduler tick timestamps

    • Loom 红测证明已 pending generation 的普通 load 不能发布随后写入的 observed_ns:consumer 可能 claim 旧 publication、读到旧时间戳,而 producer 又因看到 pending 而不重新入队;
    • coalesced 快路径现在也执行同值 AcqRel CAS。若 CAS 在线性化顺序上先发生,consumer 的 claim 获取最新时间戳;若 consumer 已清除 generation,CAS 失败后 producer 安装新的物理 publication;
    • 该协议对应 Linux v7.1 irq_work_claim() 即使 work 已 pending 仍执行 atomic RMW 的 publish/claim 配对。
  5. perf(ax-runtime): streamline preemption guard access

    • scheduler lock hook 直接使用 current-thread 寄存器和已验证 CPU binding 访问 per-CPU guard state,不再为每次 preemption enter/exit 重建完整 CpuPin/ExclusiveCpu
    • TaskRuntime::current_cpu_id 收窄为要求既有 migration pin 的 unsafe capability,IRQ-context 检查在该 pin 下直接读取平台 publication bit;
    • 初版重排在嵌套 NoPreempt drop 中递归进入通用 IRQ 查询并触发 x86_64 double fault;确定性 host 测试要求嵌套退出不调用 IRQ/reschedule probe,修复采用 Linux preempt_count_dec_and_test() 一样的 state-first 短路顺序;
    • qperf 已证明旧 current_area/current_thread/symbol_offset 热点消失,但 DHCP 到 shell 仍为 13.43 秒/13,113 samples,明显慢于 dev 的 4.99 秒/4,606 samples;剩余 owner schedule、remote/policy inbox drain 的插件放大继续追踪,真实性能由第 9 项无插件对照判定。
  6. perf(ax-task): skip empty owner inbox drains

    • 确定性红测证明 scheduler-only safe point 会无条件进入两个空 inbox drain;owner 现在只在相应 inbox 实际有 publication 时进入有界 drain;
    • policy-only/reclaim-only 路径仍先消费 coalesced IPI epoch,再 drain,并由最终 pending 复查保留并发 publication;伴随回归验证 policy 被消费且空 wake inbox 不被触碰;
    • 参考 Linux v7.1 sched_ttwu_pending() 的空 llist 快速返回;没有把该优化扩大为跳过 dispatch commit/Deadline service,因为 __schedule()prev == next 时仍维护 rq clock、hrtick 和调度状态;
    • 完整 ax-task 测试和 clippy 通过。新 qperf 窗口为 14.33 秒/13,980 samples,dev 为 4.99 秒/4,606 samples;scheduler_wait_preempt 仍占 46.27%,因此该提交只关闭空 drain 浪费;该插件窗口不再单独作为真实性能结论,见第 9 项无插件对照。
  7. fix(ax-task): bound deadline member scan rounds

    • 两个确定性红测分别证明:deadline_members > batch_limit 时旧游标会永久重投 owner work;第一批 backlog 又被 no-switch tail 误报为 Quiescent
    • CPU-local 扫描现在保留本轮剩余成员数,成员变化会重启本轮,只有未完成批次继续发布 sticky work;SchedulerOutcome::OwnerWorkPending 覆盖全部有界 owner work;
    • 参考 Linux v7.1 sched/deadline.c 的 per-entity dl_timer/inactive_timer,文档已把成员扫描重新列为待关闭架构 finding:本提交只封住有限批次 livelock,后续将 CBS replenishment 与 GRUB zero-lag 改为 generation-checked typed event;
    • 完整 ax-task 193 个 unit test、全部 integration/doc test、20 个 loom model 以及 package clippy 通过。
  8. test(ax-sync): keep lock audit stable across module splits

    • 最新 dev 将 axfs-ng inode cache 拆入子模块后,静态锁边界测试仍硬编码旧 cache.rs 路径而失败;
    • 测试现在递归检查 cache 模块,并要求目标 SpinMutex 声明恰好出现一次,继续约束 IRQ/任务态锁分类,而不是放宽断言。
  9. perf(ax-task): cache the current CPU remote endpoint

    • 确定性红测先观察到 pinned need_resched 查询仍执行一次通用 remote registry lookup (0, 1);修复后为 (0, 0)
    • 参考 Linux v7.1 当前 CPU preempt_count/need_resched 直接访问,ax-runtime 在 CPU online 前缓存 shutdown-lifetime CpuRemote endpoint,当前 CPU 查询通过 current-thread 寄存器访问,远程 producer 仍显式按 CPU 查找;
    • lifecycle 测试验证同一 endpoint 在 offline/re-online 周期内地址不变,仅 publication state 改变;
    • 使用相同 qperf Cargo feature、NVMe rootfs 和 virtio-net,但不加载指令插件,当前分支 DHCP 为 3.328285 秒,dev 为 3.321183 秒,差 7.1ms(约 0.21%),不支持材料性的真实 wall-time 回退;缺失 workload marker 的插件结果明确作废。
  10. fix(ax-task): replace deadline scans with typed timer events

  • 确定性红测证明两个未来 Deadline reservation、batch_limit = 1 时,旧普通 safe point 仍会因成员扫描返回 OwnerWorkPending;新实现不再扫描未到期 reservation;
  • 参考 Linux v7.1 每个 sched_dl_entity 独立的 dl_timerinactive_timer,每线程嵌入 park、CBS、zero-lag 三类节点,硬 IRQ 只复制值类型事件,safe point 按完整 registration identity 验证;
  • 删除 deadline_members timer scan 和第二套 deferred_scheduler_deadline_ns 标量;deadline_members 仅保留 GRUB ownership/offline registry 语义;
  • remote PI CBS baton 返回改为 retained、generation-bearing DeadlineRefresh 定向投递;合并保留的旧消息按当前 CBS generation 重算,不重放旧状态;
  • 第二个确定性红测证明同一 ThreadId/class 的不同 node 会发生 registration ABA;token 现在组合 process-lifetime node identity 与 node-local generation,旧 registration 不能取消另一节点;
  • scheduler late claim 对齐 Linux __schedule() 在 rq clock/accounting 后清 need_resched 的顺序,补 RR forced-yield 回归;完整 ax-task、ax-runtime、ax-sync 测试与 feature clippy 通过。
  1. fix(ax-task): return typed PI cycle errors
  • 现有最低层测试原先明确要求 PI cycle 触发 runtime fatal;改成 typed-result 断言后稳定红于 fatal hook;
  • 对照 Linux v7.1:普通 rt_mutex_lock() 可把内核死锁视为调用错误,但 PI-futex/proxy registration 的 full chain walk 返回 -EDEADLK
  • ax-task::pi_wait_start() 接受显式 waiter/owner,属于可复用 graph/proxy 边界,现在在任何 generation/edge mutation 前返回 TaskError::PiCycle
  • ax-sync::RawMutex 的 infallible lock API 仍可把该错误升级为 kernel programming failure,策略不再硬编码进调度核心;红绿测试同时证明失败后原有 donation edge 仍可正常取消;
  • ax-task 全套(200 unit、全部 integration/doc、20 loom)、ax-sync 全套及两包 feature clippy 通过。
  1. fix(starry-task): use PI locks for task registries
  • 确定性锁边界红测证明 task、PID identity、process-group 和 session 四个纯任务态注册表仍使用不禁抢占的 raw SpinRwLock;这些临界区会执行 BTreeMap/WeakMap 插入、删除、遍历和 weak handle upgrade;
  • 对照 Linux v7.1 PREEMPT_RT:tasklist_lockrwlock_t 会替换为 rwbase_rt/rtmutex-backed wait path;四个 Starry 注册表改用 PiMutex,竞争时睡眠并提供优先级继承;
  • 每个 ProcessIdentity 的短小、无分配生命周期状态仍使用 SpinNoIrq,锁序明确为 registry → identity state,避免机械替换 IRQ/原子状态锁;
  • 红绿测试、Starry 24/24 feature clippy、ax-sync 全测试与 3/3 clippy、x86_64 Starry axtest QEMU 385/385 通过。
  1. fix(starry-task): close clone activation window
  • 确定性 QEMU 红测证明旧 scheduler stage 会立即执行线程入口,无法在公开 PID/TID 前建立不可运行边界;
  • 对照 Linux v7.1 copy_process() 的“最后可失败准备 → tasklist 可见性提交 → 不可失败 wake_up_new_task()”,ax-runtime 将启动拆成可失败的 PreparedThread::stage() 与不可失败的 StagedThread::activate()
  • staged trampoline 通过原子 start gate 等待;事务失败或 token drop 会发布 Aborted 并让线程在消费 Starry/user entry 前退出、进入正常 switch-tail/reap;
  • Starry clone 在 publication mutex 外完成 scheduler placement,在 gate 关闭期间提交 PID namespace、cgroup、process relation、TASK_TABLE/PROCESS_TABLE,释放 publication mutex 后才 activate;dev 的 ProcessIdentity: Live -> Zombie -> Reaping -> Reaped 仍是唯一 identity authority;
  • 两份独立 ownership/drop-order 复核未发现半初始化暴露、generation rollback 或资源泄漏;ax-runtime 26/26、Starry 24/24 feature clippy、186-package sync-lint 与 x86_64 Starry axtest QEMU 387/387 通过。
  1. fix(starry-perf): separate control and IRQ output locks
  • 确定性 QEMU 红测从 PerfEventOps::enable 执行 scheduler yield,旧 SpinNoPreempt<Box<dyn PerfEventOps>> 使其稳定返回 unsafe-context,套件为 387 pass / 1 fail;
  • 对照 Linux v7.1 perf context/mmap mutex,generic perf ioctl、read、BPF attach 与 mmap control plane 改用 PiMutex,不再在禁抢占 raw gate 内分配页、构建 VM 或等待 PMU worker;
  • 软件 BPF 单独发布 BpfPerfOutput raw endpoint,IRQ/trace producer 只进入有界 ring write 与 IrqNotify publication;页分配、清零和 Arc 创建均在 raw gate 外;
  • concurrent mmap 在 raw state 内重新验证唯一映射,失败页在释放 gate 后回收;fd/VMA 的强弱引用与关闭后映射生命周期保持不变;
  • 同一红测修复后转绿;x86_64 Starry axtest QEMU 388/388、Starry 24/24 feature clippy、186-package sync-lint 通过。
  1. fix(starry-trace): publish callbacks outside raw locks
  • 确定性 x86_64 QEMU 红测在 tracepoint read callback 中执行真实 scheduler yield;旧 SpinNoPreempt<ExtTracePoint> 把任意 trace/perf/BPF callback 包在禁抢占 raw gate 内,套件稳定为 388 pass / 1 fail;
  • 对照 Linux v7.1 kernel/tracepoint.c:先发布完整 probe generation 再打开 fast-path gate,最终移除先关 gate,旧 probe array 通过 SRCU/RCU grace period 延迟释放;
  • workspace-local ktracepoint 将 callback list mutation 改为无全局副作用的值操作,以 Acquire/Release AtomicBool 作为 runtime gate,不再在 SMP 运行期间为 tracepoint patch executable text;dev 的 static-keys 与 dynamic-debug 初始化原样保留;
  • Starry writer 使用 PiMutex 构造 replacement,raw gate 只负责 Arc snapshot acquire/swap;两 epoch reader lease 覆盖 callback,最后读者仅发布 IRQ-safe sticky notify,task worker 负责最终回收;
  • 测试覆盖 callback 外 raw gate、read→update 重入、跨两 epoch 的三次连续更新和 gate publication;修复后 x86_64 QEMU 389/389、本地 crate test/example、Starry 24/24 feature clippy 与 187-package sync-lint 通过。
  1. fix(ax-task): service local wakes at scheduler safe points
  • 同 CPU、普通任务态 wake 在经过 blocking-context 校验后直接进入 owner runqueue;硬 IRQ、远程 CPU 和任意外层 guard 继续使用 generation-bearing lock-free inbox,避免把设备中断路径引入调度锁;
  • final task IRQ guard 在 IRQ 关闭状态下直接转换为 scheduler baton,本地硬 IRQ/任务态 publication 不再依赖 self-IPI;
  • 红测覆盖 direct wake、guarded fallback、wake-before-park 唯一通知,以及 hard IRQ 零分配/零 self-IPI 后的 owner drain;ax-task 全测试和 ax-task/ax-runtime feature clippy 通过。
  1. perf(ax-runtime): fold reschedule state into preemption guards
  • 参考 Linux v7.1 x86 __preempt_count,把普通 guard depth 与反向 need_resched bit 合并进 current-thread fast-path word;无调度请求的最终 guard 通过一次 CAS 直接退出,不再关闭 IRQ、解析 CPU-local handle;
  • scheduler baton 和 IRQ depth 仍由 CPU-local runtime state 独占,不随任务迁移;最终待调度 depth 只在 IRQ 关闭后转换为 baton,保持无可抢占窗口;
  • x86 架构叶子使用对本地中断不可分割、无 lock 前缀的 RMW,其他架构使用 portable atomic fallback;红绿测试覆盖嵌套、无 resched fast path、pending baton 和单 generation 消费;
  • x86 block 定向 QEMU 正式通过,当前 write 288588us、read 17853us;读路径较改造前改善,但 write 仍慢于 dev 约 191685us,因此该提交只作为性能审计检查点,剩余写路径回退继续用 qperf/调用链定位。
  1. fix(axbuild): test new ax-task without legacy features
  • 保留 ax-task 标准测试清单,但删除旧 axtask 的 host-test/multitask/preempt/lockdep profile;新核心使用默认 cargo test -p ax-task
  • runner 回归先稳定失败于旧映射,修复后 std-runner 16 项和 ax-task 全套测试通过。
  1. fix(ax-runtime): model pre-bootstrap host guards safely
  • cpu-local host register 在 CPU area 未安装时返回空 current-thread,而不是解引用零基址;
  • ax-runtime 仅在 host-test 下允许 bootstrap 前的 preemption guard 安全 no-op,生产构建继续严格拒绝缺失 current-thread;
  • axvm/host-testax-std/host-test 补齐 runtime 配置,原精确 SIGSEGV 用例和后续 IRQ sender 触发点均转绿,axvm 143 项 host-test 全部通过。
  1. fix(ax-task): make owner migration transactional
  • source rq detach 使用 move-only restore token 保留 Deadline、RT FIFO 与 Fair 的精确位置;placement 以单一 Queued -> Migrating 转换提交;
  • Deadline bandwidth/timer、target CPU 与 load summary 在 carrier 发布失败时一并恢复;migration delivery reservation 失败不再误判为成功;
  • 红测覆盖 detach 后遗失 rq/bandwidth、同优先级 RT FIFO 顺序和 publication activity gate 关闭;修复后 ax-task 208 个 unit、全部 integration/doc、20 个 loom 与 clippy 通过。
  1. test(ax-runtime): declare host guard lock dependency
  • host-test 单独 profile 现在显式声明 ax-kspin/host-test dev dependency,保持 bootstrap 前 SpinNoIrq 回归在与 CI 相同的 feature 闭包内可编译;
  • 修复前精确命令稳定报 unresolved ax_kspin,修复后 cargo test -p ax-runtime --features host-test 21/21、ax-runtime 26/26 feature clippy 通过。
  1. fix(ax-task): preserve EEVDF ordering across wrap
  • near-u64::MAX 红测先稳定复现两个 virtual deadline 被 saturating_add 压成同一值、随后按入队顺序选错任务;
  • 对照 Linux v7.1 vruntime_cmpentity_beforezero_vruntimesum_w_vruntimeavg_vruntime,owner fair rq 改为有符号环形比较和相对加权和;负值平均保持左偏,running entity 与 queued entities 参与同一 rebase;
  • placement、renew、yield、charge 和 policy reconfigure 使用统一的 wrapping timeline;AVL deadline key、minimum-vruntime augmentation、eligibility 与 fair pushable summary 使用同一模块化顺序;
  • 回归覆盖 near-MAX 反序、跨 wrap 加权虚拟时间、running entity、迁移重权与 published summary;修复后 ax-task 213 个 unit、全部 integration/doc、20 个 loom 及 clippy 通过。
  1. fix(ax-task): replenish CBS at the next release
  • D<P 红测先证明旧实现把 depleted CBS timer 设在当前 absolute deadline,R=2/D=5/P=10 会在 t=5 提前给出第二份预算;timer 延迟红测同时证明旧批量推进会把跳过的 period 预算累积到 3R;
  • 对照 Linux v7.1 dl_next_period()start_dl_timer()replenish_dl_entity(),普通 depletion 和 yield 都在 next release 触发;overrun debt 只推进到正预算,若所得 deadline 已落后于 now,则启动恰好一个 fresh job;
  • deadline/period 无法表示时保持 throttled,不以饱和值伪造可运行预算;GRUB 与手工 replenish 回归更新为同一 release contract;
  • 修复后 ax-task 215 个 unit、全部 integration/doc、20 个 loom 及 clippy 通过。
  1. fix(ax-task): enforce constrained deadline wake rules
  • 确定性红测证明 constrained D<P 线程在 absolute deadline 之后、next release 之前 wake 时,旧实现会提前发放新预算;revised-wakeup density 又错误使用 period 而不是 relative deadline;
  • 对照 Linux v7.1 dl_entity_overflow()update_dl_revised_wakeup()dl_check_constrained_dl():deadline 前超密度只削减 residual runtime,deadline 后保持 blocked 并把 clockevent 设为 next release;
  • Deadline wake 激活收敛到 TaskSystem 唯一 owner,RunQueue 只接收已激活实体;PI-boosted 锁持有者覆盖 throttle,避免非 Deadline base thread 因不存在 replenishment carrier 而永久阻塞;
  • 修复后 ax-task 217 个 unit、全部 integration/doc、20 个 loom 与 clippy 通过。
  1. fix(axvm): route timer cancellation to owner worker
  • rebase dev axvisor: virtualize AArch64 physical timer state #1770 时没有恢复旧的 hard-IRQ 任意 timer callback/全局 SpinNoIrq wheel;保留 CPU-affine task worker 和有界 wake 边界;
  • generation-unique token 在任务态路由到注册时 worker,跨 CPU cancel 与 Arm 进入同一 owner channel,worker 在 callback 前退休 route;
  • 冲突后的旧 API 编译红灯转绿;AxVM 123 个 unit、19 个 architecture-boundary、4 个 error-contract 测试与 6/6 feature clippy 通过。
  1. fix(starry-process): release address space before zombie wake
  • x86_64 full-system CI 红测稳定复现 fork 子进程退出并被 waitpid 观察后,父进程 munmap 最后一处 shared-writable memfd VMA,F_ADD_SEALS(F_SEAL_WRITE) 仍错误返回 EBUSY
  • 根因是 Starry 先发布 zombie 并唤醒 parent,随后才释放子进程 address-space slot,父进程可抢占回来与退出清理竞争;
  • 对照 Linux v7.1 do_exit()exit_mm() 先于 exit_notify(),Starry 现在先完成 SysV SHM 与地址空间资源回收,再发布稳定 zombie identity 和 wait/pidfd 通知;
  • 同一个 qemu/system/syscall-test-modern-fd-family 从 244/245 红灯转为 245/245,正式 grouped 成功标志通过;starry-kernel 24/24 feature/target clippy、fmt 和 diff check 通过。
  1. fix(starry-ptrace): deliver kill before releasing event stop
  1. perf(ax-task): reduce placement and guard overhead
  • 确定性红测观察到一次 yield_current 在 scheduler baton 内又进入 8 次完整 IRQ guard;scheduler 内部纯任务态 registry、runqueue、wait 与 kernel-thread 元数据改为 preemption-only ticket lock,IRQ publication 继续保留 IRQ-safe gate;
  • Fair 初始 placement 按允许 CPU 的 queued + running + in-flight migration workload 选取,避免所有新线程集中到创建 CPU;完整 ax-task(218 unit、全部 integration/doc、20 loom)及 ax-task/ax-runtime/ax-sync/ax-net clippy 通过。
  1. perf(ax-runtime): lazily defer later clockevent rearm
  • 确定性红测证明 task deadline 从 300 推迟到 400 时旧实现产生一次不必要的物理 Program(400)
  • 对齐 Linux v7.1 HRTIMER_MODE_LAZY_REARM:新期限更早时立即重编程,向未来移动时保留已武装的更早中断并在 firing transaction 中汇总最新逻辑期限;59 项 ax-runtime host 行为测试与 26 组 feature clippy 通过;
  • x86 AVX yield 定向用例功能 4/4 通过,但 workload 仍为 42 秒,说明 lazy rearm 只关闭硬件重编程浪费,尚未关闭 scheduler yield 通用尾部回退;后续继续对照 Linux do_sched_yield() 收窄 deadline service、balance 与 clockevent publication。
  1. perf(ax-runtime): make preemption state CPU-local
  • 普通 preemption depth 与本 CPU反向 need_resched 位从 task-owned CurrentThreadHeader 移入固定 CpuRuntimeAnchor,上下文切换不再搬运或重置 CPU guard 状态;
  • x86_64 通过 GS 直接读写 CPU-local preemption word,其他架构经固定 CPU base 访问;RISC-V 非 TLS 模式保留 trap handshake 所需的 current-header CPU-base 恢复;
  • 最终 FinalPending 本身即为调度请求观察,IRQ 关闭后原子转换为 scheduler baton,不再二次查询 CpuRemote/registry;
  • 两个确定性红测分别证明旧普通 guard 会读取 current-thread 两次、旧最终退出会重新查询 reschedule endpoint;修复后均为零次,并通过四架构 task-yield 与 x86_64 task-irq
  1. perf(starry-task): make CPU vtime owner-written
  • 对照 Linux v7.1 vtime_user_enter/exitvtime_task_switch_generictask_cputime,删除 Starry 跨 CPU SpinNoPreempt writer gate;只有运行线程的 owner CPU 在短 NoPreempt 区间写 task vtime,远端 scheduler-tick worker 通过奇偶 sequence 只读采样;
  • 每线程 user/system high-water mark 统一 owner transition 与远端 sample 的 process aggregate publication,避免重复计费;Starry 不再使用 accounting Retry
  • running base-policy 变更由 owner scheduler baton 下的有界 hook 记账;queued/inactive 线程不执行 owner hook,而由紧凑的 next-side ScheduleDecision 把 applied base policy 直接交给 switch-in,删除旁路 realtime_policy 原子并关闭 inactive-to-running 竞态;
  • 旧实现下 inactive policy apply 会错误触发 execution-owner hook(确定性红测 1 对 0);修复后 hook 不触发且首次 switch-in 获得同一 applied policy。为避免热路径对象膨胀,policy 只在 next-side handoff 保存一次,不复制到两个 endpoint。
  1. perf(ax-task): make wake and deadline service scheduler-driven
  • Starry futex WAKE/REQUEUE/WAKE_OP 只完成 wake publication,不再强制让 syscall 调用者 yield_now();调度器的 sticky need_resched 与 guard/IRQ exit 负责必要抢占,对齐 Linux v7.1 wake_q 的 producer/consumer 边界;
  • 两个确定性红测分别证明旧 futex wake 会产生一次额外调度、空 deadline safe point 会扫描一次 heap 并读取两次单调时钟;修复后 idle safe point 只采样一次时钟,只有 sticky pending 或 heap head 已到期才进入有界 expiry;
  • 公共 TaskSystem 入口保留 direct-core deadline service,facade 使用 typed AlreadyServiced 入口避免同一 safe point 二次扫描;timer batch 满载时先排空已提升事件,再进行一次到期 promotion,保证无需偶然下一次 IRQ 也能推进;
  • rebase 到 origin/dev 31f341abc 时保留 fix(cpu-local): guard uninstalled host CPU areas #1798 更完整的 host CPU-area guard,并保留本分支 pre-bootstrap guard 修复;CPU-local host 测试、ax-task 222 个 unit、全部 integration/doc、20 个 loom、相关 clippy 与 x86_64 Starry 391 项 axtest 通过。
  1. perf(ax-task): unify scheduler work and IPI ownership
  • 删除 ax-task 内第二套 scheduler IPI epoch/claim/ack 状态;ax-runtime 的 per-CPU SchedulerIpiDoorbell 成为唯一物理投递 owner,并在 IPI entry 先消费再执行共享 callback;
  • sticky scheduler work 与 idle polling 合并进一个原子状态字,producer 只在 inbox empty-to-nonempty 转换时响铃;普通 owner work 不再被无条件提升为 policy preemption;
  • bounded owner drain 留有下一批时显式重新武装 fresh physical edge,不依赖未来 tick;CPU offline 同时拒绝未消费的 core sticky work 和 runtime doorbell,禁止 hotplug 清除待处理状态;
  • 五个确定性红测覆盖 polling owner 多余 IPI、错误 preemption promotion、同 generation 重复 doorbell、batch remainder 无 fresh edge 与 offline 丢 sticky work;ax-task 222 个 unit、全部 integration/doc、20 个 loom,ax-runtime 62 个 host test、26/26 feature clippy,以及 x86_64 Starry 391/391 axtest 全部通过。
  1. perf(ax-task): separate forced yield from scheduler work
  • 对照 Linux v7.1 do_sched_yield() 与 fair/deadline class yield,forced yield 只提交当前 dispatch、消费本次选择覆盖的 preemption request、执行 class transition 并选取 successor,不再顺带 drain owner inbox 或运行 deadline/deferred work;
  • 删除旧 forced-yield deadline-entry 包装;相关 sticky work 保留给已经拥有投递边界的 timer IRQ、IPI 和通用 scheduler safe point;
  • CpuLocal 缓存最后一次发布的逻辑 task-deadline 状态,普通 switch tail 仅在 deadline 或 deferred-work 位变化时增加 generation 并调用 runtime;物理 clockevent commit 由 runtime 唯一、不可失败的所有权边界完成;
  • 两个确定性红测分别证明旧 yield 会消费无关 owner work、会重新发布不变 clockevent;修复后 ax-task 224 个 unit、全部 integration/doc、20 个 loom,ax-runtime 62 个 host test、两包 feature clippy 与 x86_64 Starry 391/391 axtest 通过;QEMU 阶段 13.72 秒,相对上一检查点 13.93 秒无回退。
  1. fix(ax-task): derive scheduler deadlines from owner state
  • 删除 CpuRemote::scheduler_deadline_ns 原子镜像;clockevent 直接从 owner 的 current dispatch、runqueue cached minimum、RT bandwidth 和 fair-balance 状态选择,任何 dequeue、policy、PI 或 migration 变化都不再等待额外 refresh;
  • due scheduler event 改为观察 owner state 并发布 sticky work,不再破坏性消费镜像;只有对应 owner 状态转换提交后事件才消失;
  • 确定性红测先证明移除唯一 fair contender 后旧镜像仍保留 1ms clockevent,修复后立即返回无期限;ax-task 225 个 unit、20 个 loom、ax-runtime 62 个 host test、两包 feature clippy 与 x86_64 Starry 391/391 axtest 通过,QEMU 阶段 13.61 秒。
  1. test(ax-runtime): compile preempt helpers in host tests
  • CI 的 ax-runtime host-test profile 单独编译时,回归测试仍调用只在 multitask feature 下编译的 enter_preempt/exit_preempt,因此在运行前报两个 E0425;
  • 保留测试本身并让这两个 CPU-local preemption helper 在 cfg(test) 下编译,不以 feature gate 跳过回归;原 CI 命令 cargo test -p ax-runtime --features host-test 由编译失败转为 24/24,通过 26/26 feature clippy。
  1. refactor(ax-task): isolate forced scheduler transitions
  • affinity、park、exit 不再借用通用 deadline safe point;无迁移 affinity 不读钟,park/exit 只处理自身 owner transition,已到期的无关 task deadline 留给真正 scheduler safe point;
  • TaskSystem::{commit_park, block_current, exit_current} 改为显式接收 owner timestamp,删除隐藏的第二状态转换时钟;exit 仍保留 selection 完成后的独立 clockevent 重采样,避免编程过期 one-shot;
  • 三个确定性红测在旧实现上分别观察到 affinity 2 次、notified park 3 次、exit 4 次读钟并消费无关 deadline;新实现为 0/1/2,且无关事件保持待处理;ax-task 228 个 unit + 20 个 loom、ax-runtime 62 个 host test、两包 clippy 与 x86_64 Starry 391/391 通过,QEMU 阶段 13.67 秒。
  1. fix(ax-task): make deadline cancellation transactional
  • park timeout 取消改为 move-only TaskDeadlineCancelTxn:deadline generation 更新失败时恢复同一 token、同一 heap entry 与 class capacity,不再返回半取消状态;
  • 明确区分 heap queued、IRQ buffered-expired 与真正 absent 三种所有权;buffered expiry 由 safe point 按 generation 淘汰,只有两处都缺失才是 invariant violation;
  • TaskRuntime::publish_task_deadline 改为类型上不可失败,物理 clockevent 的 local state 与硬件 commit 由 ax-runtime 在同一 IRQ-excluded transaction 中独占,删除测试专用的伪 recoverable failure;
  • 确定性红测先证明旧取消在 publication generation 耗尽时丢失 ticket/heap/core owner;修复后同一 registration 完整回滚。ax-task 228 unit + 20 loom、ax-runtime 62/62、ax-net 72/72、相关 feature clippy 与 x86_64 Starry 391/391 通过,QEMU 阶段 13.73 秒;范围外 ax-sync 并行 fixture 问题登记 test(ax-sync): isolate preemption state between parallel unit tests #1812
  1. fix(ax-task): reject task control from hard irq
  • 将 policy、affinity、current address-space replacement、deadline drain 和 initial switch-tail completion 收敛到同一 validate_task_context() authority;
  • 确定性红测证明旧 policy facade 可从 hard IRQ 进入 registry、root-domain admission、PI recompute 和 owner publication;修复后返回 UnsafeContext 且策略不变;
  • 删除无调用者的 try_thread_state() 及生产态 try-lock escape hatch;ax-task 229 个 unit、20 个 loom、ax-runtime 62/62 和两包 clippy 通过。
  1. fix(ax-task): split CPU placement from wake reachability
  • 对照 Linux v7.1 cpu_active/cpu_online 分层,将 CPU lifecycle 重构为 Online / Inactive / Draining / Offline:Inactive 关闭新 placement,但保留旧 generation-bearing wake route 的可达性;
  • blocked thread 的历史 target_cpu 不再被误判为物理 CPU ownership;CPU-down 只拒绝 queued/running/on-CPU/migrating、Deadline bandwidth 和 sleep timer 等真实 owner,并把 dormant wake route 事务式重定向到允许的 active CPU;
  • 低层红测先稳定得到 CpuNotQuiescent(1),修复后 CPU 1 成功 offline、wake 路由迁至 CPU 0 并通过真实 inbox drain 进入 Ready;publisher 测试证明在途旧 wake 阻止最终 draining;
  • ax-task 231 个 unit、全部 integration/doc、20 个 loom,ax-runtime 62/62、ax-task 1/1 和 ax-runtime 26/26 feature clippy 通过。
  1. fix(ax-task): make wake routing carrier-owned
  • stale-route 红测先让 wake 读取 CPU 1,随后完成 route 重定向与 CPU 1 offlining,再恢复同一次 wake;旧实现返回 Unavailable 并清除 sticky wake,修复后通过 CPU 0 carrier 投递并进入 Ready;
  • target_cpu 只保留 placement hint 语义;CpuWakeCarrier 从 inbox publication 到 doorbell 全程持有 lifecycle publisher lease,preferred endpoint 已关闭时在不可变 CPU capacity 内选择任一 scheduler-ready carrier;
  • carrier owner 消费 wake 后在 thread scheduler lock 下读取最新 placement 并转发,生产路径删除直接 cpu_local_for_wake() 与可绕过 lease 的 remote wake API;
  • 旧 Loom 仍是三态且只覆盖“已取得 publication 后 offline”的竞态;现改为四态并增加 stale-route fallback 模型。ax-task 232 个 unit、全部 integration/doc、21 个 loom,ax-runtime 62/62 和两包 feature clippy 通过。
  1. test(ax-task): isolate stale wake route regression
  • 将 CPU-down route 重定向与 stale snapshot wake 分成两个独立行为测试,测试名分别表达 placement cleanup 与事件不丢失不变量;
  • 共享 fixture 仍创建真实两 CPU blocked thread,未使用源码断言或放宽期望;两项定向测试均通过,unit 总数为 232。
  1. refactor(ax-task): isolate remote scheduler ownership
  • 对照 Linux v7.1 的 hotplug、rq->ttwu_pending/idle polling、balancing 与 task placement 分层,将 1,089 行 CpuRemote 平铺实现拆为 lifecycle publication、scheduler doorbell、owner snapshot、load summary、idle-pull 和 delivery 六个私有状态对象;根模块收敛为 46 行稳定组合入口;
  • 各状态只能通过命名方法跨协议协作,CPU offline、incoming migration 与 idle-pull quiescence 不再直接修改其他职责的原子字段;
  • 删除已失真的 Migration inbox 类名与 publish_policy_update/publish_migration 双入口,统一为 OwnerControlpublish_owner_control;只有真实 runqueue ownership transfer 继续使用 Migration message operation;
  • 该阶段保持原子序、队列和运行时行为不变。ax-task 232 个 unit、全部 integration/doc、hard-IRQ allocation contract 与 21 个 Loom model,ax-runtime 62/62 host multitask,以及 ax-task 1/1、ax-runtime 26/26 feature clippy 全部通过。
  1. refactor(ax-task): isolate owner runqueue state
  • 对照 Linux v7.1 struct rq 的 current/idle、CFS/RT/DL class、ttwu_pending 与 timing state 所有权,把平铺的 CpuLocal 拆为 OwnerDispatchStateDeadlineClassStateLocalTaskDeadlineStateOwnerDrainScratch 四个 owner-only 域;
  • 删除可修改整个 pinned CPU 对象的 fields_mut() 逃逸;balance、wake/control drain、Deadline admission、clockevent 与 switch-tail 只能取得所需状态域或调用命名的跨域事务;
  • migration_buffer 更名为真实语义的 owner_control_buffer,并保留 scheduler/IRQ 热路径的零额外引用计数:runtime accounting、clockevent selection、deadline expiry 与 fair balance 直接投影 owner-local 字段;
  • 该阶段保持调度行为不变。ax-task 232 个 unit、全部 integration/doc、hard-IRQ allocation contract 与 21 个 Loom model,ax-runtime 62/62 host multitask,以及 ax-task 1/1、ax-runtime 26/26 feature clippy 全部通过。
  1. refactor(ax-task): separate per-thread scheduler state
  • 对照 Linux v7.1 task_struct 内 sched entity、physical placement、PI 与 memory ownership 的分域方式,把 34 个平铺的 ThreadSchedState 字段收敛为 lifecycle、policy、placement、Deadline、PI、runtime 六个所有权域;
  • 删除 base_policyactive_base_policypolicy 三者含义依赖上下文的旧字段,显式命名为 requested、owner-applied、PI-effective policy/entity 及各自 generation;线程创建统一通过一个构造事务初始化所有域;
  • CPU affinity 和 affinity generation 纳入 placement domain;底层 SchedulerPlacement 变为该域私有的唯一物理状态机,没有增加 queued/running/on_cpu 镜像缓存;
  • 该阶段保持调度行为不变。ax-task 232 个 unit、全部 integration/doc、hard-IRQ allocation contract 与 21 个 Loom model,ax-runtime 62/62 host multitask,以及 ax-task 1/1、ax-runtime 26/26 feature clippy 全部通过。
  1. fix(ax-task): avoid registry scans for exited work
  • 对照 Linux v7.1 exit_notify() 的显式 dead-list 与 release_task() 锁外 teardown,把 exit callback/reap 从“扫描全部 registry slot”改为 generation-bearing ExitedThreadWork candidate;
  • candidate storage 在线程 slot 创建阶段预留;普通退出和 switch-tail 只做 O(1) publication 且不分配,busy zombie 轮转到队尾,显式 reap 按 generation 删除后才允许 slot 复用;
  • 确定性红测在 32 个无关活线程前回收一个 zombie:旧实现访问 33 个记录,新实现只访问 1 个;另有测试证明全部 slot 同时退出不会扩容;
  • ax-task 234 个 unit、全部 integration/doc、hard-IRQ allocation contract 与 21 个 Loom model,ax-runtime 62/62 host multitask,以及 ax-task 1/1、ax-runtime 26/26 feature clippy 全部通过。
  1. refactor(ax-task): type deferred callback claims
  • ThreadRecord 的 exit pending/claimed 与 Deadline claimed 三个并行 bool 收敛为 ThreadCallbackState
  • exit 只允许 Absent -> Pending -> Claimed -> Absent;无 callback 保持 Absent;Deadline claim 必须恰好 finish 一次;
  • reap 通过 typed state 查询 callback ownership,不再重建非法 bool 组合;保持 registry lock 与锁外 callback 边界不变;
  • ax-task 237 个 unit、全部 integration/doc、hard-IRQ allocation contract 与 21 个 Loom model,ax-runtime 62/62 host multitask,以及 ax-task 1/1 feature clippy 全部通过。
  1. fix(ax-task): publish deadline callbacks without registry scans
  • 对照 Linux v7.1 task_work/irq_work 的显式 work identity,删除每派发一个 Deadline overrun callback 就扫描全部 registry slot 的旧 cursor;
  • 确定性红测把唯一 pending 线程放在 32 个无关 live record 后:旧实现访问 33 个 record,新实现只精确 claim 1 个;
  • 没有采用需要 scheduler 获取全局 registry lock 的预分配队列;每个 ThreadCore 嵌入独立 task-work node,producer 只转移一个 retained core reference 并 lock-free publish,事件数在 per-thread state 中 coalesce;
  • 第二个确定性 race 在第一个 callback 已 claim 且阻塞时发布新 overrun,验证 fresh physical delivery 恰好再执行一次;callback 继续只在任务态、registry/scheduler lock 外运行;
  • ax-task 240 个 unit、全部 integration/doc、hard-IRQ/零分配 contract 与 21 个 Loom model,ax-runtime 62/62 host multitask,以及 ax-task clippy 1/1 全部通过。
  1. fix(cpu-local): select preemption ownership by architecture
  • AArch64 Starry CI 通过 GDB 定位到 CPU1 framebuffer worker 在 WaitQueue::wait_once_inner() 退出时触发 unbalanced CPU-local preemption guard exit;根因是把 x86 的 per-CPU __preempt_count 存储方式机械推广到所有架构,使任务迁移后继承前一任务的普通 guard depth;
  • 对照 Linux v7.1:x86 继续使用 GS per-CPU fast word,AArch64/RISC-V/LoongArch 改由 current-thread header 持有普通 preemption depth;scheduler baton 与 IRQ owner 始终属于 CPU;
  • current-thread publication 增加对齐和 CPU binding 验证,切换提交保持 CPU anchor publication 与架构寄存器 tail 两阶段边界;
  • 确定性红测证明旧实现中 task B 继承 task A depth,新实现中 B 为 0 且恢复 A 后 depth 为 1;错误 current publication 由错误 Ok(0x1) 改为 typed mismatch;cpu-local 全部 unit/integration/doc tests、3/3 clippy、ax-runtime 26/26 clippy 和 AArch64 Starry test-sched-family 37/37 通过。
  1. docs(ax-task): document RT ownership model in Chinese
  • 将 scheduler、deadline/clockevent 与 Starry PID/zombie 三份设计材料统一改为中文,保留 Linux v7.1 对应符号、确定性证据和未关闭 finding;
  • 明确四架构只统一调度语义和安全不变量,不强制统一物理 current/preempt 存储;
  • 将硬中断可见对象建模为独立 endpoint 生命周期 Unpublished -> Published -> Draining -> Dead:IRQ 只访问有界私有状态,经固定队列/IrqWaitCell 发布,外部锁与完整 OS 对象只在线程上下文持有;
  • 当前 IrqWaitCell 在无法证明 notifier quiescent 时会安全泄漏 storage,后续需先补确定性 revoke/drop 红测,再实现显式 draining/grace/reclaim 状态机。
  1. fix(ax-task): separate IRQ registration drain lifetime
  • 确定性红测在旧 unregister 的 generation load 与 pointer CAS 之间暂停:IRQ 完成旧 generation,同一 node 地址重新发布新 generation;恢复旧 detach 后会删除新 waiter,并在取消旧 generation 时 panic;
  • 根因是 Detached 同时表示“IRQ reader 已结束”和“允许同地址复用”,而旧 Loom 只建模 registration 原子,没有把 cell pointer ABA 纳入状态空间;
  • registration 改为 Detached -> Attached -> Notifying -> Draining -> Detached。IRQ direct wake 完成只进入 Draining,任务侧 move-only IrqWaitToken::detach() 转换为 IrqWaitDrain,只有 try_finish() 完成 grace 后才开放复用;
  • quiesce_irq_wait 不再接受可传错的 cell 参数;硬 IRQ 保持有界 CAS、零等待、零分配/析构,所有真实调用点均在无外部锁的任务上下文完成 quiesce;
  • 对照 Linux v7.1 disable_irq_nosyncsynchronize_hardirqirq_work_sync 的“先关 admission,再等在途 reader,最后释放”边界;显式遗忘 token 仍以泄漏而非 UAF 失效;
  • 同一红测与 pointer+generation Loom 转绿;ax-task 242 个 unit、全部 integration/doc、21 个 Loom,ax-runtime host multitask、ax-net 72、axvm 180 通过;ax-task 1/1、ax-runtime 26/26、ax-net 3/3、axvm 6/6、Starry 25/25 feature clippy 通过。
  1. fix(axbuild): preserve qperf kernel build contracts
  • 两个确定性红测分别复现 qperf 追加 CARGO_ENCODED_RUSTFLAGS 遮蔽 target inline linker script,以及 --qemu-arg -cpu 被 argparse 误当选项的回归;
  • qperf 现在经 axbuild 通用 append_encoded_rustflags 合并 debuginfo/frame-pointer 标志,并以 --qemu-arg=<value> 传递连字号开头的 QEMU 参数;
  • 同一红测转绿,cargo xtask clippy --package axbuild 通过;frame-pointer 模式进一步暴露 qperf plugin 在 guest 早期启动栈上 unwind 导致 host QEMU SIGSEGV,这是归因边界而非 guest scheduler panic。
  1. test(starry): add Linux RT futex wake benchmark
  • 新增同源 futex ping-pong 基准,Linux v7.1 PREEMPT_RT 与 Starry 均使用 q35 TCG、-cpu max、2 CPU、512 MiB、CPU0/CPU1 affinity、200 次预热与 7 组 2000 次交接;
  • Linux RT 中位数为 13,908 ns,Starry 为 221,878 ns,Starry 约慢 15.95 倍,证明现实现未达 Linux RT 级别;
  • 基准 app 显式加入 apps/.ignore,避免扩大通用 app CI;中文审计文档记录环境、数据和当前归因;
  • 路径审计已确认每次 FUTEX_WAIT 创建 LocalExecutorWaitQueueArc<WaiterState> 和 wake Vec<Waker>,下一阶段以线程自有等待节点和解锁后批量唤醒替换该架构。
  1. refactor(starry-futex): park directly on scheduler threads
  • 新增 move-only PreparedCurrentPark,让 OS waiter 在自己的队列锁内完成条件检查与 publication,同时由 ax-task 独占 park generation、task deadline 和上下文切换事务;Starry futex 不再为每次 wait 创建临时 LocalExecutorWaitQueue、coroutine 和 waker;
  • 值不匹配时 waiter 分配计数红测在旧实现稳定失败,新实现先检查条件再创建 WaiterState;re-park 准备失败时旧实现遗留已入队 waiter,新增错误注入回归在修复前为 392/393、修复后为 393/393;
  • wake/requeue 在 PI queue lock 内只选择 waiter 并取得 generation-bearing ThreadWakeHandle,释放锁后才进入 scheduler wake;signal、timeout 与 notify 通过同一 park generation 决定唯一结果;
  • 同源 futex ping-pong 中位数从 221,878 ns 降到 138,786 ns,改善约 37.4%,但仍约为 Linux RT 13,908 ns 的 9.98 倍;后续继续消除 Arc<WaiterState>、wake Vec 和按 key 动态 entry,不把该阶段误报为性能达标。
  1. refactor(starry-futex): embed generation wait state in threads
  • 将每次排队单独分配的 Arc<WaiterState> 收敛为稳定 Thread 内嵌的 generation 状态机;队列保存 UserTaskRef + generation,由同一状态源裁决 wake、signal、timeout、cancel 和 requeue,旧 generation 不能命中新一轮等待;
  • 新增零状态分配红测:旧实现 x86_64 axtest 为 393/394,新实现为 394/394;park prepare 错误注入改为直接验证事务清理回调,不依赖 axtest 内核线程伪装成 Starry 用户任务;
  • 25/25 Starry clippy feature/target 组合通过;同源 futex ping-pong 中位数从 138,786 ns 降到 111,948 ns,再改善约 19.3%,但仍约为 Linux RT 的 8.05 倍;下一阶段继续用稳定 mm/shared key、固定 hash bucket 和无堆分配 wake batch 替换 HashMap/FutexEntry/Vec
  1. fix(starry-timer): isolate alarm worker wake transport
  • 完整 x86_64 QEMU 顺序测试在普通用例结束后随机停滞;GDB 证明一个 CPU 永久自旋于 no_std event-listener fallback spinlock,调用链来自 Starry alarm_task,其余 CPU已进入 idle;
  • 旧实现把可抢占内核线程、计时器堆快照和第三方 async waker 绑在同一个内部 raw lock 生命周期中,既不满足 PREEMPT_RT 的睡眠等待边界,也可能在持锁唤醒时递归;
  • alarm worker 改为线程态 WaitQueue + AtomicU64 epoch:producer 在 alarm heap 锁外 publish epoch 并唤醒,worker 先观察 generation、再做 heap snapshot,通过带谓词的 timed wait 关闭 snapshot-vs-publish 丢唤醒窗口;
  • 确定性模型覆盖 publish 落在 queue snapshot 期间的竞争;rebase 后 cargo xtask clippy --package starry-kernel 25/25 通过;完整 x86_64 system 已越过原全局停滞并完成 398 个 common case;随后停在 USB audio,作为相同 event-listener 驱动外围边界单独登记 bug(starry-usb): replace no_std event-listener wake transport #1838,本 PR 不越界修改;
  • 同次本分支/dev 逐项比较按正回退差值排序,当前下一目标是 ext4 inode unique(110s vs 57s,+53s);dev 只用于选择优化顺序,根因、调用链和目标架构继续以 Linux v7.1 PREEMPT_RT 为准。
  1. refactor(axbuild): make grouped case execution explicit
  • qperf 可直接选择正式 Starry QEMU case,复用同一 build/QEMU/rootfs/二进制资产,并按当前 ostool 模型为 x86_64 显式补齐 q35
  • grouped case 执行所有权类型化为 GuestInit / ShellCommand / External,Starry、Axvisor 与 qperf 各自只有一条入口;删除旧 profile autorun 字段和脚本,不保留双启动兼容;
  • 确定性红测复现 qperf 注入 runner 后 init 抢跑 workload;同一测试及实际 QEMU 证明 External 只注入目标二进制,性能窗口前不再启动正式 runner;
  • axbuild 831/831、package clippy、fmt 与 diff check 通过。
  1. perf(ax-task): measure remote wake delivery
  • feature-gated 指标精确记录 remote wake publication/head transition/drain/lifecycle activation/owner enqueue、物理 scheduler IPI、clockevent IRQ 与 context switch;默认构建零开销,debugfs 仅在任务态格式化;
  • x86_64 4-vCPU 正式 test-ext4-inode-unique 的 30.6237922 秒窗口中,48,657 个 remote wake 全部 drain,41,648 次 activation 与 owner enqueue 一一相等,38,251 次 IPI send/consume 一一相等,排除永久 lost wake;
  • 物理 IPI 占 remote publication 的 78.6%,证明 owner inbox/safe-point 是结构性放大;对照 Linux v7.1 PREEMPT_RT 的 TTWU_QUEUE=false,下一阶段直接改为 target raw-rq-lock activate,仅实际抢占时发 reschedule IPI;
  • ax-task 258 个 unit、全部 integration/doc 与 21 个 Loom model、相关 qperf feature clippy、fmt 与 diff check 通过。
  1. refactor(ax-task): activate wakeups under target runqueue lock
  • 只借鉴 Linux v7.1 PREEMPT_RT 当前活跃的 try_to_wake_up() -> ttwu_do_activate() 路径:waker 在 thread scheduler-state 锁下确定目标,再在目标 CPU 的 IRQ-safe runqueue 锁内完成生命周期激活、物理入队、当前任务抢占判断与 load-summary 发布;
  • 删除旧 RemoteWake inbox、线程内嵌 wake node、owner drain batch、旧指标名及对应兼容入口;不引入非 RT TTWU_QUEUE wake-list feature fallback,也不保留历史 API 别名;
  • 低优先级远程 wake 只入队不发 IPI;只有目标 runqueue 判断需要抢占时才发布 sticky reschedule 并发送一次跨 CPU scheduler IPI;同 CPU hard-IRQ wake 只发布本地 sticky 状态;
  • balance 与 pick-next 不再在持有 runqueue 锁时反向获取 thread scheduler-state 锁,迁移候选采用 scan、sched-state、runqueue revalidate 的固定锁序;CPU offline 失败不会清除并发新 waker 的 publication;
  • qperf 指标改为 direct_wake_attempts / activations / enqueues / preemptions,旧 remote-wake 数字只作为已删除架构的历史基线;
  • cargo test -p ax-task --features qperf-metrics 全部通过;cargo xtask clippy --package ax-task 2/2、ax-runtime 27/27、starry-kernel 26/26 通过;fmt 与 diff check 通过。

该边界对应 Linux 的 task-work/irq-work 所有权逻辑,但不照搬对象布局:固定 task-work consumer 只读取 generation-bearing target vtime 快照并发布 high-water delta,不再成为 target task writer;真正的 task vtime 写入始终由执行 owner 和 scheduler baton 串行化。

确定性红绿证据

  • 旧 hard-IRQ callback 在三次 timer IRQ 中执行了三次 OS work;新测试要求 IRQ 中为零,并在一次 deferred callback 中收到最新时间戳。
  • 旧 CPU accounting sequence 只保护 reader,不能排除第二个 writer;早期 x86_64 axtest 修复前为 384 pass / 1 fail。随后 read-only tick 红测又证明 writer gate 仍保留了错误所有权;inactive policy 回归进一步稳定观察到非 owner hook 被调用一次。
  • 未实现 retry ownership 时,第二次有界 worker pass 为 0;实现后恰好重投递一次。
  • 未限制 same-pass retry 时,64 项 batch 会连续调用 64 次;修复后每个 pass 恰好一次且 pending 保持。
  • coalesced timestamp Loom 模型在旧普通-load 快路径下稳定找到“旧时间戳且无后续 publication”的反例;同一个模型在同值 RMW 修复后转绿。
  • 新测试覆盖 retry-vs-new-tick、disable epoch、carrier exit;loom 覆盖 retry 与新 IRQ 的单一 delivery owner及 coalesced timestamp 的 publish-before-claim。
  • clone start-gate 测试在旧语义下会在 activation 前观察到 entry 执行;两阶段 gate 修复后,activate 才允许 entry,drop staged token 则完成 scheduler exit/reap 且不消费 entry。
  • perf control callback 红测在旧 raw lock 下不能 yield;改为 PI control mutex 并拆出 IRQ output endpoint 后,同一真实调度行为测试通过。
  • tracepoint callback 红测在旧 registry raw gate 下不能 yield;snapshot/epoch publication 后同一测试通过,旧 callback allocation 由 task reclaimer 延迟释放。

2026-08-03 EEVDF 最新进展

  • 对照 Linux v7.1 PLACE_DEADLINE_INITIALsysctl_sched_base_slice,Fair 默认基础 request 从 1 ms 调整为 700 us;初始实体只获得半 request,sleep 后和后续 request 使用完整 slice。
  • 新增确定性红绿测试,覆盖本地初始放置与直接迁移到远端 owner 的初始放置;非法 Active/Migrating wake activation 不再走兼容兜底,而是返回类型化配置错误。
  • cargo test -p ax-task(257 个 unit、全部 integration/doc、21 个 Loom 模型)、cargo xtask clippy --package ax-task、fmt 与 diff check 通过。
  • x86_64 test-ext4-inode-unique 在 guest 约 45 秒完成 786/2048,投影仍约 118 秒,明显慢于用于选题的 dev 57 秒,因此按约定主动终止;总墙钟 92.98 秒包含约 23 秒重编译及启动,不声明该 QEMU case 通过。
  • 该结果说明最新 EEVDF 初始放置是必要的正确性修复,但并非主性能瓶颈。下一步按 Linux v7.1 PREEMPT_RT 的 TTWU_QUEUE=false 模型,验证“直接锁目标 runqueue 激活、仅需要抢占时发送 reschedule IPI”,不恢复旧 wakeup granularity 或其他兼容路径。

当前验证

  • 当前 head CI 已启动,尚无 terminal 结论。上一 head 的正式失败是 ArceOS x86_64 run_host 在 NVMe block endpoint 注册后、测试套件开始前超时 120 秒,其余后续 job 被 fail-fast 取消;该启动期 deferred worker/timer/IRQ 链路将在本 head 上继续复现,cancelled job 不作为通过或失败证据。
  • ArceOS task-yield:x86_64、AArch64、RISC-V、LoongArch64 全部通过;x86_64 task-irq 通过。
  • x86_64 Starry qemu/system/syscall-test-modern-fd-family:245/245,正式 STARRY_GROUPED_TESTS_PASSED;覆盖 fork/exit/wait 后 memfd shared-writable VMA 计数已在 parent 可见前释放。
  • cargo test -p cpu-local --features host-test:全部 unit/integration/doc tests 通过;旧 thread-owned preempt 集成测试已由 fixed-anchor 状态机与 runtime 行为测试取代。
  • x86_64 Starry qemu/block-io-bench:1/1,正式 STARRY_GROUPED_TESTS_PASSED;write 288588us、read 17853us。
  • cargo test -p ax-task --lib:243/243。
  • cargo test -p ax-runtime --no-default-features --features host-test,multitask:62/62。
  • cargo test -p ax-runtime --features host-test:24/24。
  • cargo test -p ax-runtime --features host-test,multitask,fs --lib:52/52。
  • cargo xtask clippy --package ax-task:1/1。
  • cargo xtask clippy --package ax-runtime:26/26 feature 组合。
  • axbuild qperf 两个构建/参数回归测试与 cargo xtask clippy --package axbuild:通过。
  • x86_64 同源 futex ping-pong:Linux v7.1 PREEMPT_RT 中位数 13,908 ns;Starry 从 221,878 ns 先降到 138,786 ns,再降到 111,948 ns;线程内嵌 generation 阶段再改善约 19.3%,当前仍约慢 8.05 倍;基准均通过正式成功标志。
  • cargo test -p cpu-local --features host-test:全部 unit/integration/doc tests 通过。
  • cargo test -p axvm --features host-test --lib:143/143。
  • cargo xtask clippy --package cpu-local:3/3;axbuild:1/1;axvm:6/6。
  • cargo test -p ax-sync --features multitask --lib -- --test-threads=1:27/27;默认并行测试的全局 preemption fixture 隔离问题已登记 test(ax-sync): isolate preemption state between parallel unit tests #1812,本轮不越界修改。
  • cargo test -p ax-net:72 个 unit test 通过。
  • cargo xtask clippy --package ax-sync:3/3 feature 组合。
  • cargo xtask clippy --package ax-net:3/3 feature 组合。
  • cargo test -p ktracepoint --lib:1/1;带 linker section 的 host example 实际运行并输出 cooked/raw callback。
  • cargo xtask clippy --package ktracepoint:1/1。
  • cargo xtask clippy --package starry-kernel:25/25 feature/target 组合。
  • cargo xtask ktest qemu --package starry-kernel --arch x86_64:394/394,AXTEST_SUITE_OK
  • cargo xtask sync-lint:187/187 workspace packages。
  • cargo fmt --all --checkgit diff --check:通过。

较早里程碑已完成四架构 ArceOS/Starry QEMU、scheduler placement、deadline/IPI/idle、PI/park/IRQ waiter、perf/PID/zombie、UART/vsock/USB 定向回归。本轮 owner-only vtime、futex wake 与 deadline safe-point 已重复运行 x86_64 全部 391 项 axtest;四架构 full-system 留到下一个核心里程碑统一运行。

兼容性与后续

Closes #1833

@ZR233
ZR233 force-pushed the codex/refactor-ax-task-from-1596 branch 2 times, most recently from 10ccb6d to 4236924 Compare July 30, 2026 02:13
@ZR233
ZR233 force-pushed the codex/refactor-ax-task-from-1596 branch 5 times, most recently from e927578 to 295087c Compare July 30, 2026 16:15
@ZR233
ZR233 force-pushed the codex/refactor-ax-task-from-1596 branch from 56056c6 to 60d6971 Compare July 31, 2026 03:25
Comment thread components/ax-task/src/scheduler/queue.rs
Comment thread components/ax-task/src/system/task_system/balance.rs Outdated
Comment thread components/ax-task/src/scheduler/fair.rs Outdated
Comment thread components/ax-task/src/thread/policy.rs Outdated
Comment thread components/ax-task/Cargo.toml
Comment thread virtualization/axvm/Cargo.toml
@ZR233
ZR233 force-pushed the codex/refactor-ax-task-from-1596 branch 2 times, most recently from d06e408 to 4dc2b44 Compare July 31, 2026 06:33
@ZR233
ZR233 force-pushed the codex/refactor-ax-task-from-1596 branch from 8998618 to 6282d90 Compare July 31, 2026 08:25
@ZR233
ZR233 force-pushed the codex/refactor-ax-task-from-1596 branch 2 times, most recently from b3d54af to 111ad4f Compare July 31, 2026 12:08
@ZR233
ZR233 force-pushed the codex/refactor-ax-task-from-1596 branch 2 times, most recently from 3758658 to b492d23 Compare August 3, 2026 02:42
@ZR233
ZR233 force-pushed the codex/refactor-ax-task-from-1596 branch from 2c7c43f to 0fe14b3 Compare August 3, 2026 09:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Development

Successfully merging this pull request may close these issues.

彻底完成任务调度与运行时重构

1 participant