Merge pull request #104689 from cynepco3hahue/memory_manager_restricted_policy_fix

kubelet: memory manager: fix preferred topology hints calculation
This commit is contained in:
Kubernetes Prow Robot 2021-10-05 06:47:08 -07:00 committed by GitHub
commit c91f9bdc60
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 119 additions and 19 deletions

View File

@ -438,28 +438,10 @@ func (p *staticPolicy) calculateHints(machineState state.NUMANodeMap, pod *v1.Po
maskBits := mask.GetBits()
singleNUMAHint := len(maskBits) == 1
// the node already in group with another node, it can not be used for the single NUMA node allocation
if singleNUMAHint && len(machineState[maskBits[0]].Cells) > 1 {
return
}
totalFreeSize := map[v1.ResourceName]uint64{}
totalAllocatableSize := map[v1.ResourceName]uint64{}
// calculate total free memory for the node mask
// calculate total free and allocatable memory for the node mask
for _, nodeID := range maskBits {
// the node already used for the memory allocation
if !singleNUMAHint && machineState[nodeID].NumberOfAssignments > 0 {
// the node used for the single NUMA memory allocation, it can not be used for the multi NUMA node allocation
if len(machineState[nodeID].Cells) == 1 {
return
}
// the node already used with different group of nodes, it can not be use with in the current hint
if !areGroupsEqual(machineState[nodeID].Cells, maskBits) {
return
}
}
for resourceName := range requestedResources {
if _, ok := totalFreeSize[resourceName]; !ok {
totalFreeSize[resourceName] = 0
@ -485,6 +467,26 @@ func (p *staticPolicy) calculateHints(machineState state.NUMANodeMap, pod *v1.Po
minAffinitySize = mask.Count()
}
// the node already in group with another node, it can not be used for the single NUMA node allocation
if singleNUMAHint && len(machineState[maskBits[0]].Cells) > 1 {
return
}
for _, nodeID := range maskBits {
// the node already used for the memory allocation
if !singleNUMAHint && machineState[nodeID].NumberOfAssignments > 0 {
// the node used for the single NUMA memory allocation, it can not be used for the multi NUMA node allocation
if len(machineState[nodeID].Cells) == 1 {
return
}
// the node already used with different group of nodes, it can not be use with in the current hint
if !areGroupsEqual(machineState[nodeID].Cells, maskBits) {
return
}
}
}
// verify that for all memory types the node mask has enough free resources
for resourceName, requestedSize := range requestedResources {
podReusableMemory := p.getPodReusableMemory(pod, mask, resourceName)

View File

@ -3049,6 +3049,104 @@ func TestStaticPolicyGetTopologyHints(t *testing.T) {
},
expectedTopologyHints: nil,
},
{
description: "should not return preferred hints with multiple NUMA nodes for the pod with resources satisfied by a single NUMA node",
assignments: state.ContainerMemoryAssignments{
"pod1": map[string][]state.Block{
"container1": {
{
NUMAAffinity: []int{0, 1},
Type: v1.ResourceMemory,
Size: 2 * gb,
},
{
NUMAAffinity: []int{0, 1},
Type: hugepages2M,
Size: 24 * mb,
},
},
},
},
machineState: state.NUMANodeMap{
0: &state.NUMANodeState{
MemoryMap: map[v1.ResourceName]*state.MemoryTable{
v1.ResourceMemory: {
Allocatable: 1536 * mb,
Free: 0,
Reserved: 1536 * mb,
SystemReserved: 512 * mb,
TotalMemSize: 2 * gb,
},
hugepages2M: {
Allocatable: 20 * mb,
Free: 0,
Reserved: 20 * mb,
SystemReserved: 0,
TotalMemSize: 20 * mb,
},
},
Cells: []int{0, 1},
NumberOfAssignments: 2,
},
1: &state.NUMANodeState{
MemoryMap: map[v1.ResourceName]*state.MemoryTable{
v1.ResourceMemory: {
Allocatable: 1536 * mb,
Free: gb,
Reserved: 512 * mb,
SystemReserved: 512 * mb,
TotalMemSize: 2 * gb,
},
hugepages2M: {
Allocatable: 20 * mb,
Free: 16 * mb,
Reserved: 4 * mb,
SystemReserved: 0,
TotalMemSize: 20 * mb,
},
},
Cells: []int{0, 1},
NumberOfAssignments: 2,
},
},
pod: getPod("pod2",
"container2",
&v1.ResourceRequirements{
Limits: v1.ResourceList{
v1.ResourceCPU: resource.MustParse("1000Mi"),
v1.ResourceMemory: resource.MustParse("1Gi"),
hugepages2M: resource.MustParse("16Mi"),
},
Requests: v1.ResourceList{
v1.ResourceCPU: resource.MustParse("1000Mi"),
v1.ResourceMemory: resource.MustParse("1Gi"),
hugepages2M: resource.MustParse("16Mi"),
},
},
),
systemReserved: systemReservedMemory{
0: map[v1.ResourceName]uint64{
v1.ResourceMemory: 512 * mb,
},
1: map[v1.ResourceName]uint64{
v1.ResourceMemory: 512 * mb,
},
},
expectedTopologyHints: map[string][]topologymanager.TopologyHint{
string(v1.ResourceMemory): {
{
NUMANodeAffinity: newNUMAAffinity(0, 1),
Preferred: false,
},
},
hugepages2M: {
{
NUMANodeAffinity: newNUMAAffinity(0, 1),
Preferred: false,
},
},
},
},
}
for _, testCase := range testCases {