mirror of
https://github.com/kata-containers/kata-containers.git
synced 2025-04-30 04:34:27 +00:00
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. Signed-off-by: Eric Ernst <eric.g.ernst@gmail.com>
This commit is contained in:
parent
2d690536b8
commit
77a463e57a
@ -332,7 +332,7 @@ func (m *Manager) RemoveDevice(device string) error {
|
|||||||
return fmt.Errorf("device %v not found in the cgroup", device)
|
return fmt.Errorf("device %v not found in the cgroup", device)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *Manager) SetCPUSet(cpuset string) error {
|
func (m *Manager) SetCPUSet(cpuset, memset string) error {
|
||||||
cgroups, err := m.GetCgroups()
|
cgroups, err := m.GetCgroups()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@ -340,6 +340,7 @@ func (m *Manager) SetCPUSet(cpuset string) error {
|
|||||||
|
|
||||||
m.Lock()
|
m.Lock()
|
||||||
cgroups.CpusetCpus = cpuset
|
cgroups.CpusetCpus = cpuset
|
||||||
|
cgroups.CpusetMems = memset
|
||||||
m.Unlock()
|
m.Unlock()
|
||||||
|
|
||||||
return m.Apply()
|
return m.Apply()
|
||||||
|
@ -1995,16 +1995,14 @@ func (s *Sandbox) cgroupsUpdate() error {
|
|||||||
// in the Kata sandbox cgroup (inherited). Check to see if sandbox cpuset needs to be
|
// in the Kata sandbox cgroup (inherited). Check to see if sandbox cpuset needs to be
|
||||||
// updated.
|
// updated.
|
||||||
if s.config.SandboxCgroupOnly {
|
if s.config.SandboxCgroupOnly {
|
||||||
cpuset, err := s.getSandboxCPUSet()
|
cpuset, memset, err := s.getSandboxCPUSet()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if cpuset != "" {
|
if err := s.cgroupMgr.SetCPUSet(cpuset, memset); err != nil {
|
||||||
if err := s.cgroupMgr.SetCPUSet(cpuset); err != nil {
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@ -2304,23 +2302,30 @@ func (s *Sandbox) GetAgentURL() (string, error) {
|
|||||||
return s.agent.getAgentURL()
|
return s.agent.getAgentURL()
|
||||||
}
|
}
|
||||||
|
|
||||||
// getSandboxCPUSet returns the union of each of the sandbox's containers' CPU sets
|
// getSandboxCPUSet returns the union of each of the sandbox's containers' CPU sets'
|
||||||
// as a string in canonical linux CPU list format
|
// cpus and mems as a string in canonical linux CPU/mems list format
|
||||||
func (s *Sandbox) getSandboxCPUSet() (string, error) {
|
func (s *Sandbox) getSandboxCPUSet() (string, string, error) {
|
||||||
if s.config == nil {
|
if s.config == nil {
|
||||||
return "", nil
|
return "", "", nil
|
||||||
}
|
}
|
||||||
|
|
||||||
result := cpuset.NewCPUSet()
|
cpuResult := cpuset.NewCPUSet()
|
||||||
|
memResult := cpuset.NewCPUSet()
|
||||||
for _, ctr := range s.config.Containers {
|
for _, ctr := range s.config.Containers {
|
||||||
if ctr.Resources.CPU != nil {
|
if ctr.Resources.CPU != nil {
|
||||||
currSet, err := cpuset.Parse(ctr.Resources.CPU.Cpus)
|
currCpuSet, err := cpuset.Parse(ctr.Resources.CPU.Cpus)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", fmt.Errorf("unable to parse CPUset for container %s", ctr.ID)
|
return "", "", fmt.Errorf("unable to parse CPUset.cpus for container %s: %v", ctr.ID, err)
|
||||||
}
|
}
|
||||||
result = result.Union(currSet)
|
cpuResult = cpuResult.Union(currCpuSet)
|
||||||
|
|
||||||
|
currMemSet, err := cpuset.Parse(ctr.Resources.CPU.Mems)
|
||||||
|
if err != nil {
|
||||||
|
return "", "", fmt.Errorf("unable to parse CPUset.mems for container %s: %v", ctr.ID, err)
|
||||||
|
}
|
||||||
|
memResult = memResult.Union(currMemSet)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return result.String(), nil
|
return cpuResult.String(), memResult.String(), nil
|
||||||
}
|
}
|
||||||
|
@ -1420,24 +1420,25 @@ func TestSandbox_SetupSandboxCgroup(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func getContainerConfigWithCPUSet(cpuset string) ContainerConfig {
|
func getContainerConfigWithCPUSet(cpuset, memset string) ContainerConfig {
|
||||||
return ContainerConfig{
|
return ContainerConfig{
|
||||||
Resources: specs.LinuxResources{
|
Resources: specs.LinuxResources{
|
||||||
CPU: &specs.LinuxCPU{
|
CPU: &specs.LinuxCPU{
|
||||||
Cpus: cpuset,
|
Cpus: cpuset,
|
||||||
|
Mems: memset,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func getSimpleSandbox(cpuset0, cpuset1, cpuset2 string) *Sandbox {
|
func getSimpleSandbox(cpusets, memsets [3]string) *Sandbox {
|
||||||
sandbox := Sandbox{}
|
sandbox := Sandbox{}
|
||||||
|
|
||||||
sandbox.config = &SandboxConfig{
|
sandbox.config = &SandboxConfig{
|
||||||
Containers: []ContainerConfig{
|
Containers: []ContainerConfig{
|
||||||
getContainerConfigWithCPUSet(cpuset0),
|
getContainerConfigWithCPUSet(cpusets[0], memsets[0]),
|
||||||
getContainerConfigWithCPUSet(cpuset1),
|
getContainerConfigWithCPUSet(cpusets[1], memsets[1]),
|
||||||
getContainerConfigWithCPUSet(cpuset2),
|
getContainerConfigWithCPUSet(cpusets[2], memsets[2]),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1448,79 +1449,96 @@ func TestGetSandboxCpuSet(t *testing.T) {
|
|||||||
|
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
name string
|
name string
|
||||||
cpuset0 string
|
cpusets [3]string
|
||||||
cpuset1 string
|
memsets [3]string
|
||||||
cpuset2 string
|
cpuResult string
|
||||||
result string
|
memResult string
|
||||||
wantErr bool
|
wantErr bool
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
"single, no cpuset",
|
"single, no cpuset",
|
||||||
"",
|
[3]string{"", "", ""},
|
||||||
"",
|
[3]string{"", "", ""},
|
||||||
"",
|
"",
|
||||||
"",
|
"",
|
||||||
false,
|
false,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"single cpuset",
|
"single cpuset",
|
||||||
|
[3]string{"0", "", ""},
|
||||||
|
[3]string{"", "", ""},
|
||||||
"0",
|
"0",
|
||||||
"",
|
"",
|
||||||
"",
|
|
||||||
"0",
|
|
||||||
false,
|
false,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"two duplicate cpuset",
|
"two duplicate cpuset",
|
||||||
"0",
|
[3]string{"0", "0", ""},
|
||||||
|
[3]string{"", "", ""},
|
||||||
"0",
|
"0",
|
||||||
"",
|
"",
|
||||||
"0",
|
|
||||||
false,
|
false,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"3 cpusets",
|
"3 cpusets",
|
||||||
"0-3",
|
[3]string{"0-3", "5-7", "1"},
|
||||||
"5-7",
|
[3]string{"", "", ""},
|
||||||
"1",
|
|
||||||
"0-3,5-7",
|
"0-3,5-7",
|
||||||
|
"",
|
||||||
false,
|
false,
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
"weird, but should be okay",
|
"weird, but should be okay",
|
||||||
"0-3",
|
[3]string{"0-3", "99999", ""},
|
||||||
"99999",
|
[3]string{"", "", ""},
|
||||||
"",
|
|
||||||
"0-3,99999",
|
"0-3,99999",
|
||||||
|
"",
|
||||||
false,
|
false,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"two, overlapping cpuset",
|
"two, overlapping cpuset",
|
||||||
|
[3]string{"0-3", "1-2", ""},
|
||||||
|
[3]string{"", "", ""},
|
||||||
"0-3",
|
"0-3",
|
||||||
"1-2",
|
|
||||||
"",
|
"",
|
||||||
"0-3",
|
|
||||||
false,
|
false,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"garbage, should fail",
|
"garbage, should fail",
|
||||||
"7 beard-seconds",
|
[3]string{"7 beard-seconds", "Audrey + 7", "Elliott - 17"},
|
||||||
"Audrey + 7",
|
[3]string{"", "", ""},
|
||||||
"Elliott - 17",
|
"",
|
||||||
"",
|
"",
|
||||||
true,
|
true,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"cpuset and memset",
|
||||||
|
[3]string{"0-3", "1-2", ""},
|
||||||
|
[3]string{"0", "1", "0-1"},
|
||||||
|
"0-3",
|
||||||
|
"0-1",
|
||||||
|
false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"memset",
|
||||||
|
[3]string{"0-3", "1-2", ""},
|
||||||
|
[3]string{"0", "3", ""},
|
||||||
|
"0-3",
|
||||||
|
"0,3",
|
||||||
|
false,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
for _, tt := range tests {
|
for _, tt := range tests {
|
||||||
|
|
||||||
t.Run(tt.name, func(t *testing.T) {
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
s := getSimpleSandbox(tt.cpuset0, tt.cpuset1, tt.cpuset2)
|
s := getSimpleSandbox(tt.cpusets, tt.memsets)
|
||||||
res, err := s.getSandboxCPUSet()
|
res, _, err := s.getSandboxCPUSet()
|
||||||
if (err != nil) != tt.wantErr {
|
if (err != nil) != tt.wantErr {
|
||||||
t.Errorf("getSandboxCPUSet() error = %v, wantErr %v", err, tt.wantErr)
|
t.Errorf("getSandboxCPUSet() error = %v, wantErr %v", err, tt.wantErr)
|
||||||
}
|
}
|
||||||
if res != tt.result {
|
if res != tt.cpuResult {
|
||||||
t.Errorf("getSandboxCPUSet() result = %s, wanted result %s", res, tt.result)
|
t.Errorf("getSandboxCPUSet() result = %s, wanted result %s", res, tt.cpuResult)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user