-
Notifications
You must be signed in to change notification settings - Fork 4.7k
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
Guard against -1 Returned from sysconf for the Cache Sizes Causing Large Gen0 Sizes and Budgets for Certain Linux Distributions. #100502
Conversation
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.
Looks good to me as a minimal delta fix for servicing backport.
(I do not particularly like how some of the local variables are used in the macro, but others are not. It makes the code hard to follow. Cleaning it up is not necessary for the servicing fix.)
/backport to release/8.0 |
Started backporting to release/8.0: https://github.com/dotnet/runtime/actions/runs/8533880062 |
/backport to release/8.0-staging |
Started backporting to release/8.0-staging: https://github.com/dotnet/runtime/actions/runs/8533996443 |
I completely agree that it would be good to eventually clean this up. Macros using ambient stuff are always difficult to follow, debug and reason about. |
Addressed: #100596 |
…rge Gen0 Sizes and Budgets for Certain Linux Distributions. (dotnet#100502) * Logging. * Fixed comparison check * Fix logical operations * Completely guard against the cacheSize as UINTMAX_MAX * Fix for right macro * Ensure we are guarded against all cases where cacheSize == SIZE_MAX * Added an extra guard and removed redundant case * Comment clean * Added some additional asserts * Removed unnecessary checks for cacheSize == SIZE_MAX * Cleaned up logic * Fix type casting comparison * Removed redundant comment * Removed one more unneccesary guard
Possibly cause of |
…rge Gen0 Sizes and Budgets for Certain Linux Distributions. (dotnet#100502) * Logging. * Fixed comparison check * Fix logical operations * Completely guard against the cacheSize as UINTMAX_MAX * Fix for right macro * Ensure we are guarded against all cases where cacheSize == SIZE_MAX * Added an extra guard and removed redundant case * Comment clean * Added some additional asserts * Removed unnecessary checks for cacheSize == SIZE_MAX * Cleaned up logic * Fix type casting comparison * Removed redundant comment * Removed one more unneccesary guard
Issue Summary
GetLogicalProcessorCacheSizeFromOS
retrieves a bogus value ofSIZE_MAX
(-1 but type casted to asize_t
) from thesysconf
call for the L4 Cache Size that's now recognized has the last cache size (as it's not 0) causing a significantly larger gen0 size and budget for Debian 12 vs. Debian 11 for the same hardware i.e., same cache sizes, architecture etc. This behavior also seems to show up for Ubuntu 22.04.getconf -a | grep LEVEL4_CACHE
on a Debian 12 (and an Ubuntu 22.04) machine results in an empty string for the L4 cache size - this is different from the behavior of Debian 11 that returns a 0 for the L4 cache size.SIZE_MAX
fromGetLogicalProcessorCacheSizeFromOS
is also returned fromGetCacheSizePerLogicalCpu
and causes an extremely large gen0 size thereby affecting the gen0 budget for Server GC.Further Details
Running
getconf -a | grep LEVEL4_CACHE
Outputs:Debian 11
LEVEL4_CACHE_SIZE 0
LEVEL4_CACHE_ASSOC 0
LEVEL4_CACHE_LINESIZE 0
Debian 12
LEVEL4_CACHE_SIZE
LEVEL4_CACHE_ASSOC
LEVEL4_CACHE_LINESIZE
Ubuntu 20.04
LEVEL4_CACHE_SIZE 0
LEVEL4_CACHE_ASSOC 0
LEVEL4_CACHE_LINESIZE 0
Ubuntu 22.04
LEVEL4_CACHE_SIZE
LEVEL4_CACHE_ASSOC
LEVEL4_CACHE_LINESIZE
How To Detect This Issue
Run
getconf -a | grep LEVEL4_CACHE
and observe if the value for the LEVEL4_CACHE is empty or 0. If it is empty, it indicates that sysconf will return -1 and therefore, we will be susceptible to a large gen0 size and not if it's 0.Solution
-1
from being returned from sysconf that we cast to a size_t and therefore becomesSIZE_MAX
to prevent much larger gen0 sizes and budgets than if -1 wasn't returned from sysconf.Testing
First, we confirmed that running a standalone C program on Debian 11 vs. Debian 12 with code:
Results in:
Debian 11:
Raw LEVEL4 Cache Size: 0
Debian 12:
Raw LEVEL4 Cache Size: 18446744073709551615 or SIZE_MAX
Ubuntu 22.04:
Raw L4 Cache Value: 18446744073709551615 or SIZE_MAX
Additionally, with this fix, the customer confirmed that this fix resulted in their memory going back to previous levels.