Update limiter.conf and support realtime 89/273589/2
authorUnsung Lee <unsung.lee@samsung.com>
Fri, 8 Apr 2022 06:05:20 +0000 (15:05 +0900)
committerUnsung Lee <unsung.lee@samsung.com>
Fri, 8 Apr 2022 07:26:55 +0000 (16:26 +0900)
Change-Id: Ic5a2200d2c0f6d03fe935e9ccdb19257c8894b34
Signed-off-by: Unsung Lee <unsung.lee@samsung.com>
20 files changed:
conf/limiter-profile-iot-headless.conf
conf/limiter-profile-tv.conf
conf/limiter.conf
conf/optimizer.conf
conf/optimizer.conf.d/0-optimizer.conf [new file with mode: 0644]
src/common/cgroup/cpu-cgroup.h
src/common/config-parser.c
src/common/config-parser.h
src/common/cpu-sched-common.h
src/common/notifier.h
src/common/proc-common.h
src/common/util.c
src/common/util.h
src/process/priority/proc-priority.c
src/process/proc-main.c
src/process/proc-monitor.c
src/resource-limiter/cpu/cpu.c
src/resource-limiter/memory/vmpressure-lowmem-handler.c
src/resource-optimizer/cpu/cpu-sched.c
src/resourced/init.c

index 4fabbbf..7fe7de7 100644 (file)
@@ -1,81 +1,20 @@
-[VIP_PROCESS]
-# predefined process list
-PREDEFINE=enlightenment
-PREDEFINE=dbus-daemon
-PREDEFINE=amd
-PREDEFINE=launchpad_preloading_preinitializing_daemon
-PREDEFINE=process_pool_launchpad_preloading_preinitializing_daemon
-
-[OOM_FIXED_APPS]
-# predefined OOM-fixed app list
-# Format : YOUR_APP=SCORE
-# OOMADJ_SERVICE_MIN < SCORE < OOMADJ_BACKGRD_LOCKED
-# NOTICE : do not set the score with the predefined value
-#          you can see the predefined value at the procfs.h
-
-# Use the ratio of the available memory to the total memory as vmpressure threshold.
-# If used with [Memory#] section, the last threshold will be applied.
-[Memory]
-NumMaxVictims=10
-#ThresholdRatioDedup=30           # %
-#ThresholdRatioSwap=24            # %
-#ThresholdRatioLow=12             # %
-#ThresholdRatioMedium=10          # %
-#ThresholdRatioLeave=15           # %
-#NumMaxVictims=1
-
-[POPUP]
-oom_popup=no
-
-[BackgroundReclaim]
-# Unset this option if it causes any unexepcted issue (e.g. jerky animation).
-AfterScreenDim=yes
-
-[MemLimit]
-# Control memory limit
-# values for MemLimitTrigger :
-#              oom (regiter event using oom_control and kill process in kernel)
-#              threshold(regiter event using usage_in_bytes and kill process in resourced)
-#              others(don't register any event for memory limit)
-MemLimitTrigger=oom
-
-# Memory limits for each supported application types.  Effective only when MemLimitTrigger
-# is set to oom or threshold.
-MemLimitService=128            # MB
-# MemLimitWidget=160            # MB
-# MemLimitGUIApp=1024           # MB
-
-# Following configuration option sets memory limit for background GUI
-# and Widget applications.  It's valid to set this option only if
-# both MemLimitWidget and MemLimitGUIApp are set.
-# MemLimitBgApp=768             # MB
-
-[Logging]
-Enable=1
-# memps logpath
-#              memps: OOM log
-#              memps_memlimit: lowmem limit log
-MaxNumLogfile=50       # default: 50
-LogPath=/var/log       # default: /var/log
-# logfile prefix
-PrefixMemps=memps
-PrefixMempsMemLimit=memps_memlimit
-
-[CPU]
-# predefined process list
-LAZY_PREDEFINE=net-config
-PREDEFINE=indicator-win
-PREDEFINE=windicator
-BOOTING_PREDEFINE=quickpanel
-WRT_PREDEFINE=wrt_launchpad_daemon
-BOOTING_PREDEFINE=volume
-BOOTING_PREDEFINE=nvitemd
-# relative cpu share
-# ROOT_CPU_SHARE=100 : fixed
-BACKGROUND_CPU_SHARE=50
-QUOTA_CPU_SHARE=25
-# max relative cpu time (max=100)
-QUOTA_MAX_BANDWIDTH=100
-
-[CPU-SCHED]
-#foreground=1,2,4-6
+[MemoryGroupLimit]
+VipGroupLimit=     100%
+HighGroupLimit=    100%
+MediumGroupLimit=  90%
+LowestGroupLimit=  70%
+
+[MemoryLevelThreshold]
+MediumLevel=       400MB
+LowLevel=          300MB
+CriticalLevel=     200MB
+OomLevel=          160MB
+OomPopup=          no
+
+[MemoryAppTypeLimit]
+ServicePerAppLimitAction=128MB,kill
+WidgetPerAppLimitAction=160MB,kill
+GUIPerAppLimitAction=1024MB,kill
+
+[MemoryAppStatusLimit]
+BackgroundPerAppLimitAction=768MB,kill
index 9fd8f4c..7fe7de7 100644 (file)
@@ -1,54 +1,20 @@
-[VIP_PROCESS]
-# predefined process list
-PREDEFINE=enlightenment
-PREDEFINE=dbus-daemon
-PREDEFINE=amd
-PREDEFINE=launchpad_preloading_preinitializing_daemon
-PREDEFINE=process_pool_launchpad_preloading_preinitializing_daemon
+[MemoryGroupLimit]
+VipGroupLimit=     100%
+HighGroupLimit=    100%
+MediumGroupLimit=  90%
+LowestGroupLimit=  70%
 
-[OOM_FIXED_APPS]
-# predefined OOM-fixed app list
-# Format : YOUR_APP=SCORE
-# OOMADJ_SERVICE_MIN < SCORE < OOMADJ_BACKGRD_LOCKED
-# NOTICE : do not set the score with the predefined value
-#          you can see the predefined value at the procfs.h
+[MemoryLevelThreshold]
+MediumLevel=       400MB
+LowLevel=          300MB
+CriticalLevel=     200MB
+OomLevel=          160MB
+OomPopup=          no
 
-[Memory]
-NumMaxVictims=10
+[MemoryAppTypeLimit]
+ServicePerAppLimitAction=128MB,kill
+WidgetPerAppLimitAction=160MB,kill
+GUIPerAppLimitAction=1024MB,kill
 
-[POPUP]
-oom_popup=no
-
-[BackgroundReclaim]
-# Unset this option if it causes any unexepcted issue (e.g. jerky animation).
-AfterScreenDim=yes
-
-[MemLimit]
-# Control memory limit
-# values for MemLimitTrigger :
-#       oom (regiter event using oom_control and kill process in kernel)
-#          threshold(regiter event using usage_in_bytes and kill process in resourced)
-#       others(don't register any event for memory limit)
-MemLimitTrigger=none
-# How long does the resourced allow that each service applications use memory
-# But, it only allows to enable when the MemLimitTrigger option is oom or threshold.
-MemLimitService=128            # MB
-
-[CPU]
-# predefined process list
-LAZY_PREDEFINE=net-config
-PREDEFINE=indicator-win
-PREDEFINE=windicator
-BOOTING_PREDEFINE=quickpanel
-WRT_PREDEFINE=wrt_launchpad_daemon
-BOOTING_PREDEFINE=volume
-BOOTING_PREDEFINE=nvitemd
-# relative cpu share
-# ROOT_CPU_SHARE=100 : fixed
-BACKGROUND_CPU_SHARE=50
-QUOTA_CPU_SHARE=25
-# max relative cpu time (max=100)
-QUOTA_MAX_BANDWIDTH=100
-
-[CPU-SCHED]
-#foreground=1,2,4-6
+[MemoryAppStatusLimit]
+BackgroundPerAppLimitAction=768MB,kill
index 7fe7de7..da00d89 100644 (file)
@@ -5,10 +5,10 @@ MediumGroupLimit=  90%
 LowestGroupLimit=  70%
 
 [MemoryLevelThreshold]
-MediumLevel=       400MB
-LowLevel=          300MB
-CriticalLevel=     200MB
-OomLevel=          160MB
+MediumLevel=       20%
+LowLevel=          15%
+CriticalLevel=     10%
+OomLevel=          7%
 OomPopup=          no
 
 [MemoryAppTypeLimit]
index 8644549..192024b 100644 (file)
@@ -17,7 +17,7 @@ PoolType=z3fold
 
 [MemoryDedup]
 DedupEnable=1
-DedupAtBoot=yes
+DedupAtBoot=no
 ScanOnLowmem=true
 
 [MemoryKsm]
@@ -25,15 +25,15 @@ KsmMode=oneshot
 #KsmMode=periodic
 
 PagesToScan=100
-PagesToScanWithBoost=1000
+PagesToScanWithBoost=1500
 
 [MemoryCompaction]
 CompactionEnable=1
 FragLevel=800
 
 [CpuSched]
-CpuSchedFeature=rt_runtime_share,rt_runtime_greed
-CpuRTRunTime=950ms
+CpuSchedFeature=no_rt_runtime_share
+CpuRTRunTime=915ms
 CpuRTPeriod=1000ms
 
 [CpuAffinity]
diff --git a/conf/optimizer.conf.d/0-optimizer.conf b/conf/optimizer.conf.d/0-optimizer.conf
new file mode 100644 (file)
index 0000000..87e60a9
--- /dev/null
@@ -0,0 +1,32 @@
+[PerProcess]
+Service=dbus.service
+CpuSched=fifo
+CpuRTPriority=5
+
+[PerProcess]
+Service=alarm-server.service
+CpuSched=rr
+CpuRTPriority=10
+
+[PerProcess]
+Service=ac.service
+CpuSched=other
+CpuNice=0
+
+[PerProcess]
+Service=scim.service
+CpuNice=1
+CpuPriority=0
+
+[PerProcess]
+Service=launchpad-process-pool.service
+CpuSched=batch
+CpuNice=2
+
+[PerProcess]
+Service=starter.service
+CpuSched=deadline
+
+[PerProcess]
+Service=at-spi-dbus-bus.service
+CpuSched=idle
index 833d80a..3ea2c42 100644 (file)
@@ -45,6 +45,8 @@ extern "C" {
 #define CPUCG_LOW_PATH                  CPUCG_PATH "/" CGROUP_VIP_NAME "/" CGROUP_HIGH_NAME "/" CGROUP_MEDIUM_NAME "/" CGROUP_LOW_NAME
 #define CPUCG_CONTROL_BANDWIDTH         "cpu.cfs_quota_us"
 #define CPUCG_CONTROL_FULL_BANDWIDTH    "cpu.cfs_period_us"
+#define CPUCG_RT_CONTROL_BANDWIDTH      "cpu.rt_runtime_us"
+#define CPUCG_RT_CONTROL_FULL_BANDWIDTH "cpu.rt_period_us"
 #define CPUCG_SHARE                     "cpu.shares"
 
 #define CPUCG_VIP_PP_PATH               CPUCG_VIP_PATH"/"CGROUP_PER_PROCESS_NAME
index 14ddca7..a011f52 100644 (file)
@@ -33,7 +33,6 @@
 #include "cpu-sched-common.h"
 
 #define MAX_SECTION            64
-#define CPU_INIT_PRIO  100
 
 static int config_parse_swap_types(
                                  const char *rvalue,
@@ -64,25 +63,25 @@ static int config_parse_swap_types(
 
 static int config_parse_cpu_sched_features(const char *value)
 {
-       int cpu_sched_type = CPU_SCHED_UNINITIALIZED;
+       int cpu_sched_flag = CPU_SCHED_UNINITIALIZED;
        char *word, *state;
        size_t l;
 
        if (is_empty(value))
-               return cpu_sched_type;
+               return cpu_sched_flag;
 
        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;
+               if (strneq(word, RT_RUNTIME_SHARE_VALUE_CONF, l))
+                       cpu_sched_flag |= CPU_SCHED_RUNTIME_SHARE;
+               else if (strneq(word, NO_RT_RUNTIME_SHARE_VALUE_CONF, l))
+                       cpu_sched_flag |= CPU_SCHED_NO_RUNTIME_SHARE;
+               else if (strneq(word, RT_RUNTIME_GREED_VALUE_CONF, l))
+                       cpu_sched_flag |= CPU_SCHED_RUNTIME_GREED;
                else
                        return CPU_SCHED_UNINITIALIZED;
        }
 
-       return cpu_sched_type;
+       return cpu_sched_flag;
 }
 
 static int config_parse_time_us(const char *value)
@@ -335,16 +334,16 @@ static int optimizer_config(struct parse_result *result, void *user_data)
        }
        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)) {
+               if (!strncmp(result->name, CPU_SCHED_FEATURE_NAME_CONF,
+                                       strlen(CPU_SCHED_FEATURE_NAME_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)) {
+               else if (!strncmp(result->name, CPU_RT_RUN_TIME_NAME_CONF,
+                                       strlen(CPU_RT_RUN_TIME_NAME_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)) {
+               else if (!strncmp(result->name, CPU_RT_PERIOD_NAME_CONF,
+                                       strlen(CPU_RT_PERIOD_NAME_CONF) + 1)) {
                        cpu_sched_conf->rt_period_us = config_parse_time_us(result->value);
                }
                else {
@@ -543,6 +542,7 @@ static int vendor_config(struct parse_result *result, void *user_data)
        if (strncmp(result->section, PER_PROCESS_SECTION, strlen(PER_PROCESS_SECTION)+1))
                return RESOURCED_ERROR_NONE;
 
+       /* common(App or Service) */
        if (!strncmp(result->name, SERVICE_NAME_CONF, strlen(SERVICE_NAME_CONF)+1) ||
                !strncmp(result->name, APP_NAME_CONF, strlen(APP_NAME_CONF)+1)) {
                pci = fixed_app_and_service_exist_check(result->value,
@@ -555,7 +555,9 @@ static int vendor_config(struct parse_result *result, void *user_data)
                        }
                        pci->mem_type = CGROUP_TOP;
                        pci->cpu_type = CGROUP_TOP;
-                       pci->cpu_priority = CPU_INIT_PRIO;
+                       pci->cpu_sched_info.cpu_sched_type = CPU_SCHED_NONE;
+                       pci->cpu_sched_info.cpu_rt_priority = CPU_INIT_PRIO;
+                       pci->cpu_sched_info.cpu_nice = CPU_INIT_NICE;
                        pci->watchdog_action = PROC_ACTION_KILL;
                        pci->fail_action = PROC_ACTION_IGNORE;
                        strncpy(pci->name, result->value, sizeof(pci->name)-1);
@@ -568,6 +570,7 @@ static int vendor_config(struct parse_result *result, void *user_data)
                        }
                }
        }
+       /* limiter.conf.d */
        else if (!strncmp(result->name, CPU_CGROUP_NAME_CONF, strlen(CPU_CGROUP_NAME_CONF)+1) &&
                        *config_type == LIMITER_CONFIG) {
                if (!pci) {
@@ -632,17 +635,74 @@ static int vendor_config(struct parse_result *result, void *user_data)
                        _E("process configuration information pointer should not be NULL");
                        return RESOURCED_ERROR_FAIL;
                }
-               
+
                error = set_mem_action_conf(&pci->mem_action, result->value);
-               return error;   
+               return error;
        }
-       else if (!strncmp(result->name, CPU_PRIORITY_NAME_CONF, strlen(CPU_PRIORITY_NAME_CONF)+1) &&
-                       *config_type == LIMITER_CONFIG) {
+       /* optimizer.conf.d */
+       else if (!strncmp(result->name, CPU_SCHED_NAME_CONF, strlen(CPU_SCHED_NAME_CONF)+1) &&
+                       *config_type == OPTIMIZER_CONFIG) {
+               if (!pci) {
+                       _E("process configuration information pointer should not be NULL");
+                       return RESOURCED_ERROR_FAIL;
+               }
+
+               if (!strncmp(result->value, CPU_SCHED_IDLE_VALUE_CONF,
+                                       strlen(CPU_SCHED_IDLE_VALUE_CONF) +1))
+                       pci->cpu_sched_info.cpu_sched_type = CPU_SCHED_IDLE;
+               else if (!strncmp(result->value, CPU_SCHED_OTHER_VALUE_CONF,
+                                       strlen(CPU_SCHED_OTHER_VALUE_CONF) +1))
+                       pci->cpu_sched_info.cpu_sched_type = CPU_SCHED_OTHER;
+               else if (!strncmp(result->value, CPU_SCHED_BATCH_VALUE_CONF,
+                                       strlen(CPU_SCHED_BATCH_VALUE_CONF) +1))
+                       pci->cpu_sched_info.cpu_sched_type = CPU_SCHED_BATCH;
+               else if (!strncmp(result->value, CPU_SCHED_FIFO_VALUE_CONF,
+                                       strlen(CPU_SCHED_FIFO_VALUE_CONF) +1))
+                       pci->cpu_sched_info.cpu_sched_type = CPU_SCHED_FIFO;
+               else if (!strncmp(result->value, CPU_SCHED_RR_VALUE_CONF,
+                                       strlen(CPU_SCHED_RR_VALUE_CONF) +1))
+                       pci->cpu_sched_info.cpu_sched_type = CPU_SCHED_RR;
+               else if (!strncmp(result->value, CPU_SCHED_DEADLINE_VALUE_CONF,
+                                       strlen(CPU_SCHED_DEADLINE_VALUE_CONF) +1))
+                       pci->cpu_sched_info.cpu_sched_type = CPU_SCHED_DEADLINE;
+               else {
+                       _E("invalid parameter (%s)", result->value);
+                       return RESOURCED_ERROR_INVALID_PARAMETER;
+               }
+       }
+       else if (!strncmp(result->name, CPU_NICE_NAME_CONF,
+                               strlen(CPU_NICE_NAME_CONF)+1) && *config_type == OPTIMIZER_CONFIG) {
+               if (!pci) {
+                       _E("process configuration information pointer should not be NULL");
+                       return RESOURCED_ERROR_FAIL;
+               }
+               pci->cpu_sched_info.cpu_nice = atoi(result->value);
+       }
+       else if (!strncmp(result->name, CPU_RT_PRIORITY_NAME_CONF,
+                               strlen(CPU_RT_PRIORITY_NAME_CONF)+1) && *config_type == OPTIMIZER_CONFIG) {
+               if (!pci) {
+                       _E("process configuration information pointer should not be NULL");
+                       return RESOURCED_ERROR_FAIL;
+               }
+               pci->cpu_sched_info.cpu_rt_priority = atoi(result->value);
+       }
+       else if (!strncmp(result->name, CPU_RT_RUN_TIME_NAME_CONF,
+                               strlen(CPU_RT_RUN_TIME_NAME_CONF)+1) &&
+                       *config_type == OPTIMIZER_CONFIG) {
+               if (!pci) {
+                       _E("process configuration information pointer should not be NULL");
+                       return RESOURCED_ERROR_FAIL;
+               }
+               pci->cpu_sched_info.rt_runtime_us = config_parse_time_us(result->value);
+       }
+       else if (!strncmp(result->name, CPU_RT_PERIOD_NAME_CONF,
+                               strlen(CPU_RT_PERIOD_NAME_CONF)+1) &&
+                       *config_type == OPTIMIZER_CONFIG) {
                if (!pci) {
                        _E("process configuration information pointer should not be NULL");
                        return RESOURCED_ERROR_FAIL;
                }
-               pci->cpu_priority = atoi(result->value);
+               pci->cpu_sched_info.rt_period_us = config_parse_time_us(result->value);
        }
        else if (!strncmp(result->name, ACTION_ON_FAILURE_NAME_CONF,
                                strlen(ACTION_ON_FAILURE_NAME_CONF)+1) && *config_type == PROCESS_CONFIG) {
index 7b905a8..a7e7947 100644 (file)
@@ -61,7 +61,6 @@ extern "C" {
 #define CPU_CGROUP_NAME_CONF                   "CpuGroup"
 #define MEM_CGROUP_NAME_CONF                   "MemGroup"
 #define MEM_LIMIT_ACTION_NAME_CONF             "MemLimitAction"
-#define CPU_PRIORITY_NAME_CONF                 "CpuPriority"
 #define ACTION_ON_FAILURE_NAME_CONF            "ActionOnFailure"
 #define        WATCHDOG_ACTION_NAME_CONF               "WatchdogAction"
 #define VIP_GROUP_LIMIT_CONF                   "VipGroupLimit"
@@ -97,11 +96,15 @@ extern "C" {
 #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 CPU_SCHED_FEATURE_NAME_CONF     "CpuSchedFeature"
+#define CPU_RT_RUN_TIME_NAME_CONF       "CpuRTRunTime"
+#define CPU_RT_PERIOD_NAME_CONF         "CpuRTPeriod"
 #define FRAG_LEVEL_CONF                                        "FragLevel"
 #define FOREGROUND_APPS                                        "ForegroundApps"
+/* optimizer.conf.d */
+#define CPU_SCHED_NAME_CONF             "CpuSched"
+#define CPU_RT_PRIORITY_NAME_CONF              "CpuRTPriority"
+#define CPU_NICE_NAME_CONF              "CpuNice"
 
 /* configuration value */
 #define CGROUP_VIP_VALUE_CONF          "vip"
@@ -113,9 +116,16 @@ extern "C" {
 #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 RT_RUNTIME_SHARE_VALUE_CONF            "rt_runtime_share"
+#define NO_RT_RUNTIME_SHARE_VALUE_CONF         "no_rt_runtime_share"
+#define RT_RUNTIME_GREED_VALUE_CONF            "rt_runtime_greed"
+
+#define CPU_SCHED_DEADLINE_VALUE_CONF          "deadline"
+#define CPU_SCHED_FIFO_VALUE_CONF              "fifo"
+#define CPU_SCHED_RR_VALUE_CONF                "rr"
+#define CPU_SCHED_OTHER_VALUE_CONF             "other"
+#define CPU_SCHED_IDLE_VALUE_CONF              "idle"
+#define CPU_SCHED_BATCH_VALUE_CONF             "batch"
 
 #define MATCH(a, b)    (!strncmp(a, b, strlen(a) + 1) ? 1 : 0)
 #define SET_CONF(a, b) (a = (b > 0.0 ? b : a))
index 68cb4d2..e2fcd41 100644 (file)
@@ -1,11 +1,18 @@
 #ifndef __CPU_SCHED_COMMON_H__
 #define __CPU_SCHED_COMMON_H__
 
-
 #ifdef __cplusplus
 extern "C" {
 #endif /* __cplusplus */
 
+#define CPU_INIT_NICE  100
+#define CPU_MAX_NICE   19
+#define CPU_MIN_NICE   -20
+
+#define CPU_INIT_PRIO  0
+#define CPU_MAX_PRIO   99
+#define CPU_MIN_PRIO   1
+
 enum cpu_sched_flag {
        CPU_SCHED_UNINITIALIZED = 0,
        CPU_SCHED_RUNTIME_SHARE = 1,
@@ -13,6 +20,24 @@ enum cpu_sched_flag {
        CPU_SCHED_RUNTIME_GREED = 4,
 };
 
+enum cpu_sched_type {
+       CPU_SCHED_NONE = 0,
+       CPU_SCHED_IDLE = 1,
+       CPU_SCHED_BATCH,
+       CPU_SCHED_OTHER,
+       CPU_SCHED_FIFO,
+       CPU_SCHED_RR,
+       CPU_SCHED_DEADLINE,
+};
+
+struct cpu_sched_info {
+       enum cpu_sched_type cpu_sched_type;
+       int cpu_nice;                        /* fixed cpu nice */
+       int cpu_rt_priority;                 /* fixed cpu priority for rt schedulers */
+       int rt_period_us;                    /* fixed cpu period */
+       int rt_runtime_us;                   /* fixed cpu runtime during period */
+};
+
 struct cpu_sched_conf {
        int rt_period_us;
        int rt_runtime_us;
index ab4ea27..416ef26 100644 (file)
@@ -95,6 +95,11 @@ enum notifier_type {
        RESOURCED_NOTIFIER_LIMIT_SYSTEM_SERVICE,
 
        /*
+        * real time scheduler
+        */
+       RESOURCED_NOTIFIER_RT_SCHEDULER,
+
+       /*
         * receive external event
         */
        RESOURCED_NOTIFIER_BOOTING_DONE,
index 32a01a7..23aeade 100644 (file)
@@ -32,6 +32,7 @@
 #include "resourced.h"
 #include "const.h"
 #include "memory-cgroup.h"
+#include "cpu-sched-common.h"
 
 #ifdef __cplusplus
 extern "C" {
@@ -59,15 +60,14 @@ enum proc_type {
        SERVICE_TYPE,
 };
 
-
 struct proc_conf_info {
        char name[MAX_NAME_LENGTH];
        enum cgroup_type mem_type;                      /* fixed memory cgroup */
        enum cgroup_type cpu_type;                      /* fixed cpu cgroup */
-       int cpu_priority;                                       /* fixed cpu priority */
        enum proc_action watchdog_action;       /* watchdog action */
        enum proc_action fail_action;           /* release action */
        struct mem_action mem_action;
+       struct cpu_sched_info cpu_sched_info;
        pid_t pid;
 };
 
@@ -210,7 +210,7 @@ struct proc_app_info {
        bool app_watchdog_exclude;
        bool app_memcg_update_exclude;
        bool app_cpucg_update_exclude;
-       bool app_cpu_prio_update_exclude;
+       bool app_cpu_nice_update_exclude;
        int runtime_exclude;
        int flags;
        int lru_state;
index 02f5e4a..48af630 100644 (file)
 
 #include <sys/stat.h>
 #include <sys/types.h>
+#include <sys/wait.h>
+#include <sys/syscall.h>
+#include <sys/time.h>
+#include <sys/resource.h>
 #include <fcntl.h>
-#include <unistd.h>
 #include <stdio.h>
 #include <assert.h>
-#include <sys/types.h>
-#include <sys/wait.h>
 #include <stdlib.h>
+#include <sched.h>
 
 #include "util.h"
 #include "trace.h"
 #include "resourced.h"
+#include "cpu-sched-common.h"
 
 #define GIGA_SHIFT 30
 #define MEGA_SHIFT 20
 #define KILO_SHIFT 10
 
+#if !defined(SYS_sched_setattr) && defined(__NR_sched_setattr)
+# define SYS_sched_setattr _NR_sched_setattr
+#endif
+
+#if !defined(SYS_sched_getattr) && defined(__NR_sched_getattr)
+# define SYS_sched_getattr _NR_sched_getattr
+#endif
+
+int sched_setattr(pid_t pid, struct sched_attr *attr, unsigned int flags)
+{
+       int error;
+
+       _I("[DEBUG] policy = %s", attr->sched_policy == SCHED_IDLE ? "SCHED_IDLE" :
+                                         attr->sched_policy == SCHED_BATCH ? "SCHED_BATCH" :
+                                                                 attr->sched_policy == SCHED_OTHER ? "SCHED_OTHER" :
+                                                                 attr->sched_policy == SCHED_FIFO ? "SCHED_FIFO" :
+                                                                 attr->sched_policy == SCHED_RR ? "SCHED_RR" :
+                                                                 attr->sched_policy == SCHED_DEADLINE ? "SCHED_DEADLINE" : "UNKNOWN");
+
+       switch (attr->sched_policy) {
+               case SCHED_IDLE:
+                       if (attr->sched_priority != 0) {
+                               _E("[DEBUG] priority of SCHED_IDLE should be 0");
+                               return RESOURCED_ERROR_FAIL;
+                       }
+                       break;
+               case SCHED_BATCH:
+               case SCHED_OTHER:
+                       if (attr->sched_priority != 0) {
+                               _E("[DEBUG] priority of %s should be 0", attr->sched_policy == SCHED_BATCH ? "SCHED_BATCH" : "SCHED_OTHER");
+                               return RESOURCED_ERROR_FAIL;
+                       }
+
+                       if (attr->sched_nice == CPU_INIT_NICE) {
+                               _W("[DEBUG] nice value should be located between %d and %d",
+                                               CPU_MIN_NICE, CPU_MAX_NICE);
+                               return RESOURCED_ERROR_FAIL;
+                       }
+
+#ifndef SYS_sched_setattr
+                       setpriority(PRIO_PROCESS, pid, attr->sched_nice);
+#endif
+                       break;
+               case SCHED_FIFO:
+               case SCHED_RR:
+                       if (attr->sched_priority == CPU_INIT_PRIO) {
+                               _E("[DEBUG] priority of %s should be located between %d and %d",
+                                               attr->sched_policy == SCHED_FIFO ? "SCHED_FIFO" : "SCHED_RR",
+                                               CPU_MIN_PRIO, CPU_MAX_PRIO);
+                               return RESOURCED_ERROR_FAIL;
+                       }
+                       break;
+               case SCHED_DEADLINE:
+                       _W("[DEBUG] we do not support deadline scheulder yet");
+                       return RESOURCED_ERROR_NONE;
+               default:
+                       _E("[DEBUG] Unknown sched type (%d)", attr->sched_policy);
+                       return RESOURCED_ERROR_FAIL;
+       }
+
+#ifdef SYS_sched_setattr
+       error = syscall(SYS_sched_setattr, pid, attr, flags);
+#else
+       {
+               struct sched_param sp = { .sched_priority = attr->sched_priority};
+               error = sched_setscheduler(pid, attr->sched_policy, &sp);
+       }
+#endif
+       if (error) {
+               _E("[DEBUG] Failed to set policy and priority");
+               return RESOURCED_ERROR_FAIL;
+       }
+
+       return RESOURCED_ERROR_NONE;
+}
+
+int sched_getattr(pid_t pid, struct sched_attr *attr, unsigned int flags)
+{
+#ifdef SYS_sched_getattr
+       return syscall(SYS_sched_getattr, pid, attr, sizeof(struct sched_attr), flags);
+#else
+       int error;
+       struct sched_param sp;
+
+       attr->sched_policy = sched_getscheduler(pid);
+       attr->sched_nice = getpriority(PRIO_PROCESS, pid);
+
+       error = sched_getparam(pid, &sp);
+       if (!error)
+               attr->sched_priority = sp.sched_priority;
+
+       if (attr->sched_policy >= 0 && !error)
+               return RESOURCED_ERROR_NONE;
+       else
+               return RESOURCED_ERROR_FAIL;
+#endif
+}
+
 static int parent(pid_t pid)
 {
        int status;
index 8f4394b..b32274f 100644 (file)
@@ -31,6 +31,7 @@
 #include <unistd.h>
 #include <string.h>
 #include <dirent.h>
+#include <stdint.h>
 
 #ifdef __cplusplus
 extern "C" {
@@ -44,6 +45,18 @@ extern "C" {
 #define _pure_ __attribute__ ((pure))
 #define _cleanup_(x) __attribute__((cleanup(x)))
 
+struct sched_attr {
+       uint32_t size;              /* Size of this structure */
+       uint32_t sched_policy;      /* Policy (SCHED_*) */
+       uint64_t sched_flags;       /* Flags */
+       int32_t sched_nice;         /* Nice value (SCHED_OTHER, SCHED_BATCH) */
+       uint32_t sched_priority;    /* Static priority (SCHED_FIFO, SCHED_RR) */
+       /* Remaining fields are for SCHED_DEADLINE */
+       uint64_t sched_runtime;
+       uint64_t sched_deadline;
+       uint64_t sched_period;
+};
+
 static inline void freep(void *p)
 {
        free(*(void**) p);
@@ -152,6 +165,9 @@ void strv_free_full(char ***strv);
 
 int resourced_restarted(void);
 
+int sched_setattr(pid_t pid, struct sched_attr *attr, unsigned int flags);
+int sched_getattr(pid_t pid, struct sched_attr *attr, unsigned int flags);
+
 #ifdef __cplusplus
 }
 #endif /* __cplusplus */
index 9351536..cd913be 100644 (file)
@@ -37,8 +37,7 @@
 #include "procfs.h"
 #include "resourced.h"
 #include "trace.h"
-
-#define CPU_INIT_PRIO  100
+#include "cpu-sched-common.h"
 
 static GHashTable *fixed_app_list;
 static GHashTable *fixed_service_list;
index 903a8ac..95d286a 100644 (file)
@@ -27,6 +27,7 @@
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <fcntl.h>
+#include <sched.h>
 
 #include <glib-object.h>
 #include <gio/gio.h>
@@ -55,6 +56,7 @@
 #include "config-parser.h"
 #include "fd-handler.h"
 #include "cpu-cgroup.h"
+#include "cpu-sched-common.h"
 
 #ifndef gettid
 #include <sys/syscall.h>
@@ -66,8 +68,6 @@
 #endif
 #endif
 
-#define CPU_INIT_PRIO  100
-
 static const struct module_ops *freezer;
 static GSList *proc_module;  /* proc sub-module list */
 
@@ -816,7 +816,9 @@ __attribute__((weak)) struct proc_app_info *proc_create_app_info(const char *app
                pai->memory.memlimit_update_exclude = false;
 
                if (fixed_app_list_get()) {
+                       int error;
                        struct proc_conf_info *pci;
+                       struct sched_attr attr;
 
                        pci = fixed_app_and_service_exist_check(appid, APP_TYPE);
 
@@ -831,14 +833,120 @@ __attribute__((weak)) struct proc_app_info *proc_create_app_info(const char *app
                                        pai->app_cpucg_update_exclude = true;
                                }
 
-                               if (pci->cpu_priority != CPU_INIT_PRIO) {
-                                       setpriority(PRIO_PROCESS, pid, pci->cpu_priority);
-                                       pai->app_cpu_prio_update_exclude = true;
+                               memset(&attr, 0, sizeof(struct sched_attr));
+                               attr.size = sizeof(struct sched_attr);
+                               if (pci->cpu_sched_info.cpu_nice >= CPU_MIN_NICE &&
+                                               pci->cpu_sched_info.cpu_nice <= CPU_MAX_NICE) {
+                                       attr.sched_nice = pci->cpu_sched_info.cpu_nice;
+                                       pai->app_cpu_nice_update_exclude = true;
+                               }
+                               else {
+                                       attr.sched_nice = CPU_INIT_NICE;
+                               }
+
+                               if (pci->cpu_sched_info.cpu_rt_priority >= CPU_MIN_PRIO &&
+                                               pci->cpu_sched_info.cpu_rt_priority <= CPU_MAX_PRIO) {
+                                       attr.sched_priority = pci->cpu_sched_info.cpu_rt_priority;
+                               }
+                               else {
+                                       attr.sched_priority = CPU_INIT_PRIO;
+                               }
+
+                               switch (pci->cpu_sched_info.cpu_sched_type) {
+                                       case CPU_SCHED_NONE:
+                                       case CPU_SCHED_OTHER:
+                                               attr.sched_policy = SCHED_OTHER;
+                                               sched_setattr(pid, &attr, 0);
+                                               error = sched_getattr(pid, &attr, 0);
+                                               if (error)
+                                                       _E("[DEBUG] Failed to get sched attributes");
+
+                                               if (attr.sched_policy != SCHED_OTHER)
+                                                       _E("[DEBUG] current policy (%d) is different from %d",
+                                                                       attr.sched_policy, SCHED_OTHER);
+                                               break;
+                                       case CPU_SCHED_IDLE:
+                                               attr.sched_policy = SCHED_IDLE;
+                                               sched_setattr(pid, &attr, 0);
+                                               error = sched_getattr(pid, &attr, 0);
+                                               if (error)
+                                                       _E("[DEBUG] Failed to get sched attributes");
+
+                                               if (attr.sched_policy != SCHED_IDLE)
+                                                       _E("[DEBUG] current policy (%d) is different from %d",
+                                                                       attr.sched_policy, SCHED_IDLE);
+                                               break;
+                                       case CPU_SCHED_BATCH:
+                                               attr.sched_policy = SCHED_BATCH;
+                                               sched_setattr(pid, &attr, 0);
+                                               error = sched_getattr(pid, &attr, 0);
+                                               if (error)
+                                                       _E("[DEBUG] Failed to get sched attributes");
+
+                                               if (attr.sched_policy != SCHED_BATCH)
+                                                       _E("[DEBUG] current policy (%d) is different from %d",
+                                                                       attr.sched_policy, SCHED_BATCH);
+                                               break;
+                                       case CPU_SCHED_FIFO:
+                                               attr.sched_policy = SCHED_FIFO;
+                                               sched_setattr(pid, &attr, 0);
+                                               error = sched_getattr(pid, &attr, 0);
+                                               if (error)
+                                                       _E("[DEBUG] Failed to get sched attributes");
+
+                                               if (attr.sched_policy != SCHED_FIFO)
+                                                       _E("[DEBUG] current policy (%d) is different from %d",
+                                                                       attr.sched_policy, SCHED_FIFO);
+                                               break;
+                                       case CPU_SCHED_RR:
+                                               attr.sched_policy = SCHED_RR;
+                                               sched_setattr(pid, &attr, 0);
+                                               error = sched_getattr(pid, &attr, 0);
+                                               if (error)
+                                                       _E("[DEBUG] Failed to get sched attributes");
+
+                                               if (attr.sched_policy != SCHED_RR)
+                                                       _E("[DEBUG] current policy (%d) is different from %d",
+                                                                       attr.sched_policy, SCHED_RR);
+                                               break;
+                                       case CPU_SCHED_DEADLINE:
+                                               attr.sched_policy = SCHED_DEADLINE;
+                                               sched_setattr(pid, &attr, 0);
+                                               error = sched_getattr(pid, &attr, 0);
+                                               if (error)
+                                                       _E("[DEBUG] Failed to get sched attributes");
+                                               break;
+                                       default:
+                                               _E("[DEBUG] Unknown CPU sched type");
                                }
 
+                               _I("[DEBUG] policy = %s", attr.sched_policy == SCHED_IDLE ? "SCHED_IDLE" :
+                                                                                 attr.sched_policy == SCHED_BATCH ? "SCHED_BATCH" :
+                                                                                 attr.sched_policy == SCHED_OTHER ? "SCHED_OTHER" :
+                                                                                 attr.sched_policy == SCHED_FIFO ? "SCHED_FIFO" :
+                                                                                 attr.sched_policy == SCHED_RR ? "SCHED_RR" :
+                                                                                 attr.sched_policy == SCHED_DEADLINE ? "SCHED_DEADLINE" : "UNKNOWN");
+                               _I("[DEBUG] nice = %d", attr.sched_nice);
+                               _I("[DEBUG] priority = %d", attr.sched_priority);
+
                                if (pci->watchdog_action == PROC_ACTION_IGNORE)
                                        pai->app_watchdog_exclude = true;
 
+                               /* register RT throttling */
+                               if (pci->cpu_sched_info.cpu_sched_type == CPU_SCHED_FIFO ||
+                                       pci->cpu_sched_info.cpu_sched_type == CPU_SCHED_RR ||
+                                       pci->cpu_sched_info.cpu_sched_type == CPU_SCHED_DEADLINE) {
+                                       if (pci->cpu_sched_info.rt_period_us > 0 &&
+                                               pci->cpu_sched_info.rt_runtime_us > 0 &&
+                                               pci->cpu_sched_info.rt_period_us > pci->cpu_sched_info.rt_runtime_us) {
+                                               struct proc_status ps = {0, };
+
+                                               ps.pid = pid;
+                                               ps.pci = pci;
+                                               resourced_notify(RESOURCED_NOTIFIER_RT_SCHEDULER, &ps);
+                                       }
+                               }
+
                                if (pci->mem_action.memory && pci->mem_action.action) {
                                        struct proc_limit_status pls = {0, };
 
index 500a931..d868742 100644 (file)
@@ -640,7 +640,7 @@ static void proc_dbus_set_priority_signal_handler(GVariant *params)
        }
 
        pai = find_app_info(pid);
-       if (pai && pai->app_cpu_prio_update_exclude)
+       if (pai && pai->app_cpu_nice_update_exclude)
                return;
 
        _D("pid (%d) requested to change priority (%s)", pid, str);
index 794c5d8..f877c73 100644 (file)
@@ -84,7 +84,7 @@ enum {
 
 static void cpu_priority_update(int which, pid_t pid, int priority, struct proc_app_info *pai)
 {
-       if (pai && pai->app_cpu_prio_update_exclude)
+       if (pai && pai->app_cpu_nice_update_exclude)
                return;
 
        setpriority(which, pid, priority);
index a4a5e90..85684dc 100644 (file)
@@ -1850,10 +1850,10 @@ static int lowmem_bg_reclaim_handler(void *data)
        return RESOURCED_ERROR_NONE;
 }
 
-static int calculate_threshold_size(double ratio)
+static inline int calculate_threshold_size(double ratio)
 {
        int size = (double)totalram * ratio / 100.0;
-       return size;
+       return BYTE_TO_MBYTE(size);
 }
 
 static void load_configs(const char *path)
@@ -1870,12 +1870,22 @@ static void load_configs(const char *path)
        /* set MemoryLevelThreshold section */
        for (int lvl = MEM_LEVEL_MEDIUM; lvl < MEM_LEVEL_MAX; lvl++) {
                if (memcg_conf->threshold[lvl].percent &&
-                       memcg_conf->threshold[lvl].threshold > 0)
+                       memcg_conf->threshold[lvl].threshold > 0) {
                        memcg_set_threshold(CGROUP_ROOT, lvl,
                                        calculate_threshold_size(memcg_conf->threshold[lvl].threshold));
-               else if (memcg_conf->threshold[lvl].threshold > 0)
+
+                       if (lvl == MEM_LEVEL_OOM)
+                               memcg_set_leave_threshold(CGROUP_ROOT,
+                                               get_memcg_info(CGROUP_ROOT)->threshold[lvl] * 1.5);
+               }
+               else if (memcg_conf->threshold[lvl].threshold > 0) {
                        memcg_set_threshold(CGROUP_ROOT, lvl,
                                        memcg_conf->threshold[lvl].threshold);
+
+                       if (lvl == MEM_LEVEL_OOM)
+                               memcg_set_leave_threshold(CGROUP_ROOT,
+                                               get_memcg_info(CGROUP_ROOT)->threshold[lvl] * 1.5);
+               }
        }
        oom_popup_enable = memcg_conf->oom_popup;
 
index 1c1cb83..3741858 100644 (file)
@@ -533,6 +533,44 @@ static int cpu_sched_app_launch(void *data)
        return cpu_sched_add_pid_to_cpuset(c, ps->pid);
 }
 
+static int cpu_sched_rt_scheduler(void *data)
+{
+       _cleanup_free_ char *path = NULL;
+       int result;
+       int32_t temp;
+       struct proc_status *ps = (struct proc_status *)data;
+
+       assert(ps);
+       assert(ps->pci);
+       assert(ps->pci->name);
+
+       result = cgroup_read_node_int32(MEMCG_HIGH_PP_PATH, CPUCG_RT_CONTROL_BANDWIDTH, &temp);
+       if (result < 0) {
+               _W("[DEBUG] rt_runtime_us is not supported");
+               return RESOURCED_ERROR_FAIL;
+       }
+
+       result = asprintf(&path, "%s/%s", MEMCG_HIGH_PP_PATH, ps->pci->name);
+       if (result < 0) {
+               _E("[DEBUG] not enough memory");
+               return RESOURCED_ERROR_OUT_OF_MEMORY;
+       }
+
+       result = cgroup_make_subdir(MEMCG_HIGH_PP_PATH, ps->pci->name, NULL);
+       if (result < 0) {
+               _E("[DEBUG] Failed to create cgroup subdir '%s/%s'",
+                               MEMCG_HIGH_PP_PATH, ps->pci->name);
+               return RESOURCED_ERROR_FAIL;
+       }
+
+       cgroup_write_node_int32(path, CPUCG_RT_CONTROL_FULL_BANDWIDTH, ps->pci->cpu_sched_info.rt_period_us);
+       cgroup_write_node_int32(path, CPUCG_RT_CONTROL_BANDWIDTH, ps->pci->cpu_sched_info.rt_runtime_us);
+
+       cgroup_write_pid_fullpath(path, ps->pid);
+
+       return RESOURCED_ERROR_NONE;
+}
+
 static void register_notifiers()
 {
        if (cs.fg) {
@@ -546,6 +584,8 @@ static void register_notifiers()
                register_notifier(RESOURCED_NOTIFIER_WIDGET_BACKGRD, cpu_sched_app_background);
        }
 
+       register_notifier(RESOURCED_NOTIFIER_RT_SCHEDULER, cpu_sched_rt_scheduler);
+
        register_notifier(RESOURCED_NOTIFIER_CPU_ON, cpu_sched_cpu_on);
        register_notifier(RESOURCED_NOTIFIER_CPU_OFF, cpu_sched_cpu_off);
 
@@ -566,6 +606,8 @@ static void unregister_notifiers()
                unregister_notifier(RESOURCED_NOTIFIER_WIDGET_BACKGRD, cpu_sched_app_background);
        }
 
+       unregister_notifier(RESOURCED_NOTIFIER_RT_SCHEDULER, cpu_sched_rt_scheduler);
+
        unregister_notifier(RESOURCED_NOTIFIER_CPU_ON, cpu_sched_cpu_on);
        unregister_notifier(RESOURCED_NOTIFIER_CPU_OFF, cpu_sched_cpu_off);
 
index 5b868b8..6d4e237 100644 (file)
@@ -23,6 +23,7 @@
  *
  **/
 
+#include "util.h"
 #include "const.h"
 #include "dbus-handler.h"
 #include "cgroup.h"
@@ -41,6 +42,7 @@
 #include "fd-handler.h"
 #include "lowmem-handler.h"
 #include "notifier.h"
+#include "cpu-sched-common.h"
 
 #include <dirent.h>
 #include <dlfcn.h>
@@ -212,13 +214,13 @@ void resourced_quit_mainloop(void)
        g_source_attach(shared_data->darg->mainloop_quit, NULL);
 }
 
-#define CPU_INIT_PRIO  100
-
 int fixed_service_list_init(void *data)
 {
+       int error;
        gpointer key;
        gpointer value;
        GHashTableIter iter;
+       struct sched_attr attr;
 
        g_hash_table_iter_init(&iter, fixed_service_list_get());
 
@@ -228,7 +230,6 @@ int fixed_service_list_init(void *data)
                GVariant *variant;
                pid_t pid = -1;
 
-
                if (!pci) {
                        _E("[DEBUG] process configuration information is NULL");
                        continue;
@@ -260,20 +261,127 @@ int fixed_service_list_init(void *data)
                        cpu_move_cgroup_foreach(pid, NULL, CPU_CGROUP_PATH(pci->cpu_type));
                }
 
-               /* fixed cpu priority */
-               if (pci->cpu_priority != CPU_INIT_PRIO) {
-                       setpriority(PRIO_PROCESS, pid, pci->cpu_priority);
+               memset(&attr, 0, sizeof(struct sched_attr));
+               attr.size = sizeof(struct sched_attr);
+               if (pci->cpu_sched_info.cpu_nice >= CPU_MIN_NICE &&
+                       pci->cpu_sched_info.cpu_nice <= CPU_MAX_NICE) {
+                       attr.sched_nice = pci->cpu_sched_info.cpu_nice;
+               }
+               else {
+                       attr.sched_nice = CPU_INIT_NICE;
+               }
+
+               if (pci->cpu_sched_info.cpu_rt_priority >= CPU_MIN_PRIO &&
+                   pci->cpu_sched_info.cpu_rt_priority <= CPU_MAX_PRIO) {
+                       attr.sched_priority = pci->cpu_sched_info.cpu_rt_priority;
+               }
+               else {
+                       attr.sched_priority = CPU_INIT_PRIO;
                }
 
+               switch (pci->cpu_sched_info.cpu_sched_type) {
+                       case CPU_SCHED_NONE:
+                       case CPU_SCHED_OTHER:
+                               attr.sched_policy = SCHED_OTHER;
+                               sched_setattr(pid, &attr, 0);
+                               error = sched_getattr(pid, &attr, 0);
+                               if (error)
+                                       _E("[DEBUG] Failed to get sched attributes");
+
+                               if (attr.sched_policy != SCHED_OTHER)
+                                       _E("[DEBUG] current policy (%d) is different from %d",
+                                       attr.sched_policy, SCHED_OTHER);
+                               break;
+                       case CPU_SCHED_IDLE:
+                               attr.sched_policy = SCHED_IDLE;
+                               sched_setattr(pid, &attr, 0);
+                               error = sched_getattr(pid, &attr, 0);
+                               if (error)
+                                       _E("[DEBUG] Failed to get sched attributes");
+
+                               if (attr.sched_policy != SCHED_IDLE)
+                                       _E("[DEBUG] current policy (%d) is different from %d",
+                                       attr.sched_policy, SCHED_IDLE);
+                               break;
+                       case CPU_SCHED_BATCH:
+                               attr.sched_policy = SCHED_BATCH;
+                               sched_setattr(pid, &attr, 0);
+                               error = sched_getattr(pid, &attr, 0);
+                               if (error)
+                                       _E("[DEBUG] Failed to get sched attributes");
+
+                               if (attr.sched_policy != SCHED_BATCH)
+                                       _E("[DEBUG] current policy (%d) is different from %d",
+                                       attr.sched_policy, SCHED_BATCH);
+                               break;
+                       case CPU_SCHED_FIFO:
+                               attr.sched_policy = SCHED_FIFO;
+                               sched_setattr(pid, &attr, 0);
+                               error = sched_getattr(pid, &attr, 0);
+                               if (error)
+                                       _E("[DEBUG] Failed to get sched attributes");
+
+                               if (attr.sched_policy != SCHED_FIFO)
+                                       _E("[DEBUG] current policy (%d) is different from %d",
+                                       attr.sched_policy, SCHED_FIFO);
+                               break;
+                       case CPU_SCHED_RR:
+                               attr.sched_policy = SCHED_RR;
+                               sched_setattr(pid, &attr, 0);
+                               error = sched_getattr(pid, &attr, 0);
+                               if (error)
+                                       _E("[DEBUG] Failed to get sched attributes");
+
+                               if (attr.sched_policy != SCHED_RR)
+                                       _E("[DEBUG] current policy (%d) is different from %d",
+                                       attr.sched_policy, SCHED_RR);
+                               break;
+                       case CPU_SCHED_DEADLINE:
+                               attr.sched_policy = SCHED_DEADLINE;
+                               sched_setattr(pid, &attr, 0);
+                               error = sched_getattr(pid, &attr, 0);
+                               if (error)
+                                       _E("[DEBUG] Failed to get sched attributes");
+                               break;
+                       default:
+                               _E("[DEBUG] Unknown CPU sched type");
+               }
+
+               _I("[DEBUG] %s's (pid = %d) policy = %s", pci->name, pid, attr.sched_policy == SCHED_IDLE ? "SCHED_IDLE" :
+                                         attr.sched_policy == SCHED_BATCH ? "SCHED_BATCH" :
+                                                                 attr.sched_policy == SCHED_OTHER ? "SCHED_OTHER" :
+                                                                 attr.sched_policy == SCHED_FIFO ? "SCHED_FIFO" :
+                                                                 attr.sched_policy == SCHED_RR ? "SCHED_RR" :
+                                                                 attr.sched_policy == SCHED_DEADLINE ? "SCHED_DEADLINE" : "UNKNOWN");
+               _I("[DEBUG] %s's nice = %d", pci->name, attr.sched_nice);
+               _I("[DEBUG] %s's priority = %d", pci->name, attr.sched_priority);
+
                /* register a notification when this service is released */
                switch (pci->fail_action) {
                        case PROC_ACTION_REBOOT:
                                proc_watchdog_booting_done(pci->name, pid);
                                break;
+                       case PROC_ACTION_IGNORE:
+                               break;
                        default:
                                _W("[DEBUG] Currently we support only REBOOT when a service is released");
                }
 
+               /* register RT throttling */
+               if (pci->cpu_sched_info.cpu_sched_type == CPU_SCHED_FIFO ||
+                   pci->cpu_sched_info.cpu_sched_type == CPU_SCHED_RR ||
+                       pci->cpu_sched_info.cpu_sched_type == CPU_SCHED_DEADLINE) {
+                       if (pci->cpu_sched_info.rt_period_us > 0 &&
+                           pci->cpu_sched_info.rt_runtime_us > 0 &&
+                               pci->cpu_sched_info.rt_period_us > pci->cpu_sched_info.rt_runtime_us) {
+                               struct proc_status ps = {0, };
+
+                               ps.pid = pid;
+                               ps.pci = pci;
+                               resourced_notify(RESOURCED_NOTIFIER_RT_SCHEDULER, &ps);
+                       }
+               }
+
                /* register a notification when this service memory is over a threshold */
                if (pci->mem_action.memory && pci->mem_action.action) {
                        struct proc_limit_status pls = {0, };