runc/patch/0019-runc-support-set-cpuset.prefer_cpus-using-cpuset-cpu.patch
2023-09-06 16:18:19 +08:00

152 lines
4.4 KiB
Diff

From da50f7d9ddf912a6e4ad8714e5aff01e85c09b21 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 | 118 +++++++++++++++++++++++++++++-
1 file changed, 114 insertions(+), 4 deletions(-)
diff --git a/libcontainer/cgroups/fs/cpuset.go b/libcontainer/cgroups/fs/cpuset.go
index 939b72c..ef9164b 100644
--- a/libcontainer/cgroups/fs/cpuset.go
+++ b/libcontainer/cgroups/fs/cpuset.go
@@ -26,16 +26,126 @@ func (s *CpusetGroup) Apply(path string, r *configs.Resources, pid int) error {
return s.ApplyDir(path, r, pid)
}
-func (s *CpusetGroup) Set(path string, r *configs.Resources) error {
- var ret error
- if r.CpusetCpus != "" {
- if err := cgroups.WriteFile(path, "cpuset.cpus", r.CpusetCpus); err != nil {
+func parseCpus(cpus string) (map[int]bool, error) {
+ persedCpus := make(map[int]bool)
+ for _, cpu := range strings.Split(cpus, ",") {
+ invalidFormatError := fmt.Errorf("invalid cpuset format: %s", cpu)
+ if cpuInt, err := strconv.Atoi(cpu); err == nil {
+ if cpuInt < 0 {
+ return nil, invalidFormatError
+ }
+ persedCpus[cpuInt] = true
+ continue
+ }
+
+ 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 < 0 || upper < 0 {
+ 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("/proc/sys/kernel/sched_util_low_pct"); 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
+}
+
+func (s *CpusetGroup) Set(path string, r *configs.Resources) error {
+ var ret error
+ if r.CpusetCpus != "" {
+ return s.setCpuset(path, cgroup.Resources.CpusetCpus)
}
if r.CpusetMems != "" {
if err := cgroups.WriteFile(path, "cpuset.mems", r.CpusetMems); err != nil {
--
2.33.0