diff --git a/src/oom/oomd-manager.c b/src/oom/oomd-manager.c index 085fc6487fd..6ce96062a1c 100644 --- a/src/oom/oomd-manager.c +++ b/src/oom/oomd-manager.c @@ -232,6 +232,26 @@ static int get_monitored_cgroup_contexts_candidates(Hashmap *monitored_cgroups, return 0; } +static int update_monitored_cgroup_contexts_candidates(Hashmap *monitored_cgroups, Hashmap **candidates) { + _cleanup_hashmap_free_ Hashmap *new_candidates = NULL; + int r; + + assert(monitored_cgroups); + assert(candidates); + assert(*candidates); + + r = get_monitored_cgroup_contexts_candidates(monitored_cgroups, &new_candidates); + if (r < 0) + return log_debug_errno(r, "Failed to get candidate contexts: %m"); + + oomd_update_cgroup_contexts_between_hashmaps(*candidates, new_candidates); + + hashmap_free(*candidates); + *candidates = TAKE_PTR(new_candidates); + + return 0; +} + static int acquire_managed_oom_connect(Manager *m) { _cleanup_(varlink_close_unrefp) Varlink *link = NULL; int r; @@ -297,6 +317,11 @@ static int monitor_cgroup_contexts_handler(sd_event_source *s, uint64_t usec, vo if (r == -ENOMEM) return log_error_errno(r, "Failed to update monitored memory pressure cgroup contexts"); + r = update_monitored_cgroup_contexts_candidates( + m->monitored_mem_pressure_cgroup_contexts, &m->monitored_mem_pressure_cgroup_contexts_candidates); + if (r == -ENOMEM) + return log_error_errno(r, "Failed to update monitored memory pressure candidate cgroup contexts"); + r = oomd_system_context_acquire("/proc/swaps", &m->system_context); /* If there aren't units depending on swap actions, the only error we exit on is ENOMEM. * Allow ENOENT in the event that swap is disabled on the system. */ @@ -326,18 +351,13 @@ static int monitor_cgroup_contexts_handler(sd_event_source *s, uint64_t usec, vo * this will cause pressure to remain high. Thus if there isn't any reclaim pressure, no need * to kill something (it won't help anyways). */ if ((usec_now - m->last_reclaim_at) <= RECLAIM_DURATION_USEC) { - _cleanup_hashmap_free_ Hashmap *candidates = NULL; OomdCGroupContext *t; - r = get_monitored_cgroup_contexts_candidates(m->monitored_mem_pressure_cgroup_contexts, &candidates); - if (r == -ENOMEM) - return log_error_errno(r, "Failed to get monitored memory pressure cgroup candidates"); - SET_FOREACH(t, targets) { log_notice("Memory pressure for %s is greater than %lu for more than %"PRIu64" seconds and there was reclaim activity", t->path, LOAD_INT(t->mem_pressure_limit), m->default_mem_pressure_duration_usec / USEC_PER_SEC); - r = oomd_kill_by_pgscan(candidates, t->path, m->dry_run); + r = oomd_kill_by_pgscan(m->monitored_mem_pressure_cgroup_contexts_candidates, t->path, m->dry_run); if (r == -ENOMEM) return log_error_errno(r, "Failed to kill cgroup processes by pgscan"); if (r < 0) @@ -412,6 +432,7 @@ Manager* manager_free(Manager *m) { hashmap_free(m->monitored_swap_cgroup_contexts); hashmap_free(m->monitored_mem_pressure_cgroup_contexts); + hashmap_free(m->monitored_mem_pressure_cgroup_contexts_candidates); return mfree(m); } @@ -448,6 +469,10 @@ int manager_new(Manager **ret) { if (!m->monitored_mem_pressure_cgroup_contexts) return -ENOMEM; + m->monitored_mem_pressure_cgroup_contexts_candidates = hashmap_new(&oomd_cgroup_ctx_hash_ops); + if (!m->monitored_mem_pressure_cgroup_contexts_candidates) + return -ENOMEM; + *ret = TAKE_PTR(m); return 0; } diff --git a/src/oom/oomd-manager.h b/src/oom/oomd-manager.h index 9ab8494c6d3..9c580c8a249 100644 --- a/src/oom/oomd-manager.h +++ b/src/oom/oomd-manager.h @@ -40,6 +40,7 @@ struct Manager { * Used to detect when to take action. */ Hashmap *monitored_swap_cgroup_contexts; Hashmap *monitored_mem_pressure_cgroup_contexts; + Hashmap *monitored_mem_pressure_cgroup_contexts_candidates; OomdSystemContext system_context;