summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorLiam Mark <lmark@codeaurora.org>2013-01-25 12:40:18 -0800
committerJeevan Shriram <jshriram@codeaurora.org>2016-04-07 15:57:13 -0700
commitcadb28dcdb660458889a13537c1c3a4620abb8da (patch)
treeb6fc3f276e7bc64d57edcd74781d865d764cbe78 /drivers
parent12e54c35abcc4dc75081c7bb79dbdaaf24b31fd0 (diff)
android/lowmemorykiller: Wait for memory to be freed
The memory reclaim code needs to give time to the system to return the memory from a killed process otherwise the memory reclaim code could run continuously, in multiple threads, which could starve both the watchdog thread and the thread which is responsible for returning the memory from the killed process. Change-Id: Ieded4bfe038ca936247fa4b638070e979b02eaa1 CRs-fixed: 447740 Signed-off-by: Liam Mark <lmark@codeaurora.org>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/staging/android/lowmemorykiller.c21
1 files changed, 19 insertions, 2 deletions
diff --git a/drivers/staging/android/lowmemorykiller.c b/drivers/staging/android/lowmemorykiller.c
index 2ad18044a11b..b9be6d9a52ef 100644
--- a/drivers/staging/android/lowmemorykiller.c
+++ b/drivers/staging/android/lowmemorykiller.c
@@ -42,6 +42,8 @@
#include <linux/rcupdate.h>
#include <linux/profile.h>
#include <linux/notifier.h>
+#include <linux/mutex.h>
+#include <linux/delay.h>
#define CREATE_TRACE_POINTS
#include "trace/lowmemorykiller.h"
@@ -95,6 +97,8 @@ static int test_task_flag(struct task_struct *p, int flag)
return 0;
}
+static DEFINE_MUTEX(scan_mutex);
+
static unsigned long lowmem_scan(struct shrinker *s, struct shrink_control *sc)
{
struct task_struct *tsk;
@@ -107,8 +111,14 @@ static unsigned long lowmem_scan(struct shrinker *s, struct shrink_control *sc)
int selected_tasksize = 0;
short selected_oom_score_adj;
int array_size = ARRAY_SIZE(lowmem_adj);
- int other_free = global_page_state(NR_FREE_PAGES) - totalreserve_pages;
- int other_file = global_page_state(NR_FILE_PAGES) -
+ int other_free;
+ int other_file;
+
+ if (mutex_lock_interruptible(&scan_mutex) < 0)
+ return 0;
+
+ other_free = global_page_state(NR_FREE_PAGES);
+ other_file = global_page_state(NR_FILE_PAGES) -
global_page_state(NR_SHMEM) -
total_swapcache_pages();
@@ -131,6 +141,7 @@ static unsigned long lowmem_scan(struct shrinker *s, struct shrink_control *sc)
if (min_score_adj == OOM_SCORE_ADJ_MAX + 1) {
lowmem_print(5, "lowmem_scan %lu, %x, return 0\n",
sc->nr_to_scan, sc->gfp_mask);
+ mutex_unlock(&scan_mutex);
return 0;
}
@@ -147,6 +158,9 @@ static unsigned long lowmem_scan(struct shrinker *s, struct shrink_control *sc)
if (time_before_eq(jiffies, lowmem_deathpending_timeout)) {
if (test_task_flag(tsk, TIF_MEMDIE)) {
rcu_read_unlock();
+ /* give the system time to free up the memory */
+ msleep_interruptible(20);
+ mutex_unlock(&scan_mutex);
return 0;
}
}
@@ -206,11 +220,14 @@ static unsigned long lowmem_scan(struct shrinker *s, struct shrink_control *sc)
free);
lowmem_deathpending_timeout = jiffies + HZ;
rem += selected_tasksize;
+ /* give the system time to free up the memory */
+ msleep_interruptible(20);
}
lowmem_print(4, "lowmem_scan %lu, %x, return %lu\n",
sc->nr_to_scan, sc->gfp_mask, rem);
rcu_read_unlock();
+ mutex_unlock(&scan_mutex);
return rem;
}