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
2 changes: 2 additions & 0 deletions libcontainer/cgroups/fs2/cpu.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,14 @@ import (
)

func setCpu(dirPath string, cgroup *configs.Cgroup) error {
// NOTE: .CpuShares is not used here. Conversion is the caller's responsibility.
if cgroup.Resources.CpuWeight != 0 {
if err := fscommon.WriteFile(dirPath, "cpu.weight", strconv.FormatUint(cgroup.Resources.CpuWeight, 10)); err != nil {
return err
}
}

// NOTE: .CpuQuota and .CpuPeriod are not used here. Conversion is the caller's responsibility.
if cgroup.Resources.CpuMax != "" {
if err := fscommon.WriteFile(dirPath, "cpu.max", cgroup.Resources.CpuMax); err != nil {
return err
Expand Down
23 changes: 22 additions & 1 deletion libcontainer/cgroups/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -592,7 +592,10 @@ func isEINVAL(err error) bool {
// the formula for BlkIOWeight is y = (1 + (x - 10) * 9999 / 990)
// convert linearly from [10-1000] to [1-10000]
func ConvertBlkIOToCgroupV2Value(blkIoWeight uint16) uint64 {
return uint64(1 + (blkIoWeight-10)*9999/990)
if blkIoWeight == 0 {
return 0
}
return uint64(1 + (uint64(blkIoWeight)-10)*9999/990)
}

// Since the OCI spec is designed for cgroup v1, in some cases
Expand All @@ -601,5 +604,23 @@ func ConvertBlkIOToCgroupV2Value(blkIoWeight uint16) uint64 {
// convert from [2-262144] to [1-10000]
// 262144 comes from Linux kernel definition "#define MAX_SHARES (1UL << 18)"
func ConvertCPUSharesToCgroupV2Value(cpuShares uint64) uint64 {
if cpuShares == 0 {
return 0
}
return (1 + ((cpuShares-2)*9999)/262142)
}

// ConvertCPUQuotaCPUPeriodToCgroupV2Value generates cpu.max string.
func ConvertCPUQuotaCPUPeriodToCgroupV2Value(quota int64, period uint64) string {
if quota <= 0 && period == 0 {
return ""
}
if period == 0 {
// This default value is documented in https://www.kernel.org/doc/html/latest/admin-guide/cgroup-v2.html
period = 100000
Comment thread
AkihiroSuda marked this conversation as resolved.
}
if quota <= 0 {
return fmt.Sprintf("max %d", period)
}
return fmt.Sprintf("%d %d", quota, period)
}
73 changes: 73 additions & 0 deletions libcontainer/cgroups/utils_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -457,3 +457,76 @@ func TestGetHugePageSizeImpl(t *testing.T) {
}
}
}

func TestConvertBlkIOToCgroupV2Value(t *testing.T) {
cases := map[uint16]uint64{
0: 0,
10: 1,
1000: 10000,
}
for i, expected := range cases {
got := ConvertBlkIOToCgroupV2Value(i)
if got != expected {
t.Errorf("expected ConvertBlkIOToCgroupV2Value(%d) to be %d, got %d", i, expected, got)
}
}
}

func TestConvertCPUSharesToCgroupV2Value(t *testing.T) {
cases := map[uint64]uint64{
0: 0,
2: 1,
262144: 10000,
}
for i, expected := range cases {
got := ConvertCPUSharesToCgroupV2Value(i)
if got != expected {
t.Errorf("expected ConvertCPUSharesToCgroupV2Value(%d) to be %d, got %d", i, expected, got)
}
}
}

func TestConvertCPUQuotaCPUPeriodToCgroupV2Value(t *testing.T) {
cases := []struct {
quota int64
period uint64
expected string
}{
{
quota: 0,
period: 0,
expected: "",
},
{
quota: -1,
period: 0,
expected: "",
},
{
quota: 1000,
period: 5000,
expected: "1000 5000",
},
{
quota: 0,
period: 5000,
expected: "max 5000",
},
{
quota: -1,
period: 5000,
expected: "max 5000",
},
{
quota: 1000,
period: 0,
expected: "1000 100000",
},
}
for _, c := range cases {
got := ConvertCPUQuotaCPUPeriodToCgroupV2Value(c.quota, c.period)
if got != c.expected {
t.Errorf("expected ConvertCPUQuotaCPUPeriodToCgroupV2Value(%d, %d) to be %s, got %s", c.quota, c.period, c.expected, got)
}
}
}
3 changes: 3 additions & 0 deletions libcontainer/specconv/spec_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -492,6 +492,9 @@ func CreateCgroupConfig(opts *CreateOpts) (*configs.Cgroup, error) {
if r.CPU.Period != nil {
c.Resources.CpuPeriod = *r.CPU.Period
}
//CpuMax is used for cgroupv2 and should be converted
c.Resources.CpuMax = cgroups.ConvertCPUQuotaCPUPeriodToCgroupV2Value(c.Resources.CpuQuota, c.Resources.CpuPeriod)

if r.CPU.RealtimeRuntime != nil {
c.Resources.CpuRtRuntime = *r.CPU.RealtimeRuntime
}
Expand Down
2 changes: 2 additions & 0 deletions update.go
Original file line number Diff line number Diff line change
Expand Up @@ -257,6 +257,8 @@ other options are ignored.
config.Cgroups.Resources.CpuShares = *r.CPU.Shares
//CpuWeight is used for cgroupv2 and should be converted
config.Cgroups.Resources.CpuWeight = cgroups.ConvertCPUSharesToCgroupV2Value(*r.CPU.Shares)
//CpuMax is used for cgroupv2 and should be converted
config.Cgroups.Resources.CpuMax = cgroups.ConvertCPUQuotaCPUPeriodToCgroupV2Value(*r.CPU.Quota, *r.CPU.Period)
config.Cgroups.Resources.CpuRtPeriod = *r.CPU.RealtimePeriod
config.Cgroups.Resources.CpuRtRuntime = *r.CPU.RealtimeRuntime
config.Cgroups.Resources.CpusetCpus = r.CPU.Cpus
Expand Down