]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
oomd: Make OomdCGroupContext reference counted
authorDaan De Meyer <daan.j.demeyer@gmail.com>
Tue, 28 Oct 2025 12:02:32 +0000 (13:02 +0100)
committerMatteo Croce <teknoraver@meta.com>
Mon, 9 Feb 2026 01:05:57 +0000 (02:05 +0100)
Preparation for adding oomd hooks.

src/oom/oomd-manager.c
src/oom/oomd-util.c
src/oom/oomd-util.h
src/oom/test-oomd-util.c

index 3fc22d43e5a3eb0efca72218ded9e646dfc8e40f..a228aa1ae0539e8715714d671a233b52b0fb3017 100644 (file)
@@ -105,7 +105,7 @@ static int process_managed_oom_message(Manager *m, uid_t uid, sd_json_variant *p
                                 m->monitored_swap_cgroup_contexts : m->monitored_mem_pressure_cgroup_contexts;
 
                 if (message.mode == MANAGED_OOM_AUTO) {
-                        (void) oomd_cgroup_context_free(hashmap_remove(monitor_hm, empty_to_root(message.path)));
+                        (void) oomd_cgroup_context_unref(hashmap_remove(monitor_hm, empty_to_root(message.path)));
                         continue;
                 }
 
index 0dcca282fe0057cf9c86a5ed86cacb538e8849b8..47b711f0bd37201ba3fd63ed3365da00072a4056 100644 (file)
@@ -25,7 +25,7 @@ DEFINE_HASH_OPS_WITH_VALUE_DESTRUCTOR(
                 path_hash_func,
                 path_compare,
                 OomdCGroupContext,
-                oomd_cgroup_context_free);
+                oomd_cgroup_context_unref);
 
 static int log_kill(const PidRef *pid, int sig, void *userdata) {
         log_debug("oomd attempting to kill " PID_FMT " with %s", pid->pid, signal_to_string(sig));
@@ -62,7 +62,7 @@ static int increment_oomd_xattr(const char *path, const char *xattr, uint64_t nu
         return 0;
 }
 
-OomdCGroupContext *oomd_cgroup_context_free(OomdCGroupContext *ctx) {
+static OomdCGroupContext *oomd_cgroup_context_free(OomdCGroupContext *ctx) {
         if (!ctx)
                 return NULL;
 
@@ -70,6 +70,8 @@ OomdCGroupContext *oomd_cgroup_context_free(OomdCGroupContext *ctx) {
         return mfree(ctx);
 }
 
+DEFINE_TRIVIAL_REF_UNREF_FUNC(OomdCGroupContext, oomd_cgroup_context, oomd_cgroup_context_free);
+
 int oomd_pressure_above(Hashmap *h, Set **ret) {
         _cleanup_set_free_ Set *targets = NULL;
         OomdCGroupContext *ctx;
@@ -413,7 +415,7 @@ int oomd_kill_by_swap_usage(Hashmap *h, uint64_t threshold_usage, bool dry_run,
 }
 
 int oomd_cgroup_context_acquire(const char *path, OomdCGroupContext **ret) {
-        _cleanup_(oomd_cgroup_context_freep) OomdCGroupContext *ctx = NULL;
+        _cleanup_(oomd_cgroup_context_unrefp) OomdCGroupContext *ctx = NULL;
         _cleanup_free_ char *p = NULL, *val = NULL;
         bool is_root;
         int r;
@@ -425,8 +427,15 @@ int oomd_cgroup_context_acquire(const char *path, OomdCGroupContext **ret) {
         if (!ctx)
                 return -ENOMEM;
 
+        *ctx = (OomdCGroupContext) {
+                .n_ref = 1,
+                .preference = MANAGED_OOM_PREFERENCE_NONE,
+                .path = strdup(empty_to_root(path)),
+        };
+        if (!ctx->path)
+                return -ENOMEM;
+
         is_root = empty_or_root(path);
-        ctx->preference = MANAGED_OOM_PREFERENCE_NONE;
 
         r = cg_get_path(path, "memory.pressure", &p);
         if (r < 0)
@@ -470,10 +479,6 @@ int oomd_cgroup_context_acquire(const char *path, OomdCGroupContext **ret) {
                         return log_debug_errno(r, "Error converting pgscan value to uint64_t: %m");
         }
 
-        r = strdup_to(&ctx->path, empty_to_root(path));
-        if (r < 0)
-                return r;
-
         *ret = TAKE_PTR(ctx);
         return 0;
 }
@@ -555,7 +560,7 @@ int oomd_system_context_acquire(const char *proc_meminfo_path, OomdSystemContext
 }
 
 int oomd_insert_cgroup_context(Hashmap *old_h, Hashmap *new_h, const char *path) {
-        _cleanup_(oomd_cgroup_context_freep) OomdCGroupContext *curr_ctx = NULL;
+        _cleanup_(oomd_cgroup_context_unrefp) OomdCGroupContext *curr_ctx = NULL;
         OomdCGroupContext *old_ctx;
         int r;
 
index 45f868bc5cec636fc147082f9837b522de5027c5..2632ebdec89ca231d08337e00a774da9fb15e6e4 100644 (file)
@@ -16,6 +16,7 @@ typedef struct OomdSystemContext OomdSystemContext;
 typedef int (oomd_compare_t)(OomdCGroupContext * const *, OomdCGroupContext * const *);
 
 struct OomdCGroupContext {
+        unsigned n_ref;
         char *path;
 
         ResourcePressure memory_pressure;
@@ -45,8 +46,9 @@ struct OomdSystemContext {
         uint64_t swap_used;
 };
 
-OomdCGroupContext *oomd_cgroup_context_free(OomdCGroupContext *ctx);
-DEFINE_TRIVIAL_CLEANUP_FUNC(OomdCGroupContext*, oomd_cgroup_context_free);
+OomdCGroupContext *oomd_cgroup_context_ref(OomdCGroupContext *p);
+OomdCGroupContext *oomd_cgroup_context_unref(OomdCGroupContext *p);
+DEFINE_TRIVIAL_CLEANUP_FUNC(OomdCGroupContext*, oomd_cgroup_context_unref);
 
 /* All hashmaps used with these functions are expected to be of the form
  * key: cgroup paths -> value: OomdCGroupContext. */
index 04db1e85ea0e027c8ba9c30c93c6a3d1ab4ec2a0..259bd9f6ae508a8c0bc9d2525cca5eb58d03b0af 100644 (file)
@@ -115,7 +115,7 @@ TEST(oomd_cgroup_kill) {
 
 TEST(oomd_cgroup_context_acquire_and_insert) {
         _cleanup_hashmap_free_ Hashmap *h1 = NULL, *h2 = NULL;
-        _cleanup_(oomd_cgroup_context_freep) OomdCGroupContext *ctx = NULL;
+        _cleanup_(oomd_cgroup_context_unrefp) OomdCGroupContext *ctx = NULL;
         OomdCGroupContext *c1, *c2;
         CGroupMask mask;
 
@@ -138,7 +138,7 @@ TEST(oomd_cgroup_context_acquire_and_insert) {
         ASSERT_EQ(ctx->swap_usage, 0u);
         ASSERT_EQ(ctx->last_pgscan, 0u);
         ASSERT_EQ(ctx->pgscan, 0u);
-        ASSERT_NULL(ctx = oomd_cgroup_context_free(ctx));
+        ASSERT_NULL(ctx = oomd_cgroup_context_unref(ctx));
 
         ASSERT_OK(oomd_cgroup_context_acquire("", &ctx));
         ASSERT_STREQ(ctx->path, "/");
@@ -429,7 +429,7 @@ TEST(oomd_sort_cgroups) {
 }
 
 TEST(oomd_fetch_cgroup_oom_preference) {
-        _cleanup_(oomd_cgroup_context_freep) OomdCGroupContext *ctx = NULL;
+        _cleanup_(oomd_cgroup_context_unrefp) OomdCGroupContext *ctx = NULL;
         ManagedOOMPreference root_pref;
         CGroupMask mask;
         bool test_xattrs;
@@ -464,7 +464,7 @@ TEST(oomd_fetch_cgroup_oom_preference) {
                 ASSERT_FAIL(oomd_fetch_cgroup_oom_preference(ctx, NULL));
                 ASSERT_EQ(ctx->preference, MANAGED_OOM_PREFERENCE_NONE);
         }
-        ctx = oomd_cgroup_context_free(ctx);
+        ctx = oomd_cgroup_context_unref(ctx);
 
         /* also check when only avoid is set to true */
         if (test_xattrs) {
@@ -473,7 +473,7 @@ TEST(oomd_fetch_cgroup_oom_preference) {
                 ASSERT_OK(oomd_cgroup_context_acquire(cgroup, &ctx));
                 ASSERT_OK(oomd_fetch_cgroup_oom_preference(ctx, NULL));
                 ASSERT_EQ(ctx->preference, geteuid() == 0 ? MANAGED_OOM_PREFERENCE_AVOID : MANAGED_OOM_PREFERENCE_NONE);
-                ctx = oomd_cgroup_context_free(ctx);
+                ctx = oomd_cgroup_context_unref(ctx);
         }
 
         /* Test the root cgroup */
@@ -493,7 +493,7 @@ TEST(oomd_fetch_cgroup_oom_preference) {
         /* Assert that avoid/omit are not set if the cgroup and prefix are not
          * owned by the same user. */
         if (test_xattrs && !empty_or_root(cgroup) && geteuid() == 0) {
-                ctx = oomd_cgroup_context_free(ctx);
+                ctx = oomd_cgroup_context_unref(ctx);
                 ASSERT_OK(cg_set_access(cgroup, 61183, 0));
                 ASSERT_OK(oomd_cgroup_context_acquire(cgroup, &ctx));