tech-kern archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
patch for kern/46168
Hello,
has someone comments about the patch I propose in kern/46168 before I commit
it ? It's also attached below.
Basically, it looks like a LWP may be added to a proc while lwp_wait1()
has released the p_lock, even if lwp_wait1() returns 0. As a result,
we're waiting for a LWP which doesn't have the LW_WEXIT flag.
What the patch does is always reprocess the lwp list if lwp_wait1() returns
and p_nlwps is still > 1.
This doesn't cause new test failures (I did 2 runs) and I coudln't
reproduce the problem in kern/46168 with this patch.
--
Manuel Bouyer <bouyer%antioche.eu.org@localhost>
NetBSD: 26 ans d'experience feront toujours la difference
--
Index: kern/kern_exit.c
===================================================================
RCS file: /cvsroot/src/sys/kern/kern_exit.c,v
retrieving revision 1.237
diff -u -p -u -r1.237 kern_exit.c
--- kern/kern_exit.c 19 Feb 2012 21:06:50 -0000 1.237
+++ kern/kern_exit.c 14 Mar 2012 16:22:47 -0000
@@ -598,44 +598,42 @@ exit_lwps(struct lwp *l)
p = l->l_proc;
KASSERT(mutex_owned(p->p_lock));
-retry:
- /*
- * Interrupt LWPs in interruptable sleep, unsuspend suspended
- * LWPs and then wait for everyone else to finish.
- */
- LIST_FOREACH(l2, &p->p_lwps, l_sibling) {
- if (l2 == l)
- continue;
- lwp_lock(l2);
- l2->l_flag |= LW_WEXIT;
- if ((l2->l_stat == LSSLEEP && (l2->l_flag & LW_SINTR)) ||
- l2->l_stat == LSSUSPENDED || l2->l_stat == LSSTOP) {
- /* setrunnable() will release the lock. */
- setrunnable(l2);
- DPRINTF(("exit_lwps: Made %d.%d runnable\n",
- p->p_pid, l2->l_lid));
- continue;
- }
- lwp_unlock(l2);
- }
while (p->p_nlwps > 1) {
+ /*
+ * Interrupt LWPs in interruptable sleep, unsuspend suspended
+ * LWPs and then wait for everyone else to finish.
+ */
+ LIST_FOREACH(l2, &p->p_lwps, l_sibling) {
+ if (l2 == l)
+ continue;
+ lwp_lock(l2);
+ l2->l_flag |= LW_WEXIT;
+ if ((l2->l_stat == LSSLEEP && (l2->l_flag & LW_SINTR))
||
+ l2->l_stat == LSSUSPENDED || l2->l_stat == LSSTOP) {
+ /* setrunnable() will release the lock. */
+ setrunnable(l2);
+ DPRINTF(("exit_lwps: Made %d.%d runnable\n",
+ p->p_pid, l2->l_lid));
+ continue;
+ }
+ lwp_unlock(l2);
+ }
DPRINTF(("exit_lwps: waiting for %d LWPs (%d zombies)\n",
p->p_nlwps, p->p_nzlwps));
error = lwp_wait1(l, 0, &waited, LWPWAIT_EXITCONTROL);
if (p->p_nlwps == 1)
break;
- if (error == EDEADLK) {
- /*
- * LWPs can get suspended/slept behind us.
- * (eg. sa_setwoken)
- * kick them again and retry.
- */
- goto retry;
- }
- if (error)
+ if (error == 0)
+ DPRINTF(("exit_lwps: Got LWP %d from lwp_wait1()\n",
+ waited));
+ else if (error != EDEADLK)
panic("exit_lwps: lwp_wait1 failed with error %d",
error);
- DPRINTF(("exit_lwps: Got LWP %d from lwp_wait1()\n", waited));
+ /*
+ * LWPs can get suspended/slept behind us.
+ * (eg. sa_setwoken)
+ * kick them again and retry.
+ */
}
KERNEL_LOCK(nlocks, l);
Home |
Main Index |
Thread Index |
Old Index