From dc2650889c423c6013b8d9dffe7cf58eab82c2c3 Mon Sep 17 00:00:00 2001 From: Eric Ernst Date: Wed, 27 Feb 2019 22:27:13 -0800 Subject: [PATCH] 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 --- virtcontainers/sandbox.go | 10 ++++++---- virtcontainers/utils/utils.go | 19 +++++++++++++++++++ 2 files changed, 25 insertions(+), 4 deletions(-) diff --git a/virtcontainers/sandbox.go b/virtcontainers/sandbox.go index a72722aa7d..cb6acbd57a 100644 --- a/virtcontainers/sandbox.go +++ b/virtcontainers/sandbox.go @@ -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 diff --git a/virtcontainers/utils/utils.go b/virtcontainers/utils/utils.go index 3d7d75c934..2358f2b934 100644 --- a/virtcontainers/utils/utils.go +++ b/virtcontainers/utils/utils.go @@ -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 {