Skip to content

feat(mm): add page reclaim for file-backed memory pressure (rebased)#1007

Merged
ZR233 merged 6 commits into
rcore-os:devfrom
seek-hope:feat/page-reclaim-v3
Jun 1, 2026
Merged

feat(mm): add page reclaim for file-backed memory pressure (rebased)#1007
ZR233 merged 6 commits into
rcore-os:devfrom
seek-hope:feat/page-reclaim-v3

Conversation

@seek-hope

@seek-hope seek-hope commented May 28, 2026

Copy link
Copy Markdown
Contributor

Summary

Add a physical-page reclaim path: when the allocator cannot satisfy a page request, it invokes a registered callback to evict clean file-backed page cache pages, then retries the allocation. This prevents OOM during memory-intensive workloads like cargo build inside StarryOS.

1. might_sleep() removal from try_lock()

Remove might_sleep() from both try_lock_plain() and try_lock_nested(). try_lock is a single atomic CAS that never blocks or sleeps (equivalent to Linux mutex_trylock). The reclaim path runs with IRQs disabled (inside the allocator spinlock), so try_lock() must be usable there.

2. Page cache eviction + global file registry

  • GLOBAL_CACHED_FILES registry: every file with a page cache is registered via register_cached_file()
  • page_cache_reclaim(): walks all files, evicting clean (non-dirty) pages. Uses try_lock throughout to avoid deadlock.
  • Reentrancy guard via RECLAIM_IN_PROGRESS AtomicBool
  • Per-file 64-page LRU with try_evict_clean_pages()
  • evict_listeners uses spin::Mutex (no might_sleep) for safety from atomic context

3. Allocator reclaim API + init hook

  • register_page_reclaim_fn() / try_page_reclaim() API in axalloc
  • SpinNoIrq guard released before callback invocation
  • Register page_cache_reclaim as the allocator callback during kernel init

Review fixes (2026-05-31)

  • Dangling PTE (87c05db): eviction listeners now return bool — if any listener cannot confirm unmap (e.g., AddrSpace lock contention), the page is re-inserted into cache instead of being freed
  • Two-phase eviction (733add3): try_evict_clean_pages() now releases page_cache lock before invoking listeners, eliminating the deadlock risk

Rebase notes

Rebased onto upstream/dev (2026-05-28), incorporating PR #987 (ax-alloc refactor: TLSF/buddy-slab backend simplification).

Supersedes: PR #804

Note: The fine-grained ext4 locking changes (InodeCache/DataBlockCache/BitmapCache internal spin::Mutex + VFS ax_sync::Mutex) have been split into PR #1057.

Files changed (7)

  • os/arceos/modules/axsync/src/mutex.rs
  • os/arceos/modules/axfs-ng/src/highlevel/file.rs
  • os/arceos/modules/axalloc/src/lib.rs
  • os/arceos/modules/axalloc/src/buddy_slab.rs
  • os/StarryOS/kernel/src/entry.rs
  • os/StarryOS/kernel/src/mm/aspace/backend/file.rs

Test plan

  • cargo check -p ax-alloc -p ax-sync -p ax-fs-ng -p starry-kernel: PASS
  • cargo clippy -p ax-alloc -p ax-sync -p ax-fs-ng: PASS
  • cargo test -p rsext4 --lib: 71/71 PASS
  • cargo test -p rsext4 --test crc_integrity: 16/16 PASS
  • rustfmt --edition 2024 --check: PASS

🤖 Generated with Claude Code

When the page allocator cannot satisfy a request, invoke a registered
callback to evict clean file-backed page cache pages, then retry the
allocation (up to 4 times). This prevents OOM during memory-intensive
workloads like cargo build inside StarryOS.

Changes:
- axsync/src/mutex.rs: remove might_sleep() from try_lock_plain()
  and try_lock_nested() — try_lock is a single CAS, never blocks
- axfs-ng/src/highlevel/file.rs: GLOBAL_CACHED_FILES registry,
  page_cache_reclaim() with per-file 64-page LRU eviction,
  RECLAIM_IN_PROGRESS reentrancy guard, evict_listeners for
  address-space unmapping callbacks
- axalloc/src/lib.rs: register_page_reclaim_fn() / try_page_reclaim()
  API with SpinNoIrq guard released before callback invocation
- axalloc/src/buddy_slab.rs: reclaim-then-retry loop in alloc_pages()
  (max 4 retries, reclaims max(16, num_pages) * 2 clean pages)
- starry-kernel/src/entry.rs: register ax_fs::page_cache_reclaim
  as the page reclaim callback at kernel init

Rebased onto upstream/dev (2026-05-28) incorporating PR rcore-os#987
(ax-alloc refactor: TLSF/buddy-slab backend simplification).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings May 28, 2026 07:42

Copilot AI 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.

Pull request overview

Note

Copilot was unable to run its full agentic suite in this review.

This PR introduces an allocator-triggered page-reclaim mechanism backed by file page-cache eviction, and refactors parts of the cached file I/O path. It also changes mutex wakeup semantics and guard sendability.

Changes:

  • Add a reclaim callback API in axalloc, invoke it on page-allocation failures, and register a filesystem-backed reclaim hook from kernel init.
  • Implement global page-cache reclaim by scanning cached files and evicting clean pages, plus refactor cached file read/write to share page-iteration logic.
  • Adjust RawMutex semantics around lockdep subclassing, wakeup handoff, and guard marker traits.

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 16 comments.

Show a summary per file
File Description
os/arceos/modules/axsync/src/mutex.rs Changes mutex guard marker, lockdep subclass handling, and unlock wakeup/handoff logic
os/arceos/modules/axfs-ng/src/highlevel/file.rs Adds page-cache reclaim + refactors cached I/O; modifies open/flag semantics and file-position initialization
os/arceos/modules/axalloc/src/lib.rs Adds reclaim callback registration and invocation API
os/arceos/modules/axalloc/src/buddy_slab.rs Retries page allocations after invoking reclaim callback
os/StarryOS/kernel/src/entry.rs Registers filesystem reclaim callback during kernel init

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread os/arceos/modules/axsync/src/mutex.rs Outdated
Comment thread os/arceos/modules/axsync/src/mutex.rs Outdated
Comment thread os/arceos/modules/axsync/src/mutex.rs
Comment thread os/arceos/modules/axsync/src/mutex.rs Outdated
Comment thread os/arceos/modules/axsync/src/mutex.rs Outdated
Comment thread os/arceos/modules/axfs-ng/src/highlevel/file.rs Outdated
Comment thread os/arceos/modules/axfs-ng/src/highlevel/file.rs
Comment thread os/arceos/modules/axfs-ng/src/highlevel/file.rs
Comment on lines +418 to +421
fn try_evict_clean_pages(&self, max: usize) -> usize {
let Some(mut cache) = self.page_cache.try_lock() else {
return 0;
};
Comment on lines +431 to +437
for &pn in to_evict[..cnt].iter() {
if let Some(page) = cache.pop(&pn) {
for listener in self.evict_listeners.lock().iter() {
(listener.listener)(pn, &page);
}
}
}
CI Test and others added 2 commits May 28, 2026 15:56
- file.rs: restore upstream/dev baseline with all 11 bug fixes, then
  re-apply only the reclaim-specific additions (GLOBAL_CACHED_FILES,
  page_cache_reclaim, try_evict_clean_pages, RECLAIM_IN_PROGRESS,
  register_cached_file, is_new tracking). The original rebase was
  based on an old snapshot that lost upstream bug fixes.
- mutex.rs: revert GuardMarker from GuardSend to GuardNoSend
  (MutexGuard must not cross thread boundaries)
- mutex.rs: restore cfg-gated LockSubclass type alias for lockdep
  safety, use ax_lockdep::DEFAULT_LOCK_SUBCLASS in lock/try_lock calls

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

@mai-team-app mai-team-app Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

PR 审核总结

变更内容

本 PR 为物理页分配器增加了 page reclaim 路径:当页面分配失败时,调用注册的回调函数回收 file-backed page cache 中的 clean 页面,然后重试分配。这解决了 StarryOS 中 cargo build 等内存密集型工作负载导致 OOM 的问题。

共 5 个文件,3 个提交:

  1. 15f02b4 — 核心 page reclaim 功能
  2. 9f516db — 修复 Copilot 审查发现的问题(GuardNoSend、LockSubclass cfg-gating、to_flags/is_valid 恢复 Linux 兼容语义)
  3. 6fd0bea — 补充 doc comment

代码分析

Mutex handoff 语义(mutex.rs)unlock() 改用 notify_one_with 直接将 ownership 交给被唤醒的等待者。关键:当等待队列为空时,notify_one_with 回调传入 0owner_id.swap(0, Ordering::Release) 正确清除 owner_id——Copilot 此前关于 "owner_id 不会被清除" 的评论不成立(参见 axtask/src/wait_queue.rs:202func(0) 分支)。try_lock 移除 might_sleep() 合理,因为 try_lock 是单次原子 CAS 永不阻塞。

Page reclaim 架构(file.rs)

  • RECLAIM_IN_PROGRESS AtomicBool 防止重入
  • page_cache_reclaim() 使用 GLOBAL_CACHED_FILES.try_read() 避免阻塞
  • try_evict_clean_pages() 使用 page_cache.try_lock() 避免死锁
  • 锁序正确:page_cacheevict_listeners,且文档明确声明 listener 不得反向获取 page_cache
  • 正确排除 tmpfs 文件(无 backing store,evict 会丢数据)

分配器集成(lib.rs + buddy_slab.rs)

  • try_page_reclaim() 在调用回调前释放 SpinNoIrq 守卫,使回调在中断启用环境下运行
  • 重试循环 4 次,reclaimed == 0 时提前退出——合理
  • buddy_slab.rs 中 dealloc 调整了 usages/inner 锁顺序(先更新 usage 再释放内存),影响极小

Copilot 审查意见处理:第二个提交 9f516db 已修复 Copilot 提出的全部关键问题:恢复 GuardNoSend、恢复 cfg-gated LockSubclassDEFAULT_LOCK_SUBCLASS、恢复 to_flags 的 Linux 兼容映射、恢复 is_valid 的 RDONLY|TRUNC 允许逻辑、恢复 saturating_addwrite_all

本地验证

  • cargo fmt --check: ✅ PASS
  • cargo clippy --manifest-path os/arceos/modules/axalloc/Cargo.toml --features buddy-slab: ✅ PASS
  • cargo clippy --manifest-path os/arceos/modules/axfs-ng/Cargo.toml: ✅ PASS
  • cargo clippy --manifest-path os/arceos/modules/axsync/Cargo.toml: ✅ PASS
  • Head SHA 6fd0bea0a 与 PR 一致

CI 状态

所有 GitHub Actions checks 显示 conclusion: skipped。这是因为 PR 来自 fork,CI 可能未完全触发。CI 失败非本 PR 导致。

重叠分析

  • PR #804(同一作者的 v2 版本)已关闭未合并,本 PR 明确 supersede #804
  • 在 dev 分支上未发现与 page reclaim 冲突的 open PR

已知限制

  • 本 PR 未添加 reclaim 路径的专用测试用例。考虑到这是系统级内存管理特性,需要 QEMU + 实际内存压力环境才能有效测试,当前以 cargo build 在 StarryOS 中不 OOM 作为验证标准可接受
  • to_evict 数组硬编码 256 限制,实际场景足够

结论

实现设计合理,Copilot 审查意见已修复,代码质量好,可合并。

Powered by mimo-v2.5-pro

@mai-team-app
mai-team-app Bot requested review from ZR233 and shilei-massclouds May 28, 2026 12:43

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

本轮重点看了 allocator reclaim -> ax-fs-ng page cache -> Starry file-backed mapping listener 这一条路径的锁序和页面生命周期。

ax-sync::RawMutex 这部分我没有看到空等待队列导致 owner 卡死的问题:WaitQueue::notify_one_with() 在空队列时会调用 func(0),当前 unlock() 会把 owner_id 置回 0;handoff 给 waiter 的路径也能让等待者通过 is_owner(current_id) 返回。try_lock 去掉 might_sleep() 本身也符合非阻塞 CAS 的语义。

但 reclaim 路径有一个阻塞问题:try_evict_clean_pages() 在弹出 clean page 后立即调用 listener,之后让 PageCache drop 释放物理页。Starry 的 file mapping listener 在拿不到 AddrSpace 锁时会直接返回;这在 populate 内部 eviction 有后续 callback 兜底,但 allocator reclaim 没有对应的延期 unmap/保活机制。因此锁竞争时可能释放仍被用户页表映射的物理页,留下悬空 PTE。这个问题和死锁规避策略直接相关,需要先修复再合并。

本地验证:

  • cargo fmt --check:通过
  • cargo xtask clippy --package ax-alloc:4/4 通过
  • cargo xtask clippy --package ax-fs-ng:7/7 通过
  • cargo xtask clippy --package ax-sync:3/3 通过
  • cargo xtask clippy --package starry-kernel:13/13 通过

CI 状态:PR 当前 run_container/相关检查为 success,host/self-hosted 中部分 skipped;没有看到由本 PR 触发的 CI 失败。

重叠检查:origin/dev 上没有同等的 page reclaim API / page_cache_reclaim 实现;#804 已关闭且被本 PR supersede;#881 依赖本 PR 的能力但不重复实现;#997 release PR 可能后续有版本同步冲突风险,但不是同一语义实现。

}
for &pn in to_evict[..cnt].iter() {
if let Some(page) = cache.pop(&pn) {
for listener in self.evict_listeners.lock().iter() {

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.

这里不能在 page_cache 锁内直接调用 eviction listener 并随后让 page drop。当前 Starry 的 listener 在 FileBackendInner::register_listener() 中会先 aspace.try_lock(),拿不到地址空间锁时直接返回;这在普通 page_or_insert() eviction 里还能由 populate callback 延后处理,但 reclaim 路径没有保存 (pn, page) 也没有重试/回滚,函数返回后 clean page 的物理页会被释放,用户页表里可能仍然保留指向该物理页的 PTE。也就是说,这个“避免死锁”的 try_lock 分支会把死锁风险转成悬空映射/use-after-free。

建议把 reclaim 改成两阶段:在持有 page_cache 时只挑选并移出候选页,释放 page_cache 后调用 listener;并且 listener/回调需要能反馈是否完成了所有映射失效。若任何 listener 因锁竞争无法完成 unmap,就不能 drop 该 page(要放回 cache,或像 populate 的 PopulateCallback 一样延后到持有 AddrSpace 时再释放)。

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.

复核 cb849d4b1 后,这个问题仍然存在。新提交把 try_evict_clean_pages() 的返回值改成实际 pop 的数量,并补了 TODO,但当前代码仍然在 page_cache 锁内调用 listener,Starry 侧 listener 在 aspace.try_lock() 失败时仍然直接返回;reclaim 路径随后会 drop page 释放物理页,没有 PopulateCallback 那样的保活/延后 unmap 机制。

这里需要先让 reclaim eviction 能确认所有相关映射已经失效;如果 listener 因锁竞争或错误无法完成 unmap,就不能释放这个 page,需要放回 cache 或保留到后续能在持有 AddrSpace 时安全 unmap。

seek-hope pushed a commit to seek-hope/tgoskits that referenced this pull request May 29, 2026
…tion

Merge the two separate self-compilation docs (PR rcore-os#881 riscv64-only and
PR rcore-os#973 riscv64+x86_64) into one unified document covering:

- Architecture status table (riscv64 ✅, x86_64 ✅, aarch64 pending)
- 5 shared blocking points (memory, tmpfs, linker, regex, workspace)
- 6 x86_64-specific blocking points (PCI BAR, QEMU lock, ext4 compat
  bug series, SMP deadlock, init.sh POSIX, rustc MSRV, USB UVC)
- 2 riscv64-specific blocking points (bitmap overflow obsoleted by
  PR rcore-os#987, dynamic RAM detection)
- Script orchestration (prepare/compile/run/filter)
- Test configuration (selfhost-manual/ out of CI path)
- Known limitations and environment requirements

Updated to reflect current state:
- PR rcore-os#987 removed page-alloc-* features (bitmap overflow no longer exists)
- PR rcore-os#1007 replaces rcore-os#804 for page reclaim
- PR rcore-os#971 provides rsext4 cache (4 entries)
- selfhost-manual/ directory structure (not normal/)

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
…d correctness

- buddy_slab: restore consistent lock order (inner then usages) in dealloc
  and dealloc_pages to match alloc_pages, preventing future ABBA deadlock
- buddy_slab: document reclaim target scaling limitation for large
  contiguous allocations
- file.rs: return actual evicted page count instead of scan count in
  try_evict_clean_pages; add TODO for lock-nesting removal
- mutex.rs: document that unlock handoff depends on notify_one_with
  always calling the callback (including for empty queues with id=0)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

@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 cb849d4b1 后,上一轮指出的 reclaim eviction 生命周期问题仍然是阻塞项。

本 PR 的主线仍然是:在 axalloc 中注册 page reclaim callback,页面分配失败时回收 ax-fs-ng file-backed page cache,并在 Starry init 时接入该回调;ax-sync::RawMutex 侧的 try_lock 非阻塞语义和 notify_one_with handoff 这部分我没有看到新的阻塞问题。新提交主要补了 buddy_slab 锁序说明、把 try_evict_clean_pages() 返回值改成实际 evicted 数量,并补了 TODO,但没有改变 reclaim 路径的页面释放时机。

阻塞问题仍在 try_evict_clean_pages():它从 page_cachepop clean page 后立即调用 listener,之后让 page drop 释放物理页。Starry 的 file mapping listener 在拿不到 AddrSpace 锁时会直接返回;普通 page_or_insert() eviction 有 PopulateCallback 保活并延后 unmap,但 allocator reclaim 没有等价机制。因此锁竞争时仍可能释放还被用户页表映射的 frame,留下悬空 PTE / use-after-free。已在原有 inline thread 里补充当前 head 的复核结论,保留该线程未解决。

建议修复方向:reclaim eviction 需要能确认所有相关映射已经失效后才释放 page。可以改成两阶段回收,并让 listener/回调返回是否完成 unmap;若任何 listener 因锁竞争无法完成,需要把 page 放回 cache,或像 populate callback 一样保留到后续持有 AddrSpace 时再释放。

本地验证:

  • cargo fmt --check:通过
  • cargo xtask clippy --package ax-alloc --package ax-fs-ng --package ax-sync --package starry-kernel:27/27 通过

CI 状态:当前 gh pr checks 中没有看到失败项;多项 run_container 检查已通过或 skipped,但 Run clippy / run_containerTest starry x86_64 qemu / run_containerTest starry riscv64 qemu / run_containerTest starry aarch64 qemu / run_container 在复核时仍为 pending,因此远端 CI 尚未完整结束。

重复/重叠检查:origin/dev 上未发现同等的 register_page_reclaim_fn / try_page_reclaim / page_cache_reclaim / GLOBAL_CACHED_FILES 实现;#804 已关闭且由本 PR supersede;#881 依赖 #1007 提供的能力但不重复实现;#997 是 release 同步 PR,可能有后续版本同步冲突风险,但不是同一语义实现。

旧 review threads 处理:已将 GuardNoSend、LockSubclass、open flags、读写路径等已经修复或过时的 14 个线程标记 resolved;保留 page-cache listener / reclaim 生命周期相关线程未解决。

@ZR233
ZR233 requested a review from luodeb May 30, 2026 03:01
When the reclaim path evicts a clean page and the listener cannot
acquire the AddrSpace lock (try_lock contention), the page was
previously dropped immediately — freeing the physical frame while
PTEs still referenced it, creating a use-after-free.

Fix: change EvictListenerFn to return bool. Listeners return false
when they cannot complete the unmap. try_evict_clean_pages puts
the page back into the LRU cache instead of dropping it. The page
survives until the next reclaim attempt when the lock is available.

The LRU-eviction path (evict_cache, called during page_or_insert)
ignores the return value because the populate process that triggers
it holds AddrSpace and handles unmap via PopulateCallback.

Fixes the blocking review finding from ZR233 on PR rcore-os#1007.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

@mai-team-app mai-team-app Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

PR 审核总结

变更内容

本 PR 为物理页分配器增加 page reclaim 路径:当页面分配失败时,调用注册的回调函数回收 file-backed page cache 中的 clean 页面,然后重试分配(最多 4 次),防止 StarryOS 中 cargo build 等内存密集型工作负载导致 OOM。

共 5 个提交,6 个文件:

  1. 15f02b4 — 核心 page reclaim 功能
  2. 9f516db — 修复 Copilot 审查发现的问题(GuardNoSend、LockSubclass cfg-gating、to_flags/is_valid 恢复 Linux 兼容语义)
  3. 6fd0bea — 补充 init_percpu_slab doc comment
  4. cb849d4 — buddy_slab 锁序修正、try_evict 返回实际 evict 数量、mutex unlock handoff 文档
  5. 87c05db修复 reclaim eviction 悬挂 PTE 问题(ZR233 阻塞项)

实现逻辑

Mutex handoff 语义(mutex.rs)unlock() 改用 notify_one_with 直接将 ownership 交给被唤醒的等待者。空队列时 notify_one_with 回调传入 0owner_id.swap(0, Release) 正确清除 owner_id。try_lock 移除 might_sleep() 合理——try_lock 是单次原子 CAS 永不阻塞,可在 allocator reclaim 路径的中断禁用上下文中使用。

Page reclaim 架构(file.rs)

  • RECLAIM_IN_PROGRESS AtomicBool 防止重入
  • page_cache_reclaim() 使用 GLOBAL_CACHED_FILES.try_read() 避免阻塞
  • try_evict_clean_pages() 使用 page_cache.try_lock() 避免死锁
  • 正确排除 tmpfs 文件(无 backing store,evict 会丢数据)
  • EvictListener 改为返回 bool:listener 返回 false 时,page 放回 LRU cache 而非 drop,避免释放仍被用户页表映射的物理帧

Dangling PTE 修复(file.rs + backend/file.rs)

  • EvictListenerFn 签名改为 Fn(u32, &PageCache) -> bool
  • Starry 的 file mapping listener 在 AddrSpace::try_lock() 竞争失败时返回 false
  • try_evict_clean_pages() 在任一 listener 返回 false 时将 page 放回 cache
  • LRU-eviction 路径(evict_cache)忽略返回值——populate 进程持有 AddrSpace,通过 PopulateCallback 处理 unmap
  • 此修复正确解决了 ZR233 提出的阻塞问题

分配器集成(lib.rs + buddy_slab.rs)

  • try_page_reclaim() 调用回调前释放 SpinNoIrq 守卫,使回调在中断启用环境下运行
  • 重试循环 4 次,reclaimed == 0 时提前退出——合理
  • buddy_slab.rs 修正了 dealloc/dealloc_pages 的锁序(inner → usages),与 alloc_pages 一致

本地验证

  • cargo fmt --check:✅ 通过
  • cargo xtask clippy --package ax-alloc --package ax-fs-ng --package ax-sync --package starry-kernel:27/27 通过
  • Head SHA 87c05db77 与 PR 最新一致

CI 状态

PR 当前 mergeable_state=blocked。远端 CI 部分检查已通过或 skipped;由 fork 提交的 PR 可能未完全触发 CI。当前环境未发现由本 PR 导致的 CI 失败。

重叠分析

  • PR #804(同一作者的 v2 版本)已关闭未合并,本 PR 明确 supersede #804
  • origin/dev 上未发现与 register_page_reclaim_fn / page_cache_reclaim / GLOBAL_CACHED_FILES 冲突的实现
  • 在 dev 分支上未发现与 page reclaim 冲突的 open PR(#1040 xattr、#1039 qperf 均不相关)
  • #881 依赖本 PR 的能力但不重复实现;#997 release PR 可能后续有版本同步冲突风险,但不是同一语义实现

测试覆盖

本 PR 未添加专用测试用例。鉴于这是系统级内存管理特性,需要 QEMU + 实际内存压力环境才能有效测试,当前以 cargo build 在 StarryOS 中不 OOM 作为验证标准可接受。PR 中也未新增 apps 测试,无需执行 Starry QEMU 验证。

已解决的审查问题

  • Copilot 审查意见(GuardNoSend、LockSubclass、to_flags、is_valid、saturating_add、write_all)已在提交 2 中修复,相关 inline thread 位于 outdated diff
  • ZR233 阻塞项(dangling PTE)已在提交 5 中修复:EvictListener 返回 false 时 page 放回 cache,不再释放仍被映射的物理帧

已知限制与后续工作

  • to_evict 数组硬编码 256 限制,实际场景足够
  • try_evict_clean_pagespage_cacheevict_listeners 的锁嵌套有潜在死锁风险(TODO 已标注),未来可重构为先收集 evicted pages 再通知 listeners
  • 未添加 reclaim 路径的集成测试,建议后续补充 QEMU 内存压力测试

结论

实现设计合理,ZR233 的 dangling PTE 阻塞问题已在最新提交中正确修复,Copilot 审查意见已处理,代码质量好,可合并。

Powered by mimo-v2.5-pro

@mai-team-app mai-team-app Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

PR 审核总结

变更内容

本 PR 为物理页分配器增加 page reclaim 路径:当页面分配失败时,调用注册的回调函数回收 file-backed page cache 中的 clean 页面,然后重试分配(最多 4 次),防止 StarryOS 中 cargo build 等内存密集型工作负载导致 OOM。

共 5 个提交,6 个文件:

  1. 15f02b4 — 核心 page reclaim 功能
  2. 9f516db — 修复 Copilot 审查发现的问题(GuardNoSend、LockSubclass cfg-gating、to_flags/is_valid 恢复 Linux 兼容语义)
  3. 6fd0bea — 补充 init_percpu_slab doc comment
  4. cb849d4 — buddy_slab 锁序修正、try_evict 返回实际 evict 数量、mutex unlock handoff 文档
  5. 87c05db修复 reclaim eviction 悬挂 PTE 问题(ZR233 阻塞项)

实现逻辑

Mutex handoff 语义(mutex.rs)unlock() 改用 notify_one_with 直接将 ownership 交给被唤醒的等待者。验证了 axtask/src/wait_queue.rs:193notify_one_with 实现:空队列时确实调用 func(0)owner_id.swap(0, Release) 正确清除 owner_id。try_lock 移除 might_sleep() 合理——try_lock 是单次原子 CAS 永不阻塞,可在 allocator reclaim 路径的中断禁用上下文中使用。

Page reclaim 架构(file.rs)

  • RECLAIM_IN_PROGRESS AtomicBool 防止重入
  • page_cache_reclaim() 使用 GLOBAL_CACHED_FILES.try_read() 避免阻塞
  • try_evict_clean_pages() 使用 page_cache.try_lock() 避免死锁
  • 正确排除 tmpfs 文件(无 backing store,evict 会丢数据)
  • EvictListener 改为返回 bool:listener 返回 false 时,page 放回 LRU cache 而非 drop,避免释放仍被用户页表映射的物理帧

Dangling PTE 修复(file.rs + backend/file.rs)

  • EvictListenerFn 签名改为 Fn(u32, &PageCache) -> bool
  • Starry 的 file mapping listener 在 AddrSpace::try_lock() 竞争失败时返回 false
  • try_evict_clean_pages() 在任一 listener 返回 false 时将 page 放回 cache(MRU 位置,延迟重试)
  • LRU-eviction 路径(evict_cache)忽略返回值——populate 进程持有 AddrSpace,通过 PopulateCallback 处理 unmap
  • 此修复正确解决了 ZR233 提出的阻塞问题

分配器集成(lib.rs + buddy_slab.rs)

  • try_page_reclaim() 调用回调前释放 SpinNoIrq 守卫,使回调在中断启用环境下运行
  • 重试循环 4 次,reclaimed == 0 时提前退出——合理
  • buddy_slab.rs 修正了 alloc_pages/alloc_pages_lowmem 之后 dealloc/dealloc_pages 的锁序(inner → usages),与 alloc_pages 一致

本地验证

  • cargo fmt --check:✅ 通过
  • cargo clippy --manifest-path os/arceos/modules/axalloc/Cargo.toml --features buddy-slab:✅ 通过
  • cargo clippy --manifest-path os/arceos/modules/axsync/Cargo.toml:✅ 通过
  • cargo clippy --manifest-path os/arceos/modules/axfs-ng/Cargo.toml:✅ 通过
  • cargo xtask clippy --package ax-alloc --package ax-fs-ng --package ax-sync --package starry-kernel:27/27 通过
  • Head SHA 87c05db77 与 PR 最新一致

CI 状态

PR 当前 mergeable_state=blocked。远端 CI 部分检查已通过或 skipped;由 fork 提交的 PR 可能未完全触发 CI。当前未发现由本 PR 导致的 CI 失败。

重叠分析

  • PR #804(同一作者的 v2 版本)已关闭未合并,本 PR 明确 supersede #804
  • origin/dev 上未发现 register_page_reclaim_fn / page_cache_reclaim / GLOBAL_CACHED_FILES 的等价实现
  • PR #881(self-compilation)依赖本 PR 的能力但不重复实现,属于 partial-overlap(互补依赖关系)
  • #1040(xattr)、#1039(qperf)均不相关
  • 无冲突风险的 open PR

测试覆盖

本 PR 未添加专用测试用例。鉴于这是系统级内存管理特性,需要 QEMU + 实际内存压力环境才能有效测试,当前以 cargo build 在 StarryOS 中不 OOM 作为验证标准可接受。PR 中也未新增 apps 测试,无需执行 Starry QEMU app 验证。

已解决的审查问题

  • Copilot 审查意见(GuardNoSend、LockSubclass、to_flags、is_valid、saturating_add、write_all)已在提交 2 和 4 中修复
  • ZR233 阻塞项(dangling PTE)已在提交 5 中正确修复:EvictListener 返回 false 时 page 放回 cache,不再释放仍被映射的物理帧

已知限制与后续工作(非阻塞)

  • to_evict 数组硬编码 256 限制,实际场景足够
  • try_evict_clean_pagespage_cacheevict_listeners 的锁嵌套有潜在死锁风险(TODO 已标注),未来可重构为先收集 evicted pages 再通知 listeners
  • 未添加 reclaim 路径的集成测试,建议后续补充 QEMU 内存压力测试
  • GLOBAL_CACHED_FILES 向量随文件打开增长,但 register_cached_file 已做 dead-ref 清理

结论

实现设计合理,锁序正确,ZR233 的 dangling PTE 阻塞问题已在最新提交中正确修复,Copilot 审查意见已处理,代码质量好,无阻塞问题,可合并。

Powered by mimo-v2.5-pro

…oking listeners

Calling eviction listeners while holding the page_cache lock creates a
deadlock risk: if any listener tries to acquire page_cache (directly or
indirectly), the lock ordering violation causes a deadlock.

This restructures try_evict_clean_pages() into two phases:
1. Under page_cache lock: identify and pop clean pages into a local Vec
2. Outside page_cache lock: invoke listeners; pages whose listeners
   cannot confirm unmap (e.g., AddrSpace lock contention) are re-inserted
   into the cache to prevent use-after-free of physical frames with
   still-live PTEs.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@seek-hope
seek-hope force-pushed the feat/page-reclaim-v3 branch from 5461a3a to 733add3 Compare May 31, 2026 03:40
@ZR233
ZR233 merged commit 6fce64b into rcore-os:dev Jun 1, 2026
102 checks passed

@mai-team-app mai-team-app Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

PR 审核总结(合并后复核)

变更内容

本 PR 为物理页分配器增加 page reclaim 路径:当页面分配失败时,调用注册的回调函数回收 file-backed page cache 中的 clean 页面,然后重试分配(最多 4 次),防止 StarryOS 中 cargo build 等内存密集型工作负载导致 OOM。

共 6 个提交,6 个文件(+260/-66):

  1. 15f02b4 — 核心 page reclaim 功能
  2. 9f516db — 修复 Copilot 审查发现的问题
  3. 6fd0bea — 补充 init_percpu_slab doc comment
  4. cb849d4 — buddy_slab 锁序修正、try_evict 返回实际 evict 数量
  5. 87c05db — 修复 reclaim eviction 悬挂 PTE 问题
  6. 733add3 — 两阶段 eviction:释放 page_cache 锁后再调用 listeners

实现逻辑分析

Mutex handoff 语义(mutex.rs)unlock() 改用 notify_one_with 直接将 ownership 交给被唤醒的等待者。验证了 axtask/src/wait_queue.rsnotify_one_with 实现:空队列时确实调用 func(0)owner_id.swap(0, Release) 正确清除 owner_id。try_lock 移除 might_sleep() 合理——try_lock 是单次原子 CAS 永不阻塞,可在 allocator reclaim 路径的中断禁用上下文中使用。注释中也明确了对 notify_one_with 行为契约的依赖。

Page reclaim 架构(file.rs)

  • RECLAIM_IN_PROGRESS AtomicBool 防止重入,使用 RAII ReclaimGuard 确保异常退出时也清除标志
  • page_cache_reclaim() 使用 GLOBAL_CACHED_FILES.try_read() 避免阻塞
  • try_evict_clean_pages() 使用 page_cache.try_lock() 避免死锁
  • 正确排除 tmpfs 文件(无 backing store,evict 会丢数据)
  • 两阶段 eviction:Phase 1 在 page_cache 锁下收集 clean pages 到本地 Vec,Phase 2 在锁外调用 listeners。这消除了之前 page_cacheevict_listeners 锁嵌套的潜在死锁风险
  • EvictListener 返回 bool:listener 返回 false 时,page 放回 LRU cache 而非 drop,避免释放仍被用户页表映射的物理帧

Dangling PTE 修复(file.rs + backend/file.rs)

  • Starry 的 file mapping listener 在 AddrSpace::try_lock() 竞争失败时返回 false
  • try_evict_clean_pages() 在任一 listener 返回 false 时将 page 放回 cache
  • LRU-eviction 路径(evict_cache)忽略返回值——populate 进程持有 AddrSpace,通过 PopulateCallback 处理 unmap
  • 注释清楚解释了两条路径的不同行为

分配器集成(lib.rs + buddy_slab.rs)

  • try_page_reclaim() 调用回调前释放 SpinNoIrq 守卫,使回调在中断启用环境下运行
  • 重试循环 4 次,reclaimed == 0 时提前退出——合理
  • buddy_slab.rs 修正了 dealloc/dealloc_pages 的锁序(inner → usages),与 alloc_pages 一致,并添加了锁序说明注释

本地验证

  • cargo fmt --check:✅ 通过
  • cargo xtask clippy --package ax-alloc --package ax-fs-ng --package ax-sync --package starry-kernel:27/27 通过
  • Head SHA 733add3ab 与 PR 最新一致

CI 状态

PR 当前已合并(merge commit 6fce64bc6)。CI 检查大部分为 skipped,因为 PR 来自 fork,CI 未完全触发。未发现由本 PR 导致的 CI 失败。

重叠分析

  • PR #804(同一作者的 v2 版本)已关闭未合并,本 PR 明确 supersede #804
  • origin/dev 上未发现 register_page_reclaim_fn / page_cache_reclaim / GLOBAL_CACHED_FILES 的等价实现
  • PR #881 依赖本 PR 的能力但不重复实现,属于 partial-overlap(互补依赖关系)
  • 无冲突风险的 open PR

测试覆盖

本 PR 未添加专用测试用例,也未新增 apps 测试。鉴于这是系统级内存管理特性,需要 QEMU + 实际内存压力环境才能有效测试,当前以 cargo build 在 StarryOS 中不 OOM 作为验证标准可接受。无需执行 Starry QEMU apps 验证。

已解决的审查问题

  • Copilot 审查意见(GuardNoSend、LockSubclass、to_flags、is_valid、saturating_add、write_all)已在后续提交中修复。最终 PR head 保留了原始 read_at/write_at_locked 实现,未引入 Copilot 标记的回归
  • ZR233 阻塞项(dangling PTE)已在提交 5 中正确修复:EvictListener 返回 false 时 page 放回 cache
  • ZR233 最终在 87c05db 后批准,随后补充了两阶段 eviction(733add3)进一步消除死锁风险

已知限制与后续工作(非阻塞)

  • to_evict 数组硬编码 256 限制,实际场景足够
  • 未添加 reclaim 路径的集成测试,建议后续补充 QEMU 内存压力测试
  • GLOBAL_CACHED_FILES 向量随文件打开增长,但 register_cached_file 已做 dead-ref 清理

结论

实现设计合理,锁序正确,两阶段 eviction 消除了死锁风险,dangling PTE 问题已正确修复。代码质量好,已合并。

Powered by mimo-v2.5-pro

This was referenced Jun 1, 2026
seek-hope pushed a commit to seek-hope/tgoskits that referenced this pull request Jun 3, 2026
…tion

Merge the two separate self-compilation docs (PR rcore-os#881 riscv64-only and
PR rcore-os#973 riscv64+x86_64) into one unified document covering:

- Architecture status table (riscv64 ✅, x86_64 ✅, aarch64 pending)
- 5 shared blocking points (memory, tmpfs, linker, regex, workspace)
- 6 x86_64-specific blocking points (PCI BAR, QEMU lock, ext4 compat
  bug series, SMP deadlock, init.sh POSIX, rustc MSRV, USB UVC)
- 2 riscv64-specific blocking points (bitmap overflow obsoleted by
  PR rcore-os#987, dynamic RAM detection)
- Script orchestration (prepare/compile/run/filter)
- Test configuration (selfhost-manual/ out of CI path)
- Known limitations and environment requirements

Updated to reflect current state:
- PR rcore-os#987 removed page-alloc-* features (bitmap overflow no longer exists)
- PR rcore-os#1007 replaces rcore-os#804 for page reclaim
- PR rcore-os#971 provides rsext4 cache (4 entries)
- selfhost-manual/ directory structure (not normal/)

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
seek-hope pushed a commit to seek-hope/tgoskits that referenced this pull request Jun 3, 2026
…tion

Merge the two separate self-compilation docs (PR rcore-os#881 riscv64-only and
PR rcore-os#973 riscv64+x86_64) into one unified document covering:

- Architecture status table (riscv64 ✅, x86_64 ✅, aarch64 pending)
- 5 shared blocking points (memory, tmpfs, linker, regex, workspace)
- 6 x86_64-specific blocking points (PCI BAR, QEMU lock, ext4 compat
  bug series, SMP deadlock, init.sh POSIX, rustc MSRV, USB UVC)
- 2 riscv64-specific blocking points (bitmap overflow obsoleted by
  PR rcore-os#987, dynamic RAM detection)
- Script orchestration (prepare/compile/run/filter)
- Test configuration (selfhost-manual/ out of CI path)
- Known limitations and environment requirements

Updated to reflect current state:
- PR rcore-os#987 removed page-alloc-* features (bitmap overflow no longer exists)
- PR rcore-os#1007 replaces rcore-os#804 for page reclaim
- PR rcore-os#971 provides rsext4 cache (4 entries)
- selfhost-manual/ directory structure (not normal/)

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@github-actions github-actions Bot mentioned this pull request Jun 3, 2026
ZR233 pushed a commit that referenced this pull request Jun 3, 2026
* docs(starry): rebase self-compilation PR onto current upstream/dev

Rebuild PR #881 on current upstream/dev (8f95b7a) after significant
dependency changes:
- PR #987 removed page-alloc-* features; drop obsolete page-alloc-64g
  passthrough and axalloc Cargo.toml injection
- PR #992 added .tracepoint/.kallsyms sections; use sed-based injection
  in test scripts instead of cat-overwrite to preserve these sections
- fsopen/fspick/open_tree ENOSYS fix already present on upstream/dev
- phys-memory-size = 0x2_0000_0000 already present on upstream/dev

Changes:
- ext_linker.ld: add PROVIDE(_ex_table_start/end = 0) for self-compile
  environments where linker.x is not passed via rustflags
- scripts/self-compile.sh: host-side automation (cleaned of dead code)
- docs/starryos-self-compilation.md: updated for post-PR #987 architecture
- test-suit/starryos/normal/qemu-selfhost/: test group with inner
  self-compile.sh (sed-based linker fix, preserves existing sections)

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

* fix(starry): add missing driver features and env vars to selfhost build config

- Add ax-driver/pci, ax-driver/virtio-blk, ax-driver/virtio-net and other
  virtio driver features to qemu-selfhost build config, matching the standard
  qemu-smp1 build config. Without these the seed kernel cannot access the
  Debian rootfs via virtio-blk-pci.
- Add AX_IP/AX_GW env vars for network stack initialization.
- Remove dead INJECT_SCRIPT variable from scripts/self-compile.sh.
- Add --features to test-suit inner cargo build for feature parity.
- Fix test-selfhost-check to actually detect missing tools (was always
  passing CHECK_DONE due to || true).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

* fix(test): remove stale ax-driver/pci feature and fix success_regex escape

Two fixes for CI failures:

1. Remove `ax-driver/pci` from build config features — this umbrella feature
   was removed from upstream/dev by PR #937 (refactor(driver): move static
   probes to platform-owned registration). PCI dependencies are now always
   available; individual device features handle their own chains.

2. Fix success_regex TOML literal string — single-quoted TOML strings do not
   process backslash escapes, so '\\s' was interpreted as literal \\s by the
   regex engine instead of \s (whitespace class). Changed to double-quoted
   TOML string "\\s" to produce the correct regex pattern.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

* fix(test): move selfhost tests out of normal/ CI path to selfhost-manual/

The qemu-selfhost test group had a build-riscv64gc-unknown-none-elf.toml
in test-suit/starryos/normal/, which caused the CI test runner to
discover and attempt to run these tests. The selfhost tests require a
12 GB Debian rootfs image that is not available in CI (not published to
the tgosimages release), causing "HTTP 404 Not Found" on rootfs download
and blocking ALL starry riscv64 tests.

Moved test infrastructure to test-suit/starryos/selfhost-manual/,
outside the normal/ directory that CI scans. Updated documentation
to reflect the new path and manual test invocation.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

* docs(starry): consolidate riscv64 + x86_64 self-compilation documentation

Merge the two separate self-compilation docs (PR #881 riscv64-only and
PR #973 riscv64+x86_64) into one unified document covering:

- Architecture status table (riscv64 ✅, x86_64 ✅, aarch64 pending)
- 5 shared blocking points (memory, tmpfs, linker, regex, workspace)
- 6 x86_64-specific blocking points (PCI BAR, QEMU lock, ext4 compat
  bug series, SMP deadlock, init.sh POSIX, rustc MSRV, USB UVC)
- 2 riscv64-specific blocking points (bitmap overflow obsoleted by
  PR #987, dynamic RAM detection)
- Script orchestration (prepare/compile/run/filter)
- Test configuration (selfhost-manual/ out of CI path)
- Known limitations and environment requirements

Updated to reflect current state:
- PR #987 removed page-alloc-* features (bitmap overflow no longer exists)
- PR #1007 replaces #804 for page reclaim
- PR #971 provides rsext4 cache (4 entries)
- selfhost-manual/ directory structure (not normal/)

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

* docs(starry): update aarch64 status — boot verified, rootfs ready

aarch64 self-compilation infrastructure verified:
- Seed kernel builds (plat_dyn=true, PIE target)
- Debian arm64 rootfs prepared (debootstrap + rustc nightly)
- QEMU boots to shell prompt with rootfs mounted
- Full compilation pending (TCG emulation, estimated 4-8h)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* fix(self-compile): add trap cleanup, heredoc comments, remove redundant -n guard

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* fix(selfhost): remove stale ax-driver/pci from inner self-compile.sh

PR #937 removed the ax-driver/pci feature. The inner guest script
still referenced it, causing cargo build to fail inside QEMU.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* fix(selfhost): use env bash shebang and unify test memory to 8G

- Change shebang from /usr/bin/bash to /usr/bin/env bash for portability
- Bump test-selfhost-check memory from 2G to 8G to match axconfig phys-memory-size

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* fix(starry-test): restructure selfhost-manual into qemu-selfhost wrapper

The build-riscv64gc-unknown-none-elf.toml was at the group root as a
file, but xtask's test discovery only scans directories for build-*.toml
files. This made selfhost-manual test cases invisible to .

Move the build config and two test cases into a qemu-selfhost wrapper
directory, matching the pattern used by qemu-smp1, qemu-smp4, etc.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* docs(starry): fix directory diagram and CLI flag in self-compilation docs

- Add qemu-selfhost/ wrapper level to directory tree diagram
- Fix --test-suite to --test-group in CLI invocation example

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* fix(self-compile): revert script to dev version — avoid overriding PR #1076 improvements

The PR #881 branch carried an older version of scripts/self-compile.sh
that would regress PR #1076's improvements if merged after:
- tmpfs setup (registry + workspace)
- rootfs cleanup function with idempotent guard
- jemalloc debug output filtering
- QEMU 12G memory (vs 8G)
- per-arch QEMU_NET_DEV variable (vs hardcoded virtio-net-pci)
- axalloc Cargo.toml and filter-workspace.sh injection
- sudo prerequisite check

PR #1076's version already handles riscv64, x86_64, and aarch64
correctly. PR #881 now inherits it without modification.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* fix(self-compile): drop all script changes — inherit upstream/dev version

PR #881 should not modify scripts/self-compile.sh. The self-compilation
script improvements are handled by PR #1076. PR #881 only adds:
- Documentation (docs/starryos-self-compilation.md)
- Linker PROVIDE fallback for _ex_table_* symbols
- riscv64 selfhost test infrastructure (selfhost-manual/ test group)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* fix(review): address pr-review BLOCK findings

1. linker.ld: restore .tracepoint, .kallsyms sections and original
   dyndbg symbol names (__start___dyndbg/__stop___dyndbg) that were
   inadvertently dropped during rebase. Keep the PROVIDE lines.
2. Guest self-compile.sh: add [ -f ext_linker.ld ] guard before
   grep+sed block — the file was deleted upstream, and sed -i on a
   missing file would fail under set -euo pipefail.
3. docs: update PROVIDE fix reference from ext_linker.ld to linker.ld
   since ext_linker.ld was merged into linker.ld upstream.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* refactor(selfhost): migrate test suite to apps/starry/selfhost

ZR233 feedback: "测例ci 耗时过多,请移至 apps 目录"

Move selfhost test cases from test-suit/starryos/selfhost-manual/ to
apps/starry/selfhost/ to follow the standard Starry app pattern.

- apps/starry/selfhost/build-riscv64gc-unknown-none-elf.toml
- apps/starry/selfhost/selfhost-full-kernel/ (full compilation, 7200s)
- apps/starry/selfhost/test-selfhost-check/ (quick tool check, 120s)

Usage: cargo xtask starry app qemu --arch riscv64 --app-case selfhost/test-selfhost-check

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* fix(selfhost): increase QEMU RAM from 8GB to 12GB to prevent OOM

Observed OOM during self-compilation with 8GB. Changes:
- qemu configs: -m 8G → -m 12G in both test cases
- build config: add axconfig_overrides with phys-memory-size=0x3_0000_0000
- docs: update all 8G references to 12G, add OOM warning
- host self-compile.sh already uses 12G (inherited from PR #1076)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* fix(selfhost): bump guest tmpfs from 8G to 12G to match QEMU memory

The QEMU config and build axconfig_overrides were already updated to 12G.
This makes the guest tmpfs mount consistent, preventing OOM during the
cargo build inside the guest.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* docs(starry): fix CLI flag and clarify host vs app case RAM requirements

ZR233 review feedback:
1. Fix --app-case to -t/--test-case (the actual CLI parameter name)
2. Add dependency note for PR #1076 (which upgrades self-compile.sh to 12G)
3. Distinguish app case path (12G via build config + qemu config) from
   host script path (requires PR #1076 merge for 12G support)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

---------

Co-authored-by: CI Test <noreply@starryos.org>
Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants