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

Commit 76afd35f authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "mm, oom_reaper: fix memory corruption"

parents a6a6e398 065e76dd
Loading
Loading
Loading
Loading
+9 −0
Original line number Diff line number Diff line
@@ -63,6 +63,15 @@ static inline bool tsk_is_oom_victim(struct task_struct * tsk)
	return tsk->signal->oom_mm;
}

/*
 * Use this helper if tsk->mm != mm and the victim mm needs a special
 * handling. This is guaranteed to stay true after once set.
 */
static inline bool mm_is_oom_victim(struct mm_struct *mm)
{
	return test_bit(MMF_OOM_VICTIM, &mm->flags);
}

extern unsigned long oom_badness(struct task_struct *p,
		struct mem_cgroup *memcg, const nodemask_t *nodemask,
		unsigned long totalpages);
+1 −0
Original line number Diff line number Diff line
@@ -636,6 +636,7 @@ static inline int get_dumpable(struct mm_struct *mm)
#define MMF_OOM_SKIP		21	/* mm is of no interest for the OOM killer */
#define MMF_UNSTABLE		22	/* mm is unstable for copy_from_user */
#define MMF_HUGE_ZERO_PAGE	23      /* mm has ever used the global huge zero page */
#define MMF_OOM_VICTIM		25      /* mm is the oom victim */

#define MMF_INIT_MASK		(MMF_DUMPABLE_MASK | MMF_DUMP_FILTER_MASK)

+5 −5
Original line number Diff line number Diff line
@@ -2984,20 +2984,20 @@ void exit_mmap(struct mm_struct *mm)
	/* Use -1 here to ensure all VMAs in the mm are unmapped */
	unmap_vmas(&tlb, vma, 0, -1);

	set_bit(MMF_OOM_SKIP, &mm->flags);
	if (unlikely(tsk_is_oom_victim(current))) {
	if (unlikely(mm_is_oom_victim(mm))) {
		/*
		 * Wait for oom_reap_task() to stop working on this
		 * mm. Because MMF_OOM_SKIP is already set before
		 * calling down_read(), oom_reap_task() will not run
		 * on this "mm" post up_write().
		 *
		 * tsk_is_oom_victim() cannot be set from under us
		 * either because current->mm is already set to NULL
		 * mm_is_oom_victim() cannot be set from under us
		 * either because victim->mm is already set to NULL
		 * under task_lock before calling mmput and oom_mm is
		 * set not NULL by the OOM killer only if current->mm
		 * set not NULL by the OOM killer only if victim->mm
		 * is found not NULL while holding the task_lock.
		 */
		set_bit(MMF_OOM_SKIP, &mm->flags);
		down_write(&mm->mmap_sem);
		up_write(&mm->mmap_sem);
	}
+3 −1
Original line number Diff line number Diff line
@@ -677,8 +677,10 @@ static void mark_oom_victim(struct task_struct *tsk)
		return;

	/* oom_mm is bound to the signal struct life time. */
	if (!cmpxchg(&tsk->signal->oom_mm, NULL, mm))
	if (!cmpxchg(&tsk->signal->oom_mm, NULL, mm)) {
		atomic_inc(&tsk->signal->oom_mm->mm_count);
		set_bit(MMF_OOM_VICTIM, &mm->flags);
	}

	/*
	 * Make sure that the task is woken up from uninterruptible sleep