virtcontainers: fix vCPU calculation errors

We were grabbing a running total of quota and period for each container
and then calculating the number of resulting vCPUs. Summing period
doesn't make sense.  To simplify, let's just calculate mCPU per
container, keep a running total of mCPUs requested, and then translate
to sandbox vCPUs after.

Fixes: #1292

Signed-off-by: Eric Ernst <eric.ernst@intel.com>
This commit is contained in:
Eric Ernst 2019-02-27 22:27:13 -08:00
parent e8a8e0db79
commit dc2650889c
2 changed files with 25 additions and 4 deletions

View File

@ -1608,7 +1608,6 @@ func (s *Sandbox) AddDevice(info config.DeviceInfo) (api.Device, error) {
func (s *Sandbox) updateResources() error {
// the hypervisor.MemorySize is the amount of memory reserved for
// the VM and contaniners without memory limit
sumResources := specs.LinuxResources{
Memory: &specs.LinuxMemory{
Limit: new(int64),
@ -1619,19 +1618,22 @@ func (s *Sandbox) updateResources() error {
},
}
var mCPU uint32
// Calculate running total of memory and mCPUs requested
for _, c := range s.config.Containers {
if m := c.Resources.Memory; m != nil && m.Limit != nil {
*sumResources.Memory.Limit += *m.Limit
}
if cpu := c.Resources.CPU; cpu != nil {
if cpu.Period != nil && cpu.Quota != nil {
*sumResources.CPU.Period += *cpu.Period
*sumResources.CPU.Quota += *cpu.Quota
mCPU += utils.CalculateMilliCPUs(*cpu.Quota, *cpu.Period)
}
}
}
sandboxVCPUs := uint32(utils.ConstraintsToVCPUs(*sumResources.CPU.Quota, *sumResources.CPU.Period))
sandboxVCPUs := utils.CalculateVCpusFromMilliCpus(mCPU)
sandboxVCPUs += s.hypervisor.hypervisorConfig().NumVCPUs
sandboxMemoryByte := int64(s.hypervisor.hypervisorConfig().MemorySize) << utils.MibToBytesShift

View File

@ -105,6 +105,25 @@ func WriteToFile(path string, data []byte) error {
return nil
}
//CalculateMilliCPUs converts CPU quota and period to milli-CPUs
func CalculateMilliCPUs(quota int64, period uint64) uint32 {
// If quota is -1, it means the CPU resource request is
// unconstrained. In that case, we don't currently assign
// additional CPUs.
if quota >= 0 && period != 0 {
return uint32((uint64(quota) * 1000) / period)
}
return 0
}
//CalculateVCpusFromMilliCpus converts from mCPU to CPU, taking the ceiling
// value when necessary
func CalculateVCpusFromMilliCpus(mCPU uint32) uint32 {
return (mCPU + 999) / 1000
}
// ConstraintsToVCPUs converts CPU quota and period to vCPUs
func ConstraintsToVCPUs(quota int64, period uint64) uint {
if quota != 0 && period != 0 {