summaryrefslogtreecommitdiff
path: root/mm/vmpressure.c
diff options
context:
space:
mode:
authorVinayak Menon <vinmenon@codeaurora.org>2016-09-19 12:44:15 +0530
committerVinayak Menon <vinmenon@codeaurora.org>2016-12-16 20:25:45 +0530
commitcfc8db22aea588a7aeae9f849a727a0ce8479cc0 (patch)
tree1738659c9d26755c77e355fcf4a07ae13ae09b81 /mm/vmpressure.c
parent3162449f7d245d45f007d4ea3224576ddf1bcc63 (diff)
mm: vmpressure: make vmpressure window variable
Right now the vmpressure window is of constant size 2MB, which works well with the following exceptions. 1) False vmpressure triggers are seen when the RAM size is greater than 3GB. This results in lowmemorykiller, which uses vmpressure events, killing tasks unnecessarily. 2) Vmpressure events are received late under memory pressure. This behaviour is seen prominently in <=2GB RAM targets. This results in lowmemorykiller kicking in late to kill tasks resulting in avoidable page cache reclaim. The problem analysis shows that the issue is with the constant size of the vmpressure window which does not adapt to the varying memory conditions. This patch recalculates the vmpressure window size at the end of each window. The chosen window size is proportional to the total of free and cached memory at that point. Change-Id: I7e9ef4ddd82e2c2dd04ce09ec8d58a8829cfb64d Signed-off-by: Vinayak Menon <vinmenon@codeaurora.org>
Diffstat (limited to 'mm/vmpressure.c')
-rw-r--r--mm/vmpressure.c28
1 files changed, 27 insertions, 1 deletions
diff --git a/mm/vmpressure.c b/mm/vmpressure.c
index 75b7ffe9e7a3..f514dc40dab1 100644
--- a/mm/vmpressure.c
+++ b/mm/vmpressure.c
@@ -41,7 +41,7 @@
* TODO: Make the window size depend on machine size, as we do for vmstat
* thresholds. Currently we set it to 512 pages (2MB for 4KB pages).
*/
-static const unsigned long vmpressure_win = SWAP_CLUSTER_MAX * 16;
+static unsigned long vmpressure_win = SWAP_CLUSTER_MAX * 16;
/*
* These thresholds are used when we account memory pressure through
@@ -290,6 +290,29 @@ void vmpressure_memcg(gfp_t gfp, struct mem_cgroup *memcg,
schedule_work(&vmpr->work);
}
+void calculate_vmpressure_win(void)
+{
+ long x;
+
+ x = global_page_state(NR_FILE_PAGES) -
+ global_page_state(NR_SHMEM) -
+ total_swapcache_pages() +
+ global_page_state(NR_FREE_PAGES);
+ if (x < 1)
+ x = 1;
+ /*
+ * For low (free + cached), vmpressure window should be
+ * small, and high for higher values of (free + cached).
+ * But it should not be linear as well. This ensures
+ * timely vmpressure notifications when system is under
+ * memory pressure, and optimal number of events when
+ * cached is high. The sqaure root function is empirically
+ * found to serve the purpose.
+ */
+ x = int_sqrt(x);
+ vmpressure_win = x;
+}
+
void vmpressure_global(gfp_t gfp, unsigned long scanned,
unsigned long reclaimed)
{
@@ -304,6 +327,9 @@ void vmpressure_global(gfp_t gfp, unsigned long scanned,
return;
spin_lock(&vmpr->sr_lock);
+ if (!vmpr->scanned)
+ calculate_vmpressure_win();
+
vmpr->scanned += scanned;
vmpr->reclaimed += reclaimed;