Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 21 additions & 6 deletions utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"errors"
"fmt"
"io"
"math"
"os"
"path/filepath"
"strconv"
Expand Down Expand Up @@ -413,16 +414,30 @@ func WriteCgroupProc(dir string, pid int) error {
return err
}

// Since the OCI spec is designed for cgroup v1, in some cases
// there is need to convert from the cgroup v1 configuration to cgroup v2
// the formula for cpuShares is y = (1 + ((x - 2) * 9999) / 262142)
// convert from [2-262144] to [1-10000]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps including the v1 range ([2-262144]) and v2 range ([1-10000]) is worth including in the documentation.

// 262144 comes from Linux kernel definition "#define MAX_SHARES (1UL << 18)"
// ConvertCPUSharesToCgroupV2Value converts CPU shares, used by cgroup v1,
// to CPU weight, used by cgroup v2.
//
// Cgroup v1 CPU shares has a range of [2^1...2^18], i.e. [2...262144],
// and the default value is 1024.
//
// Cgroup v2 CPU weight has a range of [10^0...10^4], i.e. [1...10000],
// and the default value is 100.
func ConvertCPUSharesToCgroupV2Value(cpuShares uint64) uint64 {
// The value of 0 means "unset".
if cpuShares == 0 {
return 0
}
return (1 + ((cpuShares-2)*9999)/262142)
if cpuShares <= 2 {
return 1
}
if cpuShares >= 262144 {
return 10000
}
l := math.Log2(float64(cpuShares))
// Quadratic function which fits min, max, and default.
exponent := (l*l+125*l)/612.0 - 7.0/34.0

return uint64(math.Ceil(math.Pow(10, exponent)))
}

// ConvertMemorySwapToCgroupV2Value converts MemorySwap value from OCI spec
Expand Down
29 changes: 22 additions & 7 deletions utils_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -535,15 +535,30 @@ func TestGetHugePageSizeImpl(t *testing.T) {
}

func TestConvertCPUSharesToCgroupV2Value(t *testing.T) {
const (
sharesMin = 2
sharesMax = 262144
sharesDef = 1024
weightMin = 1
weightMax = 10000
weightDef = 100
unset = 0
)
cases := map[uint64]uint64{
0: 0,
2: 1,
262144: 10000,
unset: unset,

sharesMin - 1: weightMin, // Below the minimum (out of range).
sharesMin: weightMin, // Minimum.
sharesMin + 1: weightMin + 1, // Just above the minimum.
sharesDef: weightDef, // Default.
sharesMax - 1: weightMax, // Just below the maximum.
sharesMax: weightMax, // Maximum.
sharesMax + 1: weightMax, // Above the maximum (out of range).
}
for i, expected := range cases {
got := ConvertCPUSharesToCgroupV2Value(i)
if got != expected {
t.Errorf("expected ConvertCPUSharesToCgroupV2Value(%d) to be %d, got %d", i, expected, got)
for shares, want := range cases {
got := ConvertCPUSharesToCgroupV2Value(shares)
if got != want {
t.Errorf("ConvertCPUSharesToCgroupV2Value(%d): got %d, want %d", shares, got, want)
}
}
}
Expand Down