[lxc-devel] [lxd/master] Cgroup package
tomponline on Github
lxc-bot at linuxcontainers.org
Mon Oct 7 10:24:22 UTC 2019
A non-text attachment was scrubbed...
Name: not available
Type: text/x-mailbox
Size: 469 bytes
Desc: not available
URL: <http://lists.linuxcontainers.org/pipermail/lxc-devel/attachments/20191007/2671b1da/attachment.bin>
-------------- next part --------------
From dc7e4e4845381f21e7d64432d77ffd7695dd92ec Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parrott at canonical.com>
Date: Mon, 7 Oct 2019 11:22:49 +0100
Subject: [PATCH 1/2] lxd/cgroup: Adds cgroup package with CPU task balancing
functions
Signed-off-by: Thomas Parrott <thomas.parrott at canonical.com>
---
lxd/cgroup/cgroup_cpu.go | 83 ++++++++++++++++++++++++++++++++++++++++
1 file changed, 83 insertions(+)
create mode 100644 lxd/cgroup/cgroup_cpu.go
diff --git a/lxd/cgroup/cgroup_cpu.go b/lxd/cgroup/cgroup_cpu.go
new file mode 100644
index 0000000000..e8d6be0530
--- /dev/null
+++ b/lxd/cgroup/cgroup_cpu.go
@@ -0,0 +1,83 @@
+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) (string, string, string, error) {
+ var err error
+
+ // Parse priority
+ cpuShares := 0
+ cpuPriorityInt := 10
+ if cpuPriority != "" {
+ cpuPriorityInt, err = strconv.Atoi(cpuPriority)
+ if err != nil {
+ return "", "", "", err
+ }
+ }
+ cpuShares -= 10 - cpuPriorityInt
+
+ // Parse allowance
+ cpuCfsQuota := "-1"
+ cpuCfsPeriod := "100000"
+
+ if cpuAllowance != "" {
+ if strings.HasSuffix(cpuAllowance, "%") {
+ // Percentage based allocation
+ percent, err := strconv.Atoi(strings.TrimSuffix(cpuAllowance, "%"))
+ if err != nil {
+ return "", "", "", err
+ }
+
+ cpuShares += (10 * percent) + 24
+ } else {
+ // Time based allocation
+ fields := strings.SplitN(cpuAllowance, "/", 2)
+ if len(fields) != 2 {
+ return "", "", "", fmt.Errorf("Invalid allowance: %s", cpuAllowance)
+ }
+
+ quota, err := strconv.Atoi(strings.TrimSuffix(fields[0], "ms"))
+ if err != nil {
+ return "", "", "", err
+ }
+
+ period, err := strconv.Atoi(strings.TrimSuffix(fields[1], "ms"))
+ if err != nil {
+ return "", "", "", err
+ }
+
+ // Set limit in ms
+ cpuCfsQuota = fmt.Sprintf("%d", quota*1000)
+ cpuCfsPeriod = fmt.Sprintf("%d", period*1000)
+ cpuShares += 1024
+ }
+ } else {
+ // Default is 100%
+ cpuShares += 1024
+ }
+
+ // Deal with a potential negative score
+ if cpuShares < 0 {
+ cpuShares = 0
+ }
+
+ return fmt.Sprintf("%d", cpuShares), cpuCfsQuota, cpuCfsPeriod, nil
+}
From f7a2cb7fb5d1193ab4dbfab48830bbc629c534f9 Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parrott at canonical.com>
Date: Mon, 7 Oct 2019 11:23:16 +0100
Subject: [PATCH 2/2] lxd: Updates to use cgroup package
Signed-off-by: Thomas Parrott <thomas.parrott at canonical.com>
---
lxd/container_lxc.go | 13 ++++----
lxd/devices.go | 76 ++------------------------------------------
2 files changed, 9 insertions(+), 80 deletions(-)
diff --git a/lxd/container_lxc.go b/lxd/container_lxc.go
index f2c7195b69..ea9819c744 100644
--- a/lxd/container_lxc.go
+++ b/lxd/container_lxc.go
@@ -26,6 +26,7 @@ import (
yaml "gopkg.in/yaml.v2"
"github.com/lxc/lxd/lxd/apparmor"
+ "github.com/lxc/lxd/lxd/cgroup"
"github.com/lxc/lxd/lxd/cluster"
"github.com/lxc/lxd/lxd/db"
"github.com/lxc/lxd/lxd/db/query"
@@ -1326,7 +1327,7 @@ func (c *containerLXC) initLXC(config bool) error {
cpuAllowance := c.expandedConfig["limits.cpu.allowance"]
if (cpuPriority != "" || cpuAllowance != "") && c.state.OS.CGroupCPUController {
- cpuShares, cpuCfsQuota, cpuCfsPeriod, err := deviceParseCPU(cpuAllowance, cpuPriority)
+ cpuShares, cpuCfsQuota, cpuCfsPeriod, err := cgroup.ParseCPU(cpuAllowance, cpuPriority)
if err != nil {
return err
}
@@ -2612,7 +2613,7 @@ func (c *containerLXC) OnStart() error {
}
// Trigger a rebalance
- deviceTaskSchedulerTrigger("container", c.name, "started")
+ cgroup.TaskSchedulerTrigger("container", c.name, "started")
// Apply network priority
if c.expandedConfig["limits.network.priority"] != "" {
@@ -2964,7 +2965,7 @@ func (c *containerLXC) OnStop(target string) error {
}
// Trigger a rebalance
- deviceTaskSchedulerTrigger("container", c.name, "stopped")
+ cgroup.TaskSchedulerTrigger("container", c.name, "stopped")
// Destroy ephemeral containers
if c.ephemeral {
@@ -4126,7 +4127,7 @@ func (c *containerLXC) Update(args db.InstanceArgs, userRequested bool) error {
}
c.cConfig = false
c.initLXC(true)
- deviceTaskSchedulerTrigger("container", c.name, "changed")
+ cgroup.TaskSchedulerTrigger("container", c.name, "changed")
}
}()
@@ -4505,7 +4506,7 @@ func (c *containerLXC) Update(args db.InstanceArgs, userRequested bool) error {
}
} else if key == "limits.cpu" {
// Trigger a scheduler re-run
- deviceTaskSchedulerTrigger("container", c.name, "changed")
+ cgroup.TaskSchedulerTrigger("container", c.name, "changed")
} else if key == "limits.cpu.priority" || key == "limits.cpu.allowance" {
// Skip if no cpu CGroup
if !c.state.OS.CGroupCPUController {
@@ -4513,7 +4514,7 @@ func (c *containerLXC) Update(args db.InstanceArgs, userRequested bool) error {
}
// Apply new CPU limits
- cpuShares, cpuCfsQuota, cpuCfsPeriod, err := deviceParseCPU(c.expandedConfig["limits.cpu.allowance"], c.expandedConfig["limits.cpu.priority"])
+ cpuShares, cpuCfsQuota, cpuCfsPeriod, err := cgroup.ParseCPU(c.expandedConfig["limits.cpu.allowance"], c.expandedConfig["limits.cpu.priority"])
if err != nil {
return err
}
diff --git a/lxd/devices.go b/lxd/devices.go
index aeecf4a69a..6b161e21fd 100644
--- a/lxd/devices.go
+++ b/lxd/devices.go
@@ -14,6 +14,7 @@ import (
"golang.org/x/sys/unix"
+ "github.com/lxc/lxd/lxd/cgroup"
"github.com/lxc/lxd/lxd/device"
"github.com/lxc/lxd/lxd/state"
"github.com/lxc/lxd/shared"
@@ -22,8 +23,6 @@ import (
log "github.com/lxc/lxd/shared/log15"
)
-var deviceSchedRebalance = make(chan []string, 2)
-
type deviceTaskCPU struct {
id int
strId string
@@ -476,7 +475,7 @@ func deviceEventListener(s *state.State) {
networkAutoAttach(s.Cluster, e[0])
case e := <-chUSB:
device.USBRunHandlers(s, &e)
- case e := <-deviceSchedRebalance:
+ case e := <-cgroup.DeviceSchedRebalance:
if len(e) != 3 {
logger.Errorf("Scheduler: received an invalid rebalance event")
continue
@@ -533,15 +532,6 @@ func devicesRegister(s *state.State) {
}
}
-func deviceTaskSchedulerTrigger(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
- }
-}
-
func deviceNextInterfaceHWAddr() (string, error) {
// Generate a new random MAC address using the usual prefix
ret := bytes.Buffer{}
@@ -559,65 +549,3 @@ func deviceNextInterfaceHWAddr() (string, error) {
return ret.String(), nil
}
-
-func deviceParseCPU(cpuAllowance string, cpuPriority string) (string, string, string, error) {
- var err error
-
- // Parse priority
- cpuShares := 0
- cpuPriorityInt := 10
- if cpuPriority != "" {
- cpuPriorityInt, err = strconv.Atoi(cpuPriority)
- if err != nil {
- return "", "", "", err
- }
- }
- cpuShares -= 10 - cpuPriorityInt
-
- // Parse allowance
- cpuCfsQuota := "-1"
- cpuCfsPeriod := "100000"
-
- if cpuAllowance != "" {
- if strings.HasSuffix(cpuAllowance, "%") {
- // Percentage based allocation
- percent, err := strconv.Atoi(strings.TrimSuffix(cpuAllowance, "%"))
- if err != nil {
- return "", "", "", err
- }
-
- cpuShares += (10 * percent) + 24
- } else {
- // Time based allocation
- fields := strings.SplitN(cpuAllowance, "/", 2)
- if len(fields) != 2 {
- return "", "", "", fmt.Errorf("Invalid allowance: %s", cpuAllowance)
- }
-
- quota, err := strconv.Atoi(strings.TrimSuffix(fields[0], "ms"))
- if err != nil {
- return "", "", "", err
- }
-
- period, err := strconv.Atoi(strings.TrimSuffix(fields[1], "ms"))
- if err != nil {
- return "", "", "", err
- }
-
- // Set limit in ms
- cpuCfsQuota = fmt.Sprintf("%d", quota*1000)
- cpuCfsPeriod = fmt.Sprintf("%d", period*1000)
- cpuShares += 1024
- }
- } else {
- // Default is 100%
- cpuShares += 1024
- }
-
- // Deal with a potential negative score
- if cpuShares < 0 {
- cpuShares = 0
- }
-
- return fmt.Sprintf("%d", cpuShares), cpuCfsQuota, cpuCfsPeriod, nil
-}
More information about the lxc-devel
mailing list