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@xxxxxx> > > > Reviewed-by: Andrey Utkin <andrey_utkin@xxxxxxxxxxxx> > > > Tested-by: Andrey Utkin <andrey_utkin@xxxxxxxxxxxx> > > > Tested-by: Adam Borowski <kilobyte@xxxxxxxxxx> > > > --- > > > 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 */ > > > } > > -- To unsubscribe from this list: send the line "unsubscribe linux-fbdev" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html