Change:
p.cpusToReuse[string(pod.UID)] = p.cpusToReuse[string(pod.UID)].Difference(cset) } <del> func (p *staticPolicy) Allocate(s state.State, pod *v1.Pod, container *v1.Container) error { if numCPUs := p.guaranteedCPUs(pod, container); numCPUs != 0 { klog.InfoS("Static policy: Allocate", "pod", klog.KObj(pod), "containerName", container.Name) // container belongs in an exclusively allocated pool if p.options.FullPhysicalCPUsOnly && ((numCPUs % p.topology.CPUsPerCore()) != 0) { // Since CPU Manager has been enabled requesting strict SMT alignment, it means a guaranteed pod can only be admitted // if the CPU requested is a multiple of the number of virtual cpus per physical cores. // In case CPU request is not a multiple of the number of virtual cpus per physical cores the Pod will be put // in Failed state, with SMTAlignmentError as reason. Since the allocation happens in terms of physical cores // and the scheduler is responsible for ensuring that the workload goes to a node that has enough CPUs, // the pod would be placed on a node where there are enough physical cores available to be allocated. // Just like the behaviour in case of static policy, takeByTopology will try to first allocate CPUs from the same socket // and only in case the request cannot be sattisfied on a single socket, CPU allocation is done for a workload to occupy all // CPUs on a physical core. Allocation of individual threads would never have to occur. return SMTAlignmentError{ RequestedCPUs: numCPUs, CpusPerCore:   p.topology.CPUsPerCore(), } } if cpuset, ok := s.GetCPUSet(string(pod.UID), container.Name); ok { p.updateCPUsToReuse(pod, container, cpuset) klog.InfoS("Static policy: container already present in state, skipping", "pod", klog.KObj(pod), "containerName", container.Name) return nil } // Call Topology Manager to get the aligned socket affinity across all hint providers. hint := p.affinity.GetAffinity(string(pod.UID), container.Name) klog.InfoS("Topology Affinity", "pod", klog.KObj(pod), "containerName", container.Name, "affinity", hint) </del> <ins> func (p *staticPolicy) Allocate(s state.State, pod *v1.Pod, container *v1.Container) (rerr error) { numCPUs := p.guaranteedCPUs(pod, container) if numCPUs == 0 { // container belongs in the shared pool (nothing to do; use default cpuset) return nil } </ins> <del> // Allocate CPUs according to the NUMA affinity contained in the hint. cpuset, err := p.allocateCPUs(s, numCPUs, hint.NUMANodeAffinity, p.cpusToReuse[string(pod.UID)]) if err != nil { klog.ErrorS(err, "Unable to allocate CPUs", "pod", klog.KObj(pod), "containerName", container.Name, "numCPUs", numCPUs) return err </del> <ins> klog.InfoS("Static policy: Allocate", "pod", klog.KObj(pod), "containerName", container.Name) // container belongs in an exclusively allocated pool metrics.CPUManagerPinningRequestsTotal.Inc() defer func() { if rerr != nil { metrics.CPUManagerPinningErrorsTotal.Inc() } }() if p.options.FullPhysicalCPUsOnly && ((numCPUs % p.topology.CPUsPerCore()) != 0) { // Since CPU Manager has been enabled requesting strict SMT alignment, it means a guaranteed pod can only be admitted // if the CPU requested is a multiple of the number of virtual cpus per physical cores. // In case CPU request is not a multiple of the number of virtual cpus per physical cores the Pod will be put // in Failed state, with SMTAlignmentError as reason. Since the allocation happens in terms of physical cores // and the scheduler is responsible for ensuring that the workload goes to a node that has enough CPUs, // the pod would be placed on a node where there are enough physical cores available to be allocated. // Just like the behaviour in case of static policy, takeByTopology will try to first allocate CPUs from the same socket // and only in case the request cannot be sattisfied on a single socket, CPU allocation is done for a workload to occupy all // CPUs on a physical core. Allocation of individual threads would never have to occur. return SMTAlignmentError{ RequestedCPUs: numCPUs, CpusPerCore:   p.topology.CPUsPerCore(), </ins> } <del> s.SetCPUSet(string(pod.UID), container.Name, cpuset) </del> <ins> } if cpuset, ok := s.GetCPUSet(string(pod.UID), container.Name); ok { </ins> p.updateCPUsToReuse(pod, container, cpuset) <ins> klog.InfoS("Static policy: container already present in state, skipping", "pod", klog.KObj(pod), "containerName", container.Name) return nil } // Call Topology Manager to get the aligned socket affinity across all hint providers. hint := p.affinity.GetAffinity(string(pod.UID), container.Name) klog.InfoS("Topology Affinity", "pod", klog.KObj(pod), "containerName", container.Name, "affinity", hint) // Allocate CPUs according to the NUMA affinity contained in the hint. cpuset, err := p.allocateCPUs(s, numCPUs, hint.NUMANodeAffinity, p.cpusToReuse[string(pod.UID)]) if err != nil { klog.ErrorS(err, "Unable to allocate CPUs", "pod", klog.KObj(pod), "containerName", container.Name, "numCPUs", numCPUs) return err </ins> } <del> // container belongs in the shared pool (nothing to do; use default cpuset) </del> <ins> s.SetCPUSet(string(pod.UID), container.Name, cpuset) p.updateCPUsToReuse(pod, container, cpuset) </ins> return nil }

Discussion:
Add to enable observability of the cpumanager. This is required to but it's also useful in general. To the best of my knowledge, it's very hard to observe the behavior of cpumanager without peeking into the pod and/or use the podresources interface (kubelet = 1.24). But even for the latter, no well known components expose metrics consuming this information. I believe anyway kubelet some expose some basic metrics about cpumanager behaviour, while deferring more fine grained metrics to external components (NFD, node_exporter, is fine)
/sig node /assign
/triage accepted /priority important-soon (as this is important for graduation for CPU Manager to GA)