memory: reclaim memory when there is no high order buddy in kernel 56/131456/4
authorByungSoo Kim <bs1770.kim@samsung.com>
Wed, 26 Apr 2017 13:31:30 +0000 (22:31 +0900)
committerKichan Kwon <k_c.kwon@samsung.com>
Mon, 3 Jul 2017 10:59:12 +0000 (19:59 +0900)
Even though there is enough memory, kswapd uses much cpu
when there is no high order buddy.
We have already triggered memory compaction.
But, if many background applications are running,
kernel can't reduce fragmentation.
The best method for reducing kernel fragmentation is
to run proactive LMK in resourced.

For example, when automatic test tool launched many applications continuously,
there were so many background applications over 24 numbers
and we could observe kswapd always used 5% cpu in order to reclaim memory
until available memory was not enough in medium threshold.

Therefore it is necessary to check buddy info and start proactive LMK.
It has been already applied in low memory device and we got better result.
Moreover, it will be better in even high memory device also.

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

index 2f0ea4975253b99ddf239111747fd55ff9f061f5..cfc6a3560f5f16ed9efcd0ccdb153fe482b880c3 100644 (file)
@@ -410,16 +410,17 @@ int clear_logs(void *data)
        char fpath[BUF_MAX];
        char *fname;
        char *dir = (char*)data;
-       int len = strlen(dir);
+       int len;
 
-       if (!dir || len <= 0) {
-               _E("Invalid parameter");
+       if (!dir) {
+               _E("Invalid parameter - dir is NULL");
                return RESOURCED_ERROR_INVALID_PARAMETER;
        }
 
-       if (len >= BUF_MAX - 1) {
-               _E("Directory path is too long");
-               return RESOURCED_ERROR_FAIL;
+       len = strlen(dir);
+       if (len <= 0 || len >= BUF_MAX -1) {
+               _E("Invalid parameter - Directory path is too short or too long");
+               return RESOURCED_ERROR_INVALID_PARAMETER;
        }
 
        n = scandir(dir, &namelist, memps_file_select, alphasort);
@@ -1690,6 +1691,10 @@ static void lowmem_deactivate_worker(void)
        lowmem_drain_queue(&lmw);
 
        ctl = LOWMEM_NEW_REQUEST();
+       if (!ctl) {
+               _E("Critical - g_slice alloc failed - Lowmem cannot be deactivated");
+               return;
+       }
        ctl->flags = OOM_DROP;
        g_async_queue_push(lmw.queue, ctl);
        g_async_queue_unref(lmw.queue);
@@ -1874,6 +1879,22 @@ static void lowmem_trigger_force_reclaim(unsigned int size)
        }
 }
 
+static bool lowmem_fragmentated(void)
+{
+       struct buddyinfo bi;
+       int ret;
+
+       ret = proc_get_buddyinfo("Normal", &bi);
+       if (ret < 0)
+               return false;
+
+       if (bi.page[PAGE_32K] + bi.page[PAGE_64K] + bi.page[PAGE_128K] == 0) {
+               _I("fragmentation detected, need to execute proactive oom killer");
+               return true;
+       }
+       return false;
+}
+
 static void lowmem_proactive_oom_killer(int flags, char *appid)
 {
        unsigned int before;
@@ -1919,13 +1940,6 @@ static void lowmem_proactive_oom_killer(int flags, char *appid)
        }
 #endif
 
-       /*
-        * When there is no history data for the launching app but it is
-        * indicated as PROC_LARGEMEMORY, run oom killer based on proactive
-        * threshold.
-        */
-       if (!(flags & PROC_LARGEMEMORY))
-               return;
        /*
         * run proactive oom killer only when available is larger than
         * proactive threshold
@@ -1933,6 +1947,15 @@ static void lowmem_proactive_oom_killer(int flags, char *appid)
        if (!proactive_threshold || before >= proactive_threshold)
                return;
 
+       /*
+        * When there is no history data for the launching app,
+        * it is necessary to check current fragmentation state or application manifest file.
+        * So, resourced feels proactive LMK is required, run oom killer based on dynamic
+        * threshold.
+        */
+       if (!lowmem_fragmentated() && !(flags & PROC_LARGEMEMORY))
+               return;
+
        /*
         * free THRESHOLD_MARGIN more than real should be freed,
         * because launching app is consuming up the memory.