@@ -21,10 +21,23 @@ import (
21
21
22
22
"k8s.io/api/core/v1"
23
23
"k8s.io/klog"
24
+ cputopology "k8s.io/kubernetes/pkg/kubelet/cm/cpumanager/topology"
24
25
"k8s.io/kubernetes/pkg/kubelet/cm/topologymanager/socketmask"
25
26
"k8s.io/kubernetes/pkg/kubelet/lifecycle"
26
27
)
27
28
29
+ const (
30
+ // maxAllowableNUMANodes specifies the maximum number of NUMA Nodes that
31
+ // the TopologyManager supports on the underlying machine.
32
+ //
33
+ // At present, having more than this number of NUMA Nodes will result in a
34
+ // state explosion when trying to enumerate possible NUMAAffinity masks and
35
+ // generate hints for them. As such, if more NUMA Nodes than this are
36
+ // present on a machine and the TopologyManager is enabled, an error will
37
+ // be returned and the TopologyManager will not be loaded.
38
+ maxAllowableNUMANodes = 8
39
+ )
40
+
28
41
//Manager interface provides methods for Kubelet to manage pod topology hints
29
42
type Manager interface {
30
43
//Manager implements pod admit handler interface
@@ -50,6 +63,8 @@ type manager struct {
50
63
podMap map [string ]string
51
64
//Topology Manager Policy
52
65
policy Policy
66
+ //List of NUMA Nodes available on the underlying machine
67
+ numaNodes []int
53
68
}
54
69
55
70
//HintProvider interface is to be implemented by Hint Providers
@@ -73,7 +88,7 @@ type TopologyHint struct {
73
88
var _ Manager = & manager {}
74
89
75
90
//NewManager creates a new TopologyManager based on provided policy
76
- func NewManager (topologyPolicyName string ) (Manager , error ) {
91
+ func NewManager (numaNodeInfo cputopology. NUMANodeInfo , topologyPolicyName string ) (Manager , error ) {
77
92
klog .Infof ("[topologymanager] Creating topology manager with %s policy" , topologyPolicyName )
78
93
var policy Policy
79
94
@@ -92,6 +107,15 @@ func NewManager(topologyPolicyName string) (Manager, error) {
92
107
return nil , fmt .Errorf ("unknown policy: \" %s\" " , topologyPolicyName )
93
108
}
94
109
110
+ var numaNodes []int
111
+ for node := range numaNodeInfo {
112
+ numaNodes = append (numaNodes , node )
113
+ }
114
+
115
+ if len (numaNodes ) > maxAllowableNUMANodes {
116
+ return nil , fmt .Errorf ("unsupported on machines with more than %v NUMA Nodes" , maxAllowableNUMANodes )
117
+ }
118
+
95
119
var hp []HintProvider
96
120
pth := make (map [string ]map [string ]TopologyHint )
97
121
pm := make (map [string ]string )
@@ -100,6 +124,7 @@ func NewManager(topologyPolicyName string) (Manager, error) {
100
124
podTopologyHints : pth ,
101
125
podMap : pm ,
102
126
policy : policy ,
127
+ numaNodes : numaNodes ,
103
128
}
104
129
105
130
return manager , nil
@@ -149,12 +174,9 @@ func (m *manager) iterateAllProviderTopologyHints(allProviderHints [][]TopologyH
149
174
150
175
// Merge the hints from all hint providers to find the best one.
151
176
func (m * manager ) calculateAffinity (pod v1.Pod , container v1.Container ) TopologyHint {
152
- // Set the default hint to return from this function as an any-numa
153
- // affinity with an unpreferred allocation. This will only be returned if
154
- // no better hint can be found when merging hints from each hint provider.
155
- defaultAffinity , _ := socketmask .NewSocketMask ()
156
- defaultAffinity .Fill ()
157
- defaultHint := TopologyHint {defaultAffinity , false }
177
+ // Set the default affinity as an any-numa affinity containing the list
178
+ // of NUMA Nodes available on this machine.
179
+ defaultAffinity , _ := socketmask .NewSocketMask (m .numaNodes ... )
158
180
159
181
// Loop through all hint providers and save an accumulated list of the
160
182
// hints returned by each hint provider. If no hints are provided, assume
@@ -167,27 +189,21 @@ func (m *manager) calculateAffinity(pod v1.Pod, container v1.Container) Topology
167
189
// If hints is nil, insert a single, preferred any-numa hint into allProviderHints.
168
190
if len (hints ) == 0 {
169
191
klog .Infof ("[topologymanager] Hint Provider has no preference for NUMA affinity with any resource" )
170
- affinity , _ := socketmask .NewSocketMask ()
171
- affinity .Fill ()
172
- allProviderHints = append (allProviderHints , []TopologyHint {{affinity , true }})
192
+ allProviderHints = append (allProviderHints , []TopologyHint {{defaultAffinity , true }})
173
193
continue
174
194
}
175
195
176
196
// Otherwise, accumulate the hints for each resource type into allProviderHints.
177
197
for resource := range hints {
178
198
if hints [resource ] == nil {
179
199
klog .Infof ("[topologymanager] Hint Provider has no preference for NUMA affinity with resource '%s'" , resource )
180
- affinity , _ := socketmask .NewSocketMask ()
181
- affinity .Fill ()
182
- allProviderHints = append (allProviderHints , []TopologyHint {{affinity , true }})
200
+ allProviderHints = append (allProviderHints , []TopologyHint {{defaultAffinity , true }})
183
201
continue
184
202
}
185
203
186
204
if len (hints [resource ]) == 0 {
187
205
klog .Infof ("[topologymanager] Hint Provider has no possible NUMA affinities for resource '%s'" , resource )
188
- affinity , _ := socketmask .NewSocketMask ()
189
- affinity .Fill ()
190
- allProviderHints = append (allProviderHints , []TopologyHint {{affinity , false }})
206
+ allProviderHints = append (allProviderHints , []TopologyHint {{defaultAffinity , false }})
191
207
continue
192
208
}
193
209
@@ -199,8 +215,8 @@ func (m *manager) calculateAffinity(pod v1.Pod, container v1.Container) Topology
199
215
// hints in each permutation by taking the bitwise-and of their affinity masks.
200
216
// Return the hint with the narrowest NUMANodeAffinity of all merged
201
217
// permutations that have at least one NUMA ID set. If no merged mask can be
202
- // found that has at least one NUMA ID set, return the 'defaultHint '.
203
- bestHint := defaultHint
218
+ // found that has at least one NUMA ID set, return the 'defaultAffinity '.
219
+ bestHint := TopologyHint { defaultAffinity , false }
204
220
m .iterateAllProviderTopologyHints (allProviderHints , func (permutation []TopologyHint ) {
205
221
// Get the NUMANodeAffinity from each hint in the permutation and see if any
206
222
// of them encode unpreferred allocations.
@@ -217,8 +233,7 @@ func (m *manager) calculateAffinity(pod v1.Pod, container v1.Container) Topology
217
233
}
218
234
219
235
// Merge the affinities using a bitwise-and operation.
220
- mergedAffinity , _ := socketmask .NewSocketMask ()
221
- mergedAffinity .Fill ()
236
+ mergedAffinity , _ := socketmask .NewSocketMask (m .numaNodes ... )
222
237
mergedAffinity .And (numaAffinities ... )
223
238
224
239
// Build a mergedHintfrom the merged affinity mask, indicating if an
0 commit comments