From 2feabc3836655ae625f5a48e800ef0075107f3ad Mon Sep 17 00:00:00 2001 From: ad Date: Sat, 31 May 2008 21:26:01 +0000 Subject: [PATCH] PR kern/38812 race between lwp_exit_switchaway and exit1/coredump Move the LWP RUNNING and TIMEINTR flags into the thread-private flag word. --- sys/kern/kern_lwp.c | 12 ++++++------ sys/kern/kern_resource.c | 6 +++--- sys/kern/kern_sleepq.c | 6 +++--- sys/kern/kern_softint.c | 12 ++++++------ sys/kern/kern_synch.c | 20 ++++++++++---------- sys/sys/lwp.h | 6 +++--- sys/uvm/uvm_glue.c | 8 +++++--- 7 files changed, 36 insertions(+), 34 deletions(-) diff --git a/sys/kern/kern_lwp.c b/sys/kern/kern_lwp.c index 81b7b9307309..2ed31c3f7426 100644 --- a/sys/kern/kern_lwp.c +++ b/sys/kern/kern_lwp.c @@ -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 -__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; diff --git a/sys/kern/kern_resource.c b/sys/kern/kern_resource.c index 4561587c5b71..121035e5deb6 100644 --- a/sys/kern/kern_resource.c +++ b/sys/kern/kern_resource.c @@ -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 -__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 #include @@ -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 diff --git a/sys/kern/kern_sleepq.c b/sys/kern/kern_sleepq.c index ce6c880cad78..18baeb821fec 100644 --- a/sys/kern/kern_sleepq.c +++ b/sys/kern/kern_sleepq.c @@ -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 -__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 #include @@ -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); diff --git a/sys/kern/kern_softint.c b/sys/kern/kern_softint.c index 74617247c31c..02c2910fad09 100644 --- a/sys/kern/kern_softint.c +++ b/sys/kern/kern_softint.c @@ -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 -__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 #include @@ -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 */ diff --git a/sys/kern/kern_synch.c b/sys/kern/kern_synch.c index a83ee2c7a2e9..223c48942142 100644 --- a/sys/kern/kern_synch.c +++ b/sys/kern/kern_synch.c @@ -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 -__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); diff --git a/sys/sys/lwp.h b/sys/sys/lwp.h index 3287b0a501e8..94fdc3be817c 100644 --- a/sys/sys/lwp.h +++ b/sys/sys/lwp.h @@ -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. */ diff --git a/sys/uvm/uvm_glue.c b/sys/uvm/uvm_glue.c index 0449b81b01a8..a9a2a27e8162 100644 --- a/sys/uvm/uvm_glue.c +++ b/sys/uvm/uvm_glue.c @@ -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 -__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;