![Eric W. Biederman](/assets/img/avatar_default.png)
switch_exec_pids is only called from de_thread by way of exec, and it is only called when we are exec'ing from a non thread group leader. Currently switch_exec_pids gives the leader the pid of the thread and unhashes and rehashes all of the process groups. The leader is already in the EXIT_DEAD state so no one cares about it's pids. The only concern for the leader is that __unhash_process called from release_task will function correctly. If we don't touch the leader at all we know that __unhash_process will work fine so there is no need to touch the leader. For the task becomming the thread group leader, we just need to give it the pid of the old thread group leader, add it to the task list, and attach it to the session and the process group of the thread group. Currently de_thread is also adding the task to the task list which is just silly. Currently the only leader of __detach_pid besides detach_pid is switch_exec_pids because of the ugly extra work that was being performed. So this patch removes switch_exec_pids because it is doing too much, it is creating an unnecessary special case in pid.c, duing work duplicated in de_thread, and generally obscuring what it is going on. The necessary work is added to de_thread, and it seems to be a little clearer there what is going on. Signed-off-by: Eric W. Biederman <ebiederm@xmission.com> Cc: Oleg Nesterov <oleg@tv-sign.ru> Cc: Kirill Korotaev <dev@sw.ru> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
55 lines
1.3 KiB
C
55 lines
1.3 KiB
C
#ifndef _LINUX_PID_H
|
|
#define _LINUX_PID_H
|
|
|
|
enum pid_type
|
|
{
|
|
PIDTYPE_PID,
|
|
PIDTYPE_TGID,
|
|
PIDTYPE_PGID,
|
|
PIDTYPE_SID,
|
|
PIDTYPE_MAX
|
|
};
|
|
|
|
struct pid
|
|
{
|
|
/* Try to keep pid_chain in the same cacheline as nr for find_pid */
|
|
int nr;
|
|
struct hlist_node pid_chain;
|
|
/* list of pids with the same nr, only one of them is in the hash */
|
|
struct list_head pid_list;
|
|
};
|
|
|
|
#define pid_task(elem, type) \
|
|
list_entry(elem, struct task_struct, pids[type].pid_list)
|
|
|
|
/*
|
|
* attach_pid() and detach_pid() must be called with the tasklist_lock
|
|
* write-held.
|
|
*/
|
|
extern int FASTCALL(attach_pid(struct task_struct *task, enum pid_type type, int nr));
|
|
|
|
extern void FASTCALL(detach_pid(struct task_struct *task, enum pid_type));
|
|
|
|
/*
|
|
* look up a PID in the hash table. Must be called with the tasklist_lock
|
|
* held.
|
|
*/
|
|
extern struct pid *FASTCALL(find_pid(enum pid_type, int));
|
|
|
|
extern int alloc_pidmap(void);
|
|
extern void FASTCALL(free_pidmap(int));
|
|
|
|
#define do_each_task_pid(who, type, task) \
|
|
if ((task = find_task_by_pid_type(type, who))) { \
|
|
prefetch((task)->pids[type].pid_list.next); \
|
|
do {
|
|
|
|
#define while_each_task_pid(who, type, task) \
|
|
} while (task = pid_task((task)->pids[type].pid_list.next,\
|
|
type), \
|
|
prefetch((task)->pids[type].pid_list.next), \
|
|
hlist_unhashed(&(task)->pids[type].pid_chain)); \
|
|
} \
|
|
|
|
#endif /* _LINUX_PID_H */
|