fix(mem): use real /proc RSS on Linux (mimalloc current_rss undercounts, blinding backpressure)#861
Merged
Merged
Conversation
…ts, blinding backpressure) Distilled from #776's 132460f. This project sets arena_eager_commit=0 + purge_decommits=1 + purge_delay=0 in cbm_mem_init to reduce upfront memory, so mimalloc's committed-page counter reads low. On Linux mi_process_info() never sets current_rss (vendored/mimalloc/src/prim/unix/prim.c only fills peak_rss), so current_rss defaults to that low committed counter — cbm_mem_rss() returned a few MB while true RSS was multiple GB, leaving cbm_mem_over_budget() backpressure, the memory ceiling, and the host RAM tier blind on Linux. Prefer os_rss() (/proc/self/statm) as the primary source on Linux; macOS and Windows are unchanged (their mi_process_info current_rss is accurate via task_info / GetProcessMemoryInfo). cbm_mem_peak_rss() is untouched. Complements #752 by making the RAM tiers actually bite on Linux. Reproduce-first: mem_rss_reflects_external_resident_memory pins mimalloc's committed counter low with a live mi_malloc, then grows true RSS via a raw 256MB mmap (invisible to mimalloc); unfixed Linux returns the ~few-MB committed counter (RED), fixed Linux returns /proc RSS (GREEN). macOS/Windows pass either way, so the RED manifests on the Linux CI leg. Co-authored-by: petercoxphoto <info@petercox.ie> Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
…-undercount Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
fix(mem): use real /proc RSS on Linux — mimalloc
current_rssundercounts, blinding backpressureDistilled from #776's commit
132460f5(author @petercoxphoto), extracted as asingle atomic stability fix. The rest of #776 (index-time importance scoring,
the
repo_mapMCP tool, per-file cap / enforcing memory ceiling) is deferred asseparate features and is not included here.
Refs #832.
The bug
cbm_mem_rss()asks mimalloc forcurrent_rss(mi_process_info(...)) andreturns it whenever it is
> 0, only falling back toos_rss()(the/proc/self/statmreader) when it is exactly0.On Linux that is wrong. mimalloc's
_mi_prim_process_info()(
vendored/mimalloc/src/prim/unix/prim.c) never setscurrent_rsson Linux— it only fills
peak_rssfromgetrusage'sru_maxrss. Socurrent_rsskeeps
mi_process_info()'s default ofpinfo.current_commit(
vendored/mimalloc/src/stats.c:555): mimalloc's own committed-page counter.This project deliberately tunes that counter low in
cbm_mem_init()(
mi_option_arena_eager_commit=0+purge_decommits=1+purge_delay=0, toreduce upfront memory), so on Linux "current RSS" reads a few MB while the real
process RSS is multiple GB.
Consequence:
cbm_mem_over_budget()and the parallel-parse backpressure spin(
pass_parallel.c) — and any memory ceiling — were blind to real memorypressure on Linux. The undercounted value is small-but-nonzero, so it even
defeats the existing
current_rss > 0ASan-only fallback guard.macOS/Windows are unaffected: mimalloc sets
current_rsscorrectly there viatask_info/GetProcessMemoryInfo.The fix (per-platform, surgical)
In
cbm_mem_rss(), on__linux__preferos_rss()(/proc/self/statm, alreadyimplemented and unaffected by mimalloc's internal accounting) as the primary
source, falling back to mimalloc's value only if
/procis unavailable.macOS/Windows behavior is unchanged (they still use mimalloc's accurate
current_rss).cbm_mem_peak_rss()is untouched —peak_rssis set correctlyon Linux via
ru_maxrss.This complements #752: it makes the RAM budget/backpressure tiers actually bite
on Linux instead of silently never firing.
Reproduce-first test — red/green
Added
mem_rss_reflects_external_resident_memorytotests/test_mem.c. It makesthe two quantities diverge deterministically:
mi_malloc()a small live block so mimalloc's committed counter is a smallpositive value (this both defeats the unfixed
current_rss > 0fallbackguard and pins the reported value low).
mi_mallocroutes through mimallocregardless of
MI_OVERRIDE, so it works in the ASan test-runner too.mmap— memorymimalloc's committed counter never sees, but
/proc/self/statmdoes.cbm_mem_rss() >= 128 MB.cbm_mem_rss()returns the ~few-MB committed counter →assertion FAILS → RED.
/procRSS (>= 256 MB) → GREEN.current_rssalready reflects the mapped region, so thetest passes both before and after the fix — the RED manifests only on the
Linux CI leg, which is exactly where the production undercount bit.
Which tier proves RED
The bug is Linux-only, so it cannot go RED on the macOS dev host (there
mi_process_info'scurrent_rssis accurate viatask_info). The mechanism wasverified locally with a standalone mimalloc probe replicating the production
allocator config and the test's alloc pattern: after
mi_malloc(1MB)+ a raw256 MB
mmap, mimalloc'scurrent_commit= 7 MB while true OS resident =258 MB. On Linux
cbm_mem_rss()(unfixed) returnscurrent_rss== thatcurrent_commit(~7 MB) → far below the 128 MB threshold → RED. The Linux CI legof
make test(test-runner mem) is the tier that turns this guard red on theunfixed code and green on the fix.
Verification
make -f Makefile.cbm cbm— production binary (MI_OVERRIDE=1),-Werrorclean.make -f Makefile.cbm lint-ci— cppcheck + clang-format + NOLINT check clean.CBM_INDEX_SUPERVISOR=0 ./build/c/test-runner mem— 34 passed (GREEN on macOS,as expected for a Linux-only bug).