Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id ; Fri, 6 Sep 2002 13:51:03 -0400 Received: (majordomo@vger.kernel.org) by vger.kernel.org id ; Fri, 6 Sep 2002 13:51:03 -0400 Received: from e2.ny.us.ibm.com ([32.97.182.102]:29930 "EHLO e2.ny.us.ibm.com") by vger.kernel.org with ESMTP id ; Fri, 6 Sep 2002 13:51:02 -0400 Subject: [PATCH] pid_max hang again... From: Paul Larson To: Ingo Molnar Cc: Linus Torvalds , lkml In-Reply-To: References: Content-Type: text/plain Content-Transfer-Encoding: 7bit X-Mailer: Ximian Evolution 1.0.5 Date: 06 Sep 2002 12:43:15 -0500 Message-Id: <1031334205.30394.14.camel@plars.austin.ibm.com> Mime-Version: 1.0 Sender: linux-kernel-owner@vger.kernel.org X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 2525 Lines: 90 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 #include #include +#include #include #include @@ -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/