CHROMIUM: low-mem: improve detection of low-memory conditions.
authorLuigi Semenzato <semenzato@chromium.org>
Thu, 23 Feb 2012 19:15:07 +0000 (11:15 -0800)
committerGrant Grundler <grundler@google.com>
Thu, 24 May 2012 22:14:38 +0000 (15:14 -0700)
This patch tries to address issues with the current low-memory detection.
Rather than using the logical conjunction of two separate conditions, we
compute a single number which estimates how much memory is available
for allocation with little or no work.

BUG=chromium-os:20086
TEST=ran kernel_LowMemNotify autotest.  Will expand test (go/crosbug/26853)

Change-Id: Ib47c4ffefac834379003c15b119a38d8ceae94a5
Signed-off-by: Luigi Semenzato <semenzato@chromium.org>
Reviewed-on: https://gerrit.chromium.org/gerrit/16499

include/linux/low-mem-notify.h

index 27978a3..31471ae 100644 (file)
@@ -15,26 +15,35 @@ extern const struct file_operations low_mem_notify_fops;
 static inline bool is_low_mem_situation(void)
 {
        const int lru_base = NR_LRU_BASE - LRU_BASE;
-       const int file_mem_multiplier = 2;  /* between 1 and 2 seems right */
        /*
-        * We declare a low-memory condition when free memory is low and there
-        * isn't much reclaimable file memory.
+        * We declare a low-memory condition when free memory plus easily
+        * reclaimable memory is low.
         */
        unsigned long free_mem = global_page_state(NR_FREE_PAGES);
        unsigned long file_mem =
                        global_page_state(lru_base + LRU_ACTIVE_FILE) +
                        global_page_state(lru_base + LRU_INACTIVE_FILE);
-       unsigned long min_file_mem = file_mem_multiplier *
-                       (min_filelist_kbytes >> (PAGE_SHIFT - 10));
-       bool is_low_mem = free_mem < low_mem_minfree && file_mem < min_file_mem;
+       unsigned long dirty_mem = global_page_state(NR_FILE_DIRTY);
+       unsigned long min_file_mem =
+                       min_filelist_kbytes >> (PAGE_SHIFT - 10);
+       /*
+        * free_mem is completely unallocated; clean file-backed memory
+        * (file_mem - dirty_mem) is easy to reclaim, except for the last
+        * min_filelist_kbytes.
+        */
+       unsigned long available_mem =
+                       free_mem - (file_mem - dirty_mem - min_file_mem);
+       bool is_low_mem = available_mem < low_mem_minfree;
 
 #ifdef CONFIG_LOW_MEM_NOTIFY_DEBUG
        {
                static bool was_low_mem;
                if (is_low_mem && !was_low_mem)
-                       printk(KERN_INFO "entering low_mem: %lu\n", in_use);
+                       printk(KERN_INFO "entering low_mem: free=%lu MB\n",
+                              free_mem >> (20 - PAGE_SHIFT));
                else if (!is_low_mem && was_low_mem)
-                       printk(KERN_INFO "exiting low_mem: %lu\n", in_use);
+                       printk(KERN_INFO "exiting low_mem: free=%lu MB\n",
+                              free_mem >> (20 - PAGE_SHIFT));
                was_low_mem = is_low_mem;
        }
 #endif