Messages in this thread Patch in this message | | | Date | Wed, 04 Dec 2002 23:48:27 -0800 | From | wli@holomorp ... | Subject | [pidhash] [3/4] eliminate proc_fill_super() tasklist iteration |
| |
Introduce a per-cpu counter for the number of processes on the system, and use that to set ->i_nlink in proc_fill_super() in constant time.
fs/proc/inode.c | 6 +----- include/linux/sched.h | 3 +++ kernel/exit.c | 2 ++ kernel/fork.c | 14 ++++++++++++++ 4 files changed, 20 insertions(+), 5 deletions(-)
diff -urpN mm1-2.5.50-2/fs/proc/inode.c wli-2.5.50-3/fs/proc/inode.c --- mm1-2.5.50-2/fs/proc/inode.c 2002-11-27 14:36:19.000000000 -0800 +++ wli-2.5.50-3/fs/proc/inode.c 2002-12-04 18:40:59.000000000 -0800 @@ -234,11 +234,7 @@ int proc_fill_super(struct super_block * /* * Fixup the root inode's nlink value */ - read_lock(&tasklist_lock); - for_each_process(p) - if (p->pid) - root_inode->i_nlink++; - read_unlock(&tasklist_lock); + root_inode->i_nlink += nr_processes(); s->s_root = d_alloc_root(root_inode); if (!s->s_root) goto out_no_root; diff -urpN mm1-2.5.50-2/include/linux/sched.h wli-2.5.50-3/include/linux/sched.h --- mm1-2.5.50-2/include/linux/sched.h 2002-12-04 12:49:47.000000000 -0800 +++ wli-2.5.50-3/include/linux/sched.h 2002-12-04 18:42:39.000000000 -0800 @@ -27,6 +27,7 @@ #include <linux/compiler.h> #include <linux/completion.h> #include <linux/pid.h> +#include <linux/percpu.h> struct exec_domain; @@ -87,6 +88,8 @@ extern unsigned long avenrun[]; /* Load extern int nr_threads; extern int last_pid; +DECLARE_PER_CPU(unsigned long, process_counts); +extern int nr_processes(void); extern unsigned long nr_running(void); extern unsigned long nr_uninterruptible(void); extern unsigned long nr_iowait(void); diff -urpN mm1-2.5.50-2/kernel/exit.c wli-2.5.50-3/kernel/exit.c --- mm1-2.5.50-2/kernel/exit.c 2002-12-04 12:49:47.000000000 -0800 +++ wli-2.5.50-3/kernel/exit.c 2002-12-04 18:57:08.000000000 -0800 @@ -41,6 +41,8 @@ static struct dentry * __unhash_process( if (thread_group_leader(p)) { detach_pid(p, PIDTYPE_PGID); detach_pid(p, PIDTYPE_SID); + if (p->pid) + per_cpu(process_counts, smp_processor_id())--; } REMOVE_LINKS(p); diff -urpN mm1-2.5.50-2/kernel/fork.c wli-2.5.50-3/kernel/fork.c --- mm1-2.5.50-2/kernel/fork.c 2002-12-04 12:49:47.000000000 -0800 +++ wli-2.5.50-3/kernel/fork.c 2002-12-04 18:56:55.000000000 -0800 @@ -48,6 +48,8 @@ int nr_threads; int max_threads; unsigned long total_forks; /* Handle normal Linux uptimes. */ +DEFINE_PER_CPU(unsigned long, process_counts); + rwlock_t tasklist_lock __cacheline_aligned = RW_LOCK_UNLOCKED; /* outer */ /* @@ -57,6 +59,16 @@ rwlock_t tasklist_lock __cacheline_align */ static task_t *task_cache[NR_CPUS] __cacheline_aligned; +int nr_processes(void) +{ + int cpu; + unsigned long total = 0; + + for (cpu = 0; cpu < NR_CPUS; ++cpu) + total += per_cpu(process_counts, cpu); + return (int)total; +} + void __put_task_struct(struct task_struct *tsk) { if (tsk != current) { @@ -934,6 +946,8 @@ static struct task_struct *copy_process( attach_pid(p, PIDTYPE_TGID, p->tgid); attach_pid(p, PIDTYPE_PGID, p->pgrp); attach_pid(p, PIDTYPE_SID, p->session); + if (p->pid) + per_cpu(process_counts, smp_processor_id())++; } else link_pid(p, p->pids + PIDTYPE_TGID, &p->group_leader->pids[PIDTYPE_TGID].pid); - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
| |