Merge "lmkd: Switch to using /proc/meminfo to have access to file cache size"
diff --git a/lmkd/lmkd.c b/lmkd/lmkd.c
index 77830a3..5eb3fbe 100644
--- a/lmkd/lmkd.c
+++ b/lmkd/lmkd.c
@@ -95,14 +95,9 @@
     "critical"
 };
 
-struct mem_size {
-    int free_mem;
-    int free_swap;
-};
-
 struct {
-    int min_free; /* recorded but not used yet */
-    int max_free;
+    int64_t min_nr_free_pages; /* recorded but not used yet */
+    int64_t max_nr_free_pages;
 } low_pressure_mem = { -1, -1 };
 
 static int level_oomadj[VMPRESS_LEVEL_COUNT];
@@ -230,13 +225,6 @@
     PARSE_SUCCESS
 };
 
-struct sysmeminfo {
-    int nr_free_pages;
-    int nr_file_pages;
-    int nr_shmem;
-    int totalreserve_pages;
-};
-
 struct adjslot_list {
     struct adjslot_list *next;
     struct adjslot_list *prev;
@@ -862,18 +850,6 @@
     return 0;
 }
 
-static int get_free_memory(struct mem_size *ms) {
-    struct sysinfo si;
-
-    if (sysinfo(&si) < 0)
-        return -1;
-
-    ms->free_mem = (int)(si.freeram * si.mem_unit / PAGE_SIZE);
-    ms->free_swap = (int)(si.freeswap * si.mem_unit / PAGE_SIZE);
-
-    return 0;
-}
-
 static int proc_get_size(int pid) {
     char path[PATH_MAX];
     char line[LINE_MAX];
@@ -1045,29 +1021,30 @@
     return mem_usage;
 }
 
-void record_low_pressure_levels(struct mem_size *free_mem) {
-    if (low_pressure_mem.min_free == -1 ||
-        low_pressure_mem.min_free > free_mem->free_mem) {
+void record_low_pressure_levels(union meminfo *mi) {
+    if (low_pressure_mem.min_nr_free_pages == -1 ||
+        low_pressure_mem.min_nr_free_pages > mi->field.nr_free_pages) {
         if (debug_process_killing) {
-            ALOGI("Low pressure min memory update from %d to %d",
-                low_pressure_mem.min_free, free_mem->free_mem);
+            ALOGI("Low pressure min memory update from %" PRId64 " to %" PRId64,
+                low_pressure_mem.min_nr_free_pages, mi->field.nr_free_pages);
         }
-        low_pressure_mem.min_free = free_mem->free_mem;
+        low_pressure_mem.min_nr_free_pages = mi->field.nr_free_pages;
     }
     /*
      * Free memory at low vmpressure events occasionally gets spikes,
      * possibly a stale low vmpressure event with memory already
      * freed up (no memory pressure should have been reported).
-     * Ignore large jumps in max_free that would mess up our stats.
+     * Ignore large jumps in max_nr_free_pages that would mess up our stats.
      */
-    if (low_pressure_mem.max_free == -1 ||
-        (low_pressure_mem.max_free < free_mem->free_mem &&
-         free_mem->free_mem - low_pressure_mem.max_free < low_pressure_mem.max_free * 0.1)) {
+    if (low_pressure_mem.max_nr_free_pages == -1 ||
+        (low_pressure_mem.max_nr_free_pages < mi->field.nr_free_pages &&
+         mi->field.nr_free_pages - low_pressure_mem.max_nr_free_pages <
+         low_pressure_mem.max_nr_free_pages * 0.1)) {
         if (debug_process_killing) {
-            ALOGI("Low pressure max memory update from %d to %d",
-                low_pressure_mem.max_free, free_mem->free_mem);
+            ALOGI("Low pressure max memory update from %" PRId64 " to %" PRId64,
+                low_pressure_mem.max_nr_free_pages, mi->field.nr_free_pages);
         }
-        low_pressure_mem.max_free = free_mem->free_mem;
+        low_pressure_mem.max_nr_free_pages = mi->field.nr_free_pages;
     }
 }
 
@@ -1093,7 +1070,7 @@
     int64_t mem_usage, memsw_usage;
     int64_t mem_pressure;
     enum vmpressure_level lvl;
-    struct mem_size free_mem;
+    union meminfo mi;
     static struct timeval last_report_tm;
     static unsigned long skip_count = 0;
     enum vmpressure_level level = (enum vmpressure_level)data;
@@ -1137,15 +1114,15 @@
         skip_count = 0;
     }
 
-    if (get_free_memory(&free_mem) == 0) {
-        if (level == VMPRESS_LEVEL_LOW) {
-            record_low_pressure_levels(&free_mem);
-        }
-    } else {
+    if (meminfo_parse(&mi) < 0) {
         ALOGE("Failed to get free memory!");
         return;
     }
 
+    if (level == VMPRESS_LEVEL_LOW) {
+        record_low_pressure_levels(&mi);
+    }
+
     if (level_oomadj[level] > OOM_SCORE_ADJ_MAX) {
         /* Do not monitor this pressure level */
         return;
@@ -1197,16 +1174,20 @@
         }
     } else {
         /* If pressure level is less than critical and enough free swap then ignore */
-        if (level < VMPRESS_LEVEL_CRITICAL && free_mem.free_swap > low_pressure_mem.max_free) {
+        if (level < VMPRESS_LEVEL_CRITICAL &&
+            mi.field.free_swap > low_pressure_mem.max_nr_free_pages) {
             if (debug_process_killing) {
-                ALOGI("Ignoring pressure since %d swap pages are available ", free_mem.free_swap);
+                ALOGI("Ignoring pressure since %" PRId64
+                      " swap pages are available ",
+                      mi.field.free_swap);
             }
             return;
         }
 
         /* Free up enough memory to downgrate the memory pressure to low level */
-        if (free_mem.free_mem < low_pressure_mem.max_free) {
-            int pages_to_free = low_pressure_mem.max_free - free_mem.free_mem;
+        if (mi.field.nr_free_pages < low_pressure_mem.max_nr_free_pages) {
+            int pages_to_free = low_pressure_mem.max_nr_free_pages -
+                    mi.field.nr_free_pages;
             if (debug_process_killing) {
                 ALOGI("Trying to free %d pages", pages_to_free);
             }