diff options
Diffstat (limited to 'kernel/exit.c')
| -rw-r--r-- | kernel/exit.c | 21 | 
1 files changed, 7 insertions, 14 deletions
| diff --git a/kernel/exit.c b/kernel/exit.c index c9e5a1c14e0..c7740fa3252 100644 --- a/kernel/exit.c +++ b/kernel/exit.c @@ -642,35 +642,31 @@ retry:  	/*  	 * 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. +	 * ptrace or page migration (get_task_mm()).  Mark owner as NULL.  	 */ -	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); +	/* +	 * Delay read_unlock() till we have the task_lock() +	 * to ensure that c does not slip away underneath us +	 */ +	read_unlock(&tasklist_lock);  	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);  }  #endif /* CONFIG_MM_OWNER */ @@ -1055,10 +1051,7 @@ NORET_TYPE void do_exit(long code)  				preempt_count());  	acct_update_integrals(tsk); -	if (tsk->mm) { -		update_hiwater_rss(tsk->mm); -		update_hiwater_vm(tsk->mm); -	} +  	group_dead = atomic_dec_and_test(&tsk->signal->live);  	if (group_dead) {  		hrtimer_cancel(&tsk->signal->real_timer); | 
