Skip to content

Mono: mono-threads-posix: use RLIMIT_STACK for default stack size.#124588

Open
tmds wants to merge 1 commit intodotnet:mainfrom
tmds:mono_default_stack_size
Open

Mono: mono-threads-posix: use RLIMIT_STACK for default stack size.#124588
tmds wants to merge 1 commit intodotnet:mainfrom
tmds:mono_default_stack_size

Conversation

@tmds
Copy link
Member

@tmds tmds commented Feb 19, 2026

This aligns Mono with to CoreCLRs behavior for (glibc-based) Linux distros.

Fixes #124368.

@jkotas @akoeplinger @hamarb123 ptal.

This aligns Mono with to CoreCLRs behavior for (glibc-based) Linux distros.
@dotnet-policy-service dotnet-policy-service bot added the community-contribution Indicates that the PR has been added by a community member label Feb 19, 2026
@tmds
Copy link
Member Author

tmds commented Feb 19, 2026

Per my comments in #124368, I also want to take a closer look at the Alpine/Musl (under ENSURE_PRIMARY_STACK_SIZE) implementation and probably suggest a change. That will be for another day/PR.

My main interest is to have this change so that the F# compiler doesn't run out of stack space while compiling fsharp repo during the .NET build on ppc64le and s390x (dotnet/fsharp#19286).

@hamarb123
Copy link
Contributor

hamarb123 commented Feb 19, 2026

Should we consider just using getrlimit on coreclr/naot also on all unix platforms? macOS defaults to 8MB for main thread by default (from that value), but then 512kB for secondary threads - we currently override manually to 1.5MB, but maybe it makes sense to just use logic this everywhere (that way it's user-controllable, consistent across all .NET on Unix, etc.)? Thoughts @tmds @jkotas?

// This matches the default stack size of pthreads on glibc Linux distros.
// On Musl Linux, pthread defaults to a small size of 128KB. Using RLIMIT_STACK aligns the behavior with glibc Linux.
struct rlimit lim;
if (getrlimit (RLIMIT_STACK, &lim) == 0) {
Copy link
Member

Choose a reason for hiding this comment

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

I do not see any code in CoreCLR that reads RLIMIT_STACK. Why do we need to read it in Mono? I would expect both CoreCLR and Mono to depend on the same APIs if the behavior is meant to be aligned.

Copy link
Member Author

Choose a reason for hiding this comment

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

The default behavior of pthreads with glibc is that when you don't specify a stack size, it uses RLIMIT_STACK.

The default behavior of pthreads with musl is that it uses a 128KB stack that is too small for .NET.

I've implemented this to not treat either glibc or Musl special and everywhere get the RLIMIT_STACK and use that.

For CoreCLR, the current behavior with glibc is not specify a stack size (-> use RLIMIT_STACK) and for Musl it uses a hard coded 1.5MB (per ENSURE_PRIMARY_STACK_SIZE).

I think we should also use RLIMIT_STACK with Musl with CoreCLR. This isn't included in this PR. I'd like to look at if we can't eliminate ENSURE_PRIMARY_STACK_SIZE (it is a guess for RLIMIT_STACK).

Copy link
Member

Choose a reason for hiding this comment

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

musl made an explicit decision to not respect RLIMIT_STACK. Is it really an improvement to override their decision?

Copy link
Member Author

Choose a reason for hiding this comment

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

We need to anyhow increase what they use per default and by aligning with glibc we eliminate an unexpected difference and provide a way for the user to control the size.

Copy link
Member Author

Choose a reason for hiding this comment

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

The Alpine maintainers also build for s390x. Without this change, it's expected they'll run into the fsharp build issue.

Copy link
Member

Choose a reason for hiding this comment

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

Mono workload owners should comment on the impact of reading RLIMIT in Mono by default.

CoreCLR allows configuration of the default stack size via Thread_DefaultStackSize. Reading this config in Mono would align it with CoreCLR.

Copy link
Member Author

Choose a reason for hiding this comment

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

I think the change is meaningful in particular for when we're source-building .NET on Linux and use Mono instead of CoreCLR. It matches the stack sizes with those of CoreCLR.

I'm not sure what other builds this affects. If desired, we could make this conditional to the source-build use-case.

We can add support for Thread_DefaultStackSize too to provide a consistent way to control the stack size.

@jkotas
Copy link
Member

jkotas commented Feb 19, 2026

Should we consider just using getrlimit on coreclr/naot also on all unix platforms? macOS defaults to 8MB for main thread by default (from that value), but then 512kB for secondary threads - we currently override manually to 1.5MB, but maybe it makes sense to just use logic this everywhere

I am hesitant to bump the default stack sizes further. This was discussed before in #98007

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area-VM-meta-mono 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.

Default stack size Mono vs CoreCLR

3 participants

Comments