diff options
| author | Oleg Nesterov <oleg@tv-sign.ru> | 2006-03-28 19:11:07 -0500 |
|---|---|---|
| committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-03-28 21:36:41 -0500 |
| commit | 73b9ebfe126a4a886ee46cbab637374d7024668a (patch) | |
| tree | d7ba00d4ce76b49c1569334956cd196b35977a04 | |
| parent | c97d98931ac52ef110b62d9b75c6a6f2bfbc1898 (diff) | |
[PATCH] pidhash: don't count idle threads
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>
| -rw-r--r-- | arch/um/kernel/smp.c | 1 | ||||
| -rw-r--r-- | include/linux/sched.h | 2 | ||||
| -rw-r--r-- | kernel/exit.c | 18 | ||||
| -rw-r--r-- | kernel/fork.c | 35 | ||||
| -rw-r--r-- | kernel/pid.c | 10 |
5 files changed, 20 insertions, 46 deletions
diff --git a/arch/um/kernel/smp.c b/arch/um/kernel/smp.c index c8d8d0ac1a7f..511116aebaf7 100644 --- a/arch/um/kernel/smp.c +++ b/arch/um/kernel/smp.c | |||
| @@ -143,7 +143,6 @@ void smp_prepare_cpus(unsigned int maxcpus) | |||
| 143 | idle = idle_thread(cpu); | 143 | idle = idle_thread(cpu); |
| 144 | 144 | ||
| 145 | init_idle(idle, cpu); | 145 | init_idle(idle, cpu); |
| 146 | unhash_process(idle); | ||
| 147 | 146 | ||
| 148 | waittime = 200000000; | 147 | waittime = 200000000; |
| 149 | while (waittime-- && !cpu_isset(cpu, cpu_callin_map)) | 148 | while (waittime-- && !cpu_isset(cpu, cpu_callin_map)) |
diff --git a/include/linux/sched.h b/include/linux/sched.h index 1f16fb1fea22..ddc0df7f8bf5 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h | |||
| @@ -1214,8 +1214,6 @@ static inline int thread_group_empty(task_t *p) | |||
| 1214 | #define delay_group_leader(p) \ | 1214 | #define delay_group_leader(p) \ |
| 1215 | (thread_group_leader(p) && !thread_group_empty(p)) | 1215 | (thread_group_leader(p) && !thread_group_empty(p)) |
| 1216 | 1216 | ||
| 1217 | extern void unhash_process(struct task_struct *p); | ||
| 1218 | |||
| 1219 | /* | 1217 | /* |
| 1220 | * Protects ->fs, ->files, ->mm, ->ptrace, ->group_info, ->comm, keyring | 1218 | * Protects ->fs, ->files, ->mm, ->ptrace, ->group_info, ->comm, keyring |
| 1221 | * subscriptions and synchronises with wait4(). Also used in procfs. Also | 1219 | * subscriptions and synchronises with wait4(). Also used in procfs. Also |
diff --git a/kernel/exit.c b/kernel/exit.c index f436a6bd3fb7..a94e1c31131b 100644 --- a/kernel/exit.c +++ b/kernel/exit.c | |||
| @@ -56,8 +56,7 @@ static void __unhash_process(struct task_struct *p) | |||
| 56 | detach_pid(p, PIDTYPE_SID); | 56 | detach_pid(p, PIDTYPE_SID); |
| 57 | 57 | ||
| 58 | list_del_init(&p->tasks); | 58 | list_del_init(&p->tasks); |
| 59 | if (p->pid) | 59 | __get_cpu_var(process_counts)--; |
| 60 | __get_cpu_var(process_counts)--; | ||
| 61 | } | 60 | } |
| 62 | 61 | ||
| 63 | remove_parent(p); | 62 | remove_parent(p); |
| @@ -118,21 +117,6 @@ repeat: | |||
| 118 | goto repeat; | 117 | goto repeat; |
| 119 | } | 118 | } |
| 120 | 119 | ||
| 121 | /* we are using it only for SMP init */ | ||
| 122 | |||
| 123 | void unhash_process(struct task_struct *p) | ||
| 124 | { | ||
| 125 | struct dentry *proc_dentry; | ||
| 126 | |||
| 127 | spin_lock(&p->proc_lock); | ||
| 128 | proc_dentry = proc_pid_unhash(p); | ||
| 129 | write_lock_irq(&tasklist_lock); | ||
| 130 | __unhash_process(p); | ||
| 131 | write_unlock_irq(&tasklist_lock); | ||
| 132 | spin_unlock(&p->proc_lock); | ||
| 133 | proc_pid_flush(proc_dentry); | ||
| 134 | } | ||
| 135 | |||
| 136 | /* | 120 | /* |
| 137 | * This checks not only the pgrp, but falls back on the pid if no | 121 | * This checks not only the pgrp, but falls back on the pid if no |
| 138 | * satisfactory pgrp is found. I dunno - gdb doesn't work correctly | 122 | * satisfactory pgrp is found. I dunno - gdb doesn't work correctly |
diff --git a/kernel/fork.c b/kernel/fork.c index 74c67629ee62..0c32e28cdc5f 100644 --- a/kernel/fork.c +++ b/kernel/fork.c | |||
| @@ -1181,25 +1181,26 @@ static task_t *copy_process(unsigned long clone_flags, | |||
| 1181 | */ | 1181 | */ |
| 1182 | p->ioprio = current->ioprio; | 1182 | p->ioprio = current->ioprio; |
| 1183 | 1183 | ||
| 1184 | add_parent(p); | 1184 | if (likely(p->pid)) { |
| 1185 | if (unlikely(p->ptrace & PT_PTRACED)) | 1185 | add_parent(p); |
| 1186 | __ptrace_link(p, current->parent); | 1186 | if (unlikely(p->ptrace & PT_PTRACED)) |
| 1187 | 1187 | __ptrace_link(p, current->parent); | |
| 1188 | if (thread_group_leader(p)) { | 1188 | |
| 1189 | p->signal->tty = current->signal->tty; | 1189 | if (thread_group_leader(p)) { |
| 1190 | p->signal->pgrp = process_group(current); | 1190 | p->signal->tty = current->signal->tty; |
| 1191 | p->signal->session = current->signal->session; | 1191 | p->signal->pgrp = process_group(current); |
| 1192 | attach_pid(p, PIDTYPE_PGID, process_group(p)); | 1192 | p->signal->session = current->signal->session; |
| 1193 | attach_pid(p, PIDTYPE_SID, p->signal->session); | 1193 | attach_pid(p, PIDTYPE_PGID, process_group(p)); |
| 1194 | 1194 | attach_pid(p, PIDTYPE_SID, p->signal->session); | |
| 1195 | list_add_tail(&p->tasks, &init_task.tasks); | 1195 | |
| 1196 | if (p->pid) | 1196 | list_add_tail(&p->tasks, &init_task.tasks); |
| 1197 | __get_cpu_var(process_counts)++; | 1197 | __get_cpu_var(process_counts)++; |
| 1198 | } | ||
| 1199 | attach_pid(p, PIDTYPE_TGID, p->tgid); | ||
| 1200 | attach_pid(p, PIDTYPE_PID, p->pid); | ||
| 1201 | nr_threads++; | ||
| 1198 | } | 1202 | } |
| 1199 | attach_pid(p, PIDTYPE_TGID, p->tgid); | ||
| 1200 | attach_pid(p, PIDTYPE_PID, p->pid); | ||
| 1201 | 1203 | ||
| 1202 | nr_threads++; | ||
| 1203 | total_forks++; | 1204 | total_forks++; |
| 1204 | spin_unlock(¤t->sighand->siglock); | 1205 | spin_unlock(¤t->sighand->siglock); |
| 1205 | write_unlock_irq(&tasklist_lock); | 1206 | write_unlock_irq(&tasklist_lock); |
| @@ -1263,7 +1264,7 @@ task_t * __devinit fork_idle(int cpu) | |||
| 1263 | if (!task) | 1264 | if (!task) |
| 1264 | return ERR_PTR(-ENOMEM); | 1265 | return ERR_PTR(-ENOMEM); |
| 1265 | init_idle(task, cpu); | 1266 | init_idle(task, cpu); |
| 1266 | unhash_process(task); | 1267 | |
| 1267 | return task; | 1268 | return task; |
| 1268 | } | 1269 | } |
| 1269 | 1270 | ||
diff --git a/kernel/pid.c b/kernel/pid.c index 7781d9999058..a9f2dfd006d2 100644 --- a/kernel/pid.c +++ b/kernel/pid.c | |||
| @@ -247,16 +247,8 @@ void __init pidhash_init(void) | |||
| 247 | 247 | ||
| 248 | void __init pidmap_init(void) | 248 | void __init pidmap_init(void) |
| 249 | { | 249 | { |
| 250 | int i; | ||
| 251 | |||
| 252 | pidmap_array->page = (void *)get_zeroed_page(GFP_KERNEL); | 250 | pidmap_array->page = (void *)get_zeroed_page(GFP_KERNEL); |
| 251 | /* Reserve PID 0. We never call free_pidmap(0) */ | ||
| 253 | set_bit(0, pidmap_array->page); | 252 | set_bit(0, pidmap_array->page); |
| 254 | atomic_dec(&pidmap_array->nr_free); | 253 | atomic_dec(&pidmap_array->nr_free); |
| 255 | |||
| 256 | /* | ||
| 257 | * Allocate PID 0, and hash it via all PID types: | ||
| 258 | */ | ||
| 259 | |||
| 260 | for (i = 0; i < PIDTYPE_MAX; i++) | ||
| 261 | attach_pid(current, i, 0); | ||
| 262 | } | 254 | } |
