PR kern/38812 race between lwp_exit_switchaway and exit1/coredump

Move the LWP RUNNING and TIMEINTR flags into the thread-private flag word.
This commit is contained in:
ad 2008-05-31 21:26:01 +00:00
parent 8f34c216d0
commit 2feabc3836
7 changed files with 36 additions and 34 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: kern_lwp.c,v 1.114 2008/05/29 22:33:27 rmind Exp $ */
/* $NetBSD: kern_lwp.c,v 1.115 2008/05/31 21:26:01 ad Exp $ */
/*-
* Copyright (c) 2001, 2006, 2007, 2008 The NetBSD Foundation, Inc.
@ -80,7 +80,7 @@
* LWP. The LWP may in fact be executing on a processor, may be
* sleeping or idle. It is expected to take the necessary action to
* stop executing or become "running" again within a short timeframe.
* The LW_RUNNING flag in lwp::l_flag indicates that an LWP is running.
* The LP_RUNNING flag in lwp::l_pflag indicates that an LWP is running.
* Importantly, it indicates that its state is tied to a CPU.
*
* LSZOMB:
@ -206,7 +206,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: kern_lwp.c,v 1.114 2008/05/29 22:33:27 rmind Exp $");
__KERNEL_RCSID(0, "$NetBSD: kern_lwp.c,v 1.115 2008/05/31 21:26:01 ad Exp $");
#include "opt_ddb.h"
#include "opt_lockdebug.h"
@ -875,11 +875,11 @@ lwp_free(struct lwp *l, bool recycle, bool last)
* all locks to avoid deadlock against interrupt handlers on
* the target CPU.
*/
if ((l->l_flag & LW_RUNNING) != 0 || l->l_cpu->ci_curlwp == l) {
if ((l->l_pflag & LP_RUNNING) != 0 || l->l_cpu->ci_curlwp == l) {
int count;
(void)count; /* XXXgcc */
KERNEL_UNLOCK_ALL(curlwp, &count);
while ((l->l_flag & LW_RUNNING) != 0 ||
while ((l->l_pflag & LP_RUNNING) != 0 ||
l->l_cpu->ci_curlwp == l)
SPINLOCK_BACKOFF_HOOK;
KERNEL_LOCK(count, curlwp);
@ -1048,7 +1048,7 @@ lwp_migrate(lwp_t *l, struct cpu_info *tci)
* The destination CPU could be changed while previous migration
* was not finished.
*/
if ((l->l_flag & LW_RUNNING) != 0 || l->l_target_cpu != NULL) {
if ((l->l_pflag & LP_RUNNING) != 0 || l->l_target_cpu != NULL) {
l->l_target_cpu = tci;
lwp_unlock(l);
return;

View File

@ -1,4 +1,4 @@
/* $NetBSD: kern_resource.c,v 1.141 2008/05/05 17:11:17 ad Exp $ */
/* $NetBSD: kern_resource.c,v 1.142 2008/05/31 21:26:01 ad Exp $ */
/*-
* Copyright (c) 1982, 1986, 1991, 1993
@ -37,7 +37,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: kern_resource.c,v 1.141 2008/05/05 17:11:17 ad Exp $");
__KERNEL_RCSID(0, "$NetBSD: kern_resource.c,v 1.142 2008/05/31 21:26:01 ad Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@ -436,7 +436,7 @@ calcru(struct proc *p, struct timeval *up, struct timeval *sp,
LIST_FOREACH(l, &p->p_lwps, l_sibling) {
lwp_lock(l);
bintime_add(&tm, &l->l_rtime);
if ((l->l_flag & LW_RUNNING) != 0) {
if ((l->l_pflag & LP_RUNNING) != 0) {
struct bintime diff;
/*
* Adjust for the current time slice. This is

View File

@ -1,4 +1,4 @@
/* $NetBSD: kern_sleepq.c,v 1.30 2008/05/26 12:08:38 ad Exp $ */
/* $NetBSD: kern_sleepq.c,v 1.31 2008/05/31 21:26:01 ad Exp $ */
/*-
* Copyright (c) 2006, 2007, 2008 The NetBSD Foundation, Inc.
@ -35,7 +35,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: kern_sleepq.c,v 1.30 2008/05/26 12:08:38 ad Exp $");
__KERNEL_RCSID(0, "$NetBSD: kern_sleepq.c,v 1.31 2008/05/31 21:26:01 ad Exp $");
#include <sys/param.h>
#include <sys/kernel.h>
@ -124,7 +124,7 @@ sleepq_remove(sleepq_t *sq, lwp_t *l)
* If the LWP is still on the CPU, mark it as LSONPROC. It may be
* about to call mi_switch(), in which case it will yield.
*/
if ((l->l_flag & LW_RUNNING) != 0) {
if ((l->l_pflag & LP_RUNNING) != 0) {
l->l_stat = LSONPROC;
l->l_slptime = 0;
lwp_setlock(l, spc->spc_lwplock);

View File

@ -1,4 +1,4 @@
/* $NetBSD: kern_softint.c,v 1.21 2008/05/27 17:51:17 ad Exp $ */
/* $NetBSD: kern_softint.c,v 1.22 2008/05/31 21:26:01 ad Exp $ */
/*-
* Copyright (c) 2007, 2008 The NetBSD Foundation, Inc.
@ -176,7 +176,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: kern_softint.c,v 1.21 2008/05/27 17:51:17 ad Exp $");
__KERNEL_RCSID(0, "$NetBSD: kern_softint.c,v 1.22 2008/05/31 21:26:01 ad Exp $");
#include <sys/param.h>
#include <sys/malloc.h>
@ -758,10 +758,10 @@ softint_dispatch(lwp_t *pinned, int s)
* the LWP locked, at this point no external agents will want to
* modify the interrupt LWP's state.
*/
timing = (softint_timing ? LW_TIMEINTR : 0);
timing = (softint_timing ? LP_TIMEINTR : 0);
l->l_switchto = pinned;
l->l_stat = LSONPROC;
l->l_flag |= (LW_RUNNING | timing);
l->l_pflag |= (LP_RUNNING | timing);
/*
* Dispatch the interrupt. If softints are being timed, charge
@ -773,7 +773,7 @@ softint_dispatch(lwp_t *pinned, int s)
if (timing) {
binuptime(&now);
updatertime(l, &now);
l->l_flag &= ~LW_TIMEINTR;
l->l_pflag &= ~LP_TIMEINTR;
}
/*
@ -797,7 +797,7 @@ softint_dispatch(lwp_t *pinned, int s)
/* NOTREACHED */
}
l->l_switchto = NULL;
l->l_flag &= ~LW_RUNNING;
l->l_pflag &= ~LP_RUNNING;
}
#endif /* !__HAVE_FAST_SOFTINTS */

View File

@ -1,4 +1,4 @@
/* $NetBSD: kern_synch.c,v 1.247 2008/05/29 23:29:59 ad Exp $ */
/* $NetBSD: kern_synch.c,v 1.248 2008/05/31 21:26:01 ad Exp $ */
/*-
* Copyright (c) 1999, 2000, 2004, 2006, 2007, 2008 The NetBSD Foundation, Inc.
@ -68,7 +68,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: kern_synch.c,v 1.247 2008/05/29 23:29:59 ad Exp $");
__KERNEL_RCSID(0, "$NetBSD: kern_synch.c,v 1.248 2008/05/31 21:26:01 ad Exp $");
#include "opt_kstack.h"
#include "opt_perfctrs.h"
@ -527,12 +527,12 @@ nextlwp(struct cpu_info *ci, struct schedstate_percpu *spc)
KASSERT(lwp_locked(newl, spc->spc_mutex));
newl->l_stat = LSONPROC;
newl->l_cpu = ci;
newl->l_flag |= LW_RUNNING;
newl->l_pflag |= LP_RUNNING;
lwp_setlock(newl, spc->spc_lwplock);
} else {
newl = ci->ci_data.cpu_idlelwp;
newl->l_stat = LSONPROC;
newl->l_flag |= LW_RUNNING;
newl->l_pflag |= LP_RUNNING;
}
/*
@ -588,7 +588,7 @@ mi_switch(lwp_t *l)
if ((l->l_pflag & LP_INTR) != 0) {
returning = true;
softint_block(l);
if ((l->l_flag & LW_TIMEINTR) != 0)
if ((l->l_pflag & LP_TIMEINTR) != 0)
updatertime(l, &bt);
}
newl = l->l_switchto;
@ -599,7 +599,7 @@ mi_switch(lwp_t *l)
/* There are pending soft interrupts, so pick one. */
newl = softint_picklwp();
newl->l_stat = LSONPROC;
newl->l_flag |= LW_RUNNING;
newl->l_pflag |= LP_RUNNING;
}
#endif /* !__HAVE_FAST_SOFTINTS */
@ -705,7 +705,7 @@ mi_switch(lwp_t *l)
KASSERT(l->l_ctxswtch == 0);
l->l_ctxswtch = 1;
l->l_ncsw++;
l->l_flag &= ~LW_RUNNING;
l->l_pflag &= ~LP_RUNNING;
/*
* Increase the count of spin-mutexes before the release
@ -835,7 +835,7 @@ lwp_exit_switchaway(lwp_t *l)
/* There are pending soft interrupts, so pick one. */
newl = softint_picklwp();
newl->l_stat = LSONPROC;
newl->l_flag |= LW_RUNNING;
newl->l_pflag |= LP_RUNNING;
} else
#endif /* !__HAVE_FAST_SOFTINTS */
{
@ -844,7 +844,7 @@ lwp_exit_switchaway(lwp_t *l)
/* Update the new LWP's start time. */
newl->l_stime = bt;
l->l_flag &= ~LW_RUNNING;
l->l_pflag &= ~LP_RUNNING;
/*
* ci_curlwp changes when a fast soft interrupt occurs.
@ -949,7 +949,7 @@ setrunnable(struct lwp *l)
* If the LWP is still on the CPU, mark it as LSONPROC. It may be
* about to call mi_switch(), in which case it will yield.
*/
if ((l->l_flag & LW_RUNNING) != 0) {
if ((l->l_pflag & LP_RUNNING) != 0) {
l->l_stat = LSONPROC;
l->l_slptime = 0;
lwp_unlock(l);

View File

@ -1,4 +1,4 @@
/* $NetBSD: lwp.h,v 1.96 2008/05/19 12:48:54 rmind Exp $ */
/* $NetBSD: lwp.h,v 1.97 2008/05/31 21:26:01 ad Exp $ */
/*-
* Copyright (c) 2001, 2006, 2007, 2008 The NetBSD Foundation, Inc.
@ -200,7 +200,6 @@ extern lwp_t lwp0; /* LWP for proc0 */
#define LW_INMEM 0x00000004 /* Loaded into memory. */
#define LW_SINTR 0x00000080 /* Sleep is interruptible. */
#define LW_SYSTEM 0x00000200 /* Kernel thread */
#define LW_TIMEINTR 0x00010000 /* Time this soft interrupt */
#define LW_WSUSPEND 0x00020000 /* Suspend before return to user */
#define LW_BATCH 0x00040000 /* LWP tends to hog CPU */
#define LW_WCORE 0x00080000 /* Stop for core dump on return to user */
@ -211,7 +210,6 @@ extern lwp_t lwp0; /* LWP for proc0 */
#define LW_WUSERRET 0x04000000 /* Call proc::p_userret on return to user */
#define LW_WREBOOT 0x08000000 /* System is rebooting, please suspend */
#define LW_UNPARKED 0x10000000 /* Unpark op pending */
#define LW_RUNNING 0x20000000 /* Active on a CPU (except if LSZOMB) */
/* The second set of flags is kept in l_pflag. */
#define LP_KTRACTIVE 0x00000001 /* Executing ktrace operation */
@ -221,6 +219,8 @@ extern lwp_t lwp0; /* LWP for proc0 */
#define LP_MPSAFE 0x00000020 /* Starts life without kernel_lock */
#define LP_INTR 0x00000040 /* Soft interrupt handler */
#define LP_SYSCTLWRITE 0x00000080 /* sysctl write lock held */
#define LP_TIMEINTR 0x00010000 /* Time this soft interrupt */
#define LP_RUNNING 0x20000000 /* Active on a CPU */
#define LP_BOUND 0x80000000 /* Bound to a CPU */
/* The third set is kept in l_prflag. */

View File

@ -1,4 +1,4 @@
/* $NetBSD: uvm_glue.c,v 1.126 2008/04/27 11:39:46 ad Exp $ */
/* $NetBSD: uvm_glue.c,v 1.127 2008/05/31 21:26:01 ad Exp $ */
/*
* Copyright (c) 1997 Charles D. Cranor and Washington University.
@ -67,7 +67,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: uvm_glue.c,v 1.126 2008/04/27 11:39:46 ad Exp $");
__KERNEL_RCSID(0, "$NetBSD: uvm_glue.c,v 1.127 2008/05/31 21:26:01 ad Exp $");
#include "opt_coredump.h"
#include "opt_kgdb.h"
@ -617,7 +617,9 @@ static bool
swappable(struct lwp *l)
{
if ((l->l_flag & (LW_INMEM|LW_RUNNING|LW_SYSTEM|LW_WEXIT)) != LW_INMEM)
if ((l->l_flag & (LW_INMEM|LW_SYSTEM|LW_WEXIT)) != LW_INMEM)
return false;
if ((l->l_pflag & LP_RUNNING) != 0)
return false;
if (l->l_holdcnt != 0)
return false;