@@ -64,11 +64,24 @@ func (a *cpuAccumulator) freeCPUsInNUMANode(numaID int) []int {
64
64
return a .cpuDetails .CPUsInNUMANodes (numaID ).ToSliceInt ()
65
65
}
66
66
67
- // freeCoresInNUMANode returns free core ids in specified NUMA
67
+ // freeCPUsInNUMANodeReversely returns free cpu ids in specified NUMA,
68
+ // and those returned cpu slices have already been sorted reversely
69
+ func (a * cpuAccumulator ) freeCPUsInNUMANodeReversely (numaID int ) []int {
70
+ return a .cpuDetails .CPUsInNUMANodes (numaID ).ToSliceIntReversely ()
71
+ }
72
+
73
+ // freeCoresInNUMANode returns free core ids in specified NUMA,
74
+ // and those returned cpu slices have already been sorted
68
75
func (a * cpuAccumulator ) freeCoresInNUMANode (numaID int ) []int {
69
76
return a .cpuDetails .CoresInNUMANodes (numaID ).Filter (a .isCoreFree ).ToSliceInt ()
70
77
}
71
78
79
+ // freeCoresInNUMANode returns free core ids in specified NUMA,
80
+ // and those returned cpu slices have already been sorted reversely
81
+ func (a * cpuAccumulator ) freeCoresInNUMANodeReversely (numaID int ) []int {
82
+ return a .cpuDetails .CoresInNUMANodes (numaID ).Filter (a .isCoreFree ).ToSliceIntReversely ()
83
+ }
84
+
72
85
// isSocketFree returns true if the supplied socket is fully available
73
86
func (a * cpuAccumulator ) isSocketFree (socketID int ) bool {
74
87
return a .cpuDetails .CPUsInSockets (socketID ).Size () == a .getTopology ().CPUsPerSocket ()
@@ -301,7 +314,7 @@ successful:
301
314
}
302
315
303
316
// TakeHTByNUMABalance tries to make the allocated cpu spread on different
304
- // sockets , and it uses cpu HT as the basic allocation unit
317
+ // NUMAs , and it uses cpu HT as the basic allocation unit
305
318
func TakeHTByNUMABalance (info * machine.KatalystMachineInfo , availableCPUs machine.CPUSet ,
306
319
cpuRequirement int ,
307
320
) (machine.CPUSet , machine.CPUSet , error ) {
@@ -338,3 +351,55 @@ failed:
338
351
successful:
339
352
return acc .result .Clone (), availableCPUs .Difference (acc .result ), nil
340
353
}
354
+
355
+ // TakeByNUMABalanceReversely tries to make the allocated cpu resersely spread on different
356
+ // NUMAs, and it uses cpu Cores as the basic allocation unit
357
+ func TakeByNUMABalanceReversely (info * machine.KatalystMachineInfo , availableCPUs machine.CPUSet ,
358
+ cpuRequirement int ,
359
+ ) (machine.CPUSet , machine.CPUSet , error ) {
360
+ var err error
361
+ acc := newCPUAccumulator (info , availableCPUs , cpuRequirement )
362
+ if acc .isSatisfied () {
363
+ goto successful
364
+ }
365
+
366
+ for {
367
+ if acc .isFailed () {
368
+ err = fmt .Errorf ("not enough cpus available to satisfy request" )
369
+ goto failed
370
+ }
371
+
372
+ numaLoop:
373
+ for _ , s := range info .CPUDetails .NUMANodes ().ToSliceInt () {
374
+ if acc .needs (acc .getTopology ().CPUsPerCore ()) && len (acc .freeCores ()) > 0 {
375
+ for _ , c := range acc .freeCoresInNUMANodeReversely (s ) {
376
+ acc .take (acc .getDetails ().CPUsInCores (c ))
377
+ if acc .isSatisfied () {
378
+ goto successful
379
+ } else {
380
+ continue numaLoop
381
+ }
382
+ }
383
+ continue
384
+ }
385
+
386
+ for _ , c := range acc .freeCPUsInNUMANodeReversely (s ) {
387
+ if acc .needs (1 ) {
388
+ acc .take (machine .NewCPUSet (c ))
389
+ }
390
+ if acc .isSatisfied () {
391
+ goto successful
392
+ } else {
393
+ break
394
+ }
395
+ }
396
+ }
397
+ }
398
+ failed:
399
+ if err == nil {
400
+ err = errors .New ("failed to allocate cpus" )
401
+ }
402
+ return availableCPUs , availableCPUs , err
403
+ successful:
404
+ return acc .result .Clone (), availableCPUs .Difference (acc .result ), nil
405
+ }
0 commit comments