From 676be0c5f86e71c7e3532e6315d5852d2627e637 Mon Sep 17 00:00:00 2001 From: Qiang Huang Date: Fri, 15 May 2015 14:24:56 +0800 Subject: [PATCH] Add support for kmem limit Signed-off-by: Qiang Huang --- cgroups/fs/memory.go | 5 +++++ cgroups/fs/memory_test.go | 28 +++++++++++++++++++++++ cgroups/systemd/apply_systemd.go | 38 ++++++++++++++++++++------------ configs/cgroup.go | 3 +++ 4 files changed, 60 insertions(+), 14 deletions(-) diff --git a/cgroups/fs/memory.go b/cgroups/fs/memory.go index 2dcef0f4..744297b7 100644 --- a/cgroups/fs/memory.go +++ b/cgroups/fs/memory.go @@ -54,6 +54,11 @@ func (s *MemoryGroup) Set(path string, cgroup *configs.Cgroup) error { return err } } + if cgroup.KernelMemory > 0 { + if err := writeFile(path, "memory.kmem.limit_in_bytes", strconv.FormatInt(cgroup.KernelMemory, 10)); err != nil { + return err + } + } if cgroup.OomKillDisable { if err := writeFile(path, "memory.oom_control", "1"); err != nil { diff --git a/cgroups/fs/memory_test.go b/cgroups/fs/memory_test.go index 60edc67a..2dd50bd1 100644 --- a/cgroups/fs/memory_test.go +++ b/cgroups/fs/memory_test.go @@ -112,6 +112,34 @@ func TestMemorySetMemoryswapDefault(t *testing.T) { } } +func TestMemorySetKernelMemory(t *testing.T) { + helper := NewCgroupTestUtil("memory", t) + defer helper.cleanup() + + const ( + kernelMemoryBefore = 314572800 // 300M + kernelMemoryAfter = 524288000 // 500M + ) + + helper.writeFileContents(map[string]string{ + "memory.kmem.limit_in_bytes": strconv.Itoa(kernelMemoryBefore), + }) + + helper.CgroupData.c.KernelMemory = kernelMemoryAfter + memory := &MemoryGroup{} + if err := memory.Set(helper.CgroupPath, helper.CgroupData.c); err != nil { + t.Fatal(err) + } + + value, err := getCgroupParamUint(helper.CgroupPath, "memory.kmem.limit_in_bytes") + if err != nil { + t.Fatalf("Failed to parse memory.kmem.limit_in_bytes - %s", err) + } + if value != kernelMemoryAfter { + t.Fatal("Got the wrong value, set memory.kmem.limit_in_bytes failed.") + } +} + func TestMemoryStats(t *testing.T) { helper := NewCgroupTestUtil("memory", t) defer helper.cleanup() diff --git a/cgroups/systemd/apply_systemd.go b/cgroups/systemd/apply_systemd.go index 27c11e18..66919816 100644 --- a/cgroups/systemd/apply_systemd.go +++ b/cgroups/systemd/apply_systemd.go @@ -200,12 +200,8 @@ func (m *Manager) Apply(pid int) error { return err } - // -1 disables memorySwap - if c.MemorySwap >= 0 && c.Memory != 0 { - if err := joinMemory(c, pid); err != nil { - return err - } - + if err := joinMemory(c, pid); err != nil { + return err } // we need to manually join the freezer, net_prio and cpuset cgroup in systemd @@ -435,19 +431,33 @@ func joinDevices(c *configs.Cgroup, pid int) error { } func joinMemory(c *configs.Cgroup, pid int) error { - memorySwap := c.MemorySwap - - if memorySwap == 0 { - // By default, MemorySwap is set to twice the size of RAM. - memorySwap = c.Memory * 2 - } - path, err := getSubsystemPath(c, "memory") if err != nil && !cgroups.IsNotFound(err) { return err } - return writeFile(path, "memory.memsw.limit_in_bytes", strconv.FormatInt(memorySwap, 10)) + // -1 disables memoryswap + if c.Memory != 0 && c.MemorySwap >= 0 { + memorySwap := c.MemorySwap + + if memorySwap == 0 { + // By default, MemorySwap is set to twice the size of RAM. + memorySwap = c.Memory * 2 + } + err = writeFile(path, "memory.memsw.limit_in_bytes", strconv.FormatInt(memorySwap, 10)) + if err != nil { + return err + } + } + + if c.KernelMemory > 0 { + err = writeFile(path, "memory.kmem.limit_in_bytes", strconv.FormatInt(c.KernelMemory, 10)) + if err != nil { + return err + } + } + + return nil } // systemd does not atm set up the cpuset controller, so we must manually diff --git a/configs/cgroup.go b/configs/cgroup.go index 8701de3f..da701291 100644 --- a/configs/cgroup.go +++ b/configs/cgroup.go @@ -30,6 +30,9 @@ type Cgroup struct { // Total memory usage (memory + swap); set `-1' to disable swap MemorySwap int64 `json:"memory_swap"` + // Kernel memory limit (in bytes) + KernelMemory int64 `json:"kernel_memory"` + // CPU shares (relative weight vs. other containers) CpuShares int64 `json:"cpu_shares"`