aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEric W. Biederman <ebiederm@xmission.com>2006-03-28 19:11:03 -0500
committerLinus Torvalds <torvalds@g5.osdl.org>2006-03-28 21:36:40 -0500
commitd73d65293e3e2de7e916a89c8da30be0948afab7 (patch)
tree62b0ca76e3099c927f2960856dd060b136a8ccef
parent652486fb84a07ed750f1c11639518f55808bf555 (diff)
[PATCH] pidhash: kill switch_exec_pids
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>
-rw-r--r--fs/exec.c14
-rw-r--r--include/linux/pid.h1
-rw-r--r--kernel/pid.c30
3 files changed, 11 insertions, 34 deletions
diff --git a/fs/exec.c b/fs/exec.c
index dd194923c52c..db0769447d33 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -708,7 +708,17 @@ static int de_thread(struct task_struct *tsk)
708 remove_parent(current); 708 remove_parent(current);
709 remove_parent(leader); 709 remove_parent(leader);
710 710
711 switch_exec_pids(leader, current); 711
712 /* Become a process group leader with the old leader's pid.
713 * Note: The old leader also uses thispid until release_task
714 * is called. Odd but simple and correct.
715 */
716 detach_pid(current, PIDTYPE_PID);
717 current->pid = leader->pid;
718 attach_pid(current, PIDTYPE_PID, current->pid);
719 attach_pid(current, PIDTYPE_PGID, current->signal->pgrp);
720 attach_pid(current, PIDTYPE_SID, current->signal->session);
721 list_add_tail(&current->tasks, &init_task.tasks);
712 722
713 current->parent = current->real_parent = leader->real_parent; 723 current->parent = current->real_parent = leader->real_parent;
714 leader->parent = leader->real_parent = child_reaper; 724 leader->parent = leader->real_parent = child_reaper;
@@ -722,8 +732,6 @@ static int de_thread(struct task_struct *tsk)
722 __ptrace_link(current, parent); 732 __ptrace_link(current, parent);
723 } 733 }
724 734
725 list_del(&current->tasks);
726 list_add_tail(&current->tasks, &init_task.tasks);
727 current->exit_signal = SIGCHLD; 735 current->exit_signal = SIGCHLD;
728 736
729 BUG_ON(leader->exit_state != EXIT_ZOMBIE); 737 BUG_ON(leader->exit_state != EXIT_ZOMBIE);
diff --git a/include/linux/pid.h b/include/linux/pid.h
index 5b2fcb19d2da..099e70ecf7c7 100644
--- a/include/linux/pid.h
+++ b/include/linux/pid.h
@@ -38,7 +38,6 @@ extern struct pid *FASTCALL(find_pid(enum pid_type, int));
38 38
39extern int alloc_pidmap(void); 39extern int alloc_pidmap(void);
40extern void FASTCALL(free_pidmap(int)); 40extern void FASTCALL(free_pidmap(int));
41extern void switch_exec_pids(struct task_struct *leader, struct task_struct *thread);
42 41
43#define do_each_task_pid(who, type, task) \ 42#define do_each_task_pid(who, type, task) \
44 if ((task = find_task_by_pid_type(type, who))) { \ 43 if ((task = find_task_by_pid_type(type, who))) { \
diff --git a/kernel/pid.c b/kernel/pid.c
index 1acc07246991..7781d9999058 100644
--- a/kernel/pid.c
+++ b/kernel/pid.c
@@ -218,36 +218,6 @@ task_t *find_task_by_pid_type(int type, int nr)
218EXPORT_SYMBOL(find_task_by_pid_type); 218EXPORT_SYMBOL(find_task_by_pid_type);
219 219
220/* 220/*
221 * This function switches the PIDs if a non-leader thread calls
222 * sys_execve() - this must be done without releasing the PID.
223 * (which a detach_pid() would eventually do.)
224 */
225void switch_exec_pids(task_t *leader, task_t *thread)
226{
227 __detach_pid(leader, PIDTYPE_PID);
228 __detach_pid(leader, PIDTYPE_TGID);
229 __detach_pid(leader, PIDTYPE_PGID);
230 __detach_pid(leader, PIDTYPE_SID);
231
232 __detach_pid(thread, PIDTYPE_PID);
233 __detach_pid(thread, PIDTYPE_TGID);
234
235 leader->pid = leader->tgid = thread->pid;
236 thread->pid = thread->tgid;
237
238 attach_pid(thread, PIDTYPE_PID, thread->pid);
239 attach_pid(thread, PIDTYPE_TGID, thread->tgid);
240 attach_pid(thread, PIDTYPE_PGID, thread->signal->pgrp);
241 attach_pid(thread, PIDTYPE_SID, thread->signal->session);
242 list_add_tail(&thread->tasks, &init_task.tasks);
243
244 attach_pid(leader, PIDTYPE_PID, leader->pid);
245 attach_pid(leader, PIDTYPE_TGID, leader->tgid);
246 attach_pid(leader, PIDTYPE_PGID, leader->signal->pgrp);
247 attach_pid(leader, PIDTYPE_SID, leader->signal->session);
248}
249
250/*
251 * The pid hash table is scaled according to the amount of memory in the 221 * The pid hash table is scaled according to the amount of memory in the
252 * machine. From a minimum of 16 slots up to 4096 slots at one gigabyte or 222 * machine. From a minimum of 16 slots up to 4096 slots at one gigabyte or
253 * more. 223 * more.