diff options
author | Jan Vorlicek <janvorli@microsoft.com> | 2019-04-26 11:53:41 +0200 |
---|---|---|
committer | Jan Vorlicek <janvorli@microsoft.com> | 2019-04-26 13:55:11 +0200 |
commit | 9733c30b27ca90d3eeb07928df6e6e5861c203bb (patch) | |
tree | 32588addecdfeac9401f3aa232af0d48328c491f /src/gc | |
parent | 9957d039a2ac69bf42fac51b45abae48c1c212d0 (diff) | |
download | coreclr-9733c30b27ca90d3eeb07928df6e6e5861c203bb.tar.gz coreclr-9733c30b27ca90d3eeb07928df6e6e5861c203bb.tar.bz2 coreclr-9733c30b27ca90d3eeb07928df6e6e5861c203bb.zip |
Fix creation of the NUMA node to heap number map
The current implementation assumes that the NUMA nodes of CPUs
used for GC threads form a zero based continous range. However that
doesn't have to be true for cases when user selects only a subset of the
available CPUs for the GC heap threads using the
COMPlus_GCHeapAffinitizeMask or COMPlus_GCHeapAffinitizeRanges. The
selected CPUs may belong only to a subset of NUMA nodes that don't
necessarily start at node 0 or form a continuous range.
This change fixes the algorithm that initializes the
numa_node_to_heap_map lookup array so that it works correctly even in
such cases.
Diffstat (limited to 'src/gc')
-rw-r--r-- | src/gc/gc.cpp | 26 |
1 files changed, 17 insertions, 9 deletions
diff --git a/src/gc/gc.cpp b/src/gc/gc.cpp index bcffca016b..b3bb610be4 100644 --- a/src/gc/gc.cpp +++ b/src/gc/gc.cpp @@ -5195,23 +5195,31 @@ public: } static void init_numa_node_to_heap_map(int nheaps) - { // called right after GCHeap::Init() for each heap is finished - // when numa is not enabled, heap_no_to_numa_node[] are all filled - // with 0s during initialization, and will be treated as one node - numa_node_to_heap_map[0] = 0; - int node_index = 1; + { // Called right after GCHeap::Init() for each heap + // For each NUMA node used by the heaps, the + // numa_node_to_heap_map[numa_node] is set to the first heap number on that node and + // numa_node_to_heap_map[numa_node + 1] is set to the first heap number not on that node + + // Set the start of the heap number range for the first NUMA node + numa_node_to_heap_map[heap_no_to_numa_node[0]] = 0; for (int i=1; i < nheaps; i++) { if (heap_no_to_numa_node[i] != heap_no_to_numa_node[i-1]) - numa_node_to_heap_map[node_index++] = (uint16_t)i; + { + // Set the end of the heap number range for the previous NUMA node + numa_node_to_heap_map[heap_no_to_numa_node[i-1] + 1] = + // Set the start of the heap number range for the current NUMA node + numa_node_to_heap_map[heap_no_to_numa_node[i]] = (uint16_t)i; + } } - numa_node_to_heap_map[node_index] = (uint16_t)nheaps; //mark the end with nheaps + + // Set the end of the heap range for the last NUMA node + numa_node_to_heap_map[heap_no_to_numa_node[nheaps-1] + 1] = (uint16_t)nheaps; //mark the end with nheaps } static void get_heap_range_for_heap(int hn, int* start, int* end) - { // 1-tier/no numa case: heap_no_to_numa_node[] all zeros, - // and treated as in one node. thus: start=0, end=n_heaps + { uint16_t numa_node = heap_no_to_numa_node[hn]; *start = (int)numa_node_to_heap_map[numa_node]; *end = (int)(numa_node_to_heap_map[numa_node+1]); |