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 {