[PATCH] pidhash: don't count idle threads
authorOleg Nesterov <oleg@tv-sign.ru>
Wed, 29 Mar 2006 00:11:07 +0000 (16:11 -0800)
committerLinus Torvalds <torvalds@g5.osdl.org>
Wed, 29 Mar 2006 02:36:41 +0000 (18:36 -0800)
fork_idle() does unhash_process() just after copy_process().  Contrary,
boot_cpu's idle thread explicitely registers itself for each pid_type with nr
= 0.

copy_process() already checks p->pid != 0 before process_counts++, I think we
can just skip attach_pid() calls and job control inits for idle threads and
kill unhash_process().  We don't need to cleanup ->proc_dentry in fork_idle()
because with this patch idle threads are never hashed in
kernel/pid.c:pid_hash[].

We don't need to hash pid == 0 in pidmap_init().  free_pidmap() is never
called with pid == 0 arg, so it will never be reused.  So it is still possible
to use pid == 0 in any PIDTYPE_xxx namespace from kernel/pid.c's POV.

However with this patch we don't hash pid == 0 for PIDTYPE_PID case.  We still
have have PIDTYPE_PGID/PIDTYPE_SID entries with pid == 0: /sbin/init and
kernel threads which don't call daemonize().

Signed-off-by: Oleg Nesterov <oleg@tv-sign.ru>
Cc: "Eric W. Biederman" <ebiederm@xmission.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
arch/um/kernel/smp.c
include/linux/sched.h
kernel/exit.c
kernel/fork.c
kernel/pid.c

index c8d8d0ac1a7f8af3af063c6773f46b17bcbb7d9b..511116aebaf7206c392401bea1b2bea2691e3e9a 100644 (file)
@@ -143,7 +143,6 @@ void smp_prepare_cpus(unsigned int maxcpus)
                idle = idle_thread(cpu);
 
                init_idle(idle, cpu);
-               unhash_process(idle);
 
                waittime = 200000000;
                while (waittime-- && !cpu_isset(cpu, cpu_callin_map))
index 1f16fb1fea221af3b6072a7c687ceff94cde92f5..ddc0df7f8bf5cdf8130a40899ce19d02ef76c26a 100644 (file)
@@ -1214,8 +1214,6 @@ static inline int thread_group_empty(task_t *p)
 #define delay_group_leader(p) \
                (thread_group_leader(p) && !thread_group_empty(p))
 
-extern void unhash_process(struct task_struct *p);
-
 /*
  * Protects ->fs, ->files, ->mm, ->ptrace, ->group_info, ->comm, keyring
  * subscriptions and synchronises with wait4().  Also used in procfs.  Also
index f436a6bd3fb7fb8b1c41c5b4cbc77636a64e4414..a94e1c31131bf71308d340030f6de766c0e09cf2 100644 (file)
@@ -56,8 +56,7 @@ static void __unhash_process(struct task_struct *p)
                detach_pid(p, PIDTYPE_SID);
 
                list_del_init(&p->tasks);
-               if (p->pid)
-                       __get_cpu_var(process_counts)--;
+               __get_cpu_var(process_counts)--;
        }
 
        remove_parent(p);
@@ -118,21 +117,6 @@ repeat:
                goto repeat;
 }
 
-/* we are using it only for SMP init */
-
-void unhash_process(struct task_struct *p)
-{
-       struct dentry *proc_dentry;
-
-       spin_lock(&p->proc_lock);
-       proc_dentry = proc_pid_unhash(p);
-       write_lock_irq(&tasklist_lock);
-       __unhash_process(p);
-       write_unlock_irq(&tasklist_lock);
-       spin_unlock(&p->proc_lock);
-       proc_pid_flush(proc_dentry);
-}
-
 /*
  * This checks not only the pgrp, but falls back on the pid if no
  * satisfactory pgrp is found. I dunno - gdb doesn't work correctly
index 74c67629ee6294cdbb2d6ab43f5d56b511d6ac2c..0c32e28cdc5f1e0748b500a16b19b5b693f427f9 100644 (file)
@@ -1181,25 +1181,26 @@ static task_t *copy_process(unsigned long clone_flags,
         */
        p->ioprio = current->ioprio;
 
-       add_parent(p);
-       if (unlikely(p->ptrace & PT_PTRACED))
-               __ptrace_link(p, current->parent);
-
-       if (thread_group_leader(p)) {
-               p->signal->tty = current->signal->tty;
-               p->signal->pgrp = process_group(current);
-               p->signal->session = current->signal->session;
-               attach_pid(p, PIDTYPE_PGID, process_group(p));
-               attach_pid(p, PIDTYPE_SID, p->signal->session);
-
-               list_add_tail(&p->tasks, &init_task.tasks);
-               if (p->pid)
+       if (likely(p->pid)) {
+               add_parent(p);
+               if (unlikely(p->ptrace & PT_PTRACED))
+                       __ptrace_link(p, current->parent);
+
+               if (thread_group_leader(p)) {
+                       p->signal->tty = current->signal->tty;
+                       p->signal->pgrp = process_group(current);
+                       p->signal->session = current->signal->session;
+                       attach_pid(p, PIDTYPE_PGID, process_group(p));
+                       attach_pid(p, PIDTYPE_SID, p->signal->session);
+
+                       list_add_tail(&p->tasks, &init_task.tasks);
                        __get_cpu_var(process_counts)++;
+               }
+               attach_pid(p, PIDTYPE_TGID, p->tgid);
+               attach_pid(p, PIDTYPE_PID, p->pid);
+               nr_threads++;
        }
-       attach_pid(p, PIDTYPE_TGID, p->tgid);
-       attach_pid(p, PIDTYPE_PID, p->pid);
 
-       nr_threads++;
        total_forks++;
        spin_unlock(&current->sighand->siglock);
        write_unlock_irq(&tasklist_lock);
@@ -1263,7 +1264,7 @@ task_t * __devinit fork_idle(int cpu)
        if (!task)
                return ERR_PTR(-ENOMEM);
        init_idle(task, cpu);
-       unhash_process(task);
+
        return task;
 }
 
index 7781d9999058337f12618910b81cea8c0ee1c0f0..a9f2dfd006d2d7ddee6f6413cbe82d793a6fc3e7 100644 (file)
@@ -247,16 +247,8 @@ void __init pidhash_init(void)
 
 void __init pidmap_init(void)
 {
-       int i;
-
        pidmap_array->page = (void *)get_zeroed_page(GFP_KERNEL);
+       /* Reserve PID 0. We never call free_pidmap(0) */
        set_bit(0, pidmap_array->page);
        atomic_dec(&pidmap_array->nr_free);
-
-       /*
-        * Allocate PID 0, and hash it via all PID types:
-        */
-
-       for (i = 0; i < PIDTYPE_MAX; i++)
-               attach_pid(current, i, 0);
 }