diff -urN 2.3.18ac7/include/linux/sched.h 2.3.18ac7-nr_threads/include/linux/sched.h --- 2.3.18ac7/include/linux/sched.h Tue Sep 21 16:46:50 1999 +++ 2.3.18ac7-nr_threads/include/linux/sched.h Wed Sep 22 15:31:53 1999 @@ -825,8 +825,8 @@ extern inline void unhash_process(struct task_struct *p) { if (task_on_runqueue(p)) BUG(); - nr_threads--; write_lock_irq(&tasklist_lock); + nr_threads--; unhash_pid(p); REMOVE_LINKS(p); write_unlock_irq(&tasklist_lock); diff -urN 2.3.18ac7/kernel/fork.c 2.3.18ac7-nr_threads/kernel/fork.c --- 2.3.18ac7/kernel/fork.c Tue Sep 21 16:46:51 1999 +++ 2.3.18ac7-nr_threads/kernel/fork.c Wed Sep 22 15:36:40 1999 @@ -617,8 +617,9 @@ } /* - * Counter atomicity is protected by - * the kernel lock + * Counter increases are protected by + * the kernel lock so nr_threads can't + * increase under us (but it may decrease). */ if (nr_threads >= max_threads) goto bad_fork_cleanup_count; @@ -718,9 +719,9 @@ write_lock_irq(&tasklist_lock); SET_LINKS(p); hash_pid(p); + nr_threads++; write_unlock_irq(&tasklist_lock); - nr_threads++; wake_up_process(p); /* do this last */ ++total_forks; @@ -742,8 +743,6 @@ __MOD_DEC_USE_COUNT(p->exec_domain->module); if (p->binfmt && p->binfmt->module) __MOD_DEC_USE_COUNT(p->binfmt->module); - - nr_threads--; bad_fork_cleanup_count: if (p->user) free_uid(p);