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:
parent
8f34c216d0
commit
2feabc3836
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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. */
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue