in pkg/noderesourcetopology/filter.go [89:155]
func resourcesAvailableInAnyNUMANodes(lh logr.Logger, numaNodes NUMANodeList, resources v1.ResourceList, qos v1.PodQOSClass, nodeInfo *framework.NodeInfo) (int, bool) {
numaID := highestNUMAID
bitmask := bm.NewEmptyBitMask()
// set all bits, each bit is a NUMA node, if resources couldn't be aligned
// on the NUMA node, bit should be unset
bitmask.Fill()
nodeResources := util.ResourceList(nodeInfo.Allocatable)
for resource, quantity := range resources {
if quantity.IsZero() {
// why bother? everything's fine from the perspective of this resource
lh.V(4).Info("ignoring zero-qty resource request", "resource", resource)
continue
}
if _, ok := nodeResources[resource]; !ok {
// some resources may not expose NUMA affinity (device plugins, extended resources), but all resources
// must be reported at node level; thus, if they are not present at node level, we can safely assume
// we don't have the resource at all.
lh.V(2).Info("early verdict: cannot meet request", "resource", resource, "suitable", "false")
return numaID, false
}
// for each requested resource, calculate which NUMA slots are good fits, and then AND with the aggregated bitmask, IOW unset appropriate bit if we can't align resources, or set it
// obvious, bits which are not in the NUMA id's range would be unset
hasNUMAAffinity := false
resourceBitmask := bm.NewEmptyBitMask()
for _, numaNode := range numaNodes {
numaQuantity, ok := numaNode.Resources[resource]
if !ok {
continue
}
hasNUMAAffinity = true
if !isResourceSetSuitable(qos, resource, quantity, numaQuantity) {
continue
}
resourceBitmask.Add(numaNode.NUMAID)
lh.V(6).Info("feasible", "numaCell", numaNode.NUMAID, "resource", resource)
}
// non-native resources or ephemeral-storage may not expose NUMA affinity,
// but since they are available at node level, this is fine
if !hasNUMAAffinity && isHostLevelResource(resource) {
lh.V(6).Info("resource available at host level (no NUMA affinity)", "resource", resource)
continue
}
bitmask.And(resourceBitmask)
if bitmask.IsEmpty() {
lh.V(2).Info("early verdict", "resource", resource, "suitable", "false")
return numaID, false
}
}
// according to TopologyManager, the preferred NUMA affinity, is the narrowest one.
// https://github.com/kubernetes/kubernetes/blob/v1.24.0-rc.1/pkg/kubelet/cm/topologymanager/policy.go#L155
// in single-numa-node policy all resources should be allocated from a single NUMA,
// which means that the lowest NUMA ID (with available resources) is the one to be selected by Kubelet.
numaID = bitmask.GetBits()[0]
// at least one NUMA node is available
ret := !bitmask.IsEmpty()
lh.V(2).Info("final verdict", "suitable", ret)
return numaID, ret
}