Skip to content

[release/10.0] Configurable EventPipe CPU sampling rate#128843

Open
steveisok wants to merge 2 commits into
dotnet:release/10.0from
steveisok:backport/pr-127292-coreclr-to-release/10.0
Open

[release/10.0] Configurable EventPipe CPU sampling rate#128843
steveisok wants to merge 2 commits into
dotnet:release/10.0from
steveisok:backport/pr-127292-coreclr-to-release/10.0

Conversation

@steveisok
Copy link
Copy Markdown
Member

@steveisok steveisok commented Jun 1, 2026

Note

This pull request was prepared with assistance from GitHub Copilot.

Backport of the CoreCLR / NativeAOT portion of #127292 to release/10.0.

Customer Impact

  • [] Customer reported
  • Found internally

Cosmic has reported dramatic overhead when trying to enable the sample profiler due to our default sampling rate being too high. They saw this change land in main and requested we backport to 10 so that they can override to a lower sampling rate.

Regression

  • Yes
  • No

Testing

Added a functional test to change the default sampling rate and make sure it lines up with what was expected.

Risk

Low - this only activates with the DOTNET_EventPipeThreadSamplingRate environment variable.

Add configurable EventPipe CPU sampling rate via DOTNET_EventPipeThreadSamplingRate
for CoreCLR and NativeAOT.

This is a partial backport of dotnet#127292 (4e8ab2d) including:
- src/coreclr/inc/clrconfigvalues.h: register INTERNAL_EventPipeThreadSamplingRate
- src/coreclr/vm/eventing/eventpipe/ep-rt-coreclr.h: CoreCLR implementation
  + PROFILING_SUPPORTED guard fix on ep_rt_notify_profiler_provider_created
- src/coreclr/nativeaot/Runtime/eventpipe/ep-rt-aot.h: NativeAOT implementation
- src/native/eventpipe/ep-rt.h: shared declaration
- src/native/eventpipe/ep.c: consume configured rate in ep_init
- src/mono/mono/eventpipe/ep-rt-mono.h: minimal stub so Mono build of ep.c stays green

Excluded from this backport: Browser/WASM build integration (WasmApp.InTree.props,
Microsoft.NET.Sdk.WebAssembly.Browser.targets), ep-rt-mono-runtime-provider.c
cleanup, ds-ipc-pal-websocket.h browser fixes, and the ep-session.c assert.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@steveisok
Copy link
Copy Markdown
Member Author

I need to change the PR description to the typical backport template

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR backports the CoreCLR/NativeAOT portion of #127292 onto release/10.0, adding a DOTNET_EventPipeThreadSamplingRate configuration knob so the EventPipe CPU sample profiler interval can be overridden from the default (1ms).

Changes:

  • Adds a new CoreCLR config value (INTERNAL_EventPipeThreadSamplingRate) and runtime-specific implementations to read the sampling interval (ms).
  • Updates EventPipe initialization to apply the configured sampling rate (ms → ns), falling back to platform defaults when unset/0.
  • Includes a small CoreCLR PROFILING_SUPPORTED guard adjustment for ep_rt_notify_profiler_provider_created, plus a Mono stub implementation to keep shared native EventPipe code building.

Reviewed changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
src/coreclr/inc/clrconfigvalues.h Registers INTERNAL_EventPipeThreadSamplingRate CoreCLR knob (ms, 0 = default).
src/coreclr/vm/eventing/eventpipe/ep-rt-coreclr.h Implements CoreCLR getter via CLRConfig and adjusts profiler-provider notification guard.
src/coreclr/nativeaot/Runtime/eventpipe/ep-rt-aot.h Implements NativeAOT getter via RhConfig::Environment::TryGetIntegerValue (decimal).
src/native/eventpipe/ep-rt.h Declares ep_rt_config_value_get_sampling_rate() in the shared runtime abstraction.
src/native/eventpipe/ep.c Reads the configured sampling rate in ep_init and applies it (ms → ns).
src/mono/mono/eventpipe/ep-rt-mono.h Adds a Mono implementation reading DOTNET_/COMPlus_EventPipeThreadSamplingRate for build compatibility.

Comment thread src/coreclr/nativeaot/Runtime/eventpipe/ep-rt-aot.h
@pavelsavara
Copy link
Copy Markdown
Member

It would be good to test it on Net11 on non-wasm OS before we backport it.

Adds a CoreCLR runtime test under src/tests/tracing/eventpipe/samplingrate
that verifies the new DOTNET_EventPipeThreadSamplingRate config knob actually
changes the EventPipe CPU sample profiler interval.

Design:
- Two-process: parent spawns a child with DOTNET_EventPipeThreadSamplingRate=50
  set in the child process environment (the runtime reads the value in ep_init
  during startup, so it must be set before the .NET process launches).
- Child runs IpcTraceTest.RunAndValidateEventCounts against itself, subscribes
  to Microsoft-DotNETCore-SampleProfiler, burns CPU for ~3 seconds, then
  inspects ThreadSample events.
- Validation on the busiest sampled thread:
    * count >= 30  (sanity: sampling actually happened)
    * count <= 600 (rejects the default ~1ms rate which produces ~1500/3s)
    * median inter-sample interval >= 20ms (rejects the default ~1ms rate)

Verified locally on osx-arm64:
  with env var:    36 samples/thread, median 85ms -> PASS
  without env var: 1573 samples/thread             -> FAIL (correct rejection)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings June 1, 2026 13:28
@steveisok
Copy link
Copy Markdown
Member Author

Note

This comment was authored with assistance from GitHub Copilot.

Added a regression test in 8277aea covering the new DOTNET_EventPipeThreadSamplingRate knob.

Test: src/tests/tracing/eventpipe/samplingrate/

Design — two-process, same binary:

  • Parent spawns a child via Process.Start with DOTNET_EventPipeThreadSamplingRate=50 set in StartInfo.Environment (the runtime reads the value in ep_init during startup, so it has to be set before the .NET process launches).
  • Child runs IpcTraceTest.RunAndValidateEventCounts against itself, subscribes to Microsoft-DotNETCore-SampleProfiler, burns CPU for ~3 s, then inspects ThreadSample events (provider name + event ID 0, to avoid relying on the friendly event name).
  • Validation on the busiest sampled thread:
    • count >= 30 — sanity: sampling actually happened
    • count <= 600 — rejects the default ~1 ms rate (which produces ~1500 samples/thread in 3 s)
    • median inter-sample interval >= 20 ms — also rejects the default ~1 ms rate

Local verification on osx-arm64:

  • With env var set: 36 samples/thread, median interval 85 ms → PASS
  • Without env var (i.e. knob ignored): 1573 samples/thread → FAIL with the targeted error message

This is intended to be upstreamed to main as a follow-up if the backport lands.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 8 out of 8 changed files in this pull request and generated 2 comments.

Comment thread src/tests/tracing/eventpipe/samplingrate/samplingrate.cs
Comment thread src/tests/tracing/eventpipe/samplingrate/samplingrate.csproj
@steveisok steveisok added the Servicing-consider Issue for next servicing release review label Jun 2, 2026
@steveisok steveisok changed the title [release/10.0] Backport CoreCLR portion of #127292: configurable EventPipe CPU sampling rate [release/10.0] Configurable EventPipe CPU sampling rate Jun 2, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area-Tracing-coreclr Servicing-consider Issue for next servicing release review

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants