[PATCH 1/3] pidhash: don't count idle threads

From: Oleg Nesterov
Date: Mon Jan 30 2006 - 04:46:50 EST


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().

Note: it is still possible to have PIDTYPE_PGID/PIDTYPE_SID entries
with nr == 0 (forked from init thread, including kernel threads
spawned from init/main.c:init()), this is ok because we never call
free_pidmap() with pid == 0 arg, so it will never be reused.

Question: why does unhash_process() call proc_pid_unhash()? Is not it
a bug to have ->proc_dentry != NULL after fork_idle()->copy_process()?

Signed-off-by: Oleg Nesterov <oleg@xxxxxxxxxx>

--- RC-1/kernel/pid.c~NOIPID 2006-01-19 18:13:07.000000000 +0300
+++ RC-1/kernel/pid.c 2006-01-30 14:21:15.000000000 +0300
@@ -277,16 +277,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 */
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);
}
--- RC-1/kernel/fork.c~NOIPID 2006-01-19 18:13:07.000000000 +0300
+++ RC-1/kernel/fork.c 2006-01-30 14:17:58.000000000 +0300
@@ -1135,19 +1135,20 @@ static task_t *copy_process(unsigned lon
if (unlikely(p->ptrace & PT_PTRACED))
__ptrace_link(p, current->parent);

- attach_pid(p, PIDTYPE_PID, p->pid);
- attach_pid(p, PIDTYPE_TGID, p->tgid);
- 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);
- if (p->pid)
+ if (p->pid) {
+ attach_pid(p, PIDTYPE_PID, p->pid);
+ attach_pid(p, PIDTYPE_TGID, p->tgid);
+ 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);
__get_cpu_var(process_counts)++;
+ }
+ nr_threads++;
}

- nr_threads++;
total_forks++;
write_unlock_irq(&tasklist_lock);
proc_fork_connector(p);
@@ -1210,7 +1211,7 @@ task_t * __devinit fork_idle(int cpu)
if (!task)
return ERR_PTR(-ENOMEM);
init_idle(task, cpu);
- unhash_process(task);
+
return task;
}

--- RC-1/include/linux/sched.h~NOIPID 2006-01-19 18:13:07.000000000 +0300
+++ RC-1/include/linux/sched.h 2006-01-29 23:35:44.000000000 +0300
@@ -1217,8 +1217,6 @@ static inline int thread_group_empty(tas
#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
--- RC-1/kernel/exit.c~NOIPID 2006-01-19 18:13:07.000000000 +0300
+++ RC-1/kernel/exit.c 2006-01-29 23:30:02.000000000 +0300
@@ -52,8 +52,7 @@ static void __unhash_process(struct task
if (thread_group_leader(p)) {
detach_pid(p, PIDTYPE_PGID);
detach_pid(p, PIDTYPE_SID);
- if (p->pid)
- __get_cpu_var(process_counts)--;
+ __get_cpu_var(process_counts)--;
}

REMOVE_LINKS(p);
@@ -114,21 +113,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
--- RC-1/arch/um/kernel/smp.c~NOIPID 2005-03-19 14:16:40.000000000 +0300
+++ RC-1/arch/um/kernel/smp.c 2006-01-29 23:42:32.000000000 +0300
@@ -143,7 +143,6 @@ void smp_prepare_cpus(unsigned int maxcp
idle = idle_thread(cpu);

init_idle(idle, cpu);
- unhash_process(idle);

waittime = 200000000;
while (waittime-- && !cpu_isset(cpu, cpu_callin_map))
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/