From ee5a0990e93f981db1df9e3f6ea7193e6cc2e257 Mon Sep 17 00:00:00 2001 From: Unsung Lee Date: Wed, 30 Mar 2022 21:28:57 +0900 Subject: [PATCH] Remove useless source code remove useless code including indent Change-Id: I5a96a373c462aee523ea072c66e2f2f78f5fd25d Signed-off-by: Unsung Lee --- ; | 2343 -------------------- src/common/cgroup/cpu-cgroup.c | 2 +- src/common/cgroup/memory-cgroup.c | 12 +- src/common/cgroup/memory-cgroup.h | 2 +- src/common/config-parser.c | 397 +--- src/common/config-parser.h | 13 +- src/common/swap-common.h | 2 +- src/resource-limiter/cpu/cpu-sched.c | 5 +- src/resource-limiter/memory/lowmem-limit.c | 39 +- .../memory/vmpressure-lowmem-handler.c | 315 +-- .../memory/compaction/compaction.c | 38 - src/resource-optimizer/memory/dedup/dedup.c | 155 +- src/resource-optimizer/memory/swap/fileswap.c | 34 - src/resource-optimizer/memory/swap/swap.c | 46 +- src/resource-optimizer/memory/swap/zramswap.c | 36 +- src/resource-optimizer/memory/swap/zswap.c | 46 +- 16 files changed, 32 insertions(+), 3453 deletions(-) delete mode 100644 ; diff --git a/; b/; deleted file mode 100644 index 86abdd8..0000000 --- a/; +++ /dev/null @@ -1,2343 +0,0 @@ -/* - * resourced - * - * Copyright (c) 2012 - 2019 Samsung Electronics Co., Ltd. All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* - * @file vmpressure-lowmem-handler.c - * - * @desc lowmem handler using memcgroup - * - * Copyright (c) 2014 Samsung Electronics Co., Ltd. All rights reserved. - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "trace.h" -#include "cgroup.h" -#include "lowmem-handler.h" -#include "proc-common.h" -#include "procfs.h" -#include "freezer.h" -#include "resourced.h" -#include "macro.h" -#include "notifier.h" -#include "config-parser.h" -#include "module.h" -#include "swap-common.h" -#include "cgroup.h" -#include "memory-cgroup.h" -#include "heart-common.h" -#include "proc-main.h" -#include "dbus-handler.h" -#include "util.h" -#include "fd-handler.h" -#include "resourced-helper-worker.h" -#include "safe-kill.h" -#include "dedup-common.h" - -#define LOWMEM_THRES_INIT 0 - -#define MEMPS_EXEC_PATH "usr/bin/memps" -#define MEM_CONF_FILE RD_CONFIG_FILE(limiter) -#define MEM_SECTION "Memory" -#define MEM_VIP_SECTION "VIP_PROCESS" -#define MEM_VIP_PREDEFINE "PREDEFINE" -#define MEM_POPUP_SECTION "POPUP" -#define MEM_POPUP_STRING "oom_popup" -#define MEM_BG_RECLAIM_SECTION "BackgroundReclaim" -#define MEM_BG_RECLAIM_STRING "AfterScreenDim" -#define MEM_LOGGING_SECTION "Logging" - -#define BUF_MAX 1024 -#define MAX_VICTIMS_BETWEEN_CHECK 3 -#define MAX_PROACTIVE_LOW_VICTIMS 2 -#define MAX_PROACTIVE_HIGH_VICTIMS 4 -#define FOREGROUND_VICTIMS 1 -#define OOM_TIMER_INTERVAL 2 -#define OOM_KILLER_PRIORITY -20 -#define THRESHOLD_MARGIN 10 /* MB */ - -#define MEM_SIZE_64 64 /* MB */ -#define MEM_SIZE_256 256 /* MB */ -#define MEM_SIZE_448 448 /* MB */ -#define MEM_SIZE_512 512 /* MB */ -#define MEM_SIZE_768 768 /* MB */ -#define MEM_SIZE_1024 1024 /* MB */ -#define MEM_SIZE_2048 2048 /* MB */ - -/* thresholds for 64M RAM*/ -#define PROACTIVE_64_THRES 10 /* MB */ -#define PROACTIVE_64_LEAVE 30 /* MB */ -#define CGROUP_ROOT_64_THRES_DEDUP 16 /* MB */ -#define CGROUP_ROOT_64_THRES_SWAP 15 /* MB */ -#define CGROUP_ROOT_64_THRES_LOW 8 /* MB */ -#define CGROUP_ROOT_64_THRES_MEDIUM 5 /* MB */ -#define CGROUP_ROOT_64_THRES_LEAVE 8 /* MB */ -#define CGROUP_ROOT_64_NUM_VICTIMS 1 - -/* thresholds for 256M RAM */ -#define PROACTIVE_256_THRES 50 /* MB */ -#define PROACTIVE_256_LEAVE 80 /* MB */ -#define CGROUP_ROOT_256_THRES_DEDUP 60 /* MB */ -#define CGROUP_ROOT_256_THRES_SWAP 40 /* MB */ -#define CGROUP_ROOT_256_THRES_LOW 20 /* MB */ -#define CGROUP_ROOT_256_THRES_MEDIUM 10 /* MB */ -#define CGROUP_ROOT_256_THRES_LEAVE 20 /* MB */ -#define CGROUP_ROOT_256_NUM_VICTIMS 2 - -/* threshold for 448M RAM */ -#define PROACTIVE_448_THRES 80 /* MB */ -#define PROACTIVE_448_LEAVE 100 /* MB */ -#define CGROUP_ROOT_448_THRES_DEDUP 120 /* MB */ -#define CGROUP_ROOT_448_THRES_SWAP 100 /* MB */ -#define CGROUP_ROOT_448_THRES_LOW 60 /* MB */ -#define CGROUP_ROOT_448_THRES_MEDIUM 50 /* MB */ -#define CGROUP_ROOT_448_THRES_LEAVE 70 /* MB */ -#define CGROUP_ROOT_448_NUM_VICTIMS 5 - -/* threshold for 512M RAM */ -#define PROACTIVE_512_THRES 100 /* MB */ -#define PROACTIVE_512_LEAVE 80 /* MB */ -#define CGROUP_ROOT_512_THRES_DEDUP 140 /* MB */ -#define CGROUP_ROOT_512_THRES_SWAP 100 /* MB */ -#define CGROUP_ROOT_512_THRES_LOW 70 /* MB */ -#define CGROUP_ROOT_512_THRES_MEDIUM 60 /* MB */ -#define CGROUP_ROOT_512_THRES_LEAVE 80 /* MB */ -#define CGROUP_ROOT_512_NUM_VICTIMS 5 - -/* threshold for 768 RAM */ -#define PROACTIVE_768_THRES 100 /* MB */ -#define PROACTIVE_768_LEAVE 130 /* MB */ -#define CGROUP_ROOT_768_THRES_DEDUP 180 /* MB */ -#define CGROUP_ROOT_768_THRES_SWAP 150 /* MB */ -#define CGROUP_ROOT_768_THRES_LOW 90 /* MB */ -#define CGROUP_ROOT_768_THRES_MEDIUM 80 /* MB */ -#define CGROUP_ROOT_768_THRES_LEAVE 100 /* MB */ -#define CGROUP_ROOT_768_NUM_VICTIMS 5 - -/* threshold for more than 1024M RAM */ -#define PROACTIVE_1024_THRES 230 /* MB */ -#define PROACTIVE_1024_LEAVE 150 /* MB */ -#define CGROUP_ROOT_1024_THRES_DEDUP 400 /* MB */ -#define CGROUP_ROOT_1024_THRES_SWAP 300 /* MB */ -#define CGROUP_ROOT_1024_THRES_LOW 120 /* MB */ -#define CGROUP_ROOT_1024_THRES_MEDIUM 100 /* MB */ -#define CGROUP_ROOT_1024_THRES_LEAVE 150 /* MB */ -#define CGROUP_ROOT_1024_NUM_VICTIMS 5 - -/* threshold for more than 2048M RAM */ -#define PROACTIVE_2048_THRES 200 /* MB */ -#define PROACTIVE_2048_LEAVE 500 /* MB */ -#define CGROUP_ROOT_2048_THRES_DEDUP 400 /* MB */ -#define CGROUP_ROOT_2048_THRES_SWAP 300 /* MB */ -#define CGROUP_ROOT_2048_THRES_LOW 200 /* MB */ -#define CGROUP_ROOT_2048_THRES_MEDIUM 160 /* MB */ -#define CGROUP_ROOT_2048_THRES_LEAVE 300 /* MB */ -#define CGROUP_ROOT_2048_NUM_VICTIMS 10 - -/* threshold for more than 3072M RAM */ -#define PROACTIVE_3072_THRES 300 /* MB */ -#define PROACTIVE_3072_LEAVE 700 /* MB */ -#define CGROUP_ROOT_3072_THRES_DEDUP 600 /* MB */ -#define CGROUP_ROOT_3072_THRES_SWAP 500 /* MB */ -#define CGROUP_ROOT_3072_THRES_LOW 400 /* MB */ -#define CGROUP_ROOT_3072_THRES_MEDIUM 250 /* MB */ -#define CGROUP_ROOT_3072_THRES_LEAVE 500 /* MB */ -#define CGROUP_ROOT_3072_NUM_VICTIMS 10 - -static unsigned proactive_threshold; -static unsigned proactive_leave; -static unsigned lmk_start_threshold; - -static char *event_level = MEMCG_DEFAULT_EVENT_LEVEL; - -/** - * Resourced Low Memory Killer - * NOTE: planned to be moved to a separate file. - */ -/*-------------------------------------------------*/ -#define OOM_TIMER_INTERVAL_SEC 2 -#define LMW_LOOP_WAIT_TIMEOUT_MSEC OOM_TIMER_INTERVAL_SEC*(G_USEC_PER_SEC) -#define LMW_RETRY_WAIT_TIMEOUT_MSEC (G_USEC_PER_SEC) - -struct lowmem_control { - /* - * For each queued request the following properties - * are required with two exceptions: - * - status is being set by LMK - * - callback is optional - */ - /* Processing flags*/ - unsigned int flags; - /* Indictator for OOM score of targeted processes */ - enum cgroup_type type; - - /* Desired size to be restored - level to be reached (MB)*/ - unsigned int size; - /* Max number of processes to be considered */ - unsigned int count; - /* Memory reclaim status */ - int status; - /* - * Optional - if set, will be triggered by LMK once the request - * is handled. - */ - void (*callback) (struct lowmem_control *); -}; - -struct lowmem_worker { - pthread_t worker_thread; - GAsyncQueue *queue; - int active; - int running; -}; - -static struct lowmem_worker lmw; - -static int memlog_enabled; -static int memlog_nr_max = DEFAULT_MEMLOG_NR_MAX; -/* remove logfiles to reduce to this threshold. - * it is about five-sixths of the memlog_nr_max. */ -static int memlog_remove_batch_thres = (DEFAULT_MEMLOG_NR_MAX * 5) / 6; -static char *memlog_path = DEFAULT_MEMLOG_PATH; -static char *memlog_prefix[MEMLOG_MAX]; - -#define LOWMEM_WORKER_IS_ACTIVE(_lmw) g_atomic_int_get(&(_lmw)->active) -#define LOWMEM_WORKER_ACTIVATE(_lmw) g_atomic_int_set(&(_lmw)->active, 1) -#define LOWMEM_WORKER_DEACTIVATE(_lmw) g_atomic_int_set(&(_lmw)->active, 0) - -#define LOWMEM_WORKER_IS_RUNNING(_lmw) g_atomic_int_get(&(_lmw)->running) -#define LOWMEM_WORKER_RUN(_lmw) g_atomic_int_set(&(_lmw)->running, 1) -#define LOWMEM_WORKER_IDLE(_lmw) g_atomic_int_set(&(_lmw)->running, 0) - -#define LOWMEM_NEW_REQUEST() g_slice_new0(struct lowmem_control) - -#define LOWMEM_DESTROY_REQUEST(_ctl) \ - g_slice_free(typeof(*(_ctl)), _ctl); \ - -#define LOWMEM_SET_REQUEST(c, __flags, __type, __size, __count, __cb) \ -{ \ - (c)->flags = __flags; (c)->type = __type; \ - (c)->size = __size; (c)->count = __count; \ - (c)->callback = __cb; \ -} - -#define BUFF_MAX 255 -#define APP_ATTR_PATH "/proc/%d/attr/current" - -static int get_privilege(pid_t pid, char *name, size_t len) -{ - char path[PATH_MAX]; - char attr[BUFF_MAX]; - size_t attr_len; - FILE *fp; - - snprintf(path, sizeof(path), APP_ATTR_PATH, pid); - - fp = fopen(path, "r"); - if (!fp) - return -errno; - - attr_len = fread(attr, 1, sizeof(attr) - 1, fp); - fclose(fp); - if (attr_len <= 0) - return -ENOENT; - - attr[attr_len] = '\0'; - - snprintf(name, len, "%s", attr); - return 0; -} - -static int is_app(pid_t pid) -{ - char attr[BUFF_MAX]; - size_t len; - int ret; - - ret = get_privilege(pid, attr, sizeof(attr)); - if (ret < 0) { - _E("Failed to get privilege of PID(%d).", pid); - return -1; - } - - len = strlen(attr) + 1; - - if (!strncmp("System", attr, len)) - return 0; - - if (!strncmp("User", attr, len)) - return 0; - - if (!strncmp("System::Privileged", attr, len)) - return 0; - - return 1; -} - - -static void lowmem_queue_request(struct lowmem_worker *lmw, - struct lowmem_control *ctl) -{ - if (LOWMEM_WORKER_IS_ACTIVE(lmw)) - g_async_queue_push(lmw->queue, ctl); -} - -/* internal */ -static void lowmem_drain_queue(struct lowmem_worker *lmw) -{ - struct lowmem_control *ctl; - - g_async_queue_lock(lmw->queue); - while ((ctl = g_async_queue_try_pop_unlocked(lmw->queue))) { - if (ctl->callback) - ctl->callback(ctl); - LOWMEM_DESTROY_REQUEST(ctl); - } - g_async_queue_unlock(lmw->queue); -} - -static void lowmem_request_destroy(gpointer data) -{ - struct lowmem_control *ctl = (struct lowmem_control*) data; - - if (ctl->callback) - ctl->callback(ctl); - LOWMEM_DESTROY_REQUEST(ctl); -} - -/*-------------------------------------------------*/ - -/* low memory action function for cgroup */ -static void memory_cgroup_proactive_lmk_act(enum cgroup_type type, struct memcg_info *mi); -/* low memory action function */ -static void high_mem_act(void); -static void swap_activate_act(void); -static void swap_compact_act(void); -static void lmk_act(void); - - -static size_t cur_mem_state = MEM_LEVEL_HIGH; -static int num_max_victims = MAX_MEMORY_CGROUP_VICTIMS; -static int num_vict_between_check = MAX_VICTIMS_BETWEEN_CHECK; - -static unsigned long totalram; -static unsigned long ktotalram; - -static struct module_ops memory_modules_ops; -static const struct module_ops *lowmem_ops; -static bool oom_popup_enable; -static bool oom_popup; -static bool memcg_swap_status; -static bool bg_reclaim; -static int fragmentation_size; - -static const char *convert_cgroup_type_to_str(int type) -{ - static const char *type_table[] = - {"/", "VIP", "High", "Medium", "Lowest"}; - if (type >= CGROUP_ROOT && type <= CGROUP_LOW) - return type_table[type]; - else - return "Error"; -} - -static const char *convert_status_to_str(int status) -{ - static const char *status_table[] = - {"none", "done", "drop", "cont", "retry", "next_type"}; - if(status >= LOWMEM_RECLAIM_NONE && status <= LOWMEM_RECLAIM_NEXT_TYPE) - return status_table[status]; - return "error status"; -} - -static const char *convert_memstate_to_str(int mem_state) -{ - static const char *state_table[] = {"mem normal", "mem dedup", "mem swap", "mem low", - "mem medium"}; - if (mem_state >= 0 && mem_state < MEM_LEVEL_MAX) - return state_table[mem_state]; - return ""; -} - -static int lowmem_launch_oompopup(void) -{ - GVariantBuilder *const gv_builder = g_variant_builder_new(G_VARIANT_TYPE("a{ss}")); - g_variant_builder_add(gv_builder, "{ss}", "_SYSPOPUP_CONTENT_", "lowmemory_oom"); - - GVariant *const params = g_variant_new("(a{ss})", gv_builder); - g_variant_builder_unref(gv_builder); - - int ret = d_bus_call_method_sync_gvariant(SYSTEM_POPUP_BUS_NAME, - SYSTEM_POPUP_PATH_SYSTEM, SYSTEM_POPUP_IFACE_SYSTEM, - "PopupLaunch", params); - - g_variant_unref(params); - - return ret; -} - -static inline void get_total_memory(void) -{ - struct sysinfo si; - if (totalram) - return; - - if (!sysinfo(&si)) { - totalram = si.totalram; - ktotalram = BYTE_TO_KBYTE(totalram); - } -} - -static int lowmem_mem_usage_uss(pid_t pid, unsigned int *usage) -{ - unsigned int uss, zram = 0; - int ret; - - *usage = 0; - - /* - * In lowmem we need to know memory size of processes to - * for terminating apps. To get most real value of usage - * we should use USS + ZRAM usage for selected process. - * - * Those values will contain the most approximated amount - * of memory that will be freed after process termination. - */ - ret = proc_get_uss(pid, &uss); - if (ret != RESOURCED_ERROR_NONE) - return ret; - - if (swap_get_state() == SWAP_ON) { - ret = proc_get_zram_usage(pid, &zram); - /* If we don't get zram usage, it's not a problem */ - if (ret != RESOURCED_ERROR_NONE) - zram = 0; - } - *usage = uss + zram; - return RESOURCED_ERROR_NONE; -} - -unsigned int lowmem_get_task_mem_usage_rss(const struct task_info *tsk) -{ - unsigned int size = 0, total_size = 0; - int index, ret; - pid_t pid; - - /* - * If pids are allocated only when there are multiple processes with - * the same pgid e.g., browser and web process. Mostly, single process - * is used. - */ - if (tsk->pids == NULL) { - ret = proc_get_ram_usage(tsk->pid, &size); - - /* If there is no proc entry for given pid the process - * should be abandoned during further processing - */ - if (ret < 0) - _D("failed to get rss memory usage of %d", tsk->pid); - - return size; - } - - for (index = 0; index < tsk->pids->len; index++) { - pid = g_array_index(tsk->pids, pid_t, index); - ret = proc_get_ram_usage(pid, &size); - if (ret != RESOURCED_ERROR_NONE) - continue; - total_size += size; - } - - return total_size; -} - -static int memps_file_select(const struct dirent *entry) -{ - return strstr(entry->d_name, "memps") ? 1 : 0; -} - -static char *strrstr(const char *str, const char *token) -{ - int len = strlen(token); - const char *p = str + strlen(str); - - while (str <= --p) - if (p[0] == token[0] && strncmp(p, token, len) == 0) - return (char *)p; - - return NULL; -} - -static int timesort(const struct dirent **a, const struct dirent **b) -{ - long long time1 = 0; - long long time2 = 0; - char *ptr; - - ptr = strrstr((*a)->d_name, "_"); - if (ptr && *++ptr) - time1 = atoll(ptr); - - ptr = strrstr((*b)->d_name, "_"); - if (ptr && *++ptr) - time2 = atoll(ptr); - - return (time1 - time2); -} - -static int clear_logs(void *data) -{ - struct dirent **namelist; - int n, i, ret; - char fpath[BUF_MAX]; - char *fname; - char *dir = (char*)data; - int len; - - if (!memlog_enabled) - return RESOURCED_ERROR_NONE; - - if (!dir) - return RESOURCED_ERROR_NONE; - - len = strlen(dir); - if (len <= 0 || len >= sizeof fpath - 1) { - _E("Invalid parameter - Directory path is too short or too long"); - return RESOURCED_ERROR_INVALID_PARAMETER; - } - - n = scandir(dir, &namelist, memps_file_select, timesort); - - _D("num of log files %d", n); - if (n <= memlog_nr_max) { - while (n--) - free(namelist[n]); - free(namelist); - return RESOURCED_ERROR_NONE; - } - - strncpy(fpath, dir, sizeof fpath - 1); - fpath[sizeof fpath - 1] = '\0'; - fname = fpath + len; - *fname++ = '/'; - - len = sizeof fpath - len - 1; - for (i = 0; i < n; i++) { - if (i < n - memlog_remove_batch_thres) { - if (strlen(namelist[i]->d_name) > len - 1) - continue; - strncpy(fname, namelist[i]->d_name, len - 1); - fpath[sizeof fpath - 1] = '\0'; - _D("remove log file %s", fpath); - ret = remove(fpath); - if (ret < 0) - _E("%s file cannot removed", fpath); - } - - free(namelist[i]); - } - free(namelist); - return RESOURCED_ERROR_NONE; -} - -void make_memps_log(enum mem_log memlog, pid_t pid, char *victim_name) -{ - time_t now; - struct tm cur_tm; - char new_log[BUF_MAX]; - static pid_t old_pid; - int oom_score_adj = 0, ret; - char *prefix; - - if (!memlog_enabled) - return; - - if (memlog < MEMLOG_MEMPS || memlog >= MEMLOG_MAX) - return; - - prefix = memlog_prefix[memlog]; - - if (old_pid == pid) - return; - - old_pid = pid; - - now = time(NULL); - - if (localtime_r(&now, &cur_tm) == NULL) { - _E("Fail to get localtime"); - return; - } - - snprintf(new_log, sizeof(new_log), - "%s/%s_%s_%d_%.4d%.2d%.2d%.2d%.2d%.2d", memlog_path, prefix, victim_name, - pid, (1900 + cur_tm.tm_year), 1 + cur_tm.tm_mon, - cur_tm.tm_mday, cur_tm.tm_hour, cur_tm.tm_min, - cur_tm.tm_sec); - - ret = proc_get_oom_score_adj(pid, &oom_score_adj); - if (ret || oom_score_adj > OOMADJ_BACKGRD_LOCKED) { - - _cleanup_fclose_ FILE *f = NULL; - - f = fopen(new_log, "w"); - if (!f) { - _E("fail to create memps log %s", new_log); - return; - } - proc_print_meninfo(f); - - } else { - - const char *argv[4] = {"/usr/bin/memps", "-f", NULL, NULL}; - - argv[2] = new_log; - exec_cmd(ARRAY_SIZE(argv), argv); - } - - /* best effort to limit the number of logfiles up to memlog_nr_max */ - clear_logs(memlog_path); -} - -static int lowmem_kill_victim(const struct task_info *tsk, - int flags, int memps_log, unsigned int *victim_size) -{ - pid_t pid; - int ret; - char appname[PATH_MAX]; - int sigterm = 0; - struct proc_app_info *pai; - - pid = tsk->pid; - - if (pid <= 0 || pid == getpid()) - return RESOURCED_ERROR_FAIL; - - ret = proc_get_cmdline(pid, appname, sizeof appname); - if (ret == RESOURCED_ERROR_FAIL) - return RESOURCED_ERROR_FAIL; - - if (!strcmp("memps", appname) || - !strcmp("crash-worker", appname) || - !strcmp("system-syspopup", appname)) { - _E("%s(%d) was selected, skip it", appname, pid); - return RESOURCED_ERROR_FAIL; - } - - if (!memps_log) - make_memps_log(MEMLOG_MEMPS, pid, appname); - - pai = tsk->pai; - if (pai) { - resourced_proc_status_change(PROC_CGROUP_SET_TERMINATE_REQUEST, - pid, NULL, NULL, PROC_TYPE_NONE); - - if (tsk->oom_score_lru <= OOMADJ_BACKGRD_LOCKED) { - sigterm = 1; - } else if (tsk->oom_score_lru > OOMADJ_BACKGRD_LOCKED && tsk->oom_score_lru < OOMADJ_BACKGRD_UNLOCKED) { - int app_flag = pai->flags; - sigterm = app_flag & PROC_SIGTERM; - } - - if (pai->memory.oom_killed) - sigterm = 0; - - pai->memory.oom_killed = true; - } - - if (sigterm) - safe_kill(pid, SIGTERM); - else - safe_kill(pid, SIGKILL); - - _D("[LMK] we killed, force(%d), %d (%s) score = %d, size: rss = %u, sigterm = %d\n", - flags & OOM_FORCE, pid, appname, tsk->oom_score_adj, - tsk->size, sigterm); - *victim_size = tsk->size; - - if (tsk->oom_score_lru > OOMADJ_FOREGRD_UNLOCKED) - return RESOURCED_ERROR_NONE; - - if (oom_popup_enable && !oom_popup) { - lowmem_launch_oompopup(); - oom_popup = true; - } - if (memps_log) - make_memps_log(MEMLOG_MEMPS, pid, appname); - - return RESOURCED_ERROR_NONE; -} - -/* return LOWMEM_RECLAIM_CONT when killing should be continued */ -static int lowmem_check_kill_continued(struct task_info *tsk, int flags) -{ - unsigned int available; - - /* - * Processes with the priority higher than perceptible are killed - * only when the available memory is less than dynamic oom threshold. - */ - if (tsk->oom_score_lru > OOMADJ_BACKGRD_PERCEPTIBLE) - return LOWMEM_RECLAIM_CONT; - - if (flags & (OOM_FORCE|OOM_SINGLE_SHOT)) { - _I("[LMK] %d is dropped during force kill, flag=%d", - tsk->pid, flags); - return LOWMEM_RECLAIM_DROP; - } - available = proc_get_mem_available(); - if (available > lmk_start_threshold) { - _I("[LMK] available=%d MB, larger than %u MB, do not kill foreground", - available, lmk_start_threshold); - return LOWMEM_RECLAIM_RETRY; - } - return LOWMEM_RECLAIM_CONT; -} - -static int compare_victims(const struct task_info *ta, const struct task_info *tb) -{ - unsigned int pa, pb; - - assert(ta != NULL); - assert(tb != NULL); - /* - * followed by kernel badness point calculation using heuristic. - * oom_score_adj is normalized by its unit, which varies -1000 ~ 1000. - */ - pa = ta->oom_score_lru * (ktotalram / 2000) + ta->size; - pb = tb->oom_score_lru * (ktotalram / 2000) + tb->size; - - return pb - pa; -} - -static void lowmem_free_task_info_array(GArray *array) -{ - int i; - - for (i = 0; i < array->len; i++) { - struct task_info *tsk; - - tsk = &g_array_index(array, struct task_info, i); - if (tsk->pids) - g_array_free(tsk->pids, true); - } - - g_array_free(array, true); -} - -static inline int is_dynamic_process_killer(int flags) -{ - return (flags & OOM_FORCE) && !(flags & OOM_NOMEMORY_CHECK); -} - -static unsigned int is_memory_recovered(unsigned int *avail, unsigned int thres) -{ - unsigned int available = proc_get_mem_available(); - unsigned int should_be_freed = 0; - - if (available < thres) - should_be_freed = thres - available; - /* - * free THRESHOLD_MARGIN more than real should be freed, - * because launching app is consuming up the memory. - */ - if (should_be_freed > 0) - should_be_freed += THRESHOLD_MARGIN; - - *avail = available; - - return should_be_freed; -} - -static int lowmem_get_pids_proc(GArray *pids) -{ - DIR *dp; - struct dirent *dentry; - - dp = opendir("/proc"); - if (!dp) { - _E("fail to open /proc"); - return RESOURCED_ERROR_FAIL; - } - while ((dentry = readdir(dp)) != NULL) { - struct task_info tsk; - pid_t pid = 0, pgid = 0; - int oom = 0; - - if (!isdigit(dentry->d_name[0])) - continue; - - pid = (pid_t)atoi(dentry->d_name); - if (pid < 1) - /* skip invalid pids or kernel processes */ - continue; - - pgid = getpgid(pid); - if (pgid < 1) - continue; - - if(is_app(pid) != 1) - continue; - - if (proc_get_oom_score_adj(pid, &oom) < 0) { - _D("pid(%d) was already terminated", pid); - continue; - } - - /* VIP pids should be excluded from the LMK list */ - if (cgroup_get_type(oom) == CGROUP_VIP) - continue; - - /* - * Check whether this array includes applications or not. - * If it doesn't require to get applications - * and pid has been already included in pai, - * skip to append. - */ - if (oom > OOMADJ_SU && oom <= OOMADJ_APP_MAX) - continue; - - /* - * Currently, for tasks in the memory cgroup, - * do not consider multiple tasks with one pgid. - */ - tsk.pid = pid; - tsk.pgid = pgid; - tsk.oom_score_adj = oom; - tsk.oom_score_lru = oom; - tsk.pids = NULL; - tsk.size = lowmem_get_task_mem_usage_rss(&tsk); - tsk.pai = NULL; - - g_array_append_val(pids, tsk); - } - - closedir(dp); - return RESOURCED_ERROR_NONE; -} - -/** - * @brief Terminate up to max_victims processes after finding them from pai. - It depends on proc_app_info lists - and it also reference systemservice cgroup - because some processes in this group don't have proc_app_info. - * - * @max_victims: max number of processes to be terminated - * @start_oom: find victims from start oom adj score value - * @end_oom: find victims to end oom adj score value - * @should_be_freed: amount of memory to be reclaimed (in MB) - * @total_size[out]: total size of possibly reclaimed memory (required) - * @completed: final outcome (optional) - * @threshold: desired value of memory available - */ -static int lowmem_kill_victims(int max_victims, - int start_oom, int end_oom, unsigned should_be_freed, int flags, - unsigned int *total_size, int *completed, int threshold) -{ - int total_count = 0; - GSList *proc_app_list = NULL; - int i, ret, victim = 0; - unsigned int victim_size = 0; - unsigned int total_victim_size = 0; - int status = LOWMEM_RECLAIM_NONE; - GArray *candidates = NULL; - GSList *iter, *iterchild; - struct proc_app_info *pai = NULL; - int oom_score_adj; - int should_be_freed_kb = MBYTE_TO_KBYTE(should_be_freed); - - candidates = g_array_new(false, false, sizeof(struct task_info)); - - proc_app_list = proc_app_list_open(); - gslist_for_each_item(iter, proc_app_list) { - struct task_info ti; - - total_count++; - pai = (struct proc_app_info *)iter->data; - if (!pai->main_pid) - continue; - - oom_score_adj = pai->memory.oom_score_adj; - if (oom_score_adj > end_oom || oom_score_adj < start_oom) - continue; - - if ((flags & OOM_REVISE) && pai->memory.oom_killed) - continue; - - ti.pid = pai->main_pid; - ti.pgid = getpgid(ti.pid); - ti.oom_score_adj = oom_score_adj; - ti.pai = pai; - - /* - * Before oom_score_adj of favourite (oom_score = 270) applications is - * independent of lru_state, now we consider lru_state, while - * killing favourite process. - */ - - if (oom_score_adj == OOMADJ_FAVORITE && pai->lru_state >= PROC_BACKGROUND) - ti.oom_score_lru = OOMADJ_FAVORITE + OOMADJ_FAVORITE_APP_INCREASE * pai->lru_state; - else - ti.oom_score_lru = oom_score_adj; - - if (pai->childs) { - ti.pids = g_array_new(false, false, sizeof(pid_t)); - g_array_append_val(ti.pids, ti.pid); - gslist_for_each_item(iterchild, pai->childs) { - pid_t child = GPOINTER_TO_PID(iterchild->data); - g_array_append_val(ti.pids, child); - } - } else - ti.pids = NULL; - - g_array_append_val(candidates, ti); - } - - proc_app_list_close(); - - if (!candidates->len) { - status = LOWMEM_RECLAIM_NEXT_TYPE; - goto leave; - } - else { - _D("[LMK] candidate ratio=%d/%d", candidates->len, total_count); - } - - for (i = 0; i < candidates->len; i++) { - struct task_info *tsk; - - tsk = &g_array_index(candidates, struct task_info, i); - tsk->size = lowmem_get_task_mem_usage_rss(tsk); - } - - /* - * In case of start_oom == OOMADJ_SU, - * we're going to try to kill some of processes in /proc - * to handle low memory situation. - * It can find malicious system process even though it has low oom score. - */ - if (start_oom == OOMADJ_SU) - lowmem_get_pids_proc(candidates); - - g_array_sort(candidates, (GCompareFunc)compare_victims); - - for (i = 0; i < candidates->len; i++) { - struct task_info *tsk; - - if (i >= max_victims) { - status = LOWMEM_RECLAIM_NEXT_TYPE; - break; - } - - /* - * Available memory is checking only every - * num_vict_between_check process for reducing burden. - */ - if (!(i % num_vict_between_check)) { - if (proc_get_mem_available() > threshold) { - status = LOWMEM_RECLAIM_DONE; - break; - } - } - - if (!(flags & OOM_NOMEMORY_CHECK) && - total_victim_size >= should_be_freed_kb) { - _D("[LMK] victim=%d, max_victims=%d, total_size=%uKB", - victim, max_victims, total_victim_size); - status = LOWMEM_RECLAIM_DONE; - break; - } - - tsk = &g_array_index(candidates, struct task_info, i); - - status = lowmem_check_kill_continued(tsk, flags); - if (status != LOWMEM_RECLAIM_CONT) - break; - - _I("[LMK] select victims from proc_app_list pid(%d) with oom_score_adj(%d)\n", tsk->pid, tsk->oom_score_adj); - - ret = lowmem_kill_victim(tsk, flags, i, &victim_size); - if (ret != RESOURCED_ERROR_NONE) - continue; - victim++; - total_victim_size += victim_size; - } - -leave: - lowmem_free_task_info_array(candidates); - *total_size = total_victim_size; - if(*completed != LOWMEM_RECLAIM_CONT) - *completed = status; - else - *completed = LOWMEM_RECLAIM_NEXT_TYPE; - return victim; -} - -static int calculate_range_of_oom(enum cgroup_type type, int *min, int *max) -{ - if (type == CGROUP_VIP || type >= CGROUP_END || type <= CGROUP_TOP) { - _E("cgroup type (%d) is out of scope", type); - return RESOURCED_ERROR_FAIL; - } - - *max = cgroup_get_highest_oom_score_adj(type); - *min = cgroup_get_lowest_oom_score_adj(type); - - return RESOURCED_ERROR_NONE; -} - -static void lowmem_handle_request(struct lowmem_control *ctl) -{ - int start_oom, end_oom; - int count = 0, victim_cnt = 0; - int max_victim_cnt = ctl->count; - int status = LOWMEM_RECLAIM_NONE; - unsigned int available = 0; - unsigned int total_size = 0; - unsigned int current_size = 0; - unsigned int reclaim_size, shortfall = 0; - enum cgroup_type cgroup_type = ctl->type; - - available = proc_get_mem_available(); - reclaim_size = ctl->size > available - ? ctl->size - available : 0; - - if (!reclaim_size) { - status = LOWMEM_RECLAIM_DONE; - goto done; - } - -retry: - /* Prepare LMK to start doing it's job. Check preconditions. */ - if (calculate_range_of_oom(cgroup_type, &start_oom, &end_oom)) - goto done; - - lmk_start_threshold = get_root_memcg_info()->threshold[MEM_LEVEL_OOM]; - shortfall = is_memory_recovered(&available, ctl->size); - - if (!shortfall || !reclaim_size) { - status = LOWMEM_RECLAIM_DONE; - goto done; - } - - /* precaution */ - current_size = 0; - victim_cnt = lowmem_kill_victims(max_victim_cnt, start_oom, end_oom, - reclaim_size, ctl->flags, ¤t_size, &status, ctl->size); - - if (victim_cnt) { - current_size = KBYTE_TO_MBYTE(current_size); - reclaim_size -= reclaim_size > current_size - ? current_size : reclaim_size; - total_size += current_size; - count += victim_cnt; - _I("[LMK] current: kill %d victims, reclaim_size=%uMB from %d to %d status=%s", - victim_cnt, current_size, - start_oom, end_oom, convert_status_to_str(status)); - } - - if ((status == LOWMEM_RECLAIM_DONE) || - (status == LOWMEM_RECLAIM_DROP) || - (status == LOWMEM_RECLAIM_RETRY)) - goto done; - - /* - * If it doesn't finish reclaiming memory in first operation, - - if flags has OOM_IN_DEPTH, - try to find victims again in the active cgroup. - otherwise, just return because there is no more victims in the desired cgroup. - - if flags has OOM_REVISE, - it means that resourced can't find victims from proc_app_list. - So, it should search victims or malicious process from /proc. - But searching /proc leads to abnormal behaviour. - (Make sluggish or kill same victims continuously) - Thus, otherwise, just return in first operation and wait some period. - */ - if (cgroup_type == CGROUP_LOW) { - cgroup_type = CGROUP_MEDIUM; - goto retry; - } else if ((cgroup_type == CGROUP_MEDIUM) && (ctl->flags & OOM_IN_DEPTH)) { - cgroup_type = CGROUP_HIGH; - if(ctl->flags & OOM_FORCE) - max_victim_cnt = FOREGROUND_VICTIMS; - goto retry; - } else if ((cgroup_type == CGROUP_HIGH) && (ctl->flags & OOM_IN_DEPTH)) { - status = LOWMEM_RECLAIM_RETRY; - ctl->type = CGROUP_ROOT; - } - else if (cgroup_type == CGROUP_ROOT) { - status = LOWMEM_RECLAIM_RETRY; - } -done: - _I("[LMK] Done: killed %d processes reclaimed=%uMB remaining=%uMB shortfall=%uMB status=%s", - count, total_size, reclaim_size, shortfall, convert_status_to_str(status)); - - /* After we finish reclaiming it's worth to remove oldest memps logs */ - if (count && memlog_enabled) - request_helper_worker(CLEAR_LOGS, memlog_path, clear_logs, NULL); - ctl->status = status; -} - -static void *lowmem_reclaim_worker(void *arg) -{ - struct lowmem_worker *lmw = (struct lowmem_worker *)arg; - - setpriority(PRIO_PROCESS, 0, OOM_KILLER_PRIORITY); - - g_async_queue_ref(lmw->queue); - - while (1) { - int try_count = 0; - struct lowmem_control *ctl; - - LOWMEM_WORKER_IDLE(lmw); - /* Wait on any wake-up call */ - ctl = g_async_queue_pop(lmw->queue); - - if (ctl->flags & OOM_DROP) - LOWMEM_DESTROY_REQUEST(ctl); - - if (!LOWMEM_WORKER_IS_ACTIVE(lmw) || !ctl) - break; - - LOWMEM_WORKER_RUN(lmw); -process_again: - _D("[LMK] %d tries", ++try_count); - lowmem_handle_request(ctl); - /** - * Case the process failed to reclaim requested amount of memory - * or still under have memory pressure - try the timeout wait. - * There is a chance this will get woken-up in a better reality. - */ - if (ctl->status == LOWMEM_RECLAIM_RETRY && - !(ctl->flags & OOM_SINGLE_SHOT)) { - unsigned int available = proc_get_mem_available(); - - if (available >= ctl->size) { - _I("[LMK] Memory restored: requested=%uMB available=%uMB\n", - ctl->size, available); - ctl->status = LOWMEM_RECLAIM_DONE; - if (ctl->callback) - ctl->callback(ctl); - LOWMEM_DESTROY_REQUEST(ctl); - LOWMEM_WORKER_IDLE(lmw); - continue; - } - - if (LOWMEM_WORKER_IS_ACTIVE(lmw)) { - g_usleep(LMW_RETRY_WAIT_TIMEOUT_MSEC); - ctl->flags |= OOM_REVISE; - goto process_again; - } - } - - /* - * The ctl callback would check available size again. - * And it is last point in reclaiming worker. - * Resourced sent SIGKILL signal to victim processes - * so it should wait for a some seconds until each processes returns memory. - */ - g_usleep(LMW_LOOP_WAIT_TIMEOUT_MSEC); - if (ctl->callback) - ctl->callback(ctl); - - /* The lmk becomes the owner of all queued requests .. */ - LOWMEM_DESTROY_REQUEST(ctl); - LOWMEM_WORKER_IDLE(lmw); - } - g_async_queue_unref(lmw->queue); - pthread_exit(NULL); -} - -static void change_lowmem_state(unsigned int mem_state) -{ - cur_mem_state = mem_state; - lmk_start_threshold = get_root_memcg_info()->threshold[MEM_LEVEL_OOM]; - - resourced_notify(RESOURCED_NOTIFIER_MEM_LEVEL_CHANGED, - (void *)&cur_mem_state); -} - -/* only app can call this function - * that is, service cannot call the function - */ -static void lowmem_swap_memory(char *path) -{ - unsigned int available; - - if (cur_mem_state == MEM_LEVEL_HIGH) - return; - - if (swap_get_state() != SWAP_ON) - return; - - available = proc_get_mem_available(); - if (cur_mem_state != MEM_LEVEL_LOW && - available <= get_root_memcg_info()->threshold[MEM_LEVEL_LOW]) - swap_activate_act(); - - resourced_notify(RESOURCED_NOTIFIER_SWAP_START, path); - memcg_swap_status = true; -} - -void lowmem_trigger_swap(pid_t pid, char *path, bool move) -{ - int error; - int oom_score_adj; - int lowest_oom_score_adj; - - if (!path) { - _E("[SWAP] Unknown memory cgroup path to swap"); - return; - } - - /* In this case, corresponding process will be moved to memory CGROUP_LOW. - */ - if (move) { - error = proc_get_oom_score_adj(pid, &oom_score_adj); - if (error) { - _E("[SWAP] Cannot get oom_score_adj of pid (%d)", pid); - return; - } - - lowest_oom_score_adj = cgroup_get_lowest_oom_score_adj(CGROUP_LOW); - - if (oom_score_adj < lowest_oom_score_adj) { - oom_score_adj = lowest_oom_score_adj; - /* End of this funciton, 'lowmem_swap_memory()' funciton will be called */ - proc_set_oom_score_adj(pid, oom_score_adj, find_app_info(pid)); - return; - } - } - - /* Correponding process is already managed per app or service. - * In addition, if some process is already located in the CGROUP_LOW, then just do swap - */ - resourced_notify(RESOURCED_NOTIFIER_SWAP_START, path); -} - -static void memory_level_send_system_event(int lv) -{ - bundle *b; - const char *str; - - switch (lv) { - case MEM_LEVEL_HIGH: - case MEM_LEVEL_MEDIUM: - case MEM_LEVEL_LOW: - str = EVT_VAL_MEMORY_NORMAL; - break; - case MEM_LEVEL_CRITICAL: - str = EVT_VAL_MEMORY_SOFT_WARNING; - break; - case MEM_LEVEL_OOM: - str = EVT_VAL_MEMORY_HARD_WARNING; - break; - default: - _E("Invalid state"); - return; - } - - b = bundle_create(); - if (!b) { - _E("Failed to create bundle"); - return; - } - - bundle_add_str(b, EVT_KEY_LOW_MEMORY, str); - eventsystem_send_system_event(SYS_EVENT_LOW_MEMORY, b); - bundle_free(b); -} - -static void high_mem_act(void) -{ - int ret, status; - - ret = vconf_get_int(VCONFKEY_SYSMAN_LOW_MEMORY, &status); - if (ret) - _D("vconf_get_int fail %s", VCONFKEY_SYSMAN_LOW_MEMORY); - if (status != VCONFKEY_SYSMAN_LOW_MEMORY_NORMAL) { - vconf_set_int(VCONFKEY_SYSMAN_LOW_MEMORY, - VCONFKEY_SYSMAN_LOW_MEMORY_NORMAL); - memory_level_send_system_event(MEM_LEVEL_HIGH); - } - - change_lowmem_state(MEM_LEVEL_HIGH); - - if (swap_get_state() == SWAP_ON && memcg_swap_status) { - resourced_notify(RESOURCED_NOTIFIER_SWAP_UNSET_LIMIT, get_memcg_info(CGROUP_LOW)); - memcg_swap_status = false; - } - if (proc_get_freezer_status() == CGROUP_FREEZER_PAUSED) - resourced_notify(RESOURCED_NOTIFIER_FREEZER_CGROUP_STATE, - (void *)CGROUP_FREEZER_ENABLED); -} - -static void swap_activate_act(void) -{ - int ret, status; - - ret = vconf_get_int(VCONFKEY_SYSMAN_LOW_MEMORY, &status); - if (ret) - _E("vconf get failed %s", VCONFKEY_SYSMAN_LOW_MEMORY); - - if (status != VCONFKEY_SYSMAN_LOW_MEMORY_NORMAL) { - vconf_set_int(VCONFKEY_SYSMAN_LOW_MEMORY, - VCONFKEY_SYSMAN_LOW_MEMORY_NORMAL); - memory_level_send_system_event(MEM_LEVEL_LOW); - } - change_lowmem_state(MEM_LEVEL_LOW); - if (proc_get_freezer_status() == CGROUP_FREEZER_PAUSED) - resourced_notify(RESOURCED_NOTIFIER_FREEZER_CGROUP_STATE, - (void *)CGROUP_FREEZER_ENABLED); - - if (swap_get_state() != SWAP_ON) - resourced_notify(RESOURCED_NOTIFIER_SWAP_ACTIVATE, NULL); -} - -static void dedup_act(enum ksm_scan_mode mode) -{ - int ret, status; - int data; - - if (dedup_get_state() != DEDUP_ONE_SHOT) - return; - - if (proc_get_freezer_status() == CGROUP_FREEZER_PAUSED) - resourced_notify(RESOURCED_NOTIFIER_FREEZER_CGROUP_STATE, - (void *)CGROUP_FREEZER_ENABLED); - - if (mode == KSM_SCAN_PARTIAL) { - ret = vconf_get_int(VCONFKEY_SYSMAN_LOW_MEMORY, &status); - if (ret) - _E("vconf get failed %s", VCONFKEY_SYSMAN_LOW_MEMORY); - - if (status != VCONFKEY_SYSMAN_LOW_MEMORY_NORMAL) { - vconf_set_int(VCONFKEY_SYSMAN_LOW_MEMORY, - VCONFKEY_SYSMAN_LOW_MEMORY_NORMAL); - memory_level_send_system_event(MEM_LEVEL_MEDIUM); - } - change_lowmem_state(MEM_LEVEL_MEDIUM); - - data = KSM_SCAN_PARTIAL; - resourced_notify(RESOURCED_NOTIFIER_DEDUP_SCAN, &data); - } else if (mode == KSM_SCAN_FULL) { - data = KSM_SCAN_FULL; - resourced_notify(RESOURCED_NOTIFIER_DEDUP_SCAN, &data); - } -} - -static void swap_compact_act(void) -{ - change_lowmem_state(MEM_LEVEL_CRITICAL); - resourced_notify(RESOURCED_NOTIFIER_SWAP_COMPACT, (void *)SWAP_COMPACT_MEM_LEVEL_CRITICAL); - memory_level_send_system_event(MEM_LEVEL_CRITICAL); -} - -static void medium_cb(struct lowmem_control *ctl) -{ - if (ctl->status == LOWMEM_RECLAIM_DONE) - oom_popup = false; - lowmem_change_memory_state(MEM_LEVEL_HIGH, 0); -} - -static void lmk_act(void) -{ - unsigned int available; - int ret; - int status = VCONFKEY_SYSMAN_LOW_MEMORY_NORMAL; - - /* - * Don't trigger reclaim worker - * if it is already running - */ - if (LOWMEM_WORKER_IS_RUNNING(&lmw)) - return; - - ret = vconf_get_int(VCONFKEY_SYSMAN_LOW_MEMORY, &status); - if (ret) - _D("vconf_get_int fail %s", VCONFKEY_SYSMAN_LOW_MEMORY); - - memory_level_send_system_event(MEM_LEVEL_OOM); - if (status != VCONFKEY_SYSMAN_LOW_MEMORY_HARD_WARNING) { - if (proc_get_freezer_status() == CGROUP_FREEZER_ENABLED) - resourced_notify(RESOURCED_NOTIFIER_FREEZER_CGROUP_STATE, - (void *)CGROUP_FREEZER_PAUSED); - vconf_set_int(VCONFKEY_SYSMAN_LOW_MEMORY, - VCONFKEY_SYSMAN_LOW_MEMORY_HARD_WARNING); - } - available = proc_get_mem_available(); - - change_lowmem_state(MEM_LEVEL_OOM); - - if (available < get_root_memcg_info()->threshold_leave) { - struct lowmem_control *ctl; - - ctl = LOWMEM_NEW_REQUEST(); - if (ctl) { - LOWMEM_SET_REQUEST(ctl, OOM_IN_DEPTH, - CGROUP_LOW, get_root_memcg_info()->threshold_leave, - num_max_victims, medium_cb); - lowmem_queue_request(&lmw, ctl); - } - } - - resourced_notify(RESOURCED_NOTIFIER_SWAP_COMPACT, (void *)SWAP_COMPACT_MEM_LEVEL_OOM); - - /* - * Flush resourced memory such as other processes. - * Resourced can use both many fast bins and sqlite3 cache memery. - */ - malloc_trim(0); - - return; -} - -static void lowmem_trigger_memory_state_action(int mem_state) -{ - /* - * Check if the state we want to set is different from current - * But it should except this condition if mem_state is already medium. - * Otherwise, recalim worker couldn't run any more. - */ - if (mem_state != MEM_LEVEL_OOM && cur_mem_state == mem_state) - return; - - switch (mem_state) { - case MEM_LEVEL_HIGH: - high_mem_act(); - break; - case MEM_LEVEL_MEDIUM: - dedup_act(KSM_SCAN_PARTIAL); - break; - case MEM_LEVEL_LOW: - swap_activate_act(); - break; - case MEM_LEVEL_CRITICAL: - dedup_act(KSM_SCAN_FULL); - swap_compact_act(); - break; - case MEM_LEVEL_OOM: - lmk_act(); - break; - default: - assert(0); - } -} - -static void lowmem_dump_cgroup_procs(struct memcg_info *mi) -{ - int i; - unsigned int size; - pid_t pid; - GArray *pids_array = NULL; - - cgroup_get_pids(mi->name, &pids_array); - - for (i = 0; i < pids_array->len; i++) { - pid = g_array_index(pids_array, pid_t, i); - lowmem_mem_usage_uss(pid, &size); - _I("pid = %d, size = %u KB", pid, size); - } - g_array_free(pids_array, true); -} - -static void memory_cgroup_proactive_lmk_act(enum cgroup_type type, struct memcg_info *mi) -{ - struct lowmem_control *ctl; - - /* To Do: only start to kill fg victim when no pending fg victim */ - lowmem_dump_cgroup_procs(mi); - - ctl = LOWMEM_NEW_REQUEST(); - if (ctl) { - LOWMEM_SET_REQUEST(ctl, OOM_SINGLE_SHOT | OOM_IN_DEPTH, type, - mi->oomleave, num_max_victims, NULL); - lowmem_queue_request(&lmw, ctl); - } -} - -static unsigned int check_mem_state(unsigned int available) -{ - int mem_state; - for (mem_state = MEM_LEVEL_MAX - 1; mem_state > MEM_LEVEL_HIGH; mem_state--) { - if (mem_state != MEM_LEVEL_OOM && available <= get_root_memcg_info()->threshold[mem_state]) - break; - else if (mem_state == MEM_LEVEL_OOM && available <= lmk_start_threshold) - break; - } - - return mem_state; -} - -/*static int load_bg_reclaim_config(struct parse_result *result, void *user_data) -{ - if (!result) - return RESOURCED_ERROR_INVALID_PARAMETER; - - if (strncmp(result->section, MEM_BG_RECLAIM_SECTION, strlen(MEM_BG_RECLAIM_SECTION)+1)) - return RESOURCED_ERROR_NONE; - - if (!strncmp(result->name, MEM_BG_RECLAIM_STRING, strlen(MEM_BG_RECLAIM_STRING)+1)) { - if (!strncmp(result->value, "yes", strlen("yes")+1)) - bg_reclaim = true; - else if (!strncmp(result->value, "no", strlen("no")+1)) - bg_reclaim = false; - } - - - return RESOURCED_ERROR_NONE; -} - -static int load_popup_config(struct parse_result *result, void *user_data) -{ - if (!result) - return RESOURCED_ERROR_INVALID_PARAMETER; - - if (strncmp(result->section, MEM_POPUP_SECTION, strlen(MEM_POPUP_SECTION)+1)) - return RESOURCED_ERROR_NONE; - - if (!strncmp(result->name, MEM_POPUP_STRING, strlen(MEM_POPUP_STRING)+1)) { - if (!strncmp(result->value, "yes", strlen("yes")+1)) - oom_popup_enable = true; - else if (!strncmp(result->value, "no", strlen("no")+1)) - oom_popup_enable = false; - } - - - return RESOURCED_ERROR_NONE; -} - -static int load_mem_log_config(struct parse_result *result, void *user_data) -{ - if (!result) - return RESOURCED_ERROR_INVALID_PARAMETER; - - if (strncmp(result->section, MEM_LOGGING_SECTION, strlen(MEM_LOGGING_SECTION)+1)) - return RESOURCED_ERROR_NONE; - - if (!strncmp(result->name, "Enable", strlen("Enable")+1)) { - memlog_enabled = atoi(result->value); - } else if (!strncmp(result->name, "LogPath", strlen("LogPath")+1)) { - memlog_path = strdup(result->value); - } else if (!strncmp(result->name, "MaxNumLogfile", strlen("MaxNumLogfile")+1)) { - memlog_nr_max = atoi(result->value); - memlog_remove_batch_thres = (memlog_nr_max * 5) / 6; - } else if (!strncmp(result->name, "PrefixMemps", strlen("PrefixMemps")+1)) { - memlog_prefix[MEMLOG_MEMPS] = strdup(result->value); - } else if (!strncmp(result->name, "PrefixMempsMemLimit", strlen("PrefixMempsMemLimit")+1)) { - memlog_prefix[MEMLOG_MEMPS_MEMLIMIT] = strdup(result->value); - } - - return RESOURCED_ERROR_NONE; -} - -static int set_memory_config(struct parse_result *result, void *user_data) -{ - if (!result) - return RESOURCED_ERROR_NONE; - - if (strncmp(result->section, MEM_SECTION, strlen(MEM_SECTION)+1)) - return RESOURCED_ERROR_NONE; - - if (!strncmp(result->name, "ThresholdDedup", strlen("ThresholdDedup")+1)) { - int value = atoi(result->value); - memcg_set_threshold(CGROUP_ROOT, MEM_LEVEL_MEDIUM, value); - } else if (!strncmp(result->name, "ThresholdSwap", strlen("ThresholdSwap")+1)) { - int value = atoi(result->value); - memcg_set_threshold(CGROUP_ROOT, MEM_LEVEL_LOW, value); - } else if (!strncmp(result->name, "ThresholdLow", strlen("ThresholdLow")+1)) { - int value = atoi(result->value); - memcg_set_threshold(CGROUP_ROOT, MEM_LEVEL_CRITICAL, value); - } else if (!strncmp(result->name, "ThresholdMedium", strlen("ThresholdMedium")+1)) { - int value = atoi(result->value); - memcg_set_threshold(CGROUP_ROOT, MEM_LEVEL_OOM, value); - } else if (!strncmp(result->name, "ThresholdLeave", strlen("ThresholdLeave")+1)) { - int value = atoi(result->value); - memcg_set_leave_threshold(CGROUP_ROOT, value); - } else if (!strncmp(result->name, "ThresholdRatioDedup", strlen("ThresholdRatioDedup")+1)) { - double ratio = atoi(result->value); - int value = (double)totalram * ratio / 100.0; - memcg_set_threshold(CGROUP_ROOT, MEM_LEVEL_MEDIUM, BYTE_TO_MBYTE(value)); - } else if (!strncmp(result->name, "ThresholdRatioSwap", strlen("ThresholdRatioSwap")+1)) { - double ratio = atoi(result->value); - int value = (double)totalram * ratio / 100.0; - memcg_set_threshold(CGROUP_ROOT, MEM_LEVEL_LOW, BYTE_TO_MBYTE(value)); - } else if (!strncmp(result->name, "ThresholdRatioLow", strlen("ThresholdRatioLow")+1)) { - double ratio = atoi(result->value); - int value = (double)totalram * ratio / 100.0; - memcg_set_threshold(CGROUP_ROOT, MEM_LEVEL_CRITICAL, BYTE_TO_MBYTE(value)); - } else if (!strncmp(result->name, "ThresholdRatioMedium", strlen("ThresholdRatioMedium")+1)) { - double ratio = atoi(result->value); - int value = (double)totalram * ratio / 100.0; - memcg_set_threshold(CGROUP_ROOT, MEM_LEVEL_OOM, BYTE_TO_MBYTE(value)); - } else if (!strncmp(result->name, "ThresholdRatioLeave", strlen("ThresholdRatioLeave")+1)) { - double ratio = atoi(result->value); - int value = (double)totalram * ratio / 100.0; - memcg_set_leave_threshold(CGROUP_ROOT, BYTE_TO_MBYTE(value)); - } else if (!strncmp(result->name, "ForegroundRatio", strlen("ForegroundRatio")+1)) { - float ratio = atof(result->value); - memcg_info_set_limit(get_memcg_info(CGROUP_HIGH), ratio, totalram); - } else if (!strncmp(result->name, "BackgroundRatio", strlen("BackgroundRatio")+1)) { - float ratio = atof(result->value); - memcg_info_set_limit(get_memcg_info(CGROUP_MEDIUM), ratio, totalram); - } else if (!strncmp(result->name, "LowRatio", strlen("LowRatio")+1)) { - float ratio = atof(result->value); - memcg_info_set_limit(get_memcg_info(CGROUP_LOW), ratio, totalram); - } else if (!strncmp(result->name, "NumMaxVictims", strlen("NumMaxVictims")+1)) { - int value = atoi(result->value); - num_max_victims = value; - num_vict_between_check = value > MAX_MEMORY_CGROUP_VICTIMS/2 - ? 3 : value > MAX_MEMORY_CGROUP_VICTIMS/4 - ? 2 : 1; - } else if (!strncmp(result->name, "ProactiveThreshold", strlen("ProactiveThreshold")+1)) { - int value = atoi(result->value); - proactive_threshold = value; - } else if (!strncmp(result->name, "ProactiveLeave", strlen("ProactiveLeave")+1)) { - int value = atoi(result->value); - proactive_leave = value; - } else if (!strncmp(result->name, "EventLevel", strlen("EventLevel")+1)) { - if (strncmp(event_level, result->value, strlen(event_level))) - event_level = strdup(result->value); - if (!event_level) - return RESOURCED_ERROR_OUT_OF_MEMORY; - } else if (!strncmp(result->name, "SWAPPINESS", strlen("SWAPPINESS")+1)) { - int value = atoi(result->value); - memcg_set_default_swappiness(value); - memcg_info_set_swappiness(get_memcg_info(CGROUP_ROOT), value); - } else if (!strncmp(result->name, "FOREGROUND_SWAPPINESS", strlen("FOREGROUND_SWAPPINESS")+1)) { - int value = atoi(result->value); - memcg_info_set_swappiness(get_memcg_info(CGROUP_HIGH), value); - } else if (!strncmp(result->name, "BACKGROUND_SWAPPINESS", strlen("BACKGROUND_SWAPPINESS")+1)) { - int value = atoi(result->value); - memcg_info_set_swappiness(get_memcg_info(CGROUP_MEDIUM), value); - } else if (!strncmp(result->name, "LOW_SWAPPINESS", strlen("LOW_SWAPPINESS")+1)) { - int value = atoi(result->value); - memcg_info_set_swappiness(get_memcg_info(CGROUP_LOW), value); - } else if (!strncmp(result->name, "NumFragSize", strlen("NumFragSize")+1)) { - fragmentation_size = atoi(result->value); - } - - return RESOURCED_ERROR_NONE; -}*/ - -/* setup memcg parameters depending on total ram size. */ -static void setup_memcg_params(void) -{ - unsigned long long total_ramsize; - - get_total_memory(); - total_ramsize = BYTE_TO_MBYTE(totalram); - - _D("Total: %llu MB", total_ramsize); - if (total_ramsize <= MEM_SIZE_64) { - /* set thresholds for ram size 64M */ - proactive_threshold = PROACTIVE_64_THRES; - proactive_leave = PROACTIVE_64_LEAVE; - memcg_set_threshold(CGROUP_ROOT, MEM_LEVEL_MEDIUM, CGROUP_ROOT_64_THRES_DEDUP); - memcg_set_threshold(CGROUP_ROOT, MEM_LEVEL_LOW, CGROUP_ROOT_64_THRES_SWAP); - memcg_set_threshold(CGROUP_ROOT, MEM_LEVEL_CRITICAL, CGROUP_ROOT_64_THRES_LOW); - memcg_set_threshold(CGROUP_ROOT, MEM_LEVEL_OOM, CGROUP_ROOT_64_THRES_MEDIUM); - memcg_set_leave_threshold(CGROUP_ROOT, CGROUP_ROOT_64_THRES_LEAVE); - num_max_victims = CGROUP_ROOT_64_NUM_VICTIMS; - } else if (total_ramsize <= MEM_SIZE_256) { - /* set thresholds for ram size 256M */ - proactive_threshold = PROACTIVE_256_THRES; - proactive_leave = PROACTIVE_256_LEAVE; - memcg_set_threshold(CGROUP_ROOT, MEM_LEVEL_MEDIUM, CGROUP_ROOT_256_THRES_DEDUP); - memcg_set_threshold(CGROUP_ROOT, MEM_LEVEL_LOW, CGROUP_ROOT_256_THRES_SWAP); - memcg_set_threshold(CGROUP_ROOT, MEM_LEVEL_CRITICAL, CGROUP_ROOT_256_THRES_LOW); - memcg_set_threshold(CGROUP_ROOT, MEM_LEVEL_OOM, CGROUP_ROOT_256_THRES_MEDIUM); - memcg_set_leave_threshold(CGROUP_ROOT, CGROUP_ROOT_256_THRES_LEAVE); - num_max_victims = CGROUP_ROOT_256_NUM_VICTIMS; - } else if (total_ramsize <= MEM_SIZE_448) { - /* set thresholds for ram size 448M */ - proactive_threshold = PROACTIVE_448_THRES; - proactive_leave = PROACTIVE_448_LEAVE; - memcg_set_threshold(CGROUP_ROOT, MEM_LEVEL_MEDIUM, CGROUP_ROOT_448_THRES_DEDUP); - memcg_set_threshold(CGROUP_ROOT, MEM_LEVEL_LOW, CGROUP_ROOT_448_THRES_SWAP); - memcg_set_threshold(CGROUP_ROOT, MEM_LEVEL_CRITICAL, CGROUP_ROOT_448_THRES_LOW); - memcg_set_threshold(CGROUP_ROOT, MEM_LEVEL_OOM, CGROUP_ROOT_448_THRES_MEDIUM); - memcg_set_leave_threshold(CGROUP_ROOT, CGROUP_ROOT_448_THRES_LEAVE); - num_max_victims = CGROUP_ROOT_448_NUM_VICTIMS; - } else if (total_ramsize <= MEM_SIZE_512) { - /* set thresholds for ram size 512M */ - proactive_threshold = PROACTIVE_512_THRES; - proactive_leave = PROACTIVE_512_LEAVE; - memcg_set_threshold(CGROUP_ROOT, MEM_LEVEL_MEDIUM, CGROUP_ROOT_512_THRES_DEDUP); - memcg_set_threshold(CGROUP_ROOT, MEM_LEVEL_LOW, CGROUP_ROOT_512_THRES_SWAP); - memcg_set_threshold(CGROUP_ROOT, MEM_LEVEL_CRITICAL, CGROUP_ROOT_512_THRES_LOW); - memcg_set_threshold(CGROUP_ROOT, MEM_LEVEL_OOM, CGROUP_ROOT_512_THRES_MEDIUM); - memcg_set_leave_threshold(CGROUP_ROOT, CGROUP_ROOT_512_THRES_LEAVE); - num_max_victims = CGROUP_ROOT_512_NUM_VICTIMS; - } else if (total_ramsize <= MEM_SIZE_768) { - /* set thresholds for ram size 512M */ - proactive_threshold = PROACTIVE_768_THRES; - proactive_leave = PROACTIVE_768_LEAVE; - memcg_set_threshold(CGROUP_ROOT, MEM_LEVEL_MEDIUM, CGROUP_ROOT_768_THRES_DEDUP); - memcg_set_threshold(CGROUP_ROOT, MEM_LEVEL_LOW, CGROUP_ROOT_768_THRES_SWAP); - memcg_set_threshold(CGROUP_ROOT, MEM_LEVEL_CRITICAL, CGROUP_ROOT_768_THRES_LOW); - memcg_set_threshold(CGROUP_ROOT, MEM_LEVEL_OOM, CGROUP_ROOT_768_THRES_MEDIUM); - memcg_set_leave_threshold(CGROUP_ROOT, CGROUP_ROOT_768_THRES_LEAVE); - num_max_victims = CGROUP_ROOT_768_NUM_VICTIMS; - } else if (total_ramsize <= MEM_SIZE_1024) { - /* set thresholds for ram size more than 1G */ - proactive_threshold = PROACTIVE_1024_THRES; - proactive_leave = PROACTIVE_1024_LEAVE; - memcg_set_threshold(CGROUP_ROOT, MEM_LEVEL_MEDIUM, CGROUP_ROOT_1024_THRES_DEDUP); - memcg_set_threshold(CGROUP_ROOT, MEM_LEVEL_LOW, CGROUP_ROOT_1024_THRES_SWAP); - memcg_set_threshold(CGROUP_ROOT, MEM_LEVEL_CRITICAL, CGROUP_ROOT_1024_THRES_LOW); - memcg_set_threshold(CGROUP_ROOT, MEM_LEVEL_OOM, CGROUP_ROOT_1024_THRES_MEDIUM); - memcg_set_leave_threshold(CGROUP_ROOT, CGROUP_ROOT_1024_THRES_LEAVE); - num_max_victims = CGROUP_ROOT_1024_NUM_VICTIMS; - } else if (total_ramsize <= MEM_SIZE_2048) { - proactive_threshold = PROACTIVE_2048_THRES; - proactive_leave = PROACTIVE_2048_LEAVE; - memcg_set_threshold(CGROUP_ROOT, MEM_LEVEL_MEDIUM, CGROUP_ROOT_2048_THRES_DEDUP); - memcg_set_threshold(CGROUP_ROOT, MEM_LEVEL_LOW, CGROUP_ROOT_2048_THRES_SWAP); - memcg_set_threshold(CGROUP_ROOT, MEM_LEVEL_CRITICAL, CGROUP_ROOT_2048_THRES_LOW); - memcg_set_threshold(CGROUP_ROOT, MEM_LEVEL_OOM, CGROUP_ROOT_2048_THRES_MEDIUM); - memcg_set_leave_threshold(CGROUP_ROOT, CGROUP_ROOT_2048_THRES_LEAVE); - num_max_victims = CGROUP_ROOT_2048_NUM_VICTIMS; - } else { - proactive_threshold = PROACTIVE_3072_THRES; - proactive_leave = PROACTIVE_3072_LEAVE; - memcg_set_threshold(CGROUP_ROOT, MEM_LEVEL_MEDIUM, CGROUP_ROOT_3072_THRES_DEDUP); - memcg_set_threshold(CGROUP_ROOT, MEM_LEVEL_LOW, CGROUP_ROOT_3072_THRES_SWAP); - memcg_set_threshold(CGROUP_ROOT, MEM_LEVEL_CRITICAL, CGROUP_ROOT_3072_THRES_LOW); - memcg_set_threshold(CGROUP_ROOT, MEM_LEVEL_OOM, CGROUP_ROOT_3072_THRES_MEDIUM); - memcg_set_leave_threshold(CGROUP_ROOT, CGROUP_ROOT_3072_THRES_LEAVE); - num_max_victims = CGROUP_ROOT_3072_NUM_VICTIMS; - } - -} - -static void lowmem_move_memcgroup(int pid, int next_oom_score_adj, struct proc_app_info *pai) -{ - int cur_oom_score_adj; - int cur_memcg_idx; - struct memcg_info *mi; - int next_memcg_idx = cgroup_get_type(next_oom_score_adj); - - if(next_memcg_idx < CGROUP_VIP || next_memcg_idx > CGROUP_LOW) { - _E("cgroup type (%d) should not be called", next_memcg_idx); - return; - } - mi = get_memcg_info(next_memcg_idx); - - if (!mi) { - return; - } - - if (!pai) { - cgroup_write_pid_fullpath(mi->name, pid); - return; - } - - /* parent pid */ - if (pai->main_pid == pid) { - cur_oom_score_adj = pai->memory.oom_score_adj; - cur_memcg_idx = cgroup_get_type(cur_oom_score_adj); - - /* -1 means that this pid is not yet registered at the memory cgroup - * plz, reference proc_create_app_info function - */ - if (cur_oom_score_adj != OOMADJ_APP_MAX + 10) { - /* VIP processes should not be asked to move. */ - if (cur_memcg_idx <= CGROUP_VIP) { - _I("[DEBUG] pid: %d, name: %s, cur_oom_score_adj: %d", pid, pai->appid, cur_oom_score_adj); - _E("[DEBUG] current cgroup (%s) cannot be VIP or Root", convert_cgroup_type_to_str(cur_memcg_idx)); - return; - } - } - - _I("app (%s) memory cgroup move from %s to %s", pai->appid, convert_cgroup_type_to_str(cur_memcg_idx), convert_cgroup_type_to_str(next_memcg_idx)); - - if (cur_oom_score_adj == next_oom_score_adj) { - _D("next oom_score_adj (%d) is same with current one", next_oom_score_adj); - return; - } - - proc_set_process_memory_state(pai, next_memcg_idx, mi, next_oom_score_adj); - - if (!lowmem_limit_move_cgroup(pai)) - return; - - if(cur_memcg_idx == next_memcg_idx) - return; - - cgroup_write_pid_fullpath(mi->name, pid); - if (next_memcg_idx == CGROUP_LOW) - lowmem_swap_memory(get_memcg_info(CGROUP_LOW)->name); - } - /* child pid */ - else { - if (pai->memory.use_mem_limit) - return; - - cgroup_write_pid_fullpath(mi->name, pid); - } -} - -static int lowmem_activate_worker(void) -{ - int ret = RESOURCED_ERROR_NONE; - - if (LOWMEM_WORKER_IS_ACTIVE(&lmw)) { - return ret; - } - - lmw.queue = g_async_queue_new_full(lowmem_request_destroy); - if (!lmw.queue) { - _E("Failed to create request queue\n"); - return RESOURCED_ERROR_FAIL; - } - LOWMEM_WORKER_ACTIVATE(&lmw); - ret = pthread_create(&lmw.worker_thread, NULL, - (void *)lowmem_reclaim_worker, (void *)&lmw); - if (ret) { - LOWMEM_WORKER_DEACTIVATE(&lmw); - _E("Failed to create LMK thread: %d\n", ret); - } else { - pthread_detach(lmw.worker_thread); - ret = RESOURCED_ERROR_NONE; - } - return ret; -} - -static void lowmem_deactivate_worker(void) -{ - struct lowmem_control *ctl; - - if (!LOWMEM_WORKER_IS_ACTIVE(&lmw)) - return; - - LOWMEM_WORKER_DEACTIVATE(&lmw); - lowmem_drain_queue(&lmw); - - ctl = LOWMEM_NEW_REQUEST(); - if (!ctl) { - _E("Critical - g_slice alloc failed - Lowmem cannot be deactivated"); - return; - } - ctl->flags = OOM_DROP; - g_async_queue_push(lmw.queue, ctl); - g_async_queue_unref(lmw.queue); -} - -static int lowmem_press_eventfd_read(int fd) -{ - uint64_t dummy_state; - - return read(fd, &dummy_state, sizeof(dummy_state)); -} - -static void lowmem_press_root_cgroup_handler(void) -{ - static unsigned int prev_available; - unsigned int available; - int mem_state; - - available = proc_get_mem_available(); - if (prev_available == available) - return; - - mem_state = check_mem_state(available); - lowmem_trigger_memory_state_action(mem_state); - - prev_available = available; -} - -static void lowmem_press_cgroup_handler(enum cgroup_type type, struct memcg_info *mi) -{ - unsigned int usage, threshold; - int ret; - - ret = memcg_get_anon_usage(mi->name, &usage); - if (ret) { - _D("getting anonymous memory usage fails"); - return; - } - - threshold = mi->threshold[MEM_LEVEL_OOM]; - if (usage >= threshold) - memory_cgroup_proactive_lmk_act(type, mi); - else - _I("anon page %u MB < medium threshold %u MB", BYTE_TO_MBYTE(usage), - BYTE_TO_MBYTE(threshold)); -} - -static bool lowmem_press_eventfd_handler(int fd, void *data) -{ - struct memcg_info *mi; - enum cgroup_type type = CGROUP_ROOT; - - // FIXME: probably shouldn't get ignored - if (lowmem_press_eventfd_read(fd) < 0) - _E("Failed to read lowmem press event, %m\n"); - - for (type = CGROUP_ROOT; type < CGROUP_END; type++) { - if (!get_cgroup_tree(type) || !get_memcg_info(type)) - continue; - mi = get_memcg_info(type); - if (fd == mi->evfd) { - /* call low memory handler for this memcg */ - if (type == CGROUP_ROOT) - lowmem_press_root_cgroup_handler(); - else { - lowmem_press_cgroup_handler(type, mi); - } - return true; - } - } - - return true; -} - -static int lowmem_press_register_eventfd(struct memcg_info *mi) -{ - int evfd; - const char *name = mi->name; - static fd_handler_h handler; - - if (mi->threshold[MEM_LEVEL_OOM] == LOWMEM_THRES_INIT) - return 0; - - evfd = memcg_set_eventfd(name, MEMCG_EVENTFD_MEMORY_PRESSURE, - event_level); - - if (evfd < 0) { - int saved_errno = errno; - _E("fail to register event press fd %s cgroup", name); - return -saved_errno; - } - - mi->evfd = evfd; - - _I("register event fd success for %s cgroup", name); - add_fd_read_handler(evfd, lowmem_press_eventfd_handler, NULL, NULL, &handler); - return 0; -} - -static int lowmem_press_setup_eventfd(void) -{ - unsigned int i; - - for (i = CGROUP_ROOT; i < CGROUP_END; i++) { - if (!get_use_hierarchy(i)) - continue; - - lowmem_press_register_eventfd(get_memcg_info(i)); - } - return RESOURCED_ERROR_NONE; -} - -static void lowmem_force_reclaim_cb(struct lowmem_control *ctl) -{ - lowmem_change_memory_state(MEM_LEVEL_HIGH, 0); -} - -int lowmem_trigger_reclaim(int flags, int victims, enum cgroup_type type, int threshold) -{ - struct lowmem_control *ctl = LOWMEM_NEW_REQUEST(); - - if (!ctl) - return -ENOMEM; - - flags |= OOM_FORCE | OOM_IN_DEPTH | OOM_SINGLE_SHOT; - victims = victims > 0 ? victims : MAX_MEMORY_CGROUP_VICTIMS; - type = type > 0 ? type : CGROUP_LOW; - threshold = threshold > 0 ? threshold : get_root_memcg_info()->threshold_leave; - - lowmem_change_memory_state(MEM_LEVEL_CRITICAL, 1); - LOWMEM_SET_REQUEST(ctl, flags, - type, threshold, victims, - lowmem_force_reclaim_cb); - lowmem_queue_request(&lmw, ctl); - - return 0; -} - -void lowmem_trigger_swap_reclaim(enum cgroup_type type, int swap_size) -{ - int size, victims; - - victims = num_max_victims > MAX_PROACTIVE_HIGH_VICTIMS - ? MAX_PROACTIVE_HIGH_VICTIMS : num_max_victims; - - size = get_root_memcg_info()->threshold_leave + BYTE_TO_MBYTE(swap_size); - _I("reclaim from swap module, type : %d, size : %d, victims: %d", type, size, victims); - lowmem_trigger_reclaim(0, victims, type, size); -} - -bool lowmem_fragmentated(void) -{ - struct buddyinfo bi; - int ret; - - ret = proc_get_buddyinfo("Normal", &bi); - if (ret < 0) - return false; - - /* - * The fragmentation_size is the minimum count of order-2 pages in "Normal" zone. - * If total buddy pages is smaller than fragmentation_size, - * resourced will detect kernel memory is fragmented. - * Default value is zero in low memory device. - */ - if (bi.page[PAGE_32K] + (bi.page[PAGE_64K] << 1) + (bi.page[PAGE_128K] << 2) + - (bi.page[PAGE_256K] << 3) < fragmentation_size) { - _I("fragmentation detected, need to execute proactive oom killer"); - return true; - } - return false; -} - -static void lowmem_proactive_oom_killer(int flags, char *appid) -{ - unsigned int before; - int victims; - - before = proc_get_mem_available(); - - /* If memory state is medium or normal, just return and kill in oom killer */ - if (before < get_root_memcg_info()->threshold[MEM_LEVEL_OOM] || before > proactive_leave) - return; - - victims = num_max_victims > MAX_PROACTIVE_HIGH_VICTIMS - ? MAX_PROACTIVE_HIGH_VICTIMS : num_max_victims; - -#ifdef HEART_SUPPORT - /* - * This branch is used only when HEART module is compiled in and - * it's MEMORY module must be enabled. Otherwise this is skipped. - */ - struct heart_memory_data *md = heart_memory_get_memdata(appid, DATA_LATEST); - if (md) { - unsigned int rss, after, size; - - rss = KBYTE_TO_MBYTE(md->avg_rss); - - free(md); - - after = before - rss; - /* - * after launching app, ensure that available memory is - * above threshold_leave - */ - if (after >= get_root_memcg_info()->threshold[MEM_LEVEL_OOM]) - return; - - if (proactive_threshold - rss >= get_root_memcg_info()->threshold[MEM_LEVEL_OOM]) - size = proactive_threshold; - else - size = rss + get_root_memcg_info()->threshold[MEM_LEVEL_OOM] + THRESHOLD_MARGIN; - - _D("history based proactive LMK : avg rss %u, available %u required = %u MB", - rss, before, size); - lowmem_trigger_reclaim(0, victims, CGROUP_LOW, size); - - return; - } -#endif - - /* - * When there is no history data for the launching app, - * it is necessary to check current fragmentation state or application manifest file. - * So, resourced feels proactive LMK is required, run oom killer based on dynamic - * threshold. - */ - if (lowmem_fragmentated()) - goto reclaim; - - /* - * run proactive oom killer only when available is larger than - * dynamic process threshold - */ - if (!proactive_threshold || before >= proactive_threshold) - return; - - if (!(flags & PROC_LARGEMEMORY)) - return; - -reclaim: - /* - * free THRESHOLD_MARGIN more than real should be freed, - * because launching app is consuming up the memory. - */ - _D("Run threshold based proactive LMK: memory level to reach: %u\n", - proactive_leave + THRESHOLD_MARGIN); - lowmem_trigger_reclaim(0, victims, CGROUP_LOW, proactive_leave + THRESHOLD_MARGIN); -} - -unsigned int lowmem_get_proactive_thres(void) -{ - return proactive_threshold; -} - -static int lowmem_prelaunch_handler(void *data) -{ - struct proc_status *ps = (struct proc_status *)data; - struct proc_app_info *pai = ps->pai; - - if (!pai || CHECK_BIT(pai->flags, PROC_SERVICEAPP)) - return RESOURCED_ERROR_NONE; - - lowmem_proactive_oom_killer(ps->pai->flags, ps->pai->appid); - return RESOURCED_ERROR_NONE; -} - -int lowmem_control_handler(void *data) -{ - struct lowmem_control_data *lowmem_data; - - lowmem_data = (struct lowmem_control_data *)data; - switch (lowmem_data->control_type) { - case LOWMEM_MOVE_CGROUP: - lowmem_move_memcgroup((pid_t)lowmem_data->pid, - lowmem_data->oom_score_adj, lowmem_data->pai); - break; - default: - break; - } - return RESOURCED_ERROR_NONE; -} - -static int lowmem_bg_reclaim_handler(void *data) -{ - if (swap_get_state() != SWAP_ON) - return RESOURCED_ERROR_NONE; - - if (!bg_reclaim) - return RESOURCED_ERROR_NONE; - - /* - * Proactively reclaiming memory used by long-lived background processes - * (such as widget instances) may be efficient on devices with limited - * memory constraints. The pages used by such processes could be reclaimed - * (if swap is enabled) earlier than they used to while minimizing the - * impact on the user experience. - */ - resourced_notify(RESOURCED_NOTIFIER_SWAP_START, get_memcg_info(CGROUP_MEDIUM)->name); - - return RESOURCED_ERROR_NONE; -} - -static void load_configs(const char *path) -{ -/* if (config_parse(path, set_memory_config, NULL)) - _E("(%s-mem) parse Fail", path); - - if (config_parse(path, load_popup_config, NULL)) - _E("(%s-popup) parse Fail", path); - - if (config_parse(path, load_bg_reclaim_config, NULL)) - _E("(%s-bg-reclaim) parse Fail", path); - - if (config_parse(path, load_mem_log_config, NULL)) - _E("(%s-mem-log) parse Fail", path);*/ - - free_memcg_conf(); -} - -static void print_mem_configs(void) -{ - /* print info of Memory section */ - for (int mem_lvl = 0; mem_lvl < MEM_LEVEL_MAX; mem_lvl++) - _I("set threshold for state '%s' to %u MB", - convert_memstate_to_str(mem_lvl), get_root_memcg_info()->threshold[mem_lvl]); - - _I("set number of max victims as %d", num_max_victims); - _I("set threshold leave to %u MB", get_root_memcg_info()->threshold_leave); - _I("set proactive threshold to %u MB", proactive_threshold); - _I("set proactive low memory killer leave to %u MB", proactive_leave); - - /* print info of POPUP section */ - _I("oom popup is %s", oom_popup_enable == true ? "enabled" : "disabled"); - - /* print info of BackgroundReclaim section */ - _I("Background reclaim is %s", bg_reclaim == true ? "enabled" : "disabled"); - - /* print info of Logging section */ - _I("memory logging is %s", memlog_enabled == 1 ? "enabled" : "disabled"); - _I("memory logging path is %s", memlog_path); - _I("the max number of memory logging is %d", memlog_nr_max); - _I("the batch threshold of memory log is %d", memlog_remove_batch_thres); - _I("prefix of memps is %s", memlog_prefix[MEMLOG_MEMPS]); - _I("prefix of memlimit memps is %s", memlog_prefix[MEMLOG_MEMPS_MEMLIMIT]); -} - -/* To Do: should we need lowmem_fd_start, lowmem_fd_stop ?? */ -static int lowmem_init(void) -{ - int ret = RESOURCED_ERROR_NONE; - - _D("resourced memory init start"); - - /* init memcg */ - ret = cgroup_make_full_subdir(MEMCG_PATH); - ret_value_msg_if(ret < 0, ret, "memory cgroup init failed\n"); - memcg_params_init(); - - setup_memcg_params(); - - /* default configuration */ - load_configs(MEM_CONF_FILE); - - /* this function should be called after parsing configurations */ - memcg_write_params(); - print_mem_configs(); - - /* make a worker thread called low memory killer */ - ret = lowmem_activate_worker(); - if (ret) { - _E("oom thread create failed\n"); - return ret; - } - - /* register threshold and event fd */ - ret = lowmem_press_setup_eventfd(); - if (ret) { - _E("eventfd setup failed"); - return ret; - } - - lowmem_dbus_init(); - lowmem_limit_init(); - lowmem_system_init(); - - register_notifier(RESOURCED_NOTIFIER_APP_PRELAUNCH, lowmem_prelaunch_handler); - register_notifier(RESOURCED_NOTIFIER_MEM_CONTROL, lowmem_control_handler); - register_notifier(RESOURCED_NOTIFIER_LCD_OFF, lowmem_bg_reclaim_handler); - - return ret; -} - -static int lowmem_exit(void) -{ - if (strncmp(event_level, MEMCG_DEFAULT_EVENT_LEVEL, sizeof(MEMCG_DEFAULT_EVENT_LEVEL))) - free(event_level); - - lowmem_deactivate_worker(); - lowmem_limit_exit(); - lowmem_system_exit(); - - unregister_notifier(RESOURCED_NOTIFIER_APP_PRELAUNCH, lowmem_prelaunch_handler); - unregister_notifier(RESOURCED_NOTIFIER_MEM_CONTROL, lowmem_control_handler); - unregister_notifier(RESOURCED_NOTIFIER_LCD_OFF, lowmem_bg_reclaim_handler); - - return RESOURCED_ERROR_NONE; -} - -static int resourced_memory_init(void *data) -{ - lowmem_ops = &memory_modules_ops; - return lowmem_init(); -} - -static int resourced_memory_finalize(void *data) -{ - return lowmem_exit(); -} - -void lowmem_change_memory_state(int state, int force) -{ - int mem_state; - - if (force) { - mem_state = state; - } else { - unsigned int available = proc_get_mem_available(); - mem_state = check_mem_state(available); - } - - lowmem_trigger_memory_state_action(mem_state); -} - -unsigned long lowmem_get_ktotalram(void) -{ - return ktotalram; -} - -unsigned long lowmem_get_totalram(void) -{ - return totalram; -} - -void lowmem_restore_memcg(struct proc_app_info *pai) -{ - char *cgpath; - int index, ret; - struct cgroup *cgroup = NULL; - struct memcg_info *mi = NULL; - pid_t pid = pai->main_pid; - - ret = cgroup_pid_get_path("memory", pid, &cgpath); - if (ret < 0) - return; - - for (index = CGROUP_END-1; index >= CGROUP_ROOT; index--) { - cgroup = get_cgroup_tree(index); - if (!cgroup) - continue; - - mi = cgroup->memcg_info; - if (!mi) - continue; - - if (!strcmp(cgroup->hashname, "")) - continue; - if (strstr(cgpath, cgroup->hashname)) - break; - } - pai->memory.memcg_idx = index; - pai->memory.memcg_info = mi; - if(strstr(cgpath, pai->appid)) - pai->memory.use_mem_limit = true; - - free(cgpath); -} - -static struct module_ops memory_modules_ops = { - .priority = MODULE_PRIORITY_HIGH, - .name = "lowmem", - .init = resourced_memory_init, - .exit = resourced_memory_finalize, -}; - -MODULE_REGISTER(&memory_modules_ops) diff --git a/src/common/cgroup/cpu-cgroup.c b/src/common/cgroup/cpu-cgroup.c index f9c056a..7e7cfa1 100644 --- a/src/common/cgroup/cpu-cgroup.c +++ b/src/common/cgroup/cpu-cgroup.c @@ -46,7 +46,7 @@ int set_cpucg_conf(const char *name, const char *value) void free_cpucg_conf(void) { - if (cpucg_conf) + if (cpucg_conf) free(cpucg_conf); } diff --git a/src/common/cgroup/memory-cgroup.c b/src/common/cgroup/memory-cgroup.c index d71e4ca..1a44fd4 100644 --- a/src/common/cgroup/memory-cgroup.c +++ b/src/common/cgroup/memory-cgroup.c @@ -126,23 +126,23 @@ int set_mem_action_conf(struct mem_action *mem_action, const char *value) return RESOURCED_ERROR_NONE; } -int set_memcg_conf_threshold(bool percent, char size, int lvl, const char *value) +int set_memcg_conf_threshold(bool percent, char size, int lvl, const char *value) { if (!percent) { if (size == 'G') { - memcg_conf->threshold[lvl].threshold = + memcg_conf->threshold[lvl].threshold = GBYTE_TO_MBYTE(atoi(value)); } else if (size == 'M') { - memcg_conf->threshold[lvl].threshold = + memcg_conf->threshold[lvl].threshold = atoi(value); } else if (size == 'K') { - memcg_conf->threshold[lvl].threshold = + memcg_conf->threshold[lvl].threshold = KBYTE_TO_MBYTE(atoi(value)); } else if (size == ' ') { - memcg_conf->threshold[lvl].threshold = + memcg_conf->threshold[lvl].threshold = BYTE_TO_MBYTE(atoi(value)); } else { @@ -206,7 +206,7 @@ int check_oom_and_set_limit(const char *dir, unsigned int limit) int error; static unsigned int poo = -1; - if (poo == -1) { + if (poo == -1) { error = fread_uint("/proc/sys/vm/panic_on_oom", &poo); if (error) { _E("[DEBUG] Failed to get %s from %s", "/proc/sys/vm/panic_on_oom", dir); diff --git a/src/common/cgroup/memory-cgroup.h b/src/common/cgroup/memory-cgroup.h index 0f3d5aa..221636a 100644 --- a/src/common/cgroup/memory-cgroup.h +++ b/src/common/cgroup/memory-cgroup.h @@ -186,7 +186,7 @@ struct cgroup_memory_stat { }; int set_mem_action_conf(struct mem_action *mem_action, const char *value); -int set_memcg_conf_threshold(bool percent, char size, int lvl, const char *value); +int set_memcg_conf_threshold(bool percent, char size, int lvl, const char *value); struct memcg_conf *get_memcg_conf(void); void free_memcg_conf(void); diff --git a/src/common/config-parser.c b/src/common/config-parser.c index 79a616a..34e642e 100644 --- a/src/common/config-parser.c +++ b/src/common/config-parser.c @@ -39,19 +39,19 @@ static int optimizer_config(struct parse_result *result, void *user_data) if (!result) return RESOURCED_ERROR_INVALID_PARAMETER; - struct swap_conf *swap_conf = get_swap_conf(); + struct swap_conf *swap_conf = get_swap_conf(); if (swap_conf == NULL) { _E("[DEBUG] swap configuration is NULL"); return RESOURCED_ERROR_FAIL; } - struct dedup_conf *dedup_conf = get_dedup_conf(); + struct dedup_conf *dedup_conf = get_dedup_conf(); if (dedup_conf == NULL) { _E("[DEBUG] dedup configuration is NULL"); return RESOURCED_ERROR_FAIL; } - struct compact_conf *compact_conf = get_compact_conf(); + struct compact_conf *compact_conf = get_compact_conf(); if (compact_conf == NULL) { _E("[DEBUG] compact configuration is NULL"); return RESOURCED_ERROR_FAIL; @@ -121,10 +121,10 @@ static int optimizer_config(struct parse_result *result, void *user_data) return RESOURCED_ERROR_OUT_OF_MEMORY; } strncpy(swap_conf->zram.algorithm, result->value, - sizeof(swap_conf->zram.algorithm) - 1); + sizeof(swap_conf->zram.algorithm) - 1); } else if (!strncmp(result->name, RATIO_CONF, strlen(RATIO_CONF)+1)) { - swap_conf->zram.ratio = atof(result->value); + swap_conf->zram.ratio = atof(result->value); } else { _E("[DEBUG] Unknown configuration name (%s) and value (%s) on section (%s)", @@ -141,7 +141,7 @@ static int optimizer_config(struct parse_result *result, void *user_data) sizeof(swap_conf->zswap.type) - 1); } else if (!strncmp(result->name, FILE_SIZE_CONF, strlen(FILE_SIZE_CONF)+1)) { - swap_conf->zswap.filesize = atol(result->value); + swap_conf->zswap.filesize = atol(result->value); } else if (!strncmp(result->name, POOL_RATIO_CONF, strlen(POOL_RATIO_CONF)+1)) { swap_conf->zswap.pool_ratio = atof(result->value); @@ -169,7 +169,7 @@ static int optimizer_config(struct parse_result *result, void *user_data) sizeof(swap_conf->fileswap.type) - 1); } else if (!strncmp(result->name, FILE_SIZE_CONF, strlen(FILE_SIZE_CONF)+1)) { - swap_conf->fileswap.filesize = atol(result->value); + swap_conf->fileswap.filesize = atol(result->value); } else { _E("[DEBUG] Unknown configuration name (%s) and value (%s) on section (%s)", @@ -272,7 +272,7 @@ static int optimizer_config(struct parse_result *result, void *user_data) _E("[DEBUG] Unknown section name (%s) and value (%s) on section (%s)", result->name, result->value, result->section); } - + return RESOURCED_ERROR_NONE; } @@ -282,7 +282,7 @@ static int limiter_config(struct parse_result *result, void *user_data) if (!result) return RESOURCED_ERROR_INVALID_PARAMETER; - struct memcg_conf *memcg_conf = get_memcg_conf(); + struct memcg_conf *memcg_conf = get_memcg_conf(); if (memcg_conf == NULL) { _E("[DEBUG] memory cgroup configuration is NULL"); return RESOURCED_ERROR_FAIL; @@ -357,7 +357,7 @@ static int limiter_config(struct parse_result *result, void *user_data) *(ptr - 1) = '\0'; percent = false; } - else { + else { *ptr = '\0'; percent = true; } @@ -733,380 +733,3 @@ error: _E("Failed to read %s:%d!", file_name, lineno); return ret; } - -static int config_table_lookup(void *table, - const char *section, - const char *lvalue, - ConfigParserCallback *func, - int *ltype, - void **data) -{ - ConfigTableItem *t; - - assert(table); - assert(lvalue); - assert(func); - assert(ltype); - assert(data); - - for (t = table; t->lvalue; t++) { - - if (!streq(lvalue, t->lvalue)) - continue; - - if (!streq_ptr(section, t->section)) - continue; - - *func = t->cb; - *ltype = t->ltype; - *data = t->data; - return 1; - } - - return 0; -} - -/* Run the user supplied parser for an assignment */ -static int config_parse_table(const char *filename, - unsigned line, - void *table, - const char *section, - const char *lvalue, - const char *rvalue) -{ - ConfigParserCallback cb = NULL; - int ltype = 0; - void *data = NULL; - int r; - - assert(filename); - assert(section); - assert(lvalue); - assert(rvalue); - - r = config_table_lookup(table, - section, - lvalue, - &cb, - <ype, - &data); - if (r <= 0) - return r; - - if (cb) - return cb(filename, - line, - section, - lvalue, - ltype, - rvalue, - data); - - return 0; -} - -int config_parse_new(const char *filename, void *table) -{ - _cleanup_fclose_ FILE *f = NULL; - char *sections[MAX_SECTION] = { 0 }; - char *section = NULL, *n, *e, l[LINE_MAX]; - size_t len; - int i, r, num_section = 0; - bool already; - unsigned line = 0; - - assert(filename); - - f = fopen(filename, "r"); - if (!f) { - const int saved_errno = errno; - _E("Failed to open file %s", filename); // can modify errno - return -saved_errno; - } - - while (!feof(f)) { - _cleanup_free_ char *lvalue = NULL, *rvalue = NULL; - char *rs = NULL; - - if (fgets(l, LINE_MAX, f) == NULL) { - if (feof(f)) - break; - - _E("Failed to parse configuration file '%s': %m", filename); - r = -errno; - goto finish; - } - - line++; - truncate_nl(l); - - if (strchr(COMMENTS NEWLINE, *l)) - continue; - - if (*l == '[') { - len = strlen(l); - if (l[len-1] != ']') { - _E("Error: Invalid section header: %s", l); - r = -EBADMSG; - goto finish; - } - - n = strndup(l+1, len-2); - if (!n) { - r = -ENOMEM; - goto finish; - } - - already = false; - for (i = 0; i < num_section; i++) { - if (streq(n, sections[i])) { - section = sections[i]; - already = true; - free(n); - break; - } - } - - if (already) - continue; - - section = n; - sections[num_section] = n; - num_section++; - if (num_section > MAX_SECTION) { - _E("Error: max number of section reached: %d", num_section); - r = -EOVERFLOW; - goto finish; - } - - continue; - } - - if (!section) - continue; - - e = strchr(l, '='); - if (e == NULL) { - _D("Warning: config: no '=' character in line '%s'.", l); - continue; - } - - lvalue = strndup(l, e-l); - if (!lvalue) { - r = -ENOMEM; - goto finish; - } - - strstrip(lvalue); - - rs = strstrip(e+1); - rvalue = strdup(rs); - if (!rvalue) { - r = -ENOMEM; - goto finish; - } - - strstrip(rvalue); - - r = config_parse_table(filename, - line, - table, - section, - lvalue, - rvalue); - if (r < 0) - goto finish; - } - - r = 0; - -finish: - for (i = 0; i < num_section; i++) - if (sections[i]) - free(sections[i]); - - return r; -} - -int config_parse_dir(const char *dir, ConfigParseFunc fp, void *data) -{ - _cleanup_closedir_ DIR *d = NULL; - struct dirent *de; - - d = opendir(dir); - if (!d) { - _E("Failed to open dir: %s", dir); - return errno; - } - - for (errno = 0, de = readdir(d);; errno = 0, de = readdir(d)) { - if (!de) { - if (errno > 0) - return -errno; - break; - } else if (streq(de->d_name, ".") || streq(de->d_name, "..")) { - continue; - } - - _cleanup_free_ char *path = NULL; - int r; - - if (de->d_type != DT_REG) - continue; - - r = asprintf(&path, "%s/%s", dir, de->d_name); - if (r < 0) - return -ENOMEM; - - r = fp(path, data); - /* Do not just break loop until parse all file of - * dir. Just only put log */ - if (r < 0) - _D("Failed to parse config: %s", de->d_name); - } - - return 0; -} - -int config_parse_bool(const char *filename, - unsigned line, - const char *section, - const char *lvalue, - int ltype, - const char *rvalue, - void *data) -{ - int k; - bool *b = data; - - assert(filename); - assert(lvalue); - assert(rvalue); - assert(data); - - k = parse_boolean(rvalue); - if (k < 0) { - _E("Failed to parse boolean value, ignoring: %s", rvalue); - return 0; - } - - *b = !!k; - - return 0; -} - -#define DEFINE_PARSER(type, vartype, conv_func) \ - int config_parse_##type( \ - const char *filename, \ - unsigned line, \ - const char *section, \ - const char *lvalue, \ - int ltype, \ - const char *rvalue, \ - void *data) { \ - \ - vartype *i = data; \ - \ - assert(filename); \ - assert(lvalue); \ - assert(rvalue); \ - assert(data); \ - \ - *i = conv_func(rvalue); \ - return 0; \ - } - -DEFINE_PARSER(int, int, atoi) -DEFINE_PARSER(float, float, atof) -DEFINE_PARSER(long, long, atol) - -int config_parse_string(const char *filename, - unsigned line, - const char *section, - const char *lvalue, - int ltype, - const char *rvalue, - void *data) -{ - char **s = data, *n; - - assert(filename); - assert(lvalue); - assert(rvalue); - assert(data); - - if (is_empty(rvalue)) - n = NULL; - else { - n = strdup(rvalue); - if (!n) - return -ENOMEM; - } - - free(*s); - *s = n; - - return 0; -} - -int config_parse_bytes(const char *filename, - unsigned line, - const char *section, - const char *lvalue, - int ltype, - const char *rvalue, - void *data) -{ - size_t *s = data; - int r; - - assert(filename); - assert(lvalue); - assert(rvalue); - assert(data); - - if (is_empty(rvalue)) - *s = 0; - else { - r = parse_bytes(rvalue, s); - if (r < 0) - return r; - } - - return 0; -} - -int config_parse_strv(const char *filename, - unsigned line, - const char *section, - const char *lvalue, - int ltype, - const char *rvalue, - void *data) -{ - char ***strv = data; - char **o = NULL, **v = NULL, **vv = NULL; - int r; - - assert(filename); - assert(lvalue); - assert(rvalue); - assert(data); - - if (is_empty(rvalue)) - return 0; - - r = str_to_strv(rvalue, &v, WHITESPACE); - if (r < 0) - return r; - - o = *strv; - - r = strv_attach(o, v, &vv, true); - if (r < 0) - return r; - - *strv = vv; - - return 0; -} diff --git a/src/common/config-parser.h b/src/common/config-parser.h index 6e3686c..fce99d6 100644 --- a/src/common/config-parser.h +++ b/src/common/config-parser.h @@ -97,7 +97,7 @@ extern "C" { #define MODE_CONF "Mode" #define PAGES_TO_SCAN_CONF "PagesToScan" #define PAGES_TO_SCAN_WITH_BOOST_CONF "PagesToScanWithBoost" -#define FRAG_LEVEL_CONF "FragLevel" +#define FRAG_LEVEL_CONF "FragLevel" /* configuration value */ #define CGROUP_VIP_VALUE_CONF "vip" @@ -164,17 +164,6 @@ typedef struct ConfigTableItem { * variable's data */ } ConfigTableItem; -int config_parse_new(const char *filename, void *table); -int config_parse_dir(const char *dir, ConfigParseFunc fp, void *data); - -int config_parse_bool(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data); -int config_parse_int(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data); -int config_parse_string(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data); -int config_parse_bytes(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data); -int config_parse_float(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data); -int config_parse_long(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data); -int config_parse_strv(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data); - void remove_app_conf_info_list(void); void remove_service_conf_info_list(void); GSList *get_app_conf_info_list(void); diff --git a/src/common/swap-common.h b/src/common/swap-common.h index 4f3bb33..918b329 100644 --- a/src/common/swap-common.h +++ b/src/common/swap-common.h @@ -111,7 +111,7 @@ struct fileswap_conf { struct swap_conf { bool enable; bool boot_reclaim_enable; - char type[30]; + char type[30]; int swappiness[CGROUP_END]; struct zram_conf zram; struct zswap_conf zswap; diff --git a/src/resource-limiter/cpu/cpu-sched.c b/src/resource-limiter/cpu/cpu-sched.c index a85a026..4521c60 100644 --- a/src/resource-limiter/cpu/cpu-sched.c +++ b/src/resource-limiter/cpu/cpu-sched.c @@ -238,7 +238,7 @@ static int load_config(struct cpu_sched *data) assert(data); - if (!get_cpucg_conf_name()) + if (!get_cpucg_conf_name()) return RESOURCED_ERROR_NONE; name = strdup(get_cpucg_conf_name()); @@ -269,9 +269,6 @@ static int load_config(struct cpu_sched *data) static int cpu_sched_parse_config(struct cpu_sched *data) { load_config(data); -/* if (config_parse(CPU_SCHED_CONF_FILE, load_config, data) < 0) - return RESOURCED_ERROR_FAIL;*/ - return RESOURCED_ERROR_NONE; } diff --git a/src/resource-limiter/memory/lowmem-limit.c b/src/resource-limiter/memory/lowmem-limit.c index 4143e36..7f5061a 100644 --- a/src/resource-limiter/memory/lowmem-limit.c +++ b/src/resource-limiter/memory/lowmem-limit.c @@ -279,14 +279,6 @@ static bool memory_action_cb(int fd, void *data) goto remove_mle; } -/* anon_usage = mem_stat->value[CGROUP_MEMORY_STAT_RSS] + - mem_stat->value[CGROUP_MEMORY_STAT_SWAP]; - if (anon_usage < mle->threshold) { - _D("[DEBUG] (%s) cgroup escaped low memory status. usage(%d), anon usage (%d), threshold(%d)", - cg_dir, usage, anon_usage, mle->threshold); - return true; - }*/ - switch (mle->action) { case PROC_ACTION_BROADCAST: main_pid = get_main_pid(cg_dir, &max_mem); @@ -421,33 +413,6 @@ int lowmem_limit_move_cgroup(struct proc_app_info *pai) return RESOURCED_ERROR_NONE; } -/*static int memlimit_config_parse(struct parse_result *result, void *user_data) -{ - if (!result->section) - return RESOURCED_ERROR_NONE; - - if (strncmp(result->section, MEMLIMIT_CONFIG_SECTION, - sizeof(MEMLIMIT_CONFIG_SECTION))) - return RESOURCED_ERROR_NONE; - - if (!result->name || !result->value) - return RESOURCED_ERROR_NONE; - - if (!strncmp(result->name, MEMLIMIT_CONFIG_LIM_PFX, sizeof(MEMLIMIT_CONFIG_LIM_PFX)-1)) { - const int limit = atoi(result->value); - if (!strcmp(result->name, MEMLIMIT_CONFIG_SERVICE)) - mem_service_limit = limit; - else if (!strcmp(result->name, MEMLIMIT_CONFIG_GUIAPP)) - mem_guiapp_limit = limit; - else if (!strcmp(result->name, MEMLIMIT_CONFIG_WIDGET)) - mem_widget_limit = limit; - else if (!strcmp(result->name, MEMLIMIT_CONFIG_BGAPP)) - mem_bgapp_limit = limit; - } - - return RESOURCED_ERROR_NONE; -}*/ - void lowmem_limit_set_system_service(pid_t pid, unsigned int limit, const char *name, enum proc_action action) { @@ -644,10 +609,10 @@ void lowmem_action_init(int service_action, int widget_action, { if (service_action > 0) mem_service_action = service_action; - + if (widget_action > 0) mem_widget_action = widget_action; - + if (guiapp_action > 0) mem_guiapp_action = guiapp_action; diff --git a/src/resource-limiter/memory/vmpressure-lowmem-handler.c b/src/resource-limiter/memory/vmpressure-lowmem-handler.c index 1e4678d..a4a5e90 100644 --- a/src/resource-limiter/memory/vmpressure-lowmem-handler.c +++ b/src/resource-limiter/memory/vmpressure-lowmem-handler.c @@ -486,153 +486,6 @@ unsigned int lowmem_get_task_mem_usage_rss(const struct task_info *tsk) return total_size; } -/*static int memps_file_select(const struct dirent *entry) -{ - return strstr(entry->d_name, "memps") ? 1 : 0; -} - -static char *strrstr(const char *str, const char *token) -{ - int len = strlen(token); - const char *p = str + strlen(str); - - while (str <= --p) - if (p[0] == token[0] && strncmp(p, token, len) == 0) - return (char *)p; - - return NULL; -} - -static int timesort(const struct dirent **a, const struct dirent **b) -{ - long long time1 = 0; - long long time2 = 0; - char *ptr; - - ptr = strrstr((*a)->d_name, "_"); - if (ptr && *++ptr) - time1 = atoll(ptr); - - ptr = strrstr((*b)->d_name, "_"); - if (ptr && *++ptr) - time2 = atoll(ptr); - - return (time1 - time2); -} - -static int clear_logs(void *data) -{ - struct dirent **namelist; - int n, i, ret; - char fpath[BUF_MAX]; - char *fname; - char *dir = (char*)data; - int len; - - if (!memlog_enabled) - return RESOURCED_ERROR_NONE; - - if (!dir) - return RESOURCED_ERROR_NONE; - - len = strlen(dir); - if (len <= 0 || len >= sizeof fpath - 1) { - _E("Invalid parameter - Directory path is too short or too long"); - return RESOURCED_ERROR_INVALID_PARAMETER; - } - - n = scandir(dir, &namelist, memps_file_select, timesort); - - _D("num of log files %d", n); - if (n <= memlog_nr_max) { - while (n--) - free(namelist[n]); - free(namelist); - return RESOURCED_ERROR_NONE; - } - - strncpy(fpath, dir, sizeof fpath - 1); - fpath[sizeof fpath - 1] = '\0'; - fname = fpath + len; - *fname++ = '/'; - - len = sizeof fpath - len - 1; - for (i = 0; i < n; i++) { - if (i < n - memlog_remove_batch_thres) { - if (strlen(namelist[i]->d_name) > len - 1) - continue; - strncpy(fname, namelist[i]->d_name, len - 1); - fpath[sizeof fpath - 1] = '\0'; - _D("remove log file %s", fpath); - ret = remove(fpath); - if (ret < 0) - _E("%s file cannot removed", fpath); - } - - free(namelist[i]); - } - free(namelist); - return RESOURCED_ERROR_NONE; -} - -void make_memps_log(enum mem_log memlog, pid_t pid, char *victim_name) -{ - time_t now; - struct tm cur_tm; - char new_log[BUF_MAX]; - static pid_t old_pid; - int oom_score_adj = 0, ret; - char *prefix; - - if (!memlog_enabled) - return; - - if (memlog < MEMLOG_MEMPS || memlog >= MEMLOG_MAX) - return; - - prefix = memlog_prefix[memlog]; - - if (old_pid == pid) - return; - - old_pid = pid; - - now = time(NULL); - - if (localtime_r(&now, &cur_tm) == NULL) { - _E("Fail to get localtime"); - return; - } - - snprintf(new_log, sizeof(new_log), - "%s/%s_%s_%d_%.4d%.2d%.2d%.2d%.2d%.2d", memlog_path, prefix, victim_name, - pid, (1900 + cur_tm.tm_year), 1 + cur_tm.tm_mon, - cur_tm.tm_mday, cur_tm.tm_hour, cur_tm.tm_min, - cur_tm.tm_sec); - - ret = proc_get_oom_score_adj(pid, &oom_score_adj); - if (ret || oom_score_adj > OOMADJ_BACKGRD_LOCKED) { - - _cleanup_fclose_ FILE *f = NULL; - - f = fopen(new_log, "w"); - if (!f) { - _E("fail to create memps log %s", new_log); - return; - } - proc_print_meninfo(f); - - } else { - - const char *argv[4] = {"/usr/bin/memps", "-f", NULL, NULL}; - - argv[2] = new_log; - exec_cmd(ARRAY_SIZE(argv), argv); - } - - clear_logs(memlog_path); -}*/ - static int lowmem_kill_victim(const struct task_info *tsk, int flags, int memps_log, unsigned int *victim_size) { @@ -658,9 +511,6 @@ static int lowmem_kill_victim(const struct task_info *tsk, return RESOURCED_ERROR_FAIL; } -/* if (!memps_log) - make_memps_log(MEMLOG_MEMPS, pid, appname);*/ - pai = tsk->pai; if (pai) { resourced_proc_status_change(PROC_CGROUP_SET_TERMINATE_REQUEST, @@ -696,8 +546,6 @@ static int lowmem_kill_victim(const struct task_info *tsk, lowmem_launch_oompopup(); oom_popup = true; } -/* if (memps_log) - make_memps_log(MEMLOG_MEMPS, pid, appname);*/ return RESOURCED_ERROR_NONE; } @@ -1107,8 +955,6 @@ done: count, total_size, reclaim_size, shortfall, convert_status_to_str(status)); /* After we finish reclaiming it's worth to remove oldest memps logs */ -/* if (count && memlog_enabled) - request_helper_worker(CLEAR_LOGS, memlog_path, clear_logs, NULL);*/ ctl->status = status; } @@ -1504,157 +1350,6 @@ static unsigned int check_mem_state(unsigned int available) return mem_state; } -/*static int load_bg_reclaim_config(struct parse_result *result, void *user_data) -{ - if (!result) - return RESOURCED_ERROR_INVALID_PARAMETER; - - if (strncmp(result->section, MEM_BG_RECLAIM_SECTION, strlen(MEM_BG_RECLAIM_SECTION)+1)) - return RESOURCED_ERROR_NONE; - - if (!strncmp(result->name, MEM_BG_RECLAIM_STRING, strlen(MEM_BG_RECLAIM_STRING)+1)) { - if (!strncmp(result->value, "yes", strlen("yes")+1)) - bg_reclaim = true; - else if (!strncmp(result->value, "no", strlen("no")+1)) - bg_reclaim = false; - } - - - return RESOURCED_ERROR_NONE; -} - -static int load_popup_config(struct parse_result *result, void *user_data) -{ - if (!result) - return RESOURCED_ERROR_INVALID_PARAMETER; - - if (strncmp(result->section, MEM_POPUP_SECTION, strlen(MEM_POPUP_SECTION)+1)) - return RESOURCED_ERROR_NONE; - - if (!strncmp(result->name, MEM_POPUP_STRING, strlen(MEM_POPUP_STRING)+1)) { - if (!strncmp(result->value, "yes", strlen("yes")+1)) - oom_popup_enable = true; - else if (!strncmp(result->value, "no", strlen("no")+1)) - oom_popup_enable = false; - } - - - return RESOURCED_ERROR_NONE; -} - -static int load_mem_log_config(struct parse_result *result, void *user_data) -{ - if (!result) - return RESOURCED_ERROR_INVALID_PARAMETER; - - if (strncmp(result->section, MEM_LOGGING_SECTION, strlen(MEM_LOGGING_SECTION)+1)) - return RESOURCED_ERROR_NONE; - - if (!strncmp(result->name, "Enable", strlen("Enable")+1)) { - memlog_enabled = atoi(result->value); - } else if (!strncmp(result->name, "LogPath", strlen("LogPath")+1)) { - memlog_path = strdup(result->value); - } else if (!strncmp(result->name, "MaxNumLogfile", strlen("MaxNumLogfile")+1)) { - memlog_nr_max = atoi(result->value); - memlog_remove_batch_thres = (memlog_nr_max * 5) / 6; - } else if (!strncmp(result->name, "PrefixMemps", strlen("PrefixMemps")+1)) { - memlog_prefix[MEMLOG_MEMPS] = strdup(result->value); - } else if (!strncmp(result->name, "PrefixMempsMemLimit", strlen("PrefixMempsMemLimit")+1)) { - memlog_prefix[MEMLOG_MEMPS_MEMLIMIT] = strdup(result->value); - } - - return RESOURCED_ERROR_NONE; -} - -static int set_memory_config(struct parse_result *result, void *user_data) -{ - if (!result) - return RESOURCED_ERROR_NONE; - - if (strncmp(result->section, MEM_SECTION, strlen(MEM_SECTION)+1)) - return RESOURCED_ERROR_NONE; - - if (!strncmp(result->name, "ThresholdDedup", strlen("ThresholdDedup")+1)) { - int value = atoi(result->value); - memcg_set_threshold(CGROUP_ROOT, MEM_LEVEL_MEDIUM, value); - } else if (!strncmp(result->name, "ThresholdSwap", strlen("ThresholdSwap")+1)) { - int value = atoi(result->value); - memcg_set_threshold(CGROUP_ROOT, MEM_LEVEL_LOW, value); - } else if (!strncmp(result->name, "ThresholdLow", strlen("ThresholdLow")+1)) { - int value = atoi(result->value); - memcg_set_threshold(CGROUP_ROOT, MEM_LEVEL_CRITICAL, value); - } else if (!strncmp(result->name, "ThresholdMedium", strlen("ThresholdMedium")+1)) { - int value = atoi(result->value); - memcg_set_threshold(CGROUP_ROOT, MEM_LEVEL_OOM, value); - } else if (!strncmp(result->name, "ThresholdLeave", strlen("ThresholdLeave")+1)) { - int value = atoi(result->value); - memcg_set_leave_threshold(CGROUP_ROOT, value); - } else if (!strncmp(result->name, "ThresholdRatioDedup", strlen("ThresholdRatioDedup")+1)) { - double ratio = atoi(result->value); - int value = (double)totalram * ratio / 100.0; - memcg_set_threshold(CGROUP_ROOT, MEM_LEVEL_MEDIUM, BYTE_TO_MBYTE(value)); - } else if (!strncmp(result->name, "ThresholdRatioSwap", strlen("ThresholdRatioSwap")+1)) { - double ratio = atoi(result->value); - int value = (double)totalram * ratio / 100.0; - memcg_set_threshold(CGROUP_ROOT, MEM_LEVEL_LOW, BYTE_TO_MBYTE(value)); - } else if (!strncmp(result->name, "ThresholdRatioLow", strlen("ThresholdRatioLow")+1)) { - double ratio = atoi(result->value); - int value = (double)totalram * ratio / 100.0; - memcg_set_threshold(CGROUP_ROOT, MEM_LEVEL_CRITICAL, BYTE_TO_MBYTE(value)); - } else if (!strncmp(result->name, "ThresholdRatioMedium", strlen("ThresholdRatioMedium")+1)) { - double ratio = atoi(result->value); - int value = (double)totalram * ratio / 100.0; - memcg_set_threshold(CGROUP_ROOT, MEM_LEVEL_OOM, BYTE_TO_MBYTE(value)); - } else if (!strncmp(result->name, "ThresholdRatioLeave", strlen("ThresholdRatioLeave")+1)) { - double ratio = atoi(result->value); - int value = (double)totalram * ratio / 100.0; - memcg_set_leave_threshold(CGROUP_ROOT, BYTE_TO_MBYTE(value)); - } else if (!strncmp(result->name, "ForegroundRatio", strlen("ForegroundRatio")+1)) { - float ratio = atof(result->value); - memcg_info_set_limit(get_memcg_info(CGROUP_HIGH), ratio, totalram); - } else if (!strncmp(result->name, "BackgroundRatio", strlen("BackgroundRatio")+1)) { - float ratio = atof(result->value); - memcg_info_set_limit(get_memcg_info(CGROUP_MEDIUM), ratio, totalram); - } else if (!strncmp(result->name, "LowRatio", strlen("LowRatio")+1)) { - float ratio = atof(result->value); - memcg_info_set_limit(get_memcg_info(CGROUP_LOW), ratio, totalram); - } else if (!strncmp(result->name, "NumMaxVictims", strlen("NumMaxVictims")+1)) { - int value = atoi(result->value); - num_max_victims = value; - num_vict_between_check = value > MAX_MEMORY_CGROUP_VICTIMS/2 - ? 3 : value > MAX_MEMORY_CGROUP_VICTIMS/4 - ? 2 : 1; - } else if (!strncmp(result->name, "ProactiveThreshold", strlen("ProactiveThreshold")+1)) { - int value = atoi(result->value); - proactive_threshold = value; - } else if (!strncmp(result->name, "ProactiveLeave", strlen("ProactiveLeave")+1)) { - int value = atoi(result->value); - proactive_leave = value; - } else if (!strncmp(result->name, "EventLevel", strlen("EventLevel")+1)) { - if (strncmp(event_level, result->value, strlen(event_level))) - event_level = strdup(result->value); - if (!event_level) - return RESOURCED_ERROR_OUT_OF_MEMORY; - } else if (!strncmp(result->name, "SWAPPINESS", strlen("SWAPPINESS")+1)) { - int value = atoi(result->value); - memcg_set_default_swappiness(value); - memcg_info_set_swappiness(get_memcg_info(CGROUP_ROOT), value); - } else if (!strncmp(result->name, "FOREGROUND_SWAPPINESS", strlen("FOREGROUND_SWAPPINESS")+1)) { - int value = atoi(result->value); - memcg_info_set_swappiness(get_memcg_info(CGROUP_HIGH), value); - } else if (!strncmp(result->name, "BACKGROUND_SWAPPINESS", strlen("BACKGROUND_SWAPPINESS")+1)) { - int value = atoi(result->value); - memcg_info_set_swappiness(get_memcg_info(CGROUP_MEDIUM), value); - } else if (!strncmp(result->name, "LOW_SWAPPINESS", strlen("LOW_SWAPPINESS")+1)) { - int value = atoi(result->value); - memcg_info_set_swappiness(get_memcg_info(CGROUP_LOW), value); - } else if (!strncmp(result->name, "NumFragSize", strlen("NumFragSize")+1)) { - fragmentation_size = atoi(result->value); - } - - return RESOURCED_ERROR_NONE; -}*/ - /* setup memcg parameters depending on total ram size. */ static void setup_memcg_params(void) { @@ -2198,7 +1893,7 @@ static void print_mem_configs(void) /* print info of Memory section */ for (int cgroup = CGROUP_VIP; cgroup < CGROUP_END; cgroup++) { _I("[DEBUG] set memory for cgroup '%s' to %u bytes", - convert_cgroup_type_to_str(cgroup), get_memcg_info(cgroup)->limit); + convert_cgroup_type_to_str(cgroup), get_memcg_info(cgroup)->limit); } for (int mem_lvl = 0; mem_lvl < MEM_LEVEL_MAX; mem_lvl++) @@ -2215,14 +1910,6 @@ static void print_mem_configs(void) /* print info of BackgroundReclaim section */ _I("[DEBUG] Background reclaim is %s", bg_reclaim == true ? "enabled" : "disabled"); - - /* print info of Logging section */ -/* _I("memory logging is %s", memlog_enabled == 1 ? "enabled" : "disabled"); - _I("memory logging path is %s", memlog_path); - _I("the max number of memory logging is %d", memlog_nr_max); - _I("the batch threshold of memory log is %d", memlog_remove_batch_thres); - _I("prefix of memps is %s", memlog_prefix[MEMLOG_MEMPS]); - _I("prefix of memlimit memps is %s", memlog_prefix[MEMLOG_MEMPS_MEMLIMIT]);*/ } #include "file-helper.h" diff --git a/src/resource-optimizer/memory/compaction/compaction.c b/src/resource-optimizer/memory/compaction/compaction.c index 0a9b40d..31251a5 100644 --- a/src/resource-optimizer/memory/compaction/compaction.c +++ b/src/resource-optimizer/memory/compaction/compaction.c @@ -594,44 +594,6 @@ static int compact_parse_config_file(struct compact_control *compact) return RESOURCED_ERROR_NONE; } -/*static int compact_config_parse(struct parse_result *result, void *user_data) -{ - struct compact_control *compact = (struct compact_control *)user_data; - unsigned long v; - char *e = NULL; - - if (!result->section || - strncmp(result->section, COMPACT_CONFIG_SECTION, strlen(COMPACT_CONFIG_SECTION)+1)) - return RESOURCED_ERROR_NONE; - - if (!result->name || !result->value) - return RESOURCED_ERROR_NONE; - - if (!strcmp(COMPACT_CONFIG_ENABLE, result->name)) { - - v = strtol(result->value, &e, 10); - - if (!(result->value != e) || *e != '\0') - return RESOURCED_ERROR_FAIL; - - if (!v) { - (void) pthread_mutex_lock(&compact->lock); - compact->status |= COMPACT_SKIP; - (void) pthread_mutex_unlock(&compact->lock); - } - - } else if (!strcmp(COMPACT_CONFIG_FRAG, result->name)) { - - v = strtol(result->value, &e, 0); - - if (!(result->value != e) || *e != '\0') - return RESOURCED_ERROR_FAIL; - compact->frag_level = v; - } - - return RESOURCED_ERROR_NONE; -}*/ - static int compact_init(void *data) { struct memory_info *mem_info; diff --git a/src/resource-optimizer/memory/dedup/dedup.c b/src/resource-optimizer/memory/dedup/dedup.c index aa4a1a5..c61b2e2 100644 --- a/src/resource-optimizer/memory/dedup/dedup.c +++ b/src/resource-optimizer/memory/dedup/dedup.c @@ -445,161 +445,10 @@ static int dedup_booting_done(void *data) return RESOURCED_ERROR_NONE; } -/*static int config_parse_dedup_modes(const char *filename, - unsigned line, - const char *section, - const char *lvalue, - int ltype, - const char *rvalue, - void *data) -{ - enum dedup_mode *mode = data; - char *word, *state; - size_t l; - - if (is_empty(rvalue)) - return 0; - - *mode = 0; - - FOREACH_WORD(word, l, rvalue, state) { - if (strneq(word, "oneshot", l)) - *mode = DEDUP_MODE_ONESHOT; - else if (strneq(word, "periodic", l)) - *mode = DEDUP_MODE_PERIODIC; - else - return -EINVAL; - } - - return 0; -} - -static int config_parse_param(const char *filename, - unsigned line, - const char *section, - const char *lvalue, - int ltype, - const char *rvalue, - void *data) -{ - int val, *var = data; - - assert(filename); - assert(lvalue); - assert(rvalue); - assert(data); - assert(section); - - val = atoi(rvalue); - if (!strncmp(section, DEDUP_SECTION, sizeof(DEDUP_SECTION))) { - if (val >= dedup_param_ranges[ltype][0] && - val < dedup_param_ranges[ltype][1]) { - *var = val; - _I("[DEDUP] Success to parse parameters, val: %d of %s in %s section", - val, lvalue, section); - } else - _E("[DEDUP] Failed to parse parameters, ignoring: %s of %s in %s section", - rvalue, lvalue, section); - } else if (!strncmp(section, KSM_SECTION, sizeof(KSM_SECTION))) { - if (val >= ksm_param_ranges[ltype][0] && - val < ksm_param_ranges[ltype][1]) { - *var = val; - _I("[DEDUP] Success to parse parameters, val: %d of %s in %s section", - val, lvalue, section); - } else - _E("[DEDUP] Failed to parse parameters, ignoring: %s of %s in %s section", - rvalue, lvalue, section); - } else - _E("[DEDUP] Unknown section: %s", section); - return 0; -} - -static int dedup_parse_config_file(void) -{ - int ret; - int arg_ksm_pages_to_scan = 100; - int arg_ksm_sleep = 20; // 20 msecs - int arg_ksm_full_scan_interval = 60000; // 60 seconds - int arg_ksm_scan_boost = 100; - - const ConfigTableItem items[] = { - { "DEDUP", "Enable", config_parse_bool, - DEDUP_PARAM_ENABLE, - &dedup_enable }, - { "DEDUP", "DedupAtBoot", config_parse_bool, - DEDUP_PARAM_AT_BOOT, - &dedup_at_boot_enable }, - { "DEDUP", "DedupAtBootDelayMs", config_parse_param, - DEDUP_PARAM_AT_BOOT_DELAY, - &dedup_at_boot_delay }, - { "DEDUP", "ScanOnLowmem", config_parse_bool, - DEDUP_PARAM_ON_LOWMEM, - &dedup_on_lowmem }, - { "DEDUP", "StatIntervalMs", config_parse_param, - DEDUP_PARAM_STAT_INTERVAL, - &dedup_stat_interval }, - { "DEDUP", "FullScanIntervalMs", config_parse_param, - DEDUP_PARAM_FULL_SCAN_INTERVAL, - &dedup_full_scan_interval }, - { "DEDUP", "PartialScanIntervalMs", config_parse_param, - DEDUP_PARAM_PARTIAL_SCAN_INTERVAL, - &dedup_partial_scan_interval }, - { "KSM", "Mode", config_parse_dedup_modes, - 0, &dedup_mode }, - { "KSM", "PagesToScan", config_parse_param, - KSM_PARAM_PAGES_TO_SCAN, - &arg_ksm_pages_to_scan }, - { "KSM", "SleepMs", config_parse_param, - KSM_PARAM_SLEEP_MSECS, - &arg_ksm_sleep }, - { "KSM", "FullScanIntervalMs", config_parse_param, - KSM_PARAM_FULL_SCAN_INTERVAL, - &arg_ksm_full_scan_interval }, - { "KSM", "ScanBoost", config_parse_param, - KSM_PARAM_SCAN_BOOST, - &arg_ksm_scan_boost }, - { NULL, NULL, NULL, - 0, NULL } - }; - - ret = config_parse_new(DEDUP_CONF_FILE, (void*) items); - if (ret < 0) { - _E("[DEDUP] Failed to parse configuration file: %d", ret); - return ret; - } - - _I("[DEDUP] dedup init"); - - ksm_params[KSM_PARAM_PAGES_TO_SCAN] = arg_ksm_pages_to_scan; - ksm_params[KSM_PARAM_SLEEP_MSECS] = arg_ksm_sleep; - ksm_params[KSM_PARAM_FULL_SCAN_INTERVAL] = arg_ksm_full_scan_interval; - ksm_params[KSM_PARAM_SCAN_BOOST] = arg_ksm_scan_boost; - - dedup_at_boot_delay /= 1000; - dedup_stat_interval /= 1000; - dedup_partial_scan_interval /= 1000; - dedup_full_scan_interval /= 1000; - - _I("[DEDUP] deduplication mode: %s", dedup_mode == DEDUP_MODE_PERIODIC ? - "kernel-managed" : "resourced-triggered"); - _I("[DEDUP] deduplication on boot: %s", dedup_at_boot_enable ? "true" : "false"); - _I("[DEDUP] scanning is invoked by %s", dedup_on_lowmem ? - "LOWMEM event" : "periodic timer"); - _I("[DEDUP] full scan interval: %d sec", dedup_full_scan_interval); - _I("[DEDUP] stat monitoring interval: %d sec", dedup_stat_interval); - - _I("[DEDUP] ksm pages to scan: %d", arg_ksm_pages_to_scan); - _I("[DEDUP] ksm sleep time: %d", arg_ksm_sleep); - _I("[DEDUP] ksm full scan interval: %d", arg_ksm_full_scan_interval); - _I("[DEDUP] ksm scan boost: %d", arg_ksm_scan_boost); - - return 0; -}*/ - static int dedup_parse_config_file(void) { int arg_ksm_pages_to_scan = 100; - int arg_ksm_sleep = 20; // 20 msecs + int arg_ksm_sleep = 20; // 20 msecs int arg_ksm_full_scan_interval = 60000; // 60 seconds int arg_ksm_scan_boost = 100; @@ -621,7 +470,7 @@ static int dedup_parse_config_file(void) if (dedup_conf->ksm.pages > ksm_param_ranges[KSM_PARAM_PAGES_TO_SCAN][0] && dedup_conf->ksm.pages <= ksm_param_ranges[KSM_PARAM_PAGES_TO_SCAN][1]) ksm_params[KSM_PARAM_PAGES_TO_SCAN] = dedup_conf->ksm.pages; - else + else ksm_params[KSM_PARAM_PAGES_TO_SCAN] = arg_ksm_pages_to_scan; if (dedup_conf->ksm.boost_pages > ksm_param_ranges[KSM_PARAM_SCAN_BOOST][0] && diff --git a/src/resource-optimizer/memory/swap/fileswap.c b/src/resource-optimizer/memory/swap/fileswap.c index bbadc8b..1825137 100644 --- a/src/resource-optimizer/memory/swap/fileswap.c +++ b/src/resource-optimizer/memory/swap/fileswap.c @@ -99,44 +99,10 @@ static int swap_file_reclaim(void *data) return -ENOSPC; } -/*static int swap_file_parse_config_file(void) -{ - ConfigTableItem items[] = { - { "FILE", "CryptType", config_parse_string, 0, NULL }, - { "FILE", "FileSize", config_parse_bytes, 0, NULL }, - { NULL, NULL, NULL, 0, NULL } - }; - - int r; - _cleanup_free_ char *crypt_type = NULL; - - items[0].data = &crypt_type; - items[1].data = &file_control.swap_file_size; - - r = config_parse_new(SWAP_CONF_FILE, (void*) items); - if (r < 0) { - _E("Failed to parse configuration file: %d", r); - return r; - } - - if (check_valid_compressor(crypt_type) == RESOURCED_ERROR_NONE) - strncpy(file_control.crypt_type, crypt_type, MAX_TYPE_LENGTH-1); - else - memset(file_control.crypt_type, 0, MAX_TYPE_LENGTH); - - return 0; -}*/ - static int swap_file_init(void *data) { struct swap_module_ops *swap = (struct swap_module_ops *)data; -/* r = swap_file_parse_config_file(); - if (r < 0) { - _E("Failed to parse SwapFile config: %d", r); - return r; - }*/ - swap->k_size = BYTE_TO_KBYTE(file_control.swap_file_size); return 0; } diff --git a/src/resource-optimizer/memory/swap/swap.c b/src/resource-optimizer/memory/swap/swap.c index 47801e2..ebf8160 100644 --- a/src/resource-optimizer/memory/swap/swap.c +++ b/src/resource-optimizer/memory/swap/swap.c @@ -234,7 +234,7 @@ static int swap_use_hard_limit(char *memcg) _D("Swap request: %s cgroup usage is %u, hard limit set to %u (hard limit fraction %f)", memcg, usage, memcg_limit, swap_hard_limit_fraction); if (memcg_limit != 0) - ret = check_oom_and_set_limit(memcg, memcg_limit); + ret = check_oom_and_set_limit(memcg, memcg_limit); else { /* If the group is empty don't set the limit to enable adding processes. */ ret = cgroup_write_node_int32(memcg, MEMCG_SWAP_LIMIT_BYTE, -1); @@ -777,7 +777,6 @@ static int swap_cgroup_reset_limit(void *data) return RESOURCED_ERROR_NONE; ret = check_oom_and_set_limit(mi->name, mi->limit); -// ret = cgroup_write_node_int32(mi->name, MEMCG_LIMIT_BYTE, mi->limit); if (ret != RESOURCED_ERROR_NONE) _E("Failed to change hard limit of %s cgroup to -1", mi->name); else @@ -876,8 +875,8 @@ static int swap_parse_config_file(void) if (arg_swap_enable == false) goto free_swap_conf; - arg_swap_at_boot = swap_conf->boot_reclaim_enable; - if (config_parse_swap_types(swap_conf->type, &arg_swap_type) < 0) { + arg_swap_at_boot = swap_conf->boot_reclaim_enable; + if (config_parse_swap_types(swap_conf->type, &arg_swap_type) < 0) { _E("[DEBUG] Failed to parse type of swap, so use default zram type"); arg_swap_type = SWAP_TYPE_ZRAM; } @@ -886,7 +885,7 @@ static int swap_parse_config_file(void) if (swap_conf->swappiness[cgroup] >= 0 && swap_conf->swappiness[cgroup] <= 100) memcg_info_set_swappiness(get_memcg_info(cgroup), - swap_conf->swappiness[cgroup]); + swap_conf->swappiness[cgroup]); } gslist_for_each_item(iter, swap_module) { @@ -910,43 +909,6 @@ free_swap_conf: return r; } -/*static int swap_parse_config_file(void) -{ - const ConfigTableItem items[] = { - { "SWAP", "Enable", config_parse_bool, - 0, &arg_swap_enable }, - { "SWAP", "Type", config_parse_swap_types, - 0, &arg_swap_type }, - { "SWAP", "ReclaimAtBoot", config_parse_bool, - 0, &arg_swap_at_boot }, - { "SWAP", "TimerReclaimAtBoot", config_parse_int, - 0, &arg_timer_swap_at_boot }, - { "SWAP", "ReclaimAtBootThreshold", config_parse_bytes, - 0, &arg_swap_at_boot_threshold }, - { "SWAP", "ReclaimAtBootMaxTry", config_parse_int, - 0, &arg_swap_at_boot_maxtry }, - { "SWAP", "ReclaimAtBootInterval", config_parse_int, - 0, &arg_swap_at_boot_interval }, - { NULL, NULL, NULL, - 0, NULL } - }; - - int r; - - r = config_parse_new(SWAP_CONF_FILE, (void*) items); - if (r < 0) { - _E("Failed to parse configuration file: %d", r); - return r; - } - - if (arg_timer_swap_at_boot < 0) { - _E("The `TimerReclaimAtBoot` field in the `" SWAP_CONF_FILE "` config file cannot be negative because it represents a time period for " EARLYRECLAIM_WITH_AN_EXPLANATION_FOR_LAYMEN); - return -EINVAL; - } - - return 0; -}*/ - static int swap_thread_create(void) { int ret = 0; diff --git a/src/resource-optimizer/memory/swap/zramswap.c b/src/resource-optimizer/memory/swap/zramswap.c index e66b158..a989bee 100644 --- a/src/resource-optimizer/memory/swap/zramswap.c +++ b/src/resource-optimizer/memory/swap/zramswap.c @@ -240,34 +240,6 @@ static int swap_zram_reclaim(void *data) return -ENOSPC; } -/*static int swap_zram_parse_config_file(void) -{ - ConfigTableItem items[] = { - { "ZRAM", "COMP_ALGORITHM", config_parse_string, 0, NULL }, - { "ZRAM", "RATIO", config_parse_float, 0, NULL }, - { NULL, NULL, NULL, 0, NULL } - }; - - int r; - _cleanup_free_ char *algorithm = NULL; - - items[0].data = &algorithm; - items[1].data = &zram_control.ratio; - - r = config_parse_new(SWAP_CONF_FILE, (void*) items); - if (r < 0) { - _E("Failed to parse configuration file: %m"); - return r; - } - - if (algorithm) - strncpy(zram_control.comp_algorithm, algorithm, MAX_TYPE_LENGTH - 1); - - _I("algorithm=%s, ratio=%f", algorithm, zram_control.ratio); - - return 0; -}*/ - static int swap_zram_init(void *data) { struct swap_module_ops *swap = (struct swap_module_ops *)data; @@ -275,12 +247,6 @@ static int swap_zram_init(void *data) if (access(swap->path, R_OK) != 0) return -ENOENT; -/* r = swap_zram_parse_config_file(); - if (r < 0) { - _E("Failed to parse SwapFile config: %m"); - return r; - }*/ - swap->k_size = lowmem_get_ktotalram() * zram_control.ratio; if (zram_control.max_comp_streams < 0) { @@ -310,7 +276,7 @@ static int swap_zram_conf(void *data) if (!is_empty(zram_conf->algorithm)) strncpy(zram_control.comp_algorithm, zram_conf->algorithm, MAX_TYPE_LENGTH - 1); - + if (zram_conf->ratio > 0.0) zram_control.ratio = zram_conf->ratio; diff --git a/src/resource-optimizer/memory/swap/zswap.c b/src/resource-optimizer/memory/swap/zswap.c index 2912160..6af8068 100644 --- a/src/resource-optimizer/memory/swap/zswap.c +++ b/src/resource-optimizer/memory/swap/zswap.c @@ -111,44 +111,6 @@ static int swap_zswap_reclaim(void *data) return -ENOSPC; } -/*static int swap_zswap_parse_config_file(void) -{ - ConfigTableItem items[] = { - { "FILE", "CryptType", config_parse_string, 0, NULL }, - { "FILE", "FileSize", config_parse_bytes, 0, NULL }, - { "ZSWAP", "PoolRatio", config_parse_float, 0, NULL }, - { "ZSWAP", "PoolType", config_parse_string, 0, NULL }, - { NULL, NULL, NULL, 0, NULL } - }; - - int r; - _cleanup_free_ char *crypt_type = NULL; - _cleanup_free_ char *zpool_type = NULL; - - items[0].data = &crypt_type; - items[1].data = &zswap_control.zswap_file_size; - items[2].data = &zswap_control.zpool_ratio; - items[3].data = &zpool_type; - - r = config_parse_new(SWAP_CONF_FILE, (void*) items); - if (r < 0) { - _E("Failed to parse configuration file: %d", r); - return r; - } - - if (check_valid_compressor(crypt_type) == RESOURCED_ERROR_NONE) - strncpy(zswap_control.crypt_type, crypt_type, MAX_TYPE_LENGTH-1); - else - memset(zswap_control.crypt_type, 0, MAX_TYPE_LENGTH); - - if (zpool_type) - strncpy(zswap_control.zpool_type, zpool_type, MAX_TYPE_LENGTH-1); - else - memset(zswap_control.zpool_type, 0, MAX_TYPE_LENGTH); - - return 0; -}*/ - static int swap_zswap_init(void *data) { struct swap_module_ops *swap = (struct swap_module_ops *)data; @@ -156,12 +118,6 @@ static int swap_zswap_init(void *data) if (access(ZSWAP_POOL_PERCENT, R_OK) != 0) return -ENOENT; -/* r = swap_zswap_parse_config_file(); - if (r < 0) { - _E("Failed to parse SwapFile config: %d", r); - return r; - }*/ - swap->k_size = BYTE_TO_KBYTE(zswap_control.zswap_file_size); return 0; } @@ -179,7 +135,7 @@ static int swap_zswap_conf(void *data) if (zswap_conf->filesize > 0) zswap_control.zswap_file_size = zswap_conf->filesize; - + if (zswap_conf->pool_ratio > 0.0) zswap_control.zpool_ratio = zswap_conf->pool_ratio; -- 2.7.4