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();
}