Add memory limit enforcement to aos_starter
This gives us a hammer to figure out who is running us out of RAM by
allocating it. That'll let us kill the culprit rather than letting the
OOM killer pick for us.
Change-Id: Id270b878e908f0bf296ed5fc176e327e9b6c2d5a
Signed-off-by: Austin Schuh <austin.schuh@bluerivertech.com>
diff --git a/aos/starter/subprocess.h b/aos/starter/subprocess.h
index a4d7cbb..bacc574 100644
--- a/aos/starter/subprocess.h
+++ b/aos/starter/subprocess.h
@@ -35,6 +35,22 @@
DISALLOW_COPY_AND_ASSIGN(SignalListener);
};
+// Class to use the V1 cgroup API to limit memory usage.
+class MemoryCGroup {
+ public:
+ MemoryCGroup(std::string_view name);
+ ~MemoryCGroup();
+
+ // Adds a thread ID to be managed by the cgroup.
+ void AddTid(pid_t pid = 0);
+
+ // Sets the provided limit to the provided value.
+ void SetLimit(std::string_view limit_name, uint64_t limit_value);
+
+ private:
+ std::string cgroup_;
+};
+
// Manages a running process, allowing starting and stopping, and restarting
// automatically.
class Application {
@@ -80,6 +96,14 @@
const std::string &GetStderr();
std::optional<int> exit_code() const { return exit_code_; }
+ // Sets the memory limit for the application to the provided limit.
+ void SetMemoryLimit(size_t limit) {
+ if (!memory_cgroup_) {
+ memory_cgroup_ = std::make_unique<MemoryCGroup>(name_);
+ }
+ memory_cgroup_->SetLimit("memory.limit_in_bytes", limit);
+ }
+
private:
typedef aos::util::ScopedPipe::PipePair PipePair;
void set_args(
@@ -144,6 +168,8 @@
std::function<void()> on_change_;
+ std::unique_ptr<MemoryCGroup> memory_cgroup_;
+
DISALLOW_COPY_AND_ASSIGN(Application);
};