-
Notifications
You must be signed in to change notification settings - Fork 4k
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
Checksum's usage of a native hash algorithm resulting in thread starvation #67995
Comments
I couldn't figure out the best area label to add to this issue. If you have write-permissions please help me learn by adding exactly one area label. |
@stephentoub any suggestions on a good way to utilize this api while avoiding this problem? |
Based on the time shown above and the fact that this is already correctly performing on a background thread, I'm OK with leaving this unchanged if any of the following is true:
|
@CyrusNajmabadi Sounds like |
Yup. I'll work on this today. |
On .NET Framework, IncrementalHash uses the OS's implementation of SHA-256, which results in several safe handles being created. These handles are finalizable and can cause lock contention in the CLR if created rapidly, which Razor does. This change adjusts the Checksum.Builder to use the SHA256 class directly on .NET Framework (and netstandard2.0), which causes the managed implementation of SHA256 to be used (if FIPS isn't enabled). That implementation avoids the creation of finalizable safe handles. See dotnet/roslyn#67995 for more detail.
On .NET Framework, IncrementalHash uses the OS's implementation of SHA-256, which results in several safe handles being created. These handles are finalizable and can cause lock contention in the CLR if created rapidly, which Razor does. This change adjusts the Checksum.Builder to use the SHA256 class directly on .NET Framework (and netstandard2.0), which causes the managed implementation of SHA256 to be used (if FIPS isn't enabled). That implementation avoids the creation of finalizable safe handles. See dotnet/roslyn#67995 for more detail. Many thanks to @sharwell for pointing out this issue along with the fix.
Version Used:
Investigating thread starvation in Speedometer's CopyRichNotAccurate, I see Checksum's usage of CAPI SHA256 hash algorithm is one of the cause of the starvations. It appears the following code path instantiates large number of finalizable objects (ie the underlying SafeHandle) on multiple threads at the same in a short burst. This hits a lock in the CLR's CFinalize::RegisterForFinalization causing contention and resulting in a lot of blocked time on the thread pool, 10% of the blocked time on these threads is this bug.
Steps to Reproduce:
I had a look at SHA265Cng and it has a similar path so is likely not the path forward. Maybe the managed version of the algorithm? Or alternative, a custom wrapper around CNG that avoids creating a finalizable safe handle over and over again?
The text was updated successfully, but these errors were encountered: