Author: bde
Date: Mon Aug 15 12:56:45 2016
New Revision: 304153
URL: https://svnweb.freebsd.org/changeset/base/304153

Log:
  Quick fix for locking fixes in r172250.  The lock added there was per-
  virtual-device, but needs to be per-physical-device so that it protects
  shared data.  Usually, scp->sc->write_in_progress got corrupted first
  and further corruption was limited when this variable was left at nonzero
  with no write in progress.
  
  Attempt to fix missing lock destruction in r162285.  Put it with the
  lock destruction for r172250 after moving the latter.  Both might be
  unreachable.
  
  To demonstrate the bug, find a buggy syscall or sysctl that calls
  printf(9) and run this often.  Run hd /dev/zero >/dev/ttyvN for any
  N != 0.  The console spam goes to ttyv0 and the non-console spam goes
  to ttyvN, so the lock provided no protection (but it helped for
  N == 0).

Modified:
  head/sys/dev/syscons/syscons.c
  head/sys/dev/syscons/syscons.h

Modified: head/sys/dev/syscons/syscons.c
==============================================================================
--- head/sys/dev/syscons/syscons.c      Mon Aug 15 12:13:14 2016        
(r304152)
+++ head/sys/dev/syscons/syscons.c      Mon Aug 15 12:56:45 2016        
(r304153)
@@ -2688,13 +2688,13 @@ sc_puts(scr_stat *scp, u_char *buf, int 
 #endif
 
     if (scp->tsw) {
-       if (!kdb_active && !mtx_owned(&scp->scr_lock)) {
+       if (!kdb_active && !mtx_owned(&scp->sc->scr_lock)) {
                need_unlock = 1;
-               mtx_lock_spin(&scp->scr_lock);
+               mtx_lock_spin(&scp->sc->scr_lock);
        }
        (*scp->tsw->te_puts)(scp, buf, len, kernel);
        if (need_unlock)
-               mtx_unlock_spin(&scp->scr_lock);
+               mtx_unlock_spin(&scp->sc->scr_lock);
     }
 
     if (scp->sc->delayed_next_scr)
@@ -2859,8 +2859,10 @@ scinit(int unit, int flags)
      * disappeared...
      */
     sc = sc_get_softc(unit, flags & SC_KERNEL_CONSOLE);
-    if ((sc->flags & SC_INIT_DONE) == 0)
+    if ((sc->flags & SC_INIT_DONE) == 0) {
+       mtx_init(&sc->scr_lock, "scrlock", NULL, MTX_SPIN);
        SC_VIDEO_LOCKINIT(sc);
+    }
 
     adp = NULL;
     if (sc->adapter >= 0) {
@@ -3077,7 +3079,8 @@ scterm(int unit, int flags)
        (*scp->tsw->te_term)(scp, &scp->ts);
     if (scp->ts != NULL)
        free(scp->ts, M_DEVBUF);
-    mtx_destroy(&scp->scr_lock);
+    mtx_destroy(&sc->scr_lock);
+    mtx_destroy(&sc->video_mtx);
 
     /* clear the structure */
     if (!(flags & SC_KERNEL_CONSOLE)) {
@@ -3302,8 +3305,6 @@ init_scp(sc_softc_t *sc, int vty, scr_st
     scp->history = NULL;
     scp->history_pos = 0;
     scp->history_size = 0;
-
-    mtx_init(&scp->scr_lock, "scrlock", NULL, MTX_SPIN);
 }
 
 int

Modified: head/sys/dev/syscons/syscons.h
==============================================================================
--- head/sys/dev/syscons/syscons.h      Mon Aug 15 12:13:14 2016        
(r304152)
+++ head/sys/dev/syscons/syscons.h      Mon Aug 15 12:56:45 2016        
(r304153)
@@ -230,6 +230,7 @@ typedef struct sc_softc {
        char            switch_in_progress;
        char            write_in_progress;
        char            blink_in_progress;
+       struct mtx      scr_lock;               /* mutex for sc_puts() */
        struct mtx      video_mtx;
 
        long            scrn_time_stamp;
@@ -344,7 +345,6 @@ typedef struct scr_stat {
 
        int             splash_save_mode;       /* saved mode for splash screen 
*/
        int             splash_save_status;     /* saved status for splash 
screen */
-       struct mtx      scr_lock;               /* mutex for sc_puts() */
 #ifdef _SCR_MD_STAT_DECLARED_
        scr_md_stat_t   md;                     /* machine dependent vars */
 #endif
_______________________________________________
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