diff options
Diffstat (limited to 'kernel/exit.c')
| -rw-r--r-- | kernel/exit.c | 38 | 
1 files changed, 18 insertions, 20 deletions
| diff --git a/kernel/exit.c b/kernel/exit.c index 6f50ef55a6f3..546774a31a66 100644 --- a/kernel/exit.c +++ b/kernel/exit.c @@ -68,10 +68,10 @@ static void __unhash_process(struct task_struct *p)  		detach_pid(p, PIDTYPE_SID);  		list_del_rcu(&p->tasks); +		list_del_init(&p->sibling);  		__get_cpu_var(process_counts)--;  	}  	list_del_rcu(&p->thread_group); -	list_del_init(&p->sibling);  }  /* @@ -736,12 +736,9 @@ static struct task_struct *find_new_reaper(struct task_struct *father)  /*  * Any that need to be release_task'd are put on the @dead list.   */ -static void reparent_thread(struct task_struct *father, struct task_struct *p, +static void reparent_leader(struct task_struct *father, struct task_struct *p,  				struct list_head *dead)  { -	if (p->pdeath_signal) -		group_send_sig_info(p->pdeath_signal, SEND_SIG_NOINFO, p); -  	list_move_tail(&p->sibling, &p->real_parent->children);  	if (task_detached(p)) @@ -780,12 +777,18 @@ static void forget_original_parent(struct task_struct *father)  	reaper = find_new_reaper(father);  	list_for_each_entry_safe(p, n, &father->children, sibling) { -		p->real_parent = reaper; -		if (p->parent == father) { -			BUG_ON(task_ptrace(p)); -			p->parent = p->real_parent; -		} -		reparent_thread(father, p, &dead_children); +		struct task_struct *t = p; +		do { +			t->real_parent = reaper; +			if (t->parent == father) { +				BUG_ON(task_ptrace(t)); +				t->parent = t->real_parent; +			} +			if (t->pdeath_signal) +				group_send_sig_info(t->pdeath_signal, +						    SEND_SIG_NOINFO, t); +		} while_each_thread(p, t); +		reparent_leader(father, p, &dead_children);  	}  	write_unlock_irq(&tasklist_lock); @@ -933,7 +936,7 @@ NORET_TYPE void do_exit(long code)  	 * an exiting task cleaning up the robust pi futexes.  	 */  	smp_mb(); -	spin_unlock_wait(&tsk->pi_lock); +	raw_spin_unlock_wait(&tsk->pi_lock);  	if (unlikely(in_atomic()))  		printk(KERN_INFO "note: %s[%d] exited with preempt_count %d\n", @@ -1551,14 +1554,9 @@ static int do_wait_thread(struct wait_opts *wo, struct task_struct *tsk)  	struct task_struct *p;  	list_for_each_entry(p, &tsk->children, sibling) { -		/* -		 * Do not consider detached threads. -		 */ -		if (!task_detached(p)) { -			int ret = wait_consider_task(wo, 0, p); -			if (ret) -				return ret; -		} +		int ret = wait_consider_task(wo, 0, p); +		if (ret) +			return ret;  	}  	return 0; | 
