android/lowmemorykiller: Check all tasks for death pending
The lowmemorykiller uses the TIF_MEMDIE flag to help ensure it doesn't kill another task until the memory from the previously killed task has been returned to the system. However the lowmemorykiller does not currently look at tasks who do not have a tasks->mm, but just because a process doesn't have a tasks->mm does not mean that the task's memory has been fully returned to the system yet. In order to prevent the lowmemorykiller from unnecessarily killing multiple applications in a row the lowmemorykiller has been changed to ensure that previous killed tasks are no longer in the process list before attempting to kill another task. Change-Id: I7d8a8fd39ca5625e6448ed2efebfb621f6e93845 Signed-off-by: Liam Mark <lmark@codeaurora.org>
This commit is contained in:
parent
b35bd9c58b
commit
12e54c35ab
1 changed files with 23 additions and 6 deletions
|
@ -79,6 +79,22 @@ static unsigned long lowmem_count(struct shrinker *s,
|
||||||
global_page_state(NR_INACTIVE_FILE);
|
global_page_state(NR_INACTIVE_FILE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int test_task_flag(struct task_struct *p, int flag)
|
||||||
|
{
|
||||||
|
struct task_struct *t = p;
|
||||||
|
|
||||||
|
do {
|
||||||
|
task_lock(t);
|
||||||
|
if (test_tsk_thread_flag(t, flag)) {
|
||||||
|
task_unlock(t);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
task_unlock(t);
|
||||||
|
} while_each_thread(p, t);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static unsigned long lowmem_scan(struct shrinker *s, struct shrink_control *sc)
|
static unsigned long lowmem_scan(struct shrinker *s, struct shrink_control *sc)
|
||||||
{
|
{
|
||||||
struct task_struct *tsk;
|
struct task_struct *tsk;
|
||||||
|
@ -128,16 +144,17 @@ static unsigned long lowmem_scan(struct shrinker *s, struct shrink_control *sc)
|
||||||
if (tsk->flags & PF_KTHREAD)
|
if (tsk->flags & PF_KTHREAD)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
if (time_before_eq(jiffies, lowmem_deathpending_timeout)) {
|
||||||
|
if (test_task_flag(tsk, TIF_MEMDIE)) {
|
||||||
|
rcu_read_unlock();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
p = find_lock_task_mm(tsk);
|
p = find_lock_task_mm(tsk);
|
||||||
if (!p)
|
if (!p)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (test_tsk_thread_flag(p, TIF_MEMDIE) &&
|
|
||||||
time_before_eq(jiffies, lowmem_deathpending_timeout)) {
|
|
||||||
task_unlock(p);
|
|
||||||
rcu_read_unlock();
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
oom_score_adj = p->signal->oom_score_adj;
|
oom_score_adj = p->signal->oom_score_adj;
|
||||||
if (oom_score_adj < min_score_adj) {
|
if (oom_score_adj < min_score_adj) {
|
||||||
task_unlock(p);
|
task_unlock(p);
|
||||||
|
|
Loading…
Add table
Reference in a new issue