svn commit: r316136 - head/sys/dev/syscons

Bruce Evans bde at FreeBSD.org
Wed Mar 29 14:46:27 UTC 2017


Author: bde
Date: Wed Mar 29 14:46:26 2017
New Revision: 316136
URL: https://svnweb.freebsd.org/changeset/base/316136

Log:
  The switch to kernel terminal context needs to update more than the cursor
  position.  Especially the screen size, and potentially everything except
  the input state and attributes.  Do this by changing the cursor position
  setting method to a general syncing method.
  
  Use proper constructors instead of copying to create kernel terminal
  contexts.  We really want clones and not new instances, but there is
  no method for cloning and there is nothing in the active instance that
  needs to be cloned exactly.
  
  Add proper destructors for kernel terminal contexts.  I doubt that the
  destructor code has every been reached, but if it was then it leaked the
  memory of the clones.
  
  Remove freeing of statically allocated memory for the non-kernel terminal
  context for the same terminal as the kernel.  This is in the nearly
  unreachable code.  This used to not happen because delicate context
  swapping made the user context use the dynamic memory and kernel
  context the static memory.  I didn't restore this swapping since it
  would have been unnatural to have all kernel contexts except 1 dynamic.
  
  The constructor for terminal context has bad layering for reasons
  related to the bug.  It has to return static memory early before
  malloc() works.  Callers also can't allocate memory until after the
  first constructor selects an emulator and tells upper layers the size
  of its context.  After that, the cloning hack required the cloning
  code to allocate the memory, but for all other constructors it would
  be better for the terminal layer to allocate and deallocate the
  memory in all cases.
  
  Zero the memory when allocating terminal contexts dynamically.

Modified:
  head/sys/dev/syscons/scterm-teken.c
  head/sys/dev/syscons/syscons.c
  head/sys/dev/syscons/syscons.h

Modified: head/sys/dev/syscons/scterm-teken.c
==============================================================================
--- head/sys/dev/syscons/scterm-teken.c	Wed Mar 29 11:03:08 2017	(r316135)
+++ head/sys/dev/syscons/scterm-teken.c	Wed Mar 29 14:46:26 2017	(r316136)
@@ -62,7 +62,7 @@ static sc_term_default_attr_t	scteken_de
 static sc_term_clear_t		scteken_clear;
 static sc_term_input_t		scteken_input;
 static sc_term_fkeystr_t	scteken_fkeystr;
-static sc_term_set_cursor_t	scteken_set_cursor;
+static sc_term_sync_t		scteken_sync;
 static void			scteken_nop(void);
 
 typedef struct {
@@ -89,7 +89,7 @@ static sc_term_sw_t sc_term_scteken = {
 	(sc_term_notify_t *)scteken_nop,
 	scteken_input,
 	scteken_fkeystr,
-	scteken_set_cursor,
+	scteken_sync,
 };
 
 SCTERM_MODULE(scteken, sc_term_scteken);
@@ -219,7 +219,7 @@ scteken_clear(scr_stat *scp)
 	teken_stat *ts = scp->ts;
 
 	sc_move_cursor(scp, 0, 0);
-	scteken_set_cursor(scp, 0, 0);
+	scteken_sync(scp);
 	sc_vtb_clear(&scp->vtb, scp->sc->scr_map[0x20],
 		     scteken_te_to_sc_attr(teken_get_curattr(&ts->ts_teken))
 		     << 8);
@@ -284,13 +284,16 @@ scteken_fkeystr(scr_stat *scp, int c)
 }
 
 static void
-scteken_set_cursor(scr_stat *scp, int col, int row)
+scteken_sync(scr_stat *scp)
 {
 	teken_stat *ts = scp->ts;
 	teken_pos_t tp;
 
-	tp.tp_col = col;
-	tp.tp_row = row;
+	tp.tp_col = scp->xsize;
+	tp.tp_row = scp->ysize;
+	teken_set_winsize_noreset(&ts->ts_teken, &tp);
+	tp.tp_col = scp->xpos;
+	tp.tp_row = scp->ypos;
 	teken_set_cursor(&ts->ts_teken, &tp);
 }
 

Modified: head/sys/dev/syscons/syscons.c
==============================================================================
--- head/sys/dev/syscons/syscons.c	Wed Mar 29 11:03:08 2017	(r316135)
+++ head/sys/dev/syscons/syscons.c	Wed Mar 29 14:46:26 2017	(r316136)
@@ -567,8 +567,9 @@ sc_attach_unit(int unit, int flags)
 	    /* assert(sc_console->ts != NULL); */
 	    oldts = sc_console->ts;
 	    for (i = 0; i <= mp_maxid; i++) {
-		ts = malloc(sc_console->tsw->te_size, M_DEVBUF, M_WAITOK);
-		bcopy(oldts, ts, sc_console->tsw->te_size);
+		ts = malloc(sc_console->tsw->te_size, M_DEVBUF,
+			    M_WAITOK | M_ZERO);
+		(*sc_console->tsw->te_init)(sc_console, &ts, SC_TE_COLD_INIT);
 		sc_console->ts = ts;
 		(*sc_console->tsw->te_default_attr)(sc_console, sc_kattrtab[i],
 						    SC_KERNEL_CONS_REV_ATTR);
@@ -1705,6 +1706,9 @@ sc_cninit(struct consdev *cp)
 static void
 sc_cnterm(struct consdev *cp)
 {
+    void *ts;
+    int i;
+
     /* we are not the kernel console any more, release everything */
 
     if (sc_console_unit < 0)
@@ -1715,6 +1719,12 @@ sc_cnterm(struct consdev *cp)
     sccnupdate(sc_console);
 #endif
 
+    for (i = 0; i <= mp_maxid; i++) {
+	ts = kernel_console_ts[i];
+	kernel_console_ts[i] = NULL;
+	(*sc_console->tsw->te_term)(sc_console, &ts);
+	free(ts, M_DEVBUF);
+    }
     scterm(sc_console_unit, SC_KERNEL_CONSOLE);
     sc_console_unit = -1;
     sc_console = NULL;
@@ -1977,11 +1987,11 @@ sc_cnputc(struct consdev *cd, int c)
 	ts = kernel_console_ts[PCPU_GET(cpuid)];
 	if (ts != NULL) {
 	    scp->ts = ts;
-	    (*scp->tsw->te_set_cursor)(scp, scp->xpos, scp->ypos);
+	    (*scp->tsw->te_sync)(scp);
 	}
 	sc_puts(scp, buf, 1);
 	scp->ts = oldts;
-	(*scp->tsw->te_set_cursor)(scp, scp->xpos, scp->ypos);
+	(*scp->tsw->te_sync)(scp);
     }
 
     s = spltty();	/* block sckbdevent and scrn_timer */
@@ -3196,7 +3206,7 @@ scinit(int unit, int flags)
 	scp->xpos = col;
 	scp->ypos = row;
 	scp->cursor_pos = scp->cursor_oldpos = row*scp->xsize + col;
-	(*scp->tsw->te_set_cursor)(scp, col, row);
+	(*scp->tsw->te_sync)(scp);
 
 	/* Sync BIOS cursor shape to s/w (sc only). */
 	if (bios_value.cursor_end < scp->font_size)
@@ -3312,12 +3322,11 @@ scterm(int unit, int flags)
     scp = sc_get_stat(sc->dev[0]);
     if (scp->tsw)
 	(*scp->tsw->te_term)(scp, &scp->ts);
-    if (scp->ts != NULL)
-	free(scp->ts, M_DEVBUF);
     mtx_destroy(&sc->video_mtx);
 
     /* clear the structure */
     if (!(flags & SC_KERNEL_CONSOLE)) {
+	free(scp->ts, M_DEVBUF);
 	/* XXX: We need delete_dev() for this */
 	free(sc->dev, M_DEVBUF);
 #if 0

Modified: head/sys/dev/syscons/syscons.h
==============================================================================
--- head/sys/dev/syscons/syscons.h	Wed Mar 29 11:03:08 2017	(r316135)
+++ head/sys/dev/syscons/syscons.h	Wed Mar 29 14:46:26 2017	(r316136)
@@ -394,7 +394,7 @@ typedef void	sc_term_notify_t(scr_stat *
 #define SC_TE_NOTIFY_VTSWITCH_OUT	1
 typedef int	sc_term_input_t(scr_stat *scp, int c, struct tty *tp);
 typedef const char *sc_term_fkeystr_t(scr_stat *scp, int c);
-typedef void sc_term_set_cursor_t(scr_stat *scp, int col, int row);
+typedef void sc_term_sync_t(scr_stat *scp);
 
 typedef struct sc_term_sw {
 	LIST_ENTRY(sc_term_sw)	link;
@@ -413,7 +413,7 @@ typedef struct sc_term_sw {
 	sc_term_notify_t	*te_notify;
 	sc_term_input_t		*te_input;
 	sc_term_fkeystr_t	*te_fkeystr;
-	sc_term_set_cursor_t	*te_set_cursor;
+	sc_term_sync_t		*te_sync;
 } sc_term_sw_t;
 
 #define SCTERM_MODULE(name, sw)					\


More information about the svn-src-head mailing list