Page MenuHomeFreeBSD

D34204.id102502.diff
No OneTemporary

D34204.id102502.diff

Index: sys/kern/subr_sleepqueue.c
===================================================================
--- sys/kern/subr_sleepqueue.c
+++ sys/kern/subr_sleepqueue.c
@@ -67,6 +67,7 @@
#include <sys/param.h>
#include <sys/systm.h>
+#include <sys/counter.h>
#include <sys/lock.h>
#include <sys/kernel.h>
#include <sys/ktr.h>
@@ -145,13 +146,17 @@
#endif
} __aligned(CACHE_LINE_SIZE);
-#ifdef SLEEPQUEUE_PROFILING
-u_int sleepq_max_depth;
static SYSCTL_NODE(_debug, OID_AUTO, sleepq, CTLFLAG_RD | CTLFLAG_MPSAFE, 0,
"sleepq profiling");
+static COUNTER_U64_DEFINE_EARLY(sleepq_spurious_timeouts);
+SYSCTL_COUNTER_U64(_debug_sleepq, OID_AUTO, spurious_timeouts, CTLFLAG_RD,
+ &sleepq_spurious_timeouts, "XXXMJ");
+
+#ifdef SLEEPQUEUE_PROFILING
static SYSCTL_NODE(_debug_sleepq, OID_AUTO, chains,
CTLFLAG_RD | CTLFLAG_MPSAFE, 0,
"sleepq chain stats");
+static u_int sleepq_max_depth;
SYSCTL_UINT(_debug_sleepq, OID_AUTO, max_depth, CTLFLAG_RD, &sleepq_max_depth,
0, "maxmimum depth achieved of a single chain");
@@ -560,6 +565,10 @@
* just return.
*/
if (td->td_sleepqueue != NULL) {
+ /*
+ * XXXMJ is it possible for TDF_TIMEOUT to be set? Does it
+ * matter?
+ */
mtx_unlock_spin(&sc->sc_lock);
thread_unlock(td);
return;
@@ -833,7 +842,8 @@
td->td_sleepqueue = LIST_FIRST(&sq->sq_free);
LIST_REMOVE(td->td_sleepqueue, sq_hash);
- if ((td->td_flags & TDF_TIMEOUT) == 0 && td->td_sleeptimo != 0)
+ if ((td->td_flags & TDF_TIMEOUT) == 0 && td->td_sleeptimo != 0 &&
+ td->td_lock == &sc->sc_lock) {
/*
* We ignore the situation where timeout subsystem was
* unable to stop our callout. The struct thread is
@@ -843,8 +853,16 @@
* sleepq_timeout() ensure that the thread does not
* get spurious wakeups, even if the callout was reset
* or thread reused.
+ *
+ * We also cannot safely stop the callout if a scheduler
+ * lock is held since softclock_thread() forces a lock
+ * order of callout lock -> scheduler lock. The thread
+ * lock will be a scheduler lock only if the thread is
+ * preparing to go to sleep, so this is hopefully a rare
+ * scenario.
*/
callout_stop(&td->td_slpcallout);
+ }
td->td_wmesg = NULL;
td->td_wchan = NULL;
@@ -1045,6 +1063,7 @@
/*
* The thread does not want a timeout (yet).
*/
+ counter_u64_add(sleepq_spurious_timeouts, 1);
} else if (TD_IS_SLEEPING(td) && TD_ON_SLEEPQ(td)) {
/*
* See if the thread is asleep and get the wait
@@ -1068,6 +1087,8 @@
* routines or it can be in sleepq_catch_signals().
*/
td->td_flags |= TDF_TIMEOUT;
+ } else {
+ counter_u64_add(sleepq_spurious_timeouts, 1);
}
thread_unlock(td);
}

File Metadata

Mime Type
text/plain
Expires
Wed, Apr 8, 8:41 AM (8 h, 32 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
31089293
Default Alt Text
D34204.id102502.diff (2 KB)

Event Timeline