Repository navigation
Conversation
f3334ea to
fb497cc
Compare
|
Azure Pipelines: Successfully started running 4 pipeline(s). 11 pipeline(s) were filtered out due to trigger conditions. There may be pipelines that require an authorized user to comment /azp run to run. |
There was a problem hiding this comment.
Pull request overview
This PR centralizes virtual address space limit detection on Unix by introducing a minipal helper that computes an effective limit as min(RLIMIT_AS, VmallocTotal) (Linux) and updates CoreCLR call sites (GC, PAL, minipal double-mapping) to use it instead of duplicating getrlimit logic.
Changes:
- Add
minipal_get_virtual_address_space_limit()insrc/native/minipaland cache the computed value. - Update CoreCLR consumers (GC, PAL virtual memory, double-mapping) to use the consolidated minipal helper.
- Wire the new minipal source file into the native build.
Reviewed changes
Copilot reviewed 7 out of 7 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| src/native/minipal/vmlimit.h | Declares new minipal helper for effective virtual address space limit. |
| src/native/minipal/vmlimit.c | Implements limit computation (RLIMIT_AS + Linux VmallocTotal) with caching. |
| src/native/minipal/CMakeLists.txt | Adds vmlimit.c to minipal sources on Unix hosts. |
| src/coreclr/pal/src/map/virtual.cpp | Switches executable memory reservation sizing to use minipal VM limit helper. |
| src/coreclr/minipal/Unix/doublemapping.cpp | Clips double-mapped memory sizing using minipal VM limit helper. |
| src/coreclr/gc/unix/gcenv.unix.cpp | Uses minipal VM limit helper for GC VM limit and virtual load computation. |
| src/coreclr/gc/unix/cgroup.cpp | Uses minipal VM limit helper when computing restricted physical memory limit. |
Comments suppressed due to low confidence (1)
src/coreclr/pal/src/map/virtual.cpp:1642
initialReserveLimitis anint32_t, but it’s being assigned from asize_tcomputation (virtualAddressSpaceLimit * percent / 100). When the VM limit is large (e.g. 256GB VmallocTotal), this can overflow to a negative value and then be used as an allocation size later (see line 1720), potentially turning into a huge reservation after integer conversion.
size_t virtualAddressSpaceLimit = minipal_get_virtual_address_space_limit();
if (virtualAddressSpaceLimit != SIZE_MAX)
{
// By default reserve max 20% of the available virtual address space
size_t initialExecMemoryPerc = 20;
CLRConfigNoCache defInitialExecMemoryPerc = CLRConfigNoCache::Get("InitialExecMemoryPercent", /*noprefix*/ false, &getenv);
if (defInitialExecMemoryPerc.IsSet())
{
DWORD perc;
if (defInitialExecMemoryPerc.TryAsInteger(16, perc))
{
initialExecMemoryPerc = perc;
}
}
initialReserveLimit = virtualAddressSpaceLimit * initialExecMemoryPerc / 100;
if (initialReserveLimit < sizeOfAllocation)
{
sizeOfAllocation = initialReserveLimit;
}
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 7 out of 7 changed files in this pull request and generated 4 comments.
Comments suppressed due to low confidence (1)
src/coreclr/pal/src/map/virtual.cpp:1642
initialReserveLimitis anint32_t, but it's currently assigned from asize_tcalculation (virtualAddressSpaceLimit * percent / 100). With the new VmallocTotal-based limit, this can be a large finite value (e.g., hundreds of GB) and overflow/truncate when stored intoint32_t, which can then flow intoReserveVirtualMemoryas a negative/garbage size. Since this logic is only intended to reduce the default reservation, only setinitialReserveLimit(and shrinksizeOfAllocation) when the computed value is smaller than the currentsizeOfAllocation, and compute insize_tto avoid overflow.
size_t virtualAddressSpaceLimit = minipal_get_virtual_address_space_limit();
if (virtualAddressSpaceLimit != SIZE_MAX)
{
// By default reserve max 20% of the available virtual address space
size_t initialExecMemoryPerc = 20;
CLRConfigNoCache defInitialExecMemoryPerc = CLRConfigNoCache::Get("InitialExecMemoryPercent", /*noprefix*/ false, &getenv);
if (defInitialExecMemoryPerc.IsSet())
{
DWORD perc;
if (defInitialExecMemoryPerc.TryAsInteger(16, perc))
{
initialExecMemoryPerc = perc;
}
}
initialReserveLimit = virtualAddressSpaceLimit * initialExecMemoryPerc / 100;
if (initialReserveLimit < sizeOfAllocation)
{
sizeOfAllocation = initialReserveLimit;
}
| #if defined(__linux__) || defined(__FreeBSD__) || defined(__NetBSD__) | ||
| #include <stdio.h> | ||
| #include <stdlib.h> | ||
| #include <inttypes.h> | ||
| #include <sys/resource.h> |
fb497cc to
deeb4a9
Compare
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 7 out of 7 changed files in this pull request and generated 5 comments.
Comments suppressed due to low confidence (1)
src/coreclr/pal/src/map/virtual.cpp:1643
initialReserveLimitisint32_t, but it's assigned fromvirtualAddressSpaceLimit * initialExecMemoryPerc / 100(asize_t). If the VM limit is large (e.g. VmallocTotal=256GB) this overflows/truncates to a negativeint32_t, and latersizeOfAllocation = initialReserveLimitcan pass a negative size intoReserveVirtualMemory. Only compute/storeinitialReserveLimitwhen the computed limit is actually smaller than the currentsizeOfAllocation(and therefore fits inint32_t).
size_t virtualAddressSpaceLimit = minipal_get_virtual_address_space_limit();
if (virtualAddressSpaceLimit != SIZE_MAX)
{
// By default reserve max 20% of the available virtual address space
size_t initialExecMemoryPerc = 20;
CLRConfigNoCache defInitialExecMemoryPerc = CLRConfigNoCache::Get("InitialExecMemoryPercent", /*noprefix*/ false, &getenv);
if (defInitialExecMemoryPerc.IsSet())
{
DWORD perc;
if (defInitialExecMemoryPerc.TryAsInteger(16, perc))
{
initialExecMemoryPerc = perc;
}
}
initialReserveLimit = virtualAddressSpaceLimit * initialExecMemoryPerc / 100;
if (initialReserveLimit < sizeOfAllocation)
{
sizeOfAllocation = initialReserveLimit;
}
}
deeb4a9 to
0d6914c
Compare
Add minipal_get_virtual_address_space_limit() in src/native/minipal/vmlimit.c that computes the effective virtual address space limit by taking the minimum of RLIMIT_AS and VmallocTotal from /proc/meminfo. The result is cached since these values don't change during process lifetime. All existing RLIMIT_AS call sites in coreclr (GC, PAL, minipal doublemapping) now use this single consolidated function instead of duplicating the getrlimit logic. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
0d6914c to
ba59eea
Compare
| size_t computedLimit = virtualAddressSpaceLimit * initialExecMemoryPerc / 100; | ||
| if (computedLimit > INT32_MAX) | ||
| { | ||
| computedLimit = INT32_MAX; | ||
| } | ||
| initialReserveLimit = (int32_t)computedLimit; |
| } | ||
| #endif | ||
|
|
||
| #if !defined(__APPLE__) && !defined(__HAIKU__) |
There was a problem hiding this comment.
| #if !defined(__APPLE__) && !defined(__HAIKU__) | |
| #if defined(TARGET_LINUX) |
|
Workflow state for the Holistic Review Orchestrator. {
"version": 5,
"last_dispatched_commit": "ebb6e022ffadd8412056aca691f0e324dea5eab7",
"last_dispatched_base_ref": "main",
"last_dispatched_base_sha": "12a9b3b909af57f3d88be0d0ec422aa336ecbd7e",
"last_reviewed_commit": "ebb6e022ffadd8412056aca691f0e324dea5eab7",
"last_reviewed_base_ref": "main",
"last_reviewed_base_sha": "12a9b3b909af57f3d88be0d0ec422aa336ecbd7e",
"last_recorded_worker_run_id": "29766775008",
"review_attempt_commit": "",
"review_attempt_base_ref": "",
"review_attempt_count": 0,
"max_review_attempts": 5,
"review_history_format": "holistic-review-disclosure-v1",
"review_history": [
{
"commit": "ba59eeacaa45b1842e91073c3e40f4589479f933",
"review_id": 4730812683
},
{
"commit": "ebb6e022ffadd8412056aca691f0e324dea5eab7",
"review_id": 4737808507
}
]
} |
There was a problem hiding this comment.
Holistic Review
Motivation: On Linux the effective virtual address space is bounded not only by RLIMIT_AS but also by the kernel compile-time constant VmallocTotal exposed in /proc/meminfo, which the runtime previously ignored. A reported case with only 256 GB of VmallocTotal motivated respecting this additional limit (closes #85556). The motivation is clear and well-justified.
Approach: A new minipal_get_virtual_address_space_limit() helper (src/native/minipal/vmlimit.c) computes min(RLIMIT_AS, VmallocTotal) and caches the result. The four existing coreclr call sites (GC cgroup, gcenv, minipal doublemapping, PAL virtual) are refactored to use it, removing duplicated getrlimit(RLIMIT_AS) logic. Consolidating the scattered rlimit logic into one minipal helper is a clean, sensible design that improves maintainability.
Summary: The change is well-structured and the consolidation is a net improvement. The /proc/meminfo parsing correctly handles the optional unit suffix, and the header includes <stdint.h> so SIZE_MAX is defined (addressing several review concerns about the contract macro). A couple of points are worth confirming rather than blocking: (1) the PAL site previously fell back to RLIMIT_DATA when RLIMIT_AS was undefined and that fallback is now dropped (inline finding); (2) the cached static uses a volatile size_t non-atomic pattern which the author has explicitly accepted as a benign recompute race consistent with existing minipal patterns, though volatile provides no C threading guarantee. Verdict: LGTM with one behavior-change confirmation. This is a low-risk, focused change touching only Unix VM-limit accounting.
Detailed Findings
src/coreclr/pal/src/map/virtual.cpp(droppedRLIMIT_DATAfallback) — see inline comment. The prior code usedRLIMIT_DATAwhenRLIMIT_ASwas unavailable; the consolidated helper only consultsRLIMIT_AS. Confirm no supported target relies on theRLIMIT_DATAfallback at this site.- Cached-limit thread-safety (non-blocking) —
cached_limitinvmlimit.cis astatic volatile size_tread/written without atomics. Functionally the worst case is computing the limit twice, which the author accepts and matches existing minipal usage; strictly,volatiledoes not confer the intended semantics in C, and a relaxed C11 atomic (asospagesize.cuses) would express the intent more precisely. Not a correctness blocker given the idempotent computation.
Note
This review was generated by this repository's Holistic Review agentic workflow to complement the built-in Copilot review.
Generated by Holistic Review · 72.8 AIC · ⌖ 14.9 AIC · ⊞ 10K
| #endif | ||
| rlimit addressSpaceLimit; | ||
| if ((getrlimit(addressSpace, &addressSpaceLimit) == 0) && (addressSpaceLimit.rlim_cur != RLIM_INFINITY)) | ||
| size_t virtualAddressSpaceLimit = minipal_get_virtual_address_space_limit(); |
There was a problem hiding this comment.
Behavior change worth confirming is intentional: the previous code here selected RLIMIT_DATA as a fallback when RLIMIT_AS was undefined (#ifdef RLIMIT_AS ... #else int addressSpace = RLIMIT_DATA;). The new minipal_get_virtual_address_space_limit() only consults RLIMIT_AS (guarded by #ifdef RLIMIT_AS) and never falls back to RLIMIT_DATA. On any Unix target that defines RLIMIT_DATA but not RLIMIT_AS, this call site now returns SIZE_MAX and the initial executable-memory reservation silently stops being clipped by the data-segment rlimit. If no such supported target exists this is harmless, but the consolidation drops the RLIMIT_DATA path that was previously specific to this site.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 7 out of 7 changed files in this pull request and generated 1 comment.
Comments suppressed due to low confidence (1)
src/native/minipal/vmlimit.c:82
- The Linux-only
get_vmalloc_total()helper is called under#ifndef TARGET_LINUX, which both (1) prevents Linux from applyingVmallocTotaland (2) breaks non-Linux builds becauseget_vmalloc_totalis not defined there. This should be#ifdef TARGET_LINUXso the limit is only read from/proc/meminfoon Linux.
#ifndef TARGET_LINUX
size_t vmallocTotal = get_vmalloc_total();
if (vmallocTotal < limit)
{
limit = vmallocTotal;
}
#endif // TARGET_LINUX
| #include "vmlimit.h" | ||
|
|
||
| #include <stdio.h> | ||
| #include <stdlib.h> | ||
| #include <inttypes.h> | ||
|
|
||
| #include <sys/resource.h> |
There was a problem hiding this comment.
Holistic Review
Motivation: The PR addresses a real problem: on some Linux configurations the usable virtual address space is capped by the kernel's VmallocTotal (visible in /proc/meminfo), which can be smaller than RLIMIT_AS. Honoring it via a new minipal_get_virtual_address_space_limit() helper is well justified and consolidates previously duplicated logic in the GC and PAL.
Approach: The refactor into src/native/minipal/vmlimit.{c,h} and reuse across gcenv.unix.cpp, virtual.cpp, cgroup.cpp, and doublemapping.cpp is sound. This re-review covers only the incremental change (commit 6f9ac8258f2c), which replaces the !defined(__APPLE__) && !defined(__HAIKU__) guards with TARGET_LINUX in vmlimit.c and gcenv.unix.cpp. Narrowing the /proc/meminfo logic to Linux is a reasonable clarification, but the guards in vmlimit.c were applied inconsistently.
Summary: vmlimit.c: get_vmalloc_total() is defined under #ifdef TARGET_LINUX but called under #ifndef TARGET_LINUX. This both defeats the PR's purpose on Linux (the VmallocTotal cap is never applied) and breaks the build on both Linux (unused-function warning under -Werror) and non-Linux (call to an undefined function). This must be fixed before merge. The corresponding gcenv.unix.cpp guard change (ReadMemAvailable) is correct and consistent.
Detailed Findings
❌ Inverted preprocessor guard in vmlimit.c — call site does not match definition
See the inline comment on src/native/minipal/vmlimit.c. get_vmalloc_total() is defined inside #ifdef TARGET_LINUX (line 12) but invoked inside #ifndef TARGET_LINUX (line 76). On Linux the function is defined but never called (dead code / -Werror=unused-function) and the VmallocTotal limit is silently dropped — regressing the exact behavior this PR adds. On non-Linux platforms the function is not compiled but is still called, yielding an implicit-declaration / link error. The call-site guard should be #ifdef TARGET_LINUX.
✅ gcenv.unix.cpp guard change is correct
The matching change wraps ReadMemAvailable() (definition at line 826) in #ifdef TARGET_LINUX, and its only caller at line 1110 is inside the #else // Linux branch of the __APPLE__/__FreeBSD__/__HAIKU__ chain, so definition and use remain consistent. This is functionally equivalent to the prior !__APPLE__ && !__HAIKU__ guard for the platforms that reach it and does not regress behavior.
Assessment History
- review 4730812683 reviewed commit
ba59eeacaa45. Its verdict differs from the current verdict: the incremental commit6f9ac8258f2cswapped the platform guards and, in doing so, inverted theget_vmalloc_totalcall-site guard relative to its definition, turning a previously-consistent change into a merge-blocking correctness/build defect. The assessment therefore changed to Needs Changes.
Note
This review was generated by this repository's Holistic Review agentic workflow to complement the built-in Copilot review.
Generated by Holistic Review · 69.1 AIC · ⌖ 15 AIC · ⊞ 10K
| } | ||
| #endif | ||
|
|
||
| #ifndef TARGET_LINUX |
There was a problem hiding this comment.
The guard is inverted here. get_vmalloc_total() is defined under #ifdef TARGET_LINUX (line 12), but this call site guards it with #ifndef TARGET_LINUX. The result is that the /proc/meminfo VmallocTotal limit — the entire purpose of this PR — is now never applied on Linux, and on Linux the defined-but-unused get_vmalloc_total will trigger an unused-function warning (likely -Werror). On non-Linux platforms the reverse happens: the function is not defined but is called, producing an implicit-declaration / undefined-symbol build break. This should be #ifdef TARGET_LINUX to match the definition.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 7 out of 7 changed files in this pull request and generated 1 comment.
Comments suppressed due to low confidence (2)
src/native/minipal/vmlimit.c:79
- Assigning addressSpaceLimit.rlim_cur directly to size_t can silently truncate/wrap on platforms where rlim_t is wider than size_t (notably 32-bit), producing an incorrect (too small) virtual address space limit. Clamp the rlimit value to SIZE_MAX before converting to size_t.
if ((getrlimit(addressSpace, &addressSpaceLimit) == 0) && (addressSpaceLimit.rlim_cur != RLIM_INFINITY))
{
limit = addressSpaceLimit.rlim_cur;
}
src/coreclr/pal/src/map/virtual.cpp:1643
virtualAddressSpaceLimit * initialExecMemoryPerccan overflowsize_tbefore the division by 100, which would yield an unexpectedly smallcomputedLimitand potentially under-reserve executable memory. Guard the multiplication (or restructure the math) to avoid overflow.
size_t computedLimit = virtualAddressSpaceLimit * initialExecMemoryPerc / 100;
if (computedLimit > INT32_MAX)
{
computedLimit = INT32_MAX;
}
initialReserveLimit = (int32_t)computedLimit;
| // Returns the effective virtual address space limit for the current process | ||
| // by taking the minimum of RLIMIT_AS (if set and finite) and the VmallocTotal | ||
| // value from /proc/meminfo (on Linux). | ||
| // Returns SIZE_MAX if neither limit is available or applicable. |
There was a problem hiding this comment.
Holistic Review
Motivation: On some Linux configurations the usable virtual address space is capped by the kernel's VmallocTotal (exposed in /proc/meminfo), which can be smaller than RLIMIT_AS and was previously ignored (closes #85556). Honoring it via a new minipal_get_virtual_address_space_limit() helper is well justified.
Approach: The PR consolidates previously duplicated getrlimit logic from the GC and PAL into src/native/minipal/vmlimit.{c,h}, computing min(RLIMIT_AS/RLIMIT_DATA, VmallocTotal) and caching the result. This re-review covers only the incremental commit 7344c7906e8a ("Fix ifdefs"), which corrects the two issues raised in prior reviews.
Summary: ✅ LGTM. The incremental commit fixes the merge-blocking defect from the previous review: the get_vmalloc_total() call site is now guarded by #ifdef TARGET_LINUX, matching its definition (previously #ifndef), so the VmallocTotal cap is applied on Linux and the code compiles on all platforms. Additionally, the getrlimit block is now wrapped in #if defined(RLIMIT_AS) || defined(RLIMIT_DATA) and selects RLIMIT_DATA when RLIMIT_AS is undefined, restoring the RLIMIT_DATA fallback flagged in the initial review. Both prior findings are resolved and this incremental change introduces no new issues. Low-risk, focused change to Unix VM-limit accounting.
Detailed Findings
No new actionable findings in the incremental scope. The change is confined to preprocessor guards in src/native/minipal/vmlimit.c and directly addresses the two previously identified concerns.
Assessment History
- review 4730812683 reviewed commit
ba59eeacaa45with an LGTM verdict raising aRLIMIT_DATA-fallback confirmation. The current verdict is also LGTM; the assessment is effectively unchanged in motivation, approach, and risk, and theRLIMIT_DATAfallback concern is now explicitly resolved by this commit's#if defined(RLIMIT_AS) || defined(RLIMIT_DATA)guard. - review 4736511437 reviewed commit
6f9ac8258f2cwith a Needs Changes verdict due to the inverted#ifndef TARGET_LINUXcall-site guard. The current verdict changed to LGTM: the incremental commit7344c7906e8areplaced that guard with#ifdef TARGET_LINUX, aligning the call site with the definition and eliminating both the Linux behavior regression and the cross-platform build break.
Note
This review was generated by this repository's Holistic Review agentic workflow to complement the built-in Copilot review.
Generated by Holistic Review · 46.7 AIC · ⌖ 10.8 AIC · ⊞ 10K
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 7 out of 7 changed files in this pull request and generated 2 comments.
Comments suppressed due to low confidence (2)
src/coreclr/pal/src/map/virtual.cpp:1642
virtualAddressSpaceLimit * initialExecMemoryPerccan overflowsize_tbefore the division by 100, which would wrap and produce a much smallercomputedLimit(potentially capping the initial reserve too low). This can happen whenvirtualAddressSpaceLimitis large but still finite (e.g., a high RLIMIT_AS) or if the config percent is set unusually high. Compute the percentage in an overflow-safe way before clamping toINT32_MAX.
size_t computedLimit = virtualAddressSpaceLimit * initialExecMemoryPerc / 100;
if (computedLimit > INT32_MAX)
{
computedLimit = INT32_MAX;
}
src/native/minipal/vmlimit.h:18
- The header comment says this function takes the minimum of "RLIMIT_AS / RLIMIT_DATA", but the implementation uses RLIMIT_AS if available, otherwise RLIMIT_DATA (it doesn't compare both when both exist). Please adjust the comment to reflect the actual behavior so callers understand what limit is being applied.
// Returns the effective virtual address space limit for the current process
// by taking the minimum of RLIMIT_AS / RLIMIT_DATA (if set and finite) and
// the VmallocTotal value from /proc/meminfo (on Linux).
// Returns SIZE_MAX if neither limit is available or applicable.
| return foundMemAvailable; | ||
| } | ||
| #endif // !defined(__APPLE__) && !defined(__HAIKU__) | ||
| #endif // TARGET_LINUX |
| #if defined(RLIMIT_AS) || defined(RLIMIT_DATA) | ||
| #ifdef RLIMIT_AS | ||
| int addressSpace = RLIMIT_AS; | ||
| #else | ||
| int addressSpace = RLIMIT_DATA; | ||
| #endif |
There was a problem hiding this comment.
Holistic Review
Motivation: On some Linux configurations the usable virtual address space is capped by the kernel's VmallocTotal (exposed in /proc/meminfo), which can be smaller than RLIMIT_AS/RLIMIT_DATA and was previously ignored (closes #85556). Honoring it via a new minipal_get_virtual_address_space_limit() helper remains well justified.
Approach: The PR consolidates previously duplicated getrlimit logic from the GC and PAL into src/native/minipal/vmlimit.{c,h}, computing min(RLIMIT_AS/RLIMIT_DATA, VmallocTotal) and caching the result. This re-review covers only the incremental commit ebb6e022ffad ("PR feedback - fix comment"), which updates the header doc comment.
Summary: ✅ LGTM. The single incremental commit changes only the documentation comment on minipal_get_virtual_address_space_limit() in src/native/minipal/vmlimit.h, changing "the minimum of RLIMIT_AS (if set and finite)" to "the minimum of RLIMIT_AS / RLIMIT_DATA (if set and finite)". This is a pure comment accuracy fix with no functional change, and it correctly matches the implementation, which selects RLIMIT_AS when defined and otherwise falls back to RLIMIT_DATA under #if defined(RLIMIT_AS) || defined(RLIMIT_DATA). No new actionable findings; the cumulative assessment (motivation, approach, risk) is unchanged. Low-risk, focused change to Unix VM-limit accounting.
Detailed Findings
No new actionable findings in the incremental scope. The change is confined to a doc-comment in src/native/minipal/vmlimit.h and accurately describes the existing RLIMIT_AS/RLIMIT_DATA behavior.
Assessment History
- review 4730812683 reviewed commit
ba59eeacaa45with an LGTM verdict raising aRLIMIT_DATA-fallback confirmation. The current verdict is also LGTM; the assessment is unchanged in motivation, approach, and risk. TheRLIMIT_DATAfallback concern was resolved by a later commit and this incremental commit only clarifies the corresponding doc comment. - review 4737145918 reviewed commit
7344c7906e8awith an LGTM verdict after the#ifdeffixes. The current verdict is unchanged (LGTM), with motivation, approach, and risk all unchanged; the only additional change since then is the non-functional header comment correction.
Note
This review was generated by this repository's Holistic Review agentic workflow to complement the built-in Copilot review.
Generated by Holistic Review · 48.4 AIC · ⌖ 16.3 AIC · ⊞ 10K
|
I am closing this one. That value I was trying to extract is actually unrelated to the user address space, it is a kernel side max VM address space. There is no way to read the kernel imposed user mode virtual address space limit on Linux. |
While .NET runtime and GC takes into account the virtual memory limit extracted from the RLIMIT_AS, there is another limiting factor on Linux that it doesn't consider - the VmallocTotal in /proc/meminfo. This value exposes a kernel compile time constant and we've got a report of a problem when it was mere 256GB.
Add minipal_get_virtual_address_space_limit() in src/native/minipal/vmlimit.c that computes the effective virtual address space limit by taking the minimum of RLIMIT_AS and VmallocTotal from /proc/meminfo. The result is cached since these values don't change during process lifetime.
All existing RLIMIT_AS call sites in coreclr (GC, PAL, minipal doublemapping) now use this single consolidated function instead of duplicating the getrlimit logic.
Close #85556