diff options
38 files changed, 565 insertions, 408 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index 965f189c..1b2cc849 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -40,14 +40,18 @@ SET(VERSION ${FULLVER}) SET(DATA_DIR ${CMAKE_SOURCE_DIR}/data) SET(CMAKELISTS_DIR ${CMAKE_SOURCE_DIR}/CMakeLists) SET(INCLUDE_COMMON_DIR ${CMAKE_SOURCE_DIR}/src/common) +SET(INCLUDE_CGROUP_DIR ${CMAKE_SOURCE_DIR}/src/common/cgroup) SET(INCLUDE_PUBLIC_DIR ${CMAKE_SOURCE_DIR}/include) -SET(RESOURCED_INCLUDEDIR ${INCLUDE_COMMON_DIR} ${INCLUDE_PUBLIC_DIR}) +SET(RESOURCED_INCLUDEDIR ${INCLUDE_COMMON_DIR} ${INCLUDE_CGROUP_DIR} ${INCLUDE_PUBLIC_DIR}) #misc SET(SOURCE_DIR ${CMAKE_SOURCE_DIR}/src) SET(RESOURCED_SOURCE_DIR ${SOURCE_DIR}/resourced) SET(COMMON_SOURCE_DIR ${SOURCE_DIR}/common) +#cgroup +SET(CGROUP_SOURCE_DIR ${COMMON_SOURCE_DIR}/cgroup) + #resource-optimizer source folders SET(RESOURCE_OPTIMIZER_SOURCE_DIR ${SOURCE_DIR}/resource-optimizer) SET(MEMORY_RESOURCE_OPTIMIZER_SOURCE_DIR ${RESOURCE_OPTIMIZER_SOURCE_DIR}/memory) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 9aa8f8d0..4fe2721d 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -44,6 +44,9 @@ SET(RESOURCED_SHARED_SOURCES ${RESOURCED_SHARED_SOURCES} ${FILES}) FILE(GLOB FILES "${COMMON_SOURCE_DIR}/*.c") SET(RESOURCED_SHARED_SOURCES ${RESOURCED_SHARED_SOURCES} ${FILES}) +FILE(GLOB FILES "${CGROUP_SOURCE_DIR}/*.c") +SET(RESOURCED_SHARED_SOURCES ${RESOURCED_SHARED_SOURCES} ${FILES}) + SET(CMAKE_EXTRA_INCLUDE_FILES unistd.h) INCLUDE_DIRECTORIES(${RESOURCED_INCLUDEDIR} @@ -111,7 +114,7 @@ CONFIGURE_FILE(${INCLUDE_COMMON_DIR}/config.h.in ${INCLUDE_COMMON_DIR}/config.h) # resourced internal private API -FILE(GLOB FILES "${INCLUDE_COMMON_DIR}/*.h" "${INCLUDE_PUBLIC_DIR}/*.h" "${PROCESS_SOURCE_DIR}/*.h" "${RESOURCED_SOURCE_DIR}/*.h") +FILE(GLOB FILES "${INCLUDE_COMMON_DIR}/*.h" "${INCLUDE_CGROUP_DIR}/*.h" "${INCLUDE_PUBLIC_DIR}/*.h" "${PROCESS_SOURCE_DIR}/*.h" "${RESOURCED_SOURCE_DIR}/*.h") FOREACH(FILE ${FILES}) SET(RESOURCED_HEADERS ${RESOURCED_HEADERS} ${FILE}) ENDFOREACH() diff --git a/src/common/cgroup-memory-stat-lookup.c b/src/common/cgroup/cgroup-memory-stat-lookup.c index 2301ec2a..3da8a203 100644 --- a/src/common/cgroup-memory-stat-lookup.c +++ b/src/common/cgroup/cgroup-memory-stat-lookup.c @@ -35,7 +35,7 @@ error "gperf generated tables don't work with this execution character set. Plea #include <assert.h> #include <string.h> -#include "cgroup.h" +#include "memory-cgroup.h" struct memory_stat_key { const char* name; diff --git a/src/common/cgroup-memory-stat-lookup.gperf b/src/common/cgroup/cgroup-memory-stat-lookup.gperf index 6522b4b3..40012c48 100644 --- a/src/common/cgroup-memory-stat-lookup.gperf +++ b/src/common/cgroup/cgroup-memory-stat-lookup.gperf @@ -2,7 +2,7 @@ #include <assert.h> #include <string.h> -#include "cgroup.h" +#include "memory-cgroup.h" struct memory_stat_key { const char* name; diff --git a/src/common/cgroup.c b/src/common/cgroup/cgroup.c index 2ea45a3b..16476a6c 100644 --- a/src/common/cgroup.c +++ b/src/common/cgroup/cgroup.c @@ -22,6 +22,7 @@ */ #include "cgroup.h" +#include "memory-cgroup.h" #include "const.h" #include "macro.h" #include "util.h" @@ -62,6 +63,29 @@ static int cgroup_create(const char *cgroup_full_path) } /* + * @desc place tid to tasks file + * @return 0 in case of success, errno value in case of failure + */ +resourced_ret_c cgroup_write_tid_fullpath(const char *cgroup_full_path, + const int tid) +{ + int ret; + + if (tid <= 0) { + _E("try to write empty tid to %s", cgroup_full_path); + return RESOURCED_ERROR_NO_DATA; + } + + ret = cgroup_write_node_uint32(cgroup_full_path, TASK_FILE_NAME, + (u_int32_t)tid); + + ret_value_msg_if(ret < 0, RESOURCED_ERROR_FAIL, + "Failed to place a tid (%d) to cgroup %s : %m", tid, + cgroup_full_path); + return RESOURCED_ERROR_NONE; +} + +/* * @desc place pid to cgroup.procs file * @return 0 in case of success, errno value in case of failure */ @@ -79,7 +103,7 @@ resourced_ret_c cgroup_write_pid_fullpath(const char *cgroup_full_path, (u_int32_t)pid); ret_value_msg_if(ret < 0, RESOURCED_ERROR_FAIL, - "Failed place all pid to cgroup %s : %m", + "Failed to place a pid (%d) to cgroup %s : %m", pid, cgroup_full_path); return RESOURCED_ERROR_NONE; } @@ -88,7 +112,11 @@ resourced_ret_c cgroup_write_pid(const char *cgroup_subsystem, const char *cgroup_name, const int pid) { char buf[MAX_PATH_LENGTH]; - snprintf(buf, sizeof(buf), "%s/%s", cgroup_subsystem, cgroup_name); + int size = snprintf(buf, sizeof(buf), "%s/%s", cgroup_subsystem, cgroup_name); + if(size < 0) { + _E("failed to setup path (%s/%s)", cgroup_subsystem, cgroup_name); + return size; + } return cgroup_write_pid_fullpath(buf, pid); } @@ -163,8 +191,8 @@ int cgroup_make_subdir(const char* parentdir, const char* cgroup_name, bool *alr /* FIXME: do something about this mounting, then replace * `is_exists` with checking for -EEXIST in `create`, * as currently this is both duplication AND a race condition */ - if (!strncmp(parentdir, DEFAULT_CGROUP, sizeof(DEFAULT_CGROUP))) { - ret = mount("tmpfs", DEFAULT_CGROUP, "tmpfs", + if (!strncmp(parentdir, CGROUP_PATH, sizeof(CGROUP_PATH))) { + ret = mount("tmpfs", CGROUP_PATH, "tmpfs", MS_REMOUNT|MS_NOSUID|MS_NOEXEC|MS_NODEV|MS_STRICTATIME, "mode=755"); if (ret < 0) { _E("Fail to RW mount cgroup directory. Can't make %s cgroup", cgroup_name); @@ -178,7 +206,7 @@ int cgroup_make_subdir(const char* parentdir, const char* cgroup_name, bool *alr "Fail to create cgroup %s : err %d", cgroup_name, errno); if (cgroup_remount) { - ret = mount("tmpfs", DEFAULT_CGROUP, "tmpfs", + ret = mount("tmpfs", CGROUP_PATH, "tmpfs", MS_REMOUNT|MS_NOSUID|MS_NOEXEC|MS_NODEV|MS_STRICTATIME|MS_RDONLY, "mode=755"); if (ret < 0) _D("Fail to RO mount"); @@ -202,7 +230,7 @@ int cgroup_set_release_agent(const char *cgroup_subsys, const char *release_agen _cleanup_free_ char *buf = NULL; int r; - r = asprintf(&buf, "%s/%s", DEFAULT_CGROUP, cgroup_subsys); + r = asprintf(&buf, "%s/%s", CGROUP_PATH, cgroup_subsys); if (r < 0) return -ENOMEM; @@ -288,11 +316,11 @@ int cgroup_get_memory_stat(const char *name, struct cgroup_memory_stat **mem_sta int l; int name_len = strlen(name); - if (strneq(name, CGROUP_MEMORY, strlen(CGROUP_MEMORY))) + if (strneq(name, MEMCG_PATH, strlen(MEMCG_PATH))) l = snprintf(p, PATH_MAX, "%s", name); else l = snprintf(p, PATH_MAX, "%s%s%s", - CGROUP_MEMORY, + MEMCG_PATH, name[0] != '/' ? "/" : "", name); @@ -302,7 +330,7 @@ int cgroup_get_memory_stat(const char *name, struct cgroup_memory_stat **mem_sta p[l - 1] != '/' ? "/" : "", memory_stat); } else - snprintf(p, PATH_MAX, "%s/%s", CGROUP_MEMORY, memory_stat); + snprintf(p, PATH_MAX, "%s/%s", MEMCG_PATH, memory_stat); f = fopen(p, "re"); if (!f) @@ -369,7 +397,7 @@ int cgroup_get_pids(const char *name, GArray **pids) assert(pids); assert(!*pids); - if (asprintf(&cg_procs, "%s/cgroup.procs", name) < 0) + if (asprintf(&cg_procs, "%s/%s", name, CGROUP_FILE_NAME) < 0) return -ENOMEM; f = fopen(cg_procs, "r"); diff --git a/src/common/cgroup.h b/src/common/cgroup/cgroup.h index f98fc8fe..7cec0ca4 100644 --- a/src/common/cgroup.h +++ b/src/common/cgroup/cgroup.h @@ -36,8 +36,11 @@ extern "C" { #endif /* __cplusplus */ -#define DEFAULT_CGROUP "/sys/fs/cgroup" -#define CGROUP_MEMORY DEFAULT_CGROUP "/memory" +#define TASK_FILE_NAME "tasks" +#define CGROUP_FILE_NAME "cgroup.procs" + +//#define DEFAULT_CGROUP "/sys/fs/cgroup" +#define CGROUP_PATH "/sys/fs/cgroup" /** * @desc Get one unsigned int32 value from cgroup @@ -107,6 +110,15 @@ int cgroup_make_subdir(const char* parentdir, const char* cgroup_name, bool *alr int cgroup_mount_subsystem(char* source, char* mount_point, char* opts); /** + * @desc write tid into cgroup_subsystem/cgroup_name file, + * @param cgroup_full_path - name in /sys/fs/cgroup/subsystem/ + * @param tid - tid to write to cgroup file + * @return negative value if error + */ +resourced_ret_c cgroup_write_tid_fullpath(const char *cgroup_full_path, + const int tid); + +/** * @desc write pid into cgroup_subsystem/cgroup_name file, * @param cgroup_full_path - name in /sys/fs/cgroup/subsystem/ * @param pid - pid to write to cgroup file @@ -147,58 +159,6 @@ int cgroup_pid_get_path(const char *controller, pid_t pid, char **path); */ int cgroup_get_pids(const char *name, GArray **pids); -enum cgroup_memory_stat_id { - CGROUP_MEMORY_STAT_CACHE = 0, - CGROUP_MEMORY_STAT_RSS, - CGROUP_MEMORY_STAT_RSS_HUGE, - CGROUP_MEMORY_STAT_MAPPED_FILE, - CGROUP_MEMORY_STAT_DIRTY, - CGROUP_MEMORY_STAT_WRITEBACK, - CGROUP_MEMORY_STAT_SWAP, - CGROUP_MEMORY_STAT_PGPGIN, - CGROUP_MEMORY_STAT_PGPGOUT, - CGROUP_MEMORY_STAT_PGFAULT, - CGROUP_MEMORY_STAT_PGMAJFAULT, - CGROUP_MEMORY_STAT_INACTIVE_ANON, - CGROUP_MEMORY_STAT_ACTIVE_ANON, - CGROUP_MEMORY_STAT_INACTIVE_FILE, - CGROUP_MEMORY_STAT_ACTIVE_FILE, - CGROUP_MEMORY_STAT_UNEVICTABLE, - CGROUP_MEMORY_STAT_HIERARCHICAL_MEMORY_LIMIT, - CGROUP_MEMORY_STAT_HIERARCHICAL_MEMSW_LIMIT, - CGROUP_MEMORY_STAT_TOTAL_CACHE, - CGROUP_MEMORY_STAT_TOTAL_RSS, - CGROUP_MEMORY_STAT_TOTAL_RSS_HUGE, - CGROUP_MEMORY_STAT_TOTAL_MAPPED_FILE, - CGROUP_MEMORY_STAT_TOTAL_DIRTY, - CGROUP_MEMORY_STAT_TOTAL_WRITEBACK, - CGROUP_MEMORY_STAT_TOTAL_SWAP, - CGROUP_MEMORY_STAT_TOTAL_PGPGIN, - CGROUP_MEMORY_STAT_TOTAL_PGPGOUT, - CGROUP_MEMORY_STAT_TOTAL_PGFAULT, - CGROUP_MEMORY_STAT_TOTAL_PGMAJFAULT, - CGROUP_MEMORY_STAT_TOTAL_INACTIVE_ANON, - CGROUP_MEMORY_STAT_TOTAL_ACTIVE_ANON, - CGROUP_MEMORY_STAT_TOTAL_INACTIVE_FILE, - CGROUP_MEMORY_STAT_TOTAL_ACTIVE_FILE, - CGROUP_MEMORY_STAT_TOTAL_UNEVICTABLE, - CGROUP_MEMORY_STAT_RECENT_ROTATED_ANON, - CGROUP_MEMORY_STAT_RECENT_ROTATED_FILE, - CGROUP_MEMORY_STAT_RECENT_SCANNED_ANON, - CGROUP_MEMORY_STAT_RECENT_SCANNED_FILE, - CGROUP_MEMORY_STAT_MAX, - CGROUP_MEMORY_STAT_INVALID = -1, -}; - -struct cgroup_memory_stat { - long long value[CGROUP_MEMORY_STAT_MAX]; -}; - -const char *cgroup_memory_stat_id_to_string(enum cgroup_memory_stat_id id); -enum cgroup_memory_stat_id cgroup_memory_stat_string_to_id(const char *str); - -int cgroup_get_memory_stat(const char *name, struct cgroup_memory_stat **mem_stat); - #ifdef __cplusplus } #endif /* __cplusplus */ diff --git a/src/common/cgroup/cpu-cgroup.h b/src/common/cgroup/cpu-cgroup.h new file mode 100644 index 00000000..8b36e34c --- /dev/null +++ b/src/common/cgroup/cpu-cgroup.h @@ -0,0 +1,51 @@ +/* + * resourced + * + * Copyright (c) 2014 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 cpu-cgroup.h + * @desc header file for handling memory cgroups + **/ + +#ifndef __CPU_CGROUP_H__ +#define __CPU_CGROUP_H__ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#define CPUCG_PATH "/sys/fs/cgroup/cpu" +#define CPUCG_BACKGROUND_PATH CPUCG_PATH"/background" +#define CPUCG_QUOTA_PATH CPUCG_PATH"/quota" +#define CPUCG_CONTROL_BANDWIDTH "cpu.cfs_quota_us" +#define CPUCG_CONTROL_FULL_BANDWIDTH "cpu.cfs_period_us" +#define CPUCG_SHARE "cpu.shares" + +/*#define CPU_DEFAULT_CGROUP "/sys/fs/cgroup/cpu" +#define CPU_BACKGROUND_GROUP CPU_DEFAULT_CGROUP"/background" +#define CPU_CPUQUOTA_GROUP CPU_DEFAULT_CGROUP"/quota" +#define CPU_CONTROL_BANDWIDTH "cpu.cfs_quota_us" +#define CPU_CONTROL_FULL_BANDWIDTH "cpu.cfs_period_us" +#define CPU_SHARE "cpu.shares"*/ + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /*__CPU_CGROUP_H__*/ diff --git a/src/common/cgroup/memory-cgroup.h b/src/common/cgroup/memory-cgroup.h new file mode 100644 index 00000000..33032fb7 --- /dev/null +++ b/src/common/cgroup/memory-cgroup.h @@ -0,0 +1,240 @@ +/* + * resourced + * + * Copyright (c) 2014 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 memory-cgroup.h + * @desc header file for handling memory cgroups + **/ + +#ifndef __MEMORY_CGROUP_H__ +#define __MEMORY_CGROUP_H__ + +#include <glib.h> +#include <stdbool.h> +#include "cgroup.h" +#include "const.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/* number of memory cgroups */ +#define MEMCG_DEFAULT_EVENT_LEVEL "low" +#define MEMCG_DEFAULT_USE_HIERARCHY 0 + +#define MEMCG_LOW_RATIO 0.8 +#define MEMCG_MEDIUM_RATIO 0.96 +#define MEMCG_FOREGROUND_LEAVE_RATIO 0.25 + + +#define MEMCG_PATH CGROUP_PATH"/memory" +#define MEMCG_APPS_PATH MEMCG_PATH"/Apps" +#define MEMCG_BGLOCKED_PATH MEMCG_PATH"/Apps/BgLocked" +#define MEMCG_MEMLIMIT_PATH MEMCG_PATH"/MemLimit" +#define MEMCG_SWAP_PATH MEMCG_PATH"/Swap" +/*#define LOWMEM_ROOT_CGROUP "/sys/fs/cgroup/memory" +#define LOWMEM_APPS_CGROUP LOWMEM_ROOT_CGROUP"/Apps" +#define LOWMEM_BGLOCKED_CGROUP LOWMEM_ROOT_CGROUP"/Apps/BgLocked" +#define LOWMEM_MEMLIMIT_CGROUP LOWMEM_ROOT_CGROUP"/MemLimit" +#define LOWMEM_SWAP_CGROUP LOWMEM_ROOT_CGROUP"/Swap"*/ + +//#define MEMCG_OOM_CONTROL_PATH "memory.oom_control" +#define MEMCG_OOM_CONTROL "memory.oom_control" +#define MEMCG_EVENTFD_CONTROL "cgroup.event_control" +#define MEMCG_EVENTFD_MEMORY_PRESSURE "memory.pressure_level" +#define MEMCG_USAGE "memory.usage_in_bytes" +#define MEMCG_SWAP_USAGE "memory.memsw.usage_in_bytes" +#define MEMCG_LIMIT_BYTE "memory.limit_in_bytes" +#define MEMCG_SWAP_LIMIT_BYTE "memory.memsw.limit_in_bytes" +#define MEMCG_SWAPPINESS "memory.swappiness" +#define MEMCG_FORCE_RECLAIM "memory.force_reclaim" +#define MEMCG_MOVE_CHARGE "memory.move_charge_at_immigrate" +//#define MEMCG_LIMIT_PATH "memory.limit_in_bytes" +//#define MEMCG_SWAP_LIMIT_PATH "memory.memsw.limit_in_bytes" +//#define MEMCG_SWAPPINESS_PATH "memory.swappiness" + +#define DEFAULT_MEMLOG_PATH "/var/log" +#define DEFAULT_MEMLOG_NR_MAX 50 + +/* + * [memory cgroup information] + * MEMCG_MEMORY : root cgroup for system daemons + * MEMCG_APPS : cgroup for general apps + * MEMCG_BGLOCKED : cgroup for background locked and favorite apps + * MEMCG_LIMIT : cgroup for each app with memory limit set if configuration is enabled + * MEMCG_SWAP : cgroup for selected victims from background apps + * + * [memory cgroup hierarchy] + (root) + ├─Apps + │ └─BgLocked + ├─MemLimit + ├─Swap + └─system.slice (not controlled by resourced) + */ +enum memcg_type { + MEMCG_ROOT = -1, + MEMCG_MEMORY, + MEMCG_APPS, + MEMCG_BGLOCKED, + MEMCG_LIMIT, + MEMCG_SWAP, + MEMCG_MAX, +}; + +enum { + LOWMEM_NORMAL, + LOWMEM_DEDUP, + LOWMEM_SWAP, + LOWMEM_LOW, + LOWMEM_MEDIUM, + LOWMEM_MAX_LEVEL, +}; + +enum lowmem_control_type { + LOWMEM_MOVE_CGROUP, + LOWMEM_MANAGE_FOREGROUND, +}; + +enum mem_log { + MEMLOG_MEMPS, + MEMLOG_MEMPS_MEMLIMIT, + MEMLOG_MAX, +}; + + +enum cgroup_memory_stat_id { + CGROUP_MEMORY_STAT_CACHE = 0, + CGROUP_MEMORY_STAT_RSS, + CGROUP_MEMORY_STAT_RSS_HUGE, + CGROUP_MEMORY_STAT_MAPPED_FILE, + CGROUP_MEMORY_STAT_DIRTY, + CGROUP_MEMORY_STAT_WRITEBACK, + CGROUP_MEMORY_STAT_SWAP, + CGROUP_MEMORY_STAT_PGPGIN, + CGROUP_MEMORY_STAT_PGPGOUT, + CGROUP_MEMORY_STAT_PGFAULT, + CGROUP_MEMORY_STAT_PGMAJFAULT, + CGROUP_MEMORY_STAT_INACTIVE_ANON, + CGROUP_MEMORY_STAT_ACTIVE_ANON, + CGROUP_MEMORY_STAT_INACTIVE_FILE, + CGROUP_MEMORY_STAT_ACTIVE_FILE, + CGROUP_MEMORY_STAT_UNEVICTABLE, + CGROUP_MEMORY_STAT_HIERARCHICAL_MEMORY_LIMIT, + CGROUP_MEMORY_STAT_HIERARCHICAL_MEMSW_LIMIT, + CGROUP_MEMORY_STAT_TOTAL_CACHE, + CGROUP_MEMORY_STAT_TOTAL_RSS, + CGROUP_MEMORY_STAT_TOTAL_RSS_HUGE, + CGROUP_MEMORY_STAT_TOTAL_MAPPED_FILE, + CGROUP_MEMORY_STAT_TOTAL_DIRTY, + CGROUP_MEMORY_STAT_TOTAL_WRITEBACK, + CGROUP_MEMORY_STAT_TOTAL_SWAP, + CGROUP_MEMORY_STAT_TOTAL_PGPGIN, + CGROUP_MEMORY_STAT_TOTAL_PGPGOUT, + CGROUP_MEMORY_STAT_TOTAL_PGFAULT, + CGROUP_MEMORY_STAT_TOTAL_PGMAJFAULT, + CGROUP_MEMORY_STAT_TOTAL_INACTIVE_ANON, + CGROUP_MEMORY_STAT_TOTAL_ACTIVE_ANON, + CGROUP_MEMORY_STAT_TOTAL_INACTIVE_FILE, + CGROUP_MEMORY_STAT_TOTAL_ACTIVE_FILE, + CGROUP_MEMORY_STAT_TOTAL_UNEVICTABLE, + CGROUP_MEMORY_STAT_RECENT_ROTATED_ANON, + CGROUP_MEMORY_STAT_RECENT_ROTATED_FILE, + CGROUP_MEMORY_STAT_RECENT_SCANNED_ANON, + CGROUP_MEMORY_STAT_RECENT_SCANNED_FILE, + CGROUP_MEMORY_STAT_MAX, + CGROUP_MEMORY_STAT_INVALID = -1, +}; + +struct memcg_info { + /* name of memory cgroup */ + char name[MAX_PATH_LENGTH]; + /* hashname of memory cgroup for restoring memcg info*/ + char hashname[MAX_NAME_LENGTH]; + /* parent id */ + int parent_memcg; + /* limit ratio, if don't want to set limit, use NO_LIMIT*/ + float limit_ratio; + unsigned int limit; + /* leave memory usage */ + unsigned int oomleave; + /* thresholds, normal, swap, low, medium, and leave */ + unsigned int threshold[LOWMEM_MAX_LEVEL]; + unsigned int threshold_leave; + int evfd; + int swappiness; +}; + +struct memcg { + /* parent cgroup */ + struct memcg_info *info; + /* set when using multiple sub cgroups */ + bool use_hierarchy; + /* list of child cgroups when using multi groups */ + GSList *cgroups; +}; + +struct lowmem_control_data { + enum lowmem_control_type control_type; + int args[2]; +}; + +struct cgroup_memory_stat { + long long value[CGROUP_MEMORY_STAT_MAX]; +}; + +void memcg_info_set_limit(struct memcg_info *memcg_info, float ratio, + unsigned int totalram); +void memcg_info_set_swappiness(struct memcg_info *mi, int swappiness); +void memcg_init(struct memcg *memcg); + +/** + * @desc get anon memory usage of cgroup based on memory.stat + * @return 0 if the value was correctly read + */ +int memcg_get_anon_usage(char *memcg, unsigned int *anon_usage); + +/** + * @desc get swapped memory usage of cgroup mi based on memory.stat + * @return 0 if the value was correctly read + */ +int memcg_get_swap_usage(char *memcg, unsigned int *usage); + +/** + * @desc register eventfd to the memory cgroup with desired value + * @return eventfd if it was registered successfully or -1 on failure + */ +int memcg_set_eventfd(const char *memcg, const char *event, char *value); + +/** + * @desc execute /usr/bin/memps and make log file with pid and process name + */ +void make_memps_log(enum mem_log path, pid_t pid, char *victim_name); + + +const char *cgroup_memory_stat_id_to_string(enum cgroup_memory_stat_id id); +enum cgroup_memory_stat_id cgroup_memory_stat_string_to_id(const char *str); + +int cgroup_get_memory_stat(const char *name, struct cgroup_memory_stat **mem_stat); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /*__MEMORY_CGROUP_H__*/ diff --git a/src/common/const.h b/src/common/const.h index 71486178..c89a6e91 100644 --- a/src/common/const.h +++ b/src/common/const.h @@ -25,8 +25,6 @@ #ifndef _RESOURCED_CONST_H #define _RESOURCED_CONST_H -#define TASK_FILE_NAME "/tasks" -#define CGROUP_FILE_NAME "/cgroup.procs" #define MAX_PATH_LENGTH 512 #define MAX_NAME_LENGTH 256 diff --git a/src/common/dedup-common.h b/src/common/dedup-common.h index 60280eac..5a04c5a4 100644 --- a/src/common/dedup-common.h +++ b/src/common/dedup-common.h @@ -27,7 +27,7 @@ #include <stdio.h> #include "resourced.h" -#include "memory-common.h" +#include "memory-cgroup.h" #ifdef __cplusplus extern "C" { diff --git a/src/common/memory-common.h b/src/common/memory-common.h deleted file mode 100644 index 15cf27c1..00000000 --- a/src/common/memory-common.h +++ /dev/null @@ -1,174 +0,0 @@ -/* - * resourced - * - * Copyright (c) 2014 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 memory-common.h - * @desc header file for handling memory cgroups - **/ - -#ifndef __MEMORY_COMMONL_H__ -#define __MEMORY_COMMONL_H__ - -#include <glib.h> -#include <stdbool.h> -#include "const.h" - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -/* - * [memory cgroup information] - * MEMCG_MEMORY : root cgroup for system daemons - * MEMCG_APPS : cgroup for general apps - * MEMCG_BGLOCKED : cgroup for background locked and favorite apps - * MEMCG_LIMIT : cgroup for each app with memory limit set if configuration is enabled - * MEMCG_SWAP : cgroup for selected victims from background apps - * - * [memory cgroup hierarchy] - (root) - ├─Apps - │ └─BgLocked - ├─MemLimit - ├─Swap - └─system.slice (not controlled by resourced) - */ -enum memcg_type { - MEMCG_ROOT = -1, - MEMCG_MEMORY, - MEMCG_APPS, - MEMCG_BGLOCKED, - MEMCG_LIMIT, - MEMCG_SWAP, - MEMCG_MAX, -}; - -enum { - LOWMEM_NORMAL, - LOWMEM_DEDUP, - LOWMEM_SWAP, - LOWMEM_LOW, - LOWMEM_MEDIUM, - LOWMEM_MAX_LEVEL, -}; - -enum lowmem_control_type { - LOWMEM_MOVE_CGROUP, - LOWMEM_MANAGE_FOREGROUND, -}; - -enum mem_log { - MEMLOG_MEMPS, - MEMLOG_MEMPS_MEMLIMIT, - MEMLOG_MAX, -}; - -/* number of memory cgroups */ -#define MEMCG_DEFAULT_EVENT_LEVEL "low" -#define MEMCG_DEFAULT_USE_HIERARCHY 0 - -#define MEMCG_LOW_RATIO 0.8 -#define MEMCG_MEDIUM_RATIO 0.96 -#define MEMCG_FOREGROUND_LEAVE_RATIO 0.25 - - -#define LOWMEM_ROOT_CGROUP "/sys/fs/cgroup/memory" -#define LOWMEM_APPS_CGROUP LOWMEM_ROOT_CGROUP"/Apps" -#define LOWMEM_BGLOCKED_CGROUP LOWMEM_ROOT_CGROUP"/Apps/BgLocked" -#define LOWMEM_MEMLIMIT_CGROUP LOWMEM_ROOT_CGROUP"/MemLimit" -#define LOWMEM_SWAP_CGROUP LOWMEM_ROOT_CGROUP"/Swap" - -#define MEMCG_OOM_CONTROL_PATH "memory.oom_control" -#define MEMCG_EVENTFD_CONTROL "cgroup.event_control" -#define MEMCG_EVENTFD_MEMORY_PRESSURE "memory.pressure_level" -#define MEMCG_USAGE "memory.usage_in_bytes" -#define MEMCG_SWAP_USAGE "memory.memsw.usage_in_bytes" -#define MEMCG_LIMIT_PATH "memory.limit_in_bytes" -#define MEMCG_SWAP_LIMIT_PATH "memory.memsw.limit_in_bytes" -#define MEMCG_SWAPPINESS_PATH "memory.swappiness" - -#define DEFAULT_MEMLOG_PATH "/var/log" -#define DEFAULT_MEMLOG_NR_MAX 50 - -struct memcg_info { - /* name of memory cgroup */ - char name[MAX_PATH_LENGTH]; - /* hashname of memory cgroup for restoring memcg info*/ - char hashname[MAX_NAME_LENGTH]; - /* parent id */ - int parent_memcg; - /* limit ratio, if don't want to set limit, use NO_LIMIT*/ - float limit_ratio; - unsigned int limit; - /* leave memory usage */ - unsigned int oomleave; - /* thresholds, normal, swap, low, medium, and leave */ - unsigned int threshold[LOWMEM_MAX_LEVEL]; - unsigned int threshold_leave; - int evfd; - int swappiness; -}; - -struct memcg { - /* parent cgroup */ - struct memcg_info *info; - /* set when using multiple sub cgroups */ - bool use_hierarchy; - /* list of child cgroups when using multi groups */ - GSList *cgroups; -}; - -struct lowmem_control_data { - enum lowmem_control_type control_type; - int args[2]; -}; - -void memcg_info_set_limit(struct memcg_info *memcg_info, float ratio, - unsigned int totalram); -void memcg_info_set_swappiness(struct memcg_info *mi, int swappiness); -void memcg_init(struct memcg *memcg); - -/** - * @desc get anon memory usage of cgroup based on memory.stat - * @return 0 if the value was correctly read - */ -int memcg_get_anon_usage(char *memcg, unsigned int *anon_usage); - -/** - * @desc get swapped memory usage of cgroup mi based on memory.stat - * @return 0 if the value was correctly read - */ -int memcg_get_swap_usage(char *memcg, unsigned int *usage); - -/** - * @desc register eventfd to the memory cgroup with desired value - * @return eventfd if it was registered successfully or -1 on failure - */ -int memcg_set_eventfd(const char *memcg, const char *event, char *value); - -/** - * @desc execute /usr/bin/memps and make log file with pid and process name - */ -void make_memps_log(enum mem_log path, pid_t pid, char *victim_name); - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /*__MEMORY_COMMONL_H__*/ diff --git a/src/common/proc-common.h b/src/common/proc-common.h index 283379ee..7d9a9647 100644 --- a/src/common/proc-common.h +++ b/src/common/proc-common.h @@ -31,7 +31,7 @@ #include "resourced.h" #include "const.h" -#include "memory-common.h" +#include "memory-cgroup.h" #ifdef __cplusplus extern "C" { diff --git a/src/common/procfs.c b/src/common/procfs.c index 9402910a..6d57624d 100644 --- a/src/common/procfs.c +++ b/src/common/procfs.c @@ -45,7 +45,7 @@ #include "util.h" #include "procfs.h" #include "proc-common.h" -#include "memory-common.h" +#include "memory-cgroup.h" #include "module.h" #include "file-helper.h" #include "swap-common.h" diff --git a/src/common/swap-common.h b/src/common/swap-common.h index 0c28ff7e..73f0c485 100644 --- a/src/common/swap-common.h +++ b/src/common/swap-common.h @@ -27,7 +27,7 @@ #include <stdio.h> #include "resourced.h" -#include "memory-common.h" +#include "memory-cgroup.h" #ifdef __cplusplus extern "C" { diff --git a/src/process/proc-process.c b/src/process/proc-process.c index 3e5583e0..488c9cec 100644 --- a/src/process/proc-process.c +++ b/src/process/proc-process.c @@ -33,7 +33,7 @@ #include "cgroup.h" #include "proc-process.h" #include "procfs.h" -#include "memory-common.h" +#include "memory-cgroup.h" #include "macro.h" #include "notifier.h" #include "proc-appusage.h" diff --git a/src/process/vip/vip-process.c b/src/process/vip/vip-process.c index acda0e3f..9435d989 100644 --- a/src/process/vip/vip-process.c +++ b/src/process/vip/vip-process.c @@ -317,12 +317,13 @@ static int vip_create_sub_cgroup(const char *name, pid_t pid) return -ENOMEM; } - r = cgroup_write_node_uint32(cgroup_name, TASK_FILE_NAME, pid); + cgroup_write_tid_fullpath(cgroup_name, pid); +/* r = cgroup_write_node_uint32(cgroup_name, TASK_FILE_NAME, pid); if (r < 0) { _E("failed to write pid '%d' to '%s': %m", pid, cgroup_name); return r; - } + }*/ _D("PID(%d) is registered as VIP sub cgroup(%s)", pid, name); @@ -463,7 +464,7 @@ static int resourced_vip_process_init(void *data) vip_load_configs(); if (!is_mounted(VIP_CGROUP)) { - r = cgroup_make_subdir(DEFAULT_CGROUP, "vip", NULL); + r = cgroup_make_subdir(CGROUP_PATH, "vip", NULL); if (r < 0) { _E("failed to make vip cgroup"); return RESOURCED_ERROR_FAIL; diff --git a/src/resource-limiter/cpu/cpu-sched.c b/src/resource-limiter/cpu/cpu-sched.c index e6540305..0cf3cdfb 100644 --- a/src/resource-limiter/cpu/cpu-sched.c +++ b/src/resource-limiter/cpu/cpu-sched.c @@ -119,7 +119,7 @@ static int cpu_sched_init_cgroup(struct cpu_sched *cs) _D("cpu-sched: init cgroup subsystem"); if (cpu_sched_is_cpuset_mounted() == false) { - r = cgroup_make_subdir(DEFAULT_CGROUP, "cpuset", NULL); + r = cgroup_make_subdir(CGROUP_PATH, "cpuset", NULL); if (r < 0) { _E("failed to make cpuset cgroup"); return r; @@ -411,7 +411,8 @@ static int cpu_sched_add_pid_to_cpuset(struct coreset *set, pid_t pid) _D("cpu-sched: add pid %d to cpuset %s", pid, set->name); - char path[PATH_MAX]; + cgroup_write_pid(CPUSET_CGROUP, set->name, pid); +/* char path[PATH_MAX]; int r = snprintf(path, sizeof path, "%s/%s", CPUSET_CGROUP, set->name); if (r < 0) { _E("cpu-sched: failed to setup path for cpuset (%s)", set->name); @@ -419,7 +420,7 @@ static int cpu_sched_add_pid_to_cpuset(struct coreset *set, pid_t pid) } r = cgroup_write_node_int32(path, "cgroup.procs", pid); - ret_value_msg_if(r < 0, RESOURCED_ERROR_FAIL, "Failed to attach pid %d to cgroup %s: %m", pid, path); + ret_value_msg_if(r < 0, RESOURCED_ERROR_FAIL, "Failed to attach pid %d to cgroup %s: %m", pid, path);*/ return RESOURCED_ERROR_NONE; } @@ -430,8 +431,9 @@ static int cpu_sched_remove_pid_from_cpuset(struct coreset *set, pid_t pid) _D("cpu-sched: moving pid %d to toplevel cpuset (from %s cpuset)", pid, set->name); - int r = cgroup_write_node_int32(CPUSET_CGROUP, "cgroup.procs", pid); - ret_value_msg_if(r < 0, RESOURCED_ERROR_FAIL, "Failed to attach pid %d to cgroup " CPUSET_CGROUP ": %m", pid); + cgroup_write_pid_fullpath(CPUSET_CGROUP, pid); +/* int r = cgroup_write_node_int32(CPUSET_CGROUP, "cgroup.procs", pid); + ret_value_msg_if(r < 0, RESOURCED_ERROR_FAIL, "Failed to attach pid %d to cgroup " CPUSET_CGROUP ": %m", pid);*/ return RESOURCED_ERROR_NONE; } diff --git a/src/resource-limiter/cpu/cpu.c b/src/resource-limiter/cpu/cpu.c index b7bad098..36c27dd0 100644 --- a/src/resource-limiter/cpu/cpu.c +++ b/src/resource-limiter/cpu/cpu.c @@ -45,13 +45,14 @@ #include "config-parser.h" #include "const.h" #include "file-helper.h" +#include "cpu-cgroup.h" -#define CPU_DEFAULT_CGROUP "/sys/fs/cgroup/cpu" -#define CPU_BACKGROUND_GROUP CPU_DEFAULT_CGROUP"/background" -#define CPU_CPUQUOTA_GROUP CPU_DEFAULT_CGROUP"/quota" -#define CPU_CONTROL_BANDWIDTH "cpu.cfs_quota_us" -#define CPU_CONTROL_FULL_BANDWIDTH "cpu.cfs_period_us" -#define CPU_SHARE "cpu.shares" +/*#define CPUCG_PATH "/sys/fs/cgroup/cpu" +#define CPUCG_BACKGROUND_PATH CPUCG_PATH"/background" +#define CPUCG_QUOTA_PATH CPUCG_PATH"/quota" +#define CPUCG_CONTROL_BANDWIDTH "cpu.cfs_quota_us" +#define CPUCG_CONTROL_FULL_BANDWIDTH "cpu.cfs_period_us" +#define CPU_SHARE "cpu.shares"*/ #define CPU_CONF_FILE RD_CONFIG_FILE(cpu) #define CPU_CONF_SECTION "CONTROL" @@ -121,7 +122,8 @@ static int check_predefined(const pid_t pid) static int cpu_move_cgroup(pid_t pid, char *path) { - return cgroup_write_node_uint32(path, CGROUP_FILE_NAME, pid); + return cgroup_write_pid_fullpath(path, pid); + //return cgroup_write_node_uint32(path, CGROUP_FILE_NAME, pid); } static int cpu_move_cgroup_foreach(pid_t pid, struct proc_app_info *pai, char *path) @@ -130,13 +132,16 @@ static int cpu_move_cgroup_foreach(pid_t pid, struct proc_app_info *pai, char *p pid_t child_pid; if (!pai) - return cgroup_write_node_uint32(path, CGROUP_FILE_NAME, pid); + return cgroup_write_pid_fullpath(path, pid); +// return cgroup_write_node_uint32(path, CGROUP_FILE_NAME, pid); - cgroup_write_node_uint32(path, CGROUP_FILE_NAME, pai->main_pid); + cgroup_write_pid_fullpath(path, pai->main_pid); +// cgroup_write_node_uint32(path, CGROUP_FILE_NAME, pai->main_pid); if (pai->childs) { gslist_for_each_item(iter, pai->childs) { child_pid = GPOINTER_TO_PID(iter->data); - cgroup_write_node_uint32(path, CGROUP_FILE_NAME, child_pid); + cgroup_write_pid_fullpath(path, child_pid); +// cgroup_write_node_uint32(path, CGROUP_FILE_NAME, child_pid); } } return RESOURCED_ERROR_NONE; @@ -152,7 +157,7 @@ static void cpu_check_cpuquota(void) int ret, node = 0; char buf[MAX_PATH_LENGTH]; - snprintf(buf, sizeof(buf), "%s/%s", CPU_DEFAULT_CGROUP, CPU_CONTROL_BANDWIDTH); + snprintf(buf, sizeof(buf), "%s/%s", CPUCG_PATH, CPUCG_CONTROL_BANDWIDTH); ret = fread_int(buf, &node); if (!ret) bCPUQuota = true; @@ -182,7 +187,7 @@ static int load_cpu_config(struct parse_result *result, void *user_data) if (!strncmp(result->name, CPU_CONF_PREDEFINE, strlen(CPU_CONF_PREDEFINE)+1)) { pid = find_pid_from_cmdline(result->value); if (pid > 0) { - cpu_move_cgroup(pid, CPU_BACKGROUND_GROUP); + cpu_move_cgroup(pid, CPUCG_BACKGROUND_PATH); def_list.control[def_list.num].pid = pid; def_list.control[def_list.num++].type = SET_DEFAUT; } else { @@ -191,7 +196,7 @@ static int load_cpu_config(struct parse_result *result, void *user_data) } else if (!strncmp(result->name, CPU_CONF_BOOTING, strlen(CPU_CONF_BOOTING)+1)) { pid = find_pid_from_cmdline(result->value); if (pid > 0) { - cpu_move_cgroup(pid, CPU_BACKGROUND_GROUP); + cpu_move_cgroup(pid, CPUCG_BACKGROUND_PATH); def_list.control[def_list.num].pid = pid; def_list.control[def_list.num++].type = SET_BOOTING; setpriority(PRIO_PROCESS, pid, CPU_BACKGROUND_PRI); @@ -199,7 +204,7 @@ static int load_cpu_config(struct parse_result *result, void *user_data) } else if (!strncmp(result->name, CPU_CONF_WRT, strlen(CPU_CONF_WRT)+1)) { pid = find_pid_from_cmdline(result->value); if (pid > 0) { - cpu_move_cgroup(pid, CPU_BACKGROUND_GROUP); + cpu_move_cgroup(pid, CPUCG_BACKGROUND_PATH); def_list.control[def_list.num].pid = pid; def_list.control[def_list.num++].type = SET_WRT; setpriority(PRIO_PROCESS, pid, CPU_CONTROL_PRI); @@ -214,19 +219,19 @@ static int load_cpu_config(struct parse_result *result, void *user_data) } else if (!strncmp(result->name, "BACKGROUND_CPU_SHARE", strlen("BACKGROUND_CPU_SHARE")+1)) { value = atoi(result->value); if (value) - cgroup_write_node_uint32(CPU_BACKGROUND_GROUP, CPU_SHARE, - get_relative_value(CPU_DEFAULT_CGROUP, CPU_SHARE, value)); + cgroup_write_node_uint32(CPUCG_BACKGROUND_PATH, CPUCG_SHARE, + get_relative_value(CPUCG_PATH, CPUCG_SHARE, value)); } else if (!strncmp(result->name, "QUOTA_CPU_SHARE", strlen("QUOTA_CPU_SHARE")+1)) { value = atoi(result->value); if (value && cpu_quota_enabled()) - cgroup_write_node_uint32(CPU_CPUQUOTA_GROUP, CPU_SHARE, - get_relative_value(CPU_DEFAULT_CGROUP, CPU_SHARE, value)); + cgroup_write_node_uint32(CPUCG_QUOTA_PATH, CPUCG_SHARE, + get_relative_value(CPUCG_PATH, CPUCG_SHARE, value)); } else if (!strncmp(result->name, "QUOTA_MAX_BANDWIDTH", strlen("QUOTA_MAX_BANDWIDTH")+1)) { value = atoi(result->value); if (value && cpu_quota_enabled()) - cgroup_write_node_uint32(CPU_CPUQUOTA_GROUP, CPU_CONTROL_BANDWIDTH, - get_relative_value(CPU_CPUQUOTA_GROUP, - CPU_CONTROL_FULL_BANDWIDTH, value)); + cgroup_write_node_uint32(CPUCG_QUOTA_PATH, CPUCG_CONTROL_BANDWIDTH, + get_relative_value(CPUCG_QUOTA_PATH, + CPUCG_CONTROL_FULL_BANDWIDTH, value)); } return RESOURCED_ERROR_NONE; @@ -244,7 +249,7 @@ static int cpu_service_state(void *data) CHECK_BIT(ps->pai->categories, PROC_BG_MEDIA)) return RESOURCED_ERROR_NONE; - cpu_move_cgroup(ps->pid, CPU_BACKGROUND_GROUP); + cpu_move_cgroup(ps->pid, CPUCG_BACKGROUND_PATH); return RESOURCED_ERROR_NONE; } @@ -256,7 +261,7 @@ static int cpu_widget_state(void *data) _D("widget background: pid = %d, appname = %s", ps->pid, ps->pai->appid); if (CHECK_BIT(ps->pai->flags, PROC_DOWNLOADAPP)) - cpu_move_cgroup(ps->pid, CPU_BACKGROUND_GROUP); + cpu_move_cgroup(ps->pid, CPUCG_BACKGROUND_PATH); return RESOURCED_ERROR_NONE; } @@ -271,7 +276,7 @@ static int cpu_foreground_state(void *data) if (pri == -1 || pri > CPU_DEFAULT_PRI) setpriority(PRIO_PGRP, ps->pid, CPU_DEFAULT_PRI); if (check_predefined(ps->pid) != SET_DEFAUT) - cpu_move_cgroup_foreach(ps->pid, ps->pai, CPU_DEFAULT_CGROUP); + cpu_move_cgroup_foreach(ps->pid, ps->pai, CPUCG_PATH); return RESOURCED_ERROR_NONE; } @@ -282,7 +287,7 @@ static int cpu_background_state(void *data) _D("app background: pid = %d", ps->pid); setpriority(PRIO_PGRP, ps->pid, CPU_BACKGROUND_PRI); - cpu_move_cgroup_foreach(ps->pid, ps->pai, CPU_BACKGROUND_GROUP); + cpu_move_cgroup_foreach(ps->pid, ps->pai, CPUCG_BACKGROUND_PATH); return RESOURCED_ERROR_NONE; } @@ -299,7 +304,7 @@ static int cpu_restrict_state(void *data) return RESOURCED_ERROR_NONE; _D("app suspend: pid = %d, appname = %s", ps->pid, ps->pai->appid); - cpu_move_cgroup_foreach(ps->pid, ps->pai, CPU_CPUQUOTA_GROUP); + cpu_move_cgroup_foreach(ps->pid, ps->pai, CPUCG_QUOTA_PATH); return RESOURCED_ERROR_NONE; } @@ -313,7 +318,7 @@ static int cpu_active_state(void *data) ret = proc_get_oom_score_adj(ps->pid, &oom_score_adj); if (ret || oom_score_adj < OOMADJ_PREVIOUS_DEFAULT) return RESOURCED_ERROR_NONE; - cpu_move_cgroup_foreach(ps->pid, ps->pai, CPU_DEFAULT_CGROUP); + cpu_move_cgroup_foreach(ps->pid, ps->pai, CPUCG_PATH); return RESOURCED_ERROR_NONE; } @@ -328,7 +333,7 @@ static int cpu_prelaunch_state(void *data) if (ps->pai->type & PROC_WEBAPP) { for (i = 0; i < def_list.num; i++) { if (def_list.control[i].type == SET_WRT) { - cpu_move_cgroup(def_list.control[i].pid, CPU_DEFAULT_CGROUP); + cpu_move_cgroup(def_list.control[i].pid, CPUCG_PATH); setpriority(PRIO_PGRP, def_list.control[i].pid, 0); ioprio_set(IOPRIO_WHO_PROCESS, def_list.control[i].pid, IOPRIO_CLASS_BE << IOPRIO_CLASS_SHIFT); return RESOURCED_ERROR_NONE; @@ -344,7 +349,7 @@ static int cpu_system_state(void *data) assert(ps); _D("system service : pid = %d", ps->pid); - cpu_move_cgroup(ps->pid, CPU_BACKGROUND_GROUP); + cpu_move_cgroup(ps->pid, CPUCG_BACKGROUND_PATH); return RESOURCED_ERROR_NONE; } @@ -353,7 +358,7 @@ static int cpu_terminatestart_state(void *data) struct proc_status *ps = (struct proc_status *)data; assert(ps); - cpu_move_cgroup_foreach(ps->pid, ps->pai, CPU_DEFAULT_CGROUP); + cpu_move_cgroup_foreach(ps->pid, ps->pai, CPUCG_PATH); return RESOURCED_ERROR_NONE; } @@ -363,9 +368,9 @@ static int cpu_exclude_state(void *data) if (check_predefined(pe->pid) == SET_DEFAUT) return RESOURCED_ERROR_NONE; if (pe->type == PROC_INCLUDE) - cpu_move_cgroup(pe->pid, CPU_BACKGROUND_GROUP); + cpu_move_cgroup(pe->pid, CPUCG_BACKGROUND_PATH); else - cpu_move_cgroup(pe->pid, CPU_DEFAULT_CGROUP); + cpu_move_cgroup(pe->pid, CPUCG_PATH); return RESOURCED_ERROR_NONE; } @@ -375,12 +380,12 @@ static gboolean cpu_predefined_cb(gpointer data) for (i = 0; i < def_list.num; i++) { if (def_list.control[i].type == SET_LAZY) { - cpu_move_cgroup(def_list.control[i].pid, CPU_BACKGROUND_GROUP); + cpu_move_cgroup(def_list.control[i].pid, CPUCG_BACKGROUND_PATH); } else if (def_list.control[i].type == SET_BOOTING) { - cpu_move_cgroup(def_list.control[i].pid, CPU_DEFAULT_CGROUP); + cpu_move_cgroup(def_list.control[i].pid, CPUCG_PATH); setpriority(PRIO_PROCESS, def_list.control[i].pid, 0); } else if (def_list.control[i].type == SET_WRT) { - cpu_move_cgroup(def_list.control[i].pid, CPU_DEFAULT_CGROUP); + cpu_move_cgroup(def_list.control[i].pid, CPUCG_PATH); setpriority(PRIO_PROCESS, def_list.control[i].pid, 0); ioprio_set(IOPRIO_WHO_PROCESS, def_list.control[i].pid, IOPRIO_CLASS_BE << IOPRIO_CLASS_SHIFT); } @@ -395,11 +400,11 @@ static int resourced_cpu_init(void *data) int ret_code; _D("resourced_cpu_init"); - ret_code = cgroup_make_subdir(CPU_DEFAULT_CGROUP, "background", NULL); + ret_code = cgroup_make_subdir(CPUCG_PATH, "background", NULL); ret_value_msg_if(ret_code < 0, ret_code, "cpu init failed\n"); cpu_check_cpuquota(); if (cpu_quota_enabled()) { - ret_code = cgroup_make_subdir(CPU_DEFAULT_CGROUP, "quota", NULL); + ret_code = cgroup_make_subdir(CPUCG_PATH, "quota", NULL); ret_value_msg_if(ret_code < 0, ret_code, "create service cgroup failed\n"); } config_parse(CPU_CONF_FILE, load_cpu_config, NULL); diff --git a/src/resource-limiter/memory/compaction.c b/src/resource-limiter/memory/compaction.c index 9749d025..1126fe4f 100644 --- a/src/resource-limiter/memory/compaction.c +++ b/src/resource-limiter/memory/compaction.c @@ -32,7 +32,7 @@ #include "config-parser.h" #include "module.h" #include "macro.h" -#include "memory-common.h" +#include "memory-cgroup.h" #include "notifier.h" #include "procfs.h" #include "resourced.h" diff --git a/src/resource-limiter/memory/lowmem-dbus.c b/src/resource-limiter/memory/lowmem-dbus.c index eaedfe87..8f6561fc 100644 --- a/src/resource-limiter/memory/lowmem-dbus.c +++ b/src/resource-limiter/memory/lowmem-dbus.c @@ -30,7 +30,7 @@ #include "dbus-handler.h" #include "resourced.h" #include "macro.h" -#include "memory-common.h" +#include "memory-cgroup.h" #include "procfs.h" #include "util.h" diff --git a/src/resource-limiter/memory/lowmem-handler.h b/src/resource-limiter/memory/lowmem-handler.h index f42106da..6c15d567 100644 --- a/src/resource-limiter/memory/lowmem-handler.h +++ b/src/resource-limiter/memory/lowmem-handler.h @@ -27,7 +27,7 @@ #define __LOWMEM_HANDLER_H__ #include <proc-common.h> -#include <memory-common.h> +#include <memory-cgroup.h> #ifdef __cplusplus extern "C" { diff --git a/src/resource-limiter/memory/lowmem-limit.c b/src/resource-limiter/memory/lowmem-limit.c index a0f70a60..3eb9f4e2 100644 --- a/src/resource-limiter/memory/lowmem-limit.c +++ b/src/resource-limiter/memory/lowmem-limit.c @@ -43,7 +43,7 @@ #include "cgroup.h" #include "const.h" #include "proc-common.h" -#include "memory-common.h" +#include "memory-cgroup.h" #include "util.h" #include "smaps.h" #include "config-parser.h" @@ -221,7 +221,7 @@ static void memlimit_finish_cb(void *data, int ret) * since kernel can find and kill victim on cgroup oom. */ else if (mem_limit == MEM_LIMIT_OOM) - cgroup_write_node_uint32(mlog->cgdir, MEMCG_OOM_CONTROL_PATH, 0); + cgroup_write_node_uint32(mlog->cgdir, MEMCG_OOM_CONTROL, 0); free(mlog->appname); free(mlog->cgdir); @@ -412,9 +412,9 @@ void lowmem_reassign_limit(const char *dir, unsigned int limit) } } - ret = cgroup_read_node_uint32(dir, MEMCG_LIMIT_PATH, &prev); + ret = cgroup_read_node_uint32(dir, MEMCG_LIMIT_BYTE, &prev); if (ret) { - _E("Failed to get %s from %s", MEMCG_LIMIT_PATH, dir); + _E("Failed to get %s from %s", MEMCG_LIMIT_BYTE, dir); return; } @@ -430,13 +430,13 @@ void lowmem_reassign_limit(const char *dir, unsigned int limit) * because almost memcg does't have a limitation about swap usage */ if (prev > limit) { - cgroup_write_node_uint32(dir, MEMCG_LIMIT_PATH, limit); - cgroup_write_node_uint32(dir, MEMCG_SWAP_LIMIT_PATH, limit); + cgroup_write_node_uint32(dir, MEMCG_LIMIT_BYTE, limit); + cgroup_write_node_uint32(dir, MEMCG_SWAP_LIMIT_BYTE, limit); } else if (prev < limit) { - cgroup_write_node_uint32(dir, MEMCG_SWAP_LIMIT_PATH, limit); - cgroup_write_node_uint32(dir, MEMCG_LIMIT_PATH, limit); + cgroup_write_node_uint32(dir, MEMCG_SWAP_LIMIT_BYTE, limit); + cgroup_write_node_uint32(dir, MEMCG_LIMIT_BYTE, limit); } else { - cgroup_write_node_uint32(dir, MEMCG_SWAP_LIMIT_PATH, limit); + cgroup_write_node_uint32(dir, MEMCG_SWAP_LIMIT_BYTE, limit); } return; case MEM_LIMIT_OOM: @@ -447,15 +447,15 @@ void lowmem_reassign_limit(const char *dir, unsigned int limit) * and collect log files about problem situation. * Otherwise, MEM_LIMIT_NONE and MEM_LIMIT_OOM will be same. */ - cgroup_write_node_uint32(dir, MEMCG_OOM_CONTROL_PATH, 1); + cgroup_write_node_uint32(dir, MEMCG_OOM_CONTROL, 1); if (prev > limit) { - cgroup_write_node_uint32(dir, MEMCG_LIMIT_PATH, limit); - cgroup_write_node_uint32(dir, MEMCG_SWAP_LIMIT_PATH, limit); + cgroup_write_node_uint32(dir, MEMCG_LIMIT_BYTE, limit); + cgroup_write_node_uint32(dir, MEMCG_SWAP_LIMIT_BYTE, limit); } else if (prev < limit) { - cgroup_write_node_uint32(dir, MEMCG_SWAP_LIMIT_PATH, limit); - cgroup_write_node_uint32(dir, MEMCG_LIMIT_PATH, limit); + cgroup_write_node_uint32(dir, MEMCG_SWAP_LIMIT_BYTE, limit); + cgroup_write_node_uint32(dir, MEMCG_LIMIT_BYTE, limit); } else { - cgroup_write_node_uint32(dir, MEMCG_SWAP_LIMIT_PATH, limit); + cgroup_write_node_uint32(dir, MEMCG_SWAP_LIMIT_BYTE, limit); } break; case MEM_LIMIT_TRHESHOLD: @@ -464,7 +464,7 @@ void lowmem_reassign_limit(const char *dir, unsigned int limit) * need to set limitation value again for preventing kernel OOM * it is larger than original limitation value */ - cgroup_write_node_uint32(dir, MEMCG_LIMIT_PATH, (limit * 1.2)); + cgroup_write_node_uint32(dir, MEMCG_LIMIT_BYTE, (limit * 1.2)); break; default: return; @@ -510,16 +510,18 @@ int lowmem_limit_move_cgroup(struct proc_app_info *pai) if (!pai->memory.use_mem_limit) return RESOURCED_ERROR_NO_DATA; - ret = asprintf(&path, "%s/%s", LOWMEM_MEMLIMIT_CGROUP, pai->appid); + ret = asprintf(&path, "%s/%s", MEMCG_MEMLIMIT_PATH, pai->appid); if (ret < 0) { _E("not enough memory"); return RESOURCED_ERROR_OUT_OF_MEMORY; } - cgroup_write_node_uint32(path, CGROUP_FILE_NAME, pai->main_pid); + cgroup_write_pid_fullpath(path, pai->main_pid); +// cgroup_write_node_uint32(path, CGROUP_FILE_NAME, pai->main_pid); if (pai->childs) { gslist_for_each_item(iter, pai->childs) - cgroup_write_node_uint32(path, CGROUP_FILE_NAME, - GPOINTER_TO_PID(iter->data)); + cgroup_write_pid_fullpath(path, GPOINTER_TO_PID(iter->data)); +/* cgroup_write_node_uint32(path, CGROUP_FILE_NAME, + GPOINTER_TO_PID(iter->data));*/ } return RESOURCED_ERROR_NONE; } @@ -563,7 +565,7 @@ static int memlimit_config_parse(struct parse_result *result, void *user_data) * if kernel is supported. * one of SIGKILL, SIGTRAP, SIGTERM */ - registerpath = MEMCG_OOM_CONTROL_PATH; + registerpath = MEMCG_OOM_CONTROL; } else { /* * check swap status when resourced registers threshold event. @@ -571,7 +573,7 @@ static int memlimit_config_parse(struct parse_result *result, void *user_data) * resourced registers memory.memsw.usage_in_bytes, * otherwise, register memory.limit_in_bytes. */ - ret = cgroup_read_node_uint32(LOWMEM_ROOT_CGROUP, + ret = cgroup_read_node_uint32(MEMCG_PATH, MEMCG_SWAP_USAGE, &usage); if (ret == RESOURCED_ERROR_NONE) registerpath = MEMCG_SWAP_USAGE; @@ -620,28 +622,32 @@ void lowmem_limit_set(pid_t pid, unsigned int limit) cgpath = appname; } - ret = asprintf(&path, "%s/%s", LOWMEM_MEMLIMIT_CGROUP, cgpath); + ret = asprintf(&path, "%s/%s", MEMCG_MEMLIMIT_PATH, cgpath); if (ret < 0) { _E("not enough memory"); return; } - ret = cgroup_make_subdir(LOWMEM_MEMLIMIT_CGROUP, cgpath, NULL); + ret = cgroup_make_subdir(MEMCG_MEMLIMIT_PATH, cgpath, NULL); if (ret < 0) { _E("Failed to create cgroup subdir '%s/%s'", - LOWMEM_MEMLIMIT_CGROUP, cgpath); + MEMCG_MEMLIMIT_PATH, cgpath); return; } lowmem_reassign_limit(path, MBYTE_TO_BYTE(limit)); - ret = cgroup_write_node_uint32(path, CGROUP_FILE_NAME, pid); + ret = cgroup_write_pid_fullpath(path, pid); if (ret < 0) { - _E("Failed to write pid(%d) to '%s/%s'", pid, path, CGROUP_FILE_NAME); return; } +/* ret = cgroup_write_node_uint32(path, CGROUP_FILE_NAME, pid); + if (ret < 0) { + _E("Failed to write pid(%d) to '%s/%s'", pid, path, CGROUP_FILE_NAME); + return; + }*/ - ret = cgroup_write_node_uint32(path, "memory.move_charge_at_immigrate", 3U); + ret = cgroup_write_node_uint32(path, MEMCG_MOVE_CHARGE, 3U); if (ret < 0) _W("Failed to set immigrate mode for %s (non-crucial, continuing)", path); @@ -656,10 +662,11 @@ void lowmem_limit_set(pid_t pid, unsigned int limit) gslist_for_each_item(iter, pai->childs) { pid_t child = GPOINTER_TO_PID(iter->data); - ret = cgroup_write_node_uint32(path, CGROUP_FILE_NAME, child); + cgroup_write_pid_fullpath(path, child); +/* ret = cgroup_write_node_uint32(path, CGROUP_FILE_NAME, child); if (ret < 0) _E("Failed to write pid(%d) to '%s/%s', ignoring for other children", - child, path, CGROUP_FILE_NAME); + child, path, CGROUP_FILE_NAME);*/ } } diff --git a/src/resource-limiter/memory/lowmem-system.c b/src/resource-limiter/memory/lowmem-system.c index f40b0d73..3cabc47a 100644 --- a/src/resource-limiter/memory/lowmem-system.c +++ b/src/resource-limiter/memory/lowmem-system.c @@ -42,7 +42,7 @@ #include "cgroup.h" #include "const.h" #include "proc-common.h" -#include "memory-common.h" +#include "memory-cgroup.h" #include "util.h" #include "smaps.h" #include "config-parser.h" @@ -74,12 +74,12 @@ static int search_systemd_cgroup(const char *dir) return -errno; } - ret = cgroup_read_node_int32(LOWMEM_ROOT_CGROUP, MEMCG_SWAPPINESS_PATH, + ret = cgroup_read_node_int32(MEMCG_PATH, MEMCG_SWAPPINESS, &rootswappiness); if (ret != RESOURCED_ERROR_NONE) return -errno; - ret = cgroup_read_node_int32(dir, MEMCG_SWAPPINESS_PATH, + ret = cgroup_read_node_int32(dir, MEMCG_SWAPPINESS, &memcgswappiness); if (ret != RESOURCED_ERROR_NONE) return -errno; @@ -87,10 +87,10 @@ static int search_systemd_cgroup(const char *dir) if ((rootswappiness >=0) && (rootswappiness != memcgswappiness)) { changeswappiness = rootswappiness; ret = cgroup_write_node_uint32(dir, - MEMCG_SWAPPINESS_PATH, changeswappiness); + MEMCG_SWAPPINESS, changeswappiness); if (ret != RESOURCED_ERROR_NONE) { _I("failed to write %s %d to %s the", - MEMCG_SWAPPINESS_PATH, changeswappiness, dir); + MEMCG_SWAPPINESS, changeswappiness, dir); return -errno; } } @@ -113,16 +113,16 @@ static int search_systemd_cgroup(const char *dir) if (ret < 0) return -ENOMEM; - ret = cgroup_read_node_uint32(path, MEMCG_LIMIT_PATH, &limit); + ret = cgroup_read_node_uint32(path, MEMCG_LIMIT_BYTE, &limit); if (ret != RESOURCED_ERROR_NONE ||limit <= 0) continue; if (changeswappiness >= 0) { ret = cgroup_write_node_uint32(path, - MEMCG_SWAPPINESS_PATH, changeswappiness); + MEMCG_SWAPPINESS, changeswappiness); if (ret != RESOURCED_ERROR_NONE) _I("failed to write %s %d to %s the", - MEMCG_SWAPPINESS_PATH, changeswappiness, path); + MEMCG_SWAPPINESS, changeswappiness, path); } lowmem_reassign_limit(path, limit); diff --git a/src/resource-limiter/memory/memcontrol.c b/src/resource-limiter/memory/memcontrol.c index 72eb99fd..4e2ae434 100644 --- a/src/resource-limiter/memory/memcontrol.c +++ b/src/resource-limiter/memory/memcontrol.c @@ -36,7 +36,7 @@ #include "resourced.h" #include "trace.h" #include "macro.h" -#include "memory-common.h" +#include "memory-cgroup.h" #include "cgroup.h" #include "module.h" #include "util.h" diff --git a/src/resource-limiter/memory/vmpressure-lowmem-handler.c b/src/resource-limiter/memory/vmpressure-lowmem-handler.c index 36400fdc..5944a77f 100644 --- a/src/resource-limiter/memory/vmpressure-lowmem-handler.c +++ b/src/resource-limiter/memory/vmpressure-lowmem-handler.c @@ -59,7 +59,7 @@ #include "module.h" #include "swap-common.h" #include "cgroup.h" -#include "memory-common.h" +#include "memory-cgroup.h" #include "heart-common.h" #include "proc-main.h" #include "dbus-handler.h" @@ -73,15 +73,15 @@ #define LOWMEM_THRES_INIT 0 #define MEMPS_EXEC_PATH "usr/bin/memps" -#define MEMCG_MOVE_CHARGE_PATH "memory.move_charge_at_immigrate" -#define MEMCG_EVENTFD_MEMORY_PRESSURE "memory.pressure_level" +//#define MEMCG_MOVE_CHARGE_PATH "memory.move_charge_at_immigrate" +//#define MEMCG_EVENTFD_MEMORY_PRESSURE "memory.pressure_level" #define MEM_CONF_FILE RD_CONFIG_FILE(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_BG_RECLAIM_STRING "AfterScreenDim" #define MEM_LOGGING_SECTION "Logging" #define BUF_MAX 1024 @@ -361,11 +361,11 @@ static bool bg_reclaim; static int fragmentation_size; static struct memcg_info gmi[MEMCG_MAX] = { - {LOWMEM_ROOT_CGROUP, "/", MEMCG_ROOT,}, - {LOWMEM_APPS_CGROUP, "Apps", MEMCG_MEMORY,}, - {LOWMEM_BGLOCKED_CGROUP, "Apps/BgLocked", MEMCG_APPS,}, - {LOWMEM_MEMLIMIT_CGROUP, "MemLimit", MEMCG_MEMORY,}, - {LOWMEM_SWAP_CGROUP, "Swap", MEMCG_MEMORY,}, + {MEMCG_PATH, "/", MEMCG_ROOT,}, + {MEMCG_APPS_PATH, "Apps", MEMCG_MEMORY,}, + {MEMCG_BGLOCKED_PATH, "Apps/BgLocked", MEMCG_APPS,}, + {MEMCG_MEMLIMIT_PATH, "MemLimit", MEMCG_MEMORY,}, + {MEMCG_SWAP_PATH, "Swap", MEMCG_MEMORY,}, }; enum memory_level { @@ -708,7 +708,7 @@ static int lowmem_kill_victim(const struct task_info *tsk, else safe_kill(pid, SIGKILL); - _E("we killed, force(%d), %d (%s) score = %d, size: rss = %u, sigterm = %d\n", + _D("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; @@ -1298,7 +1298,8 @@ void lowmem_trigger_swap(pid_t pid, int memcg_idx) mi = memcg_tree[memcg_idx]->info; _D("name : %s, pid : %d", mi->name, pid); - cgroup_write_node_uint32(mi->name, CGROUP_FILE_NAME, pid); + cgroup_write_pid_fullpath(mi->name, pid); + //cgroup_write_node_uint32(mi->name, CGROUP_FILE_NAME, pid); msg.type = memcg_idx; msg.info = mi; resourced_notify(RESOURCED_NOTIFIER_SWAP_START, &msg); @@ -1871,7 +1872,7 @@ static int write_params_memcg_info(struct memcg_info *mi) _I("write memcg param for %s", name); /* enable cgroup move */ ret = cgroup_write_node_uint32(name, - MEMCG_MOVE_CHARGE_PATH, 3); + MEMCG_MOVE_CHARGE, 3); if (ret) return ret; @@ -1887,10 +1888,10 @@ static int write_params_memcg_info(struct memcg_info *mi) if (swappiness >= 0) { ret = cgroup_write_node_uint32(name, - MEMCG_SWAPPINESS_PATH, swappiness); + MEMCG_SWAPPINESS, swappiness); if (ret) _I("failed to write %s %d to %s the", - MEMCG_SWAPPINESS_PATH, swappiness, name); + MEMCG_SWAPPINESS, swappiness, name); } if (mi->limit_ratio == LOWMEM_NO_LIMIT) @@ -1898,7 +1899,7 @@ static int write_params_memcg_info(struct memcg_info *mi) /* write limit_in_bytes */ ret = cgroup_write_node_uint32(name, - MEMCG_LIMIT_PATH, limit); + MEMCG_LIMIT_BYTE, limit); _I("set %s's limit to %u", name, limit); return ret; } @@ -1983,7 +1984,8 @@ static void lowmem_move_memcgroup(int pid, int oom_score_adj) return; } } - cgroup_write_node_uint32(mi->name, CGROUP_FILE_NAME, pid); + cgroup_write_pid_fullpath(mi->name, pid); + //cgroup_write_node_uint32(mi->name, CGROUP_FILE_NAME, pid); proc_set_process_memory_state(pai, memcg_idx, mi, oom_score_adj); /* @@ -2056,7 +2058,7 @@ static int create_memcgs(void) continue; mi = memcg_tree[i]->info; name = mi->hashname; - ret = cgroup_make_subdir(LOWMEM_ROOT_CGROUP, name, NULL); + ret = cgroup_make_subdir(MEMCG_PATH, name, NULL); _D("create memory cgroup for %s, ret = %d", name, ret); } diff --git a/src/resource-optimizer/memory/dedup/.dedup.c.swp b/src/resource-optimizer/memory/dedup/.dedup.c.swp Binary files differnew file mode 100644 index 00000000..3cfa9a4e --- /dev/null +++ b/src/resource-optimizer/memory/dedup/.dedup.c.swp diff --git a/src/resource-optimizer/memory/dedup/dedup.c b/src/resource-optimizer/memory/dedup/dedup.c index 76134731..ebd23634 100644 --- a/src/resource-optimizer/memory/dedup/dedup.c +++ b/src/resource-optimizer/memory/dedup/dedup.c @@ -32,7 +32,7 @@ #include <sys/sysinfo.h> #include <sys/time.h> #include <sys/resource.h> -#include <memory-common.h> +#include <memory-cgroup.h> #include <linux/loop.h> #include <fcntl.h> #include <string.h> diff --git a/src/resource-optimizer/memory/swap/fileswap.c b/src/resource-optimizer/memory/swap/fileswap.c index 9f3f6421..2f783c91 100644 --- a/src/resource-optimizer/memory/swap/fileswap.c +++ b/src/resource-optimizer/memory/swap/fileswap.c @@ -24,7 +24,7 @@ #include "file-helper.h" #include "procfs.h" #include "swap-common.h" -#include "memory-common.h" +#include "memory-cgroup.h" #include "config-parser.h" #include "lowmem-handler.h" #include "losetup.h" diff --git a/src/resource-optimizer/memory/swap/swap.c b/src/resource-optimizer/memory/swap/swap.c index 87d67de0..e421f433 100644 --- a/src/resource-optimizer/memory/swap/swap.c +++ b/src/resource-optimizer/memory/swap/swap.c @@ -32,7 +32,7 @@ #include <sys/sysinfo.h> #include <sys/time.h> #include <sys/resource.h> -#include <memory-common.h> +#include <memory-cgroup.h> #include <sys/swap.h> #include <linux/loop.h> #include <fcntl.h> @@ -55,21 +55,21 @@ #include "losetup.h" #include "init.h" -#define MEMCG_PATH "/sys/fs/cgroup/memory/" +/*#define MEMCG_PATH "/sys/fs/cgroup/memory/" #define MEMCG_SIZE_LIMIT "memory.limit_in_bytes" -#define SWAPCG_RECLAIM "memory.force_reclaim" -#define MOVE_CHARGE "memory.move_charge_at_immigrate" - -#define SWAP_PRIORITY 20 -#define SWAP_HARD_LIMIT_DEFAULT 0.5 -#define SWAP_FORCE_RECLAIM_NUM_MAX 5 -#define SWAP_RECLAIM_PAGES_MAX 2560 -#define SWAP_RECLAIM_PAGES_MIN 128 -#define SWAP_MEMCG_SWAPPINESS 60 -#define SWAP_MIN_SWAPPINESS 0 -#define SWAP_EARLYRECLAIM_TIME_DEFAULT 60 -#define SWAP_EARLYRECLAIM_INTERVAL 1 -#define SWAP_EARLYRECLAIM_MAXTRY 2 +#define MEMCG_FORCE_RECLAIM "memory.force_reclaim" +#define MEMCG_MOVE_CHARGE "memory.move_charge_at_immigrate"*/ + +#define SWAP_PRIORITY 20 +#define SWAP_HARD_LIMIT_DEFAULT 0.5 +#define SWAP_FORCE_RECLAIM_NUM_MAX 5 +#define SWAP_RECLAIM_PAGES_MAX 2560 +#define SWAP_RECLAIM_PAGES_MIN 128 +#define SWAP_MEMCG_SWAPPINESS 60 +#define SWAP_MIN_SWAPPINESS 0 +#define SWAP_EARLYRECLAIM_TIME_DEFAULT 60 +#define SWAP_EARLYRECLAIM_INTERVAL 1 +#define SWAP_EARLYRECLAIM_MAXTRY 2 #define SWAP_EARLYRECLAIM_THRESHOLD_DEFAULT MBYTE_TO_BYTE(1024) #define EARLYRECLAIM_WITH_AN_EXPLANATION_FOR_LAYMEN "early memory reclaim (done to retrieve resources used by daemons during system start-up)" @@ -130,6 +130,7 @@ static int swap_sort_func(const struct swap_module_ops *a, void swap_add(const struct swap_module_ops *ops) { + _I("Swap module name: %s", ops->name); swap_module = g_slist_insert_sorted(swap_module, (gpointer)ops, (GCompareFunc) swap_sort_func); @@ -317,10 +318,10 @@ 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 = cgroup_write_node_uint32(memcg, MEMCG_SIZE_LIMIT, memcg_limit); + ret = cgroup_write_node_uint32(memcg, MEMCG_LIMIT_BYTE, memcg_limit); else /* If the group is empty don't set the limit to enable adding processes. */ - ret = cgroup_write_node_int32(memcg, MEMCG_SIZE_LIMIT, -1); + ret = cgroup_write_node_int32(memcg, MEMCG_LIMIT_BYTE, -1); if (ret != RESOURCED_ERROR_NONE) _E("Not able to set hard limit of %s memory cgroup", memcg); @@ -337,14 +338,14 @@ static int swap_use_force_reclaim(char *memcg) bool root_memcg = false; /* - * In case of LOWMEM_ROOT_CGROUP, + * In case of MEMCG_PATH, * it is no necessary to check anon usage of memcg * because it doesn't include all memory usage. * But instead, try to swap memory as much as possible. * It will be happend only once after booting done. */ len = strlen(memcg); - if (!strncmp(memcg, LOWMEM_ROOT_CGROUP, len)) + if (!strncmp(memcg, MEMCG_PATH, len)) root_memcg = true; do { @@ -370,7 +371,7 @@ static int swap_use_force_reclaim(char *memcg) nr_to_reclaim = SWAP_RECLAIM_PAGES_MAX; total_reclaim += nr_to_reclaim; - ret = cgroup_write_node_uint32(memcg, SWAPCG_RECLAIM, + ret = cgroup_write_node_uint32(memcg, MEMCG_FORCE_RECLAIM, nr_to_reclaim); if (ret != RESOURCED_ERROR_NONE) break; /* if we can't reclaim don't continue */ @@ -387,7 +388,7 @@ static int swap_start_reclaim(char *memcg) int r; int swappiness; - r = cgroup_read_node_int32(memcg, MEMCG_SWAPPINESS_PATH, + r = cgroup_read_node_int32(memcg, MEMCG_SWAPPINESS, &swappiness); if (r) return r; @@ -401,10 +402,10 @@ static int swap_start_reclaim(char *memcg) */ if (swappiness != SWAP_MEMCG_SWAPPINESS) { r = cgroup_write_node_uint32(memcg, - MEMCG_SWAPPINESS_PATH, SWAP_MEMCG_SWAPPINESS); + MEMCG_SWAPPINESS, SWAP_MEMCG_SWAPPINESS); if (r) { _I("failed to write %s %d to %s the", - MEMCG_SWAPPINESS_PATH, SWAP_MEMCG_SWAPPINESS, memcg); + MEMCG_SWAPPINESS, SWAP_MEMCG_SWAPPINESS, memcg); return -errno; } } @@ -418,10 +419,10 @@ static int swap_start_reclaim(char *memcg) */ if (current_swappiness != SWAP_MEMCG_SWAPPINESS) { r = cgroup_write_node_uint32(memcg, - MEMCG_SWAPPINESS_PATH, current_swappiness); + MEMCG_SWAPPINESS, current_swappiness); if (r) { _I("failed to write %s %d to %s the", - MEMCG_SWAPPINESS_PATH, SWAP_MEMCG_SWAPPINESS, memcg); + MEMCG_SWAPPINESS, SWAP_MEMCG_SWAPPINESS, memcg); return -errno; } } @@ -464,12 +465,12 @@ static int swap_reclaim_memcg(struct swap_status_msg msg) * swap will be blocked with minimum swappiness. */ r = cgroup_read_node_int32(info->name, - MEMCG_SWAPPINESS_PATH, ¤t_swappiness); + MEMCG_SWAPPINESS, ¤t_swappiness); if (r) return r; r = cgroup_write_node_uint32(info->name, - MEMCG_SWAPPINESS_PATH, SWAP_MIN_SWAPPINESS); + MEMCG_SWAPPINESS, SWAP_MIN_SWAPPINESS); } return r; } @@ -652,8 +653,8 @@ static void swap_activate_in_module(void) struct swap_module_ops *swaps; static bool early_reclaim; - r = cgroup_read_node_int32(LOWMEM_ROOT_CGROUP, - MEMCG_SWAPPINESS_PATH, ¤t_swappiness); + r = cgroup_read_node_int32(MEMCG_PATH, + MEMCG_SWAPPINESS, ¤t_swappiness); if (r) return; @@ -702,16 +703,16 @@ static void swap_activate_in_module(void) int try = arg_swap_at_boot_maxtry; unsigned int usage, prev_usage = 0; - r = cgroup_read_node_uint32(LOWMEM_ROOT_CGROUP, + r = cgroup_read_node_uint32(MEMCG_PATH, MEMCG_SWAP_USAGE, &prev_usage); if (r) prev_usage = UINT_MAX; for (;;) { try--; - swap_start_reclaim(LOWMEM_ROOT_CGROUP); + swap_start_reclaim(MEMCG_PATH); - r = cgroup_read_node_uint32(LOWMEM_ROOT_CGROUP, + r = cgroup_read_node_uint32(MEMCG_PATH, MEMCG_SWAP_USAGE, &usage); if (r) { _E("Early reclaimed is aborted"); @@ -919,7 +920,7 @@ static int swap_cgroup_reset_limit(void *data) return RESOURCED_ERROR_NONE; limit = -1; - ret = cgroup_write_node_int32(msg->info->name, MEMCG_SIZE_LIMIT, limit); + ret = cgroup_write_node_int32(msg->info->name, MEMCG_LIMIT_BYTE, limit); if (ret != RESOURCED_ERROR_NONE) _E("Failed to change hard limit of %s cgroup to -1", msg->info->name); else @@ -1140,7 +1141,7 @@ static int resourced_swap_check_runtime_support(void *data) /* * Check whether kernel is supporting MEMCG_SWAP. */ - r = cgroup_read_node_uint32(LOWMEM_ROOT_CGROUP, + r = cgroup_read_node_uint32(MEMCG_PATH, MEMCG_SWAP_USAGE, &usage); if (r) return -ENOENT; @@ -1189,15 +1190,15 @@ static void resourced_swap_change_memcg_settings(enum memcg_type type) if (ret != RESOURCED_ERROR_NONE) return; - cgroup_write_node_uint32(memcg_swap->info->name, MOVE_CHARGE, 1); - snprintf(buf, sizeof(buf), "%s/%s", MEMCG_PATH, SWAPCG_RECLAIM); + cgroup_write_node_uint32(memcg_swap->info->name, MEMCG_MOVE_CHARGE, 1); + snprintf(buf, sizeof(buf), "%s/%s", MEMCG_PATH, MEMCG_FORCE_RECLAIM); ret = swap_check_node(buf); if (ret == RESOURCED_ERROR_NONE) { swap_node = SWAP_NODE_FORCE_RECLAIM; - _I("use %s node for swapping memory", SWAPCG_RECLAIM); + _I("use %s node for swapping memory", MEMCG_FORCE_RECLAIM); } else { swap_node = SWAP_NODE_HARD_LIMIT; - _I("use %s node for swapping memory", MEMCG_SIZE_LIMIT); + _I("use %s node for swapping memory", MEMCG_LIMIT_BYTE); } } diff --git a/src/resource-optimizer/memory/swap/zramswap.c b/src/resource-optimizer/memory/swap/zramswap.c index e179713a..7fb188c5 100644 --- a/src/resource-optimizer/memory/swap/zramswap.c +++ b/src/resource-optimizer/memory/swap/zramswap.c @@ -24,7 +24,7 @@ #include "file-helper.h" #include "procfs.h" #include "swap-common.h" -#include "memory-common.h" +#include "memory-cgroup.h" #include "config-parser.h" #include "lowmem-handler.h" @@ -226,7 +226,7 @@ static int swap_zram_reclaim(void *data) if (!swap_total) swap_total = proc_get_swap_total(); - r = memcg_get_swap_usage(LOWMEM_SWAP_CGROUP, &swap_usage); + r = memcg_get_swap_usage(MEMCG_SWAP_PATH, &swap_usage); if (r) return r; swapcg_usage_ratio = (float)(swap_usage / (swap_total - swap_available) *100); diff --git a/src/resource-optimizer/memory/swap/zswap.c b/src/resource-optimizer/memory/swap/zswap.c index daf183da..bae4dabb 100644 --- a/src/resource-optimizer/memory/swap/zswap.c +++ b/src/resource-optimizer/memory/swap/zswap.c @@ -24,7 +24,7 @@ #include "file-helper.h" #include "procfs.h" #include "swap-common.h" -#include "memory-common.h" +#include "memory-cgroup.h" #include "config-parser.h" #include "lowmem-handler.h" #include "losetup.h" diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 7e103b47..c7394c3a 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -38,7 +38,9 @@ SET(CMAKE_LDFLAGS_RELEASE "") SET(UNIT_TESTS_CFLAGS "-O0 -D_UNIT_TEST -D_GNU_SOURCE ${GLIB2_CFLAGS}") SET(UNIT_TESTS_CFLAGS "${UNIT_TESTS_CFLAGS} -I${COMMON_SOURCE_DIR}") +SET(UNIT_TESTS_CFLAGS "${UNIT_TESTS_CFLAGS} -I${CGROUP_SOURCE_DIR}") SET(UNIT_TESTS_CFLAGS "${UNIT_TESTS_CFLAGS} -I${INCLUDE_COMMON_DIR}") +SET(UNIT_TESTS_CFLAGS "${UNIT_TESTS_CFLAGS} -I${INCLUDE_CGROUP_DIR}") SET(UNIT_TESTS_CFLAGS "${UNIT_TESTS_CFLAGS} -I${INCLUDE_PUBLIC_DIR}") SET(UNIT_TESTS_CFLAGS "${UNIT_TESTS_CFLAGS} -I${BLOCK_SOURCE_DIR}") SET(UNIT_TESTS_CFLAGS "${UNIT_TESTS_CFLAGS} -I${FREEZER_SOURCE_DIR}") @@ -116,10 +118,12 @@ function(ADD_MEMORY_TESTS name libs wraps sources) PRIVATE RD_CONFIG_PATH="." SYSTEM_LIB_PATH="/usr/lib" SWAP_SUPPORT RD_SYS_DB="." RD_SYS_DATA="." _UNIT_TEST) TARGET_INCLUDE_DIRECTORIES(${name} PRIVATE ${COMMON_SOURCE_DIR} + PRIVATE ${CGROUP_SOURCE_DIR} ../include ../src/resource-limiter/memory ../src/resourced ../src/common + ../src/common/cgroup PUBLIC ${RESOURCED_REQUIRE_PKGS_INCLUDE_DIRS}) TARGET_LINK_LIBRARIES(${name} cmocka pthread dl m gcov dlog ${libs}) ADD_TEST(${name} ${name}) diff --git a/tests/lowmem-dbus-test.cpp b/tests/lowmem-dbus-test.cpp index 70a190cf..2d0e2e80 100644 --- a/tests/lowmem-dbus-test.cpp +++ b/tests/lowmem-dbus-test.cpp @@ -21,7 +21,7 @@ #include "cmocka-wrap.hpp" #include "lowmem-handler.h" -#include "memory-common.h" +#include "memory-cgroup.h" #include "procfs.h" #include <limits> diff --git a/tests/lowmem-limit-env.cpp b/tests/lowmem-limit-env.cpp index e8580cec..070247d1 100644 --- a/tests/lowmem-limit-env.cpp +++ b/tests/lowmem-limit-env.cpp @@ -292,7 +292,7 @@ int LowmemLimitEnv::cgroup_write_node_uint32(const char *cgroup_name, const char const std::string fname = file_name; - if (fname == "/cgroup.procs") { + if (fname == "cgroup.procs") { cgroup_memory[std::string(cgroup_name)].pids.push_back(value); } else { cgroup_memory[std::string(cgroup_name)].files[fname] = std::to_string(value); @@ -300,6 +300,16 @@ int LowmemLimitEnv::cgroup_write_node_uint32(const char *cgroup_name, const char return 0; } +resourced_ret_c LowmemLimitEnv::cgroup_write_pid_fullpath(const char *cgroup_full_path, const int pid) +{ + std::cerr << " cgroup_full_path=" << cgroup_full_path << ", pid=" << pid << std::endl; + check_expected(cgroup_full_path); + check_expected(pid); + + cgroup_memory[std::string(cgroup_full_path)].pids.push_back(pid); + return RESOURCED_ERROR_NONE; +} + int LowmemLimitEnv::cgroup_read_node_uint32(const char *cgroup_name, const char *file_name, uint32_t *value) { std::cerr << " cgroup_name=" << cgroup_name << ", file_name=" << file_name << std::endl; @@ -350,7 +360,7 @@ int LowmemLimitEnv::cgroup_make_subdir(const char* parentdir, const char* cgroup {"memory.oom_control", "0"}, {"memory.memsw.limit_in_bytes", "0"}, {"memory.limit_in_bytes", "0"}, - {"/cgroup.procs", ""}, + {"cgroup.procs", ""}, {"memory.usage_in_bytes", "0"}, {"memory.memsw.usage_in_bytes", "0"} }}; diff --git a/tests/lowmem-limit-env.hpp b/tests/lowmem-limit-env.hpp index 8c345572..60d9c38c 100644 --- a/tests/lowmem-limit-env.hpp +++ b/tests/lowmem-limit-env.hpp @@ -27,7 +27,7 @@ #include "config-parser.h" #include "fd-handler.h" #include "proc-common.h" -#include "memory-common.h" +#include "memory-cgroup.h" #include "resourced.h" #include "resourced-helper-worker.h" @@ -111,6 +111,9 @@ public: void make_memps_log(enum mem_log path, pid_t pid, char *victim_name); + resourced_ret_c cgroup_write_pid_fullpath(const char *cgroup_full_path, + const int pid); + int cgroup_get_pids(const char *name, GArray **pids); int cgroup_write_node_uint32(const char *cgroup_name, const char *file_name, uint32_t value); int cgroup_read_node_uint32(const char *cgroup_name, const char *file_name, uint32_t *value); diff --git a/tests/lowmem-limit-mock.cpp b/tests/lowmem-limit-mock.cpp index e03d1b0f..d248c952 100644 --- a/tests/lowmem-limit-mock.cpp +++ b/tests/lowmem-limit-mock.cpp @@ -39,6 +39,9 @@ MOCK_LIMIT(proc_app_info *, find_app_info, (const pid_t pid), (pid)) MOCK_LIMIT(int, exec_cmd, (int argc, const char *argv[]), (argc, argv)) MOCK_LIMIT(void, make_memps_log, (enum mem_log path, pid_t pid, char *victim_name), (path, pid, victim_name)) +MOCK_LIMIT(resourced_ret_c, cgroup_write_pid_fullpath, + (const char *cgroup_full_path, const int pid), + (cgroup_full_path, pid)) MOCK_LIMIT(int, cgroup_get_pids, (const char *name, GArray **pids), (name, pids)) MOCK_LIMIT(int, cgroup_write_node_uint32, (const char *cgroup_name, const char *file_name, uint32_t value), diff --git a/tests/lowmem-limit-test.cpp b/tests/lowmem-limit-test.cpp index a4eade99..ab08a398 100644 --- a/tests/lowmem-limit-test.cpp +++ b/tests/lowmem-limit-test.cpp @@ -29,6 +29,13 @@ #include "lowmem-limit-env.hpp" +void expect_cgroup_write_pid_fullpath(const char *cgroup_full_path, const int pid) +{ + std::cerr << "expecting cgroup: " << cgroup_full_path << " " << " pid: " << pid << std::endl; + expect_string(cgroup_write_pid_fullpath, cgroup_full_path, cgroup_full_path); + expect_value(cgroup_write_pid_fullpath, pid, pid); +} + void expect_cgroup_write_uint32(const char *cgroup_name, const char *file_name, uint32_t val) { std::cerr << "expecting cgroup write: " << cgroup_name << " " << file_name << " " << val << std::endl; @@ -89,11 +96,13 @@ void app_test_prepare( } else { expect_cgroup_write_uint32(cg_name, "memory.limit_in_bytes", MEM_LIMIT*1.2); // increased by resourced } - expect_cgroup_write_uint32(cg_name, "/cgroup.procs", APP_PID); +// expect_cgroup_write_uint32(cg_name, "cgroup.procs", APP_PID); + expect_cgroup_write_pid_fullpath(cg_name, APP_PID); expect_cgroup_write_uint32(cg_name, "memory.move_charge_at_immigrate", 3U); for (const auto &u: usages) { if (u.first != APP_PID) - expect_cgroup_write_uint32(cg_name, "/cgroup.procs", u.first); + expect_cgroup_write_pid_fullpath(cg_name, u.first); + //expect_cgroup_write_uint32(cg_name, "cgroup.procs", u.first); } test_lowmem_limit_env.event_service_launch(APP_PID); diff --git a/tests/lowmem-system-test.cpp b/tests/lowmem-system-test.cpp index 7d434c47..18ad1133 100644 --- a/tests/lowmem-system-test.cpp +++ b/tests/lowmem-system-test.cpp @@ -21,7 +21,7 @@ #include "cmocka-wrap.hpp" #include "lowmem-handler.h" -#include "memory-common.h" +#include "memory-cgroup.h" #include <vector> @@ -72,11 +72,11 @@ void expect_cgroup_write_node_uint32(const char *cgroup_name, const char *file_n void mock_search_systemd_cgroup(const char *dir, int32_t root_swappiness, int32_t dir_swappiness, const Subdirs &subdirs = Subdirs()) { - mock_cgroup_read_node_int32(LOWMEM_ROOT_CGROUP, MEMCG_SWAPPINESS_PATH, root_swappiness); - mock_cgroup_read_node_int32(dir, MEMCG_SWAPPINESS_PATH, dir_swappiness); + mock_cgroup_read_node_int32(MEMCG_PATH, MEMCG_SWAPPINESS, root_swappiness); + mock_cgroup_read_node_int32(dir, MEMCG_SWAPPINESS, dir_swappiness); if (root_swappiness >= 0 && root_swappiness != dir_swappiness) { - expect_cgroup_write_node_uint32(dir, MEMCG_SWAPPINESS_PATH, root_swappiness); + expect_cgroup_write_node_uint32(dir, MEMCG_SWAPPINESS, root_swappiness); } // subdirs @@ -85,9 +85,9 @@ void mock_search_systemd_cgroup(const char *dir, int32_t root_swappiness, int32_ // mock subdir will_return(readdir, subdir.get_subdir()); - mock_cgroup_read_node_uint32(subdir.get_subdir_full(), MEMCG_LIMIT_PATH, subdir.get_limit()); + mock_cgroup_read_node_uint32(subdir.get_subdir_full(), MEMCG_LIMIT_BYTE, subdir.get_limit()); if (subdir.get_limit() > 0) { - expect_cgroup_write_node_uint32(subdir.get_subdir_full(), MEMCG_SWAPPINESS_PATH, root_swappiness); + expect_cgroup_write_node_uint32(subdir.get_subdir_full(), MEMCG_SWAPPINESS, root_swappiness); expect_string(lowmem_reassign_limit, dir, subdir.get_subdir_full()); expect_value(lowmem_reassign_limit, limit, subdir.get_limit()); |