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 04f973ba1 [cgroups2] Add memory usage reporting to the
MemoryControllerProcess
04f973ba1 is described below
commit 04f973ba1526224aab3031b9502507abf74d9864
Author: None <None>
AuthorDate: Wed May 15 17:47:31 2024 -0400
[cgroups2] Add memory usage reporting to the MemoryControllerProcess
Introduces `::usage` to the MemoryControllerProcess to report the total
memory usage of a cgroup as well as memory usage statistics provided
by `cgroups2::memory:stats`.
Review: https://reviews.apache.org/r/74985/
---
include/mesos/mesos.proto | 11 +++++
include/mesos/v1/mesos.proto | 9 ++++
.../isolators/cgroups2/controllers/memory.cpp | 49 ++++++++++++++++++++++
.../isolators/cgroups2/controllers/memory.hpp | 4 ++
src/tests/containerizer/memory_isolator_tests.cpp | 10 +++--
src/tests/mesos.cpp | 4 +-
6 files changed, 81 insertions(+), 6 deletions(-)
diff --git a/include/mesos/mesos.proto b/include/mesos/mesos.proto
index 2aad66d67..01f37ae38 100644
--- a/include/mesos/mesos.proto
+++ b/include/mesos/mesos.proto
@@ -1836,20 +1836,31 @@ message ResourceStatistics {
// TODO(chzhcn) mem_file_bytes and mem_anon_bytes are deprecated in
// 0.23.0 and will be removed in 0.24.0.
+ // Amount of memory used to cache filesystem data, including tmpfs and shared
+ // memory, in bytes.
optional uint64 mem_file_bytes = 10;
+ // Amount of memory used in anonymous mappings in bytes.
optional uint64 mem_anon_bytes = 11;
// mem_cache_bytes is added in 0.23.0 to represent page cache usage.
+ // Amount of memory used to cache filesystem data, including tmpfs and shared
+ // memory, in bytes.
optional uint64 mem_cache_bytes = 39;
// Since 0.23.0, mem_rss_bytes is changed to represent only
// anonymous memory usage. Note that neither its requiredness, type,
// name nor numeric tag has been changed.
+ // Amount of memory used in anonymous mappings in bytes.
optional uint64 mem_rss_bytes = 5;
+ // Amount of cached filesystem data mapped with mmap() in bytes.
optional uint64 mem_mapped_file_bytes = 12;
+
// This is only set if swap is enabled.
+ // Amount of swap usage in bytes.
optional uint64 mem_swap_bytes = 40;
+
+ // Amount of unevictable usage in bytes.
optional uint64 mem_unevictable_bytes = 41;
// Number of occurrences of different levels of memory pressure
diff --git a/include/mesos/v1/mesos.proto b/include/mesos/v1/mesos.proto
index d4ab6f35f..ef4920a47 100644
--- a/include/mesos/v1/mesos.proto
+++ b/include/mesos/v1/mesos.proto
@@ -1800,20 +1800,29 @@ message ResourceStatistics {
// TODO(chzhcn) mem_file_bytes and mem_anon_bytes are deprecated in
// 0.23.0 and will be removed in 0.24.0.
+ // Amount of memory used to cache filesystem data, including tmpfs and shared
+ // memory, in bytes.
optional uint64 mem_file_bytes = 10;
+ // Amount of memory used in anonymous mappings in bytes.
optional uint64 mem_anon_bytes = 11;
// mem_cache_bytes is added in 0.23.0 to represent page cache usage.
+ // Amount of memory used to cache filesystem data, including tmpfs and shared
+ // memory, in bytes.
optional uint64 mem_cache_bytes = 39;
// Since 0.23.0, mem_rss_bytes is changed to represent only
// anonymous memory usage. Note that neither its requiredness, type,
// name nor numeric tag has been changed.
+ // Amount of memory used in anonymous mappings in bytes.
optional uint64 mem_rss_bytes = 5;
+ // Amount of cached filesystem data mapped with mmap() in bytes.
optional uint64 mem_mapped_file_bytes = 12;
// This is only set if swap is enabled.
+ // Amount of swap usage in bytes.
optional uint64 mem_swap_bytes = 40;
+ // Amount of unevictable usage in bytes.
optional uint64 mem_unevictable_bytes = 41;
// Number of occurrences of different levels of memory pressure
diff --git
a/src/slave/containerizer/mesos/isolators/cgroups2/controllers/memory.cpp
b/src/slave/containerizer/mesos/isolators/cgroups2/controllers/memory.cpp
index 872a585e2..4da2ab79e 100644
--- a/src/slave/containerizer/mesos/isolators/cgroups2/controllers/memory.cpp
+++ b/src/slave/containerizer/mesos/isolators/cgroups2/controllers/memory.cpp
@@ -197,6 +197,55 @@ Future<Nothing> MemoryControllerProcess::update(
}
+Future<ResourceStatistics> MemoryControllerProcess::usage(
+ const ContainerID& containerId,
+ const string& cgroup)
+{
+ if (!infos.contains(containerId)) {
+ return Failure("Unknown container");
+ }
+
+ // TODO (jasonzhou): Report a greater variety of stats which are available in
+ // cgroups2 memory.stat file.
+ ResourceStatistics stats;
+
+ // Current memory usage.
+ Try<Bytes> usage = cgroups2::memory::usage(cgroup);
+ if (usage.isError()) {
+ return Failure("Failed to get current memory usage: " + usage.error());
+ }
+
+ stats.set_mem_total_bytes(usage->bytes());
+
+ Try<Stats> memoryStats = cgroups2::memory::stats(cgroup);
+ if (memoryStats.isError()) {
+ return Failure("Failed to get cgroup memory stats: " +
memoryStats.error());
+ }
+
+ // Kernel memory usage.
+ stats.set_mem_kmem_usage_bytes(memoryStats->kernel.bytes());
+
+ // Kernel TCP buffers usage.
+ stats.set_mem_kmem_tcp_usage_bytes(memoryStats->sock.bytes());
+
+ // Page cache usage.
+ stats.set_mem_file_bytes(memoryStats->file.bytes());
+ stats.set_mem_cache_bytes(memoryStats->file.bytes());
+
+ // Anonymous memory usage.
+ stats.set_mem_anon_bytes(memoryStats->anon.bytes());
+ stats.set_mem_rss_bytes(memoryStats->anon.bytes());
+
+ // File mapped memory usage.
+ stats.set_mem_mapped_file_bytes(memoryStats->file_mapped.bytes());
+
+ // Total unevictable memory.
+ stats.set_mem_unevictable_bytes(memoryStats->unevictable.bytes());
+
+ return stats;
+}
+
+
Future<Nothing> MemoryControllerProcess::cleanup(
const ContainerID& containerId,
const string& cgroup)
diff --git
a/src/slave/containerizer/mesos/isolators/cgroups2/controllers/memory.hpp
b/src/slave/containerizer/mesos/isolators/cgroups2/controllers/memory.hpp
index 3dbfca917..4a80717e6 100644
--- a/src/slave/containerizer/mesos/isolators/cgroups2/controllers/memory.hpp
+++ b/src/slave/containerizer/mesos/isolators/cgroups2/controllers/memory.hpp
@@ -65,6 +65,10 @@ public:
const google::protobuf::Map<
std::string, Value::Scalar>& resourceLimits = {}) override;
+ process::Future<ResourceStatistics> usage(
+ const ContainerID& containerId,
+ const std::string& cgroup) override;
+
process::Future<Nothing> cleanup(
const ContainerID& containerId,
const std::string& cgroup) override;
diff --git a/src/tests/containerizer/memory_isolator_tests.cpp
b/src/tests/containerizer/memory_isolator_tests.cpp
index 6e0e51455..be8475f51 100644
--- a/src/tests/containerizer/memory_isolator_tests.cpp
+++ b/src/tests/containerizer/memory_isolator_tests.cpp
@@ -152,6 +152,11 @@ TEST_P(MemoryIsolatorTest, ROOT_MemUsage)
// Metrics for kmem are only enabled with memory isolation.
if (GetParam() == "cgroups/mem") {
+ // Check that at least one page of kernel memory is used. Each page is
+ // 4096 bytes so we expect at least that much memory to be used.
+#ifdef ENABLE_CGROUPS_V2
+ ASSERT_LT(4096u, usage->mem_kmem_usage_bytes());
+#else
Result<std::string> hierarchy = cgroups::hierarchy("memory");
ASSERT_SOME(hierarchy);
@@ -160,11 +165,10 @@ TEST_P(MemoryIsolatorTest, ROOT_MemUsage)
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->mem_kmem_usage_bytes());
}
- }
+#endif // ENABLE_CGROUPS_V2
+ }
driver.stop();
driver.join();
diff --git a/src/tests/mesos.cpp b/src/tests/mesos.cpp
index 762200cda..ffbb30b95 100644
--- a/src/tests/mesos.cpp
+++ b/src/tests/mesos.cpp
@@ -586,9 +586,7 @@ slave::Flags
ContainerizerTest<slave::MesosContainerizer>::CreateSlaveFlags()
// Use cgroup isolators if they're available and we're root.
// TODO(idownes): Refactor the cgroups/non-cgroups code.
if (cgroupsV2() && *user == "root") {
- // TODO(dleamy): Add the memory isolator once it's supported by the cgroups
- // v2 isolator.
- flags.isolation = "cgroups/cpu";
+ flags.isolation = "cgroups/cpu,cgroups/mem";
flags.cgroups_hierarchy = "/sys/fs/cgroup";
flags.cgroups_root = TEST_CGROUPS_ROOT;
} else if (cgroups::enabled() && *user == "root") {