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

Commit 0e0ef63

Browse files
committed
cpuset: support setting mems for sandbox
CPUSet cgroup allows for pinning the memory associated with a cpuset to a given numa node. Similar to cpuset.cpus, we should take cpuset.mems into account for the sandbox-cgroup that Kata creates. Fixes: #2970 Signed-off-by: Eric Ernst <[email protected]>
1 parent 911a495 commit 0e0ef63

File tree

3 files changed

+71
-47
lines changed

3 files changed

+71
-47
lines changed

virtcontainers/pkg/cgroups/manager.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -329,14 +329,15 @@ func (m *Manager) RemoveDevice(device string) error {
329329
return fmt.Errorf("device %v not found in the cgroup", device)
330330
}
331331

332-
func (m *Manager) SetCPUSet(cpuset string) error {
332+
func (m *Manager) SetCPUSet(cpuset, memset string) error {
333333
cgroups, err := m.GetCgroups()
334334
if err != nil {
335335
return err
336336
}
337337

338338
m.Lock()
339339
cgroups.CpusetCpus = cpuset
340+
cgroups.CpusetMems = memset
340341
m.Unlock()
341342

342343
return m.Apply()

virtcontainers/sandbox.go

Lines changed: 19 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1959,15 +1959,13 @@ func (s *Sandbox) cgroupsUpdate() error {
19591959
// in the Kata sandbox cgroup (inherited). Check to see if sandbox cpuset needs to be
19601960
// updated.
19611961
if s.config.SandboxCgroupOnly {
1962-
cpuset, err := s.getSandboxCPUSet()
1962+
cpuset, memset, err := s.getSandboxCPUSet()
19631963
if err != nil {
19641964
return err
19651965
}
19661966

1967-
if cpuset != "" {
1968-
if err := s.cgroupMgr.SetCPUSet(cpuset); err != nil {
1969-
return err
1970-
}
1967+
if err := s.cgroupMgr.SetCPUSet(cpuset, memset); err != nil {
1968+
return err
19711969
}
19721970

19731971
return nil
@@ -2264,23 +2262,30 @@ func (s *Sandbox) GetOOMEvent() (string, error) {
22642262
return s.agent.getOOMEvent()
22652263
}
22662264

2267-
// getSandboxCPUSet returns the union of each of the sandbox's containers' CPU sets
2268-
// as a string in canonical linux CPU list format
2269-
func (s *Sandbox) getSandboxCPUSet() (string, error) {
2265+
// getSandboxCPUSet returns the union of each of the sandbox's containers' CPU sets'
2266+
// cpus and mems as a string in canonical linux CPU/mems list format
2267+
func (s *Sandbox) getSandboxCPUSet() (string, string, error) {
22702268
if s.config == nil {
2271-
return "", nil
2269+
return "", "", nil
22722270
}
22732271

2274-
result := cpuset.NewCPUSet()
2272+
cpuResult := cpuset.NewCPUSet()
2273+
memResult := cpuset.NewCPUSet()
22752274
for _, ctr := range s.config.Containers {
22762275
if ctr.Resources.CPU != nil {
2277-
currSet, err := cpuset.Parse(ctr.Resources.CPU.Cpus)
2276+
currCpuSet, err := cpuset.Parse(ctr.Resources.CPU.Cpus)
2277+
if err != nil {
2278+
return "", "", fmt.Errorf("unable to parse CPUset.cpus for container %s: %v", ctr.ID, err)
2279+
}
2280+
cpuResult = cpuResult.Union(currCpuSet)
2281+
2282+
currMemSet, err := cpuset.Parse(ctr.Resources.CPU.Mems)
22782283
if err != nil {
2279-
return "", fmt.Errorf("unable to parse CPUset for container %s: %v", ctr.ID, err)
2284+
return "", "", fmt.Errorf("unable to parse CPUset.mems for container %s: %v", ctr.ID, err)
22802285
}
2281-
result = result.Union(currSet)
2286+
memResult = memResult.Union(currMemSet)
22822287
}
22832288
}
22842289

2285-
return result.String(), nil
2290+
return cpuResult.String(), memResult.String(), nil
22862291
}

virtcontainers/sandbox_test.go

Lines changed: 50 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1422,24 +1422,25 @@ func TestSandbox_SetupSandboxCgroup(t *testing.T) {
14221422
}
14231423
}
14241424

1425-
func getContainerConfigWithCPUSet(cpuset string) ContainerConfig {
1425+
func getContainerConfigWithCPUSet(cpuset, memset string) ContainerConfig {
14261426
return ContainerConfig{
14271427
Resources: specs.LinuxResources{
14281428
CPU: &specs.LinuxCPU{
14291429
Cpus: cpuset,
1430+
Mems: memset,
14301431
},
14311432
},
14321433
}
14331434
}
14341435

1435-
func getSimpleSandbox(cpuset0, cpuset1, cpuset2 string) *Sandbox {
1436+
func getSimpleSandbox(cpusets, memsets [3]string) *Sandbox {
14361437
sandbox := Sandbox{}
14371438

14381439
sandbox.config = &SandboxConfig{
14391440
Containers: []ContainerConfig{
1440-
getContainerConfigWithCPUSet(cpuset0),
1441-
getContainerConfigWithCPUSet(cpuset1),
1442-
getContainerConfigWithCPUSet(cpuset2),
1441+
getContainerConfigWithCPUSet(cpusets[0], memsets[0]),
1442+
getContainerConfigWithCPUSet(cpusets[1], memsets[1]),
1443+
getContainerConfigWithCPUSet(cpusets[2], memsets[2]),
14431444
},
14441445
}
14451446

@@ -1449,80 +1450,97 @@ func getSimpleSandbox(cpuset0, cpuset1, cpuset2 string) *Sandbox {
14491450
func TestGetSandboxCpuSet(t *testing.T) {
14501451

14511452
tests := []struct {
1452-
name string
1453-
cpuset0 string
1454-
cpuset1 string
1455-
cpuset2 string
1456-
result string
1457-
wantErr bool
1453+
name string
1454+
cpusets [3]string
1455+
memsets [3]string
1456+
cpuResult string
1457+
memResult string
1458+
wantErr bool
14581459
}{
14591460
{
14601461
"single, no cpuset",
1461-
"",
1462-
"",
1462+
[3]string{"", "", ""},
1463+
[3]string{"", "", ""},
14631464
"",
14641465
"",
14651466
false,
14661467
},
14671468
{
14681469
"single cpuset",
1470+
[3]string{"0", "", ""},
1471+
[3]string{"", "", ""},
14691472
"0",
14701473
"",
1471-
"",
1472-
"0",
14731474
false,
14741475
},
14751476
{
14761477
"two duplicate cpuset",
1477-
"0",
1478+
[3]string{"0", "0", ""},
1479+
[3]string{"", "", ""},
14781480
"0",
14791481
"",
1480-
"0",
14811482
false,
14821483
},
14831484
{
14841485
"3 cpusets",
1485-
"0-3",
1486-
"5-7",
1487-
"1",
1486+
[3]string{"0-3", "5-7", "1"},
1487+
[3]string{"", "", ""},
14881488
"0-3,5-7",
1489+
"",
14891490
false,
14901491
},
1492+
14911493
{
14921494
"weird, but should be okay",
1493-
"0-3",
1494-
"99999",
1495-
"",
1495+
[3]string{"0-3", "99999", ""},
1496+
[3]string{"", "", ""},
14961497
"0-3,99999",
1498+
"",
14971499
false,
14981500
},
14991501
{
15001502
"two, overlapping cpuset",
1503+
[3]string{"0-3", "1-2", ""},
1504+
[3]string{"", "", ""},
15011505
"0-3",
1502-
"1-2",
15031506
"",
1504-
"0-3",
15051507
false,
15061508
},
15071509
{
15081510
"garbage, should fail",
1509-
"7 beard-seconds",
1510-
"Audrey + 7",
1511-
"Elliott - 17",
1511+
[3]string{"7 beard-seconds", "Audrey + 7", "Elliott - 17"},
1512+
[3]string{"", "", ""},
1513+
"",
15121514
"",
15131515
true,
15141516
},
1517+
{
1518+
"cpuset and memset",
1519+
[3]string{"0-3", "1-2", ""},
1520+
[3]string{"0", "1", "0-1"},
1521+
"0-3",
1522+
"0-1",
1523+
false,
1524+
},
1525+
{
1526+
"memset",
1527+
[3]string{"0-3", "1-2", ""},
1528+
[3]string{"0", "3", ""},
1529+
"0-3",
1530+
"0,3",
1531+
false,
1532+
},
15151533
}
15161534
for _, tt := range tests {
15171535

15181536
t.Run(tt.name, func(t *testing.T) {
1519-
s := getSimpleSandbox(tt.cpuset0, tt.cpuset1, tt.cpuset2)
1520-
res, err := s.getSandboxCPUSet()
1537+
s := getSimpleSandbox(tt.cpusets, tt.memsets)
1538+
res, _, err := s.getSandboxCPUSet()
15211539
if (err != nil) != tt.wantErr {
15221540
t.Errorf("getSandboxCPUSet() error = %v, wantErr %v", err, tt.wantErr)
15231541
}
1524-
if res != tt.result {
1525-
t.Errorf("getSandboxCPUSet() result = %s, wanted result %s", res, tt.result)
1542+
if res != tt.cpuResult {
1543+
t.Errorf("getSandboxCPUSet() result = %s, wanted result %s", res, tt.cpuResult)
15261544
}
15271545
})
15281546
}

0 commit comments

Comments
 (0)