On Fri, 2002-09-06 at 10:39, Ingo Molnar wrote:
> On 6 Sep 2002, Paul Larson wrote:
> > It looks like this change dropped us back to the same error all this was
> > originally supposed to fix. When you hit PID_MAX, get_pid() starts
> > looping forever looking for a free pid and hangs. I could probably make
> > my original fix work on this very easily if you'd like.
>
> yes please send a patch for this. Reintroduction of the looping bug was
> unintended.
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/
This archive was generated by hypermail 2b29 : Sat Sep 07 2002 - 22:00:29 EST