PR kern/38761: new (?) race in buffer cache code
- Back out the previous workaround now that the sleep queue code has been changed to never let the queue become empty if there are valid waiters. - Use sleepq_hashlock() to improve clarity. - Sprinkle some assertions.
This commit is contained in:
parent
461a5fb24b
commit
672f91757e
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: kern_condvar.c,v 1.23 2008/06/15 09:56:18 chris Exp $ */
|
||||
/* $NetBSD: kern_condvar.c,v 1.24 2008/06/16 10:03:47 ad Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2006, 2007, 2008 The NetBSD Foundation, Inc.
|
||||
|
@ -30,15 +30,11 @@
|
|||
*/
|
||||
|
||||
/*
|
||||
* Kernel condition variable implementation, modeled after those found in
|
||||
* Solaris, a description of which can be found in:
|
||||
*
|
||||
* Solaris Internals: Core Kernel Architecture, Jim Mauro and
|
||||
* Richard McDougall.
|
||||
* Kernel condition variable implementation.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: kern_condvar.c,v 1.23 2008/06/15 09:56:18 chris Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: kern_condvar.c,v 1.24 2008/06/16 10:03:47 ad Exp $");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/proc.h>
|
||||
|
@ -47,6 +43,7 @@ __KERNEL_RCSID(0, "$NetBSD: kern_condvar.c,v 1.23 2008/06/15 09:56:18 chris Exp
|
|||
#include <sys/condvar.h>
|
||||
#include <sys/sleepq.h>
|
||||
#include <sys/lockdebug.h>
|
||||
#include <sys/cpu.h>
|
||||
|
||||
#include <uvm/uvm_extern.h>
|
||||
|
||||
|
@ -127,16 +124,18 @@ cv_enter(kcondvar_t *cv, kmutex_t *mtx, lwp_t *l)
|
|||
kmutex_t *mp;
|
||||
|
||||
KASSERT(cv_is_valid(cv));
|
||||
KASSERT(!cpu_intr_p());
|
||||
KASSERT((l->l_pflag & LP_INTR) == 0 || panicstr != NULL);
|
||||
|
||||
LOCKDEBUG_LOCKED(CV_DEBUG_P(cv), cv, mtx, CV_RA, 0);
|
||||
|
||||
l->l_kpriority = true;
|
||||
(void)sleeptab_lookup(&sleeptab, cv, &mp);
|
||||
mp = sleepq_hashlock(cv);
|
||||
sq = CV_SLEEPQ(cv);
|
||||
sleepq_enter(sq, l, mp);
|
||||
sleepq_enqueue(sq, cv, cv->cv_wmesg, &cv_syncobj);
|
||||
mutex_exit(mtx);
|
||||
KASSERT(cv_has_waiters(cv));
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -181,7 +180,7 @@ cv_unsleep(lwp_t *l, bool cleanup)
|
|||
KASSERT(l->l_wchan == (wchan_t)cv);
|
||||
KASSERT(l->l_sleepq == CV_SLEEPQ(cv));
|
||||
KASSERT(cv_is_valid(cv));
|
||||
KASSERT(!TAILQ_EMPTY(CV_SLEEPQ(cv)));
|
||||
KASSERT(cv_has_waiters(cv));
|
||||
|
||||
return sleepq_unsleep(l, cleanup);
|
||||
}
|
||||
|
@ -279,7 +278,8 @@ cv_signal(kcondvar_t *cv)
|
|||
/* LOCKDEBUG_WAKEUP(CV_DEBUG_P(cv), cv, CV_RA); */
|
||||
KASSERT(cv_is_valid(cv));
|
||||
|
||||
cv_wakeup_one(cv);
|
||||
if (__predict_false(!TAILQ_EMPTY(CV_SLEEPQ(cv))))
|
||||
cv_wakeup_one(cv);
|
||||
}
|
||||
|
||||
static void __noinline
|
||||
|
@ -292,8 +292,8 @@ cv_wakeup_one(kcondvar_t *cv)
|
|||
|
||||
KASSERT(cv_is_valid(cv));
|
||||
|
||||
mp = sleepq_hashlock(cv);
|
||||
sq = CV_SLEEPQ(cv);
|
||||
(void)sleeptab_lookup(&sleeptab, cv, &mp);
|
||||
l = TAILQ_FIRST(sq);
|
||||
if (l == NULL) {
|
||||
mutex_spin_exit(mp);
|
||||
|
@ -328,7 +328,8 @@ cv_broadcast(kcondvar_t *cv)
|
|||
/* LOCKDEBUG_WAKEUP(CV_DEBUG_P(cv), cv, CV_RA); */
|
||||
KASSERT(cv_is_valid(cv));
|
||||
|
||||
cv_wakeup_all(cv);
|
||||
if (__predict_false(!TAILQ_EMPTY(CV_SLEEPQ(cv))))
|
||||
cv_wakeup_all(cv);
|
||||
}
|
||||
|
||||
static void __noinline
|
||||
|
@ -341,9 +342,9 @@ cv_wakeup_all(kcondvar_t *cv)
|
|||
|
||||
KASSERT(cv_is_valid(cv));
|
||||
|
||||
sq = CV_SLEEPQ(cv);
|
||||
(void)sleeptab_lookup(&sleeptab, cv, &mp);
|
||||
mp = sleepq_hashlock(cv);
|
||||
swapin = 0;
|
||||
sq = CV_SLEEPQ(cv);
|
||||
for (l = TAILQ_FIRST(sq); l != NULL; l = next) {
|
||||
KASSERT(l->l_sleepq == sq);
|
||||
KASSERT(l->l_mutex == mp);
|
||||
|
|
Loading…
Reference in New Issue