kernel/fork.c:copy_process(): consolidate the lockless CLONE_THREAD checks
copy_process() does a lot of "chaotic" initializations and checks CLONE_THREAD twice before it takes tasklist. In particular it sets "p->group_leader = p" and then changes it again under tasklist if !thread_group_leader(p). This looks a bit confusing, lets create a single "if (CLONE_THREAD)" block which initializes ->exit_signal, ->group_leader, and ->tgid. Signed-off-by: Oleg Nesterov <oleg@redhat.com> Cc: "Eric W. Biederman" <ebiederm@xmission.com> Cc: Michal Hocko <mhocko@suse.cz> Cc: Pavel Emelyanov <xemul@parallels.com> Cc: Sergey Dyasly <dserrg@gmail.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
		
					parent
					
						
							
								8190773985
							
						
					
				
			
			
				commit
				
					
						18c830df77
					
				
			
		
					 1 changed files with 16 additions and 17 deletions
				
			
		| 
						 | 
					@ -1360,11 +1360,6 @@ static struct task_struct *copy_process(unsigned long clone_flags,
 | 
				
			||||||
			goto bad_fork_cleanup_io;
 | 
								goto bad_fork_cleanup_io;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	p->pid = pid_nr(pid);
 | 
					 | 
				
			||||||
	p->tgid = p->pid;
 | 
					 | 
				
			||||||
	if (clone_flags & CLONE_THREAD)
 | 
					 | 
				
			||||||
		p->tgid = current->tgid;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	p->set_child_tid = (clone_flags & CLONE_CHILD_SETTID) ? child_tidptr : NULL;
 | 
						p->set_child_tid = (clone_flags & CLONE_CHILD_SETTID) ? child_tidptr : NULL;
 | 
				
			||||||
	/*
 | 
						/*
 | 
				
			||||||
	 * Clear TID on mm_release()?
 | 
						 * Clear TID on mm_release()?
 | 
				
			||||||
| 
						 | 
					@ -1400,12 +1395,19 @@ static struct task_struct *copy_process(unsigned long clone_flags,
 | 
				
			||||||
	clear_all_latency_tracing(p);
 | 
						clear_all_latency_tracing(p);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* ok, now we should be set up.. */
 | 
						/* ok, now we should be set up.. */
 | 
				
			||||||
	if (clone_flags & CLONE_THREAD)
 | 
						p->pid = pid_nr(pid);
 | 
				
			||||||
 | 
						if (clone_flags & CLONE_THREAD) {
 | 
				
			||||||
		p->exit_signal = -1;
 | 
							p->exit_signal = -1;
 | 
				
			||||||
	else if (clone_flags & CLONE_PARENT)
 | 
							p->group_leader = current->group_leader;
 | 
				
			||||||
 | 
							p->tgid = current->tgid;
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							if (clone_flags & CLONE_PARENT)
 | 
				
			||||||
			p->exit_signal = current->group_leader->exit_signal;
 | 
								p->exit_signal = current->group_leader->exit_signal;
 | 
				
			||||||
		else
 | 
							else
 | 
				
			||||||
			p->exit_signal = (clone_flags & CSIGNAL);
 | 
								p->exit_signal = (clone_flags & CSIGNAL);
 | 
				
			||||||
 | 
							p->group_leader = p;
 | 
				
			||||||
 | 
							p->tgid = p->pid;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	p->pdeath_signal = 0;
 | 
						p->pdeath_signal = 0;
 | 
				
			||||||
	p->exit_state = 0;
 | 
						p->exit_state = 0;
 | 
				
			||||||
| 
						 | 
					@ -1414,15 +1416,13 @@ static struct task_struct *copy_process(unsigned long clone_flags,
 | 
				
			||||||
	p->nr_dirtied_pause = 128 >> (PAGE_SHIFT - 10);
 | 
						p->nr_dirtied_pause = 128 >> (PAGE_SHIFT - 10);
 | 
				
			||||||
	p->dirty_paused_when = 0;
 | 
						p->dirty_paused_when = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/*
 | 
					 | 
				
			||||||
	 * Ok, make it visible to the rest of the system.
 | 
					 | 
				
			||||||
	 * We dont wake it up yet.
 | 
					 | 
				
			||||||
	 */
 | 
					 | 
				
			||||||
	p->group_leader = p;
 | 
					 | 
				
			||||||
	INIT_LIST_HEAD(&p->thread_group);
 | 
						INIT_LIST_HEAD(&p->thread_group);
 | 
				
			||||||
	p->task_works = NULL;
 | 
						p->task_works = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Need tasklist lock for parent etc handling! */
 | 
						/*
 | 
				
			||||||
 | 
						 * Make it visible to the rest of the system, but dont wake it up yet.
 | 
				
			||||||
 | 
						 * Need tasklist lock for parent etc handling!
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
	write_lock_irq(&tasklist_lock);
 | 
						write_lock_irq(&tasklist_lock);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* CLONE_PARENT re-uses the old parent */
 | 
						/* CLONE_PARENT re-uses the old parent */
 | 
				
			||||||
| 
						 | 
					@ -1476,7 +1476,6 @@ static struct task_struct *copy_process(unsigned long clone_flags,
 | 
				
			||||||
			current->signal->nr_threads++;
 | 
								current->signal->nr_threads++;
 | 
				
			||||||
			atomic_inc(¤t->signal->live);
 | 
								atomic_inc(¤t->signal->live);
 | 
				
			||||||
			atomic_inc(¤t->signal->sigcnt);
 | 
								atomic_inc(¤t->signal->sigcnt);
 | 
				
			||||||
			p->group_leader = current->group_leader;
 | 
					 | 
				
			||||||
			list_add_tail_rcu(&p->thread_group,
 | 
								list_add_tail_rcu(&p->thread_group,
 | 
				
			||||||
					  &p->group_leader->thread_group);
 | 
										  &p->group_leader->thread_group);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue