From 8fba6e2b407870939c9e17543a4d89b125e361f6 Mon Sep 17 00:00:00 2001 From: Daan De Meyer Date: Tue, 28 Oct 2025 13:02:32 +0100 Subject: [PATCH] oomd: Make OomdCGroupContext reference counted Preparation for adding oomd hooks. --- src/oom/oomd-manager.c | 2 +- src/oom/oomd-util.c | 23 ++++++++++++++--------- src/oom/oomd-util.h | 6 ++++-- src/oom/test-oomd-util.c | 12 ++++++------ 4 files changed, 25 insertions(+), 18 deletions(-) diff --git a/src/oom/oomd-manager.c b/src/oom/oomd-manager.c index 3fc22d43e5a..a228aa1ae05 100644 --- a/src/oom/oomd-manager.c +++ b/src/oom/oomd-manager.c @@ -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; } diff --git a/src/oom/oomd-util.c b/src/oom/oomd-util.c index 0dcca282fe0..47b711f0bd3 100644 --- a/src/oom/oomd-util.c +++ b/src/oom/oomd-util.c @@ -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; diff --git a/src/oom/oomd-util.h b/src/oom/oomd-util.h index 45f868bc5ce..2632ebdec89 100644 --- a/src/oom/oomd-util.h +++ b/src/oom/oomd-util.h @@ -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. */ diff --git a/src/oom/test-oomd-util.c b/src/oom/test-oomd-util.c index 04db1e85ea0..259bd9f6ae5 100644 --- a/src/oom/test-oomd-util.c +++ b/src/oom/test-oomd-util.c @@ -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)); -- 2.47.3