-
Notifications
You must be signed in to change notification settings - Fork 4.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Profiler] Avoid Recursive ThreadStoreLock in Profiling Thread Enumerator #110548
[Profiler] Avoid Recursive ThreadStoreLock in Profiling Thread Enumerator #110548
Conversation
Do we need a test for this? |
Profiling Enumerators look to acquire the ThreadStoreLock. In release config, re-acquiring the ThreadStoreLock and releasing it in ProfilerThreadEnum::Init will cause problems if the callback invoking EnumThread has logic that depends on the ThreadStoreLock being held. To avoid recursively acquiring the ThreadStoreLock, expand the condition when the profiling thread enumerator shouldn't acquire the ThreadStoreLock.
There was a potential race condition when setting the flag before suspending and resetting the flag after restarting. For example, if the thread restarting runtime is preempted right after resuming runtime, the flag could remain unset by the time another thread looks to suspend runtime, which would see that the flag as set.
cd6f6f5
to
d56d8bb
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
Given that this test should run quickly when it passes, and its expected failure case is when it hangs/deadlocks, is there a straightforward way to set a quick timeout for this test instead of hitting CI's timeouts? And is there a way to hit such a timeout in a local run via corerun? @davmason @jkotas |
The problem with timeouts is you can't check them in because we run a lot of tests in various modes (GCStress, JITStress, etc) that can make them take 10+ minutes. For this kind of thing what I have done in the past is make the timeout short locally and run it in a loop on your dev machine to build confidence, but leave the timeout unchanged in the tree. |
/backport to release/9.0-staging |
Started backporting to release/9.0-staging: https://github.com/dotnet/runtime/actions/runs/12303767691 |
…ator (dotnet#110548) * [Profiler] Avoid Recursive ThreadStoreLock Profiling Enumerators look to acquire the ThreadStoreLock. In release config, re-acquiring the ThreadStoreLock and releasing it in ProfilerThreadEnum::Init will cause problems if the callback invoking EnumThread has logic that depends on the ThreadStoreLock being held. To avoid recursively acquiring the ThreadStoreLock, expand the condition when the profiling thread enumerator shouldn't acquire the ThreadStoreLock. * [Profiler] Change order to set fProfilerRequestedRuntimeSuspend There was a potential race condition when setting the flag before suspending and resetting the flag after restarting. For example, if the thread restarting runtime is preempted right after resuming runtime, the flag could remain unset by the time another thread looks to suspend runtime, which would see that the flag as set. * [Profiler][Tests] Add unit test for EnumThreads during suspension * [Profiler][Tests] Fixup EnumThreads test
Fixes #110062
Profiling Enumerators look to acquire the ThreadStoreLock.
In release config, re-acquiring the ThreadStoreLock and releasing it in ProfilerThreadEnum::Init will cause problems if the callback invoking EnumThread has logic that depends on the ThreadStoreLock being held.
For example, invoking
EnumThread
withinRuntimeSuspendFinished
will violate the expectation that the ThreadStoreLock is held until RestartEE is called, demonstrated in #110062This PR aims to avoid recursively acquiring the ThreadStoreLock by expanding the known scnearios where the profiling thread enumerator shouldn't acquire the ThreadStoreLock.