Here's the original one without all the bitmap stuff, JUST the fix for
the hang problem plain and simple. It should apply cleanly against the
current bk. The only other small bit in here moves the test for flags &
CLONE_IDLETASK outside of get_pid since we can skip the unnecessary call
to get_pid if it's true. Except for the last part, this is the same
thing I put into 2.4 some time ago.
Please comment or apply.
Thanks,
Paul Larson
diff -Nru a/kernel/fork.c b/kernel/fork.c
--- a/kernel/fork.c Fri Sep 6 20:19:21 2002
+++ b/kernel/fork.c Fri Sep 6 20:19:21 2002
@@ -28,6 +28,7 @@
#include <linux/security.h>
#include <linux/futex.h>
#include <linux/ptrace.h>
+#include <linux/compiler.h>
#include <asm/pgtable.h>
#include <asm/pgalloc.h>
@@ -162,12 +163,10 @@
static int get_pid(unsigned long flags)
{
struct task_struct *p;
- int pid;
-
- if (flags & CLONE_IDLETASK)
- return 0;
+ int pid, beginpid;
spin_lock(&lastpid_lock);
+ beginpid = last_pid;
if (++last_pid > pid_max) {
last_pid = 300; /* Skip daemons etc. */
goto inside;
@@ -188,6 +187,8 @@
last_pid = 300;
next_safe = pid_max;
}
+ if (unlikely(last_pid == beginpid))
+ goto nomorepids;
goto repeat;
}
if (p->pid > last_pid && next_safe > p->pid)
@@ -205,6 +206,11 @@
spin_unlock(&lastpid_lock);
return pid;
+
+nomorepids:
+ read_unlock(&tasklist_lock);
+ spin_unlock(&lastpid_lock);
+ return 0;
}
static inline int dup_mmap(struct mm_struct * mm)
@@ -707,7 +713,13 @@
p->state = TASK_UNINTERRUPTIBLE;
copy_flags(clone_flags, p);
- p->pid = get_pid(clone_flags);
+ if (clone_flags & CLONE_IDLETASK)
+ p->pid = 0;
+ else {
+ p->pid = get_pid(clone_flags);
+ if (p->pid == 0)
+ goto bad_fork_cleanup;
+ }
p->proc_dentry = NULL;
INIT_LIST_HEAD(&p->run_list);
-
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/