Skip to content
This repository was archived by the owner on May 12, 2021. It is now read-only.

Commit 8ef2946

Browse files
committed
sandbox: consider cpusets if quota is not enforced
If quota is not being enforced on any containers but CPUsets are specified, take the number of CPU sets into account when sizing the virtual machine. Fixes: #2971 Signed-off-by: Eric Ernst <[email protected]>
1 parent 0e0ef63 commit 8ef2946

File tree

2 files changed

+34
-8
lines changed

2 files changed

+34
-8
lines changed

virtcontainers/sandbox.go

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1863,7 +1863,10 @@ func (s *Sandbox) updateResources() error {
18631863
return fmt.Errorf("sandbox config is nil")
18641864
}
18651865

1866-
sandboxVCPUs := s.calculateSandboxCPUs()
1866+
sandboxVCPUs, err := s.calculateSandboxCPUs()
1867+
if err != nil {
1868+
return err
1869+
}
18671870
// Add default vcpus for sandbox
18681871
sandboxVCPUs += s.hypervisor.hypervisorConfig().NumVCPUs
18691872

@@ -1923,8 +1926,9 @@ func (s *Sandbox) calculateSandboxMemory() int64 {
19231926
return memorySandbox
19241927
}
19251928

1926-
func (s *Sandbox) calculateSandboxCPUs() uint32 {
1929+
func (s *Sandbox) calculateSandboxCPUs() (uint32, error) {
19271930
mCPU := uint32(0)
1931+
cpusetCount := int(0)
19281932

19291933
for _, c := range s.config.Containers {
19301934
// Do not hot add again non-running containers resources
@@ -1938,9 +1942,22 @@ func (s *Sandbox) calculateSandboxCPUs() uint32 {
19381942
mCPU += utils.CalculateMilliCPUs(*cpu.Quota, *cpu.Period)
19391943
}
19401944

1945+
set, err := cpuset.Parse(cpu.Cpus)
1946+
if err != nil {
1947+
return 0, nil
1948+
}
1949+
cpusetCount += set.Size()
19411950
}
19421951
}
1943-
return utils.CalculateVCpusFromMilliCpus(mCPU)
1952+
1953+
// If we aren't being constrained, then we could have two scenarios:
1954+
// 1. BestEffort QoS: no proper support today in Kata.
1955+
// 2. We could be constrained only by CPUSets. Check for this:
1956+
if mCPU == 0 && cpusetCount > 0 {
1957+
return uint32(cpusetCount), nil
1958+
}
1959+
1960+
return utils.CalculateVCpusFromMilliCpus(mCPU), nil
19441961
}
19451962

19461963
// GetHypervisorType is used for getting Hypervisor name currently used.
@@ -2273,11 +2290,11 @@ func (s *Sandbox) getSandboxCPUSet() (string, string, error) {
22732290
memResult := cpuset.NewCPUSet()
22742291
for _, ctr := range s.config.Containers {
22752292
if ctr.Resources.CPU != nil {
2276-
currCpuSet, err := cpuset.Parse(ctr.Resources.CPU.Cpus)
2293+
currCPUSet, err := cpuset.Parse(ctr.Resources.CPU.Cpus)
22772294
if err != nil {
22782295
return "", "", fmt.Errorf("unable to parse CPUset.cpus for container %s: %v", ctr.ID, err)
22792296
}
2280-
cpuResult = cpuResult.Union(currCpuSet)
2297+
cpuResult = cpuResult.Union(currCPUSet)
22812298

22822299
currMemSet, err := cpuset.Parse(ctr.Resources.CPU.Mems)
22832300
if err != nil {

virtcontainers/sandbox_test.go

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -106,12 +106,18 @@ func TestCreateMockSandbox(t *testing.T) {
106106
func TestCalculateSandboxCPUs(t *testing.T) {
107107
sandbox := &Sandbox{}
108108
sandbox.config = &SandboxConfig{}
109+
109110
unconstrained := newTestContainerConfigNoop("cont-00001")
110-
constrained := newTestContainerConfigNoop("cont-00001")
111+
constrained := newTestContainerConfigNoop("cont-00002")
112+
unconstrainedCpusets0_1 := newTestContainerConfigNoop("cont-00003")
113+
unconstrainedCpusets2 := newTestContainerConfigNoop("cont-00004")
114+
constrainedCpusets0_7 := newTestContainerConfigNoop("cont-00005")
111115
quota := int64(4000)
112116
period := uint64(1000)
113117
constrained.Resources.CPU = &specs.LinuxCPU{Period: &period, Quota: &quota}
114-
118+
unconstrainedCpusets0_1.Resources.CPU = &specs.LinuxCPU{Cpus: "0-1"}
119+
unconstrainedCpusets2.Resources.CPU = &specs.LinuxCPU{Cpus: "2"}
120+
constrainedCpusets0_7.Resources.CPU = &specs.LinuxCPU{Period: &period, Quota: &quota, Cpus: "0-7"}
115121
tests := []struct {
116122
name string
117123
containers []ContainerConfig
@@ -123,11 +129,14 @@ func TestCalculateSandboxCPUs(t *testing.T) {
123129
{"2-constrained", []ContainerConfig{constrained, constrained}, 8},
124130
{"3-mix-constraints", []ContainerConfig{unconstrained, constrained, constrained}, 8},
125131
{"3-constrained", []ContainerConfig{constrained, constrained, constrained}, 12},
132+
{"unconstrained-1-cpuset", []ContainerConfig{unconstrained, unconstrained, unconstrainedCpusets0_1}, 2},
133+
{"unconstrained-2-cpuset", []ContainerConfig{unconstrainedCpusets0_1, unconstrainedCpusets2}, 3},
134+
{"constrained-cpuset", []ContainerConfig{constrainedCpusets0_7}, 4},
126135
}
127136
for _, tt := range tests {
128137
t.Run(tt.name, func(t *testing.T) {
129138
sandbox.config.Containers = tt.containers
130-
got := sandbox.calculateSandboxCPUs()
139+
got, _ := sandbox.calculateSandboxCPUs()
131140
assert.Equal(t, got, tt.want)
132141
})
133142
}

0 commit comments

Comments
 (0)