Skip to content

Commit 6b761e5

Browse files
authored
Merge pull request #375 from AkihiroSuda/runc-1.3.2
cgroup2: cpu shares: follow the behavior of runc v1.3.2
2 parents 751ce28 + 6b170ea commit 6b761e5

File tree

2 files changed

+63
-2
lines changed

2 files changed

+63
-2
lines changed

cgroup2/utils.go

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,35 @@ func parseCgroupFromReader(r io.Reader) (string, error) {
146146
return "", fmt.Errorf("cgroup path not found")
147147
}
148148

149+
// ConvertCPUSharesToCgroupV2Value converts CPU shares, used by cgroup v1,
150+
// to CPU weight, used by cgroup v2.
151+
//
152+
// Cgroup v1 CPU shares has a range of [2^1...2^18], i.e. [2...262144],
153+
// and the default value is 1024.
154+
//
155+
// Cgroup v2 CPU weight has a range of [10^0...10^4], i.e. [1...10000],
156+
// and the default value is 100.
157+
//
158+
// Taken from https://github.com/opencontainers/cgroups/blob/v0.0.5/utils.go#L417-L441
159+
// (Apache License 2.0)
160+
func ConvertCPUSharesToCgroupV2Value(cpuShares uint64) uint64 {
161+
// The value of 0 means "unset".
162+
if cpuShares == 0 {
163+
return 0
164+
}
165+
if cpuShares <= 2 {
166+
return 1
167+
}
168+
if cpuShares >= 262144 {
169+
return 10000
170+
}
171+
l := math.Log2(float64(cpuShares))
172+
// Quadratic function which fits min, max, and default.
173+
exponent := (l*l+125*l)/612.0 - 7.0/34.0
174+
175+
return uint64(math.Ceil(math.Pow(10, exponent)))
176+
}
177+
149178
// ToResources converts the oci LinuxResources struct into a
150179
// v2 Resources type for use with this package.
151180
//
@@ -159,7 +188,7 @@ func ToResources(spec *specs.LinuxResources) *Resources {
159188
Mems: cpu.Mems,
160189
}
161190
if shares := cpu.Shares; shares != nil {
162-
convertedWeight := 1 + ((*shares-2)*9999)/262142
191+
convertedWeight := ConvertCPUSharesToCgroupV2Value(*shares)
163192
resources.CPU.Weight = &convertedWeight
164193
}
165194
if period := cpu.Period; period != nil {

cgroup2/utils_test.go

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,38 @@ full avg10=1.00 avg60=1.01 avg300=1.00 total=157622356`
7575
assert.Equal(t, &st.Full, &expected.Full)
7676
}
7777

78+
// TestConvertCPUSharesToCgroupV2Value tests the ConvertCPUSharesToCgroupV2Value function.
79+
// Taken from https://github.com/opencontainers/cgroups/blob/v0.0.5/utils_test.go#L537-L564
80+
// (Apache License 2.0)
81+
func TestConvertCPUSharesToCgroupV2Value(t *testing.T) {
82+
const (
83+
sharesMin = 2
84+
sharesMax = 262144
85+
sharesDef = 1024
86+
weightMin = 1
87+
weightMax = 10000
88+
weightDef = 100
89+
unset = 0
90+
)
91+
cases := map[uint64]uint64{
92+
unset: unset,
93+
94+
sharesMin - 1: weightMin, // Below the minimum (out of range).
95+
sharesMin: weightMin, // Minimum.
96+
sharesMin + 1: weightMin + 1, // Just above the minimum.
97+
sharesDef: weightDef, // Default.
98+
sharesMax - 1: weightMax, // Just below the maximum.
99+
sharesMax: weightMax, // Maximum.
100+
sharesMax + 1: weightMax, // Above the maximum (out of range).
101+
}
102+
for shares, want := range cases {
103+
got := ConvertCPUSharesToCgroupV2Value(shares)
104+
if got != want {
105+
t.Errorf("ConvertCPUSharesToCgroupV2Value(%d): got %d, want %d", shares, got, want)
106+
}
107+
}
108+
}
109+
78110
func TestToResources(t *testing.T) {
79111
var (
80112
quota int64 = 8000
@@ -84,7 +116,7 @@ func TestToResources(t *testing.T) {
84116
mem int64 = 300
85117
swap int64 = 500
86118
)
87-
weight := 1 + ((shares-2)*9999)/262142
119+
weight := ConvertCPUSharesToCgroupV2Value(shares)
88120
res := specs.LinuxResources{
89121
CPU: &specs.LinuxCPU{Quota: &quota, Period: &period, Shares: &shares},
90122
Memory: &specs.LinuxMemory{Limit: &mem, Swap: &swap},

0 commit comments

Comments
 (0)