Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 4f1cdd2b authored by Liam Mark's avatar Liam Mark Committed by Vinayak Menon
Browse files

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: default avatarLiam Mark <lmark@codeaurora.org>
Signed-off-by: default avatarVinayak Menon <vinmenon@codeaurora.org>
parent 11a71a36
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -148,6 +148,7 @@ extern int vfp_restore_user_hwstate(struct user_vfp __user *,
#define TIF_USING_IWMMXT	17
#define TIF_MEMDIE		18	/* is terminating due to OOM killer */
#define TIF_RESTORE_SIGMASK	20
#define TIF_MM_RELEASED	21	/* task MM has been released */

#define _TIF_SIGPENDING		(1 << TIF_SIGPENDING)
#define _TIF_NEED_RESCHED	(1 << TIF_NEED_RESCHED)
+1 −0
Original line number Diff line number Diff line
@@ -63,6 +63,7 @@ static inline struct thread_info *current_thread_info(void)
#define TIF_RESTORE_SIGMASK	7
#define TIF_NOTIFY_RESUME	8
#define TIF_SECCOMP		9	/* secure computing */
#define TIF_MM_RELEASED         10	/* task MM has been released */

#define _TIF_SYSCALL_TRACE	(1 << TIF_SYSCALL_TRACE)
#define _TIF_SIGPENDING		(1 << TIF_SIGPENDING)
+23 −2
Original line number Diff line number Diff line
@@ -83,6 +83,22 @@ static unsigned long lowmem_count(struct shrinker *s,
		global_node_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 int test_task_lmk_waiting(struct task_struct *p)
{
	struct task_struct *t = p;
@@ -158,6 +174,10 @@ static unsigned long lowmem_scan(struct shrinker *s, struct shrink_control *sc)
		if (tsk->flags & PF_KTHREAD)
			continue;

		/* if task no longer has any memory ignore it */
		if (test_task_flag(tsk, TIF_MM_RELEASED))
			continue;

		if (time_before_eq(jiffies, lowmem_deathpending_timeout)) {
			if (test_task_lmk_waiting(tsk)) {
				rcu_read_unlock();
@@ -218,13 +238,14 @@ static unsigned long lowmem_scan(struct shrinker *s, struct shrink_control *sc)
			     free);
		lowmem_deathpending_timeout = jiffies + HZ;
		rem += selected_tasksize;
		rcu_read_unlock();
		/* give the system time to free up the memory */
		msleep_interruptible(20);
	}
	} else
		rcu_read_unlock();

	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;
}
+1 −1
Original line number Diff line number Diff line
@@ -3217,7 +3217,7 @@ static inline bool mmget_not_zero(struct mm_struct *mm)
}

/* mmput gets rid of the mappings and all user-space */
extern void mmput(struct mm_struct *);
extern int mmput(struct mm_struct *mm);
#ifdef CONFIG_MMU
/* same as above but performs the slow path from the async context. Can
 * be called from the atomic context as well
+5 −1
Original line number Diff line number Diff line
@@ -465,6 +465,7 @@ static void exit_mm(struct task_struct *tsk)
{
	struct mm_struct *mm = tsk->mm;
	struct core_state *core_state;
	int mm_released;

	mm_release(tsk, mm);
	if (!mm)
@@ -511,9 +512,12 @@ static void exit_mm(struct task_struct *tsk)
	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)
Loading