Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 73b9ebfe authored by Oleg Nesterov's avatar Oleg Nesterov Committed by Linus Torvalds
Browse files

[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: default avatarOleg Nesterov <oleg@tv-sign.ru>
Cc: "Eric W. Biederman" <ebiederm@xmission.com>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent c97d9893
Loading
Loading
Loading
Loading
+0 −1
Original line number Original line Diff line number Diff line
@@ -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))
+0 −2
Original line number Original line Diff line number Diff line
@@ -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
+1 −17
Original line number Original line Diff line number Diff line
@@ -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
+18 −17
Original line number Original line Diff line number Diff line
@@ -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(&current->sighand->siglock);
	spin_unlock(&current->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;
}
}


+1 −9
Original line number Original line Diff line number Diff line
@@ -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);
}
}