Merge pull request #2248 from AkihiroSuda/fix-cgroupv2-conversion
cgroup2: fix conversion
This commit is contained in:
commit
525b9f311c
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
@ -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
|
||||
}
|
||||
if quota <= 0 {
|
||||
return fmt.Sprintf("max %d", period)
|
||||
}
|
||||
return fmt.Sprintf("%d %d", quota, period)
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue