diff --git a/pkg/kubelet/cm/cpumanager/cpu_assignment.go b/pkg/kubelet/cm/cpumanager/cpu_assignment.go index c744cc988af06..fe643a1666020 100644 --- a/pkg/kubelet/cm/cpumanager/cpu_assignment.go +++ b/pkg/kubelet/cm/cpumanager/cpu_assignment.go @@ -24,6 +24,7 @@ import ( "k8s.io/klog/v2" "k8s.io/kubernetes/pkg/kubelet/cm/cpumanager/topology" + "k8s.io/kubernetes/pkg/kubelet/metrics" "k8s.io/utils/cpuset" ) @@ -102,7 +103,7 @@ func min(x, y int) int { type numaOrSocketsFirstFuncs interface { takeFullFirstLevel() takeFullSecondLevel() - takeThirdLevel() + takeThirdLevel() (int, int) sortAvailableNUMANodes() []int sortAvailableSockets() []int sortAvailableUnCoreCaches() []int @@ -128,8 +129,8 @@ func (n *numaFirst) takeFullSecondLevel() { } // In Split L3 Topology, we take from the sets of uncorecache as the third level -func (n *numaFirst) takeThirdLevel() { - n.acc.takeUnCoreCache() +func (n *numaFirst) takeThirdLevel() (int, int) { + return n.acc.takeUnCoreCache() } // If NUMA nodes are higher in the memory hierarchy than sockets, then just @@ -189,8 +190,8 @@ func (s *socketsFirst) takeFullSecondLevel() { s.acc.takeFullNUMANodes() } -func (s *socketsFirst) takeThirdLevel() { - s.acc.takeUnCoreCache() +func (s *socketsFirst) takeThirdLevel() (int, int) { + return s.acc.takeUnCoreCache() } // If sockets are higher in the memory hierarchy than NUMA nodes, then we need @@ -430,8 +431,10 @@ func (a *cpuAccumulator) takeFullUnCore() { // First try to take partial uncorecache (CCD), if available and the request size can fit w/in the uncorecache. // Second try to take the full CCD if available and need is at least the size of the uncorecache group. -func (a *cpuAccumulator) takeUnCoreCache() { +func (a *cpuAccumulator) takeUnCoreCache() (int, int) { // check if SMT ON + part := 0 + full := 0 for _, uncore := range a.allUnCoreCache() { numCoresNeeded := a.numCPUsNeeded / a.topo.CPUsPerCore() // this is another new change @@ -447,14 +450,18 @@ func (a *cpuAccumulator) takeUnCoreCache() { if a.numCPUsNeeded == freeCPUsInUncorecache.Size() { klog.V(4).InfoS("takePartialUncore: claiming cores from Uncorecache ID", "uncore", uncore) a.take(freeCPUsInUncorecache) + part += 1 } // take full Uncorecache if the numCPUsNeeded is greater the L3 cache size a.takeFullUnCore() + full += 1 if a.isSatisfied() { - return + return part, full } } + + return part, full } func (a *cpuAccumulator) takeFullCores() { @@ -614,8 +621,11 @@ func takeByTopologyUnCoreCachePacked(topo *topology.CPUTopology, availableCPUs c // 2. Acquire partial uncorecache, if there are enough CPUs available to satisfy the container requirement // Acquire the full uncorecache, if available and the container requires at least all the CPUs in the uncorecache grouping - acc.numaOrSocketsFirst.takeThirdLevel() + part, full := acc.numaOrSocketsFirst.takeThirdLevel() if acc.isSatisfied() { + if part == 0 && full > 0 { + metrics.ContainerAlignedComputeResources.WithLabelValues(metrics.AlignedL3CacheGroup).Inc() + } return acc.result, nil } diff --git a/pkg/kubelet/metrics/metrics.go b/pkg/kubelet/metrics/metrics.go index c024da5906a65..3529d102d354e 100644 --- a/pkg/kubelet/metrics/metrics.go +++ b/pkg/kubelet/metrics/metrics.go @@ -128,8 +128,9 @@ const ( InitContainer = "init_container" EphemeralContainer = "ephemeral_container" - AlignedPhysicalCPU = "physical_cpu" - AlignedNUMAZone = "numa_zone" + AlignedPhysicalCPU = "physical_cpu" + AlignedNUMAZone = "numa_zone" + AlignedL3CacheGroup = "l3_cache_group" ) var ( @@ -836,7 +837,7 @@ var ( Help: "Cumulative number of aligned compute resources allocated to containers by alignment type.", StabilityLevel: metrics.ALPHA, }, - []string{"physical_cpu", "numa_zone"}, + []string{"physical_cpu", "l3_cache_group", "numa_zone"}, ) )