From 2f0800bd55e13e28042fb9da6d857ecf6a2a57fb Mon Sep 17 00:00:00 2001 From: Krisztian Litkey Date: Mon, 18 Mar 2024 15:44:22 +0200 Subject: [PATCH] cpuallocator: make idle package allocation core type aware. When allocating idle packages, consider a package idle if all online cores *with preferred priorities* for that allocation are idle. Also, from the picked packages take cores with this same restriction. In particular, on hybrid architectures with multiple core types, this will exclude - E-cores from allocations with Priority{Normal,High} preference - P-cores from allocations with PriorityLow preference Signed-off-by: Krisztian Litkey --- pkg/cpuallocator/allocator.go | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/pkg/cpuallocator/allocator.go b/pkg/cpuallocator/allocator.go index df0db47f1..d230c1241 100644 --- a/pkg/cpuallocator/allocator.go +++ b/pkg/cpuallocator/allocator.go @@ -160,7 +160,14 @@ func (a *allocatorHelper) takeIdlePackages() { // pick idle packages pkgs := pickIds(a.sys.PackageIDs(), func(id idset.ID) bool { + // Consider a package idle if all online preferred CPUs are idle. + // In particular, on hybrid core architectures exclude + // - exclude E-cores from allocations with <= PriorityNormal preference + // - exclude P-cores from allocations with > PriorityLow preferences cset := a.topology.pkg[id].Difference(offline) + if a.prefer < NumCPUPriorities { + cset = cset.Intersection(a.topology.cpuPriorities[a.prefer]) + } return cset.Intersection(a.from).Equals(cset) }) @@ -178,6 +185,9 @@ func (a *allocatorHelper) takeIdlePackages() { // take as many idle packages as we need/can for _, id := range pkgs { cset := a.topology.pkg[id].Difference(offline) + if a.prefer < NumCPUPriorities { + cset = cset.Intersection(a.topology.cpuPriorities[a.prefer]) + } a.Debug(" => considering package %v (#%s)...", id, cset) if a.cnt >= cset.Size() { a.Debug(" => taking package %v...", id) @@ -704,9 +714,17 @@ func (c *topologyCache) discoverCPUPriorities(sys sysfs.System) { cpuPriorities = c.discoverCpufreqPriority(sys, id) } + ecores := c.kind[sysfs.EfficientCore] + ocores := sys.OnlineCPUs().Difference(ecores) + for p, cpus := range cpuPriorities { source := map[bool]string{true: "sst", false: "cpufreq"}[sstActive] cset := sysfs.CPUSetFromIDSet(idset.NewIDSet(cpus...)) + + if p != int(PriorityLow) && ocores.Size() > 0 { + cset = cset.Difference(ecores) + } + log.Debug("package #%d (%s): %d %s priority cpus (%v)", id, source, len(cpus), CPUPriority(p), cset) prio[p] = prio[p].Union(cset) }