android/lowmemorykiller: Ignore tasks with freed mm
A killed task can stay in the task list long after its
memory has been returned to the system, therefore
ignore any tasks whose mm struct has been freed.
Change-Id: I76394b203b4ab2312437c839976f0ecb7b6dde4e
Signed-off-by: Liam Mark <lmark@codeaurora.org>
Signed-off-by: Vinayak Menon <vinmenon@codeaurora.org>
diff --git a/kernel/exit.c b/kernel/exit.c
index 83e8afa..35ff283 100644
--- a/kernel/exit.c
+++ b/kernel/exit.c
@@ -465,6 +465,7 @@
{
struct mm_struct *mm = tsk->mm;
struct core_state *core_state;
+ int mm_released;
mm_release(tsk, mm);
if (!mm)
@@ -511,9 +512,12 @@
enter_lazy_tlb(mm, current);
task_unlock(tsk);
mm_update_next_owner(mm);
- mmput(mm);
+
+ mm_released = mmput(mm);
if (test_thread_flag(TIF_MEMDIE))
exit_oom_victim();
+ if (mm_released)
+ set_tsk_thread_flag(tsk, TIF_MM_RELEASED);
}
static struct task_struct *find_alive_thread(struct task_struct *p)
diff --git a/kernel/fork.c b/kernel/fork.c
index 33663b0..f90327b 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -877,12 +877,17 @@
/*
* Decrement the use count and release all resources for an mm.
*/
-void mmput(struct mm_struct *mm)
+int mmput(struct mm_struct *mm)
{
+ int mm_freed = 0;
might_sleep();
- if (atomic_dec_and_test(&mm->mm_users))
+ if (atomic_dec_and_test(&mm->mm_users)) {
__mmput(mm);
+ mm_freed = 1;
+ }
+
+ return mm_freed;
}
EXPORT_SYMBOL_GPL(mmput);