File: cgroup_cpu.go

package info (click to toggle)
incus 6.0.5-2
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 24,428 kB
  • sloc: sh: 16,313; ansic: 3,121; python: 457; makefile: 337; ruby: 51; sql: 50; lisp: 6
file content (92 lines) | stat: -rw-r--r-- 2,164 bytes parent folder | download | duplicates (7)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
package cgroup

import (
	"fmt"
	"strconv"
	"strings"
)

// DeviceSchedRebalance channel for scheduling a CPU rebalance.
var DeviceSchedRebalance = make(chan []string, 2)

// TaskSchedulerTrigger triggers a CPU rebalance.
func TaskSchedulerTrigger(srcType string, srcName string, srcStatus string) {
	// Spawn a go routine which then triggers the scheduler
	select {
	case DeviceSchedRebalance <- []string{srcType, srcName, srcStatus}:
	default:
		// Channel is full, drop the event
	}
}

// ParseCPU parses CPU allowances.
func ParseCPU(cpuAllowance string, cpuPriority string) (int64, int64, int64, error) {
	var err error

	// Max shares depending on backend.
	maxShares := int64(1024)
	if cgControllers["cpu"] == V2 {
		maxShares = 100
	}

	// Parse priority
	cpuShares := int64(0)
	cpuPriorityInt := 10
	if cpuPriority != "" {
		cpuPriorityInt, err = strconv.Atoi(cpuPriority)
		if err != nil {
			return -1, -1, -1, err
		}
	}
	cpuShares -= int64(10 - cpuPriorityInt)

	// Parse allowance
	cpuCfsQuota := int64(-1)
	cpuCfsPeriod := int64(100000)
	if cgControllers["cpu"] == V2 {
		cpuCfsPeriod = -1
	}

	if cpuAllowance != "" {
		if strings.HasSuffix(cpuAllowance, "%") {
			// Percentage based allocation
			percent, err := strconv.Atoi(strings.TrimSuffix(cpuAllowance, "%"))
			if err != nil {
				return -1, -1, -1, err
			}

			cpuShares += int64(float64(maxShares) / float64(100) * float64(percent))
		} else {
			// Time based allocation
			fields := strings.SplitN(cpuAllowance, "/", 2)
			if len(fields) != 2 {
				return -1, -1, -1, fmt.Errorf("Invalid allowance: %s", cpuAllowance)
			}

			quota, err := strconv.Atoi(strings.TrimSuffix(fields[0], "ms"))
			if err != nil {
				return -1, -1, -1, err
			}

			period, err := strconv.Atoi(strings.TrimSuffix(fields[1], "ms"))
			if err != nil {
				return -1, -1, -1, err
			}

			// Set limit in ms
			cpuCfsQuota = int64(quota * 1000)
			cpuCfsPeriod = int64(period * 1000)
			cpuShares += maxShares
		}
	} else {
		// Default is 100%
		cpuShares += maxShares
	}

	// Deal with a potential negative score
	if cpuShares < 0 {
		cpuShares = 0
	}

	return cpuShares, cpuCfsQuota, cpuCfsPeriod, nil
}