Pull requests / #2217

#2217 Count clean active file cache as reclaimable under a cgroup limit

open · @kuhlsnu · 0 コメント · GitHub で見る

Multi-GPUAMD / HIPNVIDIA / CUDALinux

本文

## Title
Issue: none filed, the numbers are below.

## Summary
In a container, the resident RAM budget swings with the page cache's history instead of the box. `cgroup_available_bytes` credits only `inactive_file`, but the model files Strata reads while loading land on the active list, so the same box with the same 50 GiB container cap granted 0.00, 20.29, 17.53, 29.66 and 26.99 GiB across five starts (2x RTX 3090, 2026-10-09). The container held 21.59 GiB of `active_file` and 0.75 GiB of `inactive_file` at the time.

This counts clean active file pages as reclaimable too, still bounded to `memory.current` and less dirty and writeback pages, so the grant stops depending on which cgroup paid for the cache first.

## What changed
- `src/core/expert_source.cpp`: `cgroup_available_bytes` sums `inactive_file + active_file` (saturating), and `read_cgroup_memory_stat` reads and requires `active_file` like the other counters.
- `include/strata/core/expert_source.hpp`: `CgroupMemoryStat` gains `active_file`.
- `tests/core/file_expert_source_test.cpp`: a loaded-model case (the 3090 numbers), a sum bounded to `current`, and an overflow case.

Left alone on purpose:
- **HIP keeps the inactive-only rule.** `pin_blobs` in `generate.cpp` registers mapped file ranges, and those pinned pages sit on the active list without being reclaimable, so crediting them could overstate the room. I have no AMD box to measure it on.
- **The SYCL mirror** (`sycl/src/core/expert_source.cpp`) and `conversation_memory.cpp`'s own credit rule are unchanged.

On the comment in `conversation_memory.cpp` that active_file "holds mlocked pages": as far as I can tell the kernel moves mlocked pages to the unevictable list (`Documentation/mm/unevictable-lru.rst`), so that is not a reason to leave active_file out. Pinned (registered) file pages are, which is why HIP is excluded here.

## Extra Notes
What ran (WSL Ubuntu 24.04, g++ 13.3, CUDA 12.0 for the `.cu` objects the test links):
- `file_expert_source_test` passes on this commit. Against the parent it fails to compile (the struct gained a field), and with the old inactive-only sum it fails with `clean active file cache was not credited against the cgroup cap`.
- CPU-only `ctest`: 39/39 before and after.

Not run yet: the after-fix grant on the GPU box. The patched build has served on that box since 2026-10-09 with no budget refusal in its 127 start and stop logs, but those starts did not log the grant. I'll add five instrumented cold starts as a comment after 2026-10-15.

Not built: HIP and SYCL. The HIP branch is a preprocessor switch back to the current rule; with `-DSTRATA_USE_HIP=1` both changed files compile and the test passes on the CPU build, which checks the branch logic but not ROCm. SYCL's files are not touched.

Default behaviour changes inside a cgroup with active file cache, so this is a fix to the default path rather than an opt-in feature; without a cgroup memory limit (`memory.max` of `max`) nothing changes.

関連リンク

インストール・モデル・リリースへの站内リンク。