CompactionEnable=1
FragLevel=800
+[CpuSched]
+CpuSchedFeature=rt_runtime_share,rt_runtime_greed
+CpuRTRunTime=950ms
+CpuRTPeriod=1000ms
+
[CpuAffinity]
ForegroundApps=1,2,4-6
#include "swap-common.h"
#include "dedup-common.h"
#include "compact-common.h"
+#include "cpu-sched-common.h"
#define MAX_SECTION 64
#define CPU_INIT_PRIO 100
+static int config_parse_swap_types(
+ const char *rvalue,
+ void *data)
+{
+ enum swap_type *type = data;
+ char *word, *state;
+ size_t l;
+
+ if (is_empty(rvalue))
+ return 0;
+
+ *type = 0;
+
+ FOREACH_WORD_SEPARATOR(word, l, rvalue, "+|", state) {
+ if (strneq(word, "zram", l))
+ *type |= SWAP_TYPE_ZRAM;
+ else if (strneq(word, "file", l))
+ *type |= SWAP_TYPE_FILE;
+ else if (strneq(word, "zswap", l))
+ *type |= SWAP_TYPE_ZSWAP;
+ else
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int config_parse_cpu_sched_features(const char *value)
+{
+ int cpu_sched_type = CPU_SCHED_UNINITIALIZED;
+ char *word, *state;
+ size_t l;
+
+ if (is_empty(value))
+ return cpu_sched_type;
+
+ FOREACH_WORD_SEPARATOR(word, l, value, ",", state) {
+ if (strneq(word, RT_RUNTIME_SHARE, l))
+ cpu_sched_type |= CPU_SCHED_RUNTIME_SHARE;
+ else if (strneq(word, NO_RT_RUNTIME_SHARE, l))
+ cpu_sched_type |= CPU_SCHED_NO_RUNTIME_SHARE;
+ else if (strneq(word, RT_RUNTIME_GREED, l))
+ cpu_sched_type |= CPU_SCHED_RUNTIME_GREED;
+ else
+ return CPU_SCHED_UNINITIALIZED;
+ }
+
+ return cpu_sched_type;
+}
+
+static int config_parse_time_us(const char *value)
+{
+ char size;
+ char *ptr = strchr(value, 's');
+ if (ptr == NULL) {
+ _E("[DEBUG] Cannot find 's' in the string (%s)", value);
+ return 0;
+ }
+
+ if (value > (ptr - 1)) {
+ _E("[DEBUG] Size of string should be larger than 1");
+ return 0;
+ }
+
+ size = *(ptr - 1);
+ *(ptr - 1) = '\0';
+
+ if (size == ' ') {
+ return atoi(value) * 1000 * 1000;
+ }
+ else if (size == 'm') {
+ return atoi(value) * 1000;
+ }
+ else if (size == 'u') {
+ return atoi(value);
+ }
+ else {
+ _E("[DEBUG] Unknown unit of time");
+ return 0;
+ }
+}
+
static int optimizer_config(struct parse_result *result, void *user_data)
{
if (!result)
return RESOURCED_ERROR_FAIL;
}
+ struct cpu_sched_conf *cpu_sched_conf = get_cpu_sched_conf();
+ if (cpu_sched_conf == NULL) {
+ _E("[DEBUG] cpu_sched configuration is NULL");
+ return RESOURCED_ERROR_FAIL;
+ }
+
if (!strncmp(result->section, SWAP_SECTION, strlen(SWAP_SECTION)+1)) {
if (!strncmp(result->name, SWAP_ENABLE_CONF, strlen(SWAP_ENABLE_CONF)+1)) {
if (!strncmp(result->value, "yes", 4) ||
}
else if (!strncmp(result->name, SWAP_TYPE_CONF,
strlen(SWAP_TYPE_CONF)+1)) {
- if (strlen(result->value) + 1 > sizeof(swap_conf->type)) {
+ if (config_parse_swap_types(result->value, &swap_conf->swap_type) < 0) {
+ _E("[DEBUG] Failed to parse type of swap, so use default zram type");
+ swap_conf->swap_type = SWAP_TYPE_ZRAM;
+ }
+/* if (strlen(result->value) + 1 > sizeof(swap_conf->type)) {
_E("Size of swap_conf->type is not enough");
return RESOURCED_ERROR_OUT_OF_MEMORY;
}
- strncpy(swap_conf->type, result->value, sizeof(swap_conf->type) - 1);
+ strncpy(swap_conf->type, result->value, sizeof(swap_conf->type) - 1);*/
}
else if (!strncmp(result->name, VIP_GROUP_SWAPPINESS_CONF,
strlen(VIP_GROUP_SWAPPINESS_CONF)+1)) {
result->name, result->value, result->section);
}
}
+ else if (!strncmp(result->section, CPU_SCHED_SECTION,
+ strlen(CPU_SCHED_SECTION)+1)) {
+ if (!strncmp(result->name, CPU_SCHED_FEATURE_CONF,
+ strlen(CPU_SCHED_FEATURE_CONF) + 1)) {
+ cpu_sched_conf->cpu_sched_flag = config_parse_cpu_sched_features(result->value);
+ }
+ else if (!strncmp(result->name, CPU_RT_RUN_TIME_CONF,
+ strlen(CPU_RT_RUN_TIME_CONF) + 1)) {
+ cpu_sched_conf->rt_runtime_us = config_parse_time_us(result->value);
+ }
+ else if (!strncmp(result->name, CPU_RT_PERIOD_CONF,
+ strlen(CPU_RT_PERIOD_CONF) + 1)) {
+ cpu_sched_conf->rt_period_us = config_parse_time_us(result->value);
+ }
+ else {
+ _E("[DEBUG] Unknown configuration name (%s) and value (%s) on section (%s)",
+ result->name, result->value, result->section);
+ }
+ }
else if (!strncmp(result->section, CPU_AFFINITY_SECTION,
strlen(CPU_AFFINITY_SECTION)+1)) {
int error = RESOURCED_ERROR_NONE;
config_type = LIMITER_CONFIG;
load_per_vendor_configs(LIMITER_CONF_DIR, vendor_config, &config_type);
- /* Load configurations in optimizer.conf */
+ /* Load configurations in optimizer.conf and optimizer.conf.d */
config_parse(OPTIMIZER_CONF_FILE, optimizer_config, NULL);
+ config_type = OPTIMIZER_CONFIG;
+ load_per_vendor_configs(OPTIMIZER_CONF_DIR, vendor_config, &config_type);
+ /* Load configuration in process.conf */
config_type = PROCESS_CONFIG;
load_per_vendor_configs(PROC_CONF_DIR, vendor_config, &config_type);
}
#define LIMITER_CONF_FILE RD_CONFIG_FILE(limiter)
#define OPTIMIZER_CONF_FILE RD_CONFIG_FILE(optimizer)
#define LIMITER_CONF_DIR RD_CONFIG_PATH"/limiter.conf.d"
+#define OPTIMIZER_CONF_DIR RD_CONFIG_PATH"/optimizer.conf.d"
#define PROC_CONF_DIR RD_CONFIG_PATH"/process.conf.d"
/* section name */
#define DEDUP_SECTION "MemoryDedup"
#define KSM_SECTION "MemoryKsm"
#define COMPACTION_SECTION "MemoryCompaction"
+#define CPU_SCHED_SECTION "CpuSched"
#define CPU_AFFINITY_SECTION "CpuAffinity"
/* configuration name */
#define PAGES_TO_SCAN_CONF "PagesToScan"
#define PAGES_TO_SCAN_WITH_BOOST_CONF "PagesToScanWithBoost"
#define COMPACTION_ENABLE_CONF "CompactionEnable"
+#define CPU_SCHED_FEATURE_CONF "CpuSchedFeature"
+#define CPU_RT_RUN_TIME_CONF "CpuRTRunTime"
+#define CPU_RT_PERIOD_CONF "CpuRTPeriod"
#define FRAG_LEVEL_CONF "FragLevel"
#define FOREGROUND_APPS "ForegroundApps"
#define ACTION_KILL_VALUE_CONF "kill"
#define ACTION_REBOOT_VALUE_CONF "reboot"
#define ACTION_IGNORE_VALUE_CONF "ignore"
-
+#define RT_RUNTIME_SHARE "rt_runtime_share"
+#define NO_RT_RUNTIME_SHARE "no_rt_runtime_share"
+#define RT_RUNTIME_GREED "rt_runtime_greed"
#define MATCH(a, b) (!strncmp(a, b, strlen(a) + 1) ? 1 : 0)
#define SET_CONF(a, b) (a = (b > 0.0 ? b : a))
--- /dev/null
+/*
+ * resourced
+ *
+ * Copyright (c) 2020 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.
+ */
+
+#include "macro.h"
+#include "cpu-sched-common.h"
+#include "trace.h"
+
+static struct cpu_sched_conf *cpu_sched_conf = NULL;
+
+struct cpu_sched_conf *get_cpu_sched_conf(void)
+{
+ if (!cpu_sched_conf) {
+ cpu_sched_conf = (struct cpu_sched_conf *)calloc(1, sizeof (struct cpu_sched_conf));
+ if (!cpu_sched_conf) {
+ _E("Failed to alloc memory for cpu configuration");
+ return NULL;
+ }
+ }
+
+ return cpu_sched_conf;
+}
+
+void free_cpu_sched_conf(void)
+{
+ if (cpu_sched_conf)
+ free(cpu_sched_conf);
+}
--- /dev/null
+#ifndef __CPU_SCHED_COMMON_H__
+#define __CPU_SCHED_COMMON_H__
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+enum cpu_sched_flag {
+ CPU_SCHED_UNINITIALIZED = 0,
+ CPU_SCHED_RUNTIME_SHARE = 1,
+ CPU_SCHED_NO_RUNTIME_SHARE = 2,
+ CPU_SCHED_RUNTIME_GREED = 4,
+};
+
+struct cpu_sched_conf {
+ int rt_period_us;
+ int rt_runtime_us;
+ enum cpu_sched_flag cpu_sched_flag;
+};
+
+struct cpu_sched_conf *get_cpu_sched_conf(void);
+void free_cpu_sched_conf(void);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* __CPU_SCHED_COMMON_H__ */
struct swap_conf {
bool enable;
bool boot_reclaim_enable;
- char type[30];
+ enum swap_type swap_type;
int swappiness[CGROUP_END];
struct zram_conf zram;
struct zswap_conf zswap;
#include "proc-common.h"
#include "file-helper.h"
#include "cpu-cgroup.h"
+#include "cpu-sched-common.h"
#include "util.h"
#define MOUNTS_PATH "/proc/mounts"
#define CPUSET_CGROUP "/sys/fs/cgroup/cpuset"
+#define GLOBAL_RT_PERIOD_US_PATH "/proc/sys/kernel/sched_rt_period_us"
+#define GLOBAL_RT_RUNTIME_US_PATH "/proc/sys/kernel/sched_rt_runtime_us"
+#define CPU_SCHED_FEATURE_PATH "/sys/kernel/debug/sched_features"
struct core {
int id;
struct cpu_sched {
struct coreset *fg;
GSList *apps;
- bool is_initalized;
+ bool is_initialized;
};
static struct cpu_sched cs;
return RESOURCED_ERROR_FAIL;
}
-static int load_config(struct cpu_sched *data)
+static int load_cpu_affinity_config(struct cpu_sched *data)
{
char *name;
bool is_fg;
return RESOURCED_ERROR_NONE;
}
+static int load_cpu_sched_config(void)
+{
+ struct cpu_sched_conf *cpu_sched_conf = get_cpu_sched_conf();
+ if (cpu_sched_conf == NULL) {
+ _E("[DEBUG] cpu sched configuration structure should not be NULL");
+ return RESOURCED_ERROR_FAIL;
+ }
+
+ if (cpu_sched_conf->rt_period_us > 0 &&
+ cpu_sched_conf->rt_runtime_us > 0 &&
+ cpu_sched_conf->rt_period_us > cpu_sched_conf->rt_runtime_us) {
+ fwrite_int(GLOBAL_RT_PERIOD_US_PATH, cpu_sched_conf->rt_period_us);
+ fwrite_int(GLOBAL_RT_RUNTIME_US_PATH, cpu_sched_conf->rt_runtime_us);
+ }
+
+ if (cpu_sched_conf->cpu_sched_flag) {
+ if (CHECK_BIT(cpu_sched_conf->cpu_sched_flag, CPU_SCHED_RUNTIME_SHARE) &&
+ CHECK_BIT(cpu_sched_conf->cpu_sched_flag, CPU_SCHED_NO_RUNTIME_SHARE)) {
+ _E("[DEBUG] RT_RUNTIME_SHARE and NO_RT_RUNTIME_SHARE cannot be coexisted");
+ }
+ else {
+ /* RT_RUNTIME_SHARE */
+ if (CHECK_BIT(cpu_sched_conf->cpu_sched_flag, CPU_SCHED_RUNTIME_SHARE))
+ fwrite_str(CPU_SCHED_FEATURE_PATH, "RT_RUNTIME_SHARE");
+ else if (CHECK_BIT(cpu_sched_conf->cpu_sched_flag, CPU_SCHED_NO_RUNTIME_SHARE))
+ fwrite_str(CPU_SCHED_FEATURE_PATH, "NO_RT_RUNTIME_SHARE");
+
+ /* RT_RUNTIME_GREED */
+ if (CHECK_BIT(cpu_sched_conf->cpu_sched_flag, CPU_SCHED_RUNTIME_GREED))
+ fwrite_str(CPU_SCHED_FEATURE_PATH, "RT_RUNTIME_GREED");
+ }
+ }
+
+ _I("[DEBUG] rt_period_us = %d", cpu_sched_conf->rt_period_us);
+ _I("[DEBUG] rt_runtime_us = %d", cpu_sched_conf->rt_runtime_us);
+ _I("[DEBUG] cpu_sched_feature = %d", cpu_sched_conf->cpu_sched_flag);
+
+ free_cpu_sched_conf();
+ return RESOURCED_ERROR_NONE;
+}
+
static int cpu_sched_parse_config(struct cpu_sched *data)
{
- load_config(data);
+ load_cpu_affinity_config(data);
+ load_cpu_sched_config();
return RESOURCED_ERROR_NONE;
}
assert(ps);
assert(ps->pai);
- if (cs.is_initalized == false || cpu_sched_is_static_app(ps->pai->appid) == true)
+ if (cs.is_initialized == false || cpu_sched_is_static_app(ps->pai->appid) == true)
return RESOURCED_ERROR_NONE;
_D("cpu-sched: app %s moved to foreground; pid=%d", ps->pai->appid, ps->pid);
assert(ps);
assert(ps->pai);
- if (cs.is_initalized == false || cpu_sched_is_static_app(ps->pai->appid) == true)
+ if (cs.is_initialized == false || cpu_sched_is_static_app(ps->pai->appid) == true)
return RESOURCED_ERROR_NONE;
_D("cpu-sched: app %s moved to background; pid=%d", ps->pai->appid, ps->pid);
return RESOURCED_ERROR_FAIL;
}
- cs.is_initalized = true;
+ cs.is_initialized = true;
cpu_sched_check_apps();
return RESOURCED_ERROR_NONE;
unregister_notifiers();
cpu_hotplug_finalize();
cpu_sched_free_cpusets();
- cs.is_initalized = false;
+ cs.is_initialized = false;
return RESOURCED_ERROR_FAIL;
}
unregister_notifiers();
cpu_hotplug_finalize();
cpu_sched_free_cpusets();
- cs.is_initalized = false;
+ cs.is_initialized = false;
return RESOURCED_ERROR_NONE;
}
d_bus_register_signals(dbus_signals, ARRAY_SIZE(dbus_signals));
}
-static int config_parse_swap_types(
- const char *rvalue,
- void *data)
-{
- enum swap_type *type = data;
- char *word, *state;
- size_t l;
-
- if (is_empty(rvalue))
- return 0;
-
- *type = 0;
-
- FOREACH_WORD_SEPARATOR(word, l, rvalue, "+|", state) {
- if (strneq(word, "zram", l))
- *type |= SWAP_TYPE_ZRAM;
- else if (strneq(word, "file", l))
- *type |= SWAP_TYPE_FILE;
- else if (strneq(word, "zswap", l))
- *type |= SWAP_TYPE_ZSWAP;
- else
- return -EINVAL;
- }
-
- return 0;
-}
static void print_swap_conf(void)
{
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) {
- _E("[DEBUG] Failed to parse type of swap, so use default zram type");
- arg_swap_type = SWAP_TYPE_ZRAM;
- }
+ arg_swap_type = swap_conf->swap_type;
for(int cgroup = CGROUP_VIP; cgroup < CGROUP_END; cgroup++) {
if (swap_conf->swappiness[cgroup] >= 0 &&