mirror of https://gitee.com/openkylin/linux.git
[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>
This commit is contained in:
parent
c97d98931a
commit
73b9ebfe12
|
@ -143,7 +143,6 @@ void smp_prepare_cpus(unsigned int maxcpus)
|
||||||
idle = idle_thread(cpu);
|
idle = idle_thread(cpu);
|
||||||
|
|
||||||
init_idle(idle, cpu);
|
init_idle(idle, cpu);
|
||||||
unhash_process(idle);
|
|
||||||
|
|
||||||
waittime = 200000000;
|
waittime = 200000000;
|
||||||
while (waittime-- && !cpu_isset(cpu, cpu_callin_map))
|
while (waittime-- && !cpu_isset(cpu, cpu_callin_map))
|
||||||
|
|
|
@ -1214,8 +1214,6 @@ static inline int thread_group_empty(task_t *p)
|
||||||
#define delay_group_leader(p) \
|
#define delay_group_leader(p) \
|
||||||
(thread_group_leader(p) && !thread_group_empty(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
|
* Protects ->fs, ->files, ->mm, ->ptrace, ->group_info, ->comm, keyring
|
||||||
* subscriptions and synchronises with wait4(). Also used in procfs. Also
|
* subscriptions and synchronises with wait4(). Also used in procfs. Also
|
||||||
|
|
|
@ -56,7 +56,6 @@ static void __unhash_process(struct task_struct *p)
|
||||||
detach_pid(p, PIDTYPE_SID);
|
detach_pid(p, PIDTYPE_SID);
|
||||||
|
|
||||||
list_del_init(&p->tasks);
|
list_del_init(&p->tasks);
|
||||||
if (p->pid)
|
|
||||||
__get_cpu_var(process_counts)--;
|
__get_cpu_var(process_counts)--;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -118,21 +117,6 @@ void release_task(struct task_struct * p)
|
||||||
goto 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
|
* 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
|
* satisfactory pgrp is found. I dunno - gdb doesn't work correctly
|
||||||
|
|
|
@ -1181,6 +1181,7 @@ static task_t *copy_process(unsigned long clone_flags,
|
||||||
*/
|
*/
|
||||||
p->ioprio = current->ioprio;
|
p->ioprio = current->ioprio;
|
||||||
|
|
||||||
|
if (likely(p->pid)) {
|
||||||
add_parent(p);
|
add_parent(p);
|
||||||
if (unlikely(p->ptrace & PT_PTRACED))
|
if (unlikely(p->ptrace & PT_PTRACED))
|
||||||
__ptrace_link(p, current->parent);
|
__ptrace_link(p, current->parent);
|
||||||
|
@ -1193,13 +1194,13 @@ static task_t *copy_process(unsigned long clone_flags,
|
||||||
attach_pid(p, PIDTYPE_SID, p->signal->session);
|
attach_pid(p, PIDTYPE_SID, p->signal->session);
|
||||||
|
|
||||||
list_add_tail(&p->tasks, &init_task.tasks);
|
list_add_tail(&p->tasks, &init_task.tasks);
|
||||||
if (p->pid)
|
|
||||||
__get_cpu_var(process_counts)++;
|
__get_cpu_var(process_counts)++;
|
||||||
}
|
}
|
||||||
attach_pid(p, PIDTYPE_TGID, p->tgid);
|
attach_pid(p, PIDTYPE_TGID, p->tgid);
|
||||||
attach_pid(p, PIDTYPE_PID, p->pid);
|
attach_pid(p, PIDTYPE_PID, p->pid);
|
||||||
|
|
||||||
nr_threads++;
|
nr_threads++;
|
||||||
|
}
|
||||||
|
|
||||||
total_forks++;
|
total_forks++;
|
||||||
spin_unlock(¤t->sighand->siglock);
|
spin_unlock(¤t->sighand->siglock);
|
||||||
write_unlock_irq(&tasklist_lock);
|
write_unlock_irq(&tasklist_lock);
|
||||||
|
@ -1263,7 +1264,7 @@ task_t * __devinit fork_idle(int cpu)
|
||||||
if (!task)
|
if (!task)
|
||||||
return ERR_PTR(-ENOMEM);
|
return ERR_PTR(-ENOMEM);
|
||||||
init_idle(task, cpu);
|
init_idle(task, cpu);
|
||||||
unhash_process(task);
|
|
||||||
return task;
|
return task;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
10
kernel/pid.c
10
kernel/pid.c
|
@ -247,16 +247,8 @@ void __init pidhash_init(void)
|
||||||
|
|
||||||
void __init pidmap_init(void)
|
void __init pidmap_init(void)
|
||||||
{
|
{
|
||||||
int i;
|
|
||||||
|
|
||||||
pidmap_array->page = (void *)get_zeroed_page(GFP_KERNEL);
|
pidmap_array->page = (void *)get_zeroed_page(GFP_KERNEL);
|
||||||
|
/* Reserve PID 0. We never call free_pidmap(0) */
|
||||||
set_bit(0, pidmap_array->page);
|
set_bit(0, pidmap_array->page);
|
||||||
atomic_dec(&pidmap_array->nr_free);
|
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);
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue