[release/10.0] Use lock-free reads for ETW rundown versions - #133084
Conversation
The current ETW rundown code holds a `CodeVersionManager` lock across the full JIT method enumeration and ETW event emission. This can block JIT paths and delay code execution. This code change removes rundown-wide `CodeVersionManager` lock and instead relies on lock-free reads of published native-code version state. It builds on PR established published version state and lock-free read-only version lookups. It is noteworthy that a concurrent ReJIT or tiering update may cause rundown to skip over a newly inserted node or skip a record when code-address validation fails (if it is in the middle of an update). The benefit of a `CodeVersionManager` lock-free rundown likely outweighs guaranteeing a globally atomic rundown snapshot. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --------- Copilot-Session: 08e6544d-6999-41a6-85b2-cbd9ea6fe071
|
Azure Pipelines: Successfully started running 3 pipeline(s). 13 pipeline(s) were filtered out due to trigger conditions. There may be pipelines that require an authorized user to comment /azp run to run. |
|
Tagging subscribers to this area: @steveisok, @tommcdon, @dotnet/dotnet-diag |
There was a problem hiding this comment.
🔵 Needs a closer look
It introduces lock-free/concurrent-read behavior in CoreCLR ETW rundown and code-versioning paths, which warrants final human validation for subtle race-condition correctness.
Pull request overview
This backport reduces CoreCLR ETW rundown lock contention by avoiding holding the CodeVersionManager lock across JIT method enumeration and event emission, instead relying on lock-free reads of published code-version state.
Changes:
- Add
MethodDesc::GetNativeCodeVolatile()for lock-free, volatile reads of a method’s current native code pointer. - Update ETW JIT rundown to tolerate concurrent publication of code-version state and skip unstable/in-progress updates.
- Make key code-version state reads volatile (native code pointer and first-version-node pointers) to support lock-free enumeration.
File summaries
| File | Description |
|---|---|
| src/coreclr/vm/method.hpp | Declares GetNativeCodeVolatile() (non-DAC) for volatile native-code pointer reads. |
| src/coreclr/vm/method.cpp | Implements GetNativeCodeVolatile() using VolatileLoad for slot/native-code reads. |
| src/coreclr/vm/eventtrace.cpp | Removes the requirement to hold the code-versioning lock during rundown; adds validation against volatile native-code reads when version state isn’t yet visible. |
| src/coreclr/vm/codeversion.cpp | Uses volatile loads for published native-code and version-list head pointers to enable lock-free readers. |
Review details
- Files reviewed: 4/4 changed files
- Comments generated: 0
- Review effort level: Lite
💡 Add a code-review agent skill for context-aware, tailored reviews. Learn more in the docs.
|
@tommcdon, it's approved. Please get code review and check test results once tests are done. |
Backport of #132757 to release/10.0
/cc @tommcdon
Customer Impact
Reported by an internal partner team. Applications with large numbers of JIT-compiled methods can spend several seconds performing ETW rundown while holding the global code-versioning lock. JIT paths that need the same lock can be delayed for the duration of rundown, blocking code execution.
Regression
No. This fixes longstanding lock contention in the ETW rundown implementation.
Testing
Risk