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);
_______________________________________________
svn-src-head@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to