From 01bfce098149bb40c9fe92bee3eee16cff50c4fb Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Tue, 4 Jun 2024 21:02:25 -0700 Subject: [PATCH] os: cgroup can set memory limits --- src/apprt/gtk/cgroup.zig | 9 +++++++++ src/os/cgroup.zig | 28 ++++++++++++++++++++++++++++ 2 files changed, 37 insertions(+) diff --git a/src/apprt/gtk/cgroup.zig b/src/apprt/gtk/cgroup.zig index 1b621d792..47edd05bc 100644 --- a/src/apprt/gtk/cgroup.zig +++ b/src/apprt/gtk/cgroup.zig @@ -52,6 +52,15 @@ pub fn init(app: *App) ![]const u8 { // I don't know a scenario where this fails yet. try enableControllers(alloc, transient); + // Configure the "high" memory limit. This limit is used instead + // of "max" because it's a soft limit that can be exceeded and + // can be monitored by things like systemd-oomd to kill if needed, + // versus an instant hard kill. + // try internal_os.cgroup.configureMemoryLimit(transient, .{ + // // 1GB + // .high = 1 * 1024 * 1024 * 1024, + // }); + return transient; } diff --git a/src/os/cgroup.zig b/src/os/cgroup.zig index baad0c070..8e666e89d 100644 --- a/src/os/cgroup.zig +++ b/src/os/cgroup.zig @@ -107,3 +107,31 @@ pub fn configureControllers( // Write try file.writer().writeAll(v); } + +pub const MemoryLimit = union(enum) { + /// memory.high + high: usize, +}; + +/// Configure the memory limit for the given cgroup. Use the various +/// fields in MemoryLimit to configure a specific type of limit. +pub fn configureMemoryLimit(cgroup: []const u8, limit: MemoryLimit) !void { + assert(cgroup[0] == '/'); + + const filename, const size = switch (limit) { + .high => |v| .{ "memory.high", v }, + }; + + // Open our file + var buf: [std.fs.MAX_PATH_BYTES]u8 = undefined; + const path = try std.fmt.bufPrint( + &buf, + "/sys/fs/cgroup{s}/{s}", + .{ cgroup, filename }, + ); + const file = try std.fs.cwd().openFile(path, .{ .mode = .write_only }); + defer file.close(); + + // Write our limit in bytes + try file.writer().print("{}", .{size}); +}