Skip to content

Commit

Permalink
lib/cgroup: attempt to obtain available CPU cores via /sys/devices/sy…
Browse files Browse the repository at this point in the history
…stem/cpu/online

See #685 (comment)
  • Loading branch information
valyala committed Sep 22, 2020
1 parent 09b0f7c commit 5c42965
Show file tree
Hide file tree
Showing 2 changed files with 75 additions and 0 deletions.
51 changes: 51 additions & 0 deletions lib/cgroup/cpu.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
package cgroup

import (
"io/ioutil"
"os"
"runtime"
"strconv"
"strings"

"github.com/VictoriaMetrics/VictoriaMetrics/lib/logger"
)
Expand Down Expand Up @@ -40,9 +43,57 @@ func getCPUQuota() float64 {
if err != nil {
return 0
}
if quotaUS <= 0 {
// The quota isn't set. This may be the case in multilevel containers.
// See https://github.com/VictoriaMetrics/VictoriaMetrics/issues/685#issuecomment-674423728
return getOnlineCPUCount()
}
periodUS, err := readInt64("/sys/fs/cgroup/cpu/cpu.cfs_period_us", "cat /sys/fs/cgroup/cpu$(cat /proc/self/cgroup | grep cpu, | cut -d: -f3)/cpu.cfs_period_us")
if err != nil {
return 0
}
return float64(quotaUS) / float64(periodUS)
}

func getOnlineCPUCount() float64 {
// See https://github.com/VictoriaMetrics/VictoriaMetrics/issues/685#issuecomment-674423728
data, err := ioutil.ReadFile("/sys/devices/system/cpu/online")
if err != nil {
return -1
}
n := float64(countCPUs(string(data)))
if n <= 0 {
return -1
}
// Add a half of CPU core, since it looks like actual cores is usually bigger than online cores.
// See https://github.com/VictoriaMetrics/VictoriaMetrics/issues/685#issuecomment-674423728
return n + 0.5
}

func countCPUs(data string) int {
data = strings.TrimSpace(data)
n := 0
for _, s := range strings.Split(data, ",") {
n++
if !strings.Contains(s, "-") {
if _, err := strconv.Atoi(s); err != nil {
return -1
}
continue
}
bounds := strings.Split(s, "-")
if len(bounds) != 2 {
return -1
}
start, err := strconv.Atoi(bounds[0])
if err != nil {
return -1
}
end, err := strconv.Atoi(bounds[1])
if err != nil {
return -1
}
n += end - start
}
return n
}
24 changes: 24 additions & 0 deletions lib/cgroup/cpu_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package cgroup

import (
"testing"
)

func TestCountCPUs(t *testing.T) {
f := func(s string, nExpected int) {
t.Helper()
n := countCPUs(s)
if n != nExpected {
t.Fatalf("unexpected result from countCPUs(%q); got %d; want %d", s, n, nExpected)
}
}
f("", -1)
f("1", 1)
f("234", 1)
f("1,2", 2)
f("0-1", 2)
f("0-0", 1)
f("1-2,3,5-9,200-210", 19)
f("0-3", 4)
f("0-6", 7)
}

0 comments on commit 5c42965

Please sign in to comment.