diff options
Diffstat (limited to 'kernel/exit.c')
| -rw-r--r-- | kernel/exit.c | 34 | 
1 files changed, 15 insertions, 19 deletions
diff --git a/kernel/exit.c b/kernel/exit.c index d0b7d988f87..d9eab2e4b43 100644 --- a/kernel/exit.c +++ b/kernel/exit.c @@ -121,9 +121,9 @@ static void __exit_signal(struct task_struct *tsk)  		 * We won't ever get here for the group leader, since it  		 * will have been the last reference on the signal_struct.  		 */ -		sig->utime = cputime_add(sig->utime, tsk->utime); -		sig->stime = cputime_add(sig->stime, tsk->stime); -		sig->gtime = cputime_add(sig->gtime, tsk->gtime); +		sig->utime += tsk->utime; +		sig->stime += tsk->stime; +		sig->gtime += tsk->gtime;  		sig->min_flt += tsk->min_flt;  		sig->maj_flt += tsk->maj_flt;  		sig->nvcsw += tsk->nvcsw; @@ -679,8 +679,6 @@ static void exit_mm(struct task_struct * tsk)  	tsk->mm = NULL;  	up_read(&mm->mmap_sem);  	enter_lazy_tlb(mm, current); -	/* We don't want this task to be frozen prematurely */ -	clear_freeze_flag(tsk);  	task_unlock(tsk);  	mm_update_next_owner(mm);  	mmput(mm); @@ -1040,6 +1038,7 @@ NORET_TYPE void do_exit(long code)  	exit_rcu();  	/* causes final put_task_struct in finish_task_switch(). */  	tsk->state = TASK_DEAD; +	tsk->flags |= PF_NOFREEZE;	/* tell freezer to ignore us */  	schedule();  	BUG();  	/* Avoid "noreturn function does return".  */ @@ -1255,19 +1254,9 @@ static int wait_task_zombie(struct wait_opts *wo, struct task_struct *p)  		spin_lock_irq(&p->real_parent->sighand->siglock);  		psig = p->real_parent->signal;  		sig = p->signal; -		psig->cutime = -			cputime_add(psig->cutime, -			cputime_add(tgutime, -				    sig->cutime)); -		psig->cstime = -			cputime_add(psig->cstime, -			cputime_add(tgstime, -				    sig->cstime)); -		psig->cgtime = -			cputime_add(psig->cgtime, -			cputime_add(p->gtime, -			cputime_add(sig->gtime, -				    sig->cgtime))); +		psig->cutime += tgutime + sig->cutime; +		psig->cstime += tgstime + sig->cstime; +		psig->cgtime += p->gtime + sig->gtime + sig->cgtime;  		psig->cmin_flt +=  			p->min_flt + sig->min_flt + sig->cmin_flt;  		psig->cmaj_flt += @@ -1540,8 +1529,15 @@ static int wait_consider_task(struct wait_opts *wo, int ptrace,  	}  	/* dead body doesn't have much to contribute */ -	if (p->exit_state == EXIT_DEAD) +	if (unlikely(p->exit_state == EXIT_DEAD)) { +		/* +		 * But do not ignore this task until the tracer does +		 * wait_task_zombie()->do_notify_parent(). +		 */ +		if (likely(!ptrace) && unlikely(ptrace_reparented(p))) +			wo->notask_error = 0;  		return 0; +	}  	/* slay zombie? */  	if (p->exit_state == EXIT_ZOMBIE) {  |