From 32e10881628c50b1c9f49d37105b7c463e9ca1c7 Mon Sep 17 00:00:00 2001 From: leeetao <3122669219@qq.com> Date: Sat, 7 Jun 2025 08:41:53 +0000 Subject: [PATCH] Fixed the issue where RAM reading was 0 in v2 containers --- common/profiler.cpp | 107 +++++++++++++++++++++----------------------- 1 file changed, 52 insertions(+), 55 deletions(-) diff --git a/common/profiler.cpp b/common/profiler.cpp index 0da13824..e833a738 100644 --- a/common/profiler.cpp +++ b/common/profiler.cpp @@ -47,6 +47,7 @@ #include #include +constexpr uint64_t kUnlimitedMemory = UINT64_MAX; static int gcd_int(int a, int b) { while (b != 0) { @@ -583,16 +584,22 @@ static uint64_t device_host_physical_memory(bool available) { static uint64_t read_value_from_file(const char * path) { std::ifstream file(path); if (!file.is_open()) { - return 0; + return kUnlimitedMemory; } + std::string line; if (!std::getline(file, line)) { - return 0; + return kUnlimitedMemory; } + + if (line == "max") { + return kUnlimitedMemory; + } + try { return std::stoull(line); } catch (...) { - return 0; + return kUnlimitedMemory; } } @@ -620,66 +627,56 @@ static std::unordered_map read_memory_stat() { } static uint64_t device_cgroup_physical_memory(bool available) { - const char * file_path = nullptr; + constexpr uint64_t kUNLIMITED = UINT64_MAX; bool is_cgroup_v2 = false; { - std::ifstream cgroup_file("/proc/cgroups"); - if (cgroup_file.is_open()) { - std::string line; - while (std::getline(cgroup_file, line)) { - if (line.find("0") != std::string::npos) { - is_cgroup_v2 = true; - break; - } + std::ifstream mi("/proc/self/mountinfo"); + std::string l; + while (std::getline(mi, l)) { + if (l.find(" - cgroup2 ") != std::string::npos) { + is_cgroup_v2 = true; + break; } } } - + + auto read_or_host = [&](const char *path) -> uint64_t { + uint64_t v = read_value_from_file(path); + return v == kUNLIMITED ? device_host_physical_memory(false) : v; + }; + if (!available) { - if (is_cgroup_v2) { - file_path = "/sys/fs/cgroup/memory.max"; - } else { - file_path = "/sys/fs/cgroup/memory/memory.limit_in_bytes"; - } - return read_value_from_file(file_path); - } else { - if (is_cgroup_v2) { - uint64_t mem_max = read_value_from_file("/sys/fs/cgroup/memory.max"); - uint64_t mem_current = read_value_from_file("/sys/fs/cgroup/memory.current"); - - if (mem_max == UINT64_MAX) { - mem_max = device_host_physical_memory(false); - } - - uint64_t mem_low = read_value_from_file("/sys/fs/cgroup/memory.low"); - - auto stats = read_memory_stat(); - - uint64_t slab_reclaimable = 0; - uint64_t mmap_file = 0; - - if (stats.find("slab_reclaimable") != stats.end()) { - slab_reclaimable = stats["slab_reclaimable"]; - } - if (stats.find("file") != stats.end()) { - mmap_file = stats["file"]; - } - - uint64_t available_memory = mem_max - mem_current; - if (mem_low > 0 && available_memory < mem_low) { - available_memory = mem_low; - } - available_memory += slab_reclaimable * 0.5 + mmap_file * 0.5; - - return available_memory < mem_max ? available_memory : mem_max; - } else { - LOG_WRN("Using cgroup v1, the available memory could be error, will be addressed later\n"); - uint64_t mem_limit = read_value_from_file("/sys/fs/cgroup/memory/memory.limit_in_bytes"); - uint64_t mem_usage = read_value_from_file("/sys/fs/cgroup/memory/memory.usage_in_bytes"); - return mem_limit - mem_usage > 0 ? mem_limit - mem_usage : 0; - } + return is_cgroup_v2 + ? read_or_host("/sys/fs/cgroup/memory.max") // v2 + : read_or_host("/sys/fs/cgroup/memory/memory.limit_in_bytes"); // v1 } + + if (is_cgroup_v2) { + uint64_t mem_max = read_or_host("/sys/fs/cgroup/memory.max"); + uint64_t mem_current = read_value_from_file("/sys/fs/cgroup/memory.current"); + uint64_t mem_low = read_value_from_file("/sys/fs/cgroup/memory.low"); + + + auto stats = read_memory_stat(); + uint64_t slab_reclaimable = stats.count("slab_reclaimable") ? stats["slab_reclaimable"] : 0; + uint64_t mmap_file = stats.count("file") ? stats["file"] : 0; + + uint64_t available_memory = mem_max > mem_current ? mem_max - mem_current : 0; + if (mem_low > 0 && available_memory < mem_low) { + available_memory = mem_low; + } + available_memory += static_cast(slab_reclaimable * 0.5 + mmap_file * 0.5); + + return std::min(available_memory, mem_max); + } + + // v1 + LOG_WRN("Using cgroup v1, the available memory may be inaccurate, will be addressed later\n"); + uint64_t mem_limit = read_or_host("/sys/fs/cgroup/memory/memory.limit_in_bytes"); + uint64_t mem_usage = read_value_from_file("/sys/fs/cgroup/memory/memory.usage_in_bytes"); + + return mem_limit > mem_usage ? mem_limit - mem_usage : 0; } uint64_t device_physical_memory(bool available) {