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 246aea6c0 Expose new metrics for memory usage in cgroup.
246aea6c0 is described below

commit 246aea6c0a6f4ff146edab607d63651afd4771e5
Author: Franck Cuny <[email protected]>
AuthorDate: Thu Feb 22 16:06:11 2018 -0800

    Expose new metrics for memory usage in cgroup.
---
 include/mesos/mesos.proto                          |  6 +++
 include/mesos/v1/mesos.proto                       |  6 +++
 src/linux/cgroups.cpp                              | 53 ++++++++++++++++++++++
 src/linux/cgroups.hpp                              | 14 ++++++
 .../mesos/isolators/cgroups/subsystems/memory.cpp  | 20 ++++++++
 src/tests/containerizer/cgroups_isolator_tests.cpp | 12 +++++
 src/tests/containerizer/memory_isolator_tests.cpp  | 16 +++++++
 7 files changed, 127 insertions(+)

diff --git a/include/mesos/mesos.proto b/include/mesos/mesos.proto
index a14cbfad9..dd3ada79c 100644
--- a/include/mesos/mesos.proto
+++ b/include/mesos/mesos.proto
@@ -1819,6 +1819,12 @@ message ResourceStatistics {
   // Total memory + swap usage. This is set if swap is enabled.
   optional uint64 mem_total_memsw_bytes = 37;
 
+  // Current kernel memory allocation.
+  optional uint64 mem_kmem_usage_bytes = 52;
+
+  // Current TCP buf memory allocation.
+  optional uint64 mem_kmem_tcp_usage_bytes = 53;
+
   // Hard memory limit.
   optional uint64 mem_limit_bytes = 6;
 
diff --git a/include/mesos/v1/mesos.proto b/include/mesos/v1/mesos.proto
index 12f8b65f7..224653300 100644
--- a/include/mesos/v1/mesos.proto
+++ b/include/mesos/v1/mesos.proto
@@ -1783,6 +1783,12 @@ message ResourceStatistics {
   // Total memory + swap usage. This is set if swap is enabled.
   optional uint64 mem_total_memsw_bytes = 37;
 
+  // Current kernel memory allocation.
+  optional uint64 mem_kmem_usage_bytes = 52;
+
+  // Current TCP buf memory allocation.
+  optional uint64 mem_kmem_tcp_usage_bytes = 53;
+
   // Hard memory limit.
   optional uint64 mem_limit_bytes = 6;
 
diff --git a/src/linux/cgroups.cpp b/src/linux/cgroups.cpp
index 11626cf49..2af654610 100644
--- a/src/linux/cgroups.cpp
+++ b/src/linux/cgroups.cpp
@@ -2466,6 +2466,59 @@ Try<Bytes> max_usage_in_bytes(const string& hierarchy, 
const string& cgroup)
 }
 
 
+Result<Bytes> kmem_usage_in_bytes(const string& hierarchy, const string& 
cgroup)
+{
+  Try<bool> exists = cgroups::exists(
+      hierarchy, cgroup, "memory.kmem.usage_in_bytes");
+
+  if (exists.isError()) {
+    return Error(
+        "Could not check for existence of 'memory.kmem.usage_in_bytes': " +
+        exists.error());
+  }
+
+  if (!exists.get()) {
+    return None();
+  }
+
+  Try<string> read = cgroups::read(
+      hierarchy, cgroup, "memory.kmem.usage_in_bytes");
+
+  if (read.isError()) {
+    return Error(read.error());
+  }
+
+  return Bytes::parse(strings::trim(read.get()) + "B");
+}
+
+
+Result<Bytes> kmem_tcp_usage_in_bytes(
+    const string& hierarchy, const string& cgroup)
+{
+  Try<bool> exists = cgroups::exists(
+      hierarchy, cgroup, "memory.kmem.tcp.usage_in_bytes");
+
+  if (exists.isError()) {
+    return Error(
+      "Could not check for existence of 'memory.kmem.tcp.usage_in_bytes': " +
+      exists.error());
+  }
+
+  if (!exists.get()) {
+    return None();
+  }
+
+  Try<string> read = cgroups::read(
+      hierarchy, cgroup, "memory.kmem.tcp.usage_in_bytes");
+
+  if (read.isError()) {
+    return Error(read.error());
+  }
+
+  return Bytes::parse(strings::trim(read.get()) + "B");
+}
+
+
 namespace oom {
 
 Future<Nothing> listen(const string& hierarchy, const string& cgroup)
diff --git a/src/linux/cgroups.hpp b/src/linux/cgroups.hpp
index f3e904250..9be53e31e 100644
--- a/src/linux/cgroups.hpp
+++ b/src/linux/cgroups.hpp
@@ -821,6 +821,20 @@ Try<Bytes> max_usage_in_bytes(
     const std::string& cgroup);
 
 
+// Returns the memory usage from memory.kmem.usage_in_bytes. Returns
+// none if memory.kmem.usage_in_bytes is not supported.
+Result<Bytes> kmem_usage_in_bytes(
+    const std::string& hierarchy,
+    const std::string& cgroup);
+
+
+// Returns the memory usage from memory.kmem.tcp.usage_in_bytes. Returns
+// none if memory.kmem.tcp.usage_in_bytes is not supported.
+Result<Bytes> kmem_tcp_usage_in_bytes(
+    const std::string& hierarchy,
+    const std::string& cgroup);
+
+
 // Out-of-memory (OOM) controls.
 namespace oom {
 
diff --git 
a/src/slave/containerizer/mesos/isolators/cgroups/subsystems/memory.cpp 
b/src/slave/containerizer/mesos/isolators/cgroups/subsystems/memory.cpp
index 15f87ba8c..566cbd3e3 100644
--- a/src/slave/containerizer/mesos/isolators/cgroups/subsystems/memory.cpp
+++ b/src/slave/containerizer/mesos/isolators/cgroups/subsystems/memory.cpp
@@ -460,6 +460,26 @@ Future<ResourceStatistics> MemorySubsystemProcess::usage(
 
   result.set_mem_total_bytes(usage->bytes());
 
+  Result<Bytes> kmem_usage = cgroups::memory::kmem_usage_in_bytes(
+      hierarchy, cgroup);
+
+  if (kmem_usage.isError()) {
+    return Failure("Failed to parse 'memory.kmem.usage_in_bytes': " +
+                   kmem_usage.error());
+  } else if (kmem_usage.isSome()) {
+    result.set_mem_kmem_usage_bytes(kmem_usage.get().bytes());
+  }
+
+  Result<Bytes> kmem_tcp_usage = cgroups::memory::kmem_tcp_usage_in_bytes(
+      hierarchy, cgroup);
+
+  if (kmem_tcp_usage.isError()) {
+    return Failure("Failed to parse 'memory.kmem.tcp.usage_in_bytes': " +
+                   kmem_tcp_usage.error());
+  } else if (kmem_tcp_usage.isSome()) {
+    result.set_mem_kmem_tcp_usage_bytes(kmem_tcp_usage.get().bytes());
+  }
+
   if (flags.cgroups_limit_swap) {
     Try<Bytes> usage = cgroups::memory::memsw_usage_in_bytes(hierarchy, 
cgroup);
 
diff --git a/src/tests/containerizer/cgroups_isolator_tests.cpp 
b/src/tests/containerizer/cgroups_isolator_tests.cpp
index 12b451d75..01e410a94 100644
--- a/src/tests/containerizer/cgroups_isolator_tests.cpp
+++ b/src/tests/containerizer/cgroups_isolator_tests.cpp
@@ -2317,6 +2317,7 @@ TEST_F(CgroupsIsolatorTest, ROOT_CGROUPS_MemoryForward)
   AWAIT_READY(usage);
 
   EXPECT_FALSE(usage->has_mem_total_bytes());
+  EXPECT_FALSE(usage->has_mem_kmem_usage_bytes());
 
   // Start a new container which will start reporting memory statistics.
   TaskInfo task2 = createTask(offers2.get()[0], "sleep 1000");
@@ -2354,6 +2355,17 @@ TEST_F(CgroupsIsolatorTest, ROOT_CGROUPS_MemoryForward)
 
   EXPECT_TRUE(usage->has_mem_total_bytes());
 
+  Result<string> hierarchy = cgroups::hierarchy("memory");
+  ASSERT_SOME(hierarchy);
+
+  Try<bool> exists = cgroups::exists(
+      hierarchy.get(), "memory.kmem.usage_in_bytes");
+  ASSERT_SOME(exists);
+
+  if (exists.get()) {
+    EXPECT_TRUE(usage->has_mem_kmem_usage_bytes());
+  }
+
   driver.stop();
   driver.join();
 }
diff --git a/src/tests/containerizer/memory_isolator_tests.cpp 
b/src/tests/containerizer/memory_isolator_tests.cpp
index cd6329f0f..266a79f93 100644
--- a/src/tests/containerizer/memory_isolator_tests.cpp
+++ b/src/tests/containerizer/memory_isolator_tests.cpp
@@ -150,6 +150,22 @@ TEST_P(MemoryIsolatorTest, ROOT_MemUsage)
   EXPECT_LT(0u, usage->mem_rss_bytes());
 #endif // __WINDOWS__
 
+  // Metrics for kmem are only enabled with memory isolation.
+  if (GetParam() == "cgroups/mem") {
+    Result<std::string> hierarchy = cgroups::hierarchy("memory");
+    ASSERT_SOME(hierarchy);
+
+    Try<bool> kmemExists = cgroups::exists(
+        hierarchy.get(), "memory.kmem.usage_in_bytes");
+    ASSERT_SOME(kmemExists);
+
+    if (kmemExists.get()) {
+      // We can assume more than 4096 bytes here, since a kernel page size is
+      // 4kB and we are allocating at least one.
+      ASSERT_LT(4096u, usage.get().mem_kmem_usage_bytes());
+    }
+  }
+
   driver.stop();
   driver.join();
 }

Reply via email to