proc_fill_super() simply wants a count of processes, not threads.
This creates a per-cpu counter for it to use to determine that.

 fs/proc/inode.c       |    7 +------
 include/linux/sched.h |    3 +++
 kernel/exit.c         |    2 ++
 kernel/fork.c         |   14 ++++++++++++++
 4 files changed, 20 insertions(+), 6 deletions(-)


diff -urpN wli-2.5.51-bk1-3/fs/proc/inode.c wli-2.5.51-bk1-4/fs/proc/inode.c
--- wli-2.5.51-bk1-3/fs/proc/inode.c	2002-12-09 18:46:20.000000000 -0800
+++ wli-2.5.51-bk1-4/fs/proc/inode.c	2002-12-11 18:31:25.000000000 -0800
@@ -221,7 +221,6 @@ out_fail:
 int proc_fill_super(struct super_block *s, void *data, int silent)
 {
 	struct inode * root_inode;
-	struct task_struct *p;
 
 	s->s_blocksize = 1024;
 	s->s_blocksize_bits = 10;
@@ -234,11 +233,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 wli-2.5.51-bk1-3/include/linux/sched.h wli-2.5.51-bk1-4/include/linux/sched.h
--- wli-2.5.51-bk1-3/include/linux/sched.h	2002-12-09 18:45:43.000000000 -0800
+++ wli-2.5.51-bk1-4/include/linux/sched.h	2002-12-11 18:31:25.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 wli-2.5.51-bk1-3/kernel/exit.c wli-2.5.51-bk1-4/kernel/exit.c
--- wli-2.5.51-bk1-3/kernel/exit.c	2002-12-09 18:46:18.000000000 -0800
+++ wli-2.5.51-bk1-4/kernel/exit.c	2002-12-11 18:31:25.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 wli-2.5.51-bk1-3/kernel/fork.c wli-2.5.51-bk1-4/kernel/fork.c
--- wli-2.5.51-bk1-3/kernel/fork.c	2002-12-09 18:45:43.000000000 -0800
+++ wli-2.5.51-bk1-4/kernel/fork.c	2002-12-11 18:31:25.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) {
@@ -929,6 +941,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);