linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v7 0/3] console: Add persistent scrollback buffers for all VGA consoles
@ 2016-12-04 10:53 Manuel Schölling
  2016-12-04 10:53 ` [PATCH v7 1/3] console: Move scrollback data into its own struct Manuel Schölling
                   ` (5 more replies)
  0 siblings, 6 replies; 62+ messages in thread
From: Manuel Schölling @ 2016-12-04 10:53 UTC (permalink / raw)
  To: plagnioj, tomi.valkeinen
  Cc: manuel.schoelling, jslaby, gregkh, andrey_utkin, kilobyte,
	linux-fbdev, linux-kernel

Reviewed-by: Andrey Utkin <andrey_utkin@fastmail.com>
Tested-by: Andrey Utkin <andrey_utkin@fastmail.com>
Tested-by: Adam Borowski <kilobyte@angband.pl>

--
Changes in v7:
  - Add new callback to consw struct for flushing video console driver's
    scrollback buffer. Fixes issues with escape sequence '\e[3J' reported
    by Adam Borowski (kilobyte@angband.pl).
  - Fix style issues
Changes in v6:
  - Change of check if feature is enabled in 
    vgacon_scrollback_switch()
Changes in v5:
  - Clearify documentation
  - Skip superfluous array initialization
  - Disable scrollback if buffer allocation fails
  - Refactor vgacon_switch_scrollback()
  - Rename vgacon_switch_scrollback() to vgacon_scrollback_switch()
  - Add check for fg_console in vgacon_scrollback_update
Changes in v4.1:
  - Fix compiler error
Changes in v4:
  - Rename from VGACON_SOFT_SCROLLBACK_FOR_EACH_CONSOLE to
    VGACON_SOFT_SCROLLBACK_PERSISTENT
  - Split into two patches
  - Rework documentation
  - Remove cosmetic changes in comments (postponed)
Changes in v3:
  - Add config option for this feature
  - Fallback to old scrollback buffer if kcalloc() fails
  - Remove ioctl() call again and add documentation about existing
    escape sequence to flush the scrollback buffer
Changes in v2:
  - Add ioctl() call to flush scrollback buffer
  - (Patch v2 was not labeled as such, sorry)

Manuel Schölling (3):
  console: Move scrollback data into its own struct
  console: Add callback to flush scrollback buffer to consw struct
  console: Add persistent scrollback buffers for all VGA consoles

 drivers/tty/vt/vt.c            |   9 +++
 drivers/video/console/Kconfig  |  25 ++++++-
 drivers/video/console/vgacon.c | 165 ++++++++++++++++++++++++++++-------------
 include/linux/console.h        |   4 +
 4 files changed, 148 insertions(+), 55 deletions(-)

-- 
2.1.4

^ permalink raw reply	[flat|nested] 62+ messages in thread

* [PATCH v7 1/3] console: Move scrollback data into its own struct
  2016-12-04 10:53 [PATCH v7 0/3] console: Add persistent scrollback buffers for all VGA consoles Manuel Schölling
@ 2016-12-04 10:53 ` Manuel Schölling
  2016-12-04 10:53 ` [PATCH v7 2/3] console: Add callback to flush scrollback buffer to consw struct Manuel Schölling
                   ` (4 subsequent siblings)
  5 siblings, 0 replies; 62+ messages in thread
From: Manuel Schölling @ 2016-12-04 10:53 UTC (permalink / raw)
  To: plagnioj, tomi.valkeinen
  Cc: manuel.schoelling, jslaby, gregkh, andrey_utkin, kilobyte,
	linux-fbdev, linux-kernel

This refactoring is in preparation for persistent scrollback
support for VGA console.

Signed-off-by: Manuel Schölling <manuel.schoelling@gmx.de>
Reviewed-by: Andrey Utkin <andrey_utkin@fastmail.com>
Tested-by: Andrey Utkin <andrey_utkin@fastmail.com>
Tested-by: Adam Borowski <kilobyte@angband.pl>

---
 drivers/video/console/vgacon.c | 91 ++++++++++++++++++++++--------------------
 1 file changed, 47 insertions(+), 44 deletions(-)

diff --git a/drivers/video/console/vgacon.c b/drivers/video/console/vgacon.c
index c22a562..48b9764 100644
--- a/drivers/video/console/vgacon.c
+++ b/drivers/video/console/vgacon.c
@@ -162,31 +162,34 @@ static inline void vga_set_mem_top(struct vc_data *c)
 
 #ifdef CONFIG_VGACON_SOFT_SCROLLBACK
 /* software scrollback */
-static void *vgacon_scrollback;
-static int vgacon_scrollback_tail;
-static int vgacon_scrollback_size;
-static int vgacon_scrollback_rows;
-static int vgacon_scrollback_cnt;
-static int vgacon_scrollback_cur;
-static int vgacon_scrollback_save;
-static int vgacon_scrollback_restore;
+static struct vgacon_scrollback_info {
+	void *data;
+	int tail;
+	int size;
+	int rows;
+	int cnt;
+	int cur;
+	int save;
+	int restore;
+} vgacon_scrollback;
 
 static void vgacon_scrollback_init(int pitch)
 {
 	int rows = CONFIG_VGACON_SOFT_SCROLLBACK_SIZE * 1024/pitch;
 
-	if (vgacon_scrollback) {
-		vgacon_scrollback_cnt  = 0;
-		vgacon_scrollback_tail = 0;
-		vgacon_scrollback_cur  = 0;
-		vgacon_scrollback_rows = rows - 1;
-		vgacon_scrollback_size = rows * pitch;
+	if (vgacon_scrollback.data) {
+		vgacon_scrollback.cnt  = 0;
+		vgacon_scrollback.tail = 0;
+		vgacon_scrollback.cur  = 0;
+		vgacon_scrollback.rows = rows - 1;
+		vgacon_scrollback.size = rows * pitch;
 	}
 }
 
 static void vgacon_scrollback_startup(void)
 {
-	vgacon_scrollback = kcalloc(CONFIG_VGACON_SOFT_SCROLLBACK_SIZE, 1024, GFP_NOWAIT);
+	vgacon_scrollback.data = kcalloc(CONFIG_VGACON_SOFT_SCROLLBACK_SIZE,
+		1024, GFP_NOWAIT);
 	vgacon_scrollback_init(vga_video_num_columns * 2);
 }
 
@@ -194,38 +197,38 @@ static void vgacon_scrollback_update(struct vc_data *c, int t, int count)
 {
 	void *p;
 
-	if (!vgacon_scrollback_size || c->vc_num != fg_console)
+	if (!vgacon_scrollback.size || c->vc_num != fg_console)
 		return;
 
 	p = (void *) (c->vc_origin + t * c->vc_size_row);
 
 	while (count--) {
-		scr_memcpyw(vgacon_scrollback + vgacon_scrollback_tail,
+		scr_memcpyw(vgacon_scrollback.data + vgacon_scrollback.tail,
 			    p, c->vc_size_row);
-		vgacon_scrollback_cnt++;
+		vgacon_scrollback.cnt++;
 		p += c->vc_size_row;
-		vgacon_scrollback_tail += c->vc_size_row;
+		vgacon_scrollback.tail += c->vc_size_row;
 
-		if (vgacon_scrollback_tail >= vgacon_scrollback_size)
-			vgacon_scrollback_tail = 0;
+		if (vgacon_scrollback.tail >= vgacon_scrollback.size)
+			vgacon_scrollback.tail = 0;
 
-		if (vgacon_scrollback_cnt > vgacon_scrollback_rows)
-			vgacon_scrollback_cnt = vgacon_scrollback_rows;
+		if (vgacon_scrollback.cnt > vgacon_scrollback.rows)
+			vgacon_scrollback.cnt = vgacon_scrollback.rows;
 
-		vgacon_scrollback_cur = vgacon_scrollback_cnt;
+		vgacon_scrollback.cur = vgacon_scrollback.cnt;
 	}
 }
 
 static void vgacon_restore_screen(struct vc_data *c)
 {
-	vgacon_scrollback_save = 0;
+	vgacon_scrollback.save = 0;
 
-	if (!vga_is_gfx && !vgacon_scrollback_restore) {
+	if (!vga_is_gfx && !vgacon_scrollback.restore) {
 		scr_memcpyw((u16 *) c->vc_origin, (u16 *) c->vc_screenbuf,
 			    c->vc_screenbuf_size > vga_vram_size ?
 			    vga_vram_size : c->vc_screenbuf_size);
-		vgacon_scrollback_restore = 1;
-		vgacon_scrollback_cur = vgacon_scrollback_cnt;
+		vgacon_scrollback.restore = 1;
+		vgacon_scrollback.cur = vgacon_scrollback.cnt;
 	}
 }
 
@@ -239,41 +242,41 @@ static void vgacon_scrolldelta(struct vc_data *c, int lines)
 		return;
 	}
 
-	if (!vgacon_scrollback)
+	if (!vgacon_scrollback.data)
 		return;
 
-	if (!vgacon_scrollback_save) {
+	if (!vgacon_scrollback.save) {
 		vgacon_cursor(c, CM_ERASE);
 		vgacon_save_screen(c);
-		vgacon_scrollback_save = 1;
+		vgacon_scrollback.save = 1;
 	}
 
-	vgacon_scrollback_restore = 0;
-	start = vgacon_scrollback_cur + lines;
+	vgacon_scrollback.restore = 0;
+	start = vgacon_scrollback.cur + lines;
 	end = start + abs(lines);
 
 	if (start < 0)
 		start = 0;
 
-	if (start > vgacon_scrollback_cnt)
-		start = vgacon_scrollback_cnt;
+	if (start > vgacon_scrollback.cnt)
+		start = vgacon_scrollback.cnt;
 
 	if (end < 0)
 		end = 0;
 
-	if (end > vgacon_scrollback_cnt)
-		end = vgacon_scrollback_cnt;
+	if (end > vgacon_scrollback.cnt)
+		end = vgacon_scrollback.cnt;
 
-	vgacon_scrollback_cur = start;
+	vgacon_scrollback.cur = start;
 	count = end - start;
-	soff = vgacon_scrollback_tail - ((vgacon_scrollback_cnt - end) *
+	soff = vgacon_scrollback.tail - ((vgacon_scrollback.cnt - end) *
 					 c->vc_size_row);
 	soff -= count * c->vc_size_row;
 
 	if (soff < 0)
-		soff += vgacon_scrollback_size;
+		soff += vgacon_scrollback.size;
 
-	count = vgacon_scrollback_cnt - start;
+	count = vgacon_scrollback.cnt - start;
 
 	if (count > c->vc_rows)
 		count = c->vc_rows;
@@ -287,13 +290,13 @@ static void vgacon_scrolldelta(struct vc_data *c, int lines)
 
 		count *= c->vc_size_row;
 		/* how much memory to end of buffer left? */
-		copysize = min(count, vgacon_scrollback_size - soff);
-		scr_memcpyw(d, vgacon_scrollback + soff, copysize);
+		copysize = min(count, vgacon_scrollback.size - soff);
+		scr_memcpyw(d, vgacon_scrollback.data + soff, copysize);
 		d += copysize;
 		count -= copysize;
 
 		if (count) {
-			scr_memcpyw(d, vgacon_scrollback, count);
+			scr_memcpyw(d, vgacon_scrollback.data, count);
 			d += count;
 		}
 
-- 
2.1.4

^ permalink raw reply	[flat|nested] 62+ messages in thread

* [PATCH v7 2/3] console: Add callback to flush scrollback buffer to consw struct
  2016-12-04 10:53 [PATCH v7 0/3] console: Add persistent scrollback buffers for all VGA consoles Manuel Schölling
  2016-12-04 10:53 ` [PATCH v7 1/3] console: Move scrollback data into its own struct Manuel Schölling
@ 2016-12-04 10:53 ` Manuel Schölling
  2016-12-04 10:53 ` [PATCH v7 3/3] console: Add persistent scrollback buffers for all VGA consoles Manuel Schölling
                   ` (3 subsequent siblings)
  5 siblings, 0 replies; 62+ messages in thread
From: Manuel Schölling @ 2016-12-04 10:53 UTC (permalink / raw)
  To: plagnioj, tomi.valkeinen
  Cc: manuel.schoelling, jslaby, gregkh, andrey_utkin, kilobyte,
	linux-fbdev, linux-kernel

This new callback is in preparation for persistent scrollback buffer
support for VGA consoles.
With a single scrollback buffer for all consoles, we could flush the
buffer just by invocating consw->con_switch(). But when each VGA console
has its own scrollback buffer, we need a new callback to tell the
video console driver which buffer to flush.

Signed-off-by: Manuel Schölling <manuel.schoelling@gmx.de>
Reviewed-by: Andrey Utkin <andrey_utkin@fastmail.com>
Tested-by: Andrey Utkin <andrey_utkin@fastmail.com>
Tested-by: Adam Borowski <kilobyte@angband.pl>

---
 drivers/tty/vt/vt.c            |  9 +++++++++
 drivers/video/console/vgacon.c | 24 +++++++++++++++++++++++-
 include/linux/console.h        |  4 ++++
 3 files changed, 36 insertions(+), 1 deletion(-)

diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c
index 4c10a9d..9d3ce50 100644
--- a/drivers/tty/vt/vt.c
+++ b/drivers/tty/vt/vt.c
@@ -625,6 +625,14 @@ static void save_screen(struct vc_data *vc)
 		vc->vc_sw->con_save_screen(vc);
 }
 
+static void flush_scrollback(struct vc_data *vc)
+{
+	WARN_CONSOLE_UNLOCKED();
+
+	if (vc->vc_sw->con_flush_scrollback)
+		vc->vc_sw->con_flush_scrollback(vc);
+}
+
 /*
  *	Redrawing of screen
  */
@@ -1171,6 +1179,7 @@ static void csi_J(struct vc_data *vc, int vpar)
 		case 3: /* erase scroll-back buffer (and whole display) */
 			scr_memsetw(vc->vc_screenbuf, vc->vc_video_erase_char,
 				    vc->vc_screenbuf_size);
+			flush_scrollback(vc);
 			set_origin(vc);
 			if (con_is_visible(vc))
 				update_screen(vc);
diff --git a/drivers/video/console/vgacon.c b/drivers/video/console/vgacon.c
index 48b9764..9a7c2bb 100644
--- a/drivers/video/console/vgacon.c
+++ b/drivers/video/console/vgacon.c
@@ -173,6 +173,16 @@ static struct vgacon_scrollback_info {
 	int restore;
 } vgacon_scrollback;
 
+static void vgacon_scrollback_reset(size_t reset_size)
+{
+	if (vgacon_scrollback.data && reset_size > 0)
+		memset(vgacon_scrollback.data, 0, reset_size);
+
+	vgacon_scrollback.cnt  = 0;
+	vgacon_scrollback.tail = 0;
+	vgacon_scrollback.cur  = 0;
+}
+
 static void vgacon_scrollback_init(int pitch)
 {
 	int rows = CONFIG_VGACON_SOFT_SCROLLBACK_SIZE * 1024/pitch;
@@ -305,6 +315,14 @@ static void vgacon_scrolldelta(struct vc_data *c, int lines)
 	} else
 		vgacon_cursor(c, CM_MOVE);
 }
+
+static void vgacon_flush_scrollback(struct vc_data *c)
+{
+	size_t size = CONFIG_VGACON_SOFT_SCROLLBACK_SIZE * 1024;
+
+	if (c->vc_num == fg_console)
+		vgacon_scrollback_reset(size);
+}
 #else
 #define vgacon_scrollback_startup(...) do { } while (0)
 #define vgacon_scrollback_init(...)    do { } while (0)
@@ -322,6 +340,10 @@ static void vgacon_scrolldelta(struct vc_data *c, int lines)
 			vga_vram_size);
 	vga_set_mem_top(c);
 }
+
+static void vgacon_flush_scrollback(struct vc_data *c)
+{
+}
 #endif /* CONFIG_VGACON_SOFT_SCROLLBACK */
 
 static const char *vgacon_startup(void)
@@ -1329,7 +1351,6 @@ static bool vgacon_scroll(struct vc_data *c, unsigned int t, unsigned int b,
 	return true;
 }
 
-
 /*
  *  The console `switch' structure for the VGA based console
  */
@@ -1362,6 +1383,7 @@ const struct consw vga_con = {
 	.con_save_screen = vgacon_save_screen,
 	.con_build_attr = vgacon_build_attr,
 	.con_invert_region = vgacon_invert_region,
+	.con_flush_scrollback = vgacon_flush_scrollback,
 };
 EXPORT_SYMBOL(vga_con);
 
diff --git a/include/linux/console.h b/include/linux/console.h
index 9c26c66..5949d18 100644
--- a/include/linux/console.h
+++ b/include/linux/console.h
@@ -73,6 +73,10 @@ struct consw {
 	u16    *(*con_screen_pos)(struct vc_data *, int);
 	unsigned long (*con_getxy)(struct vc_data *, unsigned long, int *, int *);
 	/*
+	 * Flush the video console driver's scrollback buffer
+	 */
+	void	(*con_flush_scrollback)(struct vc_data *);
+	/*
 	 * Prepare the console for the debugger.  This includes, but is not
 	 * limited to, unblanking the console, loading an appropriate
 	 * palette, and allowing debugger generated output.
-- 
2.1.4

^ permalink raw reply	[flat|nested] 62+ messages in thread

* [PATCH v7 3/3] console: Add persistent scrollback buffers for all VGA consoles
  2016-12-04 10:53 [PATCH v7 0/3] console: Add persistent scrollback buffers for all VGA consoles Manuel Schölling
  2016-12-04 10:53 ` [PATCH v7 1/3] console: Move scrollback data into its own struct Manuel Schölling
  2016-12-04 10:53 ` [PATCH v7 2/3] console: Add callback to flush scrollback buffer to consw struct Manuel Schölling
@ 2016-12-04 10:53 ` Manuel Schölling
  2016-12-06 10:02 ` [PATCH v7 0/3] " Greg KH
                   ` (2 subsequent siblings)
  5 siblings, 0 replies; 62+ messages in thread
From: Manuel Schölling @ 2016-12-04 10:53 UTC (permalink / raw)
  To: plagnioj, tomi.valkeinen
  Cc: manuel.schoelling, jslaby, gregkh, andrey_utkin, kilobyte,
	linux-fbdev, linux-kernel

Add a scrollback buffers for each VGA console. The benefit is that
the scrollback history is not flushed when switching between consoles
but is persistent.
The buffers are allocated on demand when a new console is opened.

This breaks tools like clear_console that rely on flushing the
scrollback history by switching back and forth between consoles
which is why this feature is disabled by default.
Use the escape sequence \e[3J instead for flushing the buffer.

Signed-off-by: Manuel Schölling <manuel.schoelling@gmx.de>
Reviewed-by: Andrey Utkin <andrey_utkin@fastmail.com>
Tested-by: Andrey Utkin <andrey_utkin@fastmail.com>
Tested-by: Adam Borowski <kilobyte@angband.pl>

---
 drivers/video/console/Kconfig  |  25 +++++++-
 drivers/video/console/vgacon.c | 142 ++++++++++++++++++++++++++---------------
 2 files changed, 111 insertions(+), 56 deletions(-)

diff --git a/drivers/video/console/Kconfig b/drivers/video/console/Kconfig
index 38da6e2..c5742d2 100644
--- a/drivers/video/console/Kconfig
+++ b/drivers/video/console/Kconfig
@@ -43,9 +43,28 @@ config VGACON_SOFT_SCROLLBACK_SIZE
        range 1 1024
        default "64"
        help
-         Enter the amount of System RAM to allocate for the scrollback
-	 buffer.  Each 64KB will give you approximately 16 80x25
-	 screenfuls of scrollback buffer
+	  Enter the amount of System RAM to allocate for scrollback
+	  buffers of VGA consoles. Each 64KB will give you approximately
+	  16 80x25 screenfuls of scrollback buffer.
+
+config VGACON_SOFT_SCROLLBACK_PERSISTENT
+	bool "Persistent Scrollback History for each console"
+	depends on VGACON_SOFT_SCROLLBACK
+	default n
+	help
+	  Say Y here if the scrollback history should persist when switching
+	  between consoles. Otherwise, the scrollback history will be flushed
+	  each time the console is switched.
+
+	  This feature might break your tool of choice to flush the scrollback
+	  buffer, e.g. clear(1) will work fine but Debian's clear_console(1)
+	  will be broken, which might cause security issues.
+	  You can use the escape sequence \e[3J instead if this feature is
+	  activated.
+
+	  Note that a buffer of VGACON_SOFT_SCROLLBACK_SIZE is taken for each
+	  created tty device.
+	  So if you use a RAM-constrained system, say N here.
 
 config MDA_CONSOLE
 	depends on !M68K && !PARISC && ISA
diff --git a/drivers/video/console/vgacon.c b/drivers/video/console/vgacon.c
index 9a7c2bb..ca23d22 100644
--- a/drivers/video/console/vgacon.c
+++ b/drivers/video/console/vgacon.c
@@ -162,7 +162,7 @@ static inline void vga_set_mem_top(struct vc_data *c)
 
 #ifdef CONFIG_VGACON_SOFT_SCROLLBACK
 /* software scrollback */
-static struct vgacon_scrollback_info {
+struct vgacon_scrollback_info {
 	void *data;
 	int tail;
 	int size;
@@ -171,74 +171,110 @@ static struct vgacon_scrollback_info {
 	int cur;
 	int save;
 	int restore;
-} vgacon_scrollback;
+};
+
+static struct vgacon_scrollback_info *vgacon_scrollback_cur;
+#ifdef CONFIG_VGACON_SOFT_SCROLLBACK_PERSISTENT
+static struct vgacon_scrollback_info vgacon_scrollbacks[MAX_NR_CONSOLES];
+#else
+static struct vgacon_scrollback_info vgacon_scrollbacks[1];
+#endif
 
-static void vgacon_scrollback_reset(size_t reset_size)
+static void vgacon_scrollback_reset(int vc_num, size_t reset_size)
 {
-	if (vgacon_scrollback.data && reset_size > 0)
-		memset(vgacon_scrollback.data, 0, reset_size);
+	struct vgacon_scrollback_info *scrollback = &vgacon_scrollbacks[vc_num];
+
+	if (scrollback->data && reset_size > 0)
+		memset(scrollback->data, 0, reset_size);
 
-	vgacon_scrollback.cnt  = 0;
-	vgacon_scrollback.tail = 0;
-	vgacon_scrollback.cur  = 0;
+	scrollback->cnt  = 0;
+	scrollback->tail = 0;
+	scrollback->cur  = 0;
 }
 
-static void vgacon_scrollback_init(int pitch)
+static void vgacon_scrollback_init(int vc_num)
 {
-	int rows = CONFIG_VGACON_SOFT_SCROLLBACK_SIZE * 1024/pitch;
-
-	if (vgacon_scrollback.data) {
-		vgacon_scrollback.cnt  = 0;
-		vgacon_scrollback.tail = 0;
-		vgacon_scrollback.cur  = 0;
-		vgacon_scrollback.rows = rows - 1;
-		vgacon_scrollback.size = rows * pitch;
+	int pitch = vga_video_num_columns * 2;
+	size_t size = CONFIG_VGACON_SOFT_SCROLLBACK_SIZE * 1024;
+	int rows = size / pitch;
+	void *data;
+
+	data = kmalloc_array(CONFIG_VGACON_SOFT_SCROLLBACK_SIZE, 1024,
+			     GFP_NOWAIT);
+
+	vgacon_scrollbacks[vc_num].data = data;
+	vgacon_scrollback_cur = &vgacon_scrollbacks[vc_num];
+
+	vgacon_scrollback_cur->rows = rows - 1;
+	vgacon_scrollback_cur->size = rows * pitch;
+
+	vgacon_scrollback_reset(vc_num, size);
+}
+
+static void vgacon_scrollback_switch(int vc_num)
+{
+#ifndef CONFIG_VGACON_SOFT_SCROLLBACK_PERSISTENT
+	vc_num = 0;
+#endif
+
+	if (!vgacon_scrollbacks[vc_num].data) {
+		vgacon_scrollback_init(vc_num);
+	} else {
+#ifdef CONFIG_VGACON_SOFT_SCROLLBACK_PERSISTENT
+		vgacon_scrollback_cur = &vgacon_scrollbacks[vc_num];
+#else
+		size_t size = CONFIG_VGACON_SOFT_SCROLLBACK_SIZE * 1024;
+
+		vgacon_scrollback_reset(vc_num, size);
+#endif
 	}
 }
 
 static void vgacon_scrollback_startup(void)
 {
-	vgacon_scrollback.data = kcalloc(CONFIG_VGACON_SOFT_SCROLLBACK_SIZE,
-		1024, GFP_NOWAIT);
-	vgacon_scrollback_init(vga_video_num_columns * 2);
+	vgacon_scrollback_cur = &vgacon_scrollbacks[0];
+	vgacon_scrollback_init(0);
 }
 
 static void vgacon_scrollback_update(struct vc_data *c, int t, int count)
 {
 	void *p;
 
-	if (!vgacon_scrollback.size || c->vc_num != fg_console)
+	if (!vgacon_scrollback_cur->data || !vgacon_scrollback_cur->size ||
+	    c->vc_num != fg_console)
 		return;
 
 	p = (void *) (c->vc_origin + t * c->vc_size_row);
 
 	while (count--) {
-		scr_memcpyw(vgacon_scrollback.data + vgacon_scrollback.tail,
+		scr_memcpyw(vgacon_scrollback_cur->data +
+			    vgacon_scrollback_cur->tail,
 			    p, c->vc_size_row);
-		vgacon_scrollback.cnt++;
+
+		vgacon_scrollback_cur->cnt++;
 		p += c->vc_size_row;
-		vgacon_scrollback.tail += c->vc_size_row;
+		vgacon_scrollback_cur->tail += c->vc_size_row;
 
-		if (vgacon_scrollback.tail >= vgacon_scrollback.size)
-			vgacon_scrollback.tail = 0;
+		if (vgacon_scrollback_cur->tail >= vgacon_scrollback_cur->size)
+			vgacon_scrollback_cur->tail = 0;
 
-		if (vgacon_scrollback.cnt > vgacon_scrollback.rows)
-			vgacon_scrollback.cnt = vgacon_scrollback.rows;
+		if (vgacon_scrollback_cur->cnt > vgacon_scrollback_cur->rows)
+			vgacon_scrollback_cur->cnt = vgacon_scrollback_cur->rows;
 
-		vgacon_scrollback.cur = vgacon_scrollback.cnt;
+		vgacon_scrollback_cur->cur = vgacon_scrollback_cur->cnt;
 	}
 }
 
 static void vgacon_restore_screen(struct vc_data *c)
 {
-	vgacon_scrollback.save = 0;
+	vgacon_scrollback_cur->save = 0;
 
-	if (!vga_is_gfx && !vgacon_scrollback.restore) {
+	if (!vga_is_gfx && !vgacon_scrollback_cur->restore) {
 		scr_memcpyw((u16 *) c->vc_origin, (u16 *) c->vc_screenbuf,
 			    c->vc_screenbuf_size > vga_vram_size ?
 			    vga_vram_size : c->vc_screenbuf_size);
-		vgacon_scrollback.restore = 1;
-		vgacon_scrollback.cur = vgacon_scrollback.cnt;
+		vgacon_scrollback_cur->restore = 1;
+		vgacon_scrollback_cur->cur = vgacon_scrollback_cur->cnt;
 	}
 }
 
@@ -252,41 +288,41 @@ static void vgacon_scrolldelta(struct vc_data *c, int lines)
 		return;
 	}
 
-	if (!vgacon_scrollback.data)
+	if (!vgacon_scrollback_cur->data)
 		return;
 
-	if (!vgacon_scrollback.save) {
+	if (!vgacon_scrollback_cur->save) {
 		vgacon_cursor(c, CM_ERASE);
 		vgacon_save_screen(c);
-		vgacon_scrollback.save = 1;
+		vgacon_scrollback_cur->save = 1;
 	}
 
-	vgacon_scrollback.restore = 0;
-	start = vgacon_scrollback.cur + lines;
+	vgacon_scrollback_cur->restore = 0;
+	start = vgacon_scrollback_cur->cur + lines;
 	end = start + abs(lines);
 
 	if (start < 0)
 		start = 0;
 
-	if (start > vgacon_scrollback.cnt)
-		start = vgacon_scrollback.cnt;
+	if (start > vgacon_scrollback_cur->cnt)
+		start = vgacon_scrollback_cur->cnt;
 
 	if (end < 0)
 		end = 0;
 
-	if (end > vgacon_scrollback.cnt)
-		end = vgacon_scrollback.cnt;
+	if (end > vgacon_scrollback_cur->cnt)
+		end = vgacon_scrollback_cur->cnt;
 
-	vgacon_scrollback.cur = start;
+	vgacon_scrollback_cur->cur = start;
 	count = end - start;
-	soff = vgacon_scrollback.tail - ((vgacon_scrollback.cnt - end) *
-					 c->vc_size_row);
+	soff = vgacon_scrollback_cur->tail -
+		((vgacon_scrollback_cur->cnt - end) * c->vc_size_row);
 	soff -= count * c->vc_size_row;
 
 	if (soff < 0)
-		soff += vgacon_scrollback.size;
+		soff += vgacon_scrollback_cur->size;
 
-	count = vgacon_scrollback.cnt - start;
+	count = vgacon_scrollback_cur->cnt - start;
 
 	if (count > c->vc_rows)
 		count = c->vc_rows;
@@ -300,13 +336,13 @@ static void vgacon_scrolldelta(struct vc_data *c, int lines)
 
 		count *= c->vc_size_row;
 		/* how much memory to end of buffer left? */
-		copysize = min(count, vgacon_scrollback.size - soff);
-		scr_memcpyw(d, vgacon_scrollback.data + soff, copysize);
+		copysize = min(count, vgacon_scrollback_cur->size - soff);
+		scr_memcpyw(d, vgacon_scrollback_cur->data + soff, copysize);
 		d += copysize;
 		count -= copysize;
 
 		if (count) {
-			scr_memcpyw(d, vgacon_scrollback.data, count);
+			scr_memcpyw(d, vgacon_scrollback_cur->data, count);
 			d += count;
 		}
 
@@ -320,13 +356,13 @@ static void vgacon_flush_scrollback(struct vc_data *c)
 {
 	size_t size = CONFIG_VGACON_SOFT_SCROLLBACK_SIZE * 1024;
 
-	if (c->vc_num == fg_console)
-		vgacon_scrollback_reset(size);
+	vgacon_scrollback_reset(c->vc_num, size);
 }
 #else
 #define vgacon_scrollback_startup(...) do { } while (0)
 #define vgacon_scrollback_init(...)    do { } while (0)
 #define vgacon_scrollback_update(...)  do { } while (0)
+#define vgacon_scrollback_switch(...)  do { } while (0)
 
 static void vgacon_restore_screen(struct vc_data *c)
 {
@@ -805,7 +841,7 @@ static int vgacon_switch(struct vc_data *c)
 			vgacon_doresize(c, c->vc_cols, c->vc_rows);
 	}
 
-	vgacon_scrollback_init(c->vc_size_row);
+	vgacon_scrollback_switch(c->vc_num);
 	return 0;		/* Redrawing not needed */
 }
 
-- 
2.1.4

^ permalink raw reply	[flat|nested] 62+ messages in thread

* Re: [PATCH v7 0/3] console: Add persistent scrollback buffers for all VGA consoles
  2016-12-04 10:53 [PATCH v7 0/3] console: Add persistent scrollback buffers for all VGA consoles Manuel Schölling
                   ` (2 preceding siblings ...)
  2016-12-04 10:53 ` [PATCH v7 3/3] console: Add persistent scrollback buffers for all VGA consoles Manuel Schölling
@ 2016-12-06 10:02 ` Greg KH
  2016-12-06 16:32   ` Manuel Schölling
  2016-12-21 16:37 ` [PATCH RESEND " Manuel Schölling
  2017-01-02 14:27 ` [PATCH RESEND v7 0/3] console: Add persistent scrollback buffers for all VGA consoles Manuel Schölling
  5 siblings, 1 reply; 62+ messages in thread
From: Greg KH @ 2016-12-06 10:02 UTC (permalink / raw)
  To: Manuel Schölling
  Cc: plagnioj, tomi.valkeinen, jslaby, andrey_utkin, kilobyte,
	linux-fbdev, linux-kernel

On Sun, Dec 04, 2016 at 11:53:53AM +0100, Manuel Schölling wrote:
> Reviewed-by: Andrey Utkin <andrey_utkin@fastmail.com>
> Tested-by: Andrey Utkin <andrey_utkin@fastmail.com>
> Tested-by: Adam Borowski <kilobyte@angband.pl>
> 
> --
> Changes in v7:
>   - Add new callback to consw struct for flushing video console driver's
>     scrollback buffer. Fixes issues with escape sequence '\e[3J' reported
>     by Adam Borowski (kilobyte@angband.pl).
>   - Fix style issues

But this is now v8, right?  I see two v7 patch series in my inbox :(

confused,

greg k-h

^ permalink raw reply	[flat|nested] 62+ messages in thread

* Re: [PATCH v7 0/3] console: Add persistent scrollback buffers for all VGA consoles
  2016-12-06 10:02 ` [PATCH v7 0/3] " Greg KH
@ 2016-12-06 16:32   ` Manuel Schölling
  0 siblings, 0 replies; 62+ messages in thread
From: Manuel Schölling @ 2016-12-06 16:32 UTC (permalink / raw)
  To: Greg KH
  Cc: plagnioj, tomi.valkeinen, jslaby, andrey_utkin, kilobyte,
	linux-fbdev, linux-kernel

Hi Greg,

On Di, 2016-12-06 at 11:02 +0100, Greg KH wrote:
> On Sun, Dec 04, 2016 at 11:53:53AM +0100, Manuel Schölling wrote:
> > Reviewed-by: Andrey Utkin <andrey_utkin@fastmail.com>
> > Tested-by: Andrey Utkin <andrey_utkin@fastmail.com>
> > Tested-by: Adam Borowski <kilobyte@angband.pl>
> > 
> > --
> > Changes in v7:
> >   - Add new callback to consw struct for flushing video console driver's
> >     scrollback buffer. Fixes issues with escape sequence '\e[3J' reported
> >     by Adam Borowski (kilobyte@angband.pl).
> >   - Fix style issues
> 
> But this is now v8, right?  I see two v7 patch series in my inbox :(
> 
> confused,
Sorry for causing confusion. I wasn't sure about the workflow so asked
on #kernelnewbies a few days ago but apparently I misunderstood the
advice I got there:

This is just the same patch (v7) as I sent before, but I added the
Tested-By/Reviewed-By tags.

^ permalink raw reply	[flat|nested] 62+ messages in thread

* [PATCH RESEND v7 0/3] console: Add persistent scrollback buffers for all VGA consoles
  2016-12-04 10:53 [PATCH v7 0/3] console: Add persistent scrollback buffers for all VGA consoles Manuel Schölling
                   ` (3 preceding siblings ...)
  2016-12-06 10:02 ` [PATCH v7 0/3] " Greg KH
@ 2016-12-21 16:37 ` Manuel Schölling
  2016-12-21 16:37   ` [PATCH RESEND v7 1/3] console: Move scrollback data into its own struct Manuel Schölling
                     ` (3 more replies)
  2017-01-02 14:27 ` [PATCH RESEND v7 0/3] console: Add persistent scrollback buffers for all VGA consoles Manuel Schölling
  5 siblings, 4 replies; 62+ messages in thread
From: Manuel Schölling @ 2016-12-21 16:37 UTC (permalink / raw)
  To: plagnioj, tomi.valkeinen
  Cc: manuel.schoelling, jslaby, gregkh, andrey_utkin, kilobyte,
	linux-fbdev, linux-kernel

Reviewed-by: Andrey Utkin <andrey_utkin@fastmail.com>
Tested-by: Andrey Utkin <andrey_utkin@fastmail.com>
Tested-by: Adam Borowski <kilobyte@angband.pl>

--
Changes in v7:
  - Add new callback to consw struct for flushing video console driver's
    scrollback buffer. Fixes issues with escape sequence '\e[3J' reported
    by Adam Borowski (kilobyte@angband.pl).
  - Fix style issues
Changes in v6:
  - Change of check if feature is enabled in 
    vgacon_scrollback_switch()
Changes in v5:
  - Clearify documentation
  - Skip superfluous array initialization
  - Disable scrollback if buffer allocation fails
  - Refactor vgacon_switch_scrollback()
  - Rename vgacon_switch_scrollback() to vgacon_scrollback_switch()
  - Add check for fg_console in vgacon_scrollback_update
Changes in v4.1:
  - Fix compiler error
Changes in v4:
  - Rename from VGACON_SOFT_SCROLLBACK_FOR_EACH_CONSOLE to
    VGACON_SOFT_SCROLLBACK_PERSISTENT
  - Split into two patches
  - Rework documentation
  - Remove cosmetic changes in comments (postponed)
Changes in v3:
  - Add config option for this feature
  - Fallback to old scrollback buffer if kcalloc() fails
  - Remove ioctl() call again and add documentation about existing
    escape sequence to flush the scrollback buffer
Changes in v2:
  - Add ioctl() call to flush scrollback buffer
  - (Patch v2 was not labeled as such, sorry)

Manuel Schölling (3):
  console: Move scrollback data into its own struct
  console: Add callback to flush scrollback buffer to consw struct
  console: Add persistent scrollback buffers for all VGA consoles

 drivers/tty/vt/vt.c            |   9 +++
 drivers/video/console/Kconfig  |  25 ++++++-
 drivers/video/console/vgacon.c | 165 ++++++++++++++++++++++++++++-------------
 include/linux/console.h        |   4 +
 4 files changed, 148 insertions(+), 55 deletions(-)

-- 
2.1.4

^ permalink raw reply	[flat|nested] 62+ messages in thread

* [PATCH RESEND v7 1/3] console: Move scrollback data into its own struct
  2016-12-21 16:37 ` [PATCH RESEND " Manuel Schölling
@ 2016-12-21 16:37   ` Manuel Schölling
  2016-12-21 16:37   ` [PATCH RESEND v7 2/3] console: Add callback to flush scrollback buffer to consw struct Manuel Schölling
                     ` (2 subsequent siblings)
  3 siblings, 0 replies; 62+ messages in thread
From: Manuel Schölling @ 2016-12-21 16:37 UTC (permalink / raw)
  To: plagnioj, tomi.valkeinen
  Cc: manuel.schoelling, jslaby, gregkh, andrey_utkin, kilobyte,
	linux-fbdev, linux-kernel

This refactoring is in preparation for persistent scrollback
support for VGA console.

Signed-off-by: Manuel Schölling <manuel.schoelling@gmx.de>
Reviewed-by: Andrey Utkin <andrey_utkin@fastmail.com>
Tested-by: Andrey Utkin <andrey_utkin@fastmail.com>
Tested-by: Adam Borowski <kilobyte@angband.pl>

---
 drivers/video/console/vgacon.c | 91 ++++++++++++++++++++++--------------------
 1 file changed, 47 insertions(+), 44 deletions(-)

diff --git a/drivers/video/console/vgacon.c b/drivers/video/console/vgacon.c
index c22a562..48b9764 100644
--- a/drivers/video/console/vgacon.c
+++ b/drivers/video/console/vgacon.c
@@ -162,31 +162,34 @@ static inline void vga_set_mem_top(struct vc_data *c)
 
 #ifdef CONFIG_VGACON_SOFT_SCROLLBACK
 /* software scrollback */
-static void *vgacon_scrollback;
-static int vgacon_scrollback_tail;
-static int vgacon_scrollback_size;
-static int vgacon_scrollback_rows;
-static int vgacon_scrollback_cnt;
-static int vgacon_scrollback_cur;
-static int vgacon_scrollback_save;
-static int vgacon_scrollback_restore;
+static struct vgacon_scrollback_info {
+	void *data;
+	int tail;
+	int size;
+	int rows;
+	int cnt;
+	int cur;
+	int save;
+	int restore;
+} vgacon_scrollback;
 
 static void vgacon_scrollback_init(int pitch)
 {
 	int rows = CONFIG_VGACON_SOFT_SCROLLBACK_SIZE * 1024/pitch;
 
-	if (vgacon_scrollback) {
-		vgacon_scrollback_cnt  = 0;
-		vgacon_scrollback_tail = 0;
-		vgacon_scrollback_cur  = 0;
-		vgacon_scrollback_rows = rows - 1;
-		vgacon_scrollback_size = rows * pitch;
+	if (vgacon_scrollback.data) {
+		vgacon_scrollback.cnt  = 0;
+		vgacon_scrollback.tail = 0;
+		vgacon_scrollback.cur  = 0;
+		vgacon_scrollback.rows = rows - 1;
+		vgacon_scrollback.size = rows * pitch;
 	}
 }
 
 static void vgacon_scrollback_startup(void)
 {
-	vgacon_scrollback = kcalloc(CONFIG_VGACON_SOFT_SCROLLBACK_SIZE, 1024, GFP_NOWAIT);
+	vgacon_scrollback.data = kcalloc(CONFIG_VGACON_SOFT_SCROLLBACK_SIZE,
+		1024, GFP_NOWAIT);
 	vgacon_scrollback_init(vga_video_num_columns * 2);
 }
 
@@ -194,38 +197,38 @@ static void vgacon_scrollback_update(struct vc_data *c, int t, int count)
 {
 	void *p;
 
-	if (!vgacon_scrollback_size || c->vc_num != fg_console)
+	if (!vgacon_scrollback.size || c->vc_num != fg_console)
 		return;
 
 	p = (void *) (c->vc_origin + t * c->vc_size_row);
 
 	while (count--) {
-		scr_memcpyw(vgacon_scrollback + vgacon_scrollback_tail,
+		scr_memcpyw(vgacon_scrollback.data + vgacon_scrollback.tail,
 			    p, c->vc_size_row);
-		vgacon_scrollback_cnt++;
+		vgacon_scrollback.cnt++;
 		p += c->vc_size_row;
-		vgacon_scrollback_tail += c->vc_size_row;
+		vgacon_scrollback.tail += c->vc_size_row;
 
-		if (vgacon_scrollback_tail >= vgacon_scrollback_size)
-			vgacon_scrollback_tail = 0;
+		if (vgacon_scrollback.tail >= vgacon_scrollback.size)
+			vgacon_scrollback.tail = 0;
 
-		if (vgacon_scrollback_cnt > vgacon_scrollback_rows)
-			vgacon_scrollback_cnt = vgacon_scrollback_rows;
+		if (vgacon_scrollback.cnt > vgacon_scrollback.rows)
+			vgacon_scrollback.cnt = vgacon_scrollback.rows;
 
-		vgacon_scrollback_cur = vgacon_scrollback_cnt;
+		vgacon_scrollback.cur = vgacon_scrollback.cnt;
 	}
 }
 
 static void vgacon_restore_screen(struct vc_data *c)
 {
-	vgacon_scrollback_save = 0;
+	vgacon_scrollback.save = 0;
 
-	if (!vga_is_gfx && !vgacon_scrollback_restore) {
+	if (!vga_is_gfx && !vgacon_scrollback.restore) {
 		scr_memcpyw((u16 *) c->vc_origin, (u16 *) c->vc_screenbuf,
 			    c->vc_screenbuf_size > vga_vram_size ?
 			    vga_vram_size : c->vc_screenbuf_size);
-		vgacon_scrollback_restore = 1;
-		vgacon_scrollback_cur = vgacon_scrollback_cnt;
+		vgacon_scrollback.restore = 1;
+		vgacon_scrollback.cur = vgacon_scrollback.cnt;
 	}
 }
 
@@ -239,41 +242,41 @@ static void vgacon_scrolldelta(struct vc_data *c, int lines)
 		return;
 	}
 
-	if (!vgacon_scrollback)
+	if (!vgacon_scrollback.data)
 		return;
 
-	if (!vgacon_scrollback_save) {
+	if (!vgacon_scrollback.save) {
 		vgacon_cursor(c, CM_ERASE);
 		vgacon_save_screen(c);
-		vgacon_scrollback_save = 1;
+		vgacon_scrollback.save = 1;
 	}
 
-	vgacon_scrollback_restore = 0;
-	start = vgacon_scrollback_cur + lines;
+	vgacon_scrollback.restore = 0;
+	start = vgacon_scrollback.cur + lines;
 	end = start + abs(lines);
 
 	if (start < 0)
 		start = 0;
 
-	if (start > vgacon_scrollback_cnt)
-		start = vgacon_scrollback_cnt;
+	if (start > vgacon_scrollback.cnt)
+		start = vgacon_scrollback.cnt;
 
 	if (end < 0)
 		end = 0;
 
-	if (end > vgacon_scrollback_cnt)
-		end = vgacon_scrollback_cnt;
+	if (end > vgacon_scrollback.cnt)
+		end = vgacon_scrollback.cnt;
 
-	vgacon_scrollback_cur = start;
+	vgacon_scrollback.cur = start;
 	count = end - start;
-	soff = vgacon_scrollback_tail - ((vgacon_scrollback_cnt - end) *
+	soff = vgacon_scrollback.tail - ((vgacon_scrollback.cnt - end) *
 					 c->vc_size_row);
 	soff -= count * c->vc_size_row;
 
 	if (soff < 0)
-		soff += vgacon_scrollback_size;
+		soff += vgacon_scrollback.size;
 
-	count = vgacon_scrollback_cnt - start;
+	count = vgacon_scrollback.cnt - start;
 
 	if (count > c->vc_rows)
 		count = c->vc_rows;
@@ -287,13 +290,13 @@ static void vgacon_scrolldelta(struct vc_data *c, int lines)
 
 		count *= c->vc_size_row;
 		/* how much memory to end of buffer left? */
-		copysize = min(count, vgacon_scrollback_size - soff);
-		scr_memcpyw(d, vgacon_scrollback + soff, copysize);
+		copysize = min(count, vgacon_scrollback.size - soff);
+		scr_memcpyw(d, vgacon_scrollback.data + soff, copysize);
 		d += copysize;
 		count -= copysize;
 
 		if (count) {
-			scr_memcpyw(d, vgacon_scrollback, count);
+			scr_memcpyw(d, vgacon_scrollback.data, count);
 			d += count;
 		}
 
-- 
2.1.4

^ permalink raw reply	[flat|nested] 62+ messages in thread

* [PATCH RESEND v7 2/3] console: Add callback to flush scrollback buffer to consw struct
  2016-12-21 16:37 ` [PATCH RESEND " Manuel Schölling
  2016-12-21 16:37   ` [PATCH RESEND v7 1/3] console: Move scrollback data into its own struct Manuel Schölling
@ 2016-12-21 16:37   ` Manuel Schölling
  2016-12-21 16:37   ` [PATCH RESEND v7 3/3] console: Add persistent scrollback buffers for all VGA consoles Manuel Schölling
  2017-01-04 13:54   ` [PATCH RESEND v7 0/3] " Andrey Utkin
  3 siblings, 0 replies; 62+ messages in thread
From: Manuel Schölling @ 2016-12-21 16:37 UTC (permalink / raw)
  To: plagnioj, tomi.valkeinen
  Cc: manuel.schoelling, jslaby, gregkh, andrey_utkin, kilobyte,
	linux-fbdev, linux-kernel

This new callback is in preparation for persistent scrollback buffer
support for VGA consoles.
With a single scrollback buffer for all consoles, we could flush the
buffer just by invocating consw->con_switch(). But when each VGA console
has its own scrollback buffer, we need a new callback to tell the
video console driver which buffer to flush.

Signed-off-by: Manuel Schölling <manuel.schoelling@gmx.de>
Reviewed-by: Andrey Utkin <andrey_utkin@fastmail.com>
Tested-by: Andrey Utkin <andrey_utkin@fastmail.com>
Tested-by: Adam Borowski <kilobyte@angband.pl>

---
 drivers/tty/vt/vt.c            |  9 +++++++++
 drivers/video/console/vgacon.c | 24 +++++++++++++++++++++++-
 include/linux/console.h        |  4 ++++
 3 files changed, 36 insertions(+), 1 deletion(-)

diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c
index 4c10a9d..9d3ce50 100644
--- a/drivers/tty/vt/vt.c
+++ b/drivers/tty/vt/vt.c
@@ -625,6 +625,14 @@ static void save_screen(struct vc_data *vc)
 		vc->vc_sw->con_save_screen(vc);
 }
 
+static void flush_scrollback(struct vc_data *vc)
+{
+	WARN_CONSOLE_UNLOCKED();
+
+	if (vc->vc_sw->con_flush_scrollback)
+		vc->vc_sw->con_flush_scrollback(vc);
+}
+
 /*
  *	Redrawing of screen
  */
@@ -1171,6 +1179,7 @@ static void csi_J(struct vc_data *vc, int vpar)
 		case 3: /* erase scroll-back buffer (and whole display) */
 			scr_memsetw(vc->vc_screenbuf, vc->vc_video_erase_char,
 				    vc->vc_screenbuf_size);
+			flush_scrollback(vc);
 			set_origin(vc);
 			if (con_is_visible(vc))
 				update_screen(vc);
diff --git a/drivers/video/console/vgacon.c b/drivers/video/console/vgacon.c
index 48b9764..9a7c2bb 100644
--- a/drivers/video/console/vgacon.c
+++ b/drivers/video/console/vgacon.c
@@ -173,6 +173,16 @@ static struct vgacon_scrollback_info {
 	int restore;
 } vgacon_scrollback;
 
+static void vgacon_scrollback_reset(size_t reset_size)
+{
+	if (vgacon_scrollback.data && reset_size > 0)
+		memset(vgacon_scrollback.data, 0, reset_size);
+
+	vgacon_scrollback.cnt  = 0;
+	vgacon_scrollback.tail = 0;
+	vgacon_scrollback.cur  = 0;
+}
+
 static void vgacon_scrollback_init(int pitch)
 {
 	int rows = CONFIG_VGACON_SOFT_SCROLLBACK_SIZE * 1024/pitch;
@@ -305,6 +315,14 @@ static void vgacon_scrolldelta(struct vc_data *c, int lines)
 	} else
 		vgacon_cursor(c, CM_MOVE);
 }
+
+static void vgacon_flush_scrollback(struct vc_data *c)
+{
+	size_t size = CONFIG_VGACON_SOFT_SCROLLBACK_SIZE * 1024;
+
+	if (c->vc_num == fg_console)
+		vgacon_scrollback_reset(size);
+}
 #else
 #define vgacon_scrollback_startup(...) do { } while (0)
 #define vgacon_scrollback_init(...)    do { } while (0)
@@ -322,6 +340,10 @@ static void vgacon_scrolldelta(struct vc_data *c, int lines)
 			vga_vram_size);
 	vga_set_mem_top(c);
 }
+
+static void vgacon_flush_scrollback(struct vc_data *c)
+{
+}
 #endif /* CONFIG_VGACON_SOFT_SCROLLBACK */
 
 static const char *vgacon_startup(void)
@@ -1329,7 +1351,6 @@ static bool vgacon_scroll(struct vc_data *c, unsigned int t, unsigned int b,
 	return true;
 }
 
-
 /*
  *  The console `switch' structure for the VGA based console
  */
@@ -1362,6 +1383,7 @@ const struct consw vga_con = {
 	.con_save_screen = vgacon_save_screen,
 	.con_build_attr = vgacon_build_attr,
 	.con_invert_region = vgacon_invert_region,
+	.con_flush_scrollback = vgacon_flush_scrollback,
 };
 EXPORT_SYMBOL(vga_con);
 
diff --git a/include/linux/console.h b/include/linux/console.h
index 9c26c66..5949d18 100644
--- a/include/linux/console.h
+++ b/include/linux/console.h
@@ -73,6 +73,10 @@ struct consw {
 	u16    *(*con_screen_pos)(struct vc_data *, int);
 	unsigned long (*con_getxy)(struct vc_data *, unsigned long, int *, int *);
 	/*
+	 * Flush the video console driver's scrollback buffer
+	 */
+	void	(*con_flush_scrollback)(struct vc_data *);
+	/*
 	 * Prepare the console for the debugger.  This includes, but is not
 	 * limited to, unblanking the console, loading an appropriate
 	 * palette, and allowing debugger generated output.
-- 
2.1.4

^ permalink raw reply	[flat|nested] 62+ messages in thread

* [PATCH RESEND v7 3/3] console: Add persistent scrollback buffers for all VGA consoles
  2016-12-21 16:37 ` [PATCH RESEND " Manuel Schölling
  2016-12-21 16:37   ` [PATCH RESEND v7 1/3] console: Move scrollback data into its own struct Manuel Schölling
  2016-12-21 16:37   ` [PATCH RESEND v7 2/3] console: Add callback to flush scrollback buffer to consw struct Manuel Schölling
@ 2016-12-21 16:37   ` Manuel Schölling
  2017-01-04 13:54   ` [PATCH RESEND v7 0/3] " Andrey Utkin
  3 siblings, 0 replies; 62+ messages in thread
From: Manuel Schölling @ 2016-12-21 16:37 UTC (permalink / raw)
  To: plagnioj, tomi.valkeinen
  Cc: manuel.schoelling, jslaby, gregkh, andrey_utkin, kilobyte,
	linux-fbdev, linux-kernel

Add a scrollback buffers for each VGA console. The benefit is that
the scrollback history is not flushed when switching between consoles
but is persistent.
The buffers are allocated on demand when a new console is opened.

This breaks tools like clear_console that rely on flushing the
scrollback history by switching back and forth between consoles
which is why this feature is disabled by default.
Use the escape sequence \e[3J instead for flushing the buffer.

Signed-off-by: Manuel Schölling <manuel.schoelling@gmx.de>
Reviewed-by: Andrey Utkin <andrey_utkin@fastmail.com>
Tested-by: Andrey Utkin <andrey_utkin@fastmail.com>
Tested-by: Adam Borowski <kilobyte@angband.pl>

---
 drivers/video/console/Kconfig  |  25 +++++++-
 drivers/video/console/vgacon.c | 142 ++++++++++++++++++++++++++---------------
 2 files changed, 111 insertions(+), 56 deletions(-)

diff --git a/drivers/video/console/Kconfig b/drivers/video/console/Kconfig
index 38da6e2..c5742d2 100644
--- a/drivers/video/console/Kconfig
+++ b/drivers/video/console/Kconfig
@@ -43,9 +43,28 @@ config VGACON_SOFT_SCROLLBACK_SIZE
        range 1 1024
        default "64"
        help
-         Enter the amount of System RAM to allocate for the scrollback
-	 buffer.  Each 64KB will give you approximately 16 80x25
-	 screenfuls of scrollback buffer
+	  Enter the amount of System RAM to allocate for scrollback
+	  buffers of VGA consoles. Each 64KB will give you approximately
+	  16 80x25 screenfuls of scrollback buffer.
+
+config VGACON_SOFT_SCROLLBACK_PERSISTENT
+	bool "Persistent Scrollback History for each console"
+	depends on VGACON_SOFT_SCROLLBACK
+	default n
+	help
+	  Say Y here if the scrollback history should persist when switching
+	  between consoles. Otherwise, the scrollback history will be flushed
+	  each time the console is switched.
+
+	  This feature might break your tool of choice to flush the scrollback
+	  buffer, e.g. clear(1) will work fine but Debian's clear_console(1)
+	  will be broken, which might cause security issues.
+	  You can use the escape sequence \e[3J instead if this feature is
+	  activated.
+
+	  Note that a buffer of VGACON_SOFT_SCROLLBACK_SIZE is taken for each
+	  created tty device.
+	  So if you use a RAM-constrained system, say N here.
 
 config MDA_CONSOLE
 	depends on !M68K && !PARISC && ISA
diff --git a/drivers/video/console/vgacon.c b/drivers/video/console/vgacon.c
index 9a7c2bb..ca23d22 100644
--- a/drivers/video/console/vgacon.c
+++ b/drivers/video/console/vgacon.c
@@ -162,7 +162,7 @@ static inline void vga_set_mem_top(struct vc_data *c)
 
 #ifdef CONFIG_VGACON_SOFT_SCROLLBACK
 /* software scrollback */
-static struct vgacon_scrollback_info {
+struct vgacon_scrollback_info {
 	void *data;
 	int tail;
 	int size;
@@ -171,74 +171,110 @@ static struct vgacon_scrollback_info {
 	int cur;
 	int save;
 	int restore;
-} vgacon_scrollback;
+};
+
+static struct vgacon_scrollback_info *vgacon_scrollback_cur;
+#ifdef CONFIG_VGACON_SOFT_SCROLLBACK_PERSISTENT
+static struct vgacon_scrollback_info vgacon_scrollbacks[MAX_NR_CONSOLES];
+#else
+static struct vgacon_scrollback_info vgacon_scrollbacks[1];
+#endif
 
-static void vgacon_scrollback_reset(size_t reset_size)
+static void vgacon_scrollback_reset(int vc_num, size_t reset_size)
 {
-	if (vgacon_scrollback.data && reset_size > 0)
-		memset(vgacon_scrollback.data, 0, reset_size);
+	struct vgacon_scrollback_info *scrollback = &vgacon_scrollbacks[vc_num];
+
+	if (scrollback->data && reset_size > 0)
+		memset(scrollback->data, 0, reset_size);
 
-	vgacon_scrollback.cnt  = 0;
-	vgacon_scrollback.tail = 0;
-	vgacon_scrollback.cur  = 0;
+	scrollback->cnt  = 0;
+	scrollback->tail = 0;
+	scrollback->cur  = 0;
 }
 
-static void vgacon_scrollback_init(int pitch)
+static void vgacon_scrollback_init(int vc_num)
 {
-	int rows = CONFIG_VGACON_SOFT_SCROLLBACK_SIZE * 1024/pitch;
-
-	if (vgacon_scrollback.data) {
-		vgacon_scrollback.cnt  = 0;
-		vgacon_scrollback.tail = 0;
-		vgacon_scrollback.cur  = 0;
-		vgacon_scrollback.rows = rows - 1;
-		vgacon_scrollback.size = rows * pitch;
+	int pitch = vga_video_num_columns * 2;
+	size_t size = CONFIG_VGACON_SOFT_SCROLLBACK_SIZE * 1024;
+	int rows = size / pitch;
+	void *data;
+
+	data = kmalloc_array(CONFIG_VGACON_SOFT_SCROLLBACK_SIZE, 1024,
+			     GFP_NOWAIT);
+
+	vgacon_scrollbacks[vc_num].data = data;
+	vgacon_scrollback_cur = &vgacon_scrollbacks[vc_num];
+
+	vgacon_scrollback_cur->rows = rows - 1;
+	vgacon_scrollback_cur->size = rows * pitch;
+
+	vgacon_scrollback_reset(vc_num, size);
+}
+
+static void vgacon_scrollback_switch(int vc_num)
+{
+#ifndef CONFIG_VGACON_SOFT_SCROLLBACK_PERSISTENT
+	vc_num = 0;
+#endif
+
+	if (!vgacon_scrollbacks[vc_num].data) {
+		vgacon_scrollback_init(vc_num);
+	} else {
+#ifdef CONFIG_VGACON_SOFT_SCROLLBACK_PERSISTENT
+		vgacon_scrollback_cur = &vgacon_scrollbacks[vc_num];
+#else
+		size_t size = CONFIG_VGACON_SOFT_SCROLLBACK_SIZE * 1024;
+
+		vgacon_scrollback_reset(vc_num, size);
+#endif
 	}
 }
 
 static void vgacon_scrollback_startup(void)
 {
-	vgacon_scrollback.data = kcalloc(CONFIG_VGACON_SOFT_SCROLLBACK_SIZE,
-		1024, GFP_NOWAIT);
-	vgacon_scrollback_init(vga_video_num_columns * 2);
+	vgacon_scrollback_cur = &vgacon_scrollbacks[0];
+	vgacon_scrollback_init(0);
 }
 
 static void vgacon_scrollback_update(struct vc_data *c, int t, int count)
 {
 	void *p;
 
-	if (!vgacon_scrollback.size || c->vc_num != fg_console)
+	if (!vgacon_scrollback_cur->data || !vgacon_scrollback_cur->size ||
+	    c->vc_num != fg_console)
 		return;
 
 	p = (void *) (c->vc_origin + t * c->vc_size_row);
 
 	while (count--) {
-		scr_memcpyw(vgacon_scrollback.data + vgacon_scrollback.tail,
+		scr_memcpyw(vgacon_scrollback_cur->data +
+			    vgacon_scrollback_cur->tail,
 			    p, c->vc_size_row);
-		vgacon_scrollback.cnt++;
+
+		vgacon_scrollback_cur->cnt++;
 		p += c->vc_size_row;
-		vgacon_scrollback.tail += c->vc_size_row;
+		vgacon_scrollback_cur->tail += c->vc_size_row;
 
-		if (vgacon_scrollback.tail >= vgacon_scrollback.size)
-			vgacon_scrollback.tail = 0;
+		if (vgacon_scrollback_cur->tail >= vgacon_scrollback_cur->size)
+			vgacon_scrollback_cur->tail = 0;
 
-		if (vgacon_scrollback.cnt > vgacon_scrollback.rows)
-			vgacon_scrollback.cnt = vgacon_scrollback.rows;
+		if (vgacon_scrollback_cur->cnt > vgacon_scrollback_cur->rows)
+			vgacon_scrollback_cur->cnt = vgacon_scrollback_cur->rows;
 
-		vgacon_scrollback.cur = vgacon_scrollback.cnt;
+		vgacon_scrollback_cur->cur = vgacon_scrollback_cur->cnt;
 	}
 }
 
 static void vgacon_restore_screen(struct vc_data *c)
 {
-	vgacon_scrollback.save = 0;
+	vgacon_scrollback_cur->save = 0;
 
-	if (!vga_is_gfx && !vgacon_scrollback.restore) {
+	if (!vga_is_gfx && !vgacon_scrollback_cur->restore) {
 		scr_memcpyw((u16 *) c->vc_origin, (u16 *) c->vc_screenbuf,
 			    c->vc_screenbuf_size > vga_vram_size ?
 			    vga_vram_size : c->vc_screenbuf_size);
-		vgacon_scrollback.restore = 1;
-		vgacon_scrollback.cur = vgacon_scrollback.cnt;
+		vgacon_scrollback_cur->restore = 1;
+		vgacon_scrollback_cur->cur = vgacon_scrollback_cur->cnt;
 	}
 }
 
@@ -252,41 +288,41 @@ static void vgacon_scrolldelta(struct vc_data *c, int lines)
 		return;
 	}
 
-	if (!vgacon_scrollback.data)
+	if (!vgacon_scrollback_cur->data)
 		return;
 
-	if (!vgacon_scrollback.save) {
+	if (!vgacon_scrollback_cur->save) {
 		vgacon_cursor(c, CM_ERASE);
 		vgacon_save_screen(c);
-		vgacon_scrollback.save = 1;
+		vgacon_scrollback_cur->save = 1;
 	}
 
-	vgacon_scrollback.restore = 0;
-	start = vgacon_scrollback.cur + lines;
+	vgacon_scrollback_cur->restore = 0;
+	start = vgacon_scrollback_cur->cur + lines;
 	end = start + abs(lines);
 
 	if (start < 0)
 		start = 0;
 
-	if (start > vgacon_scrollback.cnt)
-		start = vgacon_scrollback.cnt;
+	if (start > vgacon_scrollback_cur->cnt)
+		start = vgacon_scrollback_cur->cnt;
 
 	if (end < 0)
 		end = 0;
 
-	if (end > vgacon_scrollback.cnt)
-		end = vgacon_scrollback.cnt;
+	if (end > vgacon_scrollback_cur->cnt)
+		end = vgacon_scrollback_cur->cnt;
 
-	vgacon_scrollback.cur = start;
+	vgacon_scrollback_cur->cur = start;
 	count = end - start;
-	soff = vgacon_scrollback.tail - ((vgacon_scrollback.cnt - end) *
-					 c->vc_size_row);
+	soff = vgacon_scrollback_cur->tail -
+		((vgacon_scrollback_cur->cnt - end) * c->vc_size_row);
 	soff -= count * c->vc_size_row;
 
 	if (soff < 0)
-		soff += vgacon_scrollback.size;
+		soff += vgacon_scrollback_cur->size;
 
-	count = vgacon_scrollback.cnt - start;
+	count = vgacon_scrollback_cur->cnt - start;
 
 	if (count > c->vc_rows)
 		count = c->vc_rows;
@@ -300,13 +336,13 @@ static void vgacon_scrolldelta(struct vc_data *c, int lines)
 
 		count *= c->vc_size_row;
 		/* how much memory to end of buffer left? */
-		copysize = min(count, vgacon_scrollback.size - soff);
-		scr_memcpyw(d, vgacon_scrollback.data + soff, copysize);
+		copysize = min(count, vgacon_scrollback_cur->size - soff);
+		scr_memcpyw(d, vgacon_scrollback_cur->data + soff, copysize);
 		d += copysize;
 		count -= copysize;
 
 		if (count) {
-			scr_memcpyw(d, vgacon_scrollback.data, count);
+			scr_memcpyw(d, vgacon_scrollback_cur->data, count);
 			d += count;
 		}
 
@@ -320,13 +356,13 @@ static void vgacon_flush_scrollback(struct vc_data *c)
 {
 	size_t size = CONFIG_VGACON_SOFT_SCROLLBACK_SIZE * 1024;
 
-	if (c->vc_num == fg_console)
-		vgacon_scrollback_reset(size);
+	vgacon_scrollback_reset(c->vc_num, size);
 }
 #else
 #define vgacon_scrollback_startup(...) do { } while (0)
 #define vgacon_scrollback_init(...)    do { } while (0)
 #define vgacon_scrollback_update(...)  do { } while (0)
+#define vgacon_scrollback_switch(...)  do { } while (0)
 
 static void vgacon_restore_screen(struct vc_data *c)
 {
@@ -805,7 +841,7 @@ static int vgacon_switch(struct vc_data *c)
 			vgacon_doresize(c, c->vc_cols, c->vc_rows);
 	}
 
-	vgacon_scrollback_init(c->vc_size_row);
+	vgacon_scrollback_switch(c->vc_num);
 	return 0;		/* Redrawing not needed */
 }
 
-- 
2.1.4

^ permalink raw reply	[flat|nested] 62+ messages in thread

* [PATCH RESEND v7 0/3] console: Add persistent scrollback buffers for all VGA consoles
  2016-12-04 10:53 [PATCH v7 0/3] console: Add persistent scrollback buffers for all VGA consoles Manuel Schölling
                   ` (4 preceding siblings ...)
  2016-12-21 16:37 ` [PATCH RESEND " Manuel Schölling
@ 2017-01-02 14:27 ` Manuel Schölling
  2017-01-02 14:27   ` [PATCH RESEND v7 1/3] console: Move scrollback data into its own struct Manuel Schölling
                     ` (2 more replies)
  5 siblings, 3 replies; 62+ messages in thread
From: Manuel Schölling @ 2017-01-02 14:27 UTC (permalink / raw)
  To: plagnioj, tomi.valkeinen
  Cc: manuel.schoelling, jslaby, gregkh, andrey_utkin, kilobyte,
	linux-fbdev, linux-kernel

Reviewed-by: Andrey Utkin <andrey_utkin@fastmail.com>
Tested-by: Andrey Utkin <andrey_utkin@fastmail.com>
Tested-by: Adam Borowski <kilobyte@angband.pl>

--
Changes in v7:
  - Add new callback to consw struct for flushing video console driver's
    scrollback buffer. Fixes issues with escape sequence '\e[3J' reported
    by Adam Borowski (kilobyte@angband.pl).
  - Fix style issues
Changes in v6:
  - Change of check if feature is enabled in 
    vgacon_scrollback_switch()
Changes in v5:
  - Clearify documentation
  - Skip superfluous array initialization
  - Disable scrollback if buffer allocation fails
  - Refactor vgacon_switch_scrollback()
  - Rename vgacon_switch_scrollback() to vgacon_scrollback_switch()
  - Add check for fg_console in vgacon_scrollback_update
Changes in v4.1:
  - Fix compiler error
Changes in v4:
  - Rename from VGACON_SOFT_SCROLLBACK_FOR_EACH_CONSOLE to
    VGACON_SOFT_SCROLLBACK_PERSISTENT
  - Split into two patches
  - Rework documentation
  - Remove cosmetic changes in comments (postponed)
Changes in v3:
  - Add config option for this feature
  - Fallback to old scrollback buffer if kcalloc() fails
  - Remove ioctl() call again and add documentation about existing
    escape sequence to flush the scrollback buffer
Changes in v2:
  - Add ioctl() call to flush scrollback buffer
  - (Patch v2 was not labeled as such, sorry)

Manuel Schölling (3):
  console: Move scrollback data into its own struct
  console: Add callback to flush scrollback buffer to consw struct
  console: Add persistent scrollback buffers for all VGA consoles

 drivers/tty/vt/vt.c            |   9 +++
 drivers/video/console/Kconfig  |  25 ++++++-
 drivers/video/console/vgacon.c | 165 ++++++++++++++++++++++++++++-------------
 include/linux/console.h        |   4 +
 4 files changed, 148 insertions(+), 55 deletions(-)

-- 
2.1.4

^ permalink raw reply	[flat|nested] 62+ messages in thread

* [PATCH RESEND v7 1/3] console: Move scrollback data into its own struct
  2017-01-02 14:27 ` [PATCH RESEND v7 0/3] console: Add persistent scrollback buffers for all VGA consoles Manuel Schölling
@ 2017-01-02 14:27   ` Manuel Schölling
  2017-01-02 14:27   ` [PATCH RESEND v7 2/3] console: Add callback to flush scrollback buffer to consw struct Manuel Schölling
  2017-01-02 14:27   ` [PATCH RESEND v7 3/3] console: Add persistent scrollback buffers for all VGA consoles Manuel Schölling
  2 siblings, 0 replies; 62+ messages in thread
From: Manuel Schölling @ 2017-01-02 14:27 UTC (permalink / raw)
  To: plagnioj, tomi.valkeinen
  Cc: manuel.schoelling, jslaby, gregkh, andrey_utkin, kilobyte,
	linux-fbdev, linux-kernel

This refactoring is in preparation for persistent scrollback
support for VGA console.

Signed-off-by: Manuel Schölling <manuel.schoelling@gmx.de>
Reviewed-by: Andrey Utkin <andrey_utkin@fastmail.com>
Tested-by: Andrey Utkin <andrey_utkin@fastmail.com>
Tested-by: Adam Borowski <kilobyte@angband.pl>

---
 drivers/video/console/vgacon.c | 91 ++++++++++++++++++++++--------------------
 1 file changed, 47 insertions(+), 44 deletions(-)

diff --git a/drivers/video/console/vgacon.c b/drivers/video/console/vgacon.c
index c22a562..48b9764 100644
--- a/drivers/video/console/vgacon.c
+++ b/drivers/video/console/vgacon.c
@@ -162,31 +162,34 @@ static inline void vga_set_mem_top(struct vc_data *c)
 
 #ifdef CONFIG_VGACON_SOFT_SCROLLBACK
 /* software scrollback */
-static void *vgacon_scrollback;
-static int vgacon_scrollback_tail;
-static int vgacon_scrollback_size;
-static int vgacon_scrollback_rows;
-static int vgacon_scrollback_cnt;
-static int vgacon_scrollback_cur;
-static int vgacon_scrollback_save;
-static int vgacon_scrollback_restore;
+static struct vgacon_scrollback_info {
+	void *data;
+	int tail;
+	int size;
+	int rows;
+	int cnt;
+	int cur;
+	int save;
+	int restore;
+} vgacon_scrollback;
 
 static void vgacon_scrollback_init(int pitch)
 {
 	int rows = CONFIG_VGACON_SOFT_SCROLLBACK_SIZE * 1024/pitch;
 
-	if (vgacon_scrollback) {
-		vgacon_scrollback_cnt  = 0;
-		vgacon_scrollback_tail = 0;
-		vgacon_scrollback_cur  = 0;
-		vgacon_scrollback_rows = rows - 1;
-		vgacon_scrollback_size = rows * pitch;
+	if (vgacon_scrollback.data) {
+		vgacon_scrollback.cnt  = 0;
+		vgacon_scrollback.tail = 0;
+		vgacon_scrollback.cur  = 0;
+		vgacon_scrollback.rows = rows - 1;
+		vgacon_scrollback.size = rows * pitch;
 	}
 }
 
 static void vgacon_scrollback_startup(void)
 {
-	vgacon_scrollback = kcalloc(CONFIG_VGACON_SOFT_SCROLLBACK_SIZE, 1024, GFP_NOWAIT);
+	vgacon_scrollback.data = kcalloc(CONFIG_VGACON_SOFT_SCROLLBACK_SIZE,
+		1024, GFP_NOWAIT);
 	vgacon_scrollback_init(vga_video_num_columns * 2);
 }
 
@@ -194,38 +197,38 @@ static void vgacon_scrollback_update(struct vc_data *c, int t, int count)
 {
 	void *p;
 
-	if (!vgacon_scrollback_size || c->vc_num != fg_console)
+	if (!vgacon_scrollback.size || c->vc_num != fg_console)
 		return;
 
 	p = (void *) (c->vc_origin + t * c->vc_size_row);
 
 	while (count--) {
-		scr_memcpyw(vgacon_scrollback + vgacon_scrollback_tail,
+		scr_memcpyw(vgacon_scrollback.data + vgacon_scrollback.tail,
 			    p, c->vc_size_row);
-		vgacon_scrollback_cnt++;
+		vgacon_scrollback.cnt++;
 		p += c->vc_size_row;
-		vgacon_scrollback_tail += c->vc_size_row;
+		vgacon_scrollback.tail += c->vc_size_row;
 
-		if (vgacon_scrollback_tail >= vgacon_scrollback_size)
-			vgacon_scrollback_tail = 0;
+		if (vgacon_scrollback.tail >= vgacon_scrollback.size)
+			vgacon_scrollback.tail = 0;
 
-		if (vgacon_scrollback_cnt > vgacon_scrollback_rows)
-			vgacon_scrollback_cnt = vgacon_scrollback_rows;
+		if (vgacon_scrollback.cnt > vgacon_scrollback.rows)
+			vgacon_scrollback.cnt = vgacon_scrollback.rows;
 
-		vgacon_scrollback_cur = vgacon_scrollback_cnt;
+		vgacon_scrollback.cur = vgacon_scrollback.cnt;
 	}
 }
 
 static void vgacon_restore_screen(struct vc_data *c)
 {
-	vgacon_scrollback_save = 0;
+	vgacon_scrollback.save = 0;
 
-	if (!vga_is_gfx && !vgacon_scrollback_restore) {
+	if (!vga_is_gfx && !vgacon_scrollback.restore) {
 		scr_memcpyw((u16 *) c->vc_origin, (u16 *) c->vc_screenbuf,
 			    c->vc_screenbuf_size > vga_vram_size ?
 			    vga_vram_size : c->vc_screenbuf_size);
-		vgacon_scrollback_restore = 1;
-		vgacon_scrollback_cur = vgacon_scrollback_cnt;
+		vgacon_scrollback.restore = 1;
+		vgacon_scrollback.cur = vgacon_scrollback.cnt;
 	}
 }
 
@@ -239,41 +242,41 @@ static void vgacon_scrolldelta(struct vc_data *c, int lines)
 		return;
 	}
 
-	if (!vgacon_scrollback)
+	if (!vgacon_scrollback.data)
 		return;
 
-	if (!vgacon_scrollback_save) {
+	if (!vgacon_scrollback.save) {
 		vgacon_cursor(c, CM_ERASE);
 		vgacon_save_screen(c);
-		vgacon_scrollback_save = 1;
+		vgacon_scrollback.save = 1;
 	}
 
-	vgacon_scrollback_restore = 0;
-	start = vgacon_scrollback_cur + lines;
+	vgacon_scrollback.restore = 0;
+	start = vgacon_scrollback.cur + lines;
 	end = start + abs(lines);
 
 	if (start < 0)
 		start = 0;
 
-	if (start > vgacon_scrollback_cnt)
-		start = vgacon_scrollback_cnt;
+	if (start > vgacon_scrollback.cnt)
+		start = vgacon_scrollback.cnt;
 
 	if (end < 0)
 		end = 0;
 
-	if (end > vgacon_scrollback_cnt)
-		end = vgacon_scrollback_cnt;
+	if (end > vgacon_scrollback.cnt)
+		end = vgacon_scrollback.cnt;
 
-	vgacon_scrollback_cur = start;
+	vgacon_scrollback.cur = start;
 	count = end - start;
-	soff = vgacon_scrollback_tail - ((vgacon_scrollback_cnt - end) *
+	soff = vgacon_scrollback.tail - ((vgacon_scrollback.cnt - end) *
 					 c->vc_size_row);
 	soff -= count * c->vc_size_row;
 
 	if (soff < 0)
-		soff += vgacon_scrollback_size;
+		soff += vgacon_scrollback.size;
 
-	count = vgacon_scrollback_cnt - start;
+	count = vgacon_scrollback.cnt - start;
 
 	if (count > c->vc_rows)
 		count = c->vc_rows;
@@ -287,13 +290,13 @@ static void vgacon_scrolldelta(struct vc_data *c, int lines)
 
 		count *= c->vc_size_row;
 		/* how much memory to end of buffer left? */
-		copysize = min(count, vgacon_scrollback_size - soff);
-		scr_memcpyw(d, vgacon_scrollback + soff, copysize);
+		copysize = min(count, vgacon_scrollback.size - soff);
+		scr_memcpyw(d, vgacon_scrollback.data + soff, copysize);
 		d += copysize;
 		count -= copysize;
 
 		if (count) {
-			scr_memcpyw(d, vgacon_scrollback, count);
+			scr_memcpyw(d, vgacon_scrollback.data, count);
 			d += count;
 		}
 
-- 
2.1.4

^ permalink raw reply	[flat|nested] 62+ messages in thread

* [PATCH RESEND v7 2/3] console: Add callback to flush scrollback buffer to consw struct
  2017-01-02 14:27 ` [PATCH RESEND v7 0/3] console: Add persistent scrollback buffers for all VGA consoles Manuel Schölling
  2017-01-02 14:27   ` [PATCH RESEND v7 1/3] console: Move scrollback data into its own struct Manuel Schölling
@ 2017-01-02 14:27   ` Manuel Schölling
  2017-01-02 14:27   ` [PATCH RESEND v7 3/3] console: Add persistent scrollback buffers for all VGA consoles Manuel Schölling
  2 siblings, 0 replies; 62+ messages in thread
From: Manuel Schölling @ 2017-01-02 14:27 UTC (permalink / raw)
  To: plagnioj, tomi.valkeinen
  Cc: manuel.schoelling, jslaby, gregkh, andrey_utkin, kilobyte,
	linux-fbdev, linux-kernel

This new callback is in preparation for persistent scrollback buffer
support for VGA consoles.
With a single scrollback buffer for all consoles, we could flush the
buffer just by invocating consw->con_switch(). But when each VGA console
has its own scrollback buffer, we need a new callback to tell the
video console driver which buffer to flush.

Signed-off-by: Manuel Schölling <manuel.schoelling@gmx.de>
Reviewed-by: Andrey Utkin <andrey_utkin@fastmail.com>
Tested-by: Andrey Utkin <andrey_utkin@fastmail.com>
Tested-by: Adam Borowski <kilobyte@angband.pl>

---
 drivers/tty/vt/vt.c            |  9 +++++++++
 drivers/video/console/vgacon.c | 24 +++++++++++++++++++++++-
 include/linux/console.h        |  4 ++++
 3 files changed, 36 insertions(+), 1 deletion(-)

diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c
index 4c10a9d..9d3ce50 100644
--- a/drivers/tty/vt/vt.c
+++ b/drivers/tty/vt/vt.c
@@ -625,6 +625,14 @@ static void save_screen(struct vc_data *vc)
 		vc->vc_sw->con_save_screen(vc);
 }
 
+static void flush_scrollback(struct vc_data *vc)
+{
+	WARN_CONSOLE_UNLOCKED();
+
+	if (vc->vc_sw->con_flush_scrollback)
+		vc->vc_sw->con_flush_scrollback(vc);
+}
+
 /*
  *	Redrawing of screen
  */
@@ -1171,6 +1179,7 @@ static void csi_J(struct vc_data *vc, int vpar)
 		case 3: /* erase scroll-back buffer (and whole display) */
 			scr_memsetw(vc->vc_screenbuf, vc->vc_video_erase_char,
 				    vc->vc_screenbuf_size);
+			flush_scrollback(vc);
 			set_origin(vc);
 			if (con_is_visible(vc))
 				update_screen(vc);
diff --git a/drivers/video/console/vgacon.c b/drivers/video/console/vgacon.c
index 48b9764..9a7c2bb 100644
--- a/drivers/video/console/vgacon.c
+++ b/drivers/video/console/vgacon.c
@@ -173,6 +173,16 @@ static struct vgacon_scrollback_info {
 	int restore;
 } vgacon_scrollback;
 
+static void vgacon_scrollback_reset(size_t reset_size)
+{
+	if (vgacon_scrollback.data && reset_size > 0)
+		memset(vgacon_scrollback.data, 0, reset_size);
+
+	vgacon_scrollback.cnt  = 0;
+	vgacon_scrollback.tail = 0;
+	vgacon_scrollback.cur  = 0;
+}
+
 static void vgacon_scrollback_init(int pitch)
 {
 	int rows = CONFIG_VGACON_SOFT_SCROLLBACK_SIZE * 1024/pitch;
@@ -305,6 +315,14 @@ static void vgacon_scrolldelta(struct vc_data *c, int lines)
 	} else
 		vgacon_cursor(c, CM_MOVE);
 }
+
+static void vgacon_flush_scrollback(struct vc_data *c)
+{
+	size_t size = CONFIG_VGACON_SOFT_SCROLLBACK_SIZE * 1024;
+
+	if (c->vc_num == fg_console)
+		vgacon_scrollback_reset(size);
+}
 #else
 #define vgacon_scrollback_startup(...) do { } while (0)
 #define vgacon_scrollback_init(...)    do { } while (0)
@@ -322,6 +340,10 @@ static void vgacon_scrolldelta(struct vc_data *c, int lines)
 			vga_vram_size);
 	vga_set_mem_top(c);
 }
+
+static void vgacon_flush_scrollback(struct vc_data *c)
+{
+}
 #endif /* CONFIG_VGACON_SOFT_SCROLLBACK */
 
 static const char *vgacon_startup(void)
@@ -1329,7 +1351,6 @@ static bool vgacon_scroll(struct vc_data *c, unsigned int t, unsigned int b,
 	return true;
 }
 
-
 /*
  *  The console `switch' structure for the VGA based console
  */
@@ -1362,6 +1383,7 @@ const struct consw vga_con = {
 	.con_save_screen = vgacon_save_screen,
 	.con_build_attr = vgacon_build_attr,
 	.con_invert_region = vgacon_invert_region,
+	.con_flush_scrollback = vgacon_flush_scrollback,
 };
 EXPORT_SYMBOL(vga_con);
 
diff --git a/include/linux/console.h b/include/linux/console.h
index 9c26c66..5949d18 100644
--- a/include/linux/console.h
+++ b/include/linux/console.h
@@ -73,6 +73,10 @@ struct consw {
 	u16    *(*con_screen_pos)(struct vc_data *, int);
 	unsigned long (*con_getxy)(struct vc_data *, unsigned long, int *, int *);
 	/*
+	 * Flush the video console driver's scrollback buffer
+	 */
+	void	(*con_flush_scrollback)(struct vc_data *);
+	/*
 	 * Prepare the console for the debugger.  This includes, but is not
 	 * limited to, unblanking the console, loading an appropriate
 	 * palette, and allowing debugger generated output.
-- 
2.1.4

^ permalink raw reply	[flat|nested] 62+ messages in thread

* [PATCH RESEND v7 3/3] console: Add persistent scrollback buffers for all VGA consoles
  2017-01-02 14:27 ` [PATCH RESEND v7 0/3] console: Add persistent scrollback buffers for all VGA consoles Manuel Schölling
  2017-01-02 14:27   ` [PATCH RESEND v7 1/3] console: Move scrollback data into its own struct Manuel Schölling
  2017-01-02 14:27   ` [PATCH RESEND v7 2/3] console: Add callback to flush scrollback buffer to consw struct Manuel Schölling
@ 2017-01-02 14:27   ` Manuel Schölling
  2 siblings, 0 replies; 62+ messages in thread
From: Manuel Schölling @ 2017-01-02 14:27 UTC (permalink / raw)
  To: plagnioj, tomi.valkeinen
  Cc: manuel.schoelling, jslaby, gregkh, andrey_utkin, kilobyte,
	linux-fbdev, linux-kernel

Add a scrollback buffers for each VGA console. The benefit is that
the scrollback history is not flushed when switching between consoles
but is persistent.
The buffers are allocated on demand when a new console is opened.

This breaks tools like clear_console that rely on flushing the
scrollback history by switching back and forth between consoles
which is why this feature is disabled by default.
Use the escape sequence \e[3J instead for flushing the buffer.

Signed-off-by: Manuel Schölling <manuel.schoelling@gmx.de>
Reviewed-by: Andrey Utkin <andrey_utkin@fastmail.com>
Tested-by: Andrey Utkin <andrey_utkin@fastmail.com>
Tested-by: Adam Borowski <kilobyte@angband.pl>

---
 drivers/video/console/Kconfig  |  25 +++++++-
 drivers/video/console/vgacon.c | 142 ++++++++++++++++++++++++++---------------
 2 files changed, 111 insertions(+), 56 deletions(-)

diff --git a/drivers/video/console/Kconfig b/drivers/video/console/Kconfig
index 38da6e2..c5742d2 100644
--- a/drivers/video/console/Kconfig
+++ b/drivers/video/console/Kconfig
@@ -43,9 +43,28 @@ config VGACON_SOFT_SCROLLBACK_SIZE
        range 1 1024
        default "64"
        help
-         Enter the amount of System RAM to allocate for the scrollback
-	 buffer.  Each 64KB will give you approximately 16 80x25
-	 screenfuls of scrollback buffer
+	  Enter the amount of System RAM to allocate for scrollback
+	  buffers of VGA consoles. Each 64KB will give you approximately
+	  16 80x25 screenfuls of scrollback buffer.
+
+config VGACON_SOFT_SCROLLBACK_PERSISTENT
+	bool "Persistent Scrollback History for each console"
+	depends on VGACON_SOFT_SCROLLBACK
+	default n
+	help
+	  Say Y here if the scrollback history should persist when switching
+	  between consoles. Otherwise, the scrollback history will be flushed
+	  each time the console is switched.
+
+	  This feature might break your tool of choice to flush the scrollback
+	  buffer, e.g. clear(1) will work fine but Debian's clear_console(1)
+	  will be broken, which might cause security issues.
+	  You can use the escape sequence \e[3J instead if this feature is
+	  activated.
+
+	  Note that a buffer of VGACON_SOFT_SCROLLBACK_SIZE is taken for each
+	  created tty device.
+	  So if you use a RAM-constrained system, say N here.
 
 config MDA_CONSOLE
 	depends on !M68K && !PARISC && ISA
diff --git a/drivers/video/console/vgacon.c b/drivers/video/console/vgacon.c
index 9a7c2bb..ca23d22 100644
--- a/drivers/video/console/vgacon.c
+++ b/drivers/video/console/vgacon.c
@@ -162,7 +162,7 @@ static inline void vga_set_mem_top(struct vc_data *c)
 
 #ifdef CONFIG_VGACON_SOFT_SCROLLBACK
 /* software scrollback */
-static struct vgacon_scrollback_info {
+struct vgacon_scrollback_info {
 	void *data;
 	int tail;
 	int size;
@@ -171,74 +171,110 @@ static struct vgacon_scrollback_info {
 	int cur;
 	int save;
 	int restore;
-} vgacon_scrollback;
+};
+
+static struct vgacon_scrollback_info *vgacon_scrollback_cur;
+#ifdef CONFIG_VGACON_SOFT_SCROLLBACK_PERSISTENT
+static struct vgacon_scrollback_info vgacon_scrollbacks[MAX_NR_CONSOLES];
+#else
+static struct vgacon_scrollback_info vgacon_scrollbacks[1];
+#endif
 
-static void vgacon_scrollback_reset(size_t reset_size)
+static void vgacon_scrollback_reset(int vc_num, size_t reset_size)
 {
-	if (vgacon_scrollback.data && reset_size > 0)
-		memset(vgacon_scrollback.data, 0, reset_size);
+	struct vgacon_scrollback_info *scrollback = &vgacon_scrollbacks[vc_num];
+
+	if (scrollback->data && reset_size > 0)
+		memset(scrollback->data, 0, reset_size);
 
-	vgacon_scrollback.cnt  = 0;
-	vgacon_scrollback.tail = 0;
-	vgacon_scrollback.cur  = 0;
+	scrollback->cnt  = 0;
+	scrollback->tail = 0;
+	scrollback->cur  = 0;
 }
 
-static void vgacon_scrollback_init(int pitch)
+static void vgacon_scrollback_init(int vc_num)
 {
-	int rows = CONFIG_VGACON_SOFT_SCROLLBACK_SIZE * 1024/pitch;
-
-	if (vgacon_scrollback.data) {
-		vgacon_scrollback.cnt  = 0;
-		vgacon_scrollback.tail = 0;
-		vgacon_scrollback.cur  = 0;
-		vgacon_scrollback.rows = rows - 1;
-		vgacon_scrollback.size = rows * pitch;
+	int pitch = vga_video_num_columns * 2;
+	size_t size = CONFIG_VGACON_SOFT_SCROLLBACK_SIZE * 1024;
+	int rows = size / pitch;
+	void *data;
+
+	data = kmalloc_array(CONFIG_VGACON_SOFT_SCROLLBACK_SIZE, 1024,
+			     GFP_NOWAIT);
+
+	vgacon_scrollbacks[vc_num].data = data;
+	vgacon_scrollback_cur = &vgacon_scrollbacks[vc_num];
+
+	vgacon_scrollback_cur->rows = rows - 1;
+	vgacon_scrollback_cur->size = rows * pitch;
+
+	vgacon_scrollback_reset(vc_num, size);
+}
+
+static void vgacon_scrollback_switch(int vc_num)
+{
+#ifndef CONFIG_VGACON_SOFT_SCROLLBACK_PERSISTENT
+	vc_num = 0;
+#endif
+
+	if (!vgacon_scrollbacks[vc_num].data) {
+		vgacon_scrollback_init(vc_num);
+	} else {
+#ifdef CONFIG_VGACON_SOFT_SCROLLBACK_PERSISTENT
+		vgacon_scrollback_cur = &vgacon_scrollbacks[vc_num];
+#else
+		size_t size = CONFIG_VGACON_SOFT_SCROLLBACK_SIZE * 1024;
+
+		vgacon_scrollback_reset(vc_num, size);
+#endif
 	}
 }
 
 static void vgacon_scrollback_startup(void)
 {
-	vgacon_scrollback.data = kcalloc(CONFIG_VGACON_SOFT_SCROLLBACK_SIZE,
-		1024, GFP_NOWAIT);
-	vgacon_scrollback_init(vga_video_num_columns * 2);
+	vgacon_scrollback_cur = &vgacon_scrollbacks[0];
+	vgacon_scrollback_init(0);
 }
 
 static void vgacon_scrollback_update(struct vc_data *c, int t, int count)
 {
 	void *p;
 
-	if (!vgacon_scrollback.size || c->vc_num != fg_console)
+	if (!vgacon_scrollback_cur->data || !vgacon_scrollback_cur->size ||
+	    c->vc_num != fg_console)
 		return;
 
 	p = (void *) (c->vc_origin + t * c->vc_size_row);
 
 	while (count--) {
-		scr_memcpyw(vgacon_scrollback.data + vgacon_scrollback.tail,
+		scr_memcpyw(vgacon_scrollback_cur->data +
+			    vgacon_scrollback_cur->tail,
 			    p, c->vc_size_row);
-		vgacon_scrollback.cnt++;
+
+		vgacon_scrollback_cur->cnt++;
 		p += c->vc_size_row;
-		vgacon_scrollback.tail += c->vc_size_row;
+		vgacon_scrollback_cur->tail += c->vc_size_row;
 
-		if (vgacon_scrollback.tail >= vgacon_scrollback.size)
-			vgacon_scrollback.tail = 0;
+		if (vgacon_scrollback_cur->tail >= vgacon_scrollback_cur->size)
+			vgacon_scrollback_cur->tail = 0;
 
-		if (vgacon_scrollback.cnt > vgacon_scrollback.rows)
-			vgacon_scrollback.cnt = vgacon_scrollback.rows;
+		if (vgacon_scrollback_cur->cnt > vgacon_scrollback_cur->rows)
+			vgacon_scrollback_cur->cnt = vgacon_scrollback_cur->rows;
 
-		vgacon_scrollback.cur = vgacon_scrollback.cnt;
+		vgacon_scrollback_cur->cur = vgacon_scrollback_cur->cnt;
 	}
 }
 
 static void vgacon_restore_screen(struct vc_data *c)
 {
-	vgacon_scrollback.save = 0;
+	vgacon_scrollback_cur->save = 0;
 
-	if (!vga_is_gfx && !vgacon_scrollback.restore) {
+	if (!vga_is_gfx && !vgacon_scrollback_cur->restore) {
 		scr_memcpyw((u16 *) c->vc_origin, (u16 *) c->vc_screenbuf,
 			    c->vc_screenbuf_size > vga_vram_size ?
 			    vga_vram_size : c->vc_screenbuf_size);
-		vgacon_scrollback.restore = 1;
-		vgacon_scrollback.cur = vgacon_scrollback.cnt;
+		vgacon_scrollback_cur->restore = 1;
+		vgacon_scrollback_cur->cur = vgacon_scrollback_cur->cnt;
 	}
 }
 
@@ -252,41 +288,41 @@ static void vgacon_scrolldelta(struct vc_data *c, int lines)
 		return;
 	}
 
-	if (!vgacon_scrollback.data)
+	if (!vgacon_scrollback_cur->data)
 		return;
 
-	if (!vgacon_scrollback.save) {
+	if (!vgacon_scrollback_cur->save) {
 		vgacon_cursor(c, CM_ERASE);
 		vgacon_save_screen(c);
-		vgacon_scrollback.save = 1;
+		vgacon_scrollback_cur->save = 1;
 	}
 
-	vgacon_scrollback.restore = 0;
-	start = vgacon_scrollback.cur + lines;
+	vgacon_scrollback_cur->restore = 0;
+	start = vgacon_scrollback_cur->cur + lines;
 	end = start + abs(lines);
 
 	if (start < 0)
 		start = 0;
 
-	if (start > vgacon_scrollback.cnt)
-		start = vgacon_scrollback.cnt;
+	if (start > vgacon_scrollback_cur->cnt)
+		start = vgacon_scrollback_cur->cnt;
 
 	if (end < 0)
 		end = 0;
 
-	if (end > vgacon_scrollback.cnt)
-		end = vgacon_scrollback.cnt;
+	if (end > vgacon_scrollback_cur->cnt)
+		end = vgacon_scrollback_cur->cnt;
 
-	vgacon_scrollback.cur = start;
+	vgacon_scrollback_cur->cur = start;
 	count = end - start;
-	soff = vgacon_scrollback.tail - ((vgacon_scrollback.cnt - end) *
-					 c->vc_size_row);
+	soff = vgacon_scrollback_cur->tail -
+		((vgacon_scrollback_cur->cnt - end) * c->vc_size_row);
 	soff -= count * c->vc_size_row;
 
 	if (soff < 0)
-		soff += vgacon_scrollback.size;
+		soff += vgacon_scrollback_cur->size;
 
-	count = vgacon_scrollback.cnt - start;
+	count = vgacon_scrollback_cur->cnt - start;
 
 	if (count > c->vc_rows)
 		count = c->vc_rows;
@@ -300,13 +336,13 @@ static void vgacon_scrolldelta(struct vc_data *c, int lines)
 
 		count *= c->vc_size_row;
 		/* how much memory to end of buffer left? */
-		copysize = min(count, vgacon_scrollback.size - soff);
-		scr_memcpyw(d, vgacon_scrollback.data + soff, copysize);
+		copysize = min(count, vgacon_scrollback_cur->size - soff);
+		scr_memcpyw(d, vgacon_scrollback_cur->data + soff, copysize);
 		d += copysize;
 		count -= copysize;
 
 		if (count) {
-			scr_memcpyw(d, vgacon_scrollback.data, count);
+			scr_memcpyw(d, vgacon_scrollback_cur->data, count);
 			d += count;
 		}
 
@@ -320,13 +356,13 @@ static void vgacon_flush_scrollback(struct vc_data *c)
 {
 	size_t size = CONFIG_VGACON_SOFT_SCROLLBACK_SIZE * 1024;
 
-	if (c->vc_num == fg_console)
-		vgacon_scrollback_reset(size);
+	vgacon_scrollback_reset(c->vc_num, size);
 }
 #else
 #define vgacon_scrollback_startup(...) do { } while (0)
 #define vgacon_scrollback_init(...)    do { } while (0)
 #define vgacon_scrollback_update(...)  do { } while (0)
+#define vgacon_scrollback_switch(...)  do { } while (0)
 
 static void vgacon_restore_screen(struct vc_data *c)
 {
@@ -805,7 +841,7 @@ static int vgacon_switch(struct vc_data *c)
 			vgacon_doresize(c, c->vc_cols, c->vc_rows);
 	}
 
-	vgacon_scrollback_init(c->vc_size_row);
+	vgacon_scrollback_switch(c->vc_num);
 	return 0;		/* Redrawing not needed */
 }
 
-- 
2.1.4

^ permalink raw reply	[flat|nested] 62+ messages in thread

* Re: [PATCH RESEND v7 0/3] console: Add persistent scrollback buffers for all VGA consoles
  2016-12-21 16:37 ` [PATCH RESEND " Manuel Schölling
                     ` (2 preceding siblings ...)
  2016-12-21 16:37   ` [PATCH RESEND v7 3/3] console: Add persistent scrollback buffers for all VGA consoles Manuel Schölling
@ 2017-01-04 13:54   ` Andrey Utkin
  2017-01-05 11:33     ` [PATCH v8 " Manuel Schölling
                       ` (3 more replies)
  3 siblings, 4 replies; 62+ messages in thread
From: Andrey Utkin @ 2017-01-04 13:54 UTC (permalink / raw)
  To: Manuel Schölling
  Cc: plagnioj, tomi.valkeinen, jslaby, gregkh, kilobyte, linux-fbdev,
	linux-kernel

Manuel,

Previous Greg KH reply implied that you should send it marked as v8 for
it to gain visibility and avoid confusion. Just prepend your changes
history with something like

Changes in v8:
 - Added Reviewed-by, Tested-by statements

^ permalink raw reply	[flat|nested] 62+ messages in thread

* [PATCH v8 0/3] console: Add persistent scrollback buffers for all VGA consoles
  2017-01-04 13:54   ` [PATCH RESEND v7 0/3] " Andrey Utkin
@ 2017-01-05 11:33     ` Manuel Schölling
  2017-01-05 11:33     ` [PATCH v8 1/3] console: Move scrollback data into its own struct Manuel Schölling
                       ` (2 subsequent siblings)
  3 siblings, 0 replies; 62+ messages in thread
From: Manuel Schölling @ 2017-01-05 11:33 UTC (permalink / raw)
  To: gregkh
  Cc: jslaby, kilobyte, lkml14, rdunlap, shorne, andrey_utkin, akpm,
	paul.burton, daniel.vetter, tj, hdegoede, linux-kernel,
	linux-fbdev, Manuel Schölling

Reviewed-by: Andrey Utkin <andrey_utkin@fastmail.com>
Tested-by: Andrey Utkin <andrey_utkin@fastmail.com>
Tested-by: Adam Borowski <kilobyte@angband.pl>

--
Changes in v8:
  - Add Reviewed-by/Tested-By statements
Changes in v7:
  - Add new callback to consw struct for flushing video console driver's
    scrollback buffer. Fixes issues with escape sequence '\e[3J' reported
    by Adam Borowski (kilobyte@angband.pl).
  - Fix style issues
Changes in v6:
  - Change of check if feature is enabled in 
    vgacon_scrollback_switch()
Changes in v5:
  - Clearify documentation
  - Skip superfluous array initialization
  - Disable scrollback if buffer allocation fails
  - Refactor vgacon_switch_scrollback()
  - Rename vgacon_switch_scrollback() to vgacon_scrollback_switch()
  - Add check for fg_console in vgacon_scrollback_update
Changes in v4.1:
  - Fix compiler error
Changes in v4:
  - Rename from VGACON_SOFT_SCROLLBACK_FOR_EACH_CONSOLE to
    VGACON_SOFT_SCROLLBACK_PERSISTENT
  - Split into two patches
  - Rework documentation
  - Remove cosmetic changes in comments (postponed)
Changes in v3:
  - Add config option for this feature
  - Fallback to old scrollback buffer if kcalloc() fails
  - Remove ioctl() call again and add documentation about existing
    escape sequence to flush the scrollback buffer
Changes in v2:
  - Add ioctl() call to flush scrollback buffer
  - (Patch v2 was not labeled as such, sorry)

Manuel Schölling (3):
  console: Move scrollback data into its own struct
  console: Add callback to flush scrollback buffer to consw struct
  console: Add persistent scrollback buffers for all VGA consoles

 drivers/tty/vt/vt.c            |   9 +++
 drivers/video/console/Kconfig  |  25 ++++++-
 drivers/video/console/vgacon.c | 165 ++++++++++++++++++++++++++++-------------
 include/linux/console.h        |   4 +
 4 files changed, 148 insertions(+), 55 deletions(-)

-- 
2.11.0

^ permalink raw reply	[flat|nested] 62+ messages in thread

* [PATCH v8 1/3] console: Move scrollback data into its own struct
  2017-01-04 13:54   ` [PATCH RESEND v7 0/3] " Andrey Utkin
  2017-01-05 11:33     ` [PATCH v8 " Manuel Schölling
@ 2017-01-05 11:33     ` Manuel Schölling
  2017-01-05 11:33     ` [PATCH v8 2/3] console: Add callback to flush scrollback buffer to consw struct Manuel Schölling
  2017-01-05 11:33     ` [PATCH v8 3/3] console: Add persistent scrollback buffers for all VGA consoles Manuel Schölling
  3 siblings, 0 replies; 62+ messages in thread
From: Manuel Schölling @ 2017-01-05 11:33 UTC (permalink / raw)
  To: gregkh
  Cc: jslaby, kilobyte, lkml14, rdunlap, shorne, andrey_utkin, akpm,
	paul.burton, daniel.vetter, tj, hdegoede, linux-kernel,
	linux-fbdev, Manuel Schölling

This refactoring is in preparation for persistent scrollback
support for VGA console.

Signed-off-by: Manuel Schölling <manuel.schoelling@gmx.de>
Reviewed-by: Andrey Utkin <andrey_utkin@fastmail.com>
Tested-by: Andrey Utkin <andrey_utkin@fastmail.com>
Tested-by: Adam Borowski <kilobyte@angband.pl>
---
 drivers/video/console/vgacon.c | 91 ++++++++++++++++++++++--------------------
 1 file changed, 47 insertions(+), 44 deletions(-)

diff --git a/drivers/video/console/vgacon.c b/drivers/video/console/vgacon.c
index c22a56232b7c..48b97648d4af 100644
--- a/drivers/video/console/vgacon.c
+++ b/drivers/video/console/vgacon.c
@@ -162,31 +162,34 @@ static inline void vga_set_mem_top(struct vc_data *c)
 
 #ifdef CONFIG_VGACON_SOFT_SCROLLBACK
 /* software scrollback */
-static void *vgacon_scrollback;
-static int vgacon_scrollback_tail;
-static int vgacon_scrollback_size;
-static int vgacon_scrollback_rows;
-static int vgacon_scrollback_cnt;
-static int vgacon_scrollback_cur;
-static int vgacon_scrollback_save;
-static int vgacon_scrollback_restore;
+static struct vgacon_scrollback_info {
+	void *data;
+	int tail;
+	int size;
+	int rows;
+	int cnt;
+	int cur;
+	int save;
+	int restore;
+} vgacon_scrollback;
 
 static void vgacon_scrollback_init(int pitch)
 {
 	int rows = CONFIG_VGACON_SOFT_SCROLLBACK_SIZE * 1024/pitch;
 
-	if (vgacon_scrollback) {
-		vgacon_scrollback_cnt  = 0;
-		vgacon_scrollback_tail = 0;
-		vgacon_scrollback_cur  = 0;
-		vgacon_scrollback_rows = rows - 1;
-		vgacon_scrollback_size = rows * pitch;
+	if (vgacon_scrollback.data) {
+		vgacon_scrollback.cnt  = 0;
+		vgacon_scrollback.tail = 0;
+		vgacon_scrollback.cur  = 0;
+		vgacon_scrollback.rows = rows - 1;
+		vgacon_scrollback.size = rows * pitch;
 	}
 }
 
 static void vgacon_scrollback_startup(void)
 {
-	vgacon_scrollback = kcalloc(CONFIG_VGACON_SOFT_SCROLLBACK_SIZE, 1024, GFP_NOWAIT);
+	vgacon_scrollback.data = kcalloc(CONFIG_VGACON_SOFT_SCROLLBACK_SIZE,
+		1024, GFP_NOWAIT);
 	vgacon_scrollback_init(vga_video_num_columns * 2);
 }
 
@@ -194,38 +197,38 @@ static void vgacon_scrollback_update(struct vc_data *c, int t, int count)
 {
 	void *p;
 
-	if (!vgacon_scrollback_size || c->vc_num != fg_console)
+	if (!vgacon_scrollback.size || c->vc_num != fg_console)
 		return;
 
 	p = (void *) (c->vc_origin + t * c->vc_size_row);
 
 	while (count--) {
-		scr_memcpyw(vgacon_scrollback + vgacon_scrollback_tail,
+		scr_memcpyw(vgacon_scrollback.data + vgacon_scrollback.tail,
 			    p, c->vc_size_row);
-		vgacon_scrollback_cnt++;
+		vgacon_scrollback.cnt++;
 		p += c->vc_size_row;
-		vgacon_scrollback_tail += c->vc_size_row;
+		vgacon_scrollback.tail += c->vc_size_row;
 
-		if (vgacon_scrollback_tail >= vgacon_scrollback_size)
-			vgacon_scrollback_tail = 0;
+		if (vgacon_scrollback.tail >= vgacon_scrollback.size)
+			vgacon_scrollback.tail = 0;
 
-		if (vgacon_scrollback_cnt > vgacon_scrollback_rows)
-			vgacon_scrollback_cnt = vgacon_scrollback_rows;
+		if (vgacon_scrollback.cnt > vgacon_scrollback.rows)
+			vgacon_scrollback.cnt = vgacon_scrollback.rows;
 
-		vgacon_scrollback_cur = vgacon_scrollback_cnt;
+		vgacon_scrollback.cur = vgacon_scrollback.cnt;
 	}
 }
 
 static void vgacon_restore_screen(struct vc_data *c)
 {
-	vgacon_scrollback_save = 0;
+	vgacon_scrollback.save = 0;
 
-	if (!vga_is_gfx && !vgacon_scrollback_restore) {
+	if (!vga_is_gfx && !vgacon_scrollback.restore) {
 		scr_memcpyw((u16 *) c->vc_origin, (u16 *) c->vc_screenbuf,
 			    c->vc_screenbuf_size > vga_vram_size ?
 			    vga_vram_size : c->vc_screenbuf_size);
-		vgacon_scrollback_restore = 1;
-		vgacon_scrollback_cur = vgacon_scrollback_cnt;
+		vgacon_scrollback.restore = 1;
+		vgacon_scrollback.cur = vgacon_scrollback.cnt;
 	}
 }
 
@@ -239,41 +242,41 @@ static void vgacon_scrolldelta(struct vc_data *c, int lines)
 		return;
 	}
 
-	if (!vgacon_scrollback)
+	if (!vgacon_scrollback.data)
 		return;
 
-	if (!vgacon_scrollback_save) {
+	if (!vgacon_scrollback.save) {
 		vgacon_cursor(c, CM_ERASE);
 		vgacon_save_screen(c);
-		vgacon_scrollback_save = 1;
+		vgacon_scrollback.save = 1;
 	}
 
-	vgacon_scrollback_restore = 0;
-	start = vgacon_scrollback_cur + lines;
+	vgacon_scrollback.restore = 0;
+	start = vgacon_scrollback.cur + lines;
 	end = start + abs(lines);
 
 	if (start < 0)
 		start = 0;
 
-	if (start > vgacon_scrollback_cnt)
-		start = vgacon_scrollback_cnt;
+	if (start > vgacon_scrollback.cnt)
+		start = vgacon_scrollback.cnt;
 
 	if (end < 0)
 		end = 0;
 
-	if (end > vgacon_scrollback_cnt)
-		end = vgacon_scrollback_cnt;
+	if (end > vgacon_scrollback.cnt)
+		end = vgacon_scrollback.cnt;
 
-	vgacon_scrollback_cur = start;
+	vgacon_scrollback.cur = start;
 	count = end - start;
-	soff = vgacon_scrollback_tail - ((vgacon_scrollback_cnt - end) *
+	soff = vgacon_scrollback.tail - ((vgacon_scrollback.cnt - end) *
 					 c->vc_size_row);
 	soff -= count * c->vc_size_row;
 
 	if (soff < 0)
-		soff += vgacon_scrollback_size;
+		soff += vgacon_scrollback.size;
 
-	count = vgacon_scrollback_cnt - start;
+	count = vgacon_scrollback.cnt - start;
 
 	if (count > c->vc_rows)
 		count = c->vc_rows;
@@ -287,13 +290,13 @@ static void vgacon_scrolldelta(struct vc_data *c, int lines)
 
 		count *= c->vc_size_row;
 		/* how much memory to end of buffer left? */
-		copysize = min(count, vgacon_scrollback_size - soff);
-		scr_memcpyw(d, vgacon_scrollback + soff, copysize);
+		copysize = min(count, vgacon_scrollback.size - soff);
+		scr_memcpyw(d, vgacon_scrollback.data + soff, copysize);
 		d += copysize;
 		count -= copysize;
 
 		if (count) {
-			scr_memcpyw(d, vgacon_scrollback, count);
+			scr_memcpyw(d, vgacon_scrollback.data, count);
 			d += count;
 		}
 
-- 
2.11.0

^ permalink raw reply	[flat|nested] 62+ messages in thread

* [PATCH v8 2/3] console: Add callback to flush scrollback buffer to consw struct
  2017-01-04 13:54   ` [PATCH RESEND v7 0/3] " Andrey Utkin
  2017-01-05 11:33     ` [PATCH v8 " Manuel Schölling
  2017-01-05 11:33     ` [PATCH v8 1/3] console: Move scrollback data into its own struct Manuel Schölling
@ 2017-01-05 11:33     ` Manuel Schölling
  2017-01-05 11:33     ` [PATCH v8 3/3] console: Add persistent scrollback buffers for all VGA consoles Manuel Schölling
  3 siblings, 0 replies; 62+ messages in thread
From: Manuel Schölling @ 2017-01-05 11:33 UTC (permalink / raw)
  To: gregkh
  Cc: jslaby, kilobyte, lkml14, rdunlap, shorne, andrey_utkin, akpm,
	paul.burton, daniel.vetter, tj, hdegoede, linux-kernel,
	linux-fbdev, Manuel Schölling

This new callback is in preparation for persistent scrollback buffer
support for VGA consoles.
With a single scrollback buffer for all consoles, we could flush the
buffer just by invocating consw->con_switch(). But when each VGA console
has its own scrollback buffer, we need a new callback to tell the
video console driver which buffer to flush.

Signed-off-by: Manuel Schölling <manuel.schoelling@gmx.de>
Reviewed-by: Andrey Utkin <andrey_utkin@fastmail.com>
Tested-by: Andrey Utkin <andrey_utkin@fastmail.com>
Tested-by: Adam Borowski <kilobyte@angband.pl>
---
 drivers/tty/vt/vt.c            |  9 +++++++++
 drivers/video/console/vgacon.c | 24 +++++++++++++++++++++++-
 include/linux/console.h        |  4 ++++
 3 files changed, 36 insertions(+), 1 deletion(-)

diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c
index 4c10a9df3b91..9d3ce505e7ab 100644
--- a/drivers/tty/vt/vt.c
+++ b/drivers/tty/vt/vt.c
@@ -625,6 +625,14 @@ static void save_screen(struct vc_data *vc)
 		vc->vc_sw->con_save_screen(vc);
 }
 
+static void flush_scrollback(struct vc_data *vc)
+{
+	WARN_CONSOLE_UNLOCKED();
+
+	if (vc->vc_sw->con_flush_scrollback)
+		vc->vc_sw->con_flush_scrollback(vc);
+}
+
 /*
  *	Redrawing of screen
  */
@@ -1171,6 +1179,7 @@ static void csi_J(struct vc_data *vc, int vpar)
 		case 3: /* erase scroll-back buffer (and whole display) */
 			scr_memsetw(vc->vc_screenbuf, vc->vc_video_erase_char,
 				    vc->vc_screenbuf_size);
+			flush_scrollback(vc);
 			set_origin(vc);
 			if (con_is_visible(vc))
 				update_screen(vc);
diff --git a/drivers/video/console/vgacon.c b/drivers/video/console/vgacon.c
index 48b97648d4af..9a7c2bbc5326 100644
--- a/drivers/video/console/vgacon.c
+++ b/drivers/video/console/vgacon.c
@@ -173,6 +173,16 @@ static struct vgacon_scrollback_info {
 	int restore;
 } vgacon_scrollback;
 
+static void vgacon_scrollback_reset(size_t reset_size)
+{
+	if (vgacon_scrollback.data && reset_size > 0)
+		memset(vgacon_scrollback.data, 0, reset_size);
+
+	vgacon_scrollback.cnt  = 0;
+	vgacon_scrollback.tail = 0;
+	vgacon_scrollback.cur  = 0;
+}
+
 static void vgacon_scrollback_init(int pitch)
 {
 	int rows = CONFIG_VGACON_SOFT_SCROLLBACK_SIZE * 1024/pitch;
@@ -305,6 +315,14 @@ static void vgacon_scrolldelta(struct vc_data *c, int lines)
 	} else
 		vgacon_cursor(c, CM_MOVE);
 }
+
+static void vgacon_flush_scrollback(struct vc_data *c)
+{
+	size_t size = CONFIG_VGACON_SOFT_SCROLLBACK_SIZE * 1024;
+
+	if (c->vc_num == fg_console)
+		vgacon_scrollback_reset(size);
+}
 #else
 #define vgacon_scrollback_startup(...) do { } while (0)
 #define vgacon_scrollback_init(...)    do { } while (0)
@@ -322,6 +340,10 @@ static void vgacon_scrolldelta(struct vc_data *c, int lines)
 			vga_vram_size);
 	vga_set_mem_top(c);
 }
+
+static void vgacon_flush_scrollback(struct vc_data *c)
+{
+}
 #endif /* CONFIG_VGACON_SOFT_SCROLLBACK */
 
 static const char *vgacon_startup(void)
@@ -1329,7 +1351,6 @@ static bool vgacon_scroll(struct vc_data *c, unsigned int t, unsigned int b,
 	return true;
 }
 
-
 /*
  *  The console `switch' structure for the VGA based console
  */
@@ -1362,6 +1383,7 @@ const struct consw vga_con = {
 	.con_save_screen = vgacon_save_screen,
 	.con_build_attr = vgacon_build_attr,
 	.con_invert_region = vgacon_invert_region,
+	.con_flush_scrollback = vgacon_flush_scrollback,
 };
 EXPORT_SYMBOL(vga_con);
 
diff --git a/include/linux/console.h b/include/linux/console.h
index 9c26c6685587..5949d1855589 100644
--- a/include/linux/console.h
+++ b/include/linux/console.h
@@ -73,6 +73,10 @@ struct consw {
 	u16    *(*con_screen_pos)(struct vc_data *, int);
 	unsigned long (*con_getxy)(struct vc_data *, unsigned long, int *, int *);
 	/*
+	 * Flush the video console driver's scrollback buffer
+	 */
+	void	(*con_flush_scrollback)(struct vc_data *);
+	/*
 	 * Prepare the console for the debugger.  This includes, but is not
 	 * limited to, unblanking the console, loading an appropriate
 	 * palette, and allowing debugger generated output.
-- 
2.11.0

^ permalink raw reply	[flat|nested] 62+ messages in thread

* [PATCH v8 3/3] console: Add persistent scrollback buffers for all VGA consoles
  2017-01-04 13:54   ` [PATCH RESEND v7 0/3] " Andrey Utkin
                       ` (2 preceding siblings ...)
  2017-01-05 11:33     ` [PATCH v8 2/3] console: Add callback to flush scrollback buffer to consw struct Manuel Schölling
@ 2017-01-05 11:33     ` Manuel Schölling
       [not found]       ` <CGME20170110162224epcas1p2095912fa6b73a1457fa86396149e78e9@epcas1p2.samsung.com>
  3 siblings, 1 reply; 62+ messages in thread
From: Manuel Schölling @ 2017-01-05 11:33 UTC (permalink / raw)
  To: gregkh
  Cc: jslaby, kilobyte, lkml14, rdunlap, shorne, andrey_utkin, akpm,
	paul.burton, daniel.vetter, tj, hdegoede, linux-kernel,
	linux-fbdev, Manuel Schölling

Add a scrollback buffers for each VGA console. The benefit is that
the scrollback history is not flushed when switching between consoles
but is persistent.
The buffers are allocated on demand when a new console is opened.

This breaks tools like clear_console that rely on flushing the
scrollback history by switching back and forth between consoles
which is why this feature is disabled by default.
Use the escape sequence \e[3J instead for flushing the buffer.

Signed-off-by: Manuel Schölling <manuel.schoelling@gmx.de>
Reviewed-by: Andrey Utkin <andrey_utkin@fastmail.com>
Tested-by: Andrey Utkin <andrey_utkin@fastmail.com>
Tested-by: Adam Borowski <kilobyte@angband.pl>
---
 drivers/video/console/Kconfig  |  25 +++++++-
 drivers/video/console/vgacon.c | 142 ++++++++++++++++++++++++++---------------
 2 files changed, 111 insertions(+), 56 deletions(-)

diff --git a/drivers/video/console/Kconfig b/drivers/video/console/Kconfig
index c3f1fb9ee820..f500e58f7636 100644
--- a/drivers/video/console/Kconfig
+++ b/drivers/video/console/Kconfig
@@ -43,9 +43,28 @@ config VGACON_SOFT_SCROLLBACK_SIZE
        range 1 1024
        default "64"
        help
-         Enter the amount of System RAM to allocate for the scrollback
-	 buffer.  Each 64KB will give you approximately 16 80x25
-	 screenfuls of scrollback buffer
+	  Enter the amount of System RAM to allocate for scrollback
+	  buffers of VGA consoles. Each 64KB will give you approximately
+	  16 80x25 screenfuls of scrollback buffer.
+
+config VGACON_SOFT_SCROLLBACK_PERSISTENT
+	bool "Persistent Scrollback History for each console"
+	depends on VGACON_SOFT_SCROLLBACK
+	default n
+	help
+	  Say Y here if the scrollback history should persist when switching
+	  between consoles. Otherwise, the scrollback history will be flushed
+	  each time the console is switched.
+
+	  This feature might break your tool of choice to flush the scrollback
+	  buffer, e.g. clear(1) will work fine but Debian's clear_console(1)
+	  will be broken, which might cause security issues.
+	  You can use the escape sequence \e[3J instead if this feature is
+	  activated.
+
+	  Note that a buffer of VGACON_SOFT_SCROLLBACK_SIZE is taken for each
+	  created tty device.
+	  So if you use a RAM-constrained system, say N here.
 
 config MDA_CONSOLE
 	depends on !M68K && !PARISC && ISA
diff --git a/drivers/video/console/vgacon.c b/drivers/video/console/vgacon.c
index 9a7c2bbc5326..ca23d222e029 100644
--- a/drivers/video/console/vgacon.c
+++ b/drivers/video/console/vgacon.c
@@ -162,7 +162,7 @@ static inline void vga_set_mem_top(struct vc_data *c)
 
 #ifdef CONFIG_VGACON_SOFT_SCROLLBACK
 /* software scrollback */
-static struct vgacon_scrollback_info {
+struct vgacon_scrollback_info {
 	void *data;
 	int tail;
 	int size;
@@ -171,74 +171,110 @@ static struct vgacon_scrollback_info {
 	int cur;
 	int save;
 	int restore;
-} vgacon_scrollback;
+};
+
+static struct vgacon_scrollback_info *vgacon_scrollback_cur;
+#ifdef CONFIG_VGACON_SOFT_SCROLLBACK_PERSISTENT
+static struct vgacon_scrollback_info vgacon_scrollbacks[MAX_NR_CONSOLES];
+#else
+static struct vgacon_scrollback_info vgacon_scrollbacks[1];
+#endif
 
-static void vgacon_scrollback_reset(size_t reset_size)
+static void vgacon_scrollback_reset(int vc_num, size_t reset_size)
 {
-	if (vgacon_scrollback.data && reset_size > 0)
-		memset(vgacon_scrollback.data, 0, reset_size);
+	struct vgacon_scrollback_info *scrollback = &vgacon_scrollbacks[vc_num];
+
+	if (scrollback->data && reset_size > 0)
+		memset(scrollback->data, 0, reset_size);
 
-	vgacon_scrollback.cnt  = 0;
-	vgacon_scrollback.tail = 0;
-	vgacon_scrollback.cur  = 0;
+	scrollback->cnt  = 0;
+	scrollback->tail = 0;
+	scrollback->cur  = 0;
 }
 
-static void vgacon_scrollback_init(int pitch)
+static void vgacon_scrollback_init(int vc_num)
 {
-	int rows = CONFIG_VGACON_SOFT_SCROLLBACK_SIZE * 1024/pitch;
-
-	if (vgacon_scrollback.data) {
-		vgacon_scrollback.cnt  = 0;
-		vgacon_scrollback.tail = 0;
-		vgacon_scrollback.cur  = 0;
-		vgacon_scrollback.rows = rows - 1;
-		vgacon_scrollback.size = rows * pitch;
+	int pitch = vga_video_num_columns * 2;
+	size_t size = CONFIG_VGACON_SOFT_SCROLLBACK_SIZE * 1024;
+	int rows = size / pitch;
+	void *data;
+
+	data = kmalloc_array(CONFIG_VGACON_SOFT_SCROLLBACK_SIZE, 1024,
+			     GFP_NOWAIT);
+
+	vgacon_scrollbacks[vc_num].data = data;
+	vgacon_scrollback_cur = &vgacon_scrollbacks[vc_num];
+
+	vgacon_scrollback_cur->rows = rows - 1;
+	vgacon_scrollback_cur->size = rows * pitch;
+
+	vgacon_scrollback_reset(vc_num, size);
+}
+
+static void vgacon_scrollback_switch(int vc_num)
+{
+#ifndef CONFIG_VGACON_SOFT_SCROLLBACK_PERSISTENT
+	vc_num = 0;
+#endif
+
+	if (!vgacon_scrollbacks[vc_num].data) {
+		vgacon_scrollback_init(vc_num);
+	} else {
+#ifdef CONFIG_VGACON_SOFT_SCROLLBACK_PERSISTENT
+		vgacon_scrollback_cur = &vgacon_scrollbacks[vc_num];
+#else
+		size_t size = CONFIG_VGACON_SOFT_SCROLLBACK_SIZE * 1024;
+
+		vgacon_scrollback_reset(vc_num, size);
+#endif
 	}
 }
 
 static void vgacon_scrollback_startup(void)
 {
-	vgacon_scrollback.data = kcalloc(CONFIG_VGACON_SOFT_SCROLLBACK_SIZE,
-		1024, GFP_NOWAIT);
-	vgacon_scrollback_init(vga_video_num_columns * 2);
+	vgacon_scrollback_cur = &vgacon_scrollbacks[0];
+	vgacon_scrollback_init(0);
 }
 
 static void vgacon_scrollback_update(struct vc_data *c, int t, int count)
 {
 	void *p;
 
-	if (!vgacon_scrollback.size || c->vc_num != fg_console)
+	if (!vgacon_scrollback_cur->data || !vgacon_scrollback_cur->size ||
+	    c->vc_num != fg_console)
 		return;
 
 	p = (void *) (c->vc_origin + t * c->vc_size_row);
 
 	while (count--) {
-		scr_memcpyw(vgacon_scrollback.data + vgacon_scrollback.tail,
+		scr_memcpyw(vgacon_scrollback_cur->data +
+			    vgacon_scrollback_cur->tail,
 			    p, c->vc_size_row);
-		vgacon_scrollback.cnt++;
+
+		vgacon_scrollback_cur->cnt++;
 		p += c->vc_size_row;
-		vgacon_scrollback.tail += c->vc_size_row;
+		vgacon_scrollback_cur->tail += c->vc_size_row;
 
-		if (vgacon_scrollback.tail >= vgacon_scrollback.size)
-			vgacon_scrollback.tail = 0;
+		if (vgacon_scrollback_cur->tail >= vgacon_scrollback_cur->size)
+			vgacon_scrollback_cur->tail = 0;
 
-		if (vgacon_scrollback.cnt > vgacon_scrollback.rows)
-			vgacon_scrollback.cnt = vgacon_scrollback.rows;
+		if (vgacon_scrollback_cur->cnt > vgacon_scrollback_cur->rows)
+			vgacon_scrollback_cur->cnt = vgacon_scrollback_cur->rows;
 
-		vgacon_scrollback.cur = vgacon_scrollback.cnt;
+		vgacon_scrollback_cur->cur = vgacon_scrollback_cur->cnt;
 	}
 }
 
 static void vgacon_restore_screen(struct vc_data *c)
 {
-	vgacon_scrollback.save = 0;
+	vgacon_scrollback_cur->save = 0;
 
-	if (!vga_is_gfx && !vgacon_scrollback.restore) {
+	if (!vga_is_gfx && !vgacon_scrollback_cur->restore) {
 		scr_memcpyw((u16 *) c->vc_origin, (u16 *) c->vc_screenbuf,
 			    c->vc_screenbuf_size > vga_vram_size ?
 			    vga_vram_size : c->vc_screenbuf_size);
-		vgacon_scrollback.restore = 1;
-		vgacon_scrollback.cur = vgacon_scrollback.cnt;
+		vgacon_scrollback_cur->restore = 1;
+		vgacon_scrollback_cur->cur = vgacon_scrollback_cur->cnt;
 	}
 }
 
@@ -252,41 +288,41 @@ static void vgacon_scrolldelta(struct vc_data *c, int lines)
 		return;
 	}
 
-	if (!vgacon_scrollback.data)
+	if (!vgacon_scrollback_cur->data)
 		return;
 
-	if (!vgacon_scrollback.save) {
+	if (!vgacon_scrollback_cur->save) {
 		vgacon_cursor(c, CM_ERASE);
 		vgacon_save_screen(c);
-		vgacon_scrollback.save = 1;
+		vgacon_scrollback_cur->save = 1;
 	}
 
-	vgacon_scrollback.restore = 0;
-	start = vgacon_scrollback.cur + lines;
+	vgacon_scrollback_cur->restore = 0;
+	start = vgacon_scrollback_cur->cur + lines;
 	end = start + abs(lines);
 
 	if (start < 0)
 		start = 0;
 
-	if (start > vgacon_scrollback.cnt)
-		start = vgacon_scrollback.cnt;
+	if (start > vgacon_scrollback_cur->cnt)
+		start = vgacon_scrollback_cur->cnt;
 
 	if (end < 0)
 		end = 0;
 
-	if (end > vgacon_scrollback.cnt)
-		end = vgacon_scrollback.cnt;
+	if (end > vgacon_scrollback_cur->cnt)
+		end = vgacon_scrollback_cur->cnt;
 
-	vgacon_scrollback.cur = start;
+	vgacon_scrollback_cur->cur = start;
 	count = end - start;
-	soff = vgacon_scrollback.tail - ((vgacon_scrollback.cnt - end) *
-					 c->vc_size_row);
+	soff = vgacon_scrollback_cur->tail -
+		((vgacon_scrollback_cur->cnt - end) * c->vc_size_row);
 	soff -= count * c->vc_size_row;
 
 	if (soff < 0)
-		soff += vgacon_scrollback.size;
+		soff += vgacon_scrollback_cur->size;
 
-	count = vgacon_scrollback.cnt - start;
+	count = vgacon_scrollback_cur->cnt - start;
 
 	if (count > c->vc_rows)
 		count = c->vc_rows;
@@ -300,13 +336,13 @@ static void vgacon_scrolldelta(struct vc_data *c, int lines)
 
 		count *= c->vc_size_row;
 		/* how much memory to end of buffer left? */
-		copysize = min(count, vgacon_scrollback.size - soff);
-		scr_memcpyw(d, vgacon_scrollback.data + soff, copysize);
+		copysize = min(count, vgacon_scrollback_cur->size - soff);
+		scr_memcpyw(d, vgacon_scrollback_cur->data + soff, copysize);
 		d += copysize;
 		count -= copysize;
 
 		if (count) {
-			scr_memcpyw(d, vgacon_scrollback.data, count);
+			scr_memcpyw(d, vgacon_scrollback_cur->data, count);
 			d += count;
 		}
 
@@ -320,13 +356,13 @@ static void vgacon_flush_scrollback(struct vc_data *c)
 {
 	size_t size = CONFIG_VGACON_SOFT_SCROLLBACK_SIZE * 1024;
 
-	if (c->vc_num == fg_console)
-		vgacon_scrollback_reset(size);
+	vgacon_scrollback_reset(c->vc_num, size);
 }
 #else
 #define vgacon_scrollback_startup(...) do { } while (0)
 #define vgacon_scrollback_init(...)    do { } while (0)
 #define vgacon_scrollback_update(...)  do { } while (0)
+#define vgacon_scrollback_switch(...)  do { } while (0)
 
 static void vgacon_restore_screen(struct vc_data *c)
 {
@@ -805,7 +841,7 @@ static int vgacon_switch(struct vc_data *c)
 			vgacon_doresize(c, c->vc_cols, c->vc_rows);
 	}
 
-	vgacon_scrollback_init(c->vc_size_row);
+	vgacon_scrollback_switch(c->vc_num);
 	return 0;		/* Redrawing not needed */
 }
 
-- 
2.11.0

^ permalink raw reply	[flat|nested] 62+ messages in thread

* Re: [PATCH v8 3/3] console: Add persistent scrollback buffers for all VGA consoles
       [not found]       ` <CGME20170110162224epcas1p2095912fa6b73a1457fa86396149e78e9@epcas1p2.samsung.com>
@ 2017-01-10 16:22         ` Bartlomiej Zolnierkiewicz
       [not found]           ` <CGME20170110164435epcas1p314efb9c6ea3ffb971fce06f3bfaec736@epcas1p3.samsung.com>
  0 siblings, 1 reply; 62+ messages in thread
From: Bartlomiej Zolnierkiewicz @ 2017-01-10 16:22 UTC (permalink / raw)
  To: Manuel Schölling
  Cc: gregkh, jslaby, kilobyte, lkml14, rdunlap, shorne, andrey_utkin,
	akpm, paul.burton, daniel.vetter, tj, hdegoede, linux-kernel,
	linux-fbdev


Hi,

The patchset generally looks fine to me but I have a question
regarding new VGACON_SOFT_SCROLLBACK_PERSISTENT config option.

Since the code size impact to support the persistent scrollback
feature is minimal wouldn't it be better to always include it?

The feature would be disabled by default and could be enabled
by using the new kernel command line parameter (you may also add
a new config option for enabling it by default if desired).

Best regards,
--
Bartlomiej Zolnierkiewicz
Samsung R&D Institute Poland
Samsung Electronics

On Thursday, January 05, 2017 12:33:20 PM Manuel Schölling wrote:
> Add a scrollback buffers for each VGA console. The benefit is that
> the scrollback history is not flushed when switching between consoles
> but is persistent.
> The buffers are allocated on demand when a new console is opened.
> 
> This breaks tools like clear_console that rely on flushing the
> scrollback history by switching back and forth between consoles
> which is why this feature is disabled by default.
> Use the escape sequence \e[3J instead for flushing the buffer.
> 
> Signed-off-by: Manuel Schölling <manuel.schoelling@gmx.de>
> Reviewed-by: Andrey Utkin <andrey_utkin@fastmail.com>
> Tested-by: Andrey Utkin <andrey_utkin@fastmail.com>
> Tested-by: Adam Borowski <kilobyte@angband.pl>
> ---
>  drivers/video/console/Kconfig  |  25 +++++++-
>  drivers/video/console/vgacon.c | 142 ++++++++++++++++++++++++++---------------
>  2 files changed, 111 insertions(+), 56 deletions(-)
> 
> diff --git a/drivers/video/console/Kconfig b/drivers/video/console/Kconfig
> index c3f1fb9ee820..f500e58f7636 100644
> --- a/drivers/video/console/Kconfig
> +++ b/drivers/video/console/Kconfig
> @@ -43,9 +43,28 @@ config VGACON_SOFT_SCROLLBACK_SIZE
>         range 1 1024
>         default "64"
>         help
> -         Enter the amount of System RAM to allocate for the scrollback
> -	 buffer.  Each 64KB will give you approximately 16 80x25
> -	 screenfuls of scrollback buffer
> +	  Enter the amount of System RAM to allocate for scrollback
> +	  buffers of VGA consoles. Each 64KB will give you approximately
> +	  16 80x25 screenfuls of scrollback buffer.
> +
> +config VGACON_SOFT_SCROLLBACK_PERSISTENT
> +	bool "Persistent Scrollback History for each console"
> +	depends on VGACON_SOFT_SCROLLBACK
> +	default n
> +	help
> +	  Say Y here if the scrollback history should persist when switching
> +	  between consoles. Otherwise, the scrollback history will be flushed
> +	  each time the console is switched.
> +
> +	  This feature might break your tool of choice to flush the scrollback
> +	  buffer, e.g. clear(1) will work fine but Debian's clear_console(1)
> +	  will be broken, which might cause security issues.
> +	  You can use the escape sequence \e[3J instead if this feature is
> +	  activated.
> +
> +	  Note that a buffer of VGACON_SOFT_SCROLLBACK_SIZE is taken for each
> +	  created tty device.
> +	  So if you use a RAM-constrained system, say N here.
>  
>  config MDA_CONSOLE
>  	depends on !M68K && !PARISC && ISA
> diff --git a/drivers/video/console/vgacon.c b/drivers/video/console/vgacon.c
> index 9a7c2bbc5326..ca23d222e029 100644
> --- a/drivers/video/console/vgacon.c
> +++ b/drivers/video/console/vgacon.c
> @@ -162,7 +162,7 @@ static inline void vga_set_mem_top(struct vc_data *c)
>  
>  #ifdef CONFIG_VGACON_SOFT_SCROLLBACK
>  /* software scrollback */
> -static struct vgacon_scrollback_info {
> +struct vgacon_scrollback_info {
>  	void *data;
>  	int tail;
>  	int size;
> @@ -171,74 +171,110 @@ static struct vgacon_scrollback_info {
>  	int cur;
>  	int save;
>  	int restore;
> -} vgacon_scrollback;
> +};
> +
> +static struct vgacon_scrollback_info *vgacon_scrollback_cur;
> +#ifdef CONFIG_VGACON_SOFT_SCROLLBACK_PERSISTENT
> +static struct vgacon_scrollback_info vgacon_scrollbacks[MAX_NR_CONSOLES];
> +#else
> +static struct vgacon_scrollback_info vgacon_scrollbacks[1];
> +#endif
>  
> -static void vgacon_scrollback_reset(size_t reset_size)
> +static void vgacon_scrollback_reset(int vc_num, size_t reset_size)
>  {
> -	if (vgacon_scrollback.data && reset_size > 0)
> -		memset(vgacon_scrollback.data, 0, reset_size);
> +	struct vgacon_scrollback_info *scrollback = &vgacon_scrollbacks[vc_num];
> +
> +	if (scrollback->data && reset_size > 0)
> +		memset(scrollback->data, 0, reset_size);
>  
> -	vgacon_scrollback.cnt  = 0;
> -	vgacon_scrollback.tail = 0;
> -	vgacon_scrollback.cur  = 0;
> +	scrollback->cnt  = 0;
> +	scrollback->tail = 0;
> +	scrollback->cur  = 0;
>  }
>  
> -static void vgacon_scrollback_init(int pitch)
> +static void vgacon_scrollback_init(int vc_num)
>  {
> -	int rows = CONFIG_VGACON_SOFT_SCROLLBACK_SIZE * 1024/pitch;
> -
> -	if (vgacon_scrollback.data) {
> -		vgacon_scrollback.cnt  = 0;
> -		vgacon_scrollback.tail = 0;
> -		vgacon_scrollback.cur  = 0;
> -		vgacon_scrollback.rows = rows - 1;
> -		vgacon_scrollback.size = rows * pitch;
> +	int pitch = vga_video_num_columns * 2;
> +	size_t size = CONFIG_VGACON_SOFT_SCROLLBACK_SIZE * 1024;
> +	int rows = size / pitch;
> +	void *data;
> +
> +	data = kmalloc_array(CONFIG_VGACON_SOFT_SCROLLBACK_SIZE, 1024,
> +			     GFP_NOWAIT);
> +
> +	vgacon_scrollbacks[vc_num].data = data;
> +	vgacon_scrollback_cur = &vgacon_scrollbacks[vc_num];
> +
> +	vgacon_scrollback_cur->rows = rows - 1;
> +	vgacon_scrollback_cur->size = rows * pitch;
> +
> +	vgacon_scrollback_reset(vc_num, size);
> +}
> +
> +static void vgacon_scrollback_switch(int vc_num)
> +{
> +#ifndef CONFIG_VGACON_SOFT_SCROLLBACK_PERSISTENT
> +	vc_num = 0;
> +#endif
> +
> +	if (!vgacon_scrollbacks[vc_num].data) {
> +		vgacon_scrollback_init(vc_num);
> +	} else {
> +#ifdef CONFIG_VGACON_SOFT_SCROLLBACK_PERSISTENT
> +		vgacon_scrollback_cur = &vgacon_scrollbacks[vc_num];
> +#else
> +		size_t size = CONFIG_VGACON_SOFT_SCROLLBACK_SIZE * 1024;
> +
> +		vgacon_scrollback_reset(vc_num, size);
> +#endif
>  	}
>  }
>  
>  static void vgacon_scrollback_startup(void)
>  {
> -	vgacon_scrollback.data = kcalloc(CONFIG_VGACON_SOFT_SCROLLBACK_SIZE,
> -		1024, GFP_NOWAIT);
> -	vgacon_scrollback_init(vga_video_num_columns * 2);
> +	vgacon_scrollback_cur = &vgacon_scrollbacks[0];
> +	vgacon_scrollback_init(0);
>  }
>  
>  static void vgacon_scrollback_update(struct vc_data *c, int t, int count)
>  {
>  	void *p;
>  
> -	if (!vgacon_scrollback.size || c->vc_num != fg_console)
> +	if (!vgacon_scrollback_cur->data || !vgacon_scrollback_cur->size ||
> +	    c->vc_num != fg_console)
>  		return;
>  
>  	p = (void *) (c->vc_origin + t * c->vc_size_row);
>  
>  	while (count--) {
> -		scr_memcpyw(vgacon_scrollback.data + vgacon_scrollback.tail,
> +		scr_memcpyw(vgacon_scrollback_cur->data +
> +			    vgacon_scrollback_cur->tail,
>  			    p, c->vc_size_row);
> -		vgacon_scrollback.cnt++;
> +
> +		vgacon_scrollback_cur->cnt++;
>  		p += c->vc_size_row;
> -		vgacon_scrollback.tail += c->vc_size_row;
> +		vgacon_scrollback_cur->tail += c->vc_size_row;
>  
> -		if (vgacon_scrollback.tail >= vgacon_scrollback.size)
> -			vgacon_scrollback.tail = 0;
> +		if (vgacon_scrollback_cur->tail >= vgacon_scrollback_cur->size)
> +			vgacon_scrollback_cur->tail = 0;
>  
> -		if (vgacon_scrollback.cnt > vgacon_scrollback.rows)
> -			vgacon_scrollback.cnt = vgacon_scrollback.rows;
> +		if (vgacon_scrollback_cur->cnt > vgacon_scrollback_cur->rows)
> +			vgacon_scrollback_cur->cnt = vgacon_scrollback_cur->rows;
>  
> -		vgacon_scrollback.cur = vgacon_scrollback.cnt;
> +		vgacon_scrollback_cur->cur = vgacon_scrollback_cur->cnt;
>  	}
>  }
>  
>  static void vgacon_restore_screen(struct vc_data *c)
>  {
> -	vgacon_scrollback.save = 0;
> +	vgacon_scrollback_cur->save = 0;
>  
> -	if (!vga_is_gfx && !vgacon_scrollback.restore) {
> +	if (!vga_is_gfx && !vgacon_scrollback_cur->restore) {
>  		scr_memcpyw((u16 *) c->vc_origin, (u16 *) c->vc_screenbuf,
>  			    c->vc_screenbuf_size > vga_vram_size ?
>  			    vga_vram_size : c->vc_screenbuf_size);
> -		vgacon_scrollback.restore = 1;
> -		vgacon_scrollback.cur = vgacon_scrollback.cnt;
> +		vgacon_scrollback_cur->restore = 1;
> +		vgacon_scrollback_cur->cur = vgacon_scrollback_cur->cnt;
>  	}
>  }
>  
> @@ -252,41 +288,41 @@ static void vgacon_scrolldelta(struct vc_data *c, int lines)
>  		return;
>  	}
>  
> -	if (!vgacon_scrollback.data)
> +	if (!vgacon_scrollback_cur->data)
>  		return;
>  
> -	if (!vgacon_scrollback.save) {
> +	if (!vgacon_scrollback_cur->save) {
>  		vgacon_cursor(c, CM_ERASE);
>  		vgacon_save_screen(c);
> -		vgacon_scrollback.save = 1;
> +		vgacon_scrollback_cur->save = 1;
>  	}
>  
> -	vgacon_scrollback.restore = 0;
> -	start = vgacon_scrollback.cur + lines;
> +	vgacon_scrollback_cur->restore = 0;
> +	start = vgacon_scrollback_cur->cur + lines;
>  	end = start + abs(lines);
>  
>  	if (start < 0)
>  		start = 0;
>  
> -	if (start > vgacon_scrollback.cnt)
> -		start = vgacon_scrollback.cnt;
> +	if (start > vgacon_scrollback_cur->cnt)
> +		start = vgacon_scrollback_cur->cnt;
>  
>  	if (end < 0)
>  		end = 0;
>  
> -	if (end > vgacon_scrollback.cnt)
> -		end = vgacon_scrollback.cnt;
> +	if (end > vgacon_scrollback_cur->cnt)
> +		end = vgacon_scrollback_cur->cnt;
>  
> -	vgacon_scrollback.cur = start;
> +	vgacon_scrollback_cur->cur = start;
>  	count = end - start;
> -	soff = vgacon_scrollback.tail - ((vgacon_scrollback.cnt - end) *
> -					 c->vc_size_row);
> +	soff = vgacon_scrollback_cur->tail -
> +		((vgacon_scrollback_cur->cnt - end) * c->vc_size_row);
>  	soff -= count * c->vc_size_row;
>  
>  	if (soff < 0)
> -		soff += vgacon_scrollback.size;
> +		soff += vgacon_scrollback_cur->size;
>  
> -	count = vgacon_scrollback.cnt - start;
> +	count = vgacon_scrollback_cur->cnt - start;
>  
>  	if (count > c->vc_rows)
>  		count = c->vc_rows;
> @@ -300,13 +336,13 @@ static void vgacon_scrolldelta(struct vc_data *c, int lines)
>  
>  		count *= c->vc_size_row;
>  		/* how much memory to end of buffer left? */
> -		copysize = min(count, vgacon_scrollback.size - soff);
> -		scr_memcpyw(d, vgacon_scrollback.data + soff, copysize);
> +		copysize = min(count, vgacon_scrollback_cur->size - soff);
> +		scr_memcpyw(d, vgacon_scrollback_cur->data + soff, copysize);
>  		d += copysize;
>  		count -= copysize;
>  
>  		if (count) {
> -			scr_memcpyw(d, vgacon_scrollback.data, count);
> +			scr_memcpyw(d, vgacon_scrollback_cur->data, count);
>  			d += count;
>  		}
>  
> @@ -320,13 +356,13 @@ static void vgacon_flush_scrollback(struct vc_data *c)
>  {
>  	size_t size = CONFIG_VGACON_SOFT_SCROLLBACK_SIZE * 1024;
>  
> -	if (c->vc_num == fg_console)
> -		vgacon_scrollback_reset(size);
> +	vgacon_scrollback_reset(c->vc_num, size);
>  }
>  #else
>  #define vgacon_scrollback_startup(...) do { } while (0)
>  #define vgacon_scrollback_init(...)    do { } while (0)
>  #define vgacon_scrollback_update(...)  do { } while (0)
> +#define vgacon_scrollback_switch(...)  do { } while (0)
>  
>  static void vgacon_restore_screen(struct vc_data *c)
>  {
> @@ -805,7 +841,7 @@ static int vgacon_switch(struct vc_data *c)
>  			vgacon_doresize(c, c->vc_cols, c->vc_rows);
>  	}
>  
> -	vgacon_scrollback_init(c->vc_size_row);
> +	vgacon_scrollback_switch(c->vc_num);
>  	return 0;		/* Redrawing not needed */
>  }

^ permalink raw reply	[flat|nested] 62+ messages in thread

* Re: [PATCH v8 3/3] console: Add persistent scrollback buffers for all VGA consoles
       [not found]           ` <CGME20170110164435epcas1p314efb9c6ea3ffb971fce06f3bfaec736@epcas1p3.samsung.com>
@ 2017-01-10 16:44             ` Bartlomiej Zolnierkiewicz
  2017-01-10 17:31               ` Manuel Schölling
                                 ` (5 more replies)
  0 siblings, 6 replies; 62+ messages in thread
From: Bartlomiej Zolnierkiewicz @ 2017-01-10 16:44 UTC (permalink / raw)
  To: Manuel Schölling
  Cc: gregkh, jslaby, kilobyte, lkml14, rdunlap, shorne, andrey_utkin,
	akpm, paul.burton, daniel.vetter, tj, hdegoede, linux-kernel,
	linux-fbdev

On Tuesday, January 10, 2017 05:22:22 PM Bartlomiej Zolnierkiewicz wrote:
> 
> Hi,
> 
> The patchset generally looks fine to me but I have a question
> regarding new VGACON_SOFT_SCROLLBACK_PERSISTENT config option.
> 
> Since the code size impact to support the persistent scrollback
> feature is minimal wouldn't it be better to always include it?
> 
> The feature would be disabled by default and could be enabled
> by using the new kernel command line parameter (you may also add
> a new config option for enabling it by default if desired).

Something like:

#ifdef VGACON_SOFT_SCROLLBACK_PERSISTENT_ENABLE_BY_DEFAULT
static bool scrollback_persistent = 1;
#else
static bool scrollback_persistent;
#endif

module_param_named(scrollback_persistent, scrollback_persistent, bool, 0);
MODULE_PARM_DESC(scrollback_persistent, "Enable persistent scrollback feature");

and then use scrollback_persistent variable in vgacon_scrollback_switch()
to control the actual behavior instead of ifdefs.

Best regards,
--
Bartlomiej Zolnierkiewicz
Samsung R&D Institute Poland
Samsung Electronics

> Best regards,
> --
> Bartlomiej Zolnierkiewicz
> Samsung R&D Institute Poland
> Samsung Electronics
> 
> On Thursday, January 05, 2017 12:33:20 PM Manuel Schölling wrote:
> > Add a scrollback buffers for each VGA console. The benefit is that
> > the scrollback history is not flushed when switching between consoles
> > but is persistent.
> > The buffers are allocated on demand when a new console is opened.
> > 
> > This breaks tools like clear_console that rely on flushing the
> > scrollback history by switching back and forth between consoles
> > which is why this feature is disabled by default.
> > Use the escape sequence \e[3J instead for flushing the buffer.
> > 
> > Signed-off-by: Manuel Schölling <manuel.schoelling@gmx.de>
> > Reviewed-by: Andrey Utkin <andrey_utkin@fastmail.com>
> > Tested-by: Andrey Utkin <andrey_utkin@fastmail.com>
> > Tested-by: Adam Borowski <kilobyte@angband.pl>
> > ---
> >  drivers/video/console/Kconfig  |  25 +++++++-
> >  drivers/video/console/vgacon.c | 142 ++++++++++++++++++++++++++---------------
> >  2 files changed, 111 insertions(+), 56 deletions(-)
> > 
> > diff --git a/drivers/video/console/Kconfig b/drivers/video/console/Kconfig
> > index c3f1fb9ee820..f500e58f7636 100644
> > --- a/drivers/video/console/Kconfig
> > +++ b/drivers/video/console/Kconfig
> > @@ -43,9 +43,28 @@ config VGACON_SOFT_SCROLLBACK_SIZE
> >         range 1 1024
> >         default "64"
> >         help
> > -         Enter the amount of System RAM to allocate for the scrollback
> > -	 buffer.  Each 64KB will give you approximately 16 80x25
> > -	 screenfuls of scrollback buffer
> > +	  Enter the amount of System RAM to allocate for scrollback
> > +	  buffers of VGA consoles. Each 64KB will give you approximately
> > +	  16 80x25 screenfuls of scrollback buffer.
> > +
> > +config VGACON_SOFT_SCROLLBACK_PERSISTENT
> > +	bool "Persistent Scrollback History for each console"
> > +	depends on VGACON_SOFT_SCROLLBACK
> > +	default n
> > +	help
> > +	  Say Y here if the scrollback history should persist when switching
> > +	  between consoles. Otherwise, the scrollback history will be flushed
> > +	  each time the console is switched.
> > +
> > +	  This feature might break your tool of choice to flush the scrollback
> > +	  buffer, e.g. clear(1) will work fine but Debian's clear_console(1)
> > +	  will be broken, which might cause security issues.
> > +	  You can use the escape sequence \e[3J instead if this feature is
> > +	  activated.
> > +
> > +	  Note that a buffer of VGACON_SOFT_SCROLLBACK_SIZE is taken for each
> > +	  created tty device.
> > +	  So if you use a RAM-constrained system, say N here.
> >  
> >  config MDA_CONSOLE
> >  	depends on !M68K && !PARISC && ISA
> > diff --git a/drivers/video/console/vgacon.c b/drivers/video/console/vgacon.c
> > index 9a7c2bbc5326..ca23d222e029 100644
> > --- a/drivers/video/console/vgacon.c
> > +++ b/drivers/video/console/vgacon.c
> > @@ -162,7 +162,7 @@ static inline void vga_set_mem_top(struct vc_data *c)
> >  
> >  #ifdef CONFIG_VGACON_SOFT_SCROLLBACK
> >  /* software scrollback */
> > -static struct vgacon_scrollback_info {
> > +struct vgacon_scrollback_info {
> >  	void *data;
> >  	int tail;
> >  	int size;
> > @@ -171,74 +171,110 @@ static struct vgacon_scrollback_info {
> >  	int cur;
> >  	int save;
> >  	int restore;
> > -} vgacon_scrollback;
> > +};
> > +
> > +static struct vgacon_scrollback_info *vgacon_scrollback_cur;
> > +#ifdef CONFIG_VGACON_SOFT_SCROLLBACK_PERSISTENT
> > +static struct vgacon_scrollback_info vgacon_scrollbacks[MAX_NR_CONSOLES];
> > +#else
> > +static struct vgacon_scrollback_info vgacon_scrollbacks[1];
> > +#endif
> >  
> > -static void vgacon_scrollback_reset(size_t reset_size)
> > +static void vgacon_scrollback_reset(int vc_num, size_t reset_size)
> >  {
> > -	if (vgacon_scrollback.data && reset_size > 0)
> > -		memset(vgacon_scrollback.data, 0, reset_size);
> > +	struct vgacon_scrollback_info *scrollback = &vgacon_scrollbacks[vc_num];
> > +
> > +	if (scrollback->data && reset_size > 0)
> > +		memset(scrollback->data, 0, reset_size);
> >  
> > -	vgacon_scrollback.cnt  = 0;
> > -	vgacon_scrollback.tail = 0;
> > -	vgacon_scrollback.cur  = 0;
> > +	scrollback->cnt  = 0;
> > +	scrollback->tail = 0;
> > +	scrollback->cur  = 0;
> >  }
> >  
> > -static void vgacon_scrollback_init(int pitch)
> > +static void vgacon_scrollback_init(int vc_num)
> >  {
> > -	int rows = CONFIG_VGACON_SOFT_SCROLLBACK_SIZE * 1024/pitch;
> > -
> > -	if (vgacon_scrollback.data) {
> > -		vgacon_scrollback.cnt  = 0;
> > -		vgacon_scrollback.tail = 0;
> > -		vgacon_scrollback.cur  = 0;
> > -		vgacon_scrollback.rows = rows - 1;
> > -		vgacon_scrollback.size = rows * pitch;
> > +	int pitch = vga_video_num_columns * 2;
> > +	size_t size = CONFIG_VGACON_SOFT_SCROLLBACK_SIZE * 1024;
> > +	int rows = size / pitch;
> > +	void *data;
> > +
> > +	data = kmalloc_array(CONFIG_VGACON_SOFT_SCROLLBACK_SIZE, 1024,
> > +			     GFP_NOWAIT);
> > +
> > +	vgacon_scrollbacks[vc_num].data = data;
> > +	vgacon_scrollback_cur = &vgacon_scrollbacks[vc_num];
> > +
> > +	vgacon_scrollback_cur->rows = rows - 1;
> > +	vgacon_scrollback_cur->size = rows * pitch;
> > +
> > +	vgacon_scrollback_reset(vc_num, size);
> > +}
> > +
> > +static void vgacon_scrollback_switch(int vc_num)
> > +{
> > +#ifndef CONFIG_VGACON_SOFT_SCROLLBACK_PERSISTENT
> > +	vc_num = 0;
> > +#endif
> > +
> > +	if (!vgacon_scrollbacks[vc_num].data) {
> > +		vgacon_scrollback_init(vc_num);
> > +	} else {
> > +#ifdef CONFIG_VGACON_SOFT_SCROLLBACK_PERSISTENT
> > +		vgacon_scrollback_cur = &vgacon_scrollbacks[vc_num];
> > +#else
> > +		size_t size = CONFIG_VGACON_SOFT_SCROLLBACK_SIZE * 1024;
> > +
> > +		vgacon_scrollback_reset(vc_num, size);
> > +#endif
> >  	}
> >  }
> >  
> >  static void vgacon_scrollback_startup(void)
> >  {
> > -	vgacon_scrollback.data = kcalloc(CONFIG_VGACON_SOFT_SCROLLBACK_SIZE,
> > -		1024, GFP_NOWAIT);
> > -	vgacon_scrollback_init(vga_video_num_columns * 2);
> > +	vgacon_scrollback_cur = &vgacon_scrollbacks[0];
> > +	vgacon_scrollback_init(0);
> >  }
> >  
> >  static void vgacon_scrollback_update(struct vc_data *c, int t, int count)
> >  {
> >  	void *p;
> >  
> > -	if (!vgacon_scrollback.size || c->vc_num != fg_console)
> > +	if (!vgacon_scrollback_cur->data || !vgacon_scrollback_cur->size ||
> > +	    c->vc_num != fg_console)
> >  		return;
> >  
> >  	p = (void *) (c->vc_origin + t * c->vc_size_row);
> >  
> >  	while (count--) {
> > -		scr_memcpyw(vgacon_scrollback.data + vgacon_scrollback.tail,
> > +		scr_memcpyw(vgacon_scrollback_cur->data +
> > +			    vgacon_scrollback_cur->tail,
> >  			    p, c->vc_size_row);
> > -		vgacon_scrollback.cnt++;
> > +
> > +		vgacon_scrollback_cur->cnt++;
> >  		p += c->vc_size_row;
> > -		vgacon_scrollback.tail += c->vc_size_row;
> > +		vgacon_scrollback_cur->tail += c->vc_size_row;
> >  
> > -		if (vgacon_scrollback.tail >= vgacon_scrollback.size)
> > -			vgacon_scrollback.tail = 0;
> > +		if (vgacon_scrollback_cur->tail >= vgacon_scrollback_cur->size)
> > +			vgacon_scrollback_cur->tail = 0;
> >  
> > -		if (vgacon_scrollback.cnt > vgacon_scrollback.rows)
> > -			vgacon_scrollback.cnt = vgacon_scrollback.rows;
> > +		if (vgacon_scrollback_cur->cnt > vgacon_scrollback_cur->rows)
> > +			vgacon_scrollback_cur->cnt = vgacon_scrollback_cur->rows;
> >  
> > -		vgacon_scrollback.cur = vgacon_scrollback.cnt;
> > +		vgacon_scrollback_cur->cur = vgacon_scrollback_cur->cnt;
> >  	}
> >  }
> >  
> >  static void vgacon_restore_screen(struct vc_data *c)
> >  {
> > -	vgacon_scrollback.save = 0;
> > +	vgacon_scrollback_cur->save = 0;
> >  
> > -	if (!vga_is_gfx && !vgacon_scrollback.restore) {
> > +	if (!vga_is_gfx && !vgacon_scrollback_cur->restore) {
> >  		scr_memcpyw((u16 *) c->vc_origin, (u16 *) c->vc_screenbuf,
> >  			    c->vc_screenbuf_size > vga_vram_size ?
> >  			    vga_vram_size : c->vc_screenbuf_size);
> > -		vgacon_scrollback.restore = 1;
> > -		vgacon_scrollback.cur = vgacon_scrollback.cnt;
> > +		vgacon_scrollback_cur->restore = 1;
> > +		vgacon_scrollback_cur->cur = vgacon_scrollback_cur->cnt;
> >  	}
> >  }
> >  
> > @@ -252,41 +288,41 @@ static void vgacon_scrolldelta(struct vc_data *c, int lines)
> >  		return;
> >  	}
> >  
> > -	if (!vgacon_scrollback.data)
> > +	if (!vgacon_scrollback_cur->data)
> >  		return;
> >  
> > -	if (!vgacon_scrollback.save) {
> > +	if (!vgacon_scrollback_cur->save) {
> >  		vgacon_cursor(c, CM_ERASE);
> >  		vgacon_save_screen(c);
> > -		vgacon_scrollback.save = 1;
> > +		vgacon_scrollback_cur->save = 1;
> >  	}
> >  
> > -	vgacon_scrollback.restore = 0;
> > -	start = vgacon_scrollback.cur + lines;
> > +	vgacon_scrollback_cur->restore = 0;
> > +	start = vgacon_scrollback_cur->cur + lines;
> >  	end = start + abs(lines);
> >  
> >  	if (start < 0)
> >  		start = 0;
> >  
> > -	if (start > vgacon_scrollback.cnt)
> > -		start = vgacon_scrollback.cnt;
> > +	if (start > vgacon_scrollback_cur->cnt)
> > +		start = vgacon_scrollback_cur->cnt;
> >  
> >  	if (end < 0)
> >  		end = 0;
> >  
> > -	if (end > vgacon_scrollback.cnt)
> > -		end = vgacon_scrollback.cnt;
> > +	if (end > vgacon_scrollback_cur->cnt)
> > +		end = vgacon_scrollback_cur->cnt;
> >  
> > -	vgacon_scrollback.cur = start;
> > +	vgacon_scrollback_cur->cur = start;
> >  	count = end - start;
> > -	soff = vgacon_scrollback.tail - ((vgacon_scrollback.cnt - end) *
> > -					 c->vc_size_row);
> > +	soff = vgacon_scrollback_cur->tail -
> > +		((vgacon_scrollback_cur->cnt - end) * c->vc_size_row);
> >  	soff -= count * c->vc_size_row;
> >  
> >  	if (soff < 0)
> > -		soff += vgacon_scrollback.size;
> > +		soff += vgacon_scrollback_cur->size;
> >  
> > -	count = vgacon_scrollback.cnt - start;
> > +	count = vgacon_scrollback_cur->cnt - start;
> >  
> >  	if (count > c->vc_rows)
> >  		count = c->vc_rows;
> > @@ -300,13 +336,13 @@ static void vgacon_scrolldelta(struct vc_data *c, int lines)
> >  
> >  		count *= c->vc_size_row;
> >  		/* how much memory to end of buffer left? */
> > -		copysize = min(count, vgacon_scrollback.size - soff);
> > -		scr_memcpyw(d, vgacon_scrollback.data + soff, copysize);
> > +		copysize = min(count, vgacon_scrollback_cur->size - soff);
> > +		scr_memcpyw(d, vgacon_scrollback_cur->data + soff, copysize);
> >  		d += copysize;
> >  		count -= copysize;
> >  
> >  		if (count) {
> > -			scr_memcpyw(d, vgacon_scrollback.data, count);
> > +			scr_memcpyw(d, vgacon_scrollback_cur->data, count);
> >  			d += count;
> >  		}
> >  
> > @@ -320,13 +356,13 @@ static void vgacon_flush_scrollback(struct vc_data *c)
> >  {
> >  	size_t size = CONFIG_VGACON_SOFT_SCROLLBACK_SIZE * 1024;
> >  
> > -	if (c->vc_num == fg_console)
> > -		vgacon_scrollback_reset(size);
> > +	vgacon_scrollback_reset(c->vc_num, size);
> >  }
> >  #else
> >  #define vgacon_scrollback_startup(...) do { } while (0)
> >  #define vgacon_scrollback_init(...)    do { } while (0)
> >  #define vgacon_scrollback_update(...)  do { } while (0)
> > +#define vgacon_scrollback_switch(...)  do { } while (0)
> >  
> >  static void vgacon_restore_screen(struct vc_data *c)
> >  {
> > @@ -805,7 +841,7 @@ static int vgacon_switch(struct vc_data *c)
> >  			vgacon_doresize(c, c->vc_cols, c->vc_rows);
> >  	}
> >  
> > -	vgacon_scrollback_init(c->vc_size_row);
> > +	vgacon_scrollback_switch(c->vc_num);
> >  	return 0;		/* Redrawing not needed */
> >  }

^ permalink raw reply	[flat|nested] 62+ messages in thread

* Re: [PATCH v8 3/3] console: Add persistent scrollback buffers for all VGA consoles
  2017-01-10 16:44             ` Bartlomiej Zolnierkiewicz
@ 2017-01-10 17:31               ` Manuel Schölling
  2017-01-10 21:28               ` [PATCH v9 0/4] " Manuel Schölling
                                 ` (4 subsequent siblings)
  5 siblings, 0 replies; 62+ messages in thread
From: Manuel Schölling @ 2017-01-10 17:31 UTC (permalink / raw)
  To: Bartlomiej Zolnierkiewicz
  Cc: gregkh, jslaby, kilobyte, lkml14, rdunlap, shorne, andrey_utkin,
	akpm, paul.burton, daniel.vetter, tj, hdegoede, linux-kernel,
	linux-fbdev

Hi Bartlomiej,

First of all thank you for you feedback!

On Tue, 2017-01-10 at 17:44 +0100, Bartlomiej Zolnierkiewicz wrote:
> On Tuesday, January 10, 2017 05:22:22 PM Bartlomiej Zolnierkiewicz
> wrote:
> > 
> > Hi,
> > 
> > The patchset generally looks fine to me but I have a question
> > regarding new VGACON_SOFT_SCROLLBACK_PERSISTENT config option.
> > 
> > Since the code size impact to support the persistent scrollback
> > feature is minimal wouldn't it be better to always include it?
> > 
> > The feature would be disabled by default and could be enabled
> > by using the new kernel command line parameter (you may also add
> > a new config option for enabling it by default if desired).
> 
> Something like:
> 
> #ifdef VGACON_SOFT_SCROLLBACK_PERSISTENT_ENABLE_BY_DEFAULT
> static bool scrollback_persistent = 1;
> #else
> static bool scrollback_persistent;
> #endif
> 
> module_param_named(scrollback_persistent, scrollback_persistent,
> bool, 0);
> MODULE_PARM_DESC(scrollback_persistent, "Enable persistent scrollback
> feature");
> 
> and then use scrollback_persistent variable in
> vgacon_scrollback_switch()
> to control the actual behavior instead of ifdefs.
Sounds pretty good to me. You are right: The code size impact is rather
small. I will apply your suggestions and send you another patch as soon
as I find the time to implement it (should be any time this week).

Thanks again!

Manuel



> Best regards,
> --
> Bartlomiej Zolnierkiewicz
> Samsung R&D Institute Poland
> Samsung Electronics
> 
> > Best regards,
> > --
> > Bartlomiej Zolnierkiewicz
> > Samsung R&D Institute Poland
> > Samsung Electronics
> > 
> > On Thursday, January 05, 2017 12:33:20 PM Manuel Schölling wrote:
> > > Add a scrollback buffers for each VGA console. The benefit is
> > > that
> > > the scrollback history is not flushed when switching between
> > > consoles
> > > but is persistent.
> > > The buffers are allocated on demand when a new console is opened.
> > > 
> > > This breaks tools like clear_console that rely on flushing the
> > > scrollback history by switching back and forth between consoles
> > > which is why this feature is disabled by default.
> > > Use the escape sequence \e[3J instead for flushing the buffer.
> > > 
> > > Signed-off-by: Manuel Schölling <manuel.schoelling@gmx.de>
> > > Reviewed-by: Andrey Utkin <andrey_utkin@fastmail.com>
> > > Tested-by: Andrey Utkin <andrey_utkin@fastmail.com>
> > > Tested-by: Adam Borowski <kilobyte@angband.pl>
> > > ---
> > >  drivers/video/console/Kconfig  |  25 +++++++-
> > >  drivers/video/console/vgacon.c | 142 ++++++++++++++++++++++++++-
> > > --------------
> > >  2 files changed, 111 insertions(+), 56 deletions(-)
> > > 
> > > diff --git a/drivers/video/console/Kconfig
> > > b/drivers/video/console/Kconfig
> > > index c3f1fb9ee820..f500e58f7636 100644
> > > --- a/drivers/video/console/Kconfig
> > > +++ b/drivers/video/console/Kconfig
> > > @@ -43,9 +43,28 @@ config VGACON_SOFT_SCROLLBACK_SIZE
> > >         range 1 1024
> > >         default "64"
> > >         help
> > > -         Enter the amount of System RAM to allocate for the
> > > scrollback
> > > -	 buffer.  Each 64KB will give you approximately 16 80x25
> > > -	 screenfuls of scrollback buffer
> > > +	  Enter the amount of System RAM to allocate for
> > > scrollback
> > > +	  buffers of VGA consoles. Each 64KB will give you
> > > approximately
> > > +	  16 80x25 screenfuls of scrollback buffer.
> > > +
> > > +config VGACON_SOFT_SCROLLBACK_PERSISTENT
> > > +	bool "Persistent Scrollback History for each console"
> > > +	depends on VGACON_SOFT_SCROLLBACK
> > > +	default n
> > > +	help
> > > +	  Say Y here if the scrollback history should persist
> > > when switching
> > > +	  between consoles. Otherwise, the scrollback history
> > > will be flushed
> > > +	  each time the console is switched.
> > > +
> > > +	  This feature might break your tool of choice to flush
> > > the scrollback
> > > +	  buffer, e.g. clear(1) will work fine but Debian's
> > > clear_console(1)
> > > +	  will be broken, which might cause security issues.
> > > +	  You can use the escape sequence \e[3J instead if this
> > > feature is
> > > +	  activated.
> > > +
> > > +	  Note that a buffer of VGACON_SOFT_SCROLLBACK_SIZE is
> > > taken for each
> > > +	  created tty device.
> > > +	  So if you use a RAM-constrained system, say N here.
> > >  
> > >  config MDA_CONSOLE
> > >  	depends on !M68K && !PARISC && ISA
> > > diff --git a/drivers/video/console/vgacon.c
> > > b/drivers/video/console/vgacon.c
> > > index 9a7c2bbc5326..ca23d222e029 100644
> > > --- a/drivers/video/console/vgacon.c
> > > +++ b/drivers/video/console/vgacon.c
> > > @@ -162,7 +162,7 @@ static inline void vga_set_mem_top(struct
> > > vc_data *c)
> > >  
> > >  #ifdef CONFIG_VGACON_SOFT_SCROLLBACK
> > >  /* software scrollback */
> > > -static struct vgacon_scrollback_info {
> > > +struct vgacon_scrollback_info {
> > >  	void *data;
> > >  	int tail;
> > >  	int size;
> > > @@ -171,74 +171,110 @@ static struct vgacon_scrollback_info {
> > >  	int cur;
> > >  	int save;
> > >  	int restore;
> > > -} vgacon_scrollback;
> > > +};
> > > +
> > > +static struct vgacon_scrollback_info *vgacon_scrollback_cur;
> > > +#ifdef CONFIG_VGACON_SOFT_SCROLLBACK_PERSISTENT
> > > +static struct vgacon_scrollback_info
> > > vgacon_scrollbacks[MAX_NR_CONSOLES];
> > > +#else
> > > +static struct vgacon_scrollback_info vgacon_scrollbacks[1];
> > > +#endif
> > >  
> > > -static void vgacon_scrollback_reset(size_t reset_size)
> > > +static void vgacon_scrollback_reset(int vc_num, size_t
> > > reset_size)
> > >  {
> > > -	if (vgacon_scrollback.data && reset_size > 0)
> > > -		memset(vgacon_scrollback.data, 0, reset_size);
> > > +	struct vgacon_scrollback_info *scrollback =
> > > &vgacon_scrollbacks[vc_num];
> > > +
> > > +	if (scrollback->data && reset_size > 0)
> > > +		memset(scrollback->data, 0, reset_size);
> > >  
> > > -	vgacon_scrollback.cnt  = 0;
> > > -	vgacon_scrollback.tail = 0;
> > > -	vgacon_scrollback.cur  = 0;
> > > +	scrollback->cnt  = 0;
> > > +	scrollback->tail = 0;
> > > +	scrollback->cur  = 0;
> > >  }
> > >  
> > > -static void vgacon_scrollback_init(int pitch)
> > > +static void vgacon_scrollback_init(int vc_num)
> > >  {
> > > -	int rows = CONFIG_VGACON_SOFT_SCROLLBACK_SIZE *
> > > 1024/pitch;
> > > -
> > > -	if (vgacon_scrollback.data) {
> > > -		vgacon_scrollback.cnt  = 0;
> > > -		vgacon_scrollback.tail = 0;
> > > -		vgacon_scrollback.cur  = 0;
> > > -		vgacon_scrollback.rows = rows - 1;
> > > -		vgacon_scrollback.size = rows * pitch;
> > > +	int pitch = vga_video_num_columns * 2;
> > > +	size_t size = CONFIG_VGACON_SOFT_SCROLLBACK_SIZE * 1024;
> > > +	int rows = size / pitch;
> > > +	void *data;
> > > +
> > > +	data = kmalloc_array(CONFIG_VGACON_SOFT_SCROLLBACK_SIZE,
> > > 1024,
> > > +			     GFP_NOWAIT);
> > > +
> > > +	vgacon_scrollbacks[vc_num].data = data;
> > > +	vgacon_scrollback_cur = &vgacon_scrollbacks[vc_num];
> > > +
> > > +	vgacon_scrollback_cur->rows = rows - 1;
> > > +	vgacon_scrollback_cur->size = rows * pitch;
> > > +
> > > +	vgacon_scrollback_reset(vc_num, size);
> > > +}
> > > +
> > > +static void vgacon_scrollback_switch(int vc_num)
> > > +{
> > > +#ifndef CONFIG_VGACON_SOFT_SCROLLBACK_PERSISTENT
> > > +	vc_num = 0;
> > > +#endif
> > > +
> > > +	if (!vgacon_scrollbacks[vc_num].data) {
> > > +		vgacon_scrollback_init(vc_num);
> > > +	} else {
> > > +#ifdef CONFIG_VGACON_SOFT_SCROLLBACK_PERSISTENT
> > > +		vgacon_scrollback_cur =
> > > &vgacon_scrollbacks[vc_num];
> > > +#else
> > > +		size_t size = CONFIG_VGACON_SOFT_SCROLLBACK_SIZE
> > > * 1024;
> > > +
> > > +		vgacon_scrollback_reset(vc_num, size);
> > > +#endif
> > >  	}
> > >  }
> > >  
> > >  static void vgacon_scrollback_startup(void)
> > >  {
> > > -	vgacon_scrollback.data =
> > > kcalloc(CONFIG_VGACON_SOFT_SCROLLBACK_SIZE,
> > > -		1024, GFP_NOWAIT);
> > > -	vgacon_scrollback_init(vga_video_num_columns * 2);
> > > +	vgacon_scrollback_cur = &vgacon_scrollbacks[0];
> > > +	vgacon_scrollback_init(0);
> > >  }
> > >  
> > >  static void vgacon_scrollback_update(struct vc_data *c, int t,
> > > int count)
> > >  {
> > >  	void *p;
> > >  
> > > -	if (!vgacon_scrollback.size || c->vc_num != fg_console)
> > > +	if (!vgacon_scrollback_cur->data ||
> > > !vgacon_scrollback_cur->size ||
> > > +	    c->vc_num != fg_console)
> > >  		return;
> > >  
> > >  	p = (void *) (c->vc_origin + t * c->vc_size_row);
> > >  
> > >  	while (count--) {
> > > -		scr_memcpyw(vgacon_scrollback.data +
> > > vgacon_scrollback.tail,
> > > +		scr_memcpyw(vgacon_scrollback_cur->data +
> > > +			    vgacon_scrollback_cur->tail,
> > >  			    p, c->vc_size_row);
> > > -		vgacon_scrollback.cnt++;
> > > +
> > > +		vgacon_scrollback_cur->cnt++;
> > >  		p += c->vc_size_row;
> > > -		vgacon_scrollback.tail += c->vc_size_row;
> > > +		vgacon_scrollback_cur->tail += c->vc_size_row;
> > >  
> > > -		if (vgacon_scrollback.tail >=
> > > vgacon_scrollback.size)
> > > -			vgacon_scrollback.tail = 0;
> > > +		if (vgacon_scrollback_cur->tail >=
> > > vgacon_scrollback_cur->size)
> > > +			vgacon_scrollback_cur->tail = 0;
> > >  
> > > -		if (vgacon_scrollback.cnt >
> > > vgacon_scrollback.rows)
> > > -			vgacon_scrollback.cnt =
> > > vgacon_scrollback.rows;
> > > +		if (vgacon_scrollback_cur->cnt >
> > > vgacon_scrollback_cur->rows)
> > > +			vgacon_scrollback_cur->cnt =
> > > vgacon_scrollback_cur->rows;
> > >  
> > > -		vgacon_scrollback.cur = vgacon_scrollback.cnt;
> > > +		vgacon_scrollback_cur->cur =
> > > vgacon_scrollback_cur->cnt;
> > >  	}
> > >  }
> > >  
> > >  static void vgacon_restore_screen(struct vc_data *c)
> > >  {
> > > -	vgacon_scrollback.save = 0;
> > > +	vgacon_scrollback_cur->save = 0;
> > >  
> > > -	if (!vga_is_gfx && !vgacon_scrollback.restore) {
> > > +	if (!vga_is_gfx && !vgacon_scrollback_cur->restore) {
> > >  		scr_memcpyw((u16 *) c->vc_origin, (u16 *) c-
> > > >vc_screenbuf,
> > >  			    c->vc_screenbuf_size > vga_vram_size
> > > ?
> > >  			    vga_vram_size : c-
> > > >vc_screenbuf_size);
> > > -		vgacon_scrollback.restore = 1;
> > > -		vgacon_scrollback.cur = vgacon_scrollback.cnt;
> > > +		vgacon_scrollback_cur->restore = 1;
> > > +		vgacon_scrollback_cur->cur =
> > > vgacon_scrollback_cur->cnt;
> > >  	}
> > >  }
> > >  
> > > @@ -252,41 +288,41 @@ static void vgacon_scrolldelta(struct
> > > vc_data *c, int lines)
> > >  		return;
> > >  	}
> > >  
> > > -	if (!vgacon_scrollback.data)
> > > +	if (!vgacon_scrollback_cur->data)
> > >  		return;
> > >  
> > > -	if (!vgacon_scrollback.save) {
> > > +	if (!vgacon_scrollback_cur->save) {
> > >  		vgacon_cursor(c, CM_ERASE);
> > >  		vgacon_save_screen(c);
> > > -		vgacon_scrollback.save = 1;
> > > +		vgacon_scrollback_cur->save = 1;
> > >  	}
> > >  
> > > -	vgacon_scrollback.restore = 0;
> > > -	start = vgacon_scrollback.cur + lines;
> > > +	vgacon_scrollback_cur->restore = 0;
> > > +	start = vgacon_scrollback_cur->cur + lines;
> > >  	end = start + abs(lines);
> > >  
> > >  	if (start < 0)
> > >  		start = 0;
> > >  
> > > -	if (start > vgacon_scrollback.cnt)
> > > -		start = vgacon_scrollback.cnt;
> > > +	if (start > vgacon_scrollback_cur->cnt)
> > > +		start = vgacon_scrollback_cur->cnt;
> > >  
> > >  	if (end < 0)
> > >  		end = 0;
> > >  
> > > -	if (end > vgacon_scrollback.cnt)
> > > -		end = vgacon_scrollback.cnt;
> > > +	if (end > vgacon_scrollback_cur->cnt)
> > > +		end = vgacon_scrollback_cur->cnt;
> > >  
> > > -	vgacon_scrollback.cur = start;
> > > +	vgacon_scrollback_cur->cur = start;
> > >  	count = end - start;
> > > -	soff = vgacon_scrollback.tail - ((vgacon_scrollback.cnt
> > > - end) *
> > > -					 c->vc_size_row);
> > > +	soff = vgacon_scrollback_cur->tail -
> > > +		((vgacon_scrollback_cur->cnt - end) * c-
> > > >vc_size_row);
> > >  	soff -= count * c->vc_size_row;
> > >  
> > >  	if (soff < 0)
> > > -		soff += vgacon_scrollback.size;
> > > +		soff += vgacon_scrollback_cur->size;
> > >  
> > > -	count = vgacon_scrollback.cnt - start;
> > > +	count = vgacon_scrollback_cur->cnt - start;
> > >  
> > >  	if (count > c->vc_rows)
> > >  		count = c->vc_rows;
> > > @@ -300,13 +336,13 @@ static void vgacon_scrolldelta(struct
> > > vc_data *c, int lines)
> > >  
> > >  		count *= c->vc_size_row;
> > >  		/* how much memory to end of buffer left? */
> > > -		copysize = min(count, vgacon_scrollback.size -
> > > soff);
> > > -		scr_memcpyw(d, vgacon_scrollback.data + soff,
> > > copysize);
> > > +		copysize = min(count, vgacon_scrollback_cur-
> > > >size - soff);
> > > +		scr_memcpyw(d, vgacon_scrollback_cur->data +
> > > soff, copysize);
> > >  		d += copysize;
> > >  		count -= copysize;
> > >  
> > >  		if (count) {
> > > -			scr_memcpyw(d, vgacon_scrollback.data,
> > > count);
> > > +			scr_memcpyw(d, vgacon_scrollback_cur-
> > > >data, count);
> > >  			d += count;
> > >  		}
> > >  
> > > @@ -320,13 +356,13 @@ static void vgacon_flush_scrollback(struct
> > > vc_data *c)
> > >  {
> > >  	size_t size = CONFIG_VGACON_SOFT_SCROLLBACK_SIZE * 1024;
> > >  
> > > -	if (c->vc_num == fg_console)
> > > -		vgacon_scrollback_reset(size);
> > > +	vgacon_scrollback_reset(c->vc_num, size);
> > >  }
> > >  #else
> > >  #define vgacon_scrollback_startup(...) do { } while (0)
> > >  #define vgacon_scrollback_init(...)    do { } while (0)
> > >  #define vgacon_scrollback_update(...)  do { } while (0)
> > > +#define vgacon_scrollback_switch(...)  do { } while (0)
> > >  
> > >  static void vgacon_restore_screen(struct vc_data *c)
> > >  {
> > > @@ -805,7 +841,7 @@ static int vgacon_switch(struct vc_data *c)
> > >  			vgacon_doresize(c, c->vc_cols, c-
> > > >vc_rows);
> > >  	}
> > >  
> > > -	vgacon_scrollback_init(c->vc_size_row);
> > > +	vgacon_scrollback_switch(c->vc_num);
> > >  	return 0;		/* Redrawing not needed */
> > >  }
> 
> 

^ permalink raw reply	[flat|nested] 62+ messages in thread

* [PATCH v9 0/4] console: Add persistent scrollback buffers for all VGA consoles
  2017-01-10 16:44             ` Bartlomiej Zolnierkiewicz
  2017-01-10 17:31               ` Manuel Schölling
@ 2017-01-10 21:28               ` Manuel Schölling
  2017-01-10 21:28               ` [PATCH v9 1/4] console: Move scrollback data into its own struct Manuel Schölling
                                 ` (3 subsequent siblings)
  5 siblings, 0 replies; 62+ messages in thread
From: Manuel Schölling @ 2017-01-10 21:28 UTC (permalink / raw)
  To: gregkh
  Cc: jslaby, kilobyte, lkml14, rdunlap, shorne, andrey_utkin, akpm,
	paul.burton, daniel.vetter, tj, hdegoede, linux-kernel,
	linux-fbdev, Manuel Schölling

--
Changes in v9:
  - Make persistent scrollback feature a boot parameter
Changes in v8:
  - Add Reviewed-by/Tested-By statements
Changes in v7:
  - Add new callback to consw struct for flushing video console driver's
    scrollback buffer. Fixes issues with escape sequence '\e[3J' reported
    by Adam Borowski (kilobyte@angband.pl).
  - Fix style issues
Changes in v6:
  - Change of check if feature is enabled in 
    vgacon_scrollback_switch()
Changes in v5:
  - Clearify documentation
  - Skip superfluous array initialization
  - Disable scrollback if buffer allocation fails
  - Refactor vgacon_switch_scrollback()
  - Rename vgacon_switch_scrollback() to vgacon_scrollback_switch()
  - Add check for fg_console in vgacon_scrollback_update
Changes in v4.1:
  - Fix compiler error
Changes in v4:
  - Rename from VGACON_SOFT_SCROLLBACK_FOR_EACH_CONSOLE to
    VGACON_SOFT_SCROLLBACK_PERSISTENT
  - Split into two patches
  - Rework documentation
  - Remove cosmetic changes in comments (postponed)
Changes in v3:
  - Add config option for this feature
  - Fallback to old scrollback buffer if kcalloc() fails
  - Remove ioctl() call again and add documentation about existing
    escape sequence to flush the scrollback buffer
Changes in v2:
  - Add ioctl() call to flush scrollback buffer
  - (Patch v2 was not labeled as such, sorry)

Manuel Schölling (3):
  console: Move scrollback data into its own struct
  console: Add callback to flush scrollback buffer to consw struct
  console: Add persistent scrollback buffers for all VGA consoles

 drivers/tty/vt/vt.c            |   9 +++
 drivers/video/console/Kconfig  |  25 ++++++-
 drivers/video/console/vgacon.c | 165 ++++++++++++++++++++++++++++-------------
 include/linux/console.h        |   4 +
 4 files changed, 148 insertions(+), 55 deletions(-)

-- 
2.11.0

^ permalink raw reply	[flat|nested] 62+ messages in thread

* [PATCH v9 1/4] console: Move scrollback data into its own struct
  2017-01-10 16:44             ` Bartlomiej Zolnierkiewicz
  2017-01-10 17:31               ` Manuel Schölling
  2017-01-10 21:28               ` [PATCH v9 0/4] " Manuel Schölling
@ 2017-01-10 21:28               ` Manuel Schölling
  2017-01-10 21:28               ` [PATCH v9 2/4] console: Add callback to flush scrollback buffer to consw struct Manuel Schölling
                                 ` (2 subsequent siblings)
  5 siblings, 0 replies; 62+ messages in thread
From: Manuel Schölling @ 2017-01-10 21:28 UTC (permalink / raw)
  To: gregkh
  Cc: jslaby, kilobyte, lkml14, rdunlap, shorne, andrey_utkin, akpm,
	paul.burton, daniel.vetter, tj, hdegoede, linux-kernel,
	linux-fbdev, Manuel Schölling

This refactoring is in preparation for persistent scrollback
support for VGA console.

Signed-off-by: Manuel Schölling <manuel.schoelling@gmx.de>
Reviewed-by: Andrey Utkin <andrey_utkin@fastmail.com>
Tested-by: Andrey Utkin <andrey_utkin@fastmail.com>
Tested-by: Adam Borowski <kilobyte@angband.pl>
---
 drivers/video/console/vgacon.c | 91 ++++++++++++++++++++++--------------------
 1 file changed, 47 insertions(+), 44 deletions(-)

diff --git a/drivers/video/console/vgacon.c b/drivers/video/console/vgacon.c
index c22a56232b7c..48b97648d4af 100644
--- a/drivers/video/console/vgacon.c
+++ b/drivers/video/console/vgacon.c
@@ -162,31 +162,34 @@ static inline void vga_set_mem_top(struct vc_data *c)
 
 #ifdef CONFIG_VGACON_SOFT_SCROLLBACK
 /* software scrollback */
-static void *vgacon_scrollback;
-static int vgacon_scrollback_tail;
-static int vgacon_scrollback_size;
-static int vgacon_scrollback_rows;
-static int vgacon_scrollback_cnt;
-static int vgacon_scrollback_cur;
-static int vgacon_scrollback_save;
-static int vgacon_scrollback_restore;
+static struct vgacon_scrollback_info {
+	void *data;
+	int tail;
+	int size;
+	int rows;
+	int cnt;
+	int cur;
+	int save;
+	int restore;
+} vgacon_scrollback;
 
 static void vgacon_scrollback_init(int pitch)
 {
 	int rows = CONFIG_VGACON_SOFT_SCROLLBACK_SIZE * 1024/pitch;
 
-	if (vgacon_scrollback) {
-		vgacon_scrollback_cnt  = 0;
-		vgacon_scrollback_tail = 0;
-		vgacon_scrollback_cur  = 0;
-		vgacon_scrollback_rows = rows - 1;
-		vgacon_scrollback_size = rows * pitch;
+	if (vgacon_scrollback.data) {
+		vgacon_scrollback.cnt  = 0;
+		vgacon_scrollback.tail = 0;
+		vgacon_scrollback.cur  = 0;
+		vgacon_scrollback.rows = rows - 1;
+		vgacon_scrollback.size = rows * pitch;
 	}
 }
 
 static void vgacon_scrollback_startup(void)
 {
-	vgacon_scrollback = kcalloc(CONFIG_VGACON_SOFT_SCROLLBACK_SIZE, 1024, GFP_NOWAIT);
+	vgacon_scrollback.data = kcalloc(CONFIG_VGACON_SOFT_SCROLLBACK_SIZE,
+		1024, GFP_NOWAIT);
 	vgacon_scrollback_init(vga_video_num_columns * 2);
 }
 
@@ -194,38 +197,38 @@ static void vgacon_scrollback_update(struct vc_data *c, int t, int count)
 {
 	void *p;
 
-	if (!vgacon_scrollback_size || c->vc_num != fg_console)
+	if (!vgacon_scrollback.size || c->vc_num != fg_console)
 		return;
 
 	p = (void *) (c->vc_origin + t * c->vc_size_row);
 
 	while (count--) {
-		scr_memcpyw(vgacon_scrollback + vgacon_scrollback_tail,
+		scr_memcpyw(vgacon_scrollback.data + vgacon_scrollback.tail,
 			    p, c->vc_size_row);
-		vgacon_scrollback_cnt++;
+		vgacon_scrollback.cnt++;
 		p += c->vc_size_row;
-		vgacon_scrollback_tail += c->vc_size_row;
+		vgacon_scrollback.tail += c->vc_size_row;
 
-		if (vgacon_scrollback_tail >= vgacon_scrollback_size)
-			vgacon_scrollback_tail = 0;
+		if (vgacon_scrollback.tail >= vgacon_scrollback.size)
+			vgacon_scrollback.tail = 0;
 
-		if (vgacon_scrollback_cnt > vgacon_scrollback_rows)
-			vgacon_scrollback_cnt = vgacon_scrollback_rows;
+		if (vgacon_scrollback.cnt > vgacon_scrollback.rows)
+			vgacon_scrollback.cnt = vgacon_scrollback.rows;
 
-		vgacon_scrollback_cur = vgacon_scrollback_cnt;
+		vgacon_scrollback.cur = vgacon_scrollback.cnt;
 	}
 }
 
 static void vgacon_restore_screen(struct vc_data *c)
 {
-	vgacon_scrollback_save = 0;
+	vgacon_scrollback.save = 0;
 
-	if (!vga_is_gfx && !vgacon_scrollback_restore) {
+	if (!vga_is_gfx && !vgacon_scrollback.restore) {
 		scr_memcpyw((u16 *) c->vc_origin, (u16 *) c->vc_screenbuf,
 			    c->vc_screenbuf_size > vga_vram_size ?
 			    vga_vram_size : c->vc_screenbuf_size);
-		vgacon_scrollback_restore = 1;
-		vgacon_scrollback_cur = vgacon_scrollback_cnt;
+		vgacon_scrollback.restore = 1;
+		vgacon_scrollback.cur = vgacon_scrollback.cnt;
 	}
 }
 
@@ -239,41 +242,41 @@ static void vgacon_scrolldelta(struct vc_data *c, int lines)
 		return;
 	}
 
-	if (!vgacon_scrollback)
+	if (!vgacon_scrollback.data)
 		return;
 
-	if (!vgacon_scrollback_save) {
+	if (!vgacon_scrollback.save) {
 		vgacon_cursor(c, CM_ERASE);
 		vgacon_save_screen(c);
-		vgacon_scrollback_save = 1;
+		vgacon_scrollback.save = 1;
 	}
 
-	vgacon_scrollback_restore = 0;
-	start = vgacon_scrollback_cur + lines;
+	vgacon_scrollback.restore = 0;
+	start = vgacon_scrollback.cur + lines;
 	end = start + abs(lines);
 
 	if (start < 0)
 		start = 0;
 
-	if (start > vgacon_scrollback_cnt)
-		start = vgacon_scrollback_cnt;
+	if (start > vgacon_scrollback.cnt)
+		start = vgacon_scrollback.cnt;
 
 	if (end < 0)
 		end = 0;
 
-	if (end > vgacon_scrollback_cnt)
-		end = vgacon_scrollback_cnt;
+	if (end > vgacon_scrollback.cnt)
+		end = vgacon_scrollback.cnt;
 
-	vgacon_scrollback_cur = start;
+	vgacon_scrollback.cur = start;
 	count = end - start;
-	soff = vgacon_scrollback_tail - ((vgacon_scrollback_cnt - end) *
+	soff = vgacon_scrollback.tail - ((vgacon_scrollback.cnt - end) *
 					 c->vc_size_row);
 	soff -= count * c->vc_size_row;
 
 	if (soff < 0)
-		soff += vgacon_scrollback_size;
+		soff += vgacon_scrollback.size;
 
-	count = vgacon_scrollback_cnt - start;
+	count = vgacon_scrollback.cnt - start;
 
 	if (count > c->vc_rows)
 		count = c->vc_rows;
@@ -287,13 +290,13 @@ static void vgacon_scrolldelta(struct vc_data *c, int lines)
 
 		count *= c->vc_size_row;
 		/* how much memory to end of buffer left? */
-		copysize = min(count, vgacon_scrollback_size - soff);
-		scr_memcpyw(d, vgacon_scrollback + soff, copysize);
+		copysize = min(count, vgacon_scrollback.size - soff);
+		scr_memcpyw(d, vgacon_scrollback.data + soff, copysize);
 		d += copysize;
 		count -= copysize;
 
 		if (count) {
-			scr_memcpyw(d, vgacon_scrollback, count);
+			scr_memcpyw(d, vgacon_scrollback.data, count);
 			d += count;
 		}
 
-- 
2.11.0

^ permalink raw reply	[flat|nested] 62+ messages in thread

* [PATCH v9 2/4] console: Add callback to flush scrollback buffer to consw struct
  2017-01-10 16:44             ` Bartlomiej Zolnierkiewicz
                                 ` (2 preceding siblings ...)
  2017-01-10 21:28               ` [PATCH v9 1/4] console: Move scrollback data into its own struct Manuel Schölling
@ 2017-01-10 21:28               ` Manuel Schölling
  2017-01-10 21:28               ` [PATCH v9 3/4] console: Add persistent scrollback buffers for all VGA consoles Manuel Schölling
  2017-01-10 21:28               ` [PATCH v9 4/4] console: Make persistent scrollback a boot parameter Manuel Schölling
  5 siblings, 0 replies; 62+ messages in thread
From: Manuel Schölling @ 2017-01-10 21:28 UTC (permalink / raw)
  To: gregkh
  Cc: jslaby, kilobyte, lkml14, rdunlap, shorne, andrey_utkin, akpm,
	paul.burton, daniel.vetter, tj, hdegoede, linux-kernel,
	linux-fbdev, Manuel Schölling

This new callback is in preparation for persistent scrollback buffer
support for VGA consoles.
With a single scrollback buffer for all consoles, we could flush the
buffer just by invocating consw->con_switch(). But when each VGA console
has its own scrollback buffer, we need a new callback to tell the
video console driver which buffer to flush.

Signed-off-by: Manuel Schölling <manuel.schoelling@gmx.de>
Reviewed-by: Andrey Utkin <andrey_utkin@fastmail.com>
Tested-by: Andrey Utkin <andrey_utkin@fastmail.com>
Tested-by: Adam Borowski <kilobyte@angband.pl>
---
 drivers/tty/vt/vt.c            |  9 +++++++++
 drivers/video/console/vgacon.c | 24 +++++++++++++++++++++++-
 include/linux/console.h        |  4 ++++
 3 files changed, 36 insertions(+), 1 deletion(-)

diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c
index 4c10a9df3b91..9d3ce505e7ab 100644
--- a/drivers/tty/vt/vt.c
+++ b/drivers/tty/vt/vt.c
@@ -625,6 +625,14 @@ static void save_screen(struct vc_data *vc)
 		vc->vc_sw->con_save_screen(vc);
 }
 
+static void flush_scrollback(struct vc_data *vc)
+{
+	WARN_CONSOLE_UNLOCKED();
+
+	if (vc->vc_sw->con_flush_scrollback)
+		vc->vc_sw->con_flush_scrollback(vc);
+}
+
 /*
  *	Redrawing of screen
  */
@@ -1171,6 +1179,7 @@ static void csi_J(struct vc_data *vc, int vpar)
 		case 3: /* erase scroll-back buffer (and whole display) */
 			scr_memsetw(vc->vc_screenbuf, vc->vc_video_erase_char,
 				    vc->vc_screenbuf_size);
+			flush_scrollback(vc);
 			set_origin(vc);
 			if (con_is_visible(vc))
 				update_screen(vc);
diff --git a/drivers/video/console/vgacon.c b/drivers/video/console/vgacon.c
index 48b97648d4af..9a7c2bbc5326 100644
--- a/drivers/video/console/vgacon.c
+++ b/drivers/video/console/vgacon.c
@@ -173,6 +173,16 @@ static struct vgacon_scrollback_info {
 	int restore;
 } vgacon_scrollback;
 
+static void vgacon_scrollback_reset(size_t reset_size)
+{
+	if (vgacon_scrollback.data && reset_size > 0)
+		memset(vgacon_scrollback.data, 0, reset_size);
+
+	vgacon_scrollback.cnt  = 0;
+	vgacon_scrollback.tail = 0;
+	vgacon_scrollback.cur  = 0;
+}
+
 static void vgacon_scrollback_init(int pitch)
 {
 	int rows = CONFIG_VGACON_SOFT_SCROLLBACK_SIZE * 1024/pitch;
@@ -305,6 +315,14 @@ static void vgacon_scrolldelta(struct vc_data *c, int lines)
 	} else
 		vgacon_cursor(c, CM_MOVE);
 }
+
+static void vgacon_flush_scrollback(struct vc_data *c)
+{
+	size_t size = CONFIG_VGACON_SOFT_SCROLLBACK_SIZE * 1024;
+
+	if (c->vc_num == fg_console)
+		vgacon_scrollback_reset(size);
+}
 #else
 #define vgacon_scrollback_startup(...) do { } while (0)
 #define vgacon_scrollback_init(...)    do { } while (0)
@@ -322,6 +340,10 @@ static void vgacon_scrolldelta(struct vc_data *c, int lines)
 			vga_vram_size);
 	vga_set_mem_top(c);
 }
+
+static void vgacon_flush_scrollback(struct vc_data *c)
+{
+}
 #endif /* CONFIG_VGACON_SOFT_SCROLLBACK */
 
 static const char *vgacon_startup(void)
@@ -1329,7 +1351,6 @@ static bool vgacon_scroll(struct vc_data *c, unsigned int t, unsigned int b,
 	return true;
 }
 
-
 /*
  *  The console `switch' structure for the VGA based console
  */
@@ -1362,6 +1383,7 @@ const struct consw vga_con = {
 	.con_save_screen = vgacon_save_screen,
 	.con_build_attr = vgacon_build_attr,
 	.con_invert_region = vgacon_invert_region,
+	.con_flush_scrollback = vgacon_flush_scrollback,
 };
 EXPORT_SYMBOL(vga_con);
 
diff --git a/include/linux/console.h b/include/linux/console.h
index 9c26c6685587..5949d1855589 100644
--- a/include/linux/console.h
+++ b/include/linux/console.h
@@ -73,6 +73,10 @@ struct consw {
 	u16    *(*con_screen_pos)(struct vc_data *, int);
 	unsigned long (*con_getxy)(struct vc_data *, unsigned long, int *, int *);
 	/*
+	 * Flush the video console driver's scrollback buffer
+	 */
+	void	(*con_flush_scrollback)(struct vc_data *);
+	/*
 	 * Prepare the console for the debugger.  This includes, but is not
 	 * limited to, unblanking the console, loading an appropriate
 	 * palette, and allowing debugger generated output.
-- 
2.11.0

^ permalink raw reply	[flat|nested] 62+ messages in thread

* [PATCH v9 3/4] console: Add persistent scrollback buffers for all VGA consoles
  2017-01-10 16:44             ` Bartlomiej Zolnierkiewicz
                                 ` (3 preceding siblings ...)
  2017-01-10 21:28               ` [PATCH v9 2/4] console: Add callback to flush scrollback buffer to consw struct Manuel Schölling
@ 2017-01-10 21:28               ` Manuel Schölling
  2017-01-10 21:28               ` [PATCH v9 4/4] console: Make persistent scrollback a boot parameter Manuel Schölling
  5 siblings, 0 replies; 62+ messages in thread
From: Manuel Schölling @ 2017-01-10 21:28 UTC (permalink / raw)
  To: gregkh
  Cc: jslaby, kilobyte, lkml14, rdunlap, shorne, andrey_utkin, akpm,
	paul.burton, daniel.vetter, tj, hdegoede, linux-kernel,
	linux-fbdev, Manuel Schölling

Add a scrollback buffers for each VGA console. The benefit is that
the scrollback history is not flushed when switching between consoles
but is persistent.
The buffers are allocated on demand when a new console is opened.

This breaks tools like clear_console that rely on flushing the
scrollback history by switching back and forth between consoles
which is why this feature is disabled by default.
Use the escape sequence \e[3J instead for flushing the buffer.

Signed-off-by: Manuel Schölling <manuel.schoelling@gmx.de>
Reviewed-by: Andrey Utkin <andrey_utkin@fastmail.com>
Tested-by: Andrey Utkin <andrey_utkin@fastmail.com>
Tested-by: Adam Borowski <kilobyte@angband.pl>
---
 drivers/video/console/Kconfig  |  25 +++++++-
 drivers/video/console/vgacon.c | 142 ++++++++++++++++++++++++++---------------
 2 files changed, 111 insertions(+), 56 deletions(-)

diff --git a/drivers/video/console/Kconfig b/drivers/video/console/Kconfig
index c3f1fb9ee820..f500e58f7636 100644
--- a/drivers/video/console/Kconfig
+++ b/drivers/video/console/Kconfig
@@ -43,9 +43,28 @@ config VGACON_SOFT_SCROLLBACK_SIZE
        range 1 1024
        default "64"
        help
-         Enter the amount of System RAM to allocate for the scrollback
-	 buffer.  Each 64KB will give you approximately 16 80x25
-	 screenfuls of scrollback buffer
+	  Enter the amount of System RAM to allocate for scrollback
+	  buffers of VGA consoles. Each 64KB will give you approximately
+	  16 80x25 screenfuls of scrollback buffer.
+
+config VGACON_SOFT_SCROLLBACK_PERSISTENT
+	bool "Persistent Scrollback History for each console"
+	depends on VGACON_SOFT_SCROLLBACK
+	default n
+	help
+	  Say Y here if the scrollback history should persist when switching
+	  between consoles. Otherwise, the scrollback history will be flushed
+	  each time the console is switched.
+
+	  This feature might break your tool of choice to flush the scrollback
+	  buffer, e.g. clear(1) will work fine but Debian's clear_console(1)
+	  will be broken, which might cause security issues.
+	  You can use the escape sequence \e[3J instead if this feature is
+	  activated.
+
+	  Note that a buffer of VGACON_SOFT_SCROLLBACK_SIZE is taken for each
+	  created tty device.
+	  So if you use a RAM-constrained system, say N here.
 
 config MDA_CONSOLE
 	depends on !M68K && !PARISC && ISA
diff --git a/drivers/video/console/vgacon.c b/drivers/video/console/vgacon.c
index 9a7c2bbc5326..ca23d222e029 100644
--- a/drivers/video/console/vgacon.c
+++ b/drivers/video/console/vgacon.c
@@ -162,7 +162,7 @@ static inline void vga_set_mem_top(struct vc_data *c)
 
 #ifdef CONFIG_VGACON_SOFT_SCROLLBACK
 /* software scrollback */
-static struct vgacon_scrollback_info {
+struct vgacon_scrollback_info {
 	void *data;
 	int tail;
 	int size;
@@ -171,74 +171,110 @@ static struct vgacon_scrollback_info {
 	int cur;
 	int save;
 	int restore;
-} vgacon_scrollback;
+};
+
+static struct vgacon_scrollback_info *vgacon_scrollback_cur;
+#ifdef CONFIG_VGACON_SOFT_SCROLLBACK_PERSISTENT
+static struct vgacon_scrollback_info vgacon_scrollbacks[MAX_NR_CONSOLES];
+#else
+static struct vgacon_scrollback_info vgacon_scrollbacks[1];
+#endif
 
-static void vgacon_scrollback_reset(size_t reset_size)
+static void vgacon_scrollback_reset(int vc_num, size_t reset_size)
 {
-	if (vgacon_scrollback.data && reset_size > 0)
-		memset(vgacon_scrollback.data, 0, reset_size);
+	struct vgacon_scrollback_info *scrollback = &vgacon_scrollbacks[vc_num];
+
+	if (scrollback->data && reset_size > 0)
+		memset(scrollback->data, 0, reset_size);
 
-	vgacon_scrollback.cnt  = 0;
-	vgacon_scrollback.tail = 0;
-	vgacon_scrollback.cur  = 0;
+	scrollback->cnt  = 0;
+	scrollback->tail = 0;
+	scrollback->cur  = 0;
 }
 
-static void vgacon_scrollback_init(int pitch)
+static void vgacon_scrollback_init(int vc_num)
 {
-	int rows = CONFIG_VGACON_SOFT_SCROLLBACK_SIZE * 1024/pitch;
-
-	if (vgacon_scrollback.data) {
-		vgacon_scrollback.cnt  = 0;
-		vgacon_scrollback.tail = 0;
-		vgacon_scrollback.cur  = 0;
-		vgacon_scrollback.rows = rows - 1;
-		vgacon_scrollback.size = rows * pitch;
+	int pitch = vga_video_num_columns * 2;
+	size_t size = CONFIG_VGACON_SOFT_SCROLLBACK_SIZE * 1024;
+	int rows = size / pitch;
+	void *data;
+
+	data = kmalloc_array(CONFIG_VGACON_SOFT_SCROLLBACK_SIZE, 1024,
+			     GFP_NOWAIT);
+
+	vgacon_scrollbacks[vc_num].data = data;
+	vgacon_scrollback_cur = &vgacon_scrollbacks[vc_num];
+
+	vgacon_scrollback_cur->rows = rows - 1;
+	vgacon_scrollback_cur->size = rows * pitch;
+
+	vgacon_scrollback_reset(vc_num, size);
+}
+
+static void vgacon_scrollback_switch(int vc_num)
+{
+#ifndef CONFIG_VGACON_SOFT_SCROLLBACK_PERSISTENT
+	vc_num = 0;
+#endif
+
+	if (!vgacon_scrollbacks[vc_num].data) {
+		vgacon_scrollback_init(vc_num);
+	} else {
+#ifdef CONFIG_VGACON_SOFT_SCROLLBACK_PERSISTENT
+		vgacon_scrollback_cur = &vgacon_scrollbacks[vc_num];
+#else
+		size_t size = CONFIG_VGACON_SOFT_SCROLLBACK_SIZE * 1024;
+
+		vgacon_scrollback_reset(vc_num, size);
+#endif
 	}
 }
 
 static void vgacon_scrollback_startup(void)
 {
-	vgacon_scrollback.data = kcalloc(CONFIG_VGACON_SOFT_SCROLLBACK_SIZE,
-		1024, GFP_NOWAIT);
-	vgacon_scrollback_init(vga_video_num_columns * 2);
+	vgacon_scrollback_cur = &vgacon_scrollbacks[0];
+	vgacon_scrollback_init(0);
 }
 
 static void vgacon_scrollback_update(struct vc_data *c, int t, int count)
 {
 	void *p;
 
-	if (!vgacon_scrollback.size || c->vc_num != fg_console)
+	if (!vgacon_scrollback_cur->data || !vgacon_scrollback_cur->size ||
+	    c->vc_num != fg_console)
 		return;
 
 	p = (void *) (c->vc_origin + t * c->vc_size_row);
 
 	while (count--) {
-		scr_memcpyw(vgacon_scrollback.data + vgacon_scrollback.tail,
+		scr_memcpyw(vgacon_scrollback_cur->data +
+			    vgacon_scrollback_cur->tail,
 			    p, c->vc_size_row);
-		vgacon_scrollback.cnt++;
+
+		vgacon_scrollback_cur->cnt++;
 		p += c->vc_size_row;
-		vgacon_scrollback.tail += c->vc_size_row;
+		vgacon_scrollback_cur->tail += c->vc_size_row;
 
-		if (vgacon_scrollback.tail >= vgacon_scrollback.size)
-			vgacon_scrollback.tail = 0;
+		if (vgacon_scrollback_cur->tail >= vgacon_scrollback_cur->size)
+			vgacon_scrollback_cur->tail = 0;
 
-		if (vgacon_scrollback.cnt > vgacon_scrollback.rows)
-			vgacon_scrollback.cnt = vgacon_scrollback.rows;
+		if (vgacon_scrollback_cur->cnt > vgacon_scrollback_cur->rows)
+			vgacon_scrollback_cur->cnt = vgacon_scrollback_cur->rows;
 
-		vgacon_scrollback.cur = vgacon_scrollback.cnt;
+		vgacon_scrollback_cur->cur = vgacon_scrollback_cur->cnt;
 	}
 }
 
 static void vgacon_restore_screen(struct vc_data *c)
 {
-	vgacon_scrollback.save = 0;
+	vgacon_scrollback_cur->save = 0;
 
-	if (!vga_is_gfx && !vgacon_scrollback.restore) {
+	if (!vga_is_gfx && !vgacon_scrollback_cur->restore) {
 		scr_memcpyw((u16 *) c->vc_origin, (u16 *) c->vc_screenbuf,
 			    c->vc_screenbuf_size > vga_vram_size ?
 			    vga_vram_size : c->vc_screenbuf_size);
-		vgacon_scrollback.restore = 1;
-		vgacon_scrollback.cur = vgacon_scrollback.cnt;
+		vgacon_scrollback_cur->restore = 1;
+		vgacon_scrollback_cur->cur = vgacon_scrollback_cur->cnt;
 	}
 }
 
@@ -252,41 +288,41 @@ static void vgacon_scrolldelta(struct vc_data *c, int lines)
 		return;
 	}
 
-	if (!vgacon_scrollback.data)
+	if (!vgacon_scrollback_cur->data)
 		return;
 
-	if (!vgacon_scrollback.save) {
+	if (!vgacon_scrollback_cur->save) {
 		vgacon_cursor(c, CM_ERASE);
 		vgacon_save_screen(c);
-		vgacon_scrollback.save = 1;
+		vgacon_scrollback_cur->save = 1;
 	}
 
-	vgacon_scrollback.restore = 0;
-	start = vgacon_scrollback.cur + lines;
+	vgacon_scrollback_cur->restore = 0;
+	start = vgacon_scrollback_cur->cur + lines;
 	end = start + abs(lines);
 
 	if (start < 0)
 		start = 0;
 
-	if (start > vgacon_scrollback.cnt)
-		start = vgacon_scrollback.cnt;
+	if (start > vgacon_scrollback_cur->cnt)
+		start = vgacon_scrollback_cur->cnt;
 
 	if (end < 0)
 		end = 0;
 
-	if (end > vgacon_scrollback.cnt)
-		end = vgacon_scrollback.cnt;
+	if (end > vgacon_scrollback_cur->cnt)
+		end = vgacon_scrollback_cur->cnt;
 
-	vgacon_scrollback.cur = start;
+	vgacon_scrollback_cur->cur = start;
 	count = end - start;
-	soff = vgacon_scrollback.tail - ((vgacon_scrollback.cnt - end) *
-					 c->vc_size_row);
+	soff = vgacon_scrollback_cur->tail -
+		((vgacon_scrollback_cur->cnt - end) * c->vc_size_row);
 	soff -= count * c->vc_size_row;
 
 	if (soff < 0)
-		soff += vgacon_scrollback.size;
+		soff += vgacon_scrollback_cur->size;
 
-	count = vgacon_scrollback.cnt - start;
+	count = vgacon_scrollback_cur->cnt - start;
 
 	if (count > c->vc_rows)
 		count = c->vc_rows;
@@ -300,13 +336,13 @@ static void vgacon_scrolldelta(struct vc_data *c, int lines)
 
 		count *= c->vc_size_row;
 		/* how much memory to end of buffer left? */
-		copysize = min(count, vgacon_scrollback.size - soff);
-		scr_memcpyw(d, vgacon_scrollback.data + soff, copysize);
+		copysize = min(count, vgacon_scrollback_cur->size - soff);
+		scr_memcpyw(d, vgacon_scrollback_cur->data + soff, copysize);
 		d += copysize;
 		count -= copysize;
 
 		if (count) {
-			scr_memcpyw(d, vgacon_scrollback.data, count);
+			scr_memcpyw(d, vgacon_scrollback_cur->data, count);
 			d += count;
 		}
 
@@ -320,13 +356,13 @@ static void vgacon_flush_scrollback(struct vc_data *c)
 {
 	size_t size = CONFIG_VGACON_SOFT_SCROLLBACK_SIZE * 1024;
 
-	if (c->vc_num == fg_console)
-		vgacon_scrollback_reset(size);
+	vgacon_scrollback_reset(c->vc_num, size);
 }
 #else
 #define vgacon_scrollback_startup(...) do { } while (0)
 #define vgacon_scrollback_init(...)    do { } while (0)
 #define vgacon_scrollback_update(...)  do { } while (0)
+#define vgacon_scrollback_switch(...)  do { } while (0)
 
 static void vgacon_restore_screen(struct vc_data *c)
 {
@@ -805,7 +841,7 @@ static int vgacon_switch(struct vc_data *c)
 			vgacon_doresize(c, c->vc_cols, c->vc_rows);
 	}
 
-	vgacon_scrollback_init(c->vc_size_row);
+	vgacon_scrollback_switch(c->vc_num);
 	return 0;		/* Redrawing not needed */
 }
 
-- 
2.11.0

^ permalink raw reply	[flat|nested] 62+ messages in thread

* [PATCH v9 4/4] console: Make persistent scrollback a boot parameter
  2017-01-10 16:44             ` Bartlomiej Zolnierkiewicz
                                 ` (4 preceding siblings ...)
  2017-01-10 21:28               ` [PATCH v9 3/4] console: Add persistent scrollback buffers for all VGA consoles Manuel Schölling
@ 2017-01-10 21:28               ` Manuel Schölling
  2017-01-10 22:58                 ` Adam Borowski
                                   ` (2 more replies)
  5 siblings, 3 replies; 62+ messages in thread
From: Manuel Schölling @ 2017-01-10 21:28 UTC (permalink / raw)
  To: gregkh
  Cc: jslaby, kilobyte, lkml14, rdunlap, shorne, andrey_utkin, akpm,
	paul.burton, daniel.vetter, tj, hdegoede, linux-kernel,
	linux-fbdev, Manuel Schölling

The impact of the persistent scrollback feature on the code size is
rather small, so the config option is removed. The feature stays
disabled by default and can be enabled by using the boot command line
parameter 'vgacon.scrollback_persistent=1' or by setting
VGACON_SOFT_SCROLLBACK_PERSISTENT_ENABLE_BY_DEFAULT=y.

Signed-off-by: Manuel Schölling <manuel.schoelling@gmx.de>
Suggested-by: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com>
---
 drivers/video/console/Kconfig  | 12 +++++++-----
 drivers/video/console/vgacon.c | 25 ++++++++++++-------------
 2 files changed, 19 insertions(+), 18 deletions(-)

diff --git a/drivers/video/console/Kconfig b/drivers/video/console/Kconfig
index f500e58f7636..5b71bd905a60 100644
--- a/drivers/video/console/Kconfig
+++ b/drivers/video/console/Kconfig
@@ -47,14 +47,16 @@ config VGACON_SOFT_SCROLLBACK_SIZE
 	  buffers of VGA consoles. Each 64KB will give you approximately
 	  16 80x25 screenfuls of scrollback buffer.
 
-config VGACON_SOFT_SCROLLBACK_PERSISTENT
-	bool "Persistent Scrollback History for each console"
+config VGACON_SOFT_SCROLLBACK_PERSISTENT_ENABLE_BY_DEFAULT
+	bool "Persistent Scrollback History for each console by default"
 	depends on VGACON_SOFT_SCROLLBACK
 	default n
 	help
-	  Say Y here if the scrollback history should persist when switching
-	  between consoles. Otherwise, the scrollback history will be flushed
-	  each time the console is switched.
+	  Say Y here if the scrollback history should persist by default when
+	  switching between consoles. Otherwise, the scrollback history will be
+	  flushed each time the console is switched. This feature can also be
+	  enabled using the boot command line parameter
+	  'vgacon.scrollback_persistent=1'.
 
 	  This feature might break your tool of choice to flush the scrollback
 	  buffer, e.g. clear(1) will work fine but Debian's clear_console(1)
diff --git a/drivers/video/console/vgacon.c b/drivers/video/console/vgacon.c
index ca23d222e029..45a76972495b 100644
--- a/drivers/video/console/vgacon.c
+++ b/drivers/video/console/vgacon.c
@@ -174,11 +174,9 @@ struct vgacon_scrollback_info {
 };
 
 static struct vgacon_scrollback_info *vgacon_scrollback_cur;
-#ifdef CONFIG_VGACON_SOFT_SCROLLBACK_PERSISTENT
 static struct vgacon_scrollback_info vgacon_scrollbacks[MAX_NR_CONSOLES];
-#else
-static struct vgacon_scrollback_info vgacon_scrollbacks[1];
-#endif
+static bool scrollback_persistent = \
+	IS_ENABLED(CONFIG_VGACON_SOFT_SCROLLBACK_PERSISTENT_ENABLE_BY_DEFAULT);
 
 static void vgacon_scrollback_reset(int vc_num, size_t reset_size)
 {
@@ -213,20 +211,19 @@ static void vgacon_scrollback_init(int vc_num)
 
 static void vgacon_scrollback_switch(int vc_num)
 {
-#ifndef CONFIG_VGACON_SOFT_SCROLLBACK_PERSISTENT
-	vc_num = 0;
-#endif
+	if (!scrollback_persistent)
+		vc_num = 0;
 
 	if (!vgacon_scrollbacks[vc_num].data) {
 		vgacon_scrollback_init(vc_num);
 	} else {
-#ifdef CONFIG_VGACON_SOFT_SCROLLBACK_PERSISTENT
-		vgacon_scrollback_cur = &vgacon_scrollbacks[vc_num];
-#else
-		size_t size = CONFIG_VGACON_SOFT_SCROLLBACK_SIZE * 1024;
+		if (scrollback_persistent) {
+			vgacon_scrollback_cur = &vgacon_scrollbacks[vc_num];
+		} else {
+			size_t size = CONFIG_VGACON_SOFT_SCROLLBACK_SIZE * 1024;
 
-		vgacon_scrollback_reset(vc_num, size);
-#endif
+			vgacon_scrollback_reset(vc_num, size);
+		}
 	}
 }
 
@@ -1423,4 +1420,6 @@ const struct consw vga_con = {
 };
 EXPORT_SYMBOL(vga_con);
 
+module_param_named(scrollback_persistent, scrollback_persistent, bool, 0000);
+MODULE_PARM_DESC(scrollback_persistent, "Enable persistent scrollback for all vga consoles");
 MODULE_LICENSE("GPL");
-- 
2.11.0

^ permalink raw reply	[flat|nested] 62+ messages in thread

* Re: [PATCH v9 4/4] console: Make persistent scrollback a boot parameter
  2017-01-10 21:28               ` [PATCH v9 4/4] console: Make persistent scrollback a boot parameter Manuel Schölling
@ 2017-01-10 22:58                 ` Adam Borowski
  2017-01-11 21:41                   ` Manuel Schölling
  2017-01-13 20:00                   ` Manuel Schölling
  2017-01-11 13:32                 ` kbuild test robot
  2017-02-02 20:07                 ` [PATCH v9 " Paul Gortmaker
  2 siblings, 2 replies; 62+ messages in thread
From: Adam Borowski @ 2017-01-10 22:58 UTC (permalink / raw)
  To: Manuel Schölling
  Cc: gregkh, jslaby, lkml14, rdunlap, shorne, andrey_utkin, akpm,
	paul.burton, daniel.vetter, tj, hdegoede, linux-kernel,
	linux-fbdev

On Tue, Jan 10, 2017 at 10:28:38PM +0100, Manuel Schölling wrote:
> The impact of the persistent scrollback feature on the code size is
> rather small, so the config option is removed. The feature stays
> disabled by default and can be enabled by using the boot command line
> parameter 'vgacon.scrollback_persistent=1' or by setting
> VGACON_SOFT_SCROLLBACK_PERSISTENT_ENABLE_BY_DEFAULT=y.
> 
> Signed-off-by: Manuel Schölling <manuel.schoelling@gmx.de>
> Suggested-by: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com>

> +module_param_named(scrollback_persistent, scrollback_persistent, bool, 0000);
> +MODULE_PARM_DESC(scrollback_persistent, "Enable persistent scrollback for all vga consoles");

A command-line knob settable by the end-user is something more persistent
than a config option.  As you're going to extend this code beyond vgacon in
the near future, perhaps it'd be better to have a shared setting for all
console drivers?


Meow!
-- 
Autotools hint: to do a zx-spectrum build on a pdp11 host, type:
  ./configure --host=zx-spectrum --build=pdp11

^ permalink raw reply	[flat|nested] 62+ messages in thread

* Re: [PATCH v9 4/4] console: Make persistent scrollback a boot parameter
  2017-01-10 21:28               ` [PATCH v9 4/4] console: Make persistent scrollback a boot parameter Manuel Schölling
  2017-01-10 22:58                 ` Adam Borowski
@ 2017-01-11 13:32                 ` kbuild test robot
  2017-01-13 20:07                   ` [PATCH v10 0/4] console: Add persistent scrollback buffers for all VGA consoles Manuel Schölling
                                     ` (4 more replies)
  2017-02-02 20:07                 ` [PATCH v9 " Paul Gortmaker
  2 siblings, 5 replies; 62+ messages in thread
From: kbuild test robot @ 2017-01-11 13:32 UTC (permalink / raw)
  To: Manuel Schölling
  Cc: kbuild-all, gregkh, jslaby, kilobyte, lkml14, rdunlap, shorne,
	andrey_utkin, akpm, paul.burton, daniel.vetter, tj, hdegoede,
	linux-kernel, linux-fbdev, Manuel Schölling

[-- Attachment #1: Type: text/plain, Size: 3974 bytes --]

Hi Manuel,

[auto build test ERROR on linus/master]
[also build test ERROR on v4.10-rc3 next-20170111]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]

url:    https://github.com/0day-ci/linux/commits/Manuel-Sch-lling/console-Add-persistent-scrollback-buffers-for-all-VGA-consoles/20170111-203640
config: i386-randconfig-x018-201702 (attached as .config)
compiler: gcc-6 (Debian 6.2.0-3) 6.2.0 20160901
reproduce:
        # save the attached .config to linux build tree
        make ARCH=i386 

All error/warnings (new ones prefixed by >>):

   In file included from include/linux/module.h:18:0,
                    from drivers/video/console/vgacon.c:36:
   drivers/video/console/vgacon.c: In function '__check_scrollback_persistent':
>> drivers/video/console/vgacon.c:1423:43: error: 'scrollback_persistent' undeclared (first use in this function)
    module_param_named(scrollback_persistent, scrollback_persistent, bool, 0000);
                                              ^
   include/linux/moduleparam.h:344:68: note: in definition of macro '__param_check'
     static inline type __always_unused *__check_##name(void) { return(p); }
                                                                       ^
   include/linux/moduleparam.h:146:2: note: in expansion of macro 'param_check_bool'
     param_check_##type(name, &(value));       \
     ^~~~~~~~~~~~
>> drivers/video/console/vgacon.c:1423:1: note: in expansion of macro 'module_param_named'
    module_param_named(scrollback_persistent, scrollback_persistent, bool, 0000);
    ^~~~~~~~~~~~~~~~~~
   drivers/video/console/vgacon.c:1423:43: note: each undeclared identifier is reported only once for each function it appears in
    module_param_named(scrollback_persistent, scrollback_persistent, bool, 0000);
                                              ^
   include/linux/moduleparam.h:344:68: note: in definition of macro '__param_check'
     static inline type __always_unused *__check_##name(void) { return(p); }
                                                                       ^
   include/linux/moduleparam.h:146:2: note: in expansion of macro 'param_check_bool'
     param_check_##type(name, &(value));       \
     ^~~~~~~~~~~~
>> drivers/video/console/vgacon.c:1423:1: note: in expansion of macro 'module_param_named'
    module_param_named(scrollback_persistent, scrollback_persistent, bool, 0000);
    ^~~~~~~~~~~~~~~~~~
   drivers/video/console/vgacon.c: At top level:
>> drivers/video/console/vgacon.c:1423:43: error: 'scrollback_persistent' undeclared here (not in a function)
    module_param_named(scrollback_persistent, scrollback_persistent, bool, 0000);
                                              ^
   include/linux/moduleparam.h:225:54: note: in definition of macro '__module_param_call'
         VERIFY_OCTAL_PERMISSIONS(perm), level, flags, { arg } }
                                                         ^~~
   include/linux/moduleparam.h:147:2: note: in expansion of macro 'module_param_cb'
     module_param_cb(name, &param_ops_##type, &value, perm);     \
     ^~~~~~~~~~~~~~~
>> drivers/video/console/vgacon.c:1423:1: note: in expansion of macro 'module_param_named'
    module_param_named(scrollback_persistent, scrollback_persistent, bool, 0000);
    ^~~~~~~~~~~~~~~~~~

vim +/scrollback_persistent +1423 drivers/video/console/vgacon.c

  1417		.con_build_attr = vgacon_build_attr,
  1418		.con_invert_region = vgacon_invert_region,
  1419		.con_flush_scrollback = vgacon_flush_scrollback,
  1420	};
  1421	EXPORT_SYMBOL(vga_con);
  1422	
> 1423	module_param_named(scrollback_persistent, scrollback_persistent, bool, 0000);
  1424	MODULE_PARM_DESC(scrollback_persistent, "Enable persistent scrollback for all vga consoles");
  1425	MODULE_LICENSE("GPL");

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation

[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 27586 bytes --]

^ permalink raw reply	[flat|nested] 62+ messages in thread

* Re: [PATCH v9 4/4] console: Make persistent scrollback a boot parameter
  2017-01-10 22:58                 ` Adam Borowski
@ 2017-01-11 21:41                   ` Manuel Schölling
  2017-01-13 20:00                   ` Manuel Schölling
  1 sibling, 0 replies; 62+ messages in thread
From: Manuel Schölling @ 2017-01-11 21:41 UTC (permalink / raw)
  To: Adam Borowski
  Cc: gregkh, jslaby, lkml14, rdunlap, shorne, andrey_utkin, akpm,
	paul.burton, daniel.vetter, tj, hdegoede, linux-kernel,
	linux-fbdev

On Tue, 2017-01-10 at 23:58 +0100, Adam Borowski wrote:
> On Tue, Jan 10, 2017 at 10:28:38PM +0100, Manuel Schölling wrote:
> > The impact of the persistent scrollback feature on the code size is
> > rather small, so the config option is removed. The feature stays
> > disabled by default and can be enabled by using the boot command
> > line
> > parameter 'vgacon.scrollback_persistent=1' or by setting
> > VGACON_SOFT_SCROLLBACK_PERSISTENT_ENABLE_BY_DEFAULT=y.
> > 
> > Signed-off-by: Manuel Schölling <manuel.schoelling@gmx.de>
> > Suggested-by: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com>
> > +module_param_named(scrollback_persistent, scrollback_persistent,
> > bool, 0000);
> > +MODULE_PARM_DESC(scrollback_persistent, "Enable persistent
> > scrollback for all vga consoles");
> 
> A command-line knob settable by the end-user is something more
> persistent
> than a config option.  As you're going to extend this code beyond
> vgacon in
> the near future, perhaps it'd be better to have a shared setting for
> all
> console drivers?
Probably a good idea, but I'm struggling with the implementation a bit:

I tried to run 

  if (strstr(boot_command_line, "nopersistentscrollback")) {...}

in vgacon_scrollback_startup() but I am getting 

  WARNING: modpost: Found 2 section mismatch(es).

when compiling. Probably because vgacon_scrollback_startup() is
executed after init.

I tried to find another way to implement a boot cmd line parameter but
had no luck.
If you/somebody could point me in the right direction, it would be very
much appreciated.

Thanks!

Manuel

^ permalink raw reply	[flat|nested] 62+ messages in thread

* Re: [PATCH v9 4/4] console: Make persistent scrollback a boot parameter
  2017-01-10 22:58                 ` Adam Borowski
  2017-01-11 21:41                   ` Manuel Schölling
@ 2017-01-13 20:00                   ` Manuel Schölling
  2017-01-14  7:26                     ` Greg KH
  1 sibling, 1 reply; 62+ messages in thread
From: Manuel Schölling @ 2017-01-13 20:00 UTC (permalink / raw)
  To: Adam Borowski
  Cc: gregkh, jslaby, lkml14, rdunlap, shorne, andrey_utkin, akpm,
	paul.burton, daniel.vetter, tj, hdegoede, linux-kernel,
	linux-fbdev

On Tue, 2017-01-10 at 23:58 +0100, Adam Borowski wrote:
> On Tue, Jan 10, 2017 at 10:28:38PM +0100, Manuel Schölling wrote:
> > The impact of the persistent scrollback feature on the code size is
> > rather small, so the config option is removed. The feature stays
> > disabled by default and can be enabled by using the boot command
> > line
> > parameter 'vgacon.scrollback_persistent=1' or by setting
> > VGACON_SOFT_SCROLLBACK_PERSISTENT_ENABLE_BY_DEFAULT=y.
> > 
> > Signed-off-by: Manuel Schölling <manuel.schoelling@gmx.de>
> > Suggested-by: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com>
> > +module_param_named(scrollback_persistent, scrollback_persistent,
> > bool, 0000);
> > +MODULE_PARM_DESC(scrollback_persistent, "Enable persistent
> > scrollback for all vga consoles");
> 
> A command-line knob settable by the end-user is something more
> persistent
> than a config option.  As you're going to extend this code beyond
> vgacon in
> the near future, perhaps it'd be better to have a shared setting for
> all
> console drivers?
According to the guys at #kernelnewbies on IRC everybody hates new
command line options.
I'd rather stick to the module parameter for now and maybe introduce a 
new cmd line option later, once this feature has been implemented in
several console drivers.

Bye,

Manuel

^ permalink raw reply	[flat|nested] 62+ messages in thread

* [PATCH v10 0/4] console: Add persistent scrollback buffers for all VGA consoles
  2017-01-11 13:32                 ` kbuild test robot
@ 2017-01-13 20:07                   ` Manuel Schölling
  2017-01-25 10:55                     ` Greg KH
  2017-01-13 20:07                   ` [PATCH v10 1/4] console: Move scrollback data into its own struct Manuel Schölling
                                     ` (3 subsequent siblings)
  4 siblings, 1 reply; 62+ messages in thread
From: Manuel Schölling @ 2017-01-13 20:07 UTC (permalink / raw)
  To: gregkh
  Cc: jslaby, kilobyte, lkml14, rdunlap, shorne, andrey_utkin, akpm,
	paul.burton, daniel.vetter, tj, hdegoede, linux-kernel,
	linux-fbdev, Manuel Schölling

Changes in v10:
  - Fix compilation error if CONFIG_VGACON_SOFT_SCROLLBACK=n
Changes in v9:
  - Make persistent scrollback feature a boot parameter
Changes in v8:
  - Add Reviewed-by/Tested-By statements
Changes in v7:
  - Add new callback to consw struct for flushing video console driver's
    scrollback buffer. Fixes issues with escape sequence '\e[3J' reported
    by Adam Borowski (kilobyte@angband.pl).
  - Fix style issues
Changes in v6:
  - Change of check if feature is enabled in 
    vgacon_scrollback_switch()
Changes in v5:
  - Clearify documentation
  - Skip superfluous array initialization
  - Disable scrollback if buffer allocation fails
  - Refactor vgacon_switch_scrollback()
  - Rename vgacon_switch_scrollback() to vgacon_scrollback_switch()
  - Add check for fg_console in vgacon_scrollback_update
Changes in v4.1:
  - Fix compiler error
Changes in v4:
  - Rename from VGACON_SOFT_SCROLLBACK_FOR_EACH_CONSOLE to
    VGACON_SOFT_SCROLLBACK_PERSISTENT
  - Split into two patches
  - Rework documentation
  - Remove cosmetic changes in comments (postponed)
Changes in v3:
  - Add config option for this feature
  - Fallback to old scrollback buffer if kcalloc() fails
  - Remove ioctl() call again and add documentation about existing
    escape sequence to flush the scrollback buffer
Changes in v2:
  - Add ioctl() call to flush scrollback buffer
  - (Patch v2 was not labeled as such, sorry)

Manuel Schölling (4):
  console: Move scrollback data into its own struct
  console: Add callback to flush scrollback buffer to consw struct
  console: Add persistent scrollback buffers for all VGA consoles
  console: Make persistent scrollback a boot parameter

 drivers/tty/vt/vt.c            |   9 +++
 drivers/video/console/Kconfig  |  27 ++++++-
 drivers/video/console/vgacon.c | 164 ++++++++++++++++++++++++++++-------------
 include/linux/console.h        |   4 +
 4 files changed, 149 insertions(+), 55 deletions(-)

-- 
2.11.0

^ permalink raw reply	[flat|nested] 62+ messages in thread

* [PATCH v10 1/4] console: Move scrollback data into its own struct
  2017-01-11 13:32                 ` kbuild test robot
  2017-01-13 20:07                   ` [PATCH v10 0/4] console: Add persistent scrollback buffers for all VGA consoles Manuel Schölling
@ 2017-01-13 20:07                   ` Manuel Schölling
  2017-01-13 20:07                   ` [PATCH v10 2/4] console: Add callback to flush scrollback buffer to consw struct Manuel Schölling
                                     ` (2 subsequent siblings)
  4 siblings, 0 replies; 62+ messages in thread
From: Manuel Schölling @ 2017-01-13 20:07 UTC (permalink / raw)
  To: gregkh
  Cc: jslaby, kilobyte, lkml14, rdunlap, shorne, andrey_utkin, akpm,
	paul.burton, daniel.vetter, tj, hdegoede, linux-kernel,
	linux-fbdev, Manuel Schölling

This refactoring is in preparation for persistent scrollback
support for VGA console.

Signed-off-by: Manuel Schölling <manuel.schoelling@gmx.de>
Reviewed-by: Andrey Utkin <andrey_utkin@fastmail.com>
Tested-by: Andrey Utkin <andrey_utkin@fastmail.com>
Tested-by: Adam Borowski <kilobyte@angband.pl>
---
 drivers/video/console/vgacon.c | 91 ++++++++++++++++++++++--------------------
 1 file changed, 47 insertions(+), 44 deletions(-)

diff --git a/drivers/video/console/vgacon.c b/drivers/video/console/vgacon.c
index c22a56232b7c..48b97648d4af 100644
--- a/drivers/video/console/vgacon.c
+++ b/drivers/video/console/vgacon.c
@@ -162,31 +162,34 @@ static inline void vga_set_mem_top(struct vc_data *c)
 
 #ifdef CONFIG_VGACON_SOFT_SCROLLBACK
 /* software scrollback */
-static void *vgacon_scrollback;
-static int vgacon_scrollback_tail;
-static int vgacon_scrollback_size;
-static int vgacon_scrollback_rows;
-static int vgacon_scrollback_cnt;
-static int vgacon_scrollback_cur;
-static int vgacon_scrollback_save;
-static int vgacon_scrollback_restore;
+static struct vgacon_scrollback_info {
+	void *data;
+	int tail;
+	int size;
+	int rows;
+	int cnt;
+	int cur;
+	int save;
+	int restore;
+} vgacon_scrollback;
 
 static void vgacon_scrollback_init(int pitch)
 {
 	int rows = CONFIG_VGACON_SOFT_SCROLLBACK_SIZE * 1024/pitch;
 
-	if (vgacon_scrollback) {
-		vgacon_scrollback_cnt  = 0;
-		vgacon_scrollback_tail = 0;
-		vgacon_scrollback_cur  = 0;
-		vgacon_scrollback_rows = rows - 1;
-		vgacon_scrollback_size = rows * pitch;
+	if (vgacon_scrollback.data) {
+		vgacon_scrollback.cnt  = 0;
+		vgacon_scrollback.tail = 0;
+		vgacon_scrollback.cur  = 0;
+		vgacon_scrollback.rows = rows - 1;
+		vgacon_scrollback.size = rows * pitch;
 	}
 }
 
 static void vgacon_scrollback_startup(void)
 {
-	vgacon_scrollback = kcalloc(CONFIG_VGACON_SOFT_SCROLLBACK_SIZE, 1024, GFP_NOWAIT);
+	vgacon_scrollback.data = kcalloc(CONFIG_VGACON_SOFT_SCROLLBACK_SIZE,
+		1024, GFP_NOWAIT);
 	vgacon_scrollback_init(vga_video_num_columns * 2);
 }
 
@@ -194,38 +197,38 @@ static void vgacon_scrollback_update(struct vc_data *c, int t, int count)
 {
 	void *p;
 
-	if (!vgacon_scrollback_size || c->vc_num != fg_console)
+	if (!vgacon_scrollback.size || c->vc_num != fg_console)
 		return;
 
 	p = (void *) (c->vc_origin + t * c->vc_size_row);
 
 	while (count--) {
-		scr_memcpyw(vgacon_scrollback + vgacon_scrollback_tail,
+		scr_memcpyw(vgacon_scrollback.data + vgacon_scrollback.tail,
 			    p, c->vc_size_row);
-		vgacon_scrollback_cnt++;
+		vgacon_scrollback.cnt++;
 		p += c->vc_size_row;
-		vgacon_scrollback_tail += c->vc_size_row;
+		vgacon_scrollback.tail += c->vc_size_row;
 
-		if (vgacon_scrollback_tail >= vgacon_scrollback_size)
-			vgacon_scrollback_tail = 0;
+		if (vgacon_scrollback.tail >= vgacon_scrollback.size)
+			vgacon_scrollback.tail = 0;
 
-		if (vgacon_scrollback_cnt > vgacon_scrollback_rows)
-			vgacon_scrollback_cnt = vgacon_scrollback_rows;
+		if (vgacon_scrollback.cnt > vgacon_scrollback.rows)
+			vgacon_scrollback.cnt = vgacon_scrollback.rows;
 
-		vgacon_scrollback_cur = vgacon_scrollback_cnt;
+		vgacon_scrollback.cur = vgacon_scrollback.cnt;
 	}
 }
 
 static void vgacon_restore_screen(struct vc_data *c)
 {
-	vgacon_scrollback_save = 0;
+	vgacon_scrollback.save = 0;
 
-	if (!vga_is_gfx && !vgacon_scrollback_restore) {
+	if (!vga_is_gfx && !vgacon_scrollback.restore) {
 		scr_memcpyw((u16 *) c->vc_origin, (u16 *) c->vc_screenbuf,
 			    c->vc_screenbuf_size > vga_vram_size ?
 			    vga_vram_size : c->vc_screenbuf_size);
-		vgacon_scrollback_restore = 1;
-		vgacon_scrollback_cur = vgacon_scrollback_cnt;
+		vgacon_scrollback.restore = 1;
+		vgacon_scrollback.cur = vgacon_scrollback.cnt;
 	}
 }
 
@@ -239,41 +242,41 @@ static void vgacon_scrolldelta(struct vc_data *c, int lines)
 		return;
 	}
 
-	if (!vgacon_scrollback)
+	if (!vgacon_scrollback.data)
 		return;
 
-	if (!vgacon_scrollback_save) {
+	if (!vgacon_scrollback.save) {
 		vgacon_cursor(c, CM_ERASE);
 		vgacon_save_screen(c);
-		vgacon_scrollback_save = 1;
+		vgacon_scrollback.save = 1;
 	}
 
-	vgacon_scrollback_restore = 0;
-	start = vgacon_scrollback_cur + lines;
+	vgacon_scrollback.restore = 0;
+	start = vgacon_scrollback.cur + lines;
 	end = start + abs(lines);
 
 	if (start < 0)
 		start = 0;
 
-	if (start > vgacon_scrollback_cnt)
-		start = vgacon_scrollback_cnt;
+	if (start > vgacon_scrollback.cnt)
+		start = vgacon_scrollback.cnt;
 
 	if (end < 0)
 		end = 0;
 
-	if (end > vgacon_scrollback_cnt)
-		end = vgacon_scrollback_cnt;
+	if (end > vgacon_scrollback.cnt)
+		end = vgacon_scrollback.cnt;
 
-	vgacon_scrollback_cur = start;
+	vgacon_scrollback.cur = start;
 	count = end - start;
-	soff = vgacon_scrollback_tail - ((vgacon_scrollback_cnt - end) *
+	soff = vgacon_scrollback.tail - ((vgacon_scrollback.cnt - end) *
 					 c->vc_size_row);
 	soff -= count * c->vc_size_row;
 
 	if (soff < 0)
-		soff += vgacon_scrollback_size;
+		soff += vgacon_scrollback.size;
 
-	count = vgacon_scrollback_cnt - start;
+	count = vgacon_scrollback.cnt - start;
 
 	if (count > c->vc_rows)
 		count = c->vc_rows;
@@ -287,13 +290,13 @@ static void vgacon_scrolldelta(struct vc_data *c, int lines)
 
 		count *= c->vc_size_row;
 		/* how much memory to end of buffer left? */
-		copysize = min(count, vgacon_scrollback_size - soff);
-		scr_memcpyw(d, vgacon_scrollback + soff, copysize);
+		copysize = min(count, vgacon_scrollback.size - soff);
+		scr_memcpyw(d, vgacon_scrollback.data + soff, copysize);
 		d += copysize;
 		count -= copysize;
 
 		if (count) {
-			scr_memcpyw(d, vgacon_scrollback, count);
+			scr_memcpyw(d, vgacon_scrollback.data, count);
 			d += count;
 		}
 
-- 
2.11.0

^ permalink raw reply	[flat|nested] 62+ messages in thread

* [PATCH v10 2/4] console: Add callback to flush scrollback buffer to consw struct
  2017-01-11 13:32                 ` kbuild test robot
  2017-01-13 20:07                   ` [PATCH v10 0/4] console: Add persistent scrollback buffers for all VGA consoles Manuel Schölling
  2017-01-13 20:07                   ` [PATCH v10 1/4] console: Move scrollback data into its own struct Manuel Schölling
@ 2017-01-13 20:07                   ` Manuel Schölling
  2017-01-13 20:07                   ` [PATCH v10 3/4] console: Add persistent scrollback buffers for all VGA consoles Manuel Schölling
  2017-01-13 20:07                   ` [PATCH v10 4/4] console: Make persistent scrollback a boot parameter Manuel Schölling
  4 siblings, 0 replies; 62+ messages in thread
From: Manuel Schölling @ 2017-01-13 20:07 UTC (permalink / raw)
  To: gregkh
  Cc: jslaby, kilobyte, lkml14, rdunlap, shorne, andrey_utkin, akpm,
	paul.burton, daniel.vetter, tj, hdegoede, linux-kernel,
	linux-fbdev, Manuel Schölling

This new callback is in preparation for persistent scrollback buffer
support for VGA consoles.
With a single scrollback buffer for all consoles, we could flush the
buffer just by invocating consw->con_switch(). But when each VGA console
has its own scrollback buffer, we need a new callback to tell the
video console driver which buffer to flush.

Signed-off-by: Manuel Schölling <manuel.schoelling@gmx.de>
Reviewed-by: Andrey Utkin <andrey_utkin@fastmail.com>
Tested-by: Andrey Utkin <andrey_utkin@fastmail.com>
Tested-by: Adam Borowski <kilobyte@angband.pl>
---
 drivers/tty/vt/vt.c            |  9 +++++++++
 drivers/video/console/vgacon.c | 24 +++++++++++++++++++++++-
 include/linux/console.h        |  4 ++++
 3 files changed, 36 insertions(+), 1 deletion(-)

diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c
index 4c10a9df3b91..9d3ce505e7ab 100644
--- a/drivers/tty/vt/vt.c
+++ b/drivers/tty/vt/vt.c
@@ -625,6 +625,14 @@ static void save_screen(struct vc_data *vc)
 		vc->vc_sw->con_save_screen(vc);
 }
 
+static void flush_scrollback(struct vc_data *vc)
+{
+	WARN_CONSOLE_UNLOCKED();
+
+	if (vc->vc_sw->con_flush_scrollback)
+		vc->vc_sw->con_flush_scrollback(vc);
+}
+
 /*
  *	Redrawing of screen
  */
@@ -1171,6 +1179,7 @@ static void csi_J(struct vc_data *vc, int vpar)
 		case 3: /* erase scroll-back buffer (and whole display) */
 			scr_memsetw(vc->vc_screenbuf, vc->vc_video_erase_char,
 				    vc->vc_screenbuf_size);
+			flush_scrollback(vc);
 			set_origin(vc);
 			if (con_is_visible(vc))
 				update_screen(vc);
diff --git a/drivers/video/console/vgacon.c b/drivers/video/console/vgacon.c
index 48b97648d4af..9a7c2bbc5326 100644
--- a/drivers/video/console/vgacon.c
+++ b/drivers/video/console/vgacon.c
@@ -173,6 +173,16 @@ static struct vgacon_scrollback_info {
 	int restore;
 } vgacon_scrollback;
 
+static void vgacon_scrollback_reset(size_t reset_size)
+{
+	if (vgacon_scrollback.data && reset_size > 0)
+		memset(vgacon_scrollback.data, 0, reset_size);
+
+	vgacon_scrollback.cnt  = 0;
+	vgacon_scrollback.tail = 0;
+	vgacon_scrollback.cur  = 0;
+}
+
 static void vgacon_scrollback_init(int pitch)
 {
 	int rows = CONFIG_VGACON_SOFT_SCROLLBACK_SIZE * 1024/pitch;
@@ -305,6 +315,14 @@ static void vgacon_scrolldelta(struct vc_data *c, int lines)
 	} else
 		vgacon_cursor(c, CM_MOVE);
 }
+
+static void vgacon_flush_scrollback(struct vc_data *c)
+{
+	size_t size = CONFIG_VGACON_SOFT_SCROLLBACK_SIZE * 1024;
+
+	if (c->vc_num == fg_console)
+		vgacon_scrollback_reset(size);
+}
 #else
 #define vgacon_scrollback_startup(...) do { } while (0)
 #define vgacon_scrollback_init(...)    do { } while (0)
@@ -322,6 +340,10 @@ static void vgacon_scrolldelta(struct vc_data *c, int lines)
 			vga_vram_size);
 	vga_set_mem_top(c);
 }
+
+static void vgacon_flush_scrollback(struct vc_data *c)
+{
+}
 #endif /* CONFIG_VGACON_SOFT_SCROLLBACK */
 
 static const char *vgacon_startup(void)
@@ -1329,7 +1351,6 @@ static bool vgacon_scroll(struct vc_data *c, unsigned int t, unsigned int b,
 	return true;
 }
 
-
 /*
  *  The console `switch' structure for the VGA based console
  */
@@ -1362,6 +1383,7 @@ const struct consw vga_con = {
 	.con_save_screen = vgacon_save_screen,
 	.con_build_attr = vgacon_build_attr,
 	.con_invert_region = vgacon_invert_region,
+	.con_flush_scrollback = vgacon_flush_scrollback,
 };
 EXPORT_SYMBOL(vga_con);
 
diff --git a/include/linux/console.h b/include/linux/console.h
index 9c26c6685587..5949d1855589 100644
--- a/include/linux/console.h
+++ b/include/linux/console.h
@@ -73,6 +73,10 @@ struct consw {
 	u16    *(*con_screen_pos)(struct vc_data *, int);
 	unsigned long (*con_getxy)(struct vc_data *, unsigned long, int *, int *);
 	/*
+	 * Flush the video console driver's scrollback buffer
+	 */
+	void	(*con_flush_scrollback)(struct vc_data *);
+	/*
 	 * Prepare the console for the debugger.  This includes, but is not
 	 * limited to, unblanking the console, loading an appropriate
 	 * palette, and allowing debugger generated output.
-- 
2.11.0

^ permalink raw reply	[flat|nested] 62+ messages in thread

* [PATCH v10 3/4] console: Add persistent scrollback buffers for all VGA consoles
  2017-01-11 13:32                 ` kbuild test robot
                                     ` (2 preceding siblings ...)
  2017-01-13 20:07                   ` [PATCH v10 2/4] console: Add callback to flush scrollback buffer to consw struct Manuel Schölling
@ 2017-01-13 20:07                   ` Manuel Schölling
  2017-01-19 13:23                     ` Greg KH
  2017-01-13 20:07                   ` [PATCH v10 4/4] console: Make persistent scrollback a boot parameter Manuel Schölling
  4 siblings, 1 reply; 62+ messages in thread
From: Manuel Schölling @ 2017-01-13 20:07 UTC (permalink / raw)
  To: gregkh
  Cc: jslaby, kilobyte, lkml14, rdunlap, shorne, andrey_utkin, akpm,
	paul.burton, daniel.vetter, tj, hdegoede, linux-kernel,
	linux-fbdev, Manuel Schölling

Add a scrollback buffers for each VGA console. The benefit is that
the scrollback history is not flushed when switching between consoles
but is persistent.
The buffers are allocated on demand when a new console is opened.

This breaks tools like clear_console that rely on flushing the
scrollback history by switching back and forth between consoles
which is why this feature is disabled by default.
Use the escape sequence \e[3J instead for flushing the buffer.

Signed-off-by: Manuel Schölling <manuel.schoelling@gmx.de>
Reviewed-by: Andrey Utkin <andrey_utkin@fastmail.com>
Tested-by: Andrey Utkin <andrey_utkin@fastmail.com>
Tested-by: Adam Borowski <kilobyte@angband.pl>
---
 drivers/video/console/Kconfig  |  25 +++++++-
 drivers/video/console/vgacon.c | 142 ++++++++++++++++++++++++++---------------
 2 files changed, 111 insertions(+), 56 deletions(-)

diff --git a/drivers/video/console/Kconfig b/drivers/video/console/Kconfig
index c3f1fb9ee820..f500e58f7636 100644
--- a/drivers/video/console/Kconfig
+++ b/drivers/video/console/Kconfig
@@ -43,9 +43,28 @@ config VGACON_SOFT_SCROLLBACK_SIZE
        range 1 1024
        default "64"
        help
-         Enter the amount of System RAM to allocate for the scrollback
-	 buffer.  Each 64KB will give you approximately 16 80x25
-	 screenfuls of scrollback buffer
+	  Enter the amount of System RAM to allocate for scrollback
+	  buffers of VGA consoles. Each 64KB will give you approximately
+	  16 80x25 screenfuls of scrollback buffer.
+
+config VGACON_SOFT_SCROLLBACK_PERSISTENT
+	bool "Persistent Scrollback History for each console"
+	depends on VGACON_SOFT_SCROLLBACK
+	default n
+	help
+	  Say Y here if the scrollback history should persist when switching
+	  between consoles. Otherwise, the scrollback history will be flushed
+	  each time the console is switched.
+
+	  This feature might break your tool of choice to flush the scrollback
+	  buffer, e.g. clear(1) will work fine but Debian's clear_console(1)
+	  will be broken, which might cause security issues.
+	  You can use the escape sequence \e[3J instead if this feature is
+	  activated.
+
+	  Note that a buffer of VGACON_SOFT_SCROLLBACK_SIZE is taken for each
+	  created tty device.
+	  So if you use a RAM-constrained system, say N here.
 
 config MDA_CONSOLE
 	depends on !M68K && !PARISC && ISA
diff --git a/drivers/video/console/vgacon.c b/drivers/video/console/vgacon.c
index 9a7c2bbc5326..ca23d222e029 100644
--- a/drivers/video/console/vgacon.c
+++ b/drivers/video/console/vgacon.c
@@ -162,7 +162,7 @@ static inline void vga_set_mem_top(struct vc_data *c)
 
 #ifdef CONFIG_VGACON_SOFT_SCROLLBACK
 /* software scrollback */
-static struct vgacon_scrollback_info {
+struct vgacon_scrollback_info {
 	void *data;
 	int tail;
 	int size;
@@ -171,74 +171,110 @@ static struct vgacon_scrollback_info {
 	int cur;
 	int save;
 	int restore;
-} vgacon_scrollback;
+};
+
+static struct vgacon_scrollback_info *vgacon_scrollback_cur;
+#ifdef CONFIG_VGACON_SOFT_SCROLLBACK_PERSISTENT
+static struct vgacon_scrollback_info vgacon_scrollbacks[MAX_NR_CONSOLES];
+#else
+static struct vgacon_scrollback_info vgacon_scrollbacks[1];
+#endif
 
-static void vgacon_scrollback_reset(size_t reset_size)
+static void vgacon_scrollback_reset(int vc_num, size_t reset_size)
 {
-	if (vgacon_scrollback.data && reset_size > 0)
-		memset(vgacon_scrollback.data, 0, reset_size);
+	struct vgacon_scrollback_info *scrollback = &vgacon_scrollbacks[vc_num];
+
+	if (scrollback->data && reset_size > 0)
+		memset(scrollback->data, 0, reset_size);
 
-	vgacon_scrollback.cnt  = 0;
-	vgacon_scrollback.tail = 0;
-	vgacon_scrollback.cur  = 0;
+	scrollback->cnt  = 0;
+	scrollback->tail = 0;
+	scrollback->cur  = 0;
 }
 
-static void vgacon_scrollback_init(int pitch)
+static void vgacon_scrollback_init(int vc_num)
 {
-	int rows = CONFIG_VGACON_SOFT_SCROLLBACK_SIZE * 1024/pitch;
-
-	if (vgacon_scrollback.data) {
-		vgacon_scrollback.cnt  = 0;
-		vgacon_scrollback.tail = 0;
-		vgacon_scrollback.cur  = 0;
-		vgacon_scrollback.rows = rows - 1;
-		vgacon_scrollback.size = rows * pitch;
+	int pitch = vga_video_num_columns * 2;
+	size_t size = CONFIG_VGACON_SOFT_SCROLLBACK_SIZE * 1024;
+	int rows = size / pitch;
+	void *data;
+
+	data = kmalloc_array(CONFIG_VGACON_SOFT_SCROLLBACK_SIZE, 1024,
+			     GFP_NOWAIT);
+
+	vgacon_scrollbacks[vc_num].data = data;
+	vgacon_scrollback_cur = &vgacon_scrollbacks[vc_num];
+
+	vgacon_scrollback_cur->rows = rows - 1;
+	vgacon_scrollback_cur->size = rows * pitch;
+
+	vgacon_scrollback_reset(vc_num, size);
+}
+
+static void vgacon_scrollback_switch(int vc_num)
+{
+#ifndef CONFIG_VGACON_SOFT_SCROLLBACK_PERSISTENT
+	vc_num = 0;
+#endif
+
+	if (!vgacon_scrollbacks[vc_num].data) {
+		vgacon_scrollback_init(vc_num);
+	} else {
+#ifdef CONFIG_VGACON_SOFT_SCROLLBACK_PERSISTENT
+		vgacon_scrollback_cur = &vgacon_scrollbacks[vc_num];
+#else
+		size_t size = CONFIG_VGACON_SOFT_SCROLLBACK_SIZE * 1024;
+
+		vgacon_scrollback_reset(vc_num, size);
+#endif
 	}
 }
 
 static void vgacon_scrollback_startup(void)
 {
-	vgacon_scrollback.data = kcalloc(CONFIG_VGACON_SOFT_SCROLLBACK_SIZE,
-		1024, GFP_NOWAIT);
-	vgacon_scrollback_init(vga_video_num_columns * 2);
+	vgacon_scrollback_cur = &vgacon_scrollbacks[0];
+	vgacon_scrollback_init(0);
 }
 
 static void vgacon_scrollback_update(struct vc_data *c, int t, int count)
 {
 	void *p;
 
-	if (!vgacon_scrollback.size || c->vc_num != fg_console)
+	if (!vgacon_scrollback_cur->data || !vgacon_scrollback_cur->size ||
+	    c->vc_num != fg_console)
 		return;
 
 	p = (void *) (c->vc_origin + t * c->vc_size_row);
 
 	while (count--) {
-		scr_memcpyw(vgacon_scrollback.data + vgacon_scrollback.tail,
+		scr_memcpyw(vgacon_scrollback_cur->data +
+			    vgacon_scrollback_cur->tail,
 			    p, c->vc_size_row);
-		vgacon_scrollback.cnt++;
+
+		vgacon_scrollback_cur->cnt++;
 		p += c->vc_size_row;
-		vgacon_scrollback.tail += c->vc_size_row;
+		vgacon_scrollback_cur->tail += c->vc_size_row;
 
-		if (vgacon_scrollback.tail >= vgacon_scrollback.size)
-			vgacon_scrollback.tail = 0;
+		if (vgacon_scrollback_cur->tail >= vgacon_scrollback_cur->size)
+			vgacon_scrollback_cur->tail = 0;
 
-		if (vgacon_scrollback.cnt > vgacon_scrollback.rows)
-			vgacon_scrollback.cnt = vgacon_scrollback.rows;
+		if (vgacon_scrollback_cur->cnt > vgacon_scrollback_cur->rows)
+			vgacon_scrollback_cur->cnt = vgacon_scrollback_cur->rows;
 
-		vgacon_scrollback.cur = vgacon_scrollback.cnt;
+		vgacon_scrollback_cur->cur = vgacon_scrollback_cur->cnt;
 	}
 }
 
 static void vgacon_restore_screen(struct vc_data *c)
 {
-	vgacon_scrollback.save = 0;
+	vgacon_scrollback_cur->save = 0;
 
-	if (!vga_is_gfx && !vgacon_scrollback.restore) {
+	if (!vga_is_gfx && !vgacon_scrollback_cur->restore) {
 		scr_memcpyw((u16 *) c->vc_origin, (u16 *) c->vc_screenbuf,
 			    c->vc_screenbuf_size > vga_vram_size ?
 			    vga_vram_size : c->vc_screenbuf_size);
-		vgacon_scrollback.restore = 1;
-		vgacon_scrollback.cur = vgacon_scrollback.cnt;
+		vgacon_scrollback_cur->restore = 1;
+		vgacon_scrollback_cur->cur = vgacon_scrollback_cur->cnt;
 	}
 }
 
@@ -252,41 +288,41 @@ static void vgacon_scrolldelta(struct vc_data *c, int lines)
 		return;
 	}
 
-	if (!vgacon_scrollback.data)
+	if (!vgacon_scrollback_cur->data)
 		return;
 
-	if (!vgacon_scrollback.save) {
+	if (!vgacon_scrollback_cur->save) {
 		vgacon_cursor(c, CM_ERASE);
 		vgacon_save_screen(c);
-		vgacon_scrollback.save = 1;
+		vgacon_scrollback_cur->save = 1;
 	}
 
-	vgacon_scrollback.restore = 0;
-	start = vgacon_scrollback.cur + lines;
+	vgacon_scrollback_cur->restore = 0;
+	start = vgacon_scrollback_cur->cur + lines;
 	end = start + abs(lines);
 
 	if (start < 0)
 		start = 0;
 
-	if (start > vgacon_scrollback.cnt)
-		start = vgacon_scrollback.cnt;
+	if (start > vgacon_scrollback_cur->cnt)
+		start = vgacon_scrollback_cur->cnt;
 
 	if (end < 0)
 		end = 0;
 
-	if (end > vgacon_scrollback.cnt)
-		end = vgacon_scrollback.cnt;
+	if (end > vgacon_scrollback_cur->cnt)
+		end = vgacon_scrollback_cur->cnt;
 
-	vgacon_scrollback.cur = start;
+	vgacon_scrollback_cur->cur = start;
 	count = end - start;
-	soff = vgacon_scrollback.tail - ((vgacon_scrollback.cnt - end) *
-					 c->vc_size_row);
+	soff = vgacon_scrollback_cur->tail -
+		((vgacon_scrollback_cur->cnt - end) * c->vc_size_row);
 	soff -= count * c->vc_size_row;
 
 	if (soff < 0)
-		soff += vgacon_scrollback.size;
+		soff += vgacon_scrollback_cur->size;
 
-	count = vgacon_scrollback.cnt - start;
+	count = vgacon_scrollback_cur->cnt - start;
 
 	if (count > c->vc_rows)
 		count = c->vc_rows;
@@ -300,13 +336,13 @@ static void vgacon_scrolldelta(struct vc_data *c, int lines)
 
 		count *= c->vc_size_row;
 		/* how much memory to end of buffer left? */
-		copysize = min(count, vgacon_scrollback.size - soff);
-		scr_memcpyw(d, vgacon_scrollback.data + soff, copysize);
+		copysize = min(count, vgacon_scrollback_cur->size - soff);
+		scr_memcpyw(d, vgacon_scrollback_cur->data + soff, copysize);
 		d += copysize;
 		count -= copysize;
 
 		if (count) {
-			scr_memcpyw(d, vgacon_scrollback.data, count);
+			scr_memcpyw(d, vgacon_scrollback_cur->data, count);
 			d += count;
 		}
 
@@ -320,13 +356,13 @@ static void vgacon_flush_scrollback(struct vc_data *c)
 {
 	size_t size = CONFIG_VGACON_SOFT_SCROLLBACK_SIZE * 1024;
 
-	if (c->vc_num == fg_console)
-		vgacon_scrollback_reset(size);
+	vgacon_scrollback_reset(c->vc_num, size);
 }
 #else
 #define vgacon_scrollback_startup(...) do { } while (0)
 #define vgacon_scrollback_init(...)    do { } while (0)
 #define vgacon_scrollback_update(...)  do { } while (0)
+#define vgacon_scrollback_switch(...)  do { } while (0)
 
 static void vgacon_restore_screen(struct vc_data *c)
 {
@@ -805,7 +841,7 @@ static int vgacon_switch(struct vc_data *c)
 			vgacon_doresize(c, c->vc_cols, c->vc_rows);
 	}
 
-	vgacon_scrollback_init(c->vc_size_row);
+	vgacon_scrollback_switch(c->vc_num);
 	return 0;		/* Redrawing not needed */
 }
 
-- 
2.11.0

^ permalink raw reply	[flat|nested] 62+ messages in thread

* [PATCH v10 4/4] console: Make persistent scrollback a boot parameter
  2017-01-11 13:32                 ` kbuild test robot
                                     ` (3 preceding siblings ...)
  2017-01-13 20:07                   ` [PATCH v10 3/4] console: Add persistent scrollback buffers for all VGA consoles Manuel Schölling
@ 2017-01-13 20:07                   ` Manuel Schölling
  4 siblings, 0 replies; 62+ messages in thread
From: Manuel Schölling @ 2017-01-13 20:07 UTC (permalink / raw)
  To: gregkh
  Cc: jslaby, kilobyte, lkml14, rdunlap, shorne, andrey_utkin, akpm,
	paul.burton, daniel.vetter, tj, hdegoede, linux-kernel,
	linux-fbdev, Manuel Schölling

The impact of the persistent scrollback feature on the code size is
rather small, so the config option is removed. The feature stays
disabled by default and can be enabled by using the boot command line
parameter 'vgacon.scrollback_persistent=1' or by setting
VGACON_SOFT_SCROLLBACK_PERSISTENT_ENABLE_BY_DEFAULT=y.

Signed-off-by: Manuel Schölling <manuel.schoelling@gmx.de>
Suggested-by: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com>
---
 drivers/video/console/Kconfig  | 12 +++++++-----
 drivers/video/console/vgacon.c | 25 ++++++++++++-------------
 2 files changed, 19 insertions(+), 18 deletions(-)

diff --git a/drivers/video/console/Kconfig b/drivers/video/console/Kconfig
index f500e58f7636..5b71bd905a60 100644
--- a/drivers/video/console/Kconfig
+++ b/drivers/video/console/Kconfig
@@ -47,14 +47,16 @@ config VGACON_SOFT_SCROLLBACK_SIZE
 	  buffers of VGA consoles. Each 64KB will give you approximately
 	  16 80x25 screenfuls of scrollback buffer.
 
-config VGACON_SOFT_SCROLLBACK_PERSISTENT
-	bool "Persistent Scrollback History for each console"
+config VGACON_SOFT_SCROLLBACK_PERSISTENT_ENABLE_BY_DEFAULT
+	bool "Persistent Scrollback History for each console by default"
 	depends on VGACON_SOFT_SCROLLBACK
 	default n
 	help
-	  Say Y here if the scrollback history should persist when switching
-	  between consoles. Otherwise, the scrollback history will be flushed
-	  each time the console is switched.
+	  Say Y here if the scrollback history should persist by default when
+	  switching between consoles. Otherwise, the scrollback history will be
+	  flushed each time the console is switched. This feature can also be
+	  enabled using the boot command line parameter
+	  'vgacon.scrollback_persistent=1'.
 
 	  This feature might break your tool of choice to flush the scrollback
 	  buffer, e.g. clear(1) will work fine but Debian's clear_console(1)
diff --git a/drivers/video/console/vgacon.c b/drivers/video/console/vgacon.c
index ca23d222e029..dc06cb6a15dc 100644
--- a/drivers/video/console/vgacon.c
+++ b/drivers/video/console/vgacon.c
@@ -174,11 +174,11 @@ struct vgacon_scrollback_info {
 };
 
 static struct vgacon_scrollback_info *vgacon_scrollback_cur;
-#ifdef CONFIG_VGACON_SOFT_SCROLLBACK_PERSISTENT
 static struct vgacon_scrollback_info vgacon_scrollbacks[MAX_NR_CONSOLES];
-#else
-static struct vgacon_scrollback_info vgacon_scrollbacks[1];
-#endif
+static bool scrollback_persistent = \
+	IS_ENABLED(CONFIG_VGACON_SOFT_SCROLLBACK_PERSISTENT_ENABLE_BY_DEFAULT);
+module_param_named(scrollback_persistent, scrollback_persistent, bool, 0000);
+MODULE_PARM_DESC(scrollback_persistent, "Enable persistent scrollback for all vga consoles");
 
 static void vgacon_scrollback_reset(int vc_num, size_t reset_size)
 {
@@ -213,20 +213,19 @@ static void vgacon_scrollback_init(int vc_num)
 
 static void vgacon_scrollback_switch(int vc_num)
 {
-#ifndef CONFIG_VGACON_SOFT_SCROLLBACK_PERSISTENT
-	vc_num = 0;
-#endif
+	if (!scrollback_persistent)
+		vc_num = 0;
 
 	if (!vgacon_scrollbacks[vc_num].data) {
 		vgacon_scrollback_init(vc_num);
 	} else {
-#ifdef CONFIG_VGACON_SOFT_SCROLLBACK_PERSISTENT
-		vgacon_scrollback_cur = &vgacon_scrollbacks[vc_num];
-#else
-		size_t size = CONFIG_VGACON_SOFT_SCROLLBACK_SIZE * 1024;
+		if (scrollback_persistent) {
+			vgacon_scrollback_cur = &vgacon_scrollbacks[vc_num];
+		} else {
+			size_t size = CONFIG_VGACON_SOFT_SCROLLBACK_SIZE * 1024;
 
-		vgacon_scrollback_reset(vc_num, size);
-#endif
+			vgacon_scrollback_reset(vc_num, size);
+		}
 	}
 }
 
-- 
2.11.0

^ permalink raw reply	[flat|nested] 62+ messages in thread

* Re: [PATCH v9 4/4] console: Make persistent scrollback a boot parameter
  2017-01-13 20:00                   ` Manuel Schölling
@ 2017-01-14  7:26                     ` Greg KH
  0 siblings, 0 replies; 62+ messages in thread
From: Greg KH @ 2017-01-14  7:26 UTC (permalink / raw)
  To: Manuel Schölling
  Cc: Adam Borowski, jslaby, lkml14, rdunlap, shorne, andrey_utkin,
	akpm, paul.burton, daniel.vetter, tj, hdegoede, linux-kernel,
	linux-fbdev

On Fri, Jan 13, 2017 at 09:00:34PM +0100, Manuel Schölling wrote:
> On Tue, 2017-01-10 at 23:58 +0100, Adam Borowski wrote:
> > On Tue, Jan 10, 2017 at 10:28:38PM +0100, Manuel Schölling wrote:
> > > The impact of the persistent scrollback feature on the code size is
> > > rather small, so the config option is removed. The feature stays
> > > disabled by default and can be enabled by using the boot command
> > > line
> > > parameter 'vgacon.scrollback_persistent=1' or by setting
> > > VGACON_SOFT_SCROLLBACK_PERSISTENT_ENABLE_BY_DEFAULT=y.
> > > 
> > > Signed-off-by: Manuel Schölling <manuel.schoelling@gmx.de>
> > > Suggested-by: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com>
> > > +module_param_named(scrollback_persistent, scrollback_persistent,
> > > bool, 0000);
> > > +MODULE_PARM_DESC(scrollback_persistent, "Enable persistent
> > > scrollback for all vga consoles");
> > 
> > A command-line knob settable by the end-user is something more
> > persistent
> > than a config option.  As you're going to extend this code beyond
> > vgacon in
> > the near future, perhaps it'd be better to have a shared setting for
> > all
> > console drivers?
> According to the guys at #kernelnewbies on IRC everybody hates new
> command line options.

That was me, you can use my name here :)

> I'd rather stick to the module parameter for now and maybe introduce a 
> new cmd line option later, once this feature has been implemented in
> several console drivers.

Yes, that should be fine.

thanks,

greg k-h

^ permalink raw reply	[flat|nested] 62+ messages in thread

* Re: [PATCH v10 3/4] console: Add persistent scrollback buffers for all VGA consoles
  2017-01-13 20:07                   ` [PATCH v10 3/4] console: Add persistent scrollback buffers for all VGA consoles Manuel Schölling
@ 2017-01-19 13:23                     ` Greg KH
  2017-01-19 16:12                       ` Manuel Schölling
  0 siblings, 1 reply; 62+ messages in thread
From: Greg KH @ 2017-01-19 13:23 UTC (permalink / raw)
  To: Manuel Schölling
  Cc: jslaby, kilobyte, lkml14, rdunlap, shorne, andrey_utkin, akpm,
	paul.burton, daniel.vetter, tj, hdegoede, linux-kernel,
	linux-fbdev

On Fri, Jan 13, 2017 at 09:07:57PM +0100, Manuel Schölling wrote:
> Add a scrollback buffers for each VGA console. The benefit is that
> the scrollback history is not flushed when switching between consoles
> but is persistent.
> The buffers are allocated on demand when a new console is opened.
> 
> This breaks tools like clear_console that rely on flushing the
> scrollback history by switching back and forth between consoles
> which is why this feature is disabled by default.
> Use the escape sequence \e[3J instead for flushing the buffer.
> 
> Signed-off-by: Manuel Schölling <manuel.schoelling@gmx.de>
> Reviewed-by: Andrey Utkin <andrey_utkin@fastmail.com>
> Tested-by: Andrey Utkin <andrey_utkin@fastmail.com>
> Tested-by: Adam Borowski <kilobyte@angband.pl>
> ---
>  drivers/video/console/Kconfig  |  25 +++++++-
>  drivers/video/console/vgacon.c | 142 ++++++++++++++++++++++++++---------------
>  2 files changed, 111 insertions(+), 56 deletions(-)
> 
> diff --git a/drivers/video/console/Kconfig b/drivers/video/console/Kconfig
> index c3f1fb9ee820..f500e58f7636 100644
> --- a/drivers/video/console/Kconfig
> +++ b/drivers/video/console/Kconfig
> @@ -43,9 +43,28 @@ config VGACON_SOFT_SCROLLBACK_SIZE
>         range 1 1024
>         default "64"
>         help
> -         Enter the amount of System RAM to allocate for the scrollback
> -	 buffer.  Each 64KB will give you approximately 16 80x25
> -	 screenfuls of scrollback buffer
> +	  Enter the amount of System RAM to allocate for scrollback
> +	  buffers of VGA consoles. Each 64KB will give you approximately
> +	  16 80x25 screenfuls of scrollback buffer.
> +
> +config VGACON_SOFT_SCROLLBACK_PERSISTENT
> +	bool "Persistent Scrollback History for each console"
> +	depends on VGACON_SOFT_SCROLLBACK
> +	default n
> +	help
> +	  Say Y here if the scrollback history should persist when switching
> +	  between consoles. Otherwise, the scrollback history will be flushed
> +	  each time the console is switched.
> +
> +	  This feature might break your tool of choice to flush the scrollback
> +	  buffer, e.g. clear(1) will work fine but Debian's clear_console(1)
> +	  will be broken, which might cause security issues.
> +	  You can use the escape sequence \e[3J instead if this feature is
> +	  activated.

This issue is the one that makes me the most worried.  Why doesn't
clear_console() work anymore?  Why doesn't it use \e[3J ?

thanks,

greg k-h

^ permalink raw reply	[flat|nested] 62+ messages in thread

* Re: [PATCH v10 3/4] console: Add persistent scrollback buffers for all VGA consoles
  2017-01-19 13:23                     ` Greg KH
@ 2017-01-19 16:12                       ` Manuel Schölling
  2017-01-19 16:33                         ` Greg KH
  2017-01-19 17:20                         ` Adam Borowski
  0 siblings, 2 replies; 62+ messages in thread
From: Manuel Schölling @ 2017-01-19 16:12 UTC (permalink / raw)
  To: Greg KH
  Cc: jslaby, kilobyte, lkml14, rdunlap, shorne, andrey_utkin, akpm,
	paul.burton, daniel.vetter, tj, hdegoede, linux-kernel,
	linux-fbdev

On Thu, 2017-01-19 at 14:23 +0100, Greg KH wrote:
> On Fri, Jan 13, 2017 at 09:07:57PM +0100, Manuel Schölling wrote:
> > Add a scrollback buffers for each VGA console. The benefit is that
> > the scrollback history is not flushed when switching between
> > consoles
> > but is persistent.
> > The buffers are allocated on demand when a new console is opened.
> > 
> > This breaks tools like clear_console that rely on flushing the
> > scrollback history by switching back and forth between consoles
> > which is why this feature is disabled by default.
> > Use the escape sequence \e[3J instead for flushing the buffer.
> > 
> > Signed-off-by: Manuel Schölling <manuel.schoelling@gmx.de>
> > Reviewed-by: Andrey Utkin <andrey_utkin@fastmail.com>
> > Tested-by: Andrey Utkin <andrey_utkin@fastmail.com>
> > Tested-by: Adam Borowski <kilobyte@angband.pl>
> > ---
> >  drivers/video/console/Kconfig  |  25 +++++++-
> >  drivers/video/console/vgacon.c | 142 ++++++++++++++++++++++++++---
> > ------------
> >  2 files changed, 111 insertions(+), 56 deletions(-)
> > 
> > diff --git a/drivers/video/console/Kconfig
> > b/drivers/video/console/Kconfig
> > index c3f1fb9ee820..f500e58f7636 100644
> > --- a/drivers/video/console/Kconfig
> > +++ b/drivers/video/console/Kconfig
> > @@ -43,9 +43,28 @@ config VGACON_SOFT_SCROLLBACK_SIZE
> >         range 1 1024
> >         default "64"
> >         help
> > -         Enter the amount of System RAM to allocate for the
> > scrollback
> > -	 buffer.  Each 64KB will give you approximately 16 80x25
> > -	 screenfuls of scrollback buffer
> > +	  Enter the amount of System RAM to allocate for
> > scrollback
> > +	  buffers of VGA consoles. Each 64KB will give you
> > approximately
> > +	  16 80x25 screenfuls of scrollback buffer.
> > +
> > +config VGACON_SOFT_SCROLLBACK_PERSISTENT
> > +	bool "Persistent Scrollback History for each console"
> > +	depends on VGACON_SOFT_SCROLLBACK
> > +	default n
> > +	help
> > +	  Say Y here if the scrollback history should persist when
> > switching
> > +	  between consoles. Otherwise, the scrollback history will
> > be flushed
> > +	  each time the console is switched.
> > +
> > +	  This feature might break your tool of choice to flush
> > the scrollback
> > +	  buffer, e.g. clear(1) will work fine but Debian's
> > clear_console(1)
> > +	  will be broken, which might cause security issues.
> > +	  You can use the escape sequence \e[3J instead if this
> > feature is
> > +	  activated.
> 
> This issue is the one that makes me the most worried.  Why doesn't
> clear_console() work anymore?  Why doesn't it use \e[3J ?

Well, clear_console() just switches from one console to another and
back again. It just assumes that the scrollback buffer is flushed when
switching.
My plan is to make a patch for clear_console() as soon as these patches
are in the kernel - it's chicken-and-egg problem.

Bye,

Manuel

^ permalink raw reply	[flat|nested] 62+ messages in thread

* Re: [PATCH v10 3/4] console: Add persistent scrollback buffers for all VGA consoles
  2017-01-19 16:12                       ` Manuel Schölling
@ 2017-01-19 16:33                         ` Greg KH
  2017-01-19 23:04                           ` Adam Borowski
  2017-01-19 17:20                         ` Adam Borowski
  1 sibling, 1 reply; 62+ messages in thread
From: Greg KH @ 2017-01-19 16:33 UTC (permalink / raw)
  To: Manuel Schölling
  Cc: jslaby, kilobyte, lkml14, rdunlap, shorne, andrey_utkin, akpm,
	paul.burton, daniel.vetter, tj, hdegoede, linux-kernel,
	linux-fbdev

On Thu, Jan 19, 2017 at 05:12:15PM +0100, Manuel Schölling wrote:
> On Thu, 2017-01-19 at 14:23 +0100, Greg KH wrote:
> > On Fri, Jan 13, 2017 at 09:07:57PM +0100, Manuel Schölling wrote:
> > > Add a scrollback buffers for each VGA console. The benefit is that
> > > the scrollback history is not flushed when switching between
> > > consoles
> > > but is persistent.
> > > The buffers are allocated on demand when a new console is opened.
> > > 
> > > This breaks tools like clear_console that rely on flushing the
> > > scrollback history by switching back and forth between consoles
> > > which is why this feature is disabled by default.
> > > Use the escape sequence \e[3J instead for flushing the buffer.
> > > 
> > > Signed-off-by: Manuel Schölling <manuel.schoelling@gmx.de>
> > > Reviewed-by: Andrey Utkin <andrey_utkin@fastmail.com>
> > > Tested-by: Andrey Utkin <andrey_utkin@fastmail.com>
> > > Tested-by: Adam Borowski <kilobyte@angband.pl>
> > > ---
> > >  drivers/video/console/Kconfig  |  25 +++++++-
> > >  drivers/video/console/vgacon.c | 142 ++++++++++++++++++++++++++---
> > > ------------
> > >  2 files changed, 111 insertions(+), 56 deletions(-)
> > > 
> > > diff --git a/drivers/video/console/Kconfig
> > > b/drivers/video/console/Kconfig
> > > index c3f1fb9ee820..f500e58f7636 100644
> > > --- a/drivers/video/console/Kconfig
> > > +++ b/drivers/video/console/Kconfig
> > > @@ -43,9 +43,28 @@ config VGACON_SOFT_SCROLLBACK_SIZE
> > >         range 1 1024
> > >         default "64"
> > >         help
> > > -         Enter the amount of System RAM to allocate for the
> > > scrollback
> > > -	 buffer.  Each 64KB will give you approximately 16 80x25
> > > -	 screenfuls of scrollback buffer
> > > +	  Enter the amount of System RAM to allocate for
> > > scrollback
> > > +	  buffers of VGA consoles. Each 64KB will give you
> > > approximately
> > > +	  16 80x25 screenfuls of scrollback buffer.
> > > +
> > > +config VGACON_SOFT_SCROLLBACK_PERSISTENT
> > > +	bool "Persistent Scrollback History for each console"
> > > +	depends on VGACON_SOFT_SCROLLBACK
> > > +	default n
> > > +	help
> > > +	  Say Y here if the scrollback history should persist when
> > > switching
> > > +	  between consoles. Otherwise, the scrollback history will
> > > be flushed
> > > +	  each time the console is switched.
> > > +
> > > +	  This feature might break your tool of choice to flush
> > > the scrollback
> > > +	  buffer, e.g. clear(1) will work fine but Debian's
> > > clear_console(1)
> > > +	  will be broken, which might cause security issues.
> > > +	  You can use the escape sequence \e[3J instead if this
> > > feature is
> > > +	  activated.
> > 
> > This issue is the one that makes me the most worried.  Why doesn't
> > clear_console() work anymore?  Why doesn't it use \e[3J ?
> 
> Well, clear_console() just switches from one console to another and
> back again. It just assumes that the scrollback buffer is flushed when
> switching.
> My plan is to make a patch for clear_console() as soon as these patches
> are in the kernel - it's chicken-and-egg problem.

I'd recommend that patch get to clear_console() first, having it use the
new escape sequence, if it isn't supported, shouldn't cause any
problems, right?

thanks,

greg k-h

^ permalink raw reply	[flat|nested] 62+ messages in thread

* Re: [PATCH v10 3/4] console: Add persistent scrollback buffers for all VGA consoles
  2017-01-19 16:12                       ` Manuel Schölling
  2017-01-19 16:33                         ` Greg KH
@ 2017-01-19 17:20                         ` Adam Borowski
  1 sibling, 0 replies; 62+ messages in thread
From: Adam Borowski @ 2017-01-19 17:20 UTC (permalink / raw)
  To: Manuel Schölling
  Cc: Greg KH, jslaby, lkml14, rdunlap, shorne, andrey_utkin, akpm,
	paul.burton, daniel.vetter, tj, hdegoede, linux-kernel,
	linux-fbdev

On Thu, Jan 19, 2017 at 05:12:15PM +0100, Manuel Schölling wrote:
> On Thu, 2017-01-19 at 14:23 +0100, Greg KH wrote:
> > On Fri, Jan 13, 2017 at 09:07:57PM +0100, Manuel Schölling wrote:
> > > Add a scrollback buffers for each VGA console.  The benefit is that
> > > the scrollback history is not flushed when switching between consoles
> > > but is persistent.  The buffers are allocated on demand when a new
> > > console is opened.
> > > 
> > > This breaks tools like clear_console that rely on flushing the
> > > scrollback history by switching back and forth between consoles
> > > which is why this feature is disabled by default.
> > > Use the escape sequence \e[3J instead for flushing the buffer.
> > 
> > This issue is the one that makes me the most worried.  Why doesn't
> > clear_console() work anymore?  Why doesn't it use \e[3J ?
> 
> Well, clear_console() just switches from one console to another and
> back again. It just assumes that the scrollback buffer is flushed when
> switching.
> My plan is to make a patch for clear_console() as soon as these patches
> are in the kernel - it's chicken-and-egg problem.

No need to wait, \e[3J is supported since Linux 2.6.39; the problem I
spotted was that a previous version of your patch would break that.

It is also safe to output that sequence to a terminal unconditionally: I've
tested a number of terminals, they all either support it (most X terminals,
our console) or silently ignore it.

We can't, though, rely on terminfo to do so: it knows about this capability
(which it calls "E3") for TERM=linux only since very recently.  The TERM
variable is also unreliable: it fails to carry over a serial link while
blindly printing \e[3J works.

As for patching clear_console, https://bugs.debian.org/845177 has a minimal
fix; although for all setups supported by Debian that program could be be
better replaced with just "printf '\e[3J\e[2J'" which would make it work on
strictly more terminals than current code does.  Same for distributions
which copied clear_console (it originates from Ubuntu, maintained in Debian
since then).


Meow!
-- 
Autotools hint: to do a zx-spectrum build on a pdp11 host, type:
  ./configure --host=zx-spectrum --build=pdp11

^ permalink raw reply	[flat|nested] 62+ messages in thread

* Re: [PATCH v10 3/4] console: Add persistent scrollback buffers for all VGA consoles
  2017-01-19 16:33                         ` Greg KH
@ 2017-01-19 23:04                           ` Adam Borowski
  2017-01-20 13:16                             ` Adam Borowski
  0 siblings, 1 reply; 62+ messages in thread
From: Adam Borowski @ 2017-01-19 23:04 UTC (permalink / raw)
  To: Greg KH, Matthias Klose, 845177
  Cc: Manuel Schölling, jslaby, lkml14, rdunlap, shorne,
	andrey_utkin, akpm, paul.burton, daniel.vetter, tj, hdegoede,
	linux-kernel, linux-fbdev

On Thu, Jan 19, 2017 at 05:33:14PM +0100, Greg KH wrote:
> On Thu, Jan 19, 2017 at 05:12:15PM +0100, Manuel Schölling wrote:
> > On Thu, 2017-01-19 at 14:23 +0100, Greg KH wrote:
> > > On Fri, Jan 13, 2017 at 09:07:57PM +0100, Manuel Schölling wrote:
> > > > +	  This feature might break your tool of choice to flush
> > > > the scrollback
> > > > +	  buffer, e.g. clear(1) will work fine but Debian's
> > > > clear_console(1)
> > > > +	  will be broken, which might cause security issues.
> > > > +	  You can use the escape sequence \e[3J instead if this
> > > > feature is
> > > > +	  activated.
> > > 
> > > This issue is the one that makes me the most worried.  Why doesn't
> > > clear_console() work anymore?  Why doesn't it use \e[3J ?
> > 
> > Well, clear_console() just switches from one console to another and
> > back again. It just assumes that the scrollback buffer is flushed when
> > switching.
> > My plan is to make a patch for clear_console() as soon as these patches
> > are in the kernel - it's chicken-and-egg problem.
> 
> I'd recommend that patch get to clear_console() first, having it use the
> new escape sequence, if it isn't supported, shouldn't cause any
> problems, right?

In that case, we need to hurry -- the last day for any non-serious fixes in
Debian is Jan 26, after that it'll be frozen for months, and any subsequent
changes won't get to stable users for around two years.

doko: would you consider, pretty please with a cherry on top, applying the
patch I've sent to this bug?  The privacy/security issue is pretty minor and
applies only to a tiny fraction of users, but I understand why Greg is
reluctant.

Manuel's scrollback changes won't go to 4.9, and won't be enabled by default
for the time being, but using a newer kernel on old userspace is something
really widespread, be it via bpo, containers on an updated host, etc.


Meow!
-- 
Autotools hint: to do a zx-spectrum build on a pdp11 host, type:
  ./configure --host=zx-spectrum --build=pdp11

^ permalink raw reply	[flat|nested] 62+ messages in thread

* Re: [PATCH v10 3/4] console: Add persistent scrollback buffers for all VGA consoles
  2017-01-19 23:04                           ` Adam Borowski
@ 2017-01-20 13:16                             ` Adam Borowski
  2017-01-20 13:31                               ` Greg KH
  0 siblings, 1 reply; 62+ messages in thread
From: Adam Borowski @ 2017-01-20 13:16 UTC (permalink / raw)
  To: Greg KH
  Cc: Manuel Schölling, jslaby, lkml14, rdunlap, shorne,
	andrey_utkin, akpm, paul.burton, daniel.vetter, tj, hdegoede,
	linux-kernel, linux-fbdev

On Fri, Jan 20, 2017 at 12:04:12AM +0100, Adam Borowski wrote:
> On Thu, Jan 19, 2017 at 05:33:14PM +0100, Greg KH wrote:
> > On Thu, Jan 19, 2017 at 05:12:15PM +0100, Manuel Schölling wrote:
> > > On Thu, 2017-01-19 at 14:23 +0100, Greg KH wrote:
> > > > On Fri, Jan 13, 2017 at 09:07:57PM +0100, Manuel Schölling wrote:
> > > > > +	  This feature might break your tool of choice to flush
> > > > > the scrollback
> > > > > +	  buffer, e.g. clear(1) will work fine but Debian's
> > > > > clear_console(1)
> > > > > +	  will be broken, which might cause security issues.
> > > > > +	  You can use the escape sequence \e[3J instead if this
> > > > > feature is
> > > > > +	  activated.
> > 
> > I'd recommend that patch get to clear_console() first, having it use the
> > new escape sequence, if it isn't supported, shouldn't cause any
> > problems, right?
> 
> doko: would you consider, pretty please with a cherry on top, applying the
> patch I've sent to this bug?  The privacy/security issue is pretty minor and
> applies only to a tiny fraction of users, but I understand why Greg is
> reluctant.

# Subject: Bug#845177 closed by Matthias Klose <doko@debian.org>
#
# This is an automatic notification regarding your Bug report
# which was filed against the bash package:
#
# #845177: clear_console: assumes VT switch clears scrollback
#
# It has been closed by Matthias Klose <doko@debian.org>.
[...]
# Changes:
#    * clear_console: Securely erase the current console. Closes: #845177.

-- 
Autotools hint: to do a zx-spectrum build on a pdp11 host, type:
  ./configure --host=zx-spectrum --build=pdp11

^ permalink raw reply	[flat|nested] 62+ messages in thread

* Re: [PATCH v10 3/4] console: Add persistent scrollback buffers for all VGA consoles
  2017-01-20 13:16                             ` Adam Borowski
@ 2017-01-20 13:31                               ` Greg KH
  2017-01-20 14:27                                 ` Adam Borowski
  0 siblings, 1 reply; 62+ messages in thread
From: Greg KH @ 2017-01-20 13:31 UTC (permalink / raw)
  To: Adam Borowski
  Cc: Manuel Schölling, jslaby, lkml14, rdunlap, shorne,
	andrey_utkin, akpm, paul.burton, daniel.vetter, tj, hdegoede,
	linux-kernel, linux-fbdev

On Fri, Jan 20, 2017 at 02:16:11PM +0100, Adam Borowski wrote:
> On Fri, Jan 20, 2017 at 12:04:12AM +0100, Adam Borowski wrote:
> > On Thu, Jan 19, 2017 at 05:33:14PM +0100, Greg KH wrote:
> > > On Thu, Jan 19, 2017 at 05:12:15PM +0100, Manuel Schölling wrote:
> > > > On Thu, 2017-01-19 at 14:23 +0100, Greg KH wrote:
> > > > > On Fri, Jan 13, 2017 at 09:07:57PM +0100, Manuel Schölling wrote:
> > > > > > +	  This feature might break your tool of choice to flush
> > > > > > the scrollback
> > > > > > +	  buffer, e.g. clear(1) will work fine but Debian's
> > > > > > clear_console(1)
> > > > > > +	  will be broken, which might cause security issues.
> > > > > > +	  You can use the escape sequence \e[3J instead if this
> > > > > > feature is
> > > > > > +	  activated.
> > > 
> > > I'd recommend that patch get to clear_console() first, having it use the
> > > new escape sequence, if it isn't supported, shouldn't cause any
> > > problems, right?
> > 
> > doko: would you consider, pretty please with a cherry on top, applying the
> > patch I've sent to this bug?  The privacy/security issue is pretty minor and
> > applies only to a tiny fraction of users, but I understand why Greg is
> > reluctant.
> 
> # Subject: Bug#845177 closed by Matthias Klose <doko@debian.org>
> #
> # This is an automatic notification regarding your Bug report
> # which was filed against the bash package:
> #
> # #845177: clear_console: assumes VT switch clears scrollback
> #
> # It has been closed by Matthias Klose <doko@debian.org>.
> [...]
> # Changes:
> #    * clear_console: Securely erase the current console. Closes: #845177.

This means it was accepted?  Or rejected?

confused,

greg k-h

^ permalink raw reply	[flat|nested] 62+ messages in thread

* Re: [PATCH v10 3/4] console: Add persistent scrollback buffers for all VGA consoles
  2017-01-20 13:31                               ` Greg KH
@ 2017-01-20 14:27                                 ` Adam Borowski
  0 siblings, 0 replies; 62+ messages in thread
From: Adam Borowski @ 2017-01-20 14:27 UTC (permalink / raw)
  To: Greg KH
  Cc: Manuel Schölling, jslaby, lkml14, rdunlap, shorne,
	andrey_utkin, akpm, paul.burton, daniel.vetter, tj, hdegoede,
	linux-kernel, linux-fbdev

On Fri, Jan 20, 2017 at 02:31:56PM +0100, Greg KH wrote:
> On Fri, Jan 20, 2017 at 02:16:11PM +0100, Adam Borowski wrote:
> > On Fri, Jan 20, 2017 at 12:04:12AM +0100, Adam Borowski wrote:
> > > On Thu, Jan 19, 2017 at 05:33:14PM +0100, Greg KH wrote:
> > > > I'd recommend that patch get to clear_console() first, having it use the
> > > > new escape sequence, if it isn't supported, shouldn't cause any
> > > > problems, right?
> > 
> > # Subject: Bug#845177 closed by Matthias Klose <doko@debian.org>
> > #
> > # This is an automatic notification regarding your Bug report
> > # which was filed against the bash package:
> > #
> > # #845177: clear_console: assumes VT switch clears scrollback
> > #
> > # It has been closed by Matthias Klose <doko@debian.org>.
> > [...]
> > # Changes:
> > #    * clear_console: Securely erase the current console. Closes: #845177.
> 
> This means it was accepted?  Or rejected?

Accepted.

It's in unstable (or will be in the next mirror pulse), we're at the fastest
possible moment to get stuff to the next stable release -- it'll be in
Stretch (about to freeze).  Ubuntu migration is currently open so it'll get
there soon, in time for Zesty (17.04).  Other Debian derivatives likewise
pull at their own pace.

Most distributions unrelated to Debian don't seem to ship clear_console but
I have no real idea: just checked Fedora 25, it doesn't have it in the
default install at least.


Meow!
-- 
Autotools hint: to do a zx-spectrum build on a pdp11 host, type:
  ./configure --host=zx-spectrum --build=pdp11

^ permalink raw reply	[flat|nested] 62+ messages in thread

* Re: [PATCH v10 0/4] console: Add persistent scrollback buffers for all VGA consoles
  2017-01-13 20:07                   ` [PATCH v10 0/4] console: Add persistent scrollback buffers for all VGA consoles Manuel Schölling
@ 2017-01-25 10:55                     ` Greg KH
  0 siblings, 0 replies; 62+ messages in thread
From: Greg KH @ 2017-01-25 10:55 UTC (permalink / raw)
  To: Manuel Schölling
  Cc: jslaby, kilobyte, lkml14, rdunlap, shorne, andrey_utkin, akpm,
	paul.burton, daniel.vetter, tj, hdegoede, linux-kernel,
	linux-fbdev

On Fri, Jan 13, 2017 at 09:07:54PM +0100, Manuel Schölling wrote:
> Changes in v10:
>   - Fix compilation error if CONFIG_VGACON_SOFT_SCROLLBACK=n

All now applied to my tty-testing branch, let's see what the 0-day bot
has to say about this :)

thanks for the persistence.

greg k-h

^ permalink raw reply	[flat|nested] 62+ messages in thread

* Re: [PATCH v9 4/4] console: Make persistent scrollback a boot parameter
  2017-01-10 21:28               ` [PATCH v9 4/4] console: Make persistent scrollback a boot parameter Manuel Schölling
  2017-01-10 22:58                 ` Adam Borowski
  2017-01-11 13:32                 ` kbuild test robot
@ 2017-02-02 20:07                 ` Paul Gortmaker
  2017-02-03 16:04                   ` Manuel Schölling
  2 siblings, 1 reply; 62+ messages in thread
From: Paul Gortmaker @ 2017-02-02 20:07 UTC (permalink / raw)
  To: Manuel Schölling
  Cc: gregkh, jslaby, kilobyte, lkml14, rdunlap, shorne, andrey_utkin,
	Andrew Morton, paul.burton, daniel.vetter, tj, hdegoede, LKML,
	linux-fbdev

On Tue, Jan 10, 2017 at 4:28 PM, Manuel Schölling
<manuel.schoelling@gmx.de> wrote:
> The impact of the persistent scrollback feature on the code size is
> rather small, so the config option is removed. The feature stays
> disabled by default and can be enabled by using the boot command line
> parameter 'vgacon.scrollback_persistent=1' or by setting
> VGACON_SOFT_SCROLLBACK_PERSISTENT_ENABLE_BY_DEFAULT=y.
>
> Signed-off-by: Manuel Schölling <manuel.schoelling@gmx.de>
> Suggested-by: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com>
> ---

[...]

> +module_param_named(scrollback_persistent, scrollback_persistent, bool, 0000);
> +MODULE_PARM_DESC(scrollback_persistent, "Enable persistent scrollback for all vga consoles");

Since this hasn't got widespread deployment yet and  only exists
in Greg's tree, can we please fix the above to use setup_param or
similar, since there is nothing modular about this code at all.

Thanks.
Paul.

^ permalink raw reply	[flat|nested] 62+ messages in thread

* Re: [PATCH v9 4/4] console: Make persistent scrollback a boot parameter
  2017-02-02 20:07                 ` [PATCH v9 " Paul Gortmaker
@ 2017-02-03 16:04                   ` Manuel Schölling
  2017-02-03 16:45                     ` Adam Borowski
  0 siblings, 1 reply; 62+ messages in thread
From: Manuel Schölling @ 2017-02-03 16:04 UTC (permalink / raw)
  To: Paul Gortmaker
  Cc: gregkh, jslaby, kilobyte, lkml14, rdunlap, shorne, andrey_utkin,
	Andrew Morton, paul.burton, daniel.vetter, tj, hdegoede, LKML,
	linux-fbdev

Hi Paul,

On Thu, 2017-02-02 at 15:07 -0500, Paul Gortmaker wrote:
> On Tue, Jan 10, 2017 at 4:28 PM, Manuel Schölling
> <manuel.schoelling@gmx.de> wrote:
> > The impact of the persistent scrollback feature on the code size is
> > rather small, so the config option is removed. The feature stays
> > disabled by default and can be enabled by using the boot command
> > line
> > parameter 'vgacon.scrollback_persistent=1' or by setting
> > VGACON_SOFT_SCROLLBACK_PERSISTENT_ENABLE_BY_DEFAULT=y.
> > 
> > Signed-off-by: Manuel Schölling <manuel.schoelling@gmx.de>
> > Suggested-by: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com>
> > ---
> 
> [...]
> 
> > +module_param_named(scrollback_persistent, scrollback_persistent,
> > bool, 0000);
> > +MODULE_PARM_DESC(scrollback_persistent, "Enable persistent
> > scrollback for all vga consoles");
> 
> Since this hasn't got widespread deployment yet and  only exists
> in Greg's tree, can we please fix the above to use setup_param or
> similar, since there is nothing modular about this code at all.
Not sure what you mean here.
If this is not the right may to declare it I'd be more than happy to
change this. But I could not find any function/macro named setup_param
[1].
It would be great if you could give me a hint what function to use
here!

Have a great weekend!

Manuel

[1] http://lxr.free-electrons.com/ident?i=setup_param

^ permalink raw reply	[flat|nested] 62+ messages in thread

* Re: [PATCH v9 4/4] console: Make persistent scrollback a boot parameter
  2017-02-03 16:04                   ` Manuel Schölling
@ 2017-02-03 16:45                     ` Adam Borowski
  0 siblings, 0 replies; 62+ messages in thread
From: Adam Borowski @ 2017-02-03 16:45 UTC (permalink / raw)
  To: Manuel Schölling
  Cc: Paul Gortmaker, gregkh, jslaby, lkml14, rdunlap, shorne,
	andrey_utkin, Andrew Morton, paul.burton, daniel.vetter, tj,
	hdegoede, LKML, linux-fbdev

On Fri, Feb 03, 2017 at 05:04:15PM +0100, Manuel Schölling wrote:
> On Thu, 2017-02-02 at 15:07 -0500, Paul Gortmaker wrote:
> > On Tue, Jan 10, 2017 at 4:28 PM, Manuel Schölling
> > <manuel.schoelling@gmx.de> wrote:
> > > The impact of the persistent scrollback feature on the code size is
> > > rather small, so the config option is removed. The feature stays
> > > disabled by default and can be enabled by using the boot command
> > > line
> > > parameter 'vgacon.scrollback_persistent=1' or by setting
> > > VGACON_SOFT_SCROLLBACK_PERSISTENT_ENABLE_BY_DEFAULT=y.
> > 
> > [...]
> > 
> > > +module_param_named(scrollback_persistent, scrollback_persistent,
> > > bool, 0000);
> > > +MODULE_PARM_DESC(scrollback_persistent, "Enable persistent
> > > scrollback for all vga consoles");
> > 
> > Since this hasn't got widespread deployment yet and  only exists
> > in Greg's tree, can we please fix the above to use setup_param or
> > similar, since there is nothing modular about this code at all.
> Not sure what you mean here.
> If this is not the right may to declare it I'd be more than happy to
> change this. But I could not find any function/macro named setup_param
> [1].
> It would be great if you could give me a hint what function to use
> here!
> 
> [1] http://lxr.free-electrons.com/ident?i=setup_param

That shows only exact matches.

You want "git grep setup_param", which shows __setup_param() plus some
unrelated stuff.  I see only four uses in the kernel, but that's enough
to see how to use it.


Meow!
-- 
Autotools hint: to do a zx-spectrum build on a pdp11 host, type:
  ./configure --host=zx-spectrum --build=pdp11

^ permalink raw reply	[flat|nested] 62+ messages in thread

* Re: [PATCH v7 0/3] console: Add persistent scrollback buffers for all VGA consoles
  2016-12-01 21:03         ` Manuel Schölling
@ 2016-12-01 21:31           ` Andrey Utkin
  0 siblings, 0 replies; 62+ messages in thread
From: Andrey Utkin @ 2016-12-01 21:31 UTC (permalink / raw)
  To: Manuel Schölling
  Cc: plagnioj, tomi.valkeinen, jslaby, gregkh, kilobyte, linux-fbdev,
	linux-kernel

On Thu, Dec 01, 2016 at 10:03:23PM +0100, Manuel Schölling wrote:
> Hi Andrey,
> 
> On Di, 2016-11-29 at 10:01 +0000, Andrey Utkin wrote:
> > On Mon, Nov 28, 2016 at 10:28:19PM +0100, Manuel Schölling wrote:
> > Regarding logout scrollback clearing not working for me. ncurses-6.0-rc1
> > which I tested it with is the latest available in Gentoo portage, please
> > confirm whether I need any newer version, or should I tune something
> > else. I'd appreciate if you also tested your patch with gentoo setup.
> 
> I finally setup gentoo

Wow, what a big undertaking.

> running agetty (util-linux-2.26.2) and patching
> the file term-utils/agetty.c with
> 
> static void termio_clear(int fd)
> {
> 	/*
> 	 * Do not write a full reset (ESC c) because this destroys
> 	 * the unicode mode again if the terminal was in unicode
> 	 * mode.  Also it clears the CONSOLE_MAGIC features which
> 	 * are required for some languages/console-fonts.
> 	 * Just put the cursor to the home position (ESC [ H),
> 	 * erase everything below the cursor (ESC [ J), and set the
> 	 * scrolling region to the full window (ESC [ r)
> 	 */
> -	write_all(fd, "\033[r\033[H\033[J", 9);
> +	write_all(fd, "\033[3J\033[r\033[H\033[J", 13);
> }
> 
> solves the issue with the scrollback buffer after log out.
> Let me know if you agree that this is the right way to go and I will
> send a patch to the maintainer of util-linux.

I believe you that this works and you must know better than me whether
this solution is correct. Besides that, I'd suggest updating that large
block comment before the updated write_all() call to describe the new
action you're doing. Please CC me in your discussion with util-linux
maintainers.

Also I'd suggest coming back in a while, to set this feature enabled by
default. I wonder how many years to wait gracefully until "stable"
distros update util-linux to ensure secure scrollback wiping. 3? 5?

> Thanks again for spending all this time to test the patch!

Thank you very much for your time and effort in bringing this useful
feature!

I give all sorts of my approval on this patchset:
Reviewed-by: Andrey Utkin <andrey_utkin@fastmail.com>
Tested-by: Andrey Utkin <andrey_utkin@fastmail.com>

^ permalink raw reply	[flat|nested] 62+ messages in thread

* Re: [PATCH v7 0/3] console: Add persistent scrollback buffers for all VGA consoles
  2016-11-29 10:01       ` Andrey Utkin
  2016-11-29 10:44         ` Adam Borowski
  2016-11-29 16:35         ` Manuel Schölling
@ 2016-12-01 21:03         ` Manuel Schölling
  2016-12-01 21:31           ` Andrey Utkin
  2 siblings, 1 reply; 62+ messages in thread
From: Manuel Schölling @ 2016-12-01 21:03 UTC (permalink / raw)
  To: Andrey Utkin
  Cc: plagnioj, tomi.valkeinen, jslaby, gregkh, kilobyte, linux-fbdev,
	linux-kernel

Hi Andrey,

On Di, 2016-11-29 at 10:01 +0000, Andrey Utkin wrote:
> On Mon, Nov 28, 2016 at 10:28:19PM +0100, Manuel Schölling wrote:
> Regarding logout scrollback clearing not working for me. ncurses-6.0-rc1
> which I tested it with is the latest available in Gentoo portage, please
> confirm whether I need any newer version, or should I tune something
> else. I'd appreciate if you also tested your patch with gentoo setup.

I finally setup gentoo running agetty (util-linux-2.26.2) and patching
the file term-utils/agetty.c with

static void termio_clear(int fd)
{
	/*
	 * Do not write a full reset (ESC c) because this destroys
	 * the unicode mode again if the terminal was in unicode
	 * mode.  Also it clears the CONSOLE_MAGIC features which
	 * are required for some languages/console-fonts.
	 * Just put the cursor to the home position (ESC [ H),
	 * erase everything below the cursor (ESC [ J), and set the
	 * scrolling region to the full window (ESC [ r)
	 */
-	write_all(fd, "\033[r\033[H\033[J", 9);
+	write_all(fd, "\033[3J\033[r\033[H\033[J", 13);
}

solves the issue with the scrollback buffer after log out.
Let me know if you agree that this is the right way to go and I will
send a patch to the maintainer of util-linux.

Thanks again for spending all this time to test the patch!

Have a good weekend!

Manuel

^ permalink raw reply	[flat|nested] 62+ messages in thread

* Re: [PATCH v7 0/3] console: Add persistent scrollback buffers for all VGA consoles
  2016-11-29 10:01       ` Andrey Utkin
  2016-11-29 10:44         ` Adam Borowski
@ 2016-11-29 16:35         ` Manuel Schölling
  2016-12-01 21:03         ` Manuel Schölling
  2 siblings, 0 replies; 62+ messages in thread
From: Manuel Schölling @ 2016-11-29 16:35 UTC (permalink / raw)
  To: Andrey Utkin
  Cc: plagnioj, tomi.valkeinen, jslaby, gregkh, kilobyte, linux-fbdev,
	linux-kernel

Hi Andrey,

On Di, 2016-11-29 at 10:01 +0000, Andrey Utkin wrote:
> Regarding logout scrollback clearing not working for me. ncurses-6.0-rc1
> which I tested it with is the latest available in Gentoo portage, please
> confirm whether I need any newer version, or should I tune something
> else. I'd appreciate if you also tested your patch with gentoo setup.
Are you sure ncurses is involved at all?
My Debian agetty(8) manpage says:

       -J,--noclear
              Do not clear the screen before prompting for the login name (the
              screen is normally cleared).

And digging into the source code of agetty shows these lines [1]:

static void termio_clear(int fd)
{
	/*
	 * Do not write a full reset (ESC c) because this destroys
	 * the unicode mode again if the terminal was in unicode
	 * mode.  Also it clears the CONSOLE_MAGIC features which
	 * are required for some languages/console-fonts.
	 * Just put the cursor to the home position (ESC [ H),
	 * erase everything below the cursor (ESC [ J), and set the
	 * scrolling region to the full window (ESC [ r)
	 */
	write_all(fd, "\033[r\033[H\033[J", 9);
}

So I guess that agetty relies on on switching the console for flushing
the scrollback buffer and we'd had to add the \E[3J sequence here.

Note that up until now I just had a look at the theory (manpage and
source code). I'd need some days to find time to show at runtime that
this really is the reason why the buffer is not flushed.

Bye,

Manuel

[1] https://github.com/karelzak/util-linux/blob/master/term-utils/agetty.c#L1175

^ permalink raw reply	[flat|nested] 62+ messages in thread

* Re: [PATCH v7 0/3] console: Add persistent scrollback buffers for all VGA consoles
  2016-11-29 10:01       ` Andrey Utkin
@ 2016-11-29 10:44         ` Adam Borowski
  2016-11-29 16:35         ` Manuel Schölling
  2016-12-01 21:03         ` Manuel Schölling
  2 siblings, 0 replies; 62+ messages in thread
From: Adam Borowski @ 2016-11-29 10:44 UTC (permalink / raw)
  To: Andrey Utkin
  Cc: Manuel Schölling, plagnioj, tomi.valkeinen, jslaby, gregkh,
	linux-fbdev, linux-kernel

On Tue, Nov 29, 2016 at 10:01:15AM +0000, Andrey Utkin wrote:
> Regarding logout scrollback clearing not working for me. ncurses-6.0-rc1
> which I tested it with is the latest available in Gentoo portage, please
> confirm whether I need any newer version, or should I tune something
> else. I'd appreciate if you also tested your patch with gentoo setup.

Could you please check whether its terminfo carries the required
definitions?  In ncurses sources, that's misc/terminfo.src

The relevant parts are:
.--====
# The 3.0 kernel adds support for clearing scrollback buffer (capability E3).
# It is the same as xterm's erase-saved-lines feature.
linux3.0|linux 3.0 kernels,
        E3=\E[3J, use=linux2.6,

# This is Linux console for ncurses.
linux|linux console,
        use=linux3.0,
`----

I believe the first part was added first; if that's true it's possible this
will work for you:
    TERM=linux3.0 clear


I'm not sure what Gentoo does to clear the console during logout: it might
just invoke "clear" (or its underlying ncurses implementation), it might
carry a copy of Debian's "clear_console"[1], it might do something else
entirely.


Meow!

[1]. It originally came from Ubuntu, forked there from "clear".
-- 
The bill declaring Jesus as the King of Poland fails to specify whether
the addition is at the top or end of the list of kings.  What should the
historians do?

^ permalink raw reply	[flat|nested] 62+ messages in thread

* Re: [PATCH v7 0/3] console: Add persistent scrollback buffers for all VGA consoles
  2016-11-28 21:28     ` Manuel Schölling
@ 2016-11-29 10:01       ` Andrey Utkin
  2016-11-29 10:44         ` Adam Borowski
                           ` (2 more replies)
  0 siblings, 3 replies; 62+ messages in thread
From: Andrey Utkin @ 2016-11-29 10:01 UTC (permalink / raw)
  To: Manuel Schölling
  Cc: plagnioj, tomi.valkeinen, jslaby, gregkh, kilobyte, linux-fbdev,
	linux-kernel

On Mon, Nov 28, 2016 at 10:28:19PM +0100, Manuel Schölling wrote:
> Hi Andrey,
> 
> Adam already discussed some of your notes, but I want to catch up one
> this one:
> 
> On So, 2016-11-27 at 21:37 +0000, Andrey Utkin wrote:
> > I see the user experience is subpar to what I'm accustomed to (I use
> > Konsole and "Clear Scrollback and Reset" action, default shortcut is
> > Ctrl+Shift+K). The strange behaviour moments have nothing to do with
> > current patchset but are properties of vgacon, though. (I compared it
> > with another PC which runs without this patchset, and it looks like it
> > runs vgacon, too, however, I'm not sure how to ensure this at runtime.)
> I'm not sure what you mean with 'subpar'. Ctrl+Shift+K would probably be
> nice - but it might interfere with some shortcuts of programs.
> Are you missing any other features?
> (I am working on persistent scrollback for framebuffer consoles in the
> mean time...)

I meant that in my terminal of choice, I have single action which does
both of these things at same time:
 - scrollback cleaning (also not leaving screen worth of emptiness in
   scrollback)
 - prompt positioning to top line

That's all. I don't appeal to bring Ctrl+Shift+K hotkey or whatever
else.

Since these cosmetic matters are inherent to vgacon I'm fine with it.

Regarding logout scrollback clearing not working for me. ncurses-6.0-rc1
which I tested it with is the latest available in Gentoo portage, please
confirm whether I need any newer version, or should I tune something
else. I'd appreciate if you also tested your patch with gentoo setup.

^ permalink raw reply	[flat|nested] 62+ messages in thread

* Re: [PATCH v7 0/3] console: Add persistent scrollback buffers for all VGA consoles
  2016-11-27 21:37   ` Andrey Utkin
  2016-11-27 23:15     ` Adam Borowski
@ 2016-11-28 21:28     ` Manuel Schölling
  2016-11-29 10:01       ` Andrey Utkin
  1 sibling, 1 reply; 62+ messages in thread
From: Manuel Schölling @ 2016-11-28 21:28 UTC (permalink / raw)
  To: Andrey Utkin
  Cc: plagnioj, tomi.valkeinen, jslaby, gregkh, kilobyte, linux-fbdev,
	linux-kernel

Hi Andrey,

Adam already discussed some of your notes, but I want to catch up one
this one:

On So, 2016-11-27 at 21:37 +0000, Andrey Utkin wrote:
> I see the user experience is subpar to what I'm accustomed to (I use
> Konsole and "Clear Scrollback and Reset" action, default shortcut is
> Ctrl+Shift+K). The strange behaviour moments have nothing to do with
> current patchset but are properties of vgacon, though. (I compared it
> with another PC which runs without this patchset, and it looks like it
> runs vgacon, too, however, I'm not sure how to ensure this at runtime.)
I'm not sure what you mean with 'subpar'. Ctrl+Shift+K would probably be
nice - but it might interfere with some shortcuts of programs.
Are you missing any other features?
(I am working on persistent scrollback for framebuffer consoles in the
mean time...)

Bye,

Manuel

^ permalink raw reply	[flat|nested] 62+ messages in thread

* Re: [PATCH v7 0/3] console: Add persistent scrollback buffers for all VGA consoles
  2016-11-27 23:53   ` Adam Borowski
@ 2016-11-28 21:23     ` Manuel Schölling
  0 siblings, 0 replies; 62+ messages in thread
From: Manuel Schölling @ 2016-11-28 21:23 UTC (permalink / raw)
  To: Adam Borowski
  Cc: plagnioj, tomi.valkeinen, jslaby, gregkh, andrey_utkin,
	linux-fbdev, linux-kernel

On Mo, 2016-11-28 at 00:53 +0100, Adam Borowski wrote:
> \e[3J works well now, thanks!
Great to hear that!

> Tested-by: Adam Borowski <kilobyte@angband.pl>
Thanks, Adam, for spending all this time testing the patches!

^ permalink raw reply	[flat|nested] 62+ messages in thread

* Re: [PATCH v7 0/3] console: Add persistent scrollback buffers for all VGA consoles
  2016-11-27 23:15     ` Adam Borowski
  2016-11-27 23:30       ` Jakub Wilk
@ 2016-11-28  0:02       ` Andrey Utkin
  1 sibling, 0 replies; 62+ messages in thread
From: Andrey Utkin @ 2016-11-28  0:02 UTC (permalink / raw)
  To: Adam Borowski
  Cc: Manuel Schölling, plagnioj, tomi.valkeinen, jslaby, gregkh,
	linux-fbdev, linux-kernel

On Mon, Nov 28, 2016 at 12:15:48AM +0100, Adam Borowski wrote:
> On Sun, Nov 27, 2016 at 09:37:30PM +0000, Andrey Utkin wrote:
> > I've just patched next-20161125 with this set and given it a run.
> > 
> > Scrollback persistence works fine, just as in earlier versions.
> > 
> > This time I didn't forget to test clear operation.
> > 
> > The only important concern is that after logout, the scrollback is not
> > wiped by /bin/login or /sbin/agetty (not sure who of them is responsible
> > for that). What do you see on your workstations in this case?
> 
> If you're on Debian or a derivative, that's clear_console.  It uses a
> switch-vt-then-back hack which obviously doesn't work with scrollback
> persistence.  Reported as https://bugs.debian.org/845177 -- I'll molest the
> maintainer if the patch doesn't get applied soon, so we can have the fix in
> time for stretch (then Ubuntu zesty).

I'm on Gentoo.

> Because of a sad lack of a time machine, old systems will use clear_console
> with that hack until they die, that's why
> CONFIG_VGACON_SOFT_SCROLLBACK_PERSISTENT defaults to n; in a few years it'll
> be ok to flip it.
> 
> > I guess we need to do something of the following:
> >  - catch some control character sequences to wipe the scrollback
> 
> \e[3J
> 
> >  - indicate (by some flag) some feature capability for this
> 
> Terminfo calls this flag "E3".
> 
> >  - request update in terminfo database or whatever, to let ncurses know
> >    that it is capable of scrollback wiping by some control charater
> >    sequences
> 
> Already there for quite a while.
> 
> > clear(1) doesn't wipe the scrollback at all, it is still reachable, all
> > of it.
> 
> It does for me on the console.  The man page says:
> 
> # clear clears your screen if this is possible, including its scrollback
> # buffer (if the extended "E3" capability is defined).  clear looks in the
> # environment for the terminal type and then in the terminfo database to
> # determine how to clear the screen.
> 
> Because of its reliance on terminfo, you need to have TERM=linux in your
> environment; also, screen/tmux obviously breaks this.

I wonder whether my ncurses is not bleeding-edge enough, or I have some
non-standard config. Anyway, thanks for explanation.

> > echo -e "\e[3J" seems to wipe the scrollback, but if you do it several
> > times in a row, every time you (or at last I do) get your prompt a bit
> > lower, so after many times you end up with blank screen and the prompt
> > at the bottom of the screen.
> 
> Yeah, none of \e[J subcommands move the cursor at all.  As you use echo
> without -n, you move two lines lower, and even with -n the command you typed
> takes a line.  You want to move the cursor explicitly, add "\e[H".

Thanks for explanation.

^ permalink raw reply	[flat|nested] 62+ messages in thread

* Re: [PATCH v7 0/3] console: Add persistent scrollback buffers for all VGA consoles
  2016-11-27 16:51 ` [PATCH v7 0/3] " Manuel Schölling
  2016-11-27 21:37   ` Andrey Utkin
@ 2016-11-27 23:53   ` Adam Borowski
  2016-11-28 21:23     ` Manuel Schölling
  1 sibling, 1 reply; 62+ messages in thread
From: Adam Borowski @ 2016-11-27 23:53 UTC (permalink / raw)
  To: Manuel Schölling
  Cc: plagnioj, tomi.valkeinen, jslaby, gregkh, andrey_utkin,
	linux-fbdev, linux-kernel

\e[3J works well now, thanks!

I haven't found any more problems; your changes also appear to make no
regressions in at least nouveau fb (which obviously doesn't have this goodie
yet).

Patch 2 doesn't apply cleanly on current Linus' tree but it's just a matter
of more fuzz than "git am" allows.

Tested-by: Adam Borowski <kilobyte@angband.pl>


Meow!
-- 
The bill declaring Jesus as the King of Poland fails to specify whether
the addition is at the top or end of the list of kings.  What should the
historians do?

^ permalink raw reply	[flat|nested] 62+ messages in thread

* Re: [PATCH v7 0/3] console: Add persistent scrollback buffers for all VGA consoles
  2016-11-27 23:15     ` Adam Borowski
@ 2016-11-27 23:30       ` Jakub Wilk
  2016-11-28  0:02       ` Andrey Utkin
  1 sibling, 0 replies; 62+ messages in thread
From: Jakub Wilk @ 2016-11-27 23:30 UTC (permalink / raw)
  To: Adam Borowski
  Cc: Andrey Utkin, Manuel Schölling, plagnioj, tomi.valkeinen,
	jslaby, gregkh, linux-fbdev, linux-kernel

* Adam Borowski <kilobyte@angband.pl>, 2016-11-28, 00:15:
>>clear(1) doesn't wipe the scrollback at all, it is still reachable, all of 
>>it.
>
>It does for me on the console.  The man page says:
>
># clear clears your screen if this is possible, including its scrollback
># buffer (if the extended "E3" capability is defined).  clear looks in the
># environment for the terminal type and then in the terminfo database to
># determine how to clear the screen.
>
>Because of its reliance on terminfo, you need to have TERM=linux in your 
>environment; also, screen/tmux obviously breaks this.

The "linux" terminfo entry didn't have E3 until very recently.
You will need ncurses >= 20160514.

-- 
Jakub Wilk

^ permalink raw reply	[flat|nested] 62+ messages in thread

* Re: [PATCH v7 0/3] console: Add persistent scrollback buffers for all VGA consoles
  2016-11-27 21:37   ` Andrey Utkin
@ 2016-11-27 23:15     ` Adam Borowski
  2016-11-27 23:30       ` Jakub Wilk
  2016-11-28  0:02       ` Andrey Utkin
  2016-11-28 21:28     ` Manuel Schölling
  1 sibling, 2 replies; 62+ messages in thread
From: Adam Borowski @ 2016-11-27 23:15 UTC (permalink / raw)
  To: Andrey Utkin
  Cc: Manuel Schölling, plagnioj, tomi.valkeinen, jslaby, gregkh,
	linux-fbdev, linux-kernel

On Sun, Nov 27, 2016 at 09:37:30PM +0000, Andrey Utkin wrote:
> I've just patched next-20161125 with this set and given it a run.
> 
> Scrollback persistence works fine, just as in earlier versions.
> 
> This time I didn't forget to test clear operation.
> 
> The only important concern is that after logout, the scrollback is not
> wiped by /bin/login or /sbin/agetty (not sure who of them is responsible
> for that). What do you see on your workstations in this case?

If you're on Debian or a derivative, that's clear_console.  It uses a
switch-vt-then-back hack which obviously doesn't work with scrollback
persistence.  Reported as https://bugs.debian.org/845177 -- I'll molest the
maintainer if the patch doesn't get applied soon, so we can have the fix in
time for stretch (then Ubuntu zesty).

Because of a sad lack of a time machine, old systems will use clear_console
with that hack until they die, that's why
CONFIG_VGACON_SOFT_SCROLLBACK_PERSISTENT defaults to n; in a few years it'll
be ok to flip it.

> I guess we need to do something of the following:
>  - catch some control character sequences to wipe the scrollback

\e[3J

>  - indicate (by some flag) some feature capability for this

Terminfo calls this flag "E3".

>  - request update in terminfo database or whatever, to let ncurses know
>    that it is capable of scrollback wiping by some control charater
>    sequences

Already there for quite a while.

> clear(1) doesn't wipe the scrollback at all, it is still reachable, all
> of it.

It does for me on the console.  The man page says:

# clear clears your screen if this is possible, including its scrollback
# buffer (if the extended "E3" capability is defined).  clear looks in the
# environment for the terminal type and then in the terminfo database to
# determine how to clear the screen.

Because of its reliance on terminfo, you need to have TERM=linux in your
environment; also, screen/tmux obviously breaks this.

> echo -e "\e[3J" seems to wipe the scrollback, but if you do it several
> times in a row, every time you (or at last I do) get your prompt a bit
> lower, so after many times you end up with blank screen and the prompt
> at the bottom of the screen.

Yeah, none of \e[J subcommands move the cursor at all.  As you use echo
without -n, you move two lines lower, and even with -n the command you typed
takes a line.  You want to move the cursor explicitly, add "\e[H".


Meow!
-- 
The bill declaring Jesus as the King of Poland fails to specify whether
the addition is at the top or end of the list of kings.  What should the
historians do?

^ permalink raw reply	[flat|nested] 62+ messages in thread

* Re: [PATCH v7 0/3] console: Add persistent scrollback buffers for all VGA consoles
  2016-11-27 16:51 ` [PATCH v7 0/3] " Manuel Schölling
@ 2016-11-27 21:37   ` Andrey Utkin
  2016-11-27 23:15     ` Adam Borowski
  2016-11-28 21:28     ` Manuel Schölling
  2016-11-27 23:53   ` Adam Borowski
  1 sibling, 2 replies; 62+ messages in thread
From: Andrey Utkin @ 2016-11-27 21:37 UTC (permalink / raw)
  To: Manuel Schölling
  Cc: plagnioj, tomi.valkeinen, jslaby, gregkh, kilobyte, linux-fbdev,
	linux-kernel

Hi Manuel,

I've just patched next-20161125 with this set and given it a run.

Scrollback persistence works fine, just as in earlier versions.

This time I didn't forget to test clear operation.

The only important concern is that after logout, the scrollback is not
wiped by /bin/login or /sbin/agetty (not sure who of them is responsible
for that). What do you see on your workstations in this case?

I guess we need to do something of the following:
 - catch some control character sequences to wipe the scrollback
 - indicate (by some flag) some feature capability for this
 - request update in terminfo database or whatever, to let ncurses know
   that it is capable of scrollback wiping by some control charater
   sequences


Some useless notes follow.

I see the user experience is subpar to what I'm accustomed to (I use
Konsole and "Clear Scrollback and Reset" action, default shortcut is
Ctrl+Shift+K). The strange behaviour moments have nothing to do with
current patchset but are properties of vgacon, though. (I compared it
with another PC which runs without this patchset, and it looks like it
runs vgacon, too, however, I'm not sure how to ensure this at runtime.)

clear(1) doesn't wipe the scrollback at all, it is still reachable, all
of it.

echo -e "\e[3J" seems to wipe the scrollback, but if you do it several
times in a row, every time you (or at last I do) get your prompt a bit
lower, so after many times you end up with blank screen and the prompt
at the bottom of the screen.

Have you encountered this, or is it something specific to my setup (I
use bash prompt spanning to multiple lines, and calling "stty sane" from
inside every PS1 evaluation. I can share the config if you request it).

^ permalink raw reply	[flat|nested] 62+ messages in thread

* [PATCH v7 0/3] console: Add persistent scrollback buffers for all VGA consoles
  2016-11-23 17:33 [PATCH v5 2/2] " Adam Borowski
@ 2016-11-27 16:51 ` Manuel Schölling
  2016-11-27 21:37   ` Andrey Utkin
  2016-11-27 23:53   ` Adam Borowski
  0 siblings, 2 replies; 62+ messages in thread
From: Manuel Schölling @ 2016-11-27 16:51 UTC (permalink / raw)
  To: plagnioj, tomi.valkeinen
  Cc: manuel.schoelling, jslaby, gregkh, andrey_utkin, kilobyte,
	linux-fbdev, linux-kernel

Changes in v7:
  - Add new callback to consw struct for flushing video console driver's
    scrollback buffer. Fixes issues with escape sequence '\e[3J' reported
    by Adam Borowski (kilobyte@angband.pl).
  - Fix style issues
Changes in v6:
  - Change of check if feature is enabled in 
    vgacon_scrollback_switch()
Changes in v5:
  - Clearify documentation
  - Skip superfluous array initialization
  - Disable scrollback if buffer allocation fails
  - Refactor vgacon_switch_scrollback()
  - Rename vgacon_switch_scrollback() to vgacon_scrollback_switch()
  - Add check for fg_console in vgacon_scrollback_update
Changes in v4.1:
  - Fix compiler error
Changes in v4:
  - Rename from VGACON_SOFT_SCROLLBACK_FOR_EACH_CONSOLE to
    VGACON_SOFT_SCROLLBACK_PERSISTENT
  - Split into two patches
  - Rework documentation
  - Remove cosmetic changes in comments (postponed)
Changes in v3:
  - Add config option for this feature
  - Fallback to old scrollback buffer if kcalloc() fails
  - Remove ioctl() call again and add documentation about existing
    escape sequence to flush the scrollback buffer
Changes in v2:
  - Add ioctl() call to flush scrollback buffer
  - (Patch v2 was not labeled as such, sorry)

Manuel Schölling (3):
  console: Move scrollback data into its own struct
  console: Add callback to flush scrollback buffer to consw struct
  console: Add persistent scrollback buffers for all VGA consoles

 drivers/tty/vt/vt.c            |   9 +++
 drivers/video/console/Kconfig  |  25 ++++++-
 drivers/video/console/vgacon.c | 165 ++++++++++++++++++++++++++++-------------
 include/linux/console.h        |   4 +
 4 files changed, 148 insertions(+), 55 deletions(-)

-- 
2.1.4

^ permalink raw reply	[flat|nested] 62+ messages in thread

end of thread, other threads:[~2017-02-03 16:46 UTC | newest]

Thread overview: 62+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-12-04 10:53 [PATCH v7 0/3] console: Add persistent scrollback buffers for all VGA consoles Manuel Schölling
2016-12-04 10:53 ` [PATCH v7 1/3] console: Move scrollback data into its own struct Manuel Schölling
2016-12-04 10:53 ` [PATCH v7 2/3] console: Add callback to flush scrollback buffer to consw struct Manuel Schölling
2016-12-04 10:53 ` [PATCH v7 3/3] console: Add persistent scrollback buffers for all VGA consoles Manuel Schölling
2016-12-06 10:02 ` [PATCH v7 0/3] " Greg KH
2016-12-06 16:32   ` Manuel Schölling
2016-12-21 16:37 ` [PATCH RESEND " Manuel Schölling
2016-12-21 16:37   ` [PATCH RESEND v7 1/3] console: Move scrollback data into its own struct Manuel Schölling
2016-12-21 16:37   ` [PATCH RESEND v7 2/3] console: Add callback to flush scrollback buffer to consw struct Manuel Schölling
2016-12-21 16:37   ` [PATCH RESEND v7 3/3] console: Add persistent scrollback buffers for all VGA consoles Manuel Schölling
2017-01-04 13:54   ` [PATCH RESEND v7 0/3] " Andrey Utkin
2017-01-05 11:33     ` [PATCH v8 " Manuel Schölling
2017-01-05 11:33     ` [PATCH v8 1/3] console: Move scrollback data into its own struct Manuel Schölling
2017-01-05 11:33     ` [PATCH v8 2/3] console: Add callback to flush scrollback buffer to consw struct Manuel Schölling
2017-01-05 11:33     ` [PATCH v8 3/3] console: Add persistent scrollback buffers for all VGA consoles Manuel Schölling
     [not found]       ` <CGME20170110162224epcas1p2095912fa6b73a1457fa86396149e78e9@epcas1p2.samsung.com>
2017-01-10 16:22         ` Bartlomiej Zolnierkiewicz
     [not found]           ` <CGME20170110164435epcas1p314efb9c6ea3ffb971fce06f3bfaec736@epcas1p3.samsung.com>
2017-01-10 16:44             ` Bartlomiej Zolnierkiewicz
2017-01-10 17:31               ` Manuel Schölling
2017-01-10 21:28               ` [PATCH v9 0/4] " Manuel Schölling
2017-01-10 21:28               ` [PATCH v9 1/4] console: Move scrollback data into its own struct Manuel Schölling
2017-01-10 21:28               ` [PATCH v9 2/4] console: Add callback to flush scrollback buffer to consw struct Manuel Schölling
2017-01-10 21:28               ` [PATCH v9 3/4] console: Add persistent scrollback buffers for all VGA consoles Manuel Schölling
2017-01-10 21:28               ` [PATCH v9 4/4] console: Make persistent scrollback a boot parameter Manuel Schölling
2017-01-10 22:58                 ` Adam Borowski
2017-01-11 21:41                   ` Manuel Schölling
2017-01-13 20:00                   ` Manuel Schölling
2017-01-14  7:26                     ` Greg KH
2017-01-11 13:32                 ` kbuild test robot
2017-01-13 20:07                   ` [PATCH v10 0/4] console: Add persistent scrollback buffers for all VGA consoles Manuel Schölling
2017-01-25 10:55                     ` Greg KH
2017-01-13 20:07                   ` [PATCH v10 1/4] console: Move scrollback data into its own struct Manuel Schölling
2017-01-13 20:07                   ` [PATCH v10 2/4] console: Add callback to flush scrollback buffer to consw struct Manuel Schölling
2017-01-13 20:07                   ` [PATCH v10 3/4] console: Add persistent scrollback buffers for all VGA consoles Manuel Schölling
2017-01-19 13:23                     ` Greg KH
2017-01-19 16:12                       ` Manuel Schölling
2017-01-19 16:33                         ` Greg KH
2017-01-19 23:04                           ` Adam Borowski
2017-01-20 13:16                             ` Adam Borowski
2017-01-20 13:31                               ` Greg KH
2017-01-20 14:27                                 ` Adam Borowski
2017-01-19 17:20                         ` Adam Borowski
2017-01-13 20:07                   ` [PATCH v10 4/4] console: Make persistent scrollback a boot parameter Manuel Schölling
2017-02-02 20:07                 ` [PATCH v9 " Paul Gortmaker
2017-02-03 16:04                   ` Manuel Schölling
2017-02-03 16:45                     ` Adam Borowski
2017-01-02 14:27 ` [PATCH RESEND v7 0/3] console: Add persistent scrollback buffers for all VGA consoles Manuel Schölling
2017-01-02 14:27   ` [PATCH RESEND v7 1/3] console: Move scrollback data into its own struct Manuel Schölling
2017-01-02 14:27   ` [PATCH RESEND v7 2/3] console: Add callback to flush scrollback buffer to consw struct Manuel Schölling
2017-01-02 14:27   ` [PATCH RESEND v7 3/3] console: Add persistent scrollback buffers for all VGA consoles Manuel Schölling
  -- strict thread matches above, loose matches on Subject: below --
2016-11-23 17:33 [PATCH v5 2/2] " Adam Borowski
2016-11-27 16:51 ` [PATCH v7 0/3] " Manuel Schölling
2016-11-27 21:37   ` Andrey Utkin
2016-11-27 23:15     ` Adam Borowski
2016-11-27 23:30       ` Jakub Wilk
2016-11-28  0:02       ` Andrey Utkin
2016-11-28 21:28     ` Manuel Schölling
2016-11-29 10:01       ` Andrey Utkin
2016-11-29 10:44         ` Adam Borowski
2016-11-29 16:35         ` Manuel Schölling
2016-12-01 21:03         ` Manuel Schölling
2016-12-01 21:31           ` Andrey Utkin
2016-11-27 23:53   ` Adam Borowski
2016-11-28 21:23     ` Manuel Schölling

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).