svn commit: r334526 - head/sys/dev/syscons
Bruce Evans
bde at FreeBSD.org
Sat Jun 2 08:39:00 UTC 2018
Author: bde
Date: Sat Jun 2 08:38:59 2018
New Revision: 334526
URL: https://svnweb.freebsd.org/changeset/base/334526
Log:
Fix low-level locking during panics.
The SCHEDULER_STOPPED() hack breaks locking generally, and
mtx_trylock_*() especially. When mtx_trylock_*() returns nonzero,
naive code version here trusts it to have worked. But when
SCHEDULER_STOPPED() is true, mtx_trylock_*() returns 1 without doing
anything. Then mtx_unlock_*() crashes especially badly attempting to
unlock iff the error is detected, since mutex unlocking functions don't
check SCHEDULER_STOPPED().
syscons already didn't trust mtx_trylock_spin(), but it was missing the
logic to turn on sp->kdb_locked when turning off sp->mtx_locked during
panics. It also used panicstr instead of SCHEDULER_LOCKED because I
thought that panicstr was more fragile. They only differ for a window
of lines in panic(), and in broken cases where stop_cpus_hard() in panic()
didn't work.
Modified:
head/sys/dev/syscons/syscons.c
Modified: head/sys/dev/syscons/syscons.c
==============================================================================
--- head/sys/dev/syscons/syscons.c Sat Jun 2 07:44:53 2018 (r334525)
+++ head/sys/dev/syscons/syscons.c Sat Jun 2 08:38:59 2018 (r334526)
@@ -1807,13 +1807,19 @@ sccnscrlock(sc_softc_t *sc, struct sc_cnstate *sp)
* enough to ignore the protection even in the kdb_active case.
*/
if (kdb_active) {
- sp->kdb_locked = sc->video_mtx.mtx_lock == MTX_UNOWNED || panicstr;
+ sp->kdb_locked = sc->video_mtx.mtx_lock == MTX_UNOWNED ||
+ SCHEDULER_STOPPED();
sp->mtx_locked = FALSE;
} else {
sp->kdb_locked = FALSE;
for (retries = 0; retries < 1000; retries++) {
sp->mtx_locked = mtx_trylock_spin_flags(&sc->video_mtx,
- MTX_QUIET) != 0 || panicstr;
+ MTX_QUIET) != 0;
+ if (SCHEDULER_STOPPED()) {
+ sp->kdb_locked = TRUE;
+ sp->mtx_locked = FALSE;
+ break;
+ }
if (sp->mtx_locked)
break;
DELAY(1);
More information about the svn-src-all
mailing list