diff options
| author | Liam Mark <lmark@codeaurora.org> | 2013-01-25 12:40:18 -0800 |
|---|---|---|
| committer | Jeevan Shriram <jshriram@codeaurora.org> | 2016-04-07 15:57:13 -0700 |
| commit | cadb28dcdb660458889a13537c1c3a4620abb8da (patch) | |
| tree | b6fc3f276e7bc64d57edcd74781d865d764cbe78 /drivers | |
| parent | 12e54c35abcc4dc75081c7bb79dbdaaf24b31fd0 (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.c | 21 |
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; } |
