aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorOleg Nesterov <oleg@tv-sign.ru>2006-03-28 19:11:07 -0500
committerLinus Torvalds <torvalds@g5.osdl.org>2006-03-28 21:36:41 -0500
commit73b9ebfe126a4a886ee46cbab637374d7024668a (patch)
treed7ba00d4ce76b49c1569334956cd196b35977a04
parentc97d98931ac52ef110b62d9b75c6a6f2bfbc1898 (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.c1
-rw-r--r--include/linux/sched.h2
-rw-r--r--kernel/exit.c18
-rw-r--r--kernel/fork.c35
-rw-r--r--kernel/pid.c10
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
1217extern 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
123void 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(&current->sighand->siglock); 1205 spin_unlock(&current->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
248void __init pidmap_init(void) 248void __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}