Skip to content

Fix segfault in GC standalone large pages emulation mode (segments path) - #127763

Merged
janvorli merged 4 commits into
dotnet:mainfrom
cshung:fix/gc-standalone-largepages-segments
Jun 17, 2026
Merged

Fix segfault in GC standalone large pages emulation mode (segments path)#127763
janvorli merged 4 commits into
dotnet:mainfrom
cshung:fix/gc-standalone-largepages-segments

Conversation

@cshung

@cshung cshung commented May 4, 2026

Copy link
Copy Markdown
Contributor

In the non-regions (segments) path, GCLargePages=2 (emulation mode) was not handled by virtual_alloc. The function only had a bool use_large_pages_p parameter, so it could not distinguish between real large pages (VirtualReserveAndCommitLargePages) and emulation mode (which needs VirtualReserve + VirtualCommit). In emulation mode, memory was reserved but never committed, causing a segfault on access.

Fix: Change virtual_alloc to accept an int large_page_config parameter:

  • 0 = no large pages (reserve only)
  • 1 = real large pages (VirtualReserveAndCommitLargePages)
  • 2 = emulation (VirtualReserve + VirtualCommit)

The caller computes large_page_config once and passes it through reserve_initial_memory, eliminating the need for reserve_initial_memory to access the static large_pages_emulation_mode_p field.

The test is updated to use per-object-heap hard limits (GCHeapHardLimitSOH/LOH/POH), which are required for the segments path with large pages since each segment is sized to the full hard limit (soh + loh + poh = 3x limit with a single combined GCHeapHardLimit).

Fixes #127668

@dotnet-policy-service dotnet-policy-service Bot added the community-contribution Indicates that the PR has been added by a community member label May 4, 2026
@dotnet-policy-service

Copy link
Copy Markdown
Contributor

Tagging subscribers to this area: @JulieLeeMSFT, @dotnet/gc
See info in area-owners.md if you want to be subscribed.

Comment thread src/coreclr/gc/regions_segments.cpp Outdated
Comment thread src/coreclr/gc/init.cpp Outdated
@cshung
cshung force-pushed the fix/gc-standalone-largepages-segments branch from 86e5612 to 0aaa427 Compare May 5, 2026 21:36
@mangod9

mangod9 commented May 5, 2026

Copy link
Copy Markdown
Member

I am not convinced whether we should do this for segments. In fact we should be looking at not shipping clrgc.dll given that regions have been live for 3+ releases already

@cshung

cshung commented May 6, 2026

Copy link
Copy Markdown
Contributor Author

I am not convinced whether we should do this for segments. In fact we should be looking at not shipping clrgc.dll given that regions have been live for 3+ releases already

I think we should still maintain this path for two reasons:

  1. The segments path (#ifndef USE_REGIONS) is not just about standalone GC — it's the codepath 32-bit systems use in production. Standalone GC is currently the mechanism that exercises this path in CI. If we stop maintaining it, we're effectively letting the 32-bit segments codepath rot without any test coverage.

  2. Even setting aside 32-bit, standalone GC provides a valuable vehicle for flexible testing and experimentation. We may not want to ship it, but that doesn't mean it isn't worth keeping functional.

The fix itself is small and straightforward — it passes the large page config as an integer through virtual_alloc so the emulation mode does Reserve+Commit correctly on both the regions and segments paths.

@mangod9

mangod9 commented May 6, 2026

Copy link
Copy Markdown
Member

is the x86 case broken due to the new changes here?

@cshung

cshung commented May 6, 2026

Copy link
Copy Markdown
Contributor Author

is the x86 case broken due to the new changes here?

No, x86 is good:

  • x86 is not broken before this PR (large pages are not supported on x86, anything broken because of large page does not impact x86).
  • x86 is not broken after this PR either (this PR impacts large page only)

@janvorli

janvorli commented Jun 8, 2026

Copy link
Copy Markdown
Member

@cshung, I'd prefer disabling the large page emulation for segments instead. As Manish mentioned, we only use segments mode on 32 bit systems and as you've also mentioned, for those, the large pages are not enabled and don't make sense.

The emulated large pages are a great tool for testing large pages during GC development and in the PR, but I don't see it as something customers should use. So this mode really seems to have benefit only when regions are enabled.

@cshung

cshung commented Jun 12, 2026

Copy link
Copy Markdown
Contributor Author

@cshung, I'd prefer disabling the large page emulation for segments instead. As Manish mentioned, we only use segments mode on 32 bit systems and as you've also mentioned, for those, the large pages are not enabled and don't make sense.

The emulated large pages are a great tool for testing large pages during GC development and in the PR, but I don't see it as something customers should use. So this mode really seems to have benefit only when regions are enabled.

I think this is the right fix, but if we wanted to simply disable the test, I am happy with that too.

Without this test though, segments + 64 bits + large page is functional but untested. That being said, it is a niche scenario, and it is just what it was, we didn't make it worse.

@janvorli

Copy link
Copy Markdown
Member

I think this is the right fix, but if we wanted to simply disable the test, I am happy with that too.

I didn't mean disabling the test, but rather disabling emulated large pages support for the segments.

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

LGTM, thank you!

cshung and others added 3 commits June 16, 2026 09:52
Change virtual_alloc to accept an integer large_pages_config parameter
(0=none, 1=real large pages, 2=emulation) instead of a boolean. When
config=2, use VirtualReserve followed by VirtualCommit to emulate large
page behavior without requiring OS large page privileges.

Update the test to use per-object-heap hard limits which are required
for the segments path with large pages.
Large page emulation mode (GCLargePages=2) is not supported on the
segments path. When emulation is requested on segments, silently
disable large pages instead of crashing with a segfault due to
memory being reserved but never committed.

Real large pages (GCLargePages=1) continue to work on segments as
before.

Fixes dotnet#127668

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@cshung
cshung force-pushed the fix/gc-standalone-largepages-segments branch from c3a2874 to 973587c Compare June 16, 2026 16:52
@janvorli

Copy link
Copy Markdown
Member

/ba-g the failures are timeouts that happen in many if not all PRs, unrelated to this change.

@janvorli
janvorli merged commit 1af2b9f into dotnet:main Jun 17, 2026
109 of 113 checks passed
@cshung
cshung deleted the fix/gc-standalone-largepages-segments branch June 17, 2026 14:34
@dotnet-milestone-bot dotnet-milestone-bot Bot added this to the 11.0-preview6 milestone Jun 18, 2026
eiriktsarpalis pushed a commit that referenced this pull request Jul 15, 2026
…th) (#127763)

In the non-regions (segments) path, `GCLargePages=2` (emulation mode)
was not handled by `virtual_alloc`. The function only had a `bool
use_large_pages_p` parameter, so it could not distinguish between real
large pages (`VirtualReserveAndCommitLargePages`) and emulation mode
(which needs `VirtualReserve` + `VirtualCommit`). In emulation mode,
memory was reserved but never committed, causing a segfault on access.

**Fix:** Change `virtual_alloc` to accept an `int large_page_config`
parameter:
- `0` = no large pages (reserve only)
- `1` = real large pages (`VirtualReserveAndCommitLargePages`)
- `2` = emulation (`VirtualReserve` + `VirtualCommit`)

The caller computes `large_page_config` once and passes it through
`reserve_initial_memory`, eliminating the need for
`reserve_initial_memory` to access the static
`large_pages_emulation_mode_p` field.

The test is updated to use per-object-heap hard limits
(`GCHeapHardLimitSOH`/`LOH`/`POH`), which are required for the segments
path with large pages since each segment is sized to the full hard limit
(soh + loh + poh = 3x limit with a single combined `GCHeapHardLimit`).

Fixes #127668

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@github-actions github-actions Bot locked and limited conversation to collaborators Jul 19, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

area-GC-coreclr community-contribution Indicates that the PR has been added by a community member

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Test Failure: GC/API/GC/Collect_Aggressive_LargePages/Collect_Aggressive_LargePages.cmd

3 participants