From 4d76b1c8de798ab7b6f41899749b7918ea101c98 Mon Sep 17 00:00:00 2001 From: nolancon Date: Wed, 22 Jan 2020 09:07:41 +0000 Subject: [PATCH] Add mergeFilteredHints: - Move remaining logic from mergeProvidersHints to generic top level mergeFilteredHints function. - Add numaNodes as parameter in order to make generic. - Move single NUMA node specific check to single-numa-node Merge function. --- pkg/kubelet/cm/topologymanager/policy.go | 47 ++++++++++++++ .../cm/topologymanager/policy_best_effort.go | 58 +---------------- .../cm/topologymanager/policy_restricted.go | 2 +- .../policy_single_numa_node.go | 64 +++---------------- 4 files changed, 60 insertions(+), 111 deletions(-) diff --git a/pkg/kubelet/cm/topologymanager/policy.go b/pkg/kubelet/cm/topologymanager/policy.go index b04062a8d64..8b845578253 100644 --- a/pkg/kubelet/cm/topologymanager/policy.go +++ b/pkg/kubelet/cm/topologymanager/policy.go @@ -93,6 +93,53 @@ func filterProvidersHints(providersHints []map[string][]TopologyHint) [][]Topolo return allProviderHints } +func mergeFilteredHints(numaNodes []int, filteredHints [][]TopologyHint) TopologyHint { + // Set the default affinity as an any-numa affinity containing the list + // of NUMA Nodes available on this machine. + defaultAffinity, _ := bitmask.NewBitMask(numaNodes...) + + // Set the bestHint to return from this function as {nil false}. + // This will only be returned if no better hint can be found when + // merging hints from each hint provider. + bestHint := TopologyHint{defaultAffinity, false} + iterateAllProviderTopologyHints(filteredHints, func(permutation []TopologyHint) { + // Get the NUMANodeAffinity from each hint in the permutation and see if any + // of them encode unpreferred allocations. + mergedHint := mergePermutation(numaNodes, permutation) + // Only consider mergedHints that result in a NUMANodeAffinity > 0 to + // replace the current bestHint. + if mergedHint.NUMANodeAffinity.Count() == 0 { + return + } + + // If the current bestHint is non-preferred and the new mergedHint is + // preferred, always choose the preferred hint over the non-preferred one. + if mergedHint.Preferred && !bestHint.Preferred { + bestHint = mergedHint + return + } + + // If the current bestHint is preferred and the new mergedHint is + // non-preferred, never update bestHint, regardless of mergedHint's + // narowness. + if !mergedHint.Preferred && bestHint.Preferred { + return + } + + // If mergedHint and bestHint has the same preference, only consider + // mergedHints that have a narrower NUMANodeAffinity than the + // NUMANodeAffinity in the current bestHint. + if !mergedHint.NUMANodeAffinity.IsNarrowerThan(bestHint.NUMANodeAffinity) { + return + } + + // In all other cases, update bestHint to the current mergedHint + bestHint = mergedHint + }) + + return bestHint +} + // Iterate over all permutations of hints in 'allProviderHints [][]TopologyHint'. // // This procedure is implemented as a recursive function over the set of hints diff --git a/pkg/kubelet/cm/topologymanager/policy_best_effort.go b/pkg/kubelet/cm/topologymanager/policy_best_effort.go index 2bdf17ba995..1f02094a045 100644 --- a/pkg/kubelet/cm/topologymanager/policy_best_effort.go +++ b/pkg/kubelet/cm/topologymanager/policy_best_effort.go @@ -17,7 +17,6 @@ limitations under the License. package topologymanager import ( - "k8s.io/kubernetes/pkg/kubelet/cm/topologymanager/bitmask" "k8s.io/kubernetes/pkg/kubelet/lifecycle" ) @@ -48,58 +47,7 @@ func (p *bestEffortPolicy) canAdmitPodResult(hint *TopologyHint) lifecycle.PodAd func (p *bestEffortPolicy) Merge(providersHints []map[string][]TopologyHint) (TopologyHint, lifecycle.PodAdmitResult) { filteredProvidersHints := filterProvidersHints(providersHints) - hint := p.mergeProvidersHints(filteredProvidersHints) - admit := p.canAdmitPodResult(&hint) - return hint, admit -} - -// Merge the hints from all hint providers to find the best one. -func (p *bestEffortPolicy) mergeProvidersHints(filteredHints [][]TopologyHint) TopologyHint { - // Set the default affinity as an any-numa affinity containing the list - // of NUMA Nodes available on this machine. - defaultAffinity, _ := bitmask.NewBitMask(p.numaNodes...) - - // Iterate over all permutations of hints in 'allProviderHints'. Merge the - // hints in each permutation by taking the bitwise-and of their affinity masks. - // Return the hint with the narrowest NUMANodeAffinity of all merged - // permutations that have at least one NUMA ID set. If no merged mask can be - // found that has at least one NUMA ID set, return the 'defaultAffinity'. - bestHint := TopologyHint{defaultAffinity, false} - iterateAllProviderTopologyHints(filteredHints, func(permutation []TopologyHint) { - // Get the NUMANodeAffinity from each hint in the permutation and see if any - // of them encode unpreferred allocations. - mergedHint := mergePermutation(p.numaNodes, permutation) - - // Only consider mergedHints that result in a NUMANodeAffinity > 0 to - // replace the current bestHint. - if mergedHint.NUMANodeAffinity.Count() == 0 { - return - } - - // If the current bestHint is non-preferred and the new mergedHint is - // preferred, always choose the preferred hint over the non-preferred one. - if mergedHint.Preferred && !bestHint.Preferred { - bestHint = mergedHint - return - } - - // If the current bestHint is preferred and the new mergedHint is - // non-preferred, never update bestHint, regardless of mergedHint's - // narowness. - if !mergedHint.Preferred && bestHint.Preferred { - return - } - - // If mergedHint and bestHint has the same preference, only consider - // mergedHints that have a narrower NUMANodeAffinity than the - // NUMANodeAffinity in the current bestHint. - if !mergedHint.NUMANodeAffinity.IsNarrowerThan(bestHint.NUMANodeAffinity) { - return - } - - // In all other cases, update bestHint to the current mergedHint - bestHint = mergedHint - }) - - return bestHint + bestHint := mergeFilteredHints(p.numaNodes, filteredProvidersHints) + admit := p.canAdmitPodResult(&bestHint) + return bestHint, admit } diff --git a/pkg/kubelet/cm/topologymanager/policy_restricted.go b/pkg/kubelet/cm/topologymanager/policy_restricted.go index 3a3d062389f..e7882083b98 100644 --- a/pkg/kubelet/cm/topologymanager/policy_restricted.go +++ b/pkg/kubelet/cm/topologymanager/policy_restricted.go @@ -53,7 +53,7 @@ func (p *restrictedPolicy) canAdmitPodResult(hint *TopologyHint) lifecycle.PodAd func (p *restrictedPolicy) Merge(providersHints []map[string][]TopologyHint) (TopologyHint, lifecycle.PodAdmitResult) { filteredHints := filterProvidersHints(providersHints) - hint := p.mergeProvidersHints(filteredHints) + hint := mergeFilteredHints(p.numaNodes, filteredHints) admit := p.canAdmitPodResult(&hint) return hint, admit } diff --git a/pkg/kubelet/cm/topologymanager/policy_single_numa_node.go b/pkg/kubelet/cm/topologymanager/policy_single_numa_node.go index da74c922691..224d4686ac7 100644 --- a/pkg/kubelet/cm/topologymanager/policy_single_numa_node.go +++ b/pkg/kubelet/cm/topologymanager/policy_single_numa_node.go @@ -71,63 +71,17 @@ func filterSingleNumaHints(allResourcesHints [][]TopologyHint) [][]TopologyHint return filteredResourcesHints } -func (p *singleNumaNodePolicy) mergeProvidersHints(filteredHints [][]TopologyHint) TopologyHint { - // Set the default affinity as an any-numa affinity containing the list - // of NUMA Nodes available on this machine. - defaultAffinity, _ := bitmask.NewBitMask(p.numaNodes...) - - // Set the bestHint to return from this function as {nil false}. - // This will only be returned if no better hint can be found when - // merging hints from each hint provider. - bestHint := TopologyHint{defaultAffinity, false} - iterateAllProviderTopologyHints(filteredHints, func(permutation []TopologyHint) { - // Get the NUMANodeAffinity from each hint in the permutation and see if any - // of them encode unpreferred allocations. - mergedHint := mergePermutation(p.numaNodes, permutation) - - // Only consider mergedHints that result in a NUMANodeAffinity > 0 to - // replace the current bestHint. - if mergedHint.NUMANodeAffinity.Count() == 0 { - return - } - - // If the current bestHint is non-preferred and the new mergedHint is - // preferred, always choose the preferred hint over the non-preferred one. - if mergedHint.Preferred && !bestHint.Preferred { - bestHint = mergedHint - return - } - - // If the current bestHint is preferred and the new mergedHint is - // non-preferred, never update bestHint, regardless of mergedHint's - // narowness. - if !mergedHint.Preferred && bestHint.Preferred { - return - } - - // If mergedHint and bestHint has the same preference, only consider - // mergedHints that have a narrower NUMANodeAffinity than the - // NUMANodeAffinity in the current bestHint. - if !mergedHint.NUMANodeAffinity.IsNarrowerThan(bestHint.NUMANodeAffinity) { - return - } - - // In all other cases, update bestHint to the current mergedHint - bestHint = mergedHint - }) - - if bestHint.NUMANodeAffinity.IsEqual(defaultAffinity) { - bestHint = TopologyHint{nil, bestHint.Preferred} - } - - return bestHint -} - func (p *singleNumaNodePolicy) Merge(providersHints []map[string][]TopologyHint) (TopologyHint, lifecycle.PodAdmitResult) { filteredHints := filterProvidersHints(providersHints) // Filter to only include don't cares and hints with a single NUMA node. singleNumaHints := filterSingleNumaHints(filteredHints) - hint := p.mergeProvidersHints(singleNumaHints) - admit := p.canAdmitPodResult(&hint) - return hint, admit + bestHint := mergeFilteredHints(p.numaNodes, singleNumaHints) + + defaultAffinity, _ := bitmask.NewBitMask(p.numaNodes...) + if bestHint.NUMANodeAffinity.IsEqual(defaultAffinity) { + bestHint = TopologyHint{nil, bestHint.Preferred} + } + + admit := p.canAdmitPodResult(&bestHint) + return bestHint, admit }