Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 29 Aug 2016 18:41:06 +0000 (UTC)
From:      Bruce Evans <bde@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r305010 - head/sys/dev/syscons
Message-ID:  <201608291841.u7TIf6mu053342@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: bde
Date: Mon Aug 29 18:41:06 2016
New Revision: 305010
URL: https://svnweb.freebsd.org/changeset/base/305010

Log:
  Add screen locking calls to sc cn grab and ungrab.  The locking functions
  just use the same mutex locking as sc cn putc so they have the same
  defects.
  
  The locking calls to acquire the lock are actually in sc cn open and close.
  Ungrab has to unlock, although this opens a race window.
  
  Change the direct mutex lock calls in sc cn putc to the new locking
  functions via the open and close functions.  Putc also has to unlock, but
  doesn't keep the screen open like grab.  Screen open and close reduce to
  locking, except screen open for grab also attempts to switch the screen.
  
  Keyboard locking is more difficult and still null, even when keyboard
  input calls screen functions, except some of the functions have locks
  too deep to work right.
  
  This organization gives a single place to fix some of the locking.

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

Modified: head/sys/dev/syscons/syscons.c
==============================================================================
--- head/sys/dev/syscons/syscons.c	Mon Aug 29 18:31:34 2016	(r305009)
+++ head/sys/dev/syscons/syscons.c	Mon Aug 29 18:41:06 2016	(r305010)
@@ -1649,6 +1649,20 @@ sc_cnterm(struct consdev *cp)
 
 static void sccnclose(sc_softc_t *sc, struct sc_cnstate *sp);
 static void sccnopen(sc_softc_t *sc, struct sc_cnstate *sp, int flags);
+static void sccnscrlock(sc_softc_t *sc, struct sc_cnstate *sp);
+static void sccnscrunlock(sc_softc_t *sc, struct sc_cnstate *sp);
+
+static void
+sccnscrlock(sc_softc_t *sc, struct sc_cnstate *sp)
+{
+    SC_VIDEO_LOCK(sc);
+}
+
+static void
+sccnscrunlock(sc_softc_t *sc, struct sc_cnstate *sp)
+{
+    SC_VIDEO_UNLOCK(sc);
+}
 
 static void
 sccnopen(sc_softc_t *sc, struct sc_cnstate *sp, int flags)
@@ -1680,6 +1694,7 @@ sccnopen(sc_softc_t *sc, struct sc_cnsta
 over_keyboard: ;
 
     /* The screen is opened iff locking it succeeds. */
+    sccnscrlock(sc, sp);
     sp->scr_opened = TRUE;
 
     /* The screen switch is optional. */
@@ -1698,6 +1713,7 @@ static void
 sccnclose(sc_softc_t *sc, struct sc_cnstate *sp)
 {
     sp->scr_opened = FALSE;
+    sccnscrunlock(sc, sp);
 
     if (!sp->kbd_opened)
 	return;
@@ -1731,8 +1747,10 @@ sc_cngrab(struct consdev *cp)
 
     sc = sc_console->sc;
     lev = atomic_fetchadd_int(&sc->grab_level, 1);
-    if (lev >= 0 && lev < 2)
+    if (lev >= 0 && lev < 2) {
 	sccnopen(sc, &sc->grab_state[lev], 1 | 2);
+	sccnscrunlock(sc, &sc->grab_state[lev]);
+    }
 }
 
 static void
@@ -1743,14 +1761,17 @@ sc_cnungrab(struct consdev *cp)
 
     sc = sc_console->sc;
     lev = atomic_load_acq_int(&sc->grab_level) - 1;
-    if (lev >= 0 && lev < 2)
+    if (lev >= 0 && lev < 2) {
+	sccnscrlock(sc, &sc->grab_state[lev]);
 	sccnclose(sc, &sc->grab_state[lev]);
+    }
     atomic_add_int(&sc->grab_level, -1);
 }
 
 static void
 sc_cnputc(struct consdev *cd, int c)
 {
+    struct sc_cnstate st;
     u_char buf[1];
     scr_stat *scp = sc_console;
 #ifndef SC_NO_HISTORY
@@ -1762,7 +1783,7 @@ sc_cnputc(struct consdev *cd, int c)
 
     /* assert(sc_console != NULL) */
 
-    SC_VIDEO_LOCK(scp->sc);
+    sccnopen(scp->sc, &st, 0);
 
 #ifndef SC_NO_HISTORY
     if (scp == scp->sc->cur_scp && scp->status & SLKED) {
@@ -1797,7 +1818,7 @@ sc_cnputc(struct consdev *cd, int c)
     s = spltty();	/* block sckbdevent and scrn_timer */
     sccnupdate(scp);
     splx(s);
-    SC_VIDEO_UNLOCK(scp->sc);
+    sccnclose(scp->sc, &st);
 }
 
 static int



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201608291841.u7TIf6mu053342>