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