DF-2928 / fix.diff
diff --git a/sys/kern/kern_spinlock.c b/sys/kern/kern_spinlock.c index 0000000..0000001 100644 --- a/sys/kern/kern_spinlock.c +++ b/sys/kern/kern_spinlock.c @@ -88,7 +88,9 @@ #ifdef INVARIANTS -static int spin_lock_test_mode; +/* + * Read by indefinite_check() (sys/sys/indefinite2.h) to break spinlock + * test waits. Must NOT be static. + */ +int spin_lock_test_mode; #endif #ifdef DEBUG_LOCKS_LATENCY diff --git a/sys/sys/indefinite.h b/sys/sys/indefinite.h index 0000000..0000002 100644 --- a/sys/sys/indefinite.h +++ b/sys/sys/indefinite.h @@ -41,6 +41,10 @@ extern int lock_test_mode; extern int indefinite_uses_rdtsc; +#if defined(INVARIANTS) +extern int spin_lock_test_mode; +#endif struct indefinite_info { diff --git a/sys/sys/indefinite2.h b/sys/sys/indefinite2.h index 0000000..0000003 100644 --- a/sys/sys/indefinite2.h +++ b/sys/sys/indefinite2.h @@ -168,6 +168,15 @@ indefinite_check(indefinite_info_t *info) kprintf("%s: %s, indefinite wait (%d secs)!\n", str, info->ident, info->secs); if (panicstr) return TRUE; #if defined(INVARIANTS) + /* + * Spinlock indefinite-wait test hook (debug.spin_lock_test=1). + * Restores the pre-indefinite2.h semantics: the sysctl's + * recursive spin_lock breaks at the first 1-second report + * instead of running into the 60-second panic below. + */ + if ((info->type == 'S' || info->type == 's') && + spin_lock_test_mode) { + print_backtrace(-1); + return TRUE; + } if (lock_test_mode) { print_backtrace(-1); return TRUE; |