From de58d1dd09a7ea964133da17d8c4281a776bc873 Mon Sep 17 00:00:00 2001 From: jwhur <57657645+JaewonHur@users.noreply.github.com> Date: Mon, 13 Apr 2026 18:42:28 -0700 Subject: [PATCH] Set memory.low for vminitd to avoid kernel reclaiming its memory (#682) Sets `memory.low` for `vminitd` cgroup to make kernel avoid reclaiming its memory under high memory pressure. Even if the container process runs in memory cgroup, consuming lots of page cache can lead to reclaiming `vminitd`'s page cache memory , which hangs the `vminitd`. Setting `memory.low` makes kernel avoid reclaiming `vminitd`'s page so that we can guarantee the proper `vminitd` operation under high memory pressure. --- vminitd/Sources/Cgroup/Cgroup2Manager.swift | 15 +++++++++++++++ vminitd/Sources/vminitd/AgentCommand.swift | 12 ++++++++---- 2 files changed, 23 insertions(+), 4 deletions(-) diff --git a/vminitd/Sources/Cgroup/Cgroup2Manager.swift b/vminitd/Sources/Cgroup/Cgroup2Manager.swift index 65ba6869..da6b72f6 100644 --- a/vminitd/Sources/Cgroup/Cgroup2Manager.swift +++ b/vminitd/Sources/Cgroup/Cgroup2Manager.swift @@ -252,6 +252,21 @@ package struct Cgroup2Manager: Sendable { ) } + package func setMemoryLow(bytes: UInt64) throws { + self.logger?.debug( + "setting memory.low", + metadata: [ + "path": "\(self.path.path)", + "bytes": "\(bytes)", + ] + ) + + try Self.writeValue( + path: self.path, + value: String(bytes), + fileName: "memory.low") + } + package func getMemoryEvents() throws -> MemoryEvents { let content = try readFileContent(fileName: "memory.events") let values = parseKeyValuePairs(content) diff --git a/vminitd/Sources/vminitd/AgentCommand.swift b/vminitd/Sources/vminitd/AgentCommand.swift index b361dde2..6b61ede9 100644 --- a/vminitd/Sources/vminitd/AgentCommand.swift +++ b/vminitd/Sources/vminitd/AgentCommand.swift @@ -123,19 +123,23 @@ struct AgentCommand: AsyncParsableCommand { try cgManager.toggleAllAvailableControllers(enable: true) // Set memory.high threshold to 75 MiB - let threshold: UInt64 = 75 * 1024 * 1024 - try cgManager.setMemoryHigh(bytes: threshold) + let high: UInt64 = 75 * 1024 * 1024 + // Set memory.low to 50 MiB to avoid reclaiming vminitd's memory + let low: UInt64 = 50 * 1024 * 1024 + + try cgManager.setMemoryHigh(bytes: high) + try cgManager.setMemoryLow(bytes: low) try cgManager.addProcess(pid: getpid()) let memoryMonitor = try MemoryMonitor( cgroupManager: cgManager, - threshold: threshold, + threshold: high, logger: log ) { [log] (currentUsage, highMark) in log.warning( "vminitd memory threshold exceeded", metadata: [ - "threshold_bytes": "\(threshold)", + "threshold_bytes": "\(high)", "current_bytes": "\(currentUsage)", "high_events_total": "\(highMark)", ])