diff options
Diffstat (limited to 'kernel/pid.c')
| -rw-r--r-- | kernel/pid.c | 42 | 
1 files changed, 20 insertions, 22 deletions
diff --git a/kernel/pid.c b/kernel/pid.c index 157fe4b19971..de1cfc4f75a2 100644 --- a/kernel/pid.c +++ b/kernel/pid.c @@ -265,27 +265,33 @@ struct pid *find_vpid(int nr)  }  EXPORT_SYMBOL_GPL(find_vpid); +static struct pid **task_pid_ptr(struct task_struct *task, enum pid_type type) +{ +	return (type == PIDTYPE_PID) ? +		&task->thread_pid : +		&task->signal->pids[type]; +} +  /*   * attach_pid() must be called with the tasklist_lock write-held.   */  void attach_pid(struct task_struct *task, enum pid_type type)  { -	struct pid_link *link = &task->pids[type]; -	hlist_add_head_rcu(&link->node, &link->pid->tasks[type]); +	struct pid *pid = *task_pid_ptr(task, type); +	hlist_add_head_rcu(&task->pid_links[type], &pid->tasks[type]);  }  static void __change_pid(struct task_struct *task, enum pid_type type,  			struct pid *new)  { -	struct pid_link *link; +	struct pid **pid_ptr = task_pid_ptr(task, type);  	struct pid *pid;  	int tmp; -	link = &task->pids[type]; -	pid = link->pid; +	pid = *pid_ptr; -	hlist_del_rcu(&link->node); -	link->pid = new; +	hlist_del_rcu(&task->pid_links[type]); +	*pid_ptr = new;  	for (tmp = PIDTYPE_MAX; --tmp >= 0; )  		if (!hlist_empty(&pid->tasks[tmp])) @@ -310,8 +316,9 @@ void change_pid(struct task_struct *task, enum pid_type type,  void transfer_pid(struct task_struct *old, struct task_struct *new,  			   enum pid_type type)  { -	new->pids[type].pid = old->pids[type].pid; -	hlist_replace_rcu(&old->pids[type].node, &new->pids[type].node); +	if (type == PIDTYPE_PID) +		new->thread_pid = old->thread_pid; +	hlist_replace_rcu(&old->pid_links[type], &new->pid_links[type]);  }  struct task_struct *pid_task(struct pid *pid, enum pid_type type) @@ -322,7 +329,7 @@ struct task_struct *pid_task(struct pid *pid, enum pid_type type)  		first = rcu_dereference_check(hlist_first_rcu(&pid->tasks[type]),  					      lockdep_tasklist_lock_is_held());  		if (first) -			result = hlist_entry(first, struct task_struct, pids[(type)].node); +			result = hlist_entry(first, struct task_struct, pid_links[(type)]);  	}  	return result;  } @@ -360,9 +367,7 @@ struct pid *get_task_pid(struct task_struct *task, enum pid_type type)  {  	struct pid *pid;  	rcu_read_lock(); -	if (type != PIDTYPE_PID) -		task = task->group_leader; -	pid = get_pid(rcu_dereference(task->pids[type].pid)); +	pid = get_pid(rcu_dereference(*task_pid_ptr(task, type)));  	rcu_read_unlock();  	return pid;  } @@ -420,15 +425,8 @@ pid_t __task_pid_nr_ns(struct task_struct *task, enum pid_type type,  	rcu_read_lock();  	if (!ns)  		ns = task_active_pid_ns(current); -	if (likely(pid_alive(task))) { -		if (type != PIDTYPE_PID) { -			if (type == __PIDTYPE_TGID) -				type = PIDTYPE_PID; - -			task = task->group_leader; -		} -		nr = pid_nr_ns(rcu_dereference(task->pids[type].pid), ns); -	} +	if (likely(pid_alive(task))) +		nr = pid_nr_ns(rcu_dereference(*task_pid_ptr(task, type)), ns);  	rcu_read_unlock();  	return nr;  |