Skip to content

Commit c48f462

Browse files
committed
nrt: filter: add function to find numa-affine resources
We call "NUMA-affine" resources compute resources like CPU and memory/hugepages which we know they do expose NUMA affinity. This is another attempt to factor this logic in a central place. Signed-off-by: Francesco Romani <[email protected]>
1 parent f7057da commit c48f462

File tree

3 files changed

+63
-15
lines changed

3 files changed

+63
-15
lines changed

pkg/noderesourcetopology/filter.go

Lines changed: 2 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@ import (
2222
v1 "k8s.io/api/core/v1"
2323
"k8s.io/apimachinery/pkg/api/resource"
2424
"k8s.io/klog/v2"
25-
v1helper "k8s.io/kubernetes/pkg/apis/core/v1/helper"
2625
v1qos "k8s.io/kubernetes/pkg/apis/core/v1/helper/qos"
2726
kubeletconfig "k8s.io/kubernetes/pkg/kubelet/apis/config"
2827
bm "k8s.io/kubernetes/pkg/kubelet/cm/topologymanager/bitmask"
@@ -156,21 +155,9 @@ func resourcesAvailableInAnyNUMANodes(lh logr.Logger, numaNodes NUMANodeList, re
156155
}
157156

158157
func isResourceSetSuitable(qos v1.PodQOSClass, resource v1.ResourceName, quantity, numaQuantity resource.Quantity) bool {
159-
// Check for the following:
160-
if qos != v1.PodQOSGuaranteed {
161-
// 1. set numa node as possible node if resource is memory or Hugepages
162-
if resource == v1.ResourceMemory {
163-
return true
164-
}
165-
if v1helper.IsHugePageResourceName(resource) {
166-
return true
167-
}
168-
// 2. set numa node as possible node if resource is CPU
169-
if resource == v1.ResourceCPU {
170-
return true
171-
}
158+
if qos != v1.PodQOSGuaranteed && isNUMAAffineResource(resource) {
159+
return true
172160
}
173-
// 3. otherwise check amount of resources
174161
return numaQuantity.Cmp(quantity) >= 0
175162
}
176163

pkg/noderesourcetopology/numaresources.go

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,3 +35,20 @@ func isHostLevelResource(resource corev1.ResourceName) bool {
3535
}
3636
return false
3737
}
38+
39+
func isNUMAAffineResource(resource corev1.ResourceName) bool {
40+
// NUMA-affine resources are resources which are required to be bound to NUMA nodes.
41+
// A Key example is CPU and memory, which must expose NUMA affinity.
42+
if resource == corev1.ResourceCPU {
43+
return true
44+
}
45+
if resource == corev1.ResourceMemory {
46+
return true
47+
}
48+
if v1helper.IsHugePageResourceName(resource) {
49+
return true
50+
}
51+
// Devices are *expected* to expose NUMA Affinity, but they are not *required* to do so.
52+
// We can't tell for sure, so we default to "no".
53+
return false
54+
}

pkg/noderesourcetopology/numaresources_test.go

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,3 +65,47 @@ func TestIsHostLevelResource(t *testing.T) {
6565
})
6666
}
6767
}
68+
69+
func TestIsNUMAAffineResource(t *testing.T) {
70+
testCases := []struct {
71+
resource corev1.ResourceName
72+
expected bool
73+
}{
74+
{
75+
resource: corev1.ResourceCPU,
76+
expected: true,
77+
},
78+
{
79+
resource: corev1.ResourceMemory,
80+
expected: true,
81+
},
82+
{
83+
resource: corev1.ResourceName("hugepages-1Gi"),
84+
expected: true,
85+
},
86+
{
87+
resource: corev1.ResourceStorage,
88+
expected: false,
89+
},
90+
{
91+
resource: corev1.ResourceEphemeralStorage,
92+
expected: false,
93+
},
94+
{
95+
resource: corev1.ResourceName("vendor.io/fastest-nic"),
96+
expected: false,
97+
},
98+
{
99+
resource: corev1.ResourceName("awesome.com/gpu-for-ai"),
100+
expected: false,
101+
},
102+
}
103+
for _, testCase := range testCases {
104+
t.Run(string(testCase.resource), func(t *testing.T) {
105+
got := isNUMAAffineResource(testCase.resource)
106+
if got != testCase.expected {
107+
t.Fatalf("expected %t to equal %t", got, testCase.expected)
108+
}
109+
})
110+
}
111+
}

0 commit comments

Comments
 (0)