You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mesos.apache.org by bm...@apache.org on 2024/04/17 16:13:55 UTC

(mesos) branch master updated: [cgroups2] Introduce API to set a soft memory limit.

This is an automated email from the ASF dual-hosted git repository.

bmahler pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/mesos.git


The following commit(s) were added to refs/heads/master by this push:
     new 4525ebfd3 [cgroups2] Introduce API to set a soft memory limit.
4525ebfd3 is described below

commit 4525ebfd34b5f84c2974697d572f4af263019200
Author: Devin Leamy <dl...@twitter.com>
AuthorDate: Tue Apr 16 16:01:51 2024 +0000

    [cgroups2] Introduce API to set a soft memory limit.
    
    The "memory.high" control contains the soft memory limit for a cgroup
    and its descendants. Exceeding the limit will cause the cgroup's
    processes to get throttled and will put the cgroup under memory
    pressure.
    
    We introduce `cgroups2::memory::set_high` and `cgroups2::memory::high`
    to set and get this soft memory limit.
---
 src/linux/cgroups2.cpp                     | 21 +++++++++++++++++++++
 src/linux/cgroups2.hpp                     | 18 ++++++++++++++++++
 src/tests/containerizer/cgroups2_tests.cpp | 21 +++++++++++++++++++++
 3 files changed, 60 insertions(+)

diff --git a/src/linux/cgroups2.cpp b/src/linux/cgroups2.cpp
index 2ae459853..35eaf1f24 100644
--- a/src/linux/cgroups2.cpp
+++ b/src/linux/cgroups2.cpp
@@ -796,6 +796,7 @@ namespace control {
 
 const string CURRENT = "memory.current";
 const string LOW = "memory.low";
+const string HIGH = "memory.high";
 const string MAX = "memory.max";
 const string MIN = "memory.min";
 
@@ -866,6 +867,26 @@ Result<Bytes> max(const string& cgroup)
   return internal::parse_bytelimit(*contents);
 }
 
+
+Try<Nothing> set_high(const string& cgroup, const Option<Bytes>& limit)
+{
+  return cgroups2::write(
+      cgroup,
+      control::HIGH,
+      limit.isNone() ?  "max" : stringify(limit->bytes()));
+}
+
+
+Result<Bytes> high(const string& cgroup)
+{
+  Try<string> contents = cgroups2::read<string>(cgroup, control::HIGH);
+  if (contents.isError()) {
+    return Error("Failed to read 'memory.high': " + contents.error());
+  }
+
+  return internal::parse_bytelimit(*contents);
+}
+
 } // namespace memory {
 
 namespace devices {
diff --git a/src/linux/cgroups2.hpp b/src/linux/cgroups2.hpp
index 86959aae7..22cfaeecf 100644
--- a/src/linux/cgroups2.hpp
+++ b/src/linux/cgroups2.hpp
@@ -296,6 +296,24 @@ Try<Nothing> set_max(const std::string& cgroup, const Option<Bytes>& limit);
 // Cannot be used for the root cgroup.
 Result<Bytes> max(const std::string& cgroup);
 
+
+// Set the soft memory limit for a cgroup and its descendants. Exceeding the
+// soft limit will cause processes in the cgroup to be throttled and put under
+// heavy reclaim pressure.
+// If limit is None, then there is no soft memory limit.
+// Note: See the top-level `cgroups2::memory` comment about byte alignment.
+//
+// Cannot be used for the root cgroup.
+Try<Nothing> set_high(
+    const std::string& cgroup, const Option<Bytes>& limit);
+
+
+// Get the soft memory limit for a cgroup and its descendants.
+// If the returned limit is None, then there is no soft memory limit.
+//
+// Cannot be used for the root cgroup.
+Result<Bytes> high(const std::string& cgroup);
+
 } // namespace memory {
 
 namespace devices {
diff --git a/src/tests/containerizer/cgroups2_tests.cpp b/src/tests/containerizer/cgroups2_tests.cpp
index 6c8156a63..ac2b0e0f2 100644
--- a/src/tests/containerizer/cgroups2_tests.cpp
+++ b/src/tests/containerizer/cgroups2_tests.cpp
@@ -383,6 +383,27 @@ TEST_F(Cgroups2Test, ROOT_CGROUPS2_MemoryMaximum)
 }
 
 
+TEST_F(Cgroups2Test, ROOT_CGROUPS2_MemorySoftMaximum)
+{
+  ASSERT_SOME(enable_controllers({"memory"}));
+
+  ASSERT_SOME(cgroups2::create(TEST_CGROUP));
+  ASSERT_SOME(cgroups2::controllers::enable(TEST_CGROUP, {"memory"}));
+
+  Bytes limit = Bytes(os::pagesize()) * 5;
+
+  // Does not exist for the root cgroup.
+  EXPECT_ERROR(cgroups2::memory::high(cgroups2::ROOT_CGROUP));
+  EXPECT_ERROR(cgroups2::memory::set_high(cgroups2::ROOT_CGROUP, limit));
+
+  EXPECT_SOME(cgroups2::memory::set_high(TEST_CGROUP, limit));
+  EXPECT_SOME_EQ(limit, cgroups2::memory::high(TEST_CGROUP));
+
+  EXPECT_SOME(cgroups2::memory::set_high(TEST_CGROUP, None()));
+  EXPECT_NONE(cgroups2::memory::high(TEST_CGROUP));
+}
+
+
 // Check that byte amounts written to the memory controller are rounded
 // down to the nearest page size.
 TEST_F(Cgroups2Test, ROOT_CGROUPS2_MemoryBytesRounding)