Move "exit_robust_list" into mm_release()

We don't want to get rid of the futexes just at exit() time, we want to
drop them when doing an execve() too, since that gets rid of the
previous VM image too.

Doing it at mm_release() time means that we automatically always do it
when we disassociate a VM map from the task.

Reported-by: pageexec@freemail.hu
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Nick Piggin <npiggin@suse.de>
Cc: Hugh Dickins <hugh@veritas.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Brad Spengler <spender@grsecurity.net>
Cc: Alex Efros <powerman@powerman.name>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Oleg Nesterov <oleg@redhat.com>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
void mm_update_next_owner(struct mm_struct *mm)
{
	struct task_struct *c, *g, *p = current;

retry:
	if (!mm_need_new_owner(mm, p))
		return;

	read_lock(&tasklist_lock);
	/*
	 * Search in the children
	 */
	list_for_each_entry(c, &p->children, sibling) {
		if (c->mm == mm)
			goto assign_new_owner;
	}

	/*
	 * Search in the siblings
	 */
	list_for_each_entry(c, &p->parent->children, sibling) {
		if (c->mm == mm)
			goto assign_new_owner;
	}

	/*
	 * Search through everything else. We should not get
	 * here often
	 */
	do_each_thread(g, c) {
		if (c->mm == mm)
			goto assign_new_owner;
	} while_each_thread(g, c);

	read_unlock(&tasklist_lock);
	/*
	 * We found no owner yet mm_users > 1: this implies that we are
	 * most likely racing with swapoff (try_to_unuse()) or /proc or
	 * ptrace or page migration (get_task_mm()).  Mark owner as NULL,
	 * so that subsystems can understand the callback and take action.
	 */
	down_write(&mm->mmap_sem);
	cgroup_mm_owner_callbacks(mm->owner, NULL);
	mm->owner = NULL;
	up_write(&mm->mmap_sem);
	return;

assign_new_owner:
	BUG_ON(c == p);
	get_task_struct(c);
	read_unlock(&tasklist_lock);
	down_write(&mm->mmap_sem);
	/*
	 * The task_lock protects c->mm from changing.
	 * We always want mm->owner->mm == mm
	 */
	task_lock(c);
	if (c->mm != mm) {
		task_unlock(c);
		up_write(&mm->mmap_sem);
		put_task_struct(c);
		goto retry;
	}
	cgroup_mm_owner_callbacks(mm->owner, c);
	mm->owner = c;
	task_unlock(c);
	up_write(&mm->mmap_sem);
	put_task_struct(c);
}

void mm_update_next_owner(struct mm_struct *mm)
{
	struct task_struct *c, *g, *p = current;

retry:
	if (!mm_need_new_owner(mm, p))
		return;

	read_lock(&tasklist_lock);
	/*
	 * Search in the children
	 */
	list_for_each_entry(c, &p->children, sibling) {
		if (c->mm == mm)
			goto assign_new_owner;
	}

	/*
	 * Search in the siblings
	 */
	list_for_each_entry(c, &p->parent->children, sibling) {
		if (c->mm == mm)
			goto assign_new_owner;
	}

	/*
	 * Search through everything else. We should not get
	 * here often
	 */
	do_each_thread(g, c) {
		if (c->mm == mm)
			goto assign_new_owner;
	} while_each_thread(g, c);

	read_unlock(&tasklist_lock);
	/*
	 * We found no owner yet mm_users > 1: this implies that we are
	 * most likely racing with swapoff (try_to_unuse()) or /proc or
	 * ptrace or page migration (get_task_mm()).  Mark owner as NULL,
	 * so that subsystems can understand the callback and take action.
	 */
	down_write(&mm->mmap_sem);
	cgroup_mm_owner_callbacks(mm->owner, NULL);
	mm->owner = NULL;
	up_write(&mm->mmap_sem);
	return;

assign_new_owner:
	BUG_ON(c == p);
	get_task_struct(c);
	read_unlock(&tasklist_lock);
	down_write(&mm->mmap_sem);
	/*
	 * The task_lock protects c->mm from changing.
	 * We always want mm->owner->mm == mm
	 */
	task_lock(c);
	if (c->mm != mm) {
		task_unlock(c);
		up_write(&mm->mmap_sem);
		put_task_struct(c);
		goto retry;
	}
	cgroup_mm_owner_callbacks(mm->owner, c);
	mm->owner = c;
	task_unlock(c);
	up_write(&mm->mmap_sem);
	put_task_struct(c);
}
