82 lines
2.7 KiB
Go
82 lines
2.7 KiB
Go
/*
|
|
Copyright 2022 The Crossplane Authors.
|
|
|
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
you may not use this file except in compliance with the License.
|
|
You may obtain a copy of the License at
|
|
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
Unless required by applicable law or agreed to in writing, software
|
|
distributed under the License is distributed on an "AS IS" BASIS,
|
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
See the License for the specific language governing permissions and
|
|
limitations under the License.
|
|
*/
|
|
|
|
package spec
|
|
|
|
// The below is all copied from k/k to avoid taking a dependency.
|
|
// https://github.com/kubernetes/kubernetes/blob/685d639/pkg/kubelet/cm/helpers_linux.go
|
|
|
|
const (
|
|
// These limits are defined in the kernel:
|
|
// https://github.com/torvalds/linux/blob/0bddd227f3dc55975e2b8dfa7fc6f959b062a2c7/kernel/sched/sched.h#L427-L428
|
|
minShares = 2
|
|
maxShares = 262144
|
|
|
|
sharesPerCPU = 1024
|
|
milliCPUToCPU = 1000
|
|
|
|
// 100000 microseconds is equivalent to 100ms
|
|
quotaPeriod = 100000
|
|
|
|
// 1000 microseconds is equivalent to 1ms
|
|
// defined here:
|
|
// https://github.com/torvalds/linux/blob/cac03ac368fabff0122853de2422d4e17a32de08/kernel/sched/core.c#L10546
|
|
minQuotaPeriod = 1000
|
|
)
|
|
|
|
// milliCPUToShares converts the milliCPU to CFS shares.
|
|
func milliCPUToShares(milliCPU int64) uint64 {
|
|
if milliCPU == 0 {
|
|
// Docker converts zero milliCPU to unset, which maps to kernel default
|
|
// for unset: 1024. Return 2 here to really match kernel default for
|
|
// zero milliCPU.
|
|
return minShares
|
|
}
|
|
// Conceptually (milliCPU / milliCPUToCPU) * sharesPerCPU, but factored to improve rounding.
|
|
shares := (milliCPU * sharesPerCPU) / milliCPUToCPU
|
|
if shares < minShares {
|
|
return minShares
|
|
}
|
|
if shares > maxShares {
|
|
return maxShares
|
|
}
|
|
return uint64(shares)
|
|
}
|
|
|
|
// milliCPUToQuota converts milliCPU to CFS quota and period values.
|
|
// Input parameters and resulting value is number of microseconds.
|
|
func milliCPUToQuota(milliCPU int64, period int64) (quota int64) {
|
|
// CFS quota is measured in two values:
|
|
// - cfs_period_us=100ms (the amount of time to measure usage across given by period)
|
|
// - cfs_quota=20ms (the amount of cpu time allowed to be used across a period)
|
|
// so in the above example, you are limited to 20% of a single CPU
|
|
// for multi-cpu environments, you just scale equivalent amounts
|
|
// see https://www.kernel.org/doc/Documentation/scheduler/sched-bwc.txt for details
|
|
|
|
if milliCPU == 0 {
|
|
return
|
|
}
|
|
|
|
// we then convert your milliCPU to a value normalized over a period
|
|
quota = (milliCPU * period) / milliCPUToCPU
|
|
|
|
// quota needs to be a minimum of 1ms.
|
|
if quota < minQuotaPeriod {
|
|
quota = minQuotaPeriod
|
|
}
|
|
return
|
|
}
|