vmpressure : improve VIP app register process 96/59196/7
authorKichan Kwon <k_c.kwon@samsung.com>
Thu, 11 Feb 2016 09:20:23 +0000 (18:20 +0900)
committerKichan Kwon <k_c.kwon@samsung.com>
Wed, 17 Feb 2016 03:04:05 +0000 (12:04 +0900)
- To convert appname to pid, existing code opens cmdline file and match appname.
 However, this process is file operation, so it causes performance degradation.

- To decrease file operation, (appname,pid) array is maken before conversion.
 By using this array, we don't have to access cmdline file many times.

Change-Id: I2de243a5ef93615288907cdd6eb848f8b15e9be1
Signed-off-by: Kichan Kwon <k_c.kwon@samsung.com>
src/memory/vmpressure-lowmem-handler.c

index 915dadc..e6f586d 100644 (file)
@@ -269,6 +269,13 @@ static struct memcg **memcg_tree;
  */
 static struct memcg_info *memcg_root;
 
+struct proc_info {
+       pid_t pid;
+       char cmdline[PROC_NAME_MAX];
+};
+static GPtrArray *proc_apps;
+static GPtrArray *vip_apps;
+
 static char *convert_memstate_to_str(int mem_state)
 {
        char *tmp = NULL;
@@ -1370,25 +1377,24 @@ static unsigned int check_mem_state(unsigned int available)
 
 static int load_vip_config(struct parse_result *result, void *user_data)
 {
-       pid_t pid = 0;
-       if (!result)
-               return -EINVAL;
+       if (!result || !vip_apps)
+               return RESOURCED_ERROR_INVALID_PARAMETER;
 
-       if (strncmp(result->section, MEM_VIP_SECTION, strlen(MEM_VIP_SECTION)+1))
+       if (strncmp(result->section, MEM_VIP_SECTION, sizeof(MEM_VIP_SECTION)))
                return RESOURCED_ERROR_NONE;
 
-       if (!strncmp(result->name, MEM_VIP_PREDEFINE, strlen(MEM_VIP_PREDEFINE)+1)) {
-               pid = find_pid_from_cmdline(result->value);
-               if (pid > 0)
-                       proc_set_oom_score_adj(pid, OOMADJ_SERVICE_MIN);
+       if (!strcmp(result->name, MEM_VIP_PREDEFINE)) {
+               char *app_name = g_strdup(result->value);
+               g_ptr_array_add(vip_apps, (gpointer)app_name);
        }
+
        return RESOURCED_ERROR_NONE;
 }
 
 static int load_mem_config(struct parse_result *result, void *user_data)
 {
        if (!result)
-               return -EINVAL;
+               return RESOURCED_ERROR_INVALID_PARAMETER;
 
        if (strncmp(result->section, MEM_POPUP_SECTION, strlen(MEM_POPUP_SECTION)+1))
                return RESOURCED_ERROR_NONE;
@@ -2026,6 +2032,101 @@ static int lowmem_press_setup_eventfd(void)
        return RESOURCED_ERROR_NONE;
 }
 
+static void set_vip_oom_score_adj(gpointer vip_app)
+{
+       int proc_index = 0;
+       struct proc_info *info;
+
+       for(proc_index = 0; proc_index < proc_apps->len; proc_index++) {
+               info = g_ptr_array_index(proc_apps, proc_index);
+               if(!strncmp(vip_app, info->cmdline, strlen(info->cmdline) + 1)) {
+                       if (info->pid > 0) {
+                               proc_set_oom_score_adj(info->pid, OOMADJ_SERVICE_MIN);
+                               break;
+                       }
+               }
+       }
+}
+
+static void free_app_list(void)
+{
+       if(proc_apps) {
+               g_ptr_array_foreach(proc_apps, (GFunc)g_free, NULL);
+               g_ptr_array_free(proc_apps, true);
+               proc_apps = NULL;
+       }
+
+       if(vip_apps) {
+               g_ptr_array_foreach(vip_apps, (GFunc)g_free, NULL);
+               g_ptr_array_free(vip_apps, true);
+               vip_apps = NULL;
+       }
+}
+
+static int allocate_app_list(void)
+{
+       vip_apps = g_ptr_array_new();
+       if(!vip_apps) {
+               _E("lowmem : out of memory");
+               return RESOURCED_ERROR_OUT_OF_MEMORY;
+       }
+
+       proc_apps = g_ptr_array_new();
+       if(!proc_apps) {
+               _E("lowmem : out of memory");
+               free_app_list();
+               return RESOURCED_ERROR_OUT_OF_MEMORY;
+       }
+
+       return RESOURCED_ERROR_NONE;
+}
+
+static int set_vip_list(void)
+{
+       pid_t pid = -1;
+       int ret = 0;
+       DIR *dp;
+       struct dirent dentry;
+       struct dirent *result;
+       char appname[PROC_NAME_MAX];
+       int appname_len;
+       struct proc_info *info;
+
+       if (!proc_apps)
+               return RESOURCED_ERROR_INVALID_PARAMETER;
+
+       /* load all (appname,pid) pairs in the /proc to the proc_apps*/
+       dp = opendir("/proc");
+       if (!dp) {
+               _E("fail to open /proc");
+               return RESOURCED_ERROR_FAIL;
+       }
+
+       while(!readdir_r(dp, &dentry, &result) && result != NULL) {
+               if (!isdigit(dentry.d_name[0]))
+                       continue;
+
+               pid = atoi(dentry.d_name);
+               if(!pid)
+                       continue;
+               ret = proc_get_cmdline(pid, appname);
+
+               if (ret == RESOURCED_ERROR_NONE) {
+                       info = (struct proc_info *)malloc(sizeof(struct proc_info)); // check malloc
+                       info->pid = pid;
+                       appname_len = strlen(appname);
+                       strncpy(info->cmdline, appname, appname_len);
+                       info->cmdline[appname_len] = '\0';
+                       g_ptr_array_add(proc_apps, (gpointer)info);
+               }
+       }
+       closedir(dp);
+
+       g_ptr_array_foreach(vip_apps, (GFunc)set_vip_oom_score_adj, NULL);
+
+       return RESOURCED_ERROR_NONE;
+}
+
 /* To Do: should we need lowmem_fd_start, lowmem_fd_stop ?? */
 int lowmem_init(void)
 {
@@ -2035,7 +2136,19 @@ int lowmem_init(void)
 
        init_memcg_params();
        setup_memcg_params();
-       config_parse(MEM_CONF_FILE, load_vip_config, NULL);
+
+       if(allocate_app_list() != RESOURCED_ERROR_NONE)
+               _E("allocate_proc_list FAIL");
+
+       if(config_parse(MEM_CONF_FILE, load_vip_config, NULL))
+               _E("(%s) parse Fail", MEM_CONF_FILE);
+
+       if(set_vip_list() != RESOURCED_ERROR_NONE)
+               _E("set_vip_list FAIL");
+
+       /* Free the GPtrArray's as these are not required anymore. */
+       free_app_list();
+
        config_parse(MEM_CONF_FILE, load_mem_config, NULL);
 
        create_memcgs();
@@ -2043,7 +2156,7 @@ int lowmem_init(void)
 
        ret = oom_thread_create();
        if (ret) {
-               _E("oom thread create failed\n");
+               _E("oom thread create failed");
                return ret;
        }