Repository: opencontainers/runc
File: libcontainer/cgroups/utils.go (Go)

Code before:
	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]
// 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)
}

// ConvertMemorySwapToCgroupV2Value converts MemorySwap value from OCI spec
// for use by cgroup v2 drivers. A conversion is needed since Resources.MemorySwap
// is defined as memory+swap combined, while in cgroup v2 swap is a separate value,
// so we need to subtract memory from it where it makes sense.
func ConvertMemorySwapToCgroupV2Value(memorySwap, memory int64) (int64, error) {
	// For compatibility with cgroup1 controller, set swap to unlimited in
	// case the memory is set to unlimited, and swap is not explicitly set,
	// treating the request as "set both memory and swap to unlimited".
	if memory == -1 && memorySwap == 0 {
		return -1, nil
	}
	if memorySwap == -1 || memorySwap == 0 || // Treat -1 ("max") and 0 ("unset") swap as is.
		memory == -1 { // Unlimited memory, so treat swap as is.
		return memorySwap, nil
	}
	if memory == 0 { // Unset or unknown -- can't calculate swap.
		return 0, errors.New("unable to set swap limit without memory limit")
	}
	if memory < 0 { // Does not make sense to subtract negative value.
		return 0, fmt.Errorf("invalid memory value: %d", memory)
	}
	if memorySwap < memory {
		return 0, errors.New("memory+swap limit should be >= memory limit")
	}

	return memorySwap - memory, nil
}

// 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 BlkIOWeight to IOWeight is y = (1 + (x - 10) * 9999 / 990)
// convert linearly from [10-1000] to [1-10000]
func ConvertBlkIOToIOWeightValue(blkIoWeight uint16) uint64 {
	if blkIoWeight == 0 {
		return 0
	}

Review comment (suggestion):
So what this basically means is that I don't have a way to set the swap limit to 0 if the memory limit is set to unlimited.

This seems a bit confusing. If I'm trying to set the swap limit to 0 while allowing unlimited memory for an important container, I end up with a container that has unlimited swap instead.

Code after:
	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]
// 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)
}

// ConvertMemorySwapToCgroupV2Value converts MemorySwap value from OCI spec
// for use by cgroup v2 drivers. A conversion is needed since Resources.MemorySwap
// is defined as memory+swap combined, while in cgroup v2 swap is a separate value,
// so we need to subtract memory from it where it makes sense.
func ConvertMemorySwapToCgroupV2Value(memorySwap, memory int64) (int64, error) {
	switch {
	case memory == -1 && memorySwap == 0:
		// For compatibility with cgroup1 controller, set swap to unlimited in
		// case the memory is set to unlimited and the swap is not explicitly set,
		// treating the request as "set both memory and swap to unlimited".
		return -1, nil
	case memorySwap == -1, memorySwap == 0:
		// Treat -1 ("max") and 0 ("unset") swap as is.
		return memorySwap, nil
	case memory == -1:
		// Unlimited memory, so treat swap as is.
		return memorySwap, nil
	case memory == 0:
		// Unset or unknown memory, can't calculate swap.
		return 0, errors.New("unable to set swap limit without memory limit")
	case memory < 0:
		// Does not make sense to subtract a negative value.
		return 0, fmt.Errorf("invalid memory value: %d", memory)
	case memorySwap < memory:
		// Sanity check.
		return 0, errors.New("memory+swap limit should be >= memory limit")
	}

	return memorySwap - memory, nil
}

// 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 BlkIOWeight to IOWeight is y = (1 + (x - 10) * 9999 / 990)
// convert linearly from [10-1000] to [1-10000]
func ConvertBlkIOToIOWeightValue(blkIoWeight uint16) uint64 {