cgroup2: add CpuMax conversion

Fix #2243

Signed-off-by: Akihiro Suda <akihiro.suda.cz@hco.ntt.co.jp>
This commit is contained in:
Akihiro Suda 2020-03-10 02:20:17 +09:00
parent 64e9a97981
commit aa269315a4
5 changed files with 67 additions and 0 deletions

View File

@ -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

View File

@ -609,3 +609,18 @@ func ConvertCPUSharesToCgroupV2Value(cpuShares uint64) uint64 {
}
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
}
if quota <= 0 {
return fmt.Sprintf("max %d", period)
}
return fmt.Sprintf("%d %d", quota, period)
}

View File

@ -485,3 +485,48 @@ func TestConvertCPUSharesToCgroupV2Value(t *testing.T) {
}
}
}
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)
}
}
}

View File

@ -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
}

View File

@ -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