Skip to content

Serialize VSD DispatchCache unlinking with cache write lock#128868

Merged
jkotas merged 2 commits into
mainfrom
copilot/vsd-fix-dispatchcache-deadlock
Jun 2, 2026
Merged

Serialize VSD DispatchCache unlinking with cache write lock#128868
jkotas merged 2 commits into
mainfrom
copilot/vsd-fix-dispatchcache-deadlock

Conversation

Copilot AI commented Jun 1, 2026

Copy link
Copy Markdown
Contributor

Collectible ALC teardown can unlink g_resolveCache bucket entries concurrently with Insert/PromoteChainEntry, violating the cache’s single-writer assumption and allowing self-referential chain cycles that hang VSD resolution. This change restores writer serialization for unlink paths.

  • DispatchCache API surface

    • Added DispatchCache::GetWriteLock() (under CHAIN_LOOKUP) to expose the existing cache writer lock for safe external mutation paths.
  • Collectible-unload unlink serialization

    • Wrapped DispatchCache::Iterator::UnlinkEntry() loops with CrstHolder in:
      • VirtualCallStubManager::ResetCache()
      • VirtualCallStubManager::~VirtualCallStubManager()
    • Locking is conditional on CHAIN_LOOKUP, matching where m_writeLock exists and where chain mutation races matter.
  • Resulting invariant

    • All chain mutations (Insert, PromoteChainEntry, unlink purge) are serialized by the same lock.
#ifdef CHAIN_LOOKUP
CrstHolder lh(g_resolveCache->GetWriteLock());
#endif
DispatchCache::Iterator it(g_resolveCache);
while (it.IsValid())
{
    it.UnlinkEntry();
}

Fixes #128859

Co-authored-by: jkotas <6668460+jkotas@users.noreply.github.com>
Copilot AI requested review from Copilot and removed request for Copilot June 1, 2026 22:06
Copilot AI changed the title [WIP] Fix DispatchCache self-loop causing process hang Serialize VSD DispatchCache unlinking with cache write lock Jun 1, 2026
Copilot finished work on behalf of jkotas June 1, 2026 22:07
Copilot AI requested a review from jkotas June 1, 2026 22:07
@dotnet-policy-service

Copy link
Copy Markdown
Contributor

Tagging subscribers to this area: @agocke
See info in area-owners.md if you want to be subscribed.

@jkotas jkotas marked this pull request as ready for review June 1, 2026 22:47
Copilot AI review requested due to automatic review settings June 1, 2026 22:47

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Fixes a race in the VSD DispatchCache where collectible ALC teardown could unlink cache chain entries concurrently with Insert/PromoteChainEntry, breaking the single-writer assumption and producing self-referential chains that hang VSD resolution. The fix exposes the existing cache write lock and acquires it around the two unlink loops invoked during cache reset and manager teardown.

Changes:

  • Expose DispatchCache::GetWriteLock() (under CHAIN_LOOKUP).
  • Take m_writeLock around the Iterator::UnlinkEntry() loops in VirtualCallStubManager::ResetCache() and ~VirtualCallStubManager().

Reviewed changes

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

File Description
src/coreclr/vm/virtualcallstub.h Adds DispatchCache::GetWriteLock() accessor (CHAIN_LOOKUP only) to allow external callers to serialize with cache writers.
src/coreclr/vm/virtualcallstub.cpp Wraps the two DispatchCache::Iterator::UnlinkEntry() loops in ResetCache and the destructor with CrstHolder(g_resolveCache->GetWriteLock()) under CHAIN_LOOKUP.

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

Thanks @jkotas!

@jkotas jkotas enabled auto-merge (squash) June 2, 2026 00:17
@jkotas jkotas merged commit 41a0abd into main Jun 2, 2026
118 checks passed
@jkotas jkotas deleted the copilot/vsd-fix-dispatchcache-deadlock branch June 2, 2026 01:52
@dotnet-milestone-bot dotnet-milestone-bot Bot added this to the 11.0-preview6 milestone Jun 2, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[VSD] DispatchCache self-loop: unlocked UnlinkEntry during collectible ALC unload races Insert → process hang

5 participants