summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorLinux Build Service Account <lnxbuild@localhost>2017-04-18 13:57:03 -0700
committerGerrit - the friendly Code Review server <code-review@localhost>2017-04-18 13:57:02 -0700
commitce87c901721567907d20d8c8323dec3a55ce3741 (patch)
treed7637059e4a72b70d6f63eb0533e37655601817f /drivers
parentbe57574adf1332f558cb09fe6dddc57bf4d42b6c (diff)
parent1b8bb0da0b2dad2cc884580d1b38aab4cca78532 (diff)
Merge "lowmemorykiller: fix scan_mutex contention"
Diffstat (limited to 'drivers')
-rw-r--r--drivers/staging/android/lowmemorykiller.c31
1 files changed, 28 insertions, 3 deletions
diff --git a/drivers/staging/android/lowmemorykiller.c b/drivers/staging/android/lowmemorykiller.c
index 9bd60de8380f..205af6627b80 100644
--- a/drivers/staging/android/lowmemorykiller.c
+++ b/drivers/staging/android/lowmemorykiller.c
@@ -217,6 +217,22 @@ static int test_task_flag(struct task_struct *p, int flag)
return 0;
}
+static int test_task_state(struct task_struct *p, int state)
+{
+ struct task_struct *t;
+
+ for_each_thread(p, t) {
+ task_lock(t);
+ if (t->state & state) {
+ task_unlock(t);
+ return 1;
+ }
+ task_unlock(t);
+ }
+
+ return 0;
+}
+
static DEFINE_MUTEX(scan_mutex);
int can_use_cma_pages(gfp_t gfp_mask)
@@ -404,7 +420,7 @@ static unsigned long lowmem_scan(struct shrinker *s, struct shrink_control *sc)
int other_free;
int other_file;
- if (mutex_lock_interruptible(&scan_mutex) < 0)
+ if (!mutex_trylock(&scan_mutex))
return 0;
other_free = global_page_state(NR_FREE_PAGES);
@@ -462,8 +478,6 @@ 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;
}
@@ -497,6 +511,17 @@ static unsigned long lowmem_scan(struct shrinker *s, struct shrink_control *sc)
}
if (selected) {
long cache_size, cache_limit, free;
+
+ if (test_task_flag(selected, TIF_MEMDIE) &&
+ (test_task_state(selected, TASK_UNINTERRUPTIBLE))) {
+ lowmem_print(2, "'%s' (%d) is already killed\n",
+ selected->comm,
+ selected->pid);
+ rcu_read_unlock();
+ mutex_unlock(&scan_mutex);
+ return 0;
+ }
+
task_lock(selected);
send_sig(SIGKILL, selected, 0);
/*