158 lines
4.6 KiB
Diff
158 lines
4.6 KiB
Diff
From 01519a2176a214dd6da1c217b4c1c8f11007fc61 Mon Sep 17 00:00:00 2001
|
|
From: Vanient <xiadanni1@huawei.com>
|
|
Date: Sat, 7 May 2022 09:39:57 +0800
|
|
Subject: [PATCH] runc: support set cpuset.prefer_cpus using --cpuset-cpus
|
|
|
|
we need to set cpuset.prefer_cpus for performance. Using "+" as
|
|
separator, the cpuset value after separator is the prefer_cpus value.
|
|
|
|
Signed-off-by: Vanient <xiadanni1@huawei.com>
|
|
---
|
|
libcontainer/cgroups/fs/cpuset.go | 116 ++++++++++++++++++++++++++++--
|
|
1 file changed, 112 insertions(+), 4 deletions(-)
|
|
|
|
diff --git a/libcontainer/cgroups/fs/cpuset.go b/libcontainer/cgroups/fs/cpuset.go
|
|
index 76cb719b..28ffbdb6 100644
|
|
--- a/libcontainer/cgroups/fs/cpuset.go
|
|
+++ b/libcontainer/cgroups/fs/cpuset.go
|
|
@@ -8,6 +8,8 @@ import (
|
|
"io/ioutil"
|
|
"os"
|
|
"path/filepath"
|
|
+ "strconv"
|
|
+ "strings"
|
|
|
|
"github.com/Sirupsen/logrus"
|
|
"github.com/opencontainers/runc/libcontainer/cgroups"
|
|
@@ -30,17 +32,123 @@ func (s *CpusetGroup) Apply(d *cgroupData) error {
|
|
return s.ApplyDir(dir, d.config, d.pid)
|
|
}
|
|
|
|
-func (s *CpusetGroup) Set(path string, cgroup *configs.Cgroup) error {
|
|
- var ret error
|
|
- if cgroup.Resources.CpusetCpus != "" {
|
|
- if err := writeFile(path, "cpuset.cpus", cgroup.Resources.CpusetCpus); err != nil {
|
|
+func parseCpus(cpus string) (map[int]bool, error) {
|
|
+ persedCpus := make(map[int]bool)
|
|
+ for _, cpu := range strings.Split(cpus, ",") {
|
|
+ if cpuInt, err := strconv.Atoi(cpu); err == nil {
|
|
+ persedCpus[cpuInt] = true
|
|
+ continue
|
|
+ }
|
|
+
|
|
+ invalidFormatError := fmt.Errorf("invalid cpuset format: %s", cpu)
|
|
+ ranges := strings.Split(cpu, "-")
|
|
+ if len(ranges) != 2 {
|
|
+ return nil, invalidFormatError
|
|
+ }
|
|
+ lower, err1 := strconv.Atoi(ranges[0])
|
|
+ upper, err2 := strconv.Atoi(ranges[1])
|
|
+ if err1 != nil || err2 != nil {
|
|
+ return nil, invalidFormatError
|
|
+ }
|
|
+ if lower > upper {
|
|
+ return nil, invalidFormatError
|
|
+ }
|
|
+ const max = 8192
|
|
+ if upper > max {
|
|
+ return nil, fmt.Errorf("value of out range, maximum is %d", max)
|
|
+ }
|
|
+ for i := lower; i <= upper; i++ {
|
|
+ persedCpus[i] = true
|
|
+ }
|
|
+ }
|
|
+
|
|
+ return persedCpus, nil
|
|
+}
|
|
+
|
|
+func checkInCpuset(cpuset, prefer map[int]bool) bool {
|
|
+ for k := range prefer {
|
|
+ if _, ok := cpuset[k]; !ok {
|
|
+ return false
|
|
+ }
|
|
+ }
|
|
+ return true
|
|
+}
|
|
+
|
|
+func parseCpuset(cpuset string) (string, string, error) {
|
|
+ var cpusetStr, preferCpusStr string
|
|
+ invalidFormatError := fmt.Errorf("invalid cpuset format: %s", cpuset)
|
|
+
|
|
+ splits := strings.Split(cpuset, "+")
|
|
+ if len(splits) == 1 {
|
|
+ cpusetStr = cpuset
|
|
+ } else if len(splits) == 2 {
|
|
+ if !strings.HasSuffix(splits[0], ",") {
|
|
+ return "", "", invalidFormatError
|
|
+ }
|
|
+ cpusetStr = strings.TrimSuffix(splits[0], ",")
|
|
+ preferCpusStr = splits[1]
|
|
+
|
|
+ cpusetMap, err := parseCpus(cpusetStr)
|
|
+ if err != nil {
|
|
+ return "", "", err
|
|
+ }
|
|
+ preferCpusMap, err := parseCpus(preferCpusStr)
|
|
+ if err != nil {
|
|
+ return "", "", err
|
|
+ }
|
|
+ if !checkInCpuset(cpusetMap, preferCpusMap) {
|
|
+ return "", "", fmt.Errorf("invalid preferred_cpus: %s not in cpuset: %s", preferCpusStr, cpusetStr)
|
|
+ }
|
|
+ } else {
|
|
+ return "", "", invalidFormatError
|
|
+ }
|
|
+
|
|
+ return cpusetStr, preferCpusStr, nil
|
|
+}
|
|
+
|
|
+func (s *CpusetGroup) setCpuset(path, cpuset string) error {
|
|
+ if _, err := os.Stat(filepath.Join(path, "cpuset.preferred_cpus")); err != nil {
|
|
+ var ret error
|
|
+ if err := writeFile(path, "cpuset.cpus", cpuset); err != nil {
|
|
ret = fmt.Errorf("failed to set cpuset.cpus, %v", err)
|
|
if _, err := os.Stat(path); err != nil {
|
|
ret = fmt.Errorf("%v, failed to stat %v, %v", ret, path, err)
|
|
}
|
|
return ret
|
|
}
|
|
+ return nil
|
|
+ }
|
|
+
|
|
+ cpusetStr, preferCpusStr, err := parseCpuset(cpuset)
|
|
+ if err != nil {
|
|
+ return err
|
|
+ }
|
|
+
|
|
+ if _, err := os.Stat(path); err != nil {
|
|
+ return fmt.Errorf("failed to stat %v, %v", path, err)
|
|
+ }
|
|
+ if err := writeFile(path, "cpuset.preferred_cpus", ""); err != nil {
|
|
+ return fmt.Errorf("failed to set cpuset.preferred_cpus to nil, %v", err)
|
|
}
|
|
+ if err := writeFile(path, "cpuset.cpus", cpusetStr); err != nil {
|
|
+ return fmt.Errorf("failed to set cpuset.cpus, %v", err)
|
|
+ }
|
|
+ if preferCpusStr != "" {
|
|
+ if err := writeFile(path, "cpuset.preferred_cpus", preferCpusStr); err != nil {
|
|
+ return fmt.Errorf("failed to set cpuset.preferred_cpus, %v", err)
|
|
+ }
|
|
+ }
|
|
+
|
|
+ return nil
|
|
+}
|
|
+
|
|
+// Set sets container cpuset cgroup
|
|
+func (s *CpusetGroup) Set(path string, cgroup *configs.Cgroup) error {
|
|
+ var ret error
|
|
+ if cgroup.Resources.CpusetCpus != "" {
|
|
+ return s.setCpuset(path, cgroup.Resources.CpusetCpus)
|
|
+ }
|
|
+
|
|
if cgroup.Resources.CpusetMems != "" {
|
|
if err := writeFile(path, "cpuset.mems", cgroup.Resources.CpusetMems); err != nil {
|
|
ret = fmt.Errorf("failed to set cpuset.cpus, %v", err)
|
|
--
|
|
2.27.0
|
|
|