Re: [PATCH v3] console: Add persistent scrollback buffers for all VGA consoles
Hi Tomi, I thought I'd let you, Tomi, (and all the others) know what the patch does: There is currently a single scrollback buffer (vgacon_scrollback) that contains the text of the current console. When you switch the console it is cleared and re-used for the new console. My patch simply replaced the single scrollback buffer with an array of scrollback buffers. One for each console. A quick shout out to everybody else: Tomi told me today that he is currently short on time to review this patch, so any Reviewed-by or Tested-by would be very appreciated. Bye, Manuel On Mo, 2016-09-19 at 00:06 +0200, 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. > > It always annoys me when I switch back to a console and I can just > read half of an error backtrace. This should fix issues like these. > > 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 > --- > 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) > --- > drivers/video/console/Kconfig | 23 +- > drivers/video/console/vgacon.c | 160 > +++-- > 2 files changed, 128 insertions(+), 55 deletions(-) > > diff --git a/drivers/video/console/Kconfig b/drivers/video/console/Kconfig > index 38da6e2..67e52f0 100644 > --- a/drivers/video/console/Kconfig > +++ b/drivers/video/console/Kconfig > @@ -43,9 +43,26 @@ 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_FOR_EACH_CONSOLE > + bool "Persistent Scrollback History for each console" > + depends on VGACON_SOFT_SCROLLBACK > + default n > + help > + Say Y here if for each VGA console a scrollback buffer should > + be allocated. The scrollback history will persist when switching > + between consoles. If you say N here, scrollback is only supported > + for the active VGA console and scrollback history will be flushed > + when switching between consoles. > + > + This breaks legacy versions of tools like clear_console which > + might cause security issues. > + Use the escape sequence \e[3J instead if this feature is activated. > + > + 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 1157661..e70e8fe 100644 > --- a/drivers/video/console/vgacon.c > +++ b/drivers/video/console/vgacon.c > @@ -1,5 +1,5 @@ > /* > - * linux/drivers/video/vgacon.c -- Low level VGA based console driver > + * linux/drivers/video/console/vgacon.c -- Low level VGA based console > driver > * > * Created 28 Sep 1997 by Geert Uytterhoeven > * > @@ -181,70 +181,125 @@ 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 void vgacon_scrollback_init(int pitch) > +struct vgacon_scrollback_info { > + void *data; > + int tail; > + int size; > + int rows; > + int cnt; > + int cur; > + int save; > + int restore; > +}; > +static struct vgacon_scrollback_info *vgacon_scrollback_cur; > +#ifdef CONFIG_VGACON_SOFT_SCROLLBACK_
[PATCH v3] console: Add persistent scrollback buffers for all VGA consoles
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. It always annoys me when I switch back to a console and I can just read half of an error backtrace. This should fix issues like these. 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 --- 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) --- drivers/video/console/Kconfig | 23 +- drivers/video/console/vgacon.c | 160 +++-- 2 files changed, 128 insertions(+), 55 deletions(-) diff --git a/drivers/video/console/Kconfig b/drivers/video/console/Kconfig index 38da6e2..67e52f0 100644 --- a/drivers/video/console/Kconfig +++ b/drivers/video/console/Kconfig @@ -43,9 +43,26 @@ 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_FOR_EACH_CONSOLE + bool "Persistent Scrollback History for each console" + depends on VGACON_SOFT_SCROLLBACK + default n + help + Say Y here if for each VGA console a scrollback buffer should + be allocated. The scrollback history will persist when switching + between consoles. If you say N here, scrollback is only supported + for the active VGA console and scrollback history will be flushed + when switching between consoles. + + This breaks legacy versions of tools like clear_console which + might cause security issues. + Use the escape sequence \e[3J instead if this feature is activated. + + 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 1157661..e70e8fe 100644 --- a/drivers/video/console/vgacon.c +++ b/drivers/video/console/vgacon.c @@ -1,5 +1,5 @@ /* - * linux/drivers/video/vgacon.c -- Low level VGA based console driver + * linux/drivers/video/console/vgacon.c -- Low level VGA based console driver * * Created 28 Sep 1997 by Geert Uytterhoeven * @@ -181,70 +181,125 @@ 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 void vgacon_scrollback_init(int pitch) +struct vgacon_scrollback_info { + void *data; + int tail; + int size; + int rows; + int cnt; + int cur; + int save; + int restore; +}; +static struct vgacon_scrollback_info *vgacon_scrollback_cur; +#ifdef CONFIG_VGACON_SOFT_SCROLLBACK_FOR_EACH_CONSOLE +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) { - 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_cur->data && reset_size > 0) + memset(vgacon_scrollback_cur->data, 0, reset_size); + + vgacon_scrollback_cur->cnt = 0; + vgacon_scrollback_cur->tail = 0; + vgacon_scrollback_cur->cur = 0; +} + +static void vgacon_scrollback_init(int vc_num) +{ + int pitch = vga_video_num_columns * 2; + size_t size = CONFIG_VGACON_SOFT_SCROLLBACK_SIZE * 1024; + int rows = size/pitch; + void *data; + + data = kcalloc(CONFIG_VG
[PATCH v3] console: Add persistent scrollback buffers for all VGA consoles
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. It always annoys me when I switch back to a console and I can just read half of an error backtrace. This should fix issues like these. 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 --- 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) --- drivers/video/console/Kconfig | 23 +- drivers/video/console/vgacon.c | 160 +++-- 2 files changed, 128 insertions(+), 55 deletions(-) diff --git a/drivers/video/console/Kconfig b/drivers/video/console/Kconfig index 38da6e2..67e52f0 100644 --- a/drivers/video/console/Kconfig +++ b/drivers/video/console/Kconfig @@ -43,9 +43,26 @@ 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_FOR_EACH_CONSOLE + bool "Persistent Scrollback History for each console" + depends on VGACON_SOFT_SCROLLBACK + default n + help + Say Y here if for each VGA console a scrollback buffer should + be allocated. The scrollback history will persist when switching + between consoles. If you say N here, scrollback is only supported + for the active VGA console and scrollback history will be flushed + when switching between consoles. + + This breaks legacy versions of tools like clear_console which + might cause security issues. + Use the escape sequence \e[3J instead if this feature is activated. + + 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 1157661..e70e8fe 100644 --- a/drivers/video/console/vgacon.c +++ b/drivers/video/console/vgacon.c @@ -1,5 +1,5 @@ /* - * linux/drivers/video/vgacon.c -- Low level VGA based console driver + * linux/drivers/video/console/vgacon.c -- Low level VGA based console driver * * Created 28 Sep 1997 by Geert Uytterhoeven * @@ -181,70 +181,125 @@ 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 void vgacon_scrollback_init(int pitch) +struct vgacon_scrollback_info { + void *data; + int tail; + int size; + int rows; + int cnt; + int cur; + int save; + int restore; +}; +static struct vgacon_scrollback_info *vgacon_scrollback_cur; +#ifdef CONFIG_VGACON_SOFT_SCROLLBACK_FOR_EACH_CONSOLE +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) { - 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_cur->data && reset_size > 0) + memset(vgacon_scrollback_cur->data, 0, reset_size); + + vgacon_scrollback_cur->cnt = 0; + vgacon_scrollback_cur->tail = 0; + vgacon_scrollback_cur->cur = 0; +} + +static void vgacon_scrollback_init(int vc_num) +{ + int pitch = vga_video_num_columns * 2; + size_t size = CONFIG_VGACON_SOFT_SCROLLBACK_SIZE * 1024; + int rows = size/pitch; + void *data; + + data = kcalloc(CONFIG_VG
[PATCH] ntfs: Cleanup string initializations (char[] instead of char *)
Initializations like 'char *foo = "bar"' will create two variables: a static string and a pointer (foo) to that static string. Instead 'char foo[] = "bar"' will allocate only a declare a single variable and will end up in shorter assembly (according to Jeff Garzik on the KernelJanitor's TODO list). Signed-off-by: Manuel Schölling --- fs/ntfs/inode.c |2 +- fs/ntfs/super.c |2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/fs/ntfs/inode.c b/fs/ntfs/inode.c index f47af5e..3975798 100644 --- a/fs/ntfs/inode.c +++ b/fs/ntfs/inode.c @@ -2368,7 +2368,7 @@ int ntfs_truncate(struct inode *vi) ntfs_attr_search_ctx *ctx; MFT_RECORD *m; ATTR_RECORD *a; - const char *te = " Leaving file length out of sync with i_size."; + const char te[] = " Leaving file length out of sync with i_size."; int err, mp_size, size_change, alloc_change; u32 attr_len; diff --git a/fs/ntfs/super.c b/fs/ntfs/super.c index 9de2491..eb2c195 100644 --- a/fs/ntfs/super.c +++ b/fs/ntfs/super.c @@ -676,7 +676,7 @@ not_ntfs: static struct buffer_head *read_ntfs_boot_sector(struct super_block *sb, const int silent) { - const char *read_err_str = "Unable to read %s boot sector."; + const char read_err_str[] = "Unable to read %s boot sector."; struct buffer_head *bh_primary, *bh_backup; sector_t nr_blocks = NTFS_SB(sb)->nr_blocks; -- 1.7.10.4 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH] pinctrl: Cleanup string initializations (char[] instead of char *)
Initializations like 'char *foo = "bar"' will create two variables: a static string and a pointer (foo) to that static string. Instead 'char foo[] = "bar"' will declare a single variable and will end up in shorter assembly (according to Jeff Garzik on the KernelJanitor's TODO list). Signed-off-by: Manuel Schölling --- drivers/pinctrl/pinctrl-mxs.c|6 +++--- drivers/pinctrl/pinctrl-single.c |4 ++-- drivers/pinctrl/pinctrl-tegra.c |2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/pinctrl/pinctrl-mxs.c b/drivers/pinctrl/pinctrl-mxs.c index 40c76f2..cd4215e 100644 --- a/drivers/pinctrl/pinctrl-mxs.c +++ b/drivers/pinctrl/pinctrl-mxs.c @@ -351,7 +351,7 @@ static int mxs_pinctrl_parse_group(struct platform_device *pdev, struct mxs_pinctrl_data *d = platform_get_drvdata(pdev); struct mxs_group *g = &d->soc->groups[idx]; struct property *prop; - const char *propname = "fsl,pinmux-ids"; + const char propname[] = "fsl,pinmux-ids"; char *group; int length = strlen(np->name) + SUFFIX_LEN; u32 val, i; @@ -399,8 +399,8 @@ static int mxs_pinctrl_probe_dt(struct platform_device *pdev, struct device_node *np = pdev->dev.of_node; struct device_node *child; struct mxs_function *f; - const char *gpio_compat = "fsl,mxs-gpio"; - const char *fn, *fnull = ""; + const char gpio_compat[] = "fsl,mxs-gpio"; + const char *fn, fnull[] = ""; int i = 0, idxf = 0, idxg = 0; int ret; u32 val; diff --git a/drivers/pinctrl/pinctrl-single.c b/drivers/pinctrl/pinctrl-single.c index 2960557..a3ed99f 100644 --- a/drivers/pinctrl/pinctrl-single.c +++ b/drivers/pinctrl/pinctrl-single.c @@ -1561,8 +1561,8 @@ static struct of_device_id pcs_of_match[]; static int pcs_add_gpio_func(struct device_node *node, struct pcs_device *pcs) { - const char *propname = "pinctrl-single,gpio-range"; - const char *cellname = "#pinctrl-single,gpio-range-cells"; + const char propname[] = "pinctrl-single,gpio-range"; + const char cellname[] = "#pinctrl-single,gpio-range-cells"; struct of_phandle_args gpiospec; struct pcs_gpiofunc_range *range; int ret, i; diff --git a/drivers/pinctrl/pinctrl-tegra.c b/drivers/pinctrl/pinctrl-tegra.c index 6545809..43eeb1b 100644 --- a/drivers/pinctrl/pinctrl-tegra.c +++ b/drivers/pinctrl/pinctrl-tegra.c @@ -576,7 +576,7 @@ static void tegra_pinconf_config_dbg_show(struct pinctrl_dev *pctldev, { enum tegra_pinconf_param param = TEGRA_PINCONF_UNPACK_PARAM(config); u16 arg = TEGRA_PINCONF_UNPACK_ARG(config); - const char *pname = "unknown"; + const char pname[] = "unknown"; int i; for (i = 0; i < ARRAY_SIZE(cfg_params); i++) { -- 1.7.10.4 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH] fs: Cleanup string initializations (char[] instead of char *)
Initializations like 'char *foo = "bar"' will create two variables: a static string and a pointer (foo) to that static string. Instead 'char foo[] = "bar"' will declare a single variable and will end up in shorter assembly (according to Jeff Garzik on the KernelJanitor's TODO list). Signed-off-by: Manuel Schölling --- fs/binfmt_misc.c |2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/binfmt_misc.c b/fs/binfmt_misc.c index b605003..2a10529 100644 --- a/fs/binfmt_misc.c +++ b/fs/binfmt_misc.c @@ -419,7 +419,7 @@ static void entry_status(Node *e, char *page) { char *dp; char *status = "disabled"; - const char * flags = "flags: "; + const char flags[] = "flags: "; if (test_bit(Enabled, &e->flags)) status = "enabled"; -- 1.7.10.4 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH] fs: FAT: Cleanup string initializations (char[] instead of char *)
Initializations like 'char *foo = "bar"' will create two variables: a static string and a pointer (foo) to that static string. Instead 'char foo[] = "bar"' will declare a single variable and will end up in shorter assembly (according to Jeff Garzik on the KernelJanitor's TODO list). Signed-off-by: Manuel Schölling --- fs/fat/inode.c |2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/fat/inode.c b/fs/fat/inode.c index b3361fe..8b7d00e 100644 --- a/fs/fat/inode.c +++ b/fs/fat/inode.c @@ -359,7 +359,7 @@ struct inode *fat_iget(struct super_block *sb, loff_t i_pos) static int is_exec(unsigned char *extension) { - unsigned char *exe_extensions = "EXECOMBAT", *walk; + unsigned char exe_extensions[] = "EXECOMBAT", *walk; for (walk = exe_extensions; *walk; walk += 3) if (!strncmp(extension, walk, 3)) -- 1.7.10.4 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH] net: 8390: use time_after() for time comparison
To be future-proof and for better readability the time comparisons are modified to use time_after() instead of raw math. Signed-off-by: Manuel Schölling --- drivers/net/ethernet/8390/ax88796.c |4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/8390/ax88796.c b/drivers/net/ethernet/8390/ax88796.c index 455d4c3..1d162cc 100644 --- a/drivers/net/ethernet/8390/ax88796.c +++ b/drivers/net/ethernet/8390/ax88796.c @@ -157,7 +157,7 @@ static void ax_reset_8390(struct net_device *dev) /* This check _should_not_ be necessary, omit eventually. */ while ((ei_inb(addr + EN0_ISR) & ENISR_RESET) == 0) { - if (jiffies - reset_start_time > 2 * HZ / 100) { + if (time_after(jiffies, reset_start_time + 2 * HZ / 100)) { netdev_warn(dev, "%s: did not complete.\n", __func__); break; } @@ -293,7 +293,7 @@ static void ax_block_output(struct net_device *dev, int count, dma_start = jiffies; while ((ei_inb(nic_base + EN0_ISR) & ENISR_RDC) == 0) { - if (jiffies - dma_start > 2 * HZ / 100) { /* 20ms */ + if (time_after(jiffies, dma_start + 2 * HZ / 100)) { /* 20ms */ netdev_warn(dev, "timeout waiting for Tx RDC.\n"); ax_reset_8390(dev); ax_NS8390_init(dev, 1); -- 1.7.10.4 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH] net: rds: Use time_after() for time comparison
To be future-proof and for better readability the time comparisons are modified to use time_after() instead of raw math. Signed-off-by: Manuel Schölling --- net/rds/ib_send.c |4 ++-- net/rds/iw_send.c |4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/net/rds/ib_send.c b/net/rds/ib_send.c index 37be6e2..1dde91e 100644 --- a/net/rds/ib_send.c +++ b/net/rds/ib_send.c @@ -298,7 +298,7 @@ void rds_ib_send_cq_comp_handler(struct ib_cq *cq, void *context) rds_ib_stats_inc(s_ib_tx_cq_event); if (wc.wr_id == RDS_IB_ACK_WR_ID) { - if (ic->i_ack_queued + HZ/2 < jiffies) + if (time_after(jiffies, ic->i_ack_queued + HZ/2)) rds_ib_stats_inc(s_ib_tx_stalled); rds_ib_ack_send_complete(ic); continue; @@ -315,7 +315,7 @@ void rds_ib_send_cq_comp_handler(struct ib_cq *cq, void *context) rm = rds_ib_send_unmap_op(ic, send, wc.status); - if (send->s_queued + HZ/2 < jiffies) + if (time_after(jiffies, send->s_queued + HZ/2)) rds_ib_stats_inc(s_ib_tx_stalled); if (send->s_op) { diff --git a/net/rds/iw_send.c b/net/rds/iw_send.c index e40c3c5..9105ea0 100644 --- a/net/rds/iw_send.c +++ b/net/rds/iw_send.c @@ -232,7 +232,7 @@ void rds_iw_send_cq_comp_handler(struct ib_cq *cq, void *context) } if (wc.wr_id == RDS_IW_ACK_WR_ID) { - if (ic->i_ack_queued + HZ/2 < jiffies) + if (time_after(jiffies, ic->i_ack_queued + HZ/2)) rds_iw_stats_inc(s_iw_tx_stalled); rds_iw_ack_send_complete(ic); continue; @@ -267,7 +267,7 @@ void rds_iw_send_cq_comp_handler(struct ib_cq *cq, void *context) send->s_wr.opcode = 0xdead; send->s_wr.num_sge = 1; - if (send->s_queued + HZ/2 < jiffies) + if (time_after(jiffies, send->s_queued + HZ/2)) rds_iw_stats_inc(s_iw_tx_stalled); /* If a RDMA operation produced an error, signal this right -- 1.7.10.4 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH 1/3] net: vxge: Use time_is_before_jiffies() for time comparison
To be future-proof and for better readability the time comparisons are modified to use time_is_before_jiffies() instead of plain, error-prone math. Signed-off-by: Manuel Schölling --- drivers/net/ethernet/neterion/vxge/vxge-main.c |4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/neterion/vxge/vxge-main.c b/drivers/net/ethernet/neterion/vxge/vxge-main.c index d107bcb..79f42db 100644 --- a/drivers/net/ethernet/neterion/vxge/vxge-main.c +++ b/drivers/net/ethernet/neterion/vxge/vxge-main.c @@ -2122,7 +2122,7 @@ static int vxge_open_vpaths(struct vxgedev *vdev) static void adaptive_coalesce_tx_interrupts(struct vxge_fifo *fifo) { fifo->interrupt_count++; - if (jiffies > fifo->jiffies + HZ / 100) { + if (time_is_before_jiffies(fifo->jiffies + HZ / 100)) { struct __vxge_hw_fifo *hw_fifo = fifo->handle; fifo->jiffies = jiffies; @@ -2150,7 +2150,7 @@ static void adaptive_coalesce_tx_interrupts(struct vxge_fifo *fifo) static void adaptive_coalesce_rx_interrupts(struct vxge_ring *ring) { ring->interrupt_count++; - if (jiffies > ring->jiffies + HZ / 100) { + if (time_is_before_jiffies(ring->jiffies + HZ / 100)) { struct __vxge_hw_ring *hw_ring = ring->handle; ring->jiffies = jiffies; -- 1.7.10.4 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[no subject]
Sorry, contrary to the subject of the previous email, this is a single file patch. Patches 2-3 do not exist -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH] net: vxge: Use time_is_before_jiffies() for time comparison
To be future-proof and for better readability the time comparisons are modified to use time_is_before_jiffies() instead of plain, error-prone math. Signed-off-by: Manuel Schölling --- drivers/net/ethernet/neterion/vxge/vxge-main.c |4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/neterion/vxge/vxge-main.c b/drivers/net/ethernet/neterion/vxge/vxge-main.c index d107bcb..79f42db 100644 --- a/drivers/net/ethernet/neterion/vxge/vxge-main.c +++ b/drivers/net/ethernet/neterion/vxge/vxge-main.c @@ -2122,7 +2122,7 @@ static int vxge_open_vpaths(struct vxgedev *vdev) static void adaptive_coalesce_tx_interrupts(struct vxge_fifo *fifo) { fifo->interrupt_count++; - if (jiffies > fifo->jiffies + HZ / 100) { + if (time_is_before_jiffies(fifo->jiffies + HZ / 100)) { struct __vxge_hw_fifo *hw_fifo = fifo->handle; fifo->jiffies = jiffies; @@ -2150,7 +2150,7 @@ static void adaptive_coalesce_tx_interrupts(struct vxge_fifo *fifo) static void adaptive_coalesce_rx_interrupts(struct vxge_ring *ring) { ring->interrupt_count++; - if (jiffies > ring->jiffies + HZ / 100) { + if (time_is_before_jiffies(ring->jiffies + HZ / 100)) { struct __vxge_hw_ring *hw_ring = ring->handle; ring->jiffies = jiffies; -- 1.7.10.4 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH v3] vxge: Use time_before()
Thanks for your hints. I tried to incorporate your points into this new version. -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH] vxge: Use time_before()
To be future-proof and for better readability the time comparisons are modified to use time_before() instead of plain, error-prone math. Signed-off-by: Manuel Schölling --- drivers/net/ethernet/neterion/vxge/vxge-main.c |4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/neterion/vxge/vxge-main.c b/drivers/net/ethernet/neterion/vxge/vxge-main.c index d107bcb..7a0dead 100644 --- a/drivers/net/ethernet/neterion/vxge/vxge-main.c +++ b/drivers/net/ethernet/neterion/vxge/vxge-main.c @@ -2122,7 +2122,7 @@ static int vxge_open_vpaths(struct vxgedev *vdev) static void adaptive_coalesce_tx_interrupts(struct vxge_fifo *fifo) { fifo->interrupt_count++; - if (jiffies > fifo->jiffies + HZ / 100) { + if (time_before(fifo->jiffies + HZ / 100, jiffies)) { struct __vxge_hw_fifo *hw_fifo = fifo->handle; fifo->jiffies = jiffies; @@ -2150,7 +2150,7 @@ static void adaptive_coalesce_tx_interrupts(struct vxge_fifo *fifo) static void adaptive_coalesce_rx_interrupts(struct vxge_ring *ring) { ring->interrupt_count++; - if (jiffies > ring->jiffies + HZ / 100) { + if (time_before(ring->jiffies + HZ / 100, jiffies)) { struct __vxge_hw_ring *hw_ring = ring->handle; ring->jiffies = jiffies; -- 1.7.10.4 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH] lpfc: Use time_after()
To be future-proof and for better readability the time comparisons are modified to use time_after() instead of plain, error-prone math. Signed-off-by: Manuel Schölling --- drivers/scsi/lpfc/lpfc_scsi.c |4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c index 462453e..fb5351a 100644 --- a/drivers/scsi/lpfc/lpfc_scsi.c +++ b/drivers/scsi/lpfc/lpfc_scsi.c @@ -380,12 +380,14 @@ lpfc_rampdown_queue_depth(struct lpfc_hba *phba) { unsigned long flags; uint32_t evt_posted; + unsigned long expires; spin_lock_irqsave(&phba->hbalock, flags); atomic_inc(&phba->num_rsrc_err); phba->last_rsrc_error_time = jiffies; - if ((phba->last_ramp_down_time + QUEUE_RAMP_DOWN_INTERVAL) > jiffies) { + expires = phba->last_ramp_down_time + QUEUE_RAMP_DOWN_INTERVAL; + if (time_after(expires, jiffies)) { spin_unlock_irqrestore(&phba->hbalock, flags); return; } -- 1.7.10.4 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH] xilinx: Fix compiler warning
The time comparsion functions require arguments of type unsigned long instead of (signed) long. Signed-off-by: Manuel Schölling --- drivers/net/ethernet/xilinx/ll_temac_main.c |2 +- drivers/net/ethernet/xilinx/xilinx_axienet_mdio.c |2 +- drivers/net/ethernet/xilinx/xilinx_emaclite.c |2 +- init/do_mounts.c |1 - 4 files changed, 3 insertions(+), 4 deletions(-) diff --git a/drivers/net/ethernet/xilinx/ll_temac_main.c b/drivers/net/ethernet/xilinx/ll_temac_main.c index 4ef818a..8a6e5c2 100644 --- a/drivers/net/ethernet/xilinx/ll_temac_main.c +++ b/drivers/net/ethernet/xilinx/ll_temac_main.c @@ -72,7 +72,7 @@ void temac_iow(struct temac_local *lp, int offset, u32 value) int temac_indirect_busywait(struct temac_local *lp) { - long end = jiffies + 2; + unsigned long end = jiffies + 2; while (!(temac_ior(lp, XTE_RDY0_OFFSET) & XTE_RDY0_HARD_ACS_RDY_MASK)) { if (time_before_eq(end, jiffies)) { diff --git a/drivers/net/ethernet/xilinx/xilinx_axienet_mdio.c b/drivers/net/ethernet/xilinx/xilinx_axienet_mdio.c index d4abf47..3b67d60 100644 --- a/drivers/net/ethernet/xilinx/xilinx_axienet_mdio.c +++ b/drivers/net/ethernet/xilinx/xilinx_axienet_mdio.c @@ -19,7 +19,7 @@ /* Wait till MDIO interface is ready to accept a new transaction.*/ int axienet_mdio_wait_until_ready(struct axienet_local *lp) { - long end = jiffies + 2; + unsigned long end = jiffies + 2; while (!(axienet_ior(lp, XAE_MDIO_MCR_OFFSET) & XAE_MDIO_MCR_READY_MASK)) { if (time_before_eq(end, jiffies)) { diff --git a/drivers/net/ethernet/xilinx/xilinx_emaclite.c b/drivers/net/ethernet/xilinx/xilinx_emaclite.c index 8c4aed3..782bb93 100644 --- a/drivers/net/ethernet/xilinx/xilinx_emaclite.c +++ b/drivers/net/ethernet/xilinx/xilinx_emaclite.c @@ -695,7 +695,7 @@ static irqreturn_t xemaclite_interrupt(int irq, void *dev_id) static int xemaclite_mdio_wait(struct net_local *lp) { - long end = jiffies + 2; + unsigned long end = jiffies + 2; /* wait for the MDIO interface to not be busy or timeout after some time. diff --git a/init/do_mounts.c b/init/do_mounts.c index 60c4196..2d069a3 100644 --- a/init/do_mounts.c +++ b/init/do_mounts.c @@ -351,7 +351,6 @@ static void __init get_fs_names(char *page) continue; line++; - /* append fsname */ memmove(fsnames, line, strlen(line)+1); fsnames += strlen(fsnames)+1; } while (page != NULL); -- 1.7.10.4 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH v2] xilinx: Fix compiler warning
The time comparsion functions require arguments of type unsigned long instead of (signed) long. Signed-off-by: Manuel Schölling --- drivers/net/ethernet/xilinx/ll_temac_main.c |2 +- drivers/net/ethernet/xilinx/xilinx_axienet_mdio.c |2 +- drivers/net/ethernet/xilinx/xilinx_emaclite.c |2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/net/ethernet/xilinx/ll_temac_main.c b/drivers/net/ethernet/xilinx/ll_temac_main.c index 4ef818a..8a6e5c2 100644 --- a/drivers/net/ethernet/xilinx/ll_temac_main.c +++ b/drivers/net/ethernet/xilinx/ll_temac_main.c @@ -72,7 +72,7 @@ void temac_iow(struct temac_local *lp, int offset, u32 value) int temac_indirect_busywait(struct temac_local *lp) { - long end = jiffies + 2; + unsigned long end = jiffies + 2; while (!(temac_ior(lp, XTE_RDY0_OFFSET) & XTE_RDY0_HARD_ACS_RDY_MASK)) { if (time_before_eq(end, jiffies)) { diff --git a/drivers/net/ethernet/xilinx/xilinx_axienet_mdio.c b/drivers/net/ethernet/xilinx/xilinx_axienet_mdio.c index d4abf47..3b67d60 100644 --- a/drivers/net/ethernet/xilinx/xilinx_axienet_mdio.c +++ b/drivers/net/ethernet/xilinx/xilinx_axienet_mdio.c @@ -19,7 +19,7 @@ /* Wait till MDIO interface is ready to accept a new transaction.*/ int axienet_mdio_wait_until_ready(struct axienet_local *lp) { - long end = jiffies + 2; + unsigned long end = jiffies + 2; while (!(axienet_ior(lp, XAE_MDIO_MCR_OFFSET) & XAE_MDIO_MCR_READY_MASK)) { if (time_before_eq(end, jiffies)) { diff --git a/drivers/net/ethernet/xilinx/xilinx_emaclite.c b/drivers/net/ethernet/xilinx/xilinx_emaclite.c index 8c4aed3..782bb93 100644 --- a/drivers/net/ethernet/xilinx/xilinx_emaclite.c +++ b/drivers/net/ethernet/xilinx/xilinx_emaclite.c @@ -695,7 +695,7 @@ static irqreturn_t xemaclite_interrupt(int irq, void *dev_id) static int xemaclite_mdio_wait(struct net_local *lp) { - long end = jiffies + 2; + unsigned long end = jiffies + 2; /* wait for the MDIO interface to not be busy or timeout after some time. -- 1.7.10.4 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH, RFC] random: introduce getrandom(2) system call
Hi, I am wondering if we could improve the design of the system call a bit to prevent programming errors. Right now, EINVAL is returned in case of invalid flags (or in the older version of getrandom() also if buflen is too large), EFAULT if buf is an invalid address and EAGAIN if there is not enough entropy. However, of course no programmer is save against programming errors. Everybody *should* check the return value of syscalls, but sometimes it is forgotten, and theoretically you must be stoned to death for that. Still, we should think about how we could prevent these errors. Here is a list of possible modifications of getrandom() and pros and cons: 1. memset(buf, 0x0, buflen) in case of an error pros: - it is more obvious to the userspace programmer that the content of buffer does *not* contain random bytes cons: - in case even the zero-ed buf is not noticed by the programmer, she/he might end up using a 100% predictable string of "random bytes". In contrast if zero-ing the buf is ommitted, you would at least end up using some (not-cryptographically) random bytes from somewhere in RAM. I am aware that this memset() call should theoretically be superfluous but it would only be executed in very rare cases where the programmer misuses getrandom(). 2. int getrandom(void **buf, size_t buflen, unsigned int flags) ^^ If flags, are fine, return a pointer to a buffer of random bytes, otherwise return a pointer to NULL. pros: - it would ensure that an error in a getrandom() call cannot be ignored. cons: - not sure if a syscall should allocate memory in the name of a userspace program - not a very unix-like syscall signature - anytime getrandom() is called, it will allocate a new buffer which might end up in decreased performance (however, getrandom() should not be called multiple times) 3. send a signal to the userland process that (by default) leads to an abnormal termination of the process Essentially an error in getrandom() could be seen as critical as a division by 0. pros: - the userspace programmer is forced to handle this error (otherwise the signal would terminate the program) cons: - adds more complexity to the userspace program that might lead to new programming errors These are three possibilities. Maybe one of you is more creative and can come up with a much better idea. At the moment, I like option 2 the best, because it forces the programmer to deal with these errors, but probably one of you has a good point why this is not a good idea. Handling the NULL pointer would be much easier than using signals (option 3). However, it lead to a syscall signature that is different from, let's say read(), because the syscall itself would allocate its buffer. Again, I am aware that you must always check return values, but programming errors happen. E.g. everybody knows that you cannot trust data that you received via network, yet heartbleed happened. Here we have the chance to eradicate a critical programming error by improving the syscall design and I think we should spend some time thinking about that. Best, Manuel -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH] dns_resolver: assure that dns_query() result is null-terminated
dns_query() credulously assumes that keys are null-terminated and returns a copy of a memory block that is off by one. --- net/dns_resolver/dns_query.c |4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/net/dns_resolver/dns_query.c b/net/dns_resolver/dns_query.c index e7b6d53..53be635 100644 --- a/net/dns_resolver/dns_query.c +++ b/net/dns_resolver/dns_query.c @@ -149,7 +149,9 @@ int dns_query(const char *type, const char *name, size_t namelen, if (!*_result) goto put; - memcpy(*_result, upayload->data, len + 1); + memcpy(*_result, upayload->data, len); + *_result[len+1] = '\0'; + if (_expiry) *_expiry = rkey->expiry; -- 1.7.10.4 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH v2] dns_resolver: assure that dns_query() result is null-terminated
dns_query() credulously assumes that keys are null-terminated and returns a copy of a memory block that is off by one. --- net/dns_resolver/dns_query.c |4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/net/dns_resolver/dns_query.c b/net/dns_resolver/dns_query.c index e7b6d53..84871a2 100644 --- a/net/dns_resolver/dns_query.c +++ b/net/dns_resolver/dns_query.c @@ -145,11 +145,11 @@ int dns_query(const char *type, const char *name, size_t namelen, len = upayload->datalen; ret = -ENOMEM; - *_result = kmalloc(len + 1, GFP_KERNEL); + *_result = kzalloc(len + 1, GFP_KERNEL); if (!*_result) goto put; - memcpy(*_result, upayload->data, len + 1); + memcpy(*_result, upayload->data, len); if (_expiry) *_expiry = rkey->expiry; -- 1.7.10.4 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH v3] dns_resolver: assure that dns_query() result is null-terminated
dns_query() credulously assumes that keys are null-terminated and returns a copy of a memory block that is off by one. Signed-off-by: Manuel Schölling --- net/dns_resolver/dns_query.c |4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/net/dns_resolver/dns_query.c b/net/dns_resolver/dns_query.c index e7b6d53..6853d22 100644 --- a/net/dns_resolver/dns_query.c +++ b/net/dns_resolver/dns_query.c @@ -149,7 +149,9 @@ int dns_query(const char *type, const char *name, size_t namelen, if (!*_result) goto put; - memcpy(*_result, upayload->data, len + 1); + memcpy(*_result, upayload->data, len); + *_result[len] = '\0'; + if (_expiry) *_expiry = rkey->expiry; -- 1.7.10.4 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH] lustre: Use time_before()
To be future-proof and for better readability the time comparisons are modified to use time_before() instead of plain, error-prone math. Signed-off-by: Manuel Schölling --- drivers/staging/lustre/lustre/include/linux/obd.h |4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/lustre/lustre/include/linux/obd.h b/drivers/staging/lustre/lustre/include/linux/obd.h index dc36f75e..518e48a 100644 --- a/drivers/staging/lustre/lustre/include/linux/obd.h +++ b/drivers/staging/lustre/lustre/include/linux/obd.h @@ -80,8 +80,8 @@ static inline void __client_obd_list_lock(client_obd_lock_t *lock, break; } - if ((jiffies - cur > 5 * HZ) && - (jiffies - lock->time > 5 * HZ)) { + if (time_before(cur + 5 * HZ, jiffies) && + time_before(lock->time + 5 * HZ, jiffies)) { struct task_struct *task = lock->task; if (task == NULL) -- 1.7.10.4 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH] qlogic: Use time_before()
To be future-proof and for better readability the time comparisons are modified to use time_before() instead of plain, error-prone math. Signed-off-by: Manuel Schölling --- drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.c | 10 +- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.c index 9f3adf4..c2a2ad4 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.c @@ -630,7 +630,7 @@ void qlcnic_prune_lb_filters(struct qlcnic_adapter *adapter) struct hlist_node *n; struct hlist_head *head; int i; - unsigned long time; + unsigned long expires; u8 cmd; for (i = 0; i < adapter->fhash.fbucket_size; i++) { @@ -638,8 +638,8 @@ void qlcnic_prune_lb_filters(struct qlcnic_adapter *adapter) hlist_for_each_entry_safe(tmp_fil, n, head, fnode) { cmd = tmp_fil->vlan_id ? QLCNIC_MAC_VLAN_DEL : QLCNIC_MAC_DEL; - time = tmp_fil->ftime; - if (jiffies > (QLCNIC_FILTER_AGE * HZ + time)) { + expires = tmp_fil->ftime + QLCNIC_FILTER_AGE * HZ; + if (time_before(expires, jiffies)) { qlcnic_sre_macaddr_change(adapter, tmp_fil->faddr, tmp_fil->vlan_id, @@ -657,8 +657,8 @@ void qlcnic_prune_lb_filters(struct qlcnic_adapter *adapter) hlist_for_each_entry_safe(tmp_fil, n, head, fnode) { - time = tmp_fil->ftime; - if (jiffies > (QLCNIC_FILTER_AGE * HZ + time)) { + expires = tmp_fil->ftime + QLCNIC_FILTER_AGE * HZ; + if (time_before(expires, jiffies)) { spin_lock_bh(&adapter->rx_mac_learn_lock); adapter->rx_fhash.fnum--; hlist_del(&tmp_fil->fnode); -- 1.7.10.4 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH] radeon: Use time_before()
To be future-proof and for better readability the time comparisons are modified to use time_before() instead of plain, error-prone math. Signed-off-by: Manuel Schölling --- drivers/gpu/drm/radeon/radeon_pm.c |2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/radeon/radeon_pm.c b/drivers/gpu/drm/radeon/radeon_pm.c index f30b842..b08db66 100644 --- a/drivers/gpu/drm/radeon/radeon_pm.c +++ b/drivers/gpu/drm/radeon/radeon_pm.c @@ -1592,7 +1592,7 @@ static void radeon_dynpm_idle_work_handler(struct work_struct *work) * to false since we want to wait for vbl to avoid flicker. */ if (rdev->pm.dynpm_planned_action != DYNPM_ACTION_NONE && - jiffies > rdev->pm.dynpm_action_timeout) { + time_before(rdev->pm.dynpm_action_timeout, jiffies)) { radeon_pm_get_dynpm_state(rdev); radeon_pm_set_clocks(rdev); } -- 1.7.10.4 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH 2/2] mISDN: use mod_timer()
The code for resetting the timer can be simplified if mod_timer() is used instead of del_timer() followed by add_timer(). Signed-off-by: Manuel Schölling --- drivers/isdn/mISDN/l1oip_core.c |8 ++-- 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/drivers/isdn/mISDN/l1oip_core.c b/drivers/isdn/mISDN/l1oip_core.c index 1c2bc36..a4c6cc0 100644 --- a/drivers/isdn/mISDN/l1oip_core.c +++ b/drivers/isdn/mISDN/l1oip_core.c @@ -288,9 +288,7 @@ l1oip_socket_send(struct l1oip *hc, u8 localcodec, u8 channel, u32 chanmask, /* restart timer */ if (time_before(hc->keep_tl.expires - 5 * HZ, jiffies)) { - del_timer(&hc->keep_tl); - hc->keep_tl.expires = jiffies + L1OIP_KEEPALIVE * HZ; - add_timer(&hc->keep_tl); + mod_timer(&hc->keep_tl, jiffies + L1OIP_KEEPALIVE * HZ); } else hc->keep_tl.expires = jiffies + L1OIP_KEEPALIVE * HZ; @@ -624,9 +622,7 @@ multiframe: if (time_before(hc->timeout_tl.expires - 5 * HZ, jiffies) || !hc->timeout_on) { hc->timeout_on = 1; - del_timer(&hc->timeout_tl); - hc->timeout_tl.expires = jiffies + L1OIP_TIMEOUT * HZ; - add_timer(&hc->timeout_tl); + mod_timer(&hc->timeout_tl, jiffies + L1OIP_TIMEOUT * HZ); } else /* only adjust timer */ hc->timeout_tl.expires = jiffies + L1OIP_TIMEOUT * HZ; -- 1.7.10.4 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH 1/2] mISDN: Use time_before()
To be future-proof and for better readability the time comparisons are modified to use time_before() instead of plain, error-prone math. Signed-off-by: Manuel Schölling --- drivers/isdn/mISDN/l1oip_core.c |5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/isdn/mISDN/l1oip_core.c b/drivers/isdn/mISDN/l1oip_core.c index 2c0d2c2..1c2bc36 100644 --- a/drivers/isdn/mISDN/l1oip_core.c +++ b/drivers/isdn/mISDN/l1oip_core.c @@ -287,7 +287,7 @@ l1oip_socket_send(struct l1oip *hc, u8 localcodec, u8 channel, u32 chanmask, p = frame; /* restart timer */ - if ((int)(hc->keep_tl.expires-jiffies) < 5 * HZ) { + if (time_before(hc->keep_tl.expires - 5 * HZ, jiffies)) { del_timer(&hc->keep_tl); hc->keep_tl.expires = jiffies + L1OIP_KEEPALIVE * HZ; add_timer(&hc->keep_tl); @@ -621,7 +621,8 @@ multiframe: goto multiframe; /* restart timer */ - if ((int)(hc->timeout_tl.expires-jiffies) < 5 * HZ || !hc->timeout_on) { + if (time_before(hc->timeout_tl.expires - 5 * HZ, jiffies) + || !hc->timeout_on) { hc->timeout_on = 1; del_timer(&hc->timeout_tl); hc->timeout_tl.expires = jiffies + L1OIP_TIMEOUT * HZ; -- 1.7.10.4 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH v2 2/2] mISDN: Use mod_timer()
The code for resetting the timer can be simplified if mod_timer() is used instead of del_timer() followed by add_timer(). Signed-off-by: Manuel Schölling --- drivers/isdn/mISDN/l1oip_core.c | 12 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/drivers/isdn/mISDN/l1oip_core.c b/drivers/isdn/mISDN/l1oip_core.c index 084f936..9f454d7 100644 --- a/drivers/isdn/mISDN/l1oip_core.c +++ b/drivers/isdn/mISDN/l1oip_core.c @@ -287,11 +287,9 @@ l1oip_socket_send(struct l1oip *hc, u8 localcodec, u8 channel, u32 chanmask, p = frame; /* restart timer */ - if (time_before(hc->keep_tl.expires, jiffies + 5 * HZ)) { - del_timer(&hc->keep_tl); - hc->keep_tl.expires = jiffies + L1OIP_KEEPALIVE * HZ; - add_timer(&hc->keep_tl); - } else + if (time_before(hc->keep_tl.expires, jiffies + 5 * HZ)) + mod_timer(&hc->keep_tl, jiffies + L1OIP_KEEPALIVE * HZ); + else hc->keep_tl.expires = jiffies + L1OIP_KEEPALIVE * HZ; if (debug & DEBUG_L1OIP_MSG) @@ -623,9 +621,7 @@ multiframe: /* restart timer */ if (time_before(hc->timeout_tl.expires, jiffies + 5 * HZ) || !hc->timeout_on) { hc->timeout_on = 1; - del_timer(&hc->timeout_tl); - hc->timeout_tl.expires = jiffies + L1OIP_TIMEOUT * HZ; - add_timer(&hc->timeout_tl); + mod_timer(&hc->timeout_tl, jiffies + L1OIP_TIMEOUT * HZ); } else /* only adjust timer */ hc->timeout_tl.expires = jiffies + L1OIP_TIMEOUT * HZ; -- 1.7.10.4 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH v2 1/2] mISDN: Use time_before()
To be future-proof and for better readability the time comparisons are modified to use time_before() instead of plain, error-prone math. Signed-off-by: Manuel Schölling --- drivers/isdn/mISDN/l1oip_core.c |4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/isdn/mISDN/l1oip_core.c b/drivers/isdn/mISDN/l1oip_core.c index 2c0d2c2..084f936 100644 --- a/drivers/isdn/mISDN/l1oip_core.c +++ b/drivers/isdn/mISDN/l1oip_core.c @@ -287,7 +287,7 @@ l1oip_socket_send(struct l1oip *hc, u8 localcodec, u8 channel, u32 chanmask, p = frame; /* restart timer */ - if ((int)(hc->keep_tl.expires-jiffies) < 5 * HZ) { + if (time_before(hc->keep_tl.expires, jiffies + 5 * HZ)) { del_timer(&hc->keep_tl); hc->keep_tl.expires = jiffies + L1OIP_KEEPALIVE * HZ; add_timer(&hc->keep_tl); @@ -621,7 +621,7 @@ multiframe: goto multiframe; /* restart timer */ - if ((int)(hc->timeout_tl.expires-jiffies) < 5 * HZ || !hc->timeout_on) { + if (time_before(hc->timeout_tl.expires, jiffies + 5 * HZ) || !hc->timeout_on) { hc->timeout_on = 1; del_timer(&hc->timeout_tl); hc->timeout_tl.expires = jiffies + L1OIP_TIMEOUT * HZ; -- 1.7.10.4 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH] sched: Use time_after()
To be future-proof and for better readability the time comparisons are modified to use time_after() instead of plain, error-prone math. Signed-off-by: Manuel Schölling --- kernel/sched/fair.c |2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c index 7570dd9..716360a 100644 --- a/kernel/sched/fair.c +++ b/kernel/sched/fair.c @@ -4014,7 +4014,7 @@ static void record_wakee(struct task_struct *p) * about the boundary, really active task won't care * about the loss. */ - if (jiffies > current->wakee_flip_decay_ts + HZ) { + if (time_after(jiffies, current->wakee_flip_decay_ts + HZ)) { current->wakee_flips = 0; current->wakee_flip_decay_ts = jiffies; } -- 1.7.10.4 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH] micrel: Use time_before_eq()
To be future-proof and for better readability the time comparisons are modified to use time_before_eq() instead of plain, error-prone math. Signed-off-by: Manuel Schölling --- drivers/net/ethernet/micrel/ksz884x.c |2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/ethernet/micrel/ksz884x.c b/drivers/net/ethernet/micrel/ksz884x.c index 14ac0e2..90fa5f3 100644 --- a/drivers/net/ethernet/micrel/ksz884x.c +++ b/drivers/net/ethernet/micrel/ksz884x.c @@ -4930,7 +4930,7 @@ static void netdev_tx_timeout(struct net_device *dev) * Only reset the hardware if time between calls is long * enough. */ - if (jiffies - last_reset <= dev->watchdog_timeo) + if (time_before_eq(jiffies, last_reset + dev->watchdog_timeo)) hw_priv = NULL; } -- 1.7.10.4 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH] xilinx: Use time_before_eq()
To be future-proof and for better readability the time comparisons are modified to use time_before_eq() instead of plain, error-prone math. Signed-off-by: Manuel Schölling --- drivers/net/ethernet/xilinx/ll_temac_main.c |2 +- drivers/net/ethernet/xilinx/xilinx_axienet_mdio.c |2 +- drivers/net/ethernet/xilinx/xilinx_emaclite.c |2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/net/ethernet/xilinx/ll_temac_main.c b/drivers/net/ethernet/xilinx/ll_temac_main.c index fa193c4..4ef818a 100644 --- a/drivers/net/ethernet/xilinx/ll_temac_main.c +++ b/drivers/net/ethernet/xilinx/ll_temac_main.c @@ -75,7 +75,7 @@ int temac_indirect_busywait(struct temac_local *lp) long end = jiffies + 2; while (!(temac_ior(lp, XTE_RDY0_OFFSET) & XTE_RDY0_HARD_ACS_RDY_MASK)) { - if (end - jiffies <= 0) { + if (time_before_eq(end, jiffies)) { WARN_ON(1); return -ETIMEDOUT; } diff --git a/drivers/net/ethernet/xilinx/xilinx_axienet_mdio.c b/drivers/net/ethernet/xilinx/xilinx_axienet_mdio.c index 64b4639..d4abf47 100644 --- a/drivers/net/ethernet/xilinx/xilinx_axienet_mdio.c +++ b/drivers/net/ethernet/xilinx/xilinx_axienet_mdio.c @@ -22,7 +22,7 @@ int axienet_mdio_wait_until_ready(struct axienet_local *lp) long end = jiffies + 2; while (!(axienet_ior(lp, XAE_MDIO_MCR_OFFSET) & XAE_MDIO_MCR_READY_MASK)) { - if (end - jiffies <= 0) { + if (time_before_eq(end, jiffies)) { WARN_ON(1); return -ETIMEDOUT; } diff --git a/drivers/net/ethernet/xilinx/xilinx_emaclite.c b/drivers/net/ethernet/xilinx/xilinx_emaclite.c index 0d87c67..8c4aed3 100644 --- a/drivers/net/ethernet/xilinx/xilinx_emaclite.c +++ b/drivers/net/ethernet/xilinx/xilinx_emaclite.c @@ -702,7 +702,7 @@ static int xemaclite_mdio_wait(struct net_local *lp) */ while (__raw_readl(lp->base_addr + XEL_MDIOCTRL_OFFSET) & XEL_MDIOCTRL_MDIOSTS_MASK) { - if (end - jiffies <= 0) { + if (time_before_eq(end, jiffies)) { WARN_ON(1); return -ETIMEDOUT; } -- 1.7.10.4 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH] ioat: Use time_before()
To be future-proof and for better readability the time comparisons are modified to use time_before() instead of plain, error-prone math. Signed-off-by: Manuel Schölling --- drivers/dma/ioat/dma_v2.c |3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/dma/ioat/dma_v2.c b/drivers/dma/ioat/dma_v2.c index 8d10580..fdd60c7 100644 --- a/drivers/dma/ioat/dma_v2.c +++ b/drivers/dma/ioat/dma_v2.c @@ -735,7 +735,8 @@ int ioat2_check_space_lock(struct ioat2_dma_chan *ioat, int num_descs) * called under bh_disabled so we need to trigger the timer * event directly */ - if (jiffies > chan->timer.expires && timer_pending(&chan->timer)) { + if (time_before(chan->timer.expires, jiffies) + && timer_pending(&chan->timer)) { struct ioatdma_device *device = chan->device; mod_timer(&chan->timer, jiffies + COMPLETION_TIMEOUT); -- 1.7.10.4 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH] e1000: Use time_after() for time comparison
To be future-proof and for better readability the time comparisons are modified to use time_after() instead of plain, error-prone math. Signed-off-by: Manuel Schölling --- drivers/net/ethernet/intel/e1000/e1000_ethtool.c |3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/net/ethernet/intel/e1000/e1000_ethtool.c b/drivers/net/ethernet/intel/e1000/e1000_ethtool.c index 73a8aee..1cbf281 100644 --- a/drivers/net/ethernet/intel/e1000/e1000_ethtool.c +++ b/drivers/net/ethernet/intel/e1000/e1000_ethtool.c @@ -1460,7 +1460,8 @@ static int e1000_run_loopback_test(struct e1000_adapter *adapter) * enough time to complete the receives, if it's * exceeded, break and error off */ - } while (good_cnt < 64 && jiffies < (time + 20)); + } while (good_cnt < 64 && time_after(time + 20, jiffies)); + if (good_cnt != 64) { ret_val = 13; /* ret_val is the same as mis-compare */ break; -- 1.7.10.4 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH] md: Use time_in_range()
To be future-proof and for better readability the time comparisons are modified to use time_in_range() instead of plain, error-prone math. Signed-off-by: Manuel Schölling --- drivers/md/dm-cache-target.c |5 +++-- drivers/md/dm-log-userspace-base.c |4 ++-- drivers/md/dm-thin.c |5 +++-- 3 files changed, 8 insertions(+), 6 deletions(-) diff --git a/drivers/md/dm-cache-target.c b/drivers/md/dm-cache-target.c index 9380be7..4378d1d 100644 --- a/drivers/md/dm-cache-target.c +++ b/drivers/md/dm-cache-target.c @@ -1429,8 +1429,9 @@ static void process_bio(struct cache *cache, struct prealloc *structs, static int need_commit_due_to_time(struct cache *cache) { - return jiffies < cache->last_commit_jiffies || - jiffies > cache->last_commit_jiffies + COMMIT_PERIOD; + return !time_in_range(jiffies, + cache->last_commit_jiffies, + cache->last_commit_jiffies + COMMIT_PERIOD); } static int commit_if_needed(struct cache *cache) diff --git a/drivers/md/dm-log-userspace-base.c b/drivers/md/dm-log-userspace-base.c index b953db6..cd9b171 100644 --- a/drivers/md/dm-log-userspace-base.c +++ b/drivers/md/dm-log-userspace-base.c @@ -829,7 +829,7 @@ static int userspace_is_remote_recovering(struct dm_dirty_log *log, int r; uint64_t region64 = region; struct log_c *lc = log->context; - static unsigned long long limit; + static unsigned long limit; struct { int64_t is_recovering; uint64_t in_sync_hint; @@ -845,7 +845,7 @@ static int userspace_is_remote_recovering(struct dm_dirty_log *log, */ if (region < lc->in_sync_hint) return 0; - else if (jiffies < limit) + else if (time_after(limit, jiffies)) return 1; limit = jiffies + (HZ / 4); diff --git a/drivers/md/dm-thin.c b/drivers/md/dm-thin.c index 2e71de8..c83b363 100644 --- a/drivers/md/dm-thin.c +++ b/drivers/md/dm-thin.c @@ -1375,8 +1375,9 @@ static void process_bio_fail(struct thin_c *tc, struct bio *bio) */ static int need_commit_due_to_time(struct pool *pool) { - return jiffies < pool->last_commit_jiffies || - jiffies > pool->last_commit_jiffies + COMMIT_PERIOD; + return !time_in_range(jiffies, + pool->last_commit_jiffies, + pool->last_commit_jiffies + COMMIT_PERIOD); } #define thin_pbd(node) rb_entry((node), struct dm_thin_endio_hook, rb_node) -- 1.7.10.4 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH] acpi: Use time_before() for time comparison
To be future-proof and for better readability the time comparisons are modified to use time_before() instead of plain, error-prone math. Signed-off-by: Manuel Schölling --- drivers/acpi/acpi_pad.c |7 --- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/acpi/acpi_pad.c b/drivers/acpi/acpi_pad.c index 37d7302..0a3bbf5 100644 --- a/drivers/acpi/acpi_pad.c +++ b/drivers/acpi/acpi_pad.c @@ -156,12 +156,13 @@ static int power_saving_thread(void *data) while (!kthread_should_stop()) { int cpu; - u64 expire_time; + unsigned long expire_time; try_to_freeze(); /* round robin to cpus */ - if (last_jiffies + round_robin_time * HZ < jiffies) { + expire_time = last_jiffies + round_robin_time * HZ; + if (time_before(expire_time, jiffies)) { last_jiffies = jiffies; round_robin_cpu(tsk_index); } @@ -200,7 +201,7 @@ static int power_saving_thread(void *data) CLOCK_EVT_NOTIFY_BROADCAST_EXIT, &cpu); local_irq_enable(); - if (jiffies > expire_time) { + if (time_before(expire_time, jiffies)) { do_sleep = 1; break; } -- 1.7.10.4 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH] msi3103: Use time_before_eq()
To be future-proof and for better readability the time comparisons are modified to use time_before_eq() instead of plain, error-prone math. Signed-off-by: Manuel Schölling --- drivers/staging/media/msi3101/sdr-msi3101.c |8 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/staging/media/msi3101/sdr-msi3101.c b/drivers/staging/media/msi3101/sdr-msi3101.c index 65d351f..b52726b 100644 --- a/drivers/staging/media/msi3101/sdr-msi3101.c +++ b/drivers/staging/media/msi3101/sdr-msi3101.c @@ -208,7 +208,7 @@ static int msi3101_convert_stream_504(struct msi3101_state *s, u8 *dst, } /* calculate samping rate and output it in 10 seconds intervals */ - if ((s->jiffies_next + msecs_to_jiffies(1)) <= jiffies) { + if (time_before_eq(s->jiffies_next + 10 * HZ, jiffies)) { unsigned long jiffies_now = jiffies; unsigned long msecs = jiffies_to_msecs(jiffies_now) - jiffies_to_msecs(s->jiffies_next); unsigned int samples = sample_num[i_max - 1] - s->sample; @@ -360,7 +360,7 @@ static int msi3101_convert_stream_384(struct msi3101_state *s, u8 *dst, } /* calculate samping rate and output it in 10 seconds intervals */ - if ((s->jiffies_next + msecs_to_jiffies(1)) <= jiffies) { + if (time_before_eq(s->jiffies_next + 10 * HZ, jiffies)) { unsigned long jiffies_now = jiffies; unsigned long msecs = jiffies_to_msecs(jiffies_now) - jiffies_to_msecs(s->jiffies_next); unsigned int samples = sample_num[i_max - 1] - s->sample; @@ -425,7 +425,7 @@ static int msi3101_convert_stream_336(struct msi3101_state *s, u8 *dst, } /* calculate samping rate and output it in 10 seconds intervals */ - if ((s->jiffies_next + msecs_to_jiffies(1)) <= jiffies) { + if (time_before_eq(s->jiffies_next + 10 * HZ, jiffies)) { unsigned long jiffies_now = jiffies; unsigned long msecs = jiffies_to_msecs(jiffies_now) - jiffies_to_msecs(s->jiffies_next); unsigned int samples = sample_num[i_max - 1] - s->sample; @@ -488,7 +488,7 @@ static int msi3101_convert_stream_252(struct msi3101_state *s, u8 *dst, } /* calculate samping rate and output it in 10 seconds intervals */ - if ((s->jiffies_next + msecs_to_jiffies(1)) <= jiffies) { + if (time_before_eq(s->jiffies_next + 10 * HZ, jiffies)) { unsigned long jiffies_now = jiffies; unsigned long msecs = jiffies_to_msecs(jiffies_now) - jiffies_to_msecs(s->jiffies_next); unsigned int samples = sample_num[i_max - 1] - s->sample; -- 1.7.10.4 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH] msi3103: Use time_before_eq()
To be future-proof and for better readability the time comparisons are modified to use time_before_eq() instead of plain, error-prone math. Signed-off-by: Manuel Schölling --- drivers/staging/media/msi3101/sdr-msi3101.c | 28 +-- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/drivers/staging/media/msi3101/sdr-msi3101.c b/drivers/staging/media/msi3101/sdr-msi3101.c index 65d351f..7a0a8ca 100644 --- a/drivers/staging/media/msi3101/sdr-msi3101.c +++ b/drivers/staging/media/msi3101/sdr-msi3101.c @@ -207,10 +207,10 @@ static int msi3101_convert_stream_504(struct msi3101_state *s, u8 *dst, dst_len += 1008; } - /* calculate samping rate and output it in 10 seconds intervals */ - if ((s->jiffies_next + msecs_to_jiffies(1)) <= jiffies) { + /* calculate sampling rate and output it in 10 seconds intervals */ + if (time_before_eq(s->jiffies_next + 10 * HZ, jiffies)) { unsigned long jiffies_now = jiffies; - unsigned long msecs = jiffies_to_msecs(jiffies_now) - jiffies_to_msecs(s->jiffies_next); + unsigned long msecs = jiffies_to_msecs(jiffies_now - s->jiffies_next); unsigned int samples = sample_num[i_max - 1] - s->sample; s->jiffies_next = jiffies_now; s->sample = sample_num[i_max - 1]; @@ -265,7 +265,7 @@ static int msi3101_convert_stream_504_u8(struct msi3101_state *s, u8 *dst, dst_len += 1008; } - /* calculate samping rate and output it in 10 seconds intervals */ + /* calculate sampling rate and output it in 10 seconds intervals */ if (unlikely(time_is_before_jiffies(s->jiffies_next))) { #define MSECS 1UL unsigned int samples = sample_num[i_max - 1] - s->sample; @@ -359,10 +359,10 @@ static int msi3101_convert_stream_384(struct msi3101_state *s, u8 *dst, dst_len += 984; } - /* calculate samping rate and output it in 10 seconds intervals */ - if ((s->jiffies_next + msecs_to_jiffies(1)) <= jiffies) { + /* calculate sampling rate and output it in 10 seconds intervals */ + if (time_before_eq(s->jiffies_next + 10 * HZ, jiffies)) { unsigned long jiffies_now = jiffies; - unsigned long msecs = jiffies_to_msecs(jiffies_now) - jiffies_to_msecs(s->jiffies_next); + unsigned long msecs = jiffies_to_msecs(jiffies_now - s->jiffies_next); unsigned int samples = sample_num[i_max - 1] - s->sample; s->jiffies_next = jiffies_now; s->sample = sample_num[i_max - 1]; @@ -424,10 +424,10 @@ static int msi3101_convert_stream_336(struct msi3101_state *s, u8 *dst, dst_len += 1008; } - /* calculate samping rate and output it in 10 seconds intervals */ - if ((s->jiffies_next + msecs_to_jiffies(1)) <= jiffies) { + /* calculate sampling rate and output it in 10 seconds intervals */ + if (time_before_eq(s->jiffies_next + 10 * HZ, jiffies)) { unsigned long jiffies_now = jiffies; - unsigned long msecs = jiffies_to_msecs(jiffies_now) - jiffies_to_msecs(s->jiffies_next); + unsigned long msecs = jiffies_to_msecs(jiffies_now - s->jiffies_next); unsigned int samples = sample_num[i_max - 1] - s->sample; s->jiffies_next = jiffies_now; s->sample = sample_num[i_max - 1]; @@ -487,10 +487,10 @@ static int msi3101_convert_stream_252(struct msi3101_state *s, u8 *dst, dst_len += 1008; } - /* calculate samping rate and output it in 10 seconds intervals */ - if ((s->jiffies_next + msecs_to_jiffies(1)) <= jiffies) { + /* calculate sampling rate and output it in 10 seconds intervals */ + if (time_before_eq(s->jiffies_next + 10 * HZ, jiffies)) { unsigned long jiffies_now = jiffies; - unsigned long msecs = jiffies_to_msecs(jiffies_now) - jiffies_to_msecs(s->jiffies_next); + unsigned long msecs = jiffies_to_msecs(jiffies_now - s->jiffies_next); unsigned int samples = sample_num[i_max - 1] - s->sample; s->jiffies_next = jiffies_now; s->sample = sample_num[i_max - 1]; @@ -560,7 +560,7 @@ static int msi3101_convert_stream_252_u16(struct msi3101_state *s, u8 *dst, dst_len += 1008; } - /* calculate samping rate and output it in 10 seconds intervals */ + /* calculate sampling rate and output it in 10 seconds intervals */ if (unlikely(time_is_before_jiffies(s->jiffies_next))) { #define MSECS 1UL unsigned int samples = sample_num[i_max - 1] - s->sample; -- 1.7.10.4 -- To unsubscribe from this list: send t
[PATCH] rtl8188eu: use time_before/time_after and change type of ips_deny_time
To be future-proof and for better readability the time comparisons are modified to use time_before/_after() instead of plain, error-prone math. To suppress compiler warnings the type of ips_deny_time was changed. Signed-off-by: Manuel Schölling --- drivers/staging/rtl8188eu/core/rtw_pwrctrl.c|9 ++--- drivers/staging/rtl8188eu/include/rtw_pwrctrl.h |2 +- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/drivers/staging/rtl8188eu/core/rtw_pwrctrl.c b/drivers/staging/rtl8188eu/core/rtw_pwrctrl.c index f658373..eaf2630 100644 --- a/drivers/staging/rtl8188eu/core/rtw_pwrctrl.c +++ b/drivers/staging/rtl8188eu/core/rtw_pwrctrl.c @@ -122,7 +122,7 @@ static bool rtw_pwr_unassociated_idle(struct adapter *adapter) bool ret = false; - if (adapter->pwrctrlpriv.ips_deny_time >= jiffies) + if (time_after_eq(adapter->pwrctrlpriv.ips_deny_time, jiffies)) goto exit; if (check_fwstate(pmlmepriv, WIFI_ASOC_STATE|WIFI_SITE_MONITOR) || @@ -523,9 +523,11 @@ int _rtw_pwr_wakeup(struct adapter *padapter, u32 ips_deffer_ms, const char *cal { struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv; struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + unsigned long expires; int ret = _SUCCESS; - if (pwrpriv->ips_deny_time < jiffies + rtw_ms_to_systime(ips_deffer_ms)) + expires = jiffies + rtw_ms_to_systime(ips_deffer_ms); + if (time_before(pwrpriv->ips_deny_time, expires)) pwrpriv->ips_deny_time = jiffies + rtw_ms_to_systime(ips_deffer_ms); { @@ -580,7 +582,8 @@ int _rtw_pwr_wakeup(struct adapter *padapter, u32 ips_deffer_ms, const char *cal } exit: - if (pwrpriv->ips_deny_time < jiffies + rtw_ms_to_systime(ips_deffer_ms)) + expires = jiffies + rtw_ms_to_systime(ips_deffer_ms); + if (time_before(pwrpriv->ips_deny_time, expires)) pwrpriv->ips_deny_time = jiffies + rtw_ms_to_systime(ips_deffer_ms); return ret; } diff --git a/drivers/staging/rtl8188eu/include/rtw_pwrctrl.h b/drivers/staging/rtl8188eu/include/rtw_pwrctrl.h index 9a42859..4211023 100644 --- a/drivers/staging/rtl8188eu/include/rtw_pwrctrl.h +++ b/drivers/staging/rtl8188eu/include/rtw_pwrctrl.h @@ -192,7 +192,7 @@ struct pwrctrl_priv { u8 ips_mode_req; /* used to accept the mode setting request, * will update to ipsmode later */ uint bips_processing; - u32 ips_deny_time; /* will deny IPS when system time less than this */ + unsigned long ips_deny_time; /* will deny IPS when system time less than this */ u8 ps_processing; /* temp used to mark whether in rtw_ps_processor */ u8 bLeisurePs; -- 1.7.10.4 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH] gdm72xx: use time_before()
To be future-proof and for better readability the time comparisons are modified to use time_before() instead of plain, error-prone math. Signed-off-by: Manuel Schölling --- drivers/staging/gdm72xx/gdm_usb.c |2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/gdm72xx/gdm_usb.c b/drivers/staging/gdm72xx/gdm_usb.c index 20539d8..9ddf8f5 100644 --- a/drivers/staging/gdm72xx/gdm_usb.c +++ b/drivers/staging/gdm72xx/gdm_usb.c @@ -730,7 +730,7 @@ static int k_mode_thread(void *arg) spin_unlock_irqrestore(&k_lock, flags2); expire = jiffies + K_WAIT_TIME; - while (jiffies < expire) + while (time_before(jiffies, expire)) schedule_timeout(K_WAIT_TIME); spin_lock_irqsave(&rx->lock, flags); -- 1.7.10.4 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH] ipath: use time_before()/_after()
To be future-proof and for better readability the time comparisons are modified to use time_before/_after() instead of plain, error-prone math. Signed-off-by: Manuel Schölling --- drivers/infiniband/hw/ipath/ipath_intr.c |4 ++-- drivers/infiniband/hw/ipath/ipath_sdma.c |4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/infiniband/hw/ipath/ipath_intr.c b/drivers/infiniband/hw/ipath/ipath_intr.c index 26dfbc8..01ba792 100644 --- a/drivers/infiniband/hw/ipath/ipath_intr.c +++ b/drivers/infiniband/hw/ipath/ipath_intr.c @@ -70,7 +70,7 @@ void ipath_disarm_senderrbufs(struct ipath_devdata *dd) if (sbuf[0] || sbuf[1] || (piobcnt > 128 && (sbuf[2] || sbuf[3]))) { int i; if (ipath_debug & (__IPATH_PKTDBG|__IPATH_DBG) && - dd->ipath_lastcancel > jiffies) { + time_after(dd->ipath_lastcancel, jiffies)) { __IPATH_DBG_WHICH(__IPATH_PKTDBG|__IPATH_DBG, "SendbufErrs %lx %lx", sbuf[0], sbuf[1]); @@ -755,7 +755,7 @@ static int handle_errors(struct ipath_devdata *dd, ipath_err_t errs) /* likely due to cancel; so suppress message unless verbose */ if ((errs & (INFINIPATH_E_SPKTLEN | INFINIPATH_E_SPIOARMLAUNCH)) && - dd->ipath_lastcancel > jiffies) { + time_after(dd->ipath_lastcancel, jiffies)) { /* armlaunch takes precedence; it often causes both. */ ipath_cdbg(VERBOSE, "Suppressed %s error (%llx) after sendbuf cancel\n", diff --git a/drivers/infiniband/hw/ipath/ipath_sdma.c b/drivers/infiniband/hw/ipath/ipath_sdma.c index 98ac18e..17a5177 100644 --- a/drivers/infiniband/hw/ipath/ipath_sdma.c +++ b/drivers/infiniband/hw/ipath/ipath_sdma.c @@ -247,7 +247,7 @@ static void sdma_abort_task(unsigned long opaque) /* ipath_sdma_abort() is done, waiting for interrupt */ if (status == IPATH_SDMA_ABORT_DISARMED) { - if (jiffies < dd->ipath_sdma_abort_intr_timeout) + if (time_before(jiffies, dd->ipath_sdma_abort_intr_timeout)) goto resched_noprint; /* give up, intr got lost somewhere */ ipath_dbg("give up waiting for SDMADISABLED intr\n"); @@ -341,7 +341,7 @@ resched: * JAG - this is bad to just have default be a loop without * state change */ - if (jiffies > dd->ipath_sdma_abort_jiffies) { + if (time_after(jiffies, dd->ipath_sdma_abort_jiffies)) { ipath_dbg("looping with status 0x%08lx\n", dd->ipath_sdma_status); dd->ipath_sdma_abort_jiffies = jiffies + 5 * HZ; -- 1.7.10.4 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH] wan: time_before()
To be future-proof and for better readability the time comparisons are modified to use time_before() instead of plain, error-prone math. Signed-off-by: Manuel Schölling --- drivers/net/wan/farsync.c |4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/wan/farsync.c b/drivers/net/wan/farsync.c index bcfff0d..d007f60 100644 --- a/drivers/net/wan/farsync.c +++ b/drivers/net/wan/farsync.c @@ -697,14 +697,14 @@ fst_cpureset(struct fst_card_info *card) * We are delaying here to allow the 9054 to reset itself */ j = jiffies + 1; - while (jiffies < j) + while (time_before(jiffies, j)) /* Do nothing */ ; outw(0x240f, card->pci_conf + CNTRL_9054 + 2); /* * We are delaying here to allow the 9054 to reload its eeprom */ j = jiffies + 1; - while (jiffies < j) + while (time_before(jiffies, j)) /* Do nothing */ ; outw(0x040f, card->pci_conf + CNTRL_9054 + 2); -- 1.7.10.4 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH] mwifiex: use time_after()
To be future-proof and for better readability the time comparisons are modified to use time_after() instead of plain, error-prone math. Signed-off-by: Manuel Schölling --- drivers/net/wireless/mwifiex/main.h |2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/mwifiex/main.h b/drivers/net/wireless/mwifiex/main.h index d53e1e8..3191066 100644 --- a/drivers/net/wireless/mwifiex/main.h +++ b/drivers/net/wireless/mwifiex/main.h @@ -1101,7 +1101,7 @@ mwifiex_11h_get_csa_closed_channel(struct mwifiex_private *priv) return 0; /* Clear csa channel, if DFS channel move time has passed */ - if (jiffies > priv->csa_expire_time) { + if (time_after(jiffies, priv->csa_expire_time)) { priv->csa_chan = 0; priv->csa_expire_time = 0; } -- 1.7.10.4 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH] dgnc: Use time_after_eq()
To be future-proof and for better readability the time comparisons are modified to use time_after_eq() instead of plain, error-prone math. Signed-off-by: Manuel Schölling --- drivers/staging/dgnc/dgnc_neo.c |3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/staging/dgnc/dgnc_neo.c b/drivers/staging/dgnc/dgnc_neo.c index cf22c7b..a8ca22a 100644 --- a/drivers/staging/dgnc/dgnc_neo.c +++ b/drivers/staging/dgnc/dgnc_neo.c @@ -395,7 +395,8 @@ static inline void neo_clear_break(struct channel_t *ch, int force) /* Turn break off, and unset some variables */ if (ch->ch_flags & CH_BREAK_SENDING) { - if ((jiffies >= ch->ch_stop_sending_break) || force) { + if (time_after_eq(jiffies, ch->ch_stop_sending_break) + || force) { uchar temp = readb(&ch->ch_neo_uart->lcr); writeb((temp & ~UART_LCR_SBC), &ch->ch_neo_uart->lcr); neo_pci_posting_flush(ch->ch_bd); -- 1.7.10.4 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH] sgi-gru: use time_before()
To be future-proof and for better readability the time comparisons are modified to use time_before() instead of plain, error-prone math. Signed-off-by: Manuel Schölling --- drivers/misc/sgi-gru/grumain.c |4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/misc/sgi-gru/grumain.c b/drivers/misc/sgi-gru/grumain.c index ae16c8c..1525870 100644 --- a/drivers/misc/sgi-gru/grumain.c +++ b/drivers/misc/sgi-gru/grumain.c @@ -930,6 +930,7 @@ int gru_fault(struct vm_area_struct *vma, struct vm_fault *vmf) { struct gru_thread_state *gts; unsigned long paddr, vaddr; + unsigned long expires; vaddr = (unsigned long)vmf->virtual_address; gru_dbg(grudev, "vma %p, vaddr 0x%lx (0x%lx)\n", @@ -954,7 +955,8 @@ again: mutex_unlock(>s->ts_ctxlock); set_current_state(TASK_INTERRUPTIBLE); schedule_timeout(GRU_ASSIGN_DELAY); /* true hack ZZZ */ - if (gts->ts_steal_jiffies + GRU_STEAL_DELAY < jiffies) + expires = gts->ts_steal_jiffies + GRU_STEAL_DELAY; + if (time_before(expires, jiffies)) gru_steal_context(gts); goto again; } -- 1.7.10.4 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH] console: Add persistent scrollback buffers for all VGA consoles
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. Signed-off-by: Manuel Schölling --- drivers/video/console/Kconfig |6 +- drivers/video/console/vgacon.c | 124 2 files changed, 79 insertions(+), 51 deletions(-) diff --git a/drivers/video/console/Kconfig b/drivers/video/console/Kconfig index fe1cd01..d7ec96c 100644 --- a/drivers/video/console/Kconfig +++ b/drivers/video/console/Kconfig @@ -38,14 +38,14 @@ config VGACON_SOFT_SCROLLBACK RAM to allocate for this buffer. If unsure, say 'N'. config VGACON_SOFT_SCROLLBACK_SIZE - int "Scrollback Buffer Size (in KB)" + int "Scrollback Buffer Size per console (in KB)" depends on VGACON_SOFT_SCROLLBACK 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 +buffer for each VGA console. Each 64KB will give you approximately +16 80x25 screenfuls of scrollback buffer. config MDA_CONSOLE depends on !M68K && !PARISC && ISA diff --git a/drivers/video/console/vgacon.c b/drivers/video/console/vgacon.c index 9d8feac..215eafb 100644 --- a/drivers/video/console/vgacon.c +++ b/drivers/video/console/vgacon.c @@ -181,75 +181,101 @@ 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 void vgacon_scrollback_init(int pitch) +struct vgacon_scrollback_info { + void *data; + int tail; + int size; + int rows; + int cnt; + int cur; + int save; + int restore; +} vgacon_scrollbacks[MAX_NR_CONSOLES]; + +static void vgacon_scrollback_init(int vc_num) { + int pitch = vga_video_num_columns * 2; int rows = CONFIG_VGACON_SOFT_SCROLLBACK_SIZE * 1024/pitch; + void *data; - 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; + data = kcalloc(CONFIG_VGACON_SOFT_SCROLLBACK_SIZE, 1024, GFP_NOWAIT); + if (!data) { + pr_warn("VGAcon: failed to allocate memory for scrollback.\n"); + vgacon_scrollbacks[vc_num].data = NULL; + return; } + + vgacon_scrollbacks[vc_num].data = data; + vgacon_scrollbacks[vc_num].cnt = 0; + vgacon_scrollbacks[vc_num].tail = 0; + vgacon_scrollbacks[vc_num].cur = 0; + vgacon_scrollbacks[vc_num].rows = rows - 1; + vgacon_scrollbacks[vc_num].size = rows * pitch; +} + +static void vgacon_switch_scrollback(int vc_num) +{ + if (!vgacon_scrollbacks[vc_num].data) + vgacon_scrollback_init(vc_num); } static void vgacon_scrollback_startup(void) { - vgacon_scrollback = kcalloc(CONFIG_VGACON_SOFT_SCROLLBACK_SIZE, 1024, GFP_NOWAIT); - vgacon_scrollback_init(vga_video_num_columns * 2); + int i; + + for (i = 0; i < MAX_NR_CONSOLES; ++i) + vgacon_scrollbacks[i].data = NULL; + + vgacon_scrollback_init(0); } static void vgacon_scrollback_update(struct vc_data *c, int t, int count) { + struct vgacon_scrollback_info *scrollback; void *p; - if (!vgacon_scrollback_size || c->vc_num != fg_console) + scrollback = &vgacon_scrollbacks[c->vc_num]; + if (!scrollback->data || !scrollback->size) return; p = (void *) (c->vc_origin + t * c->vc_size_row); while (count--) { - scr_memcpyw(vgacon_scrollback + vgacon_scrollback_tail, + scr_memcpyw(scrollback->data + scrollback->tail, p, c->vc_size_row); - vgacon_scrollback_cnt++; + scrollback->cnt++; p += c->vc_size_row; - vgacon_scrollback_tail += c->vc_size_row; + scrollback->tail += c->vc_size_row; - if (vgacon_scrollback_tail >= vgacon_scrollback_size) - vgacon_scrollback_tail = 0; + if (scrollback->tail >= scrollback->size) + scrollback->tail = 0; - if (vgacon_scrollback_cnt >
[PATCH RESEND] sgi-gru: use time_before()
To be future-proof and for better readability the time comparisons are modified to use time_before() instead of plain, error-prone math. Signed-off-by: Manuel Schölling --- drivers/misc/sgi-gru/grumain.c |4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/misc/sgi-gru/grumain.c b/drivers/misc/sgi-gru/grumain.c index ae16c8c..1525870 100644 --- a/drivers/misc/sgi-gru/grumain.c +++ b/drivers/misc/sgi-gru/grumain.c @@ -930,6 +930,7 @@ int gru_fault(struct vm_area_struct *vma, struct vm_fault *vmf) { struct gru_thread_state *gts; unsigned long paddr, vaddr; + unsigned long expires; vaddr = (unsigned long)vmf->virtual_address; gru_dbg(grudev, "vma %p, vaddr 0x%lx (0x%lx)\n", @@ -954,7 +955,8 @@ again: mutex_unlock(>s->ts_ctxlock); set_current_state(TASK_INTERRUPTIBLE); schedule_timeout(GRU_ASSIGN_DELAY); /* true hack ZZZ */ - if (gts->ts_steal_jiffies + GRU_STEAL_DELAY < jiffies) + expires = gts->ts_steal_jiffies + GRU_STEAL_DELAY; + if (time_before(expires, jiffies)) gru_steal_context(gts); goto again; } -- 1.7.10.4 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH v2] console: Add persistent scrollback buffers for all VGA consoles
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. Signed-off-by: Manuel Schölling --- drivers/video/console/Kconfig | 19 - drivers/video/console/vgacon.c | 159 +++- 2 files changed, 124 insertions(+), 54 deletions(-) diff --git a/drivers/video/console/Kconfig b/drivers/video/console/Kconfig index fe1cd01..05fdc2c 100644 --- a/drivers/video/console/Kconfig +++ b/drivers/video/console/Kconfig @@ -43,9 +43,22 @@ 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_FOR_EACH_CONSOLE + bool "Persistent Scrollback History for each console" + depends on VGACON_SOFT_SCROLLBACK + default y + help + Say Y here if for each VGA console a scrollback buffer should + be allocated. The scrollback history will persist when switching + between consoles. If you say N here, scrollback is only supported + for the active VGA console and scrollback history will be flushed + when switching between consoles. + + 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 9d8feac..652131d 100644 --- a/drivers/video/console/vgacon.c +++ b/drivers/video/console/vgacon.c @@ -181,70 +181,126 @@ 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 void vgacon_scrollback_init(int pitch) +struct vgacon_scrollback_info { + void *data; + int tail; + int size; + int rows; + int cnt; + int cur; + int save; + int restore; +}; +static struct vgacon_scrollback_info *vgacon_scrollback_cur; +#ifdef CONFIG_VGACON_SOFT_SCROLLBACK_FOR_EACH_CONSOLE +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) { - 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_cur->data && reset_size > 0) + memset(vgacon_scrollback_cur->data, 0, reset_size); + + vgacon_scrollback_cur->cnt = 0; + vgacon_scrollback_cur->tail = 0; + vgacon_scrollback_cur->cur = 0; +} + +static void vgacon_scrollback_init(int vc_num) +{ + int pitch = vga_video_num_columns * 2; + size_t size = CONFIG_VGACON_SOFT_SCROLLBACK_SIZE * 1024; + int rows = size/pitch; + void *data; + + data = kcalloc(CONFIG_VGACON_SOFT_SCROLLBACK_SIZE, 1024, GFP_NOWAIT); + if (data) { + 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(0); + } else { + pr_warn("VGAcon: failed to allocate memory for scrollback. Trying to reuse previous buffer.\n"); + /* leave vgacon_scrollback_cur untouched + but reset its content */ + vgacon_scrollback_reset(size); } } +static void vgacon_switch_scrollback(int vc_num) +{ +#ifdef CONFIG_VGACON_SOFT_SCROLLBACK_FOR_EACH_CONSOLE + if (!vgacon_scrollbacks[vc_num].data) + vgacon_scrollback_init(vc_num); + else + vgacon_scrollback_cur = &vgacon_scrollbacks[vc_num]; +#else + vc_num = 0; + + if (!vgacon_scrollbacks[vc_num].data) + vgacon_scrollback_init(vc_num); + else { + size_t size = CONFIG_VGACON_SOFT_SCROLLBACK_SIZE * 1024
[PATCH] wan: Use usleep_range()
Instead of using a jiffies hack we can use the standard api for delays. Signed-off-by: Manuel Schölling --- drivers/net/wan/farsync.c | 10 +++--- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/drivers/net/wan/farsync.c b/drivers/net/wan/farsync.c index bcfff0d..02f6d1c 100644 --- a/drivers/net/wan/farsync.c +++ b/drivers/net/wan/farsync.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include @@ -678,7 +679,6 @@ static inline void fst_cpureset(struct fst_card_info *card) { unsigned char interrupt_line_register; - unsigned long j = jiffies + 1; unsigned int regval; if (card->family == FST_FAMILY_TXU) { @@ -696,16 +696,12 @@ fst_cpureset(struct fst_card_info *card) /* * We are delaying here to allow the 9054 to reset itself */ - j = jiffies + 1; - while (jiffies < j) - /* Do nothing */ ; + usleep_range(10, 20); outw(0x240f, card->pci_conf + CNTRL_9054 + 2); /* * We are delaying here to allow the 9054 to reload its eeprom */ - j = jiffies + 1; - while (jiffies < j) - /* Do nothing */ ; + usleep_range(10, 20); outw(0x040f, card->pci_conf + CNTRL_9054 + 2); if (pci_write_config_byte -- 1.7.10.4 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH] dns_resolver: Do not accept domain names longer than 255 chars
According to RFC1035 "[...] the total length of a domain name (i.e., label octets and label length octets) is restricted to 255 octets or less." Signed-off-by: Manuel Schölling --- net/dns_resolver/dns_query.c |2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/dns_resolver/dns_query.c b/net/dns_resolver/dns_query.c index e7b6d53..e0fde29 100644 --- a/net/dns_resolver/dns_query.c +++ b/net/dns_resolver/dns_query.c @@ -94,7 +94,7 @@ int dns_query(const char *type, const char *name, size_t namelen, if (!namelen) namelen = strlen(name); - if (namelen < 3) + if (namelen < 3 || namelen > 255) return -EINVAL; desclen += namelen + 1; -- 1.7.10.4 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH v2] dns_resolver: Do not accept domain names longer than 255 chars
According to RFC1035 "[...] the total length of a domain name (i.e., label octets and label length octets) is restricted to 255 octets or less." Signed-off-by: Manuel Schölling --- net/dns_resolver/dns_query.c |4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/net/dns_resolver/dns_query.c b/net/dns_resolver/dns_query.c index e7b6d53..5b49958 100644 --- a/net/dns_resolver/dns_query.c +++ b/net/dns_resolver/dns_query.c @@ -93,8 +93,8 @@ int dns_query(const char *type, const char *name, size_t namelen, } if (!namelen) - namelen = strlen(name); - if (namelen < 3) + namelen = strnlen(name, 256); + if (namelen < 3 || namelen > 255) return -EINVAL; desclen += namelen + 1; -- 1.7.10.4 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH RESEND v2] console: Add persistent scrollback buffers for all VGA consoles
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. Signed-off-by: Manuel Schölling --- drivers/video/console/Kconfig | 19 - drivers/video/console/vgacon.c | 159 +++- 2 files changed, 124 insertions(+), 54 deletions(-) diff --git a/drivers/video/console/Kconfig b/drivers/video/console/Kconfig index fe1cd01..05fdc2c 100644 --- a/drivers/video/console/Kconfig +++ b/drivers/video/console/Kconfig @@ -43,9 +43,22 @@ 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_FOR_EACH_CONSOLE + bool "Persistent Scrollback History for each console" + depends on VGACON_SOFT_SCROLLBACK + default y + help + Say Y here if for each VGA console a scrollback buffer should + be allocated. The scrollback history will persist when switching + between consoles. If you say N here, scrollback is only supported + for the active VGA console and scrollback history will be flushed + when switching between consoles. + + 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 9d8feac..652131d 100644 --- a/drivers/video/console/vgacon.c +++ b/drivers/video/console/vgacon.c @@ -181,70 +181,126 @@ 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 void vgacon_scrollback_init(int pitch) +struct vgacon_scrollback_info { + void *data; + int tail; + int size; + int rows; + int cnt; + int cur; + int save; + int restore; +}; +static struct vgacon_scrollback_info *vgacon_scrollback_cur; +#ifdef CONFIG_VGACON_SOFT_SCROLLBACK_FOR_EACH_CONSOLE +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) { - 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_cur->data && reset_size > 0) + memset(vgacon_scrollback_cur->data, 0, reset_size); + + vgacon_scrollback_cur->cnt = 0; + vgacon_scrollback_cur->tail = 0; + vgacon_scrollback_cur->cur = 0; +} + +static void vgacon_scrollback_init(int vc_num) +{ + int pitch = vga_video_num_columns * 2; + size_t size = CONFIG_VGACON_SOFT_SCROLLBACK_SIZE * 1024; + int rows = size/pitch; + void *data; + + data = kcalloc(CONFIG_VGACON_SOFT_SCROLLBACK_SIZE, 1024, GFP_NOWAIT); + if (data) { + 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(0); + } else { + pr_warn("VGAcon: failed to allocate memory for scrollback. Trying to reuse previous buffer.\n"); + /* leave vgacon_scrollback_cur untouched + but reset its content */ + vgacon_scrollback_reset(size); } } +static void vgacon_switch_scrollback(int vc_num) +{ +#ifdef CONFIG_VGACON_SOFT_SCROLLBACK_FOR_EACH_CONSOLE + if (!vgacon_scrollbacks[vc_num].data) + vgacon_scrollback_init(vc_num); + else + vgacon_scrollback_cur = &vgacon_scrollbacks[vc_num]; +#else + vc_num = 0; + + if (!vgacon_scrollbacks[vc_num].data) + vgacon_scrollback_init(vc_num); + else { + size_t size = CONFIG_VGACON_SOFT_SCROLLBACK_SIZE * 1024
[PATCH] console: Add persistent scrollback buffers for all VGA consoles
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 --- drivers/video/console/Kconfig | 23 +- drivers/video/console/vgacon.c | 172 +++-- 2 files changed, 134 insertions(+), 61 deletions(-) diff --git a/drivers/video/console/Kconfig b/drivers/video/console/Kconfig index 38da6e2..67e52f0 100644 --- a/drivers/video/console/Kconfig +++ b/drivers/video/console/Kconfig @@ -43,9 +43,26 @@ 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_FOR_EACH_CONSOLE + bool "Persistent Scrollback History for each console" + depends on VGACON_SOFT_SCROLLBACK + default n + help + Say Y here if for each VGA console a scrollback buffer should + be allocated. The scrollback history will persist when switching + between consoles. If you say N here, scrollback is only supported + for the active VGA console and scrollback history will be flushed + when switching between consoles. + + This breaks legacy versions of tools like clear_console which + might cause security issues. + Use the escape sequence \e[3J instead if this feature is activated. + + 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 517f565..6c0b9ba 100644 --- a/drivers/video/console/vgacon.c +++ b/drivers/video/console/vgacon.c @@ -1,5 +1,5 @@ /* - * linux/drivers/video/vgacon.c -- Low level VGA based console driver + * linux/drivers/video/console/vgacon.c -- Low level VGA based console driver * * Created 28 Sep 1997 by Geert Uytterhoeven * @@ -106,12 +106,12 @@ static unsigned char vga_hardscroll_enabled __read_mostly; static unsigned char vga_hardscroll_user_enable __read_mostly = 1; static unsigned char vga_font_is_default = 1; static int vga_vesa_blanked; -static int vga_palette_blanked; -static int vga_is_gfx; -static int vga_512_chars; -static int vga_video_font_height; -static int vga_scan_lines __read_mostly; -static unsigned intvga_rolled_over; +static int vga_palette_blanked; +static int vga_is_gfx; +static int vga_512_chars; +static int vga_video_font_height; +static int vga_scan_lines __read_mostly; +static unsigned intvga_rolled_over; static int vgacon_text_mode_force; @@ -182,70 +182,125 @@ 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 void vgacon_scrollback_init(int pitch) +struct vgacon_scrollback_info { + void *data; + int tail; + int size; + int rows; + int cnt; + int cur; + int save; + int restore; +}; +static struct vgacon_scrollback_info *vgacon_scrollback_cur; +#ifdef CONFIG_VGACON_SOFT_SCROLLBACK_FOR_EACH_CONSOLE +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) { - 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_cur->data && reset_size > 0) + memset(vgacon_scrollback_cur->data, 0, reset_size); + + vgacon_scrollback_cur->cnt = 0; + vgacon
[PATCH] console: Add persistent scrollback buffers for all VGA consoles
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 --- drivers/video/console/Kconfig | 23 +- drivers/video/console/vgacon.c | 172 +++-- 2 files changed, 134 insertions(+), 61 deletions(-) diff --git a/drivers/video/console/Kconfig b/drivers/video/console/Kconfig index 38da6e2..67e52f0 100644 --- a/drivers/video/console/Kconfig +++ b/drivers/video/console/Kconfig @@ -43,9 +43,26 @@ 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_FOR_EACH_CONSOLE + bool "Persistent Scrollback History for each console" + depends on VGACON_SOFT_SCROLLBACK + default n + help + Say Y here if for each VGA console a scrollback buffer should + be allocated. The scrollback history will persist when switching + between consoles. If you say N here, scrollback is only supported + for the active VGA console and scrollback history will be flushed + when switching between consoles. + + This breaks legacy versions of tools like clear_console which + might cause security issues. + Use the escape sequence \e[3J instead if this feature is activated. + + 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 517f565..6c0b9ba 100644 --- a/drivers/video/console/vgacon.c +++ b/drivers/video/console/vgacon.c @@ -1,5 +1,5 @@ /* - * linux/drivers/video/vgacon.c -- Low level VGA based console driver + * linux/drivers/video/console/vgacon.c -- Low level VGA based console driver * * Created 28 Sep 1997 by Geert Uytterhoeven * @@ -106,12 +106,12 @@ static unsigned char vga_hardscroll_enabled __read_mostly; static unsigned char vga_hardscroll_user_enable __read_mostly = 1; static unsigned char vga_font_is_default = 1; static int vga_vesa_blanked; -static int vga_palette_blanked; -static int vga_is_gfx; -static int vga_512_chars; -static int vga_video_font_height; -static int vga_scan_lines __read_mostly; -static unsigned intvga_rolled_over; +static int vga_palette_blanked; +static int vga_is_gfx; +static int vga_512_chars; +static int vga_video_font_height; +static int vga_scan_lines __read_mostly; +static unsigned intvga_rolled_over; static int vgacon_text_mode_force; @@ -182,70 +182,125 @@ 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 void vgacon_scrollback_init(int pitch) +struct vgacon_scrollback_info { + void *data; + int tail; + int size; + int rows; + int cnt; + int cur; + int save; + int restore; +}; +static struct vgacon_scrollback_info *vgacon_scrollback_cur; +#ifdef CONFIG_VGACON_SOFT_SCROLLBACK_FOR_EACH_CONSOLE +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) { - 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_cur->data && reset_size > 0) + memset(vgacon_scrollback_cur->data, 0, reset_size); + + vgacon_scrollback_cur->cnt = 0; + vgacon
[PATCH] console: Add persistent scrollback buffers for all VGA consoles
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 --- drivers/video/console/Kconfig | 23 +- drivers/video/console/vgacon.c | 172 +++-- 2 files changed, 134 insertions(+), 61 deletions(-) diff --git a/drivers/video/console/Kconfig b/drivers/video/console/Kconfig index 38da6e2..67e52f0 100644 --- a/drivers/video/console/Kconfig +++ b/drivers/video/console/Kconfig @@ -43,9 +43,26 @@ 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_FOR_EACH_CONSOLE + bool "Persistent Scrollback History for each console" + depends on VGACON_SOFT_SCROLLBACK + default n + help + Say Y here if for each VGA console a scrollback buffer should + be allocated. The scrollback history will persist when switching + between consoles. If you say N here, scrollback is only supported + for the active VGA console and scrollback history will be flushed + when switching between consoles. + + This breaks legacy versions of tools like clear_console which + might cause security issues. + Use the escape sequence \e[3J instead if this feature is activated. + + 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 517f565..6c0b9ba 100644 --- a/drivers/video/console/vgacon.c +++ b/drivers/video/console/vgacon.c @@ -1,5 +1,5 @@ /* - * linux/drivers/video/vgacon.c -- Low level VGA based console driver + * linux/drivers/video/console/vgacon.c -- Low level VGA based console driver * * Created 28 Sep 1997 by Geert Uytterhoeven * @@ -106,12 +106,12 @@ static unsigned char vga_hardscroll_enabled __read_mostly; static unsigned char vga_hardscroll_user_enable __read_mostly = 1; static unsigned char vga_font_is_default = 1; static int vga_vesa_blanked; -static int vga_palette_blanked; -static int vga_is_gfx; -static int vga_512_chars; -static int vga_video_font_height; -static int vga_scan_lines __read_mostly; -static unsigned intvga_rolled_over; +static int vga_palette_blanked; +static int vga_is_gfx; +static int vga_512_chars; +static int vga_video_font_height; +static int vga_scan_lines __read_mostly; +static unsigned intvga_rolled_over; static int vgacon_text_mode_force; @@ -182,70 +182,125 @@ 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 void vgacon_scrollback_init(int pitch) +struct vgacon_scrollback_info { + void *data; + int tail; + int size; + int rows; + int cnt; + int cur; + int save; + int restore; +}; +static struct vgacon_scrollback_info *vgacon_scrollback_cur; +#ifdef CONFIG_VGACON_SOFT_SCROLLBACK_FOR_EACH_CONSOLE +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) { - 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_cur->data && reset_size > 0) + memset(vgacon_scrollback_cur->data, 0, reset_size); + + vgacon_scrollback_cur->cnt = 0; + vgacon
[PATCH] console: Add persistent scrollback buffers for all VGA consoles
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 --- drivers/video/console/Kconfig | 23 +- drivers/video/console/vgacon.c | 172 +++-- 2 files changed, 134 insertions(+), 61 deletions(-) diff --git a/drivers/video/console/Kconfig b/drivers/video/console/Kconfig index 38da6e2..67e52f0 100644 --- a/drivers/video/console/Kconfig +++ b/drivers/video/console/Kconfig @@ -43,9 +43,26 @@ 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_FOR_EACH_CONSOLE + bool "Persistent Scrollback History for each console" + depends on VGACON_SOFT_SCROLLBACK + default n + help + Say Y here if for each VGA console a scrollback buffer should + be allocated. The scrollback history will persist when switching + between consoles. If you say N here, scrollback is only supported + for the active VGA console and scrollback history will be flushed + when switching between consoles. + + This breaks legacy versions of tools like clear_console which + might cause security issues. + Use the escape sequence \e[3J instead if this feature is activated. + + 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 517f565..6c0b9ba 100644 --- a/drivers/video/console/vgacon.c +++ b/drivers/video/console/vgacon.c @@ -1,5 +1,5 @@ /* - * linux/drivers/video/vgacon.c -- Low level VGA based console driver + * linux/drivers/video/console/vgacon.c -- Low level VGA based console driver * * Created 28 Sep 1997 by Geert Uytterhoeven * @@ -106,12 +106,12 @@ static unsigned char vga_hardscroll_enabled __read_mostly; static unsigned char vga_hardscroll_user_enable __read_mostly = 1; static unsigned char vga_font_is_default = 1; static int vga_vesa_blanked; -static int vga_palette_blanked; -static int vga_is_gfx; -static int vga_512_chars; -static int vga_video_font_height; -static int vga_scan_lines __read_mostly; -static unsigned intvga_rolled_over; +static int vga_palette_blanked; +static int vga_is_gfx; +static int vga_512_chars; +static int vga_video_font_height; +static int vga_scan_lines __read_mostly; +static unsigned intvga_rolled_over; static int vgacon_text_mode_force; @@ -182,70 +182,125 @@ 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 void vgacon_scrollback_init(int pitch) +struct vgacon_scrollback_info { + void *data; + int tail; + int size; + int rows; + int cnt; + int cur; + int save; + int restore; +}; +static struct vgacon_scrollback_info *vgacon_scrollback_cur; +#ifdef CONFIG_VGACON_SOFT_SCROLLBACK_FOR_EACH_CONSOLE +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) { - 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_cur->data && reset_size > 0) + memset(vgacon_scrollback_cur->data, 0, reset_size); + + vgacon_scrollback_cur->cnt = 0; + vgacon
[PATCH 0/2] Persistent scrollback buffers for all VGA consoles
Another attempt to add persistent scrollback buffers for all VGA consoles, so the buffer is not flushed when swithing back and forth between consoles. Note that breaks tools like bash's clear_console and thus might have security implications: clear_console relies on this 'anti-feature' of the kernel to clear the buffer when consoles are switched. To offer a way for userland tools to flush the buffer my second patch adds a ioctl call for that. Also this feature is disabled by default and security implications are clearly stated in its documentation. Manuel Schölling (2): console: Add persistent scrollback buffers for all VGA consoles console: Add ioctl for flushing the scrollback buffer drivers/tty/vt/vt_ioctl.c | 20 drivers/usb/misc/sisusbvga/sisusb_con.c | 1 + drivers/video/console/Kconfig | 22 +++- drivers/video/console/dummycon.c| 1 + drivers/video/console/mdacon.c | 6 + drivers/video/console/newport_con.c | 1 + drivers/video/console/sticon.c | 7 ++ drivers/video/console/vgacon.c | 195 ++-- include/linux/console.h | 1 + include/uapi/linux/vt.h | 1 + 10 files changed, 194 insertions(+), 61 deletions(-) -- 2.1.4
[PATCH 0/2] Persistent scrollback buffers for all VGA consoles
Another attempt to add persistent scrollback buffers for all VGA consoles, so the buffer is not flushed when swithing back and forth between consoles. Note that breaks tools like bash's clear_console and thus might have security implications: clear_console relies on this 'anti-feature' of the kernel to clear the buffer when consoles are switched. To offer a way for userland tools to flush the buffer my second patch adds a ioctl call for that. Also this feature is disabled by default and security implications are clearly stated in its documentation. Manuel Schölling (2): console: Add persistent scrollback buffers for all VGA consoles console: Add ioctl for flushing the scrollback buffer drivers/tty/vt/vt_ioctl.c | 20 drivers/usb/misc/sisusbvga/sisusb_con.c | 1 + drivers/video/console/Kconfig | 22 +++- drivers/video/console/dummycon.c| 1 + drivers/video/console/mdacon.c | 6 + drivers/video/console/newport_con.c | 1 + drivers/video/console/sticon.c | 7 ++ drivers/video/console/vgacon.c | 195 ++-- include/linux/console.h | 1 + include/uapi/linux/vt.h | 1 + 10 files changed, 194 insertions(+), 61 deletions(-) -- 2.1.4
[PATCH 1/2] console: Add persistent scrollback buffers for all VGA consoles
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. Signed-off-by: Manuel Schölling --- drivers/video/console/Kconfig | 22 +- drivers/video/console/vgacon.c | 172 +++-- 2 files changed, 133 insertions(+), 61 deletions(-) diff --git a/drivers/video/console/Kconfig b/drivers/video/console/Kconfig index 38da6e2..f101a63 100644 --- a/drivers/video/console/Kconfig +++ b/drivers/video/console/Kconfig @@ -43,9 +43,25 @@ 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_FOR_EACH_CONSOLE + bool "Persistent Scrollback History for each console" + depends on VGACON_SOFT_SCROLLBACK + default n + help + Say Y here if for each VGA console a scrollback buffer should + be allocated. The scrollback history will persist when switching + between consoles. If you say N here, scrollback is only supported + for the active VGA console and scrollback history will be flushed + when switching between consoles. + + This breaks legacy versions of tools like clear_console which + might raise security issues. + + 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 517f565..6c0b9ba 100644 --- a/drivers/video/console/vgacon.c +++ b/drivers/video/console/vgacon.c @@ -1,5 +1,5 @@ /* - * linux/drivers/video/vgacon.c -- Low level VGA based console driver + * linux/drivers/video/console/vgacon.c -- Low level VGA based console driver * * Created 28 Sep 1997 by Geert Uytterhoeven * @@ -106,12 +106,12 @@ static unsigned char vga_hardscroll_enabled __read_mostly; static unsigned char vga_hardscroll_user_enable __read_mostly = 1; static unsigned char vga_font_is_default = 1; static int vga_vesa_blanked; -static int vga_palette_blanked; -static int vga_is_gfx; -static int vga_512_chars; -static int vga_video_font_height; -static int vga_scan_lines __read_mostly; -static unsigned intvga_rolled_over; +static int vga_palette_blanked; +static int vga_is_gfx; +static int vga_512_chars; +static int vga_video_font_height; +static int vga_scan_lines __read_mostly; +static unsigned intvga_rolled_over; static int vgacon_text_mode_force; @@ -182,70 +182,125 @@ 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 void vgacon_scrollback_init(int pitch) +struct vgacon_scrollback_info { + void *data; + int tail; + int size; + int rows; + int cnt; + int cur; + int save; + int restore; +}; +static struct vgacon_scrollback_info *vgacon_scrollback_cur; +#ifdef CONFIG_VGACON_SOFT_SCROLLBACK_FOR_EACH_CONSOLE +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) { - 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_cur->data && reset_size > 0) + memset(vgacon_scrollback_cur->data, 0, reset_size); + + vgacon_scrollback_cur->cnt = 0; + vgacon_scrollback_cur->tail = 0; + vgacon_scrollback_cur->cur = 0; +} + +static void vgacon_scrollback_init(int vc_num) +{ +
[PATCH 2/2] console: Add ioctl for flushing the scrollback buffer
Tools like clear_console rely on the fact that scrollback history is flushed when switching back and forth between consoles. Persistent scrollback buffers for each console breaks this, so this patch adds a ioctl() callf for flushing the scrollback history. Signed-off-by: Manuel Schölling --- drivers/tty/vt/vt_ioctl.c | 20 drivers/usb/misc/sisusbvga/sisusb_con.c | 1 + drivers/video/console/dummycon.c| 1 + drivers/video/console/mdacon.c | 6 ++ drivers/video/console/newport_con.c | 1 + drivers/video/console/sticon.c | 7 +++ drivers/video/console/vgacon.c | 23 +++ include/linux/console.h | 1 + include/uapi/linux/vt.h | 1 + 9 files changed, 61 insertions(+) diff --git a/drivers/tty/vt/vt_ioctl.c b/drivers/tty/vt/vt_ioctl.c index 97d5a74..18adc23 100644 --- a/drivers/tty/vt/vt_ioctl.c +++ b/drivers/tty/vt/vt_ioctl.c @@ -903,6 +903,26 @@ int vt_ioctl(struct tty_struct *tty, break; } + /* +* flush the specified VT's scollback buffer +*/ + case VT_FLUSH_SCROLLBACK: { + if (!perm) + return -EPERM; + if (arg == 0 || arg > MAX_NR_CONSOLES) + ret = -ENXIO; + else { + struct vc_data *data = vc_cons[arg-1].d; + + if (!data) + ret = -ENXIO; + else + ret = data->vc_sw->con_flush_scrollback(data); + } + + break; + } + case PIO_FONT: { if (!perm) return -EPERM; diff --git a/drivers/usb/misc/sisusbvga/sisusb_con.c b/drivers/usb/misc/sisusbvga/sisusb_con.c index ace3430..cc5fc10 100644 --- a/drivers/usb/misc/sisusbvga/sisusb_con.c +++ b/drivers/usb/misc/sisusbvga/sisusb_con.c @@ -1442,6 +1442,7 @@ static const struct consw sisusb_dummy_con = { .con_font_copy =SISUSBCONDUMMY, .con_set_palette = SISUSBCONDUMMY, .con_scrolldelta = SISUSBCONDUMMY, + .con_flush_scrollback = SISUSBCONDUMMY, }; int diff --git a/drivers/video/console/dummycon.c b/drivers/video/console/dummycon.c index 0efc52f..d2888e5 100644 --- a/drivers/video/console/dummycon.c +++ b/drivers/video/console/dummycon.c @@ -73,5 +73,6 @@ const struct consw dummy_con = { .con_font_copy = DUMMY, .con_set_palette = DUMMY, .con_scrolldelta = DUMMY, +.con_flush_scrollback = DUMMY, }; EXPORT_SYMBOL_GPL(dummy_con); diff --git a/drivers/video/console/mdacon.c b/drivers/video/console/mdacon.c index 296e945..10ebcbe 100644 --- a/drivers/video/console/mdacon.c +++ b/drivers/video/console/mdacon.c @@ -510,6 +510,11 @@ static int mdacon_scrolldelta(struct vc_data *c, int lines) return 0; } +static int mdacon_flush_scrollback(struct vc_data *c) +{ + return 0; +} + static void mdacon_cursor(struct vc_data *c, int mode) { if (mode == CM_ERASE) { @@ -579,6 +584,7 @@ static const struct consw mda_con = { .con_blank =mdacon_blank, .con_set_palette = mdacon_set_palette, .con_scrolldelta = mdacon_scrolldelta, + .con_flush_scrollback = mdacon_flush_scrollback, .con_build_attr = mdacon_build_attr, .con_invert_region =mdacon_invert_region, }; diff --git a/drivers/video/console/newport_con.c b/drivers/video/console/newport_con.c index bb4e962..d04183c 100644 --- a/drivers/video/console/newport_con.c +++ b/drivers/video/console/newport_con.c @@ -738,6 +738,7 @@ const struct consw newport_con = { .con_scrolldelta = newport_scrolldelta, .con_set_origin = DUMMY, .con_save_screen = DUMMY + .con_flush_scrollback = DUMMY, }; static int newport_probe(struct gio_device *dev, diff --git a/drivers/video/console/sticon.c b/drivers/video/console/sticon.c index 026fd12..46046d6 100644 --- a/drivers/video/console/sticon.c +++ b/drivers/video/console/sticon.c @@ -345,6 +345,12 @@ static void sticon_save_screen(struct vc_data *conp) { } +static int sticon_flush_scrollback(struct vc_data *c) +{ + return 0; +} + + static const struct consw sti_con = { .owner = THIS_MODULE, .con_startup= sticon_startup, @@ -360,6 +366,7 @@ static const struct consw sti_con = { .con_blank = sticon_blank, .con_set_palette= sticon_set_palette, .con_scrolldelta= sticon_scrolldelta, + .con_flush_scrollback = sticon_flush_scrollback, .con_set_origin = sticon_set_origin, .con_save_screen= sticon_save_screen, .con_build_attr = sticon_build_attr, diff --git a/drivers/video/console/vgacon.c b/drivers/video/console/vgacon.c index 6c0b9ba..b5ea94f 100644
[PATCH] console: Add persistent scrollback buffers for all VGA consoles
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 --- drivers/video/console/Kconfig | 23 +- drivers/video/console/vgacon.c | 172 +++-- 2 files changed, 134 insertions(+), 61 deletions(-) diff --git a/drivers/video/console/Kconfig b/drivers/video/console/Kconfig index 38da6e2..67e52f0 100644 --- a/drivers/video/console/Kconfig +++ b/drivers/video/console/Kconfig @@ -43,9 +43,26 @@ 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_FOR_EACH_CONSOLE + bool "Persistent Scrollback History for each console" + depends on VGACON_SOFT_SCROLLBACK + default n + help + Say Y here if for each VGA console a scrollback buffer should + be allocated. The scrollback history will persist when switching + between consoles. If you say N here, scrollback is only supported + for the active VGA console and scrollback history will be flushed + when switching between consoles. + + This breaks legacy versions of tools like clear_console which + might cause security issues. + Use the escape sequence \e[3J instead if this feature is activated. + + 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 517f565..6c0b9ba 100644 --- a/drivers/video/console/vgacon.c +++ b/drivers/video/console/vgacon.c @@ -1,5 +1,5 @@ /* - * linux/drivers/video/vgacon.c -- Low level VGA based console driver + * linux/drivers/video/console/vgacon.c -- Low level VGA based console driver * * Created 28 Sep 1997 by Geert Uytterhoeven * @@ -106,12 +106,12 @@ static unsigned char vga_hardscroll_enabled __read_mostly; static unsigned char vga_hardscroll_user_enable __read_mostly = 1; static unsigned char vga_font_is_default = 1; static int vga_vesa_blanked; -static int vga_palette_blanked; -static int vga_is_gfx; -static int vga_512_chars; -static int vga_video_font_height; -static int vga_scan_lines __read_mostly; -static unsigned intvga_rolled_over; +static int vga_palette_blanked; +static int vga_is_gfx; +static int vga_512_chars; +static int vga_video_font_height; +static int vga_scan_lines __read_mostly; +static unsigned intvga_rolled_over; static int vgacon_text_mode_force; @@ -182,70 +182,125 @@ 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 void vgacon_scrollback_init(int pitch) +struct vgacon_scrollback_info { + void *data; + int tail; + int size; + int rows; + int cnt; + int cur; + int save; + int restore; +}; +static struct vgacon_scrollback_info *vgacon_scrollback_cur; +#ifdef CONFIG_VGACON_SOFT_SCROLLBACK_FOR_EACH_CONSOLE +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) { - 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_cur->data && reset_size > 0) + memset(vgacon_scrollback_cur->data, 0, reset_size); + + vgacon_scrollback_cur->cnt = 0; + vgacon
Re: [PATCH v7 0/3] console: Add persistent scrollback buffers for all VGA consoles
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 > > Tested-by: Andrey Utkin > > Tested-by: Adam Borowski > > > > -- > > 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 (kilob...@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.
[PATCH v6 1/2] console: Move scrollback data into its own struct
This refactoring is in preparation for persistent scrollback support for VGA console. Signed-off-by: Manuel Schölling --- 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);
[PATCH v6 0/2] console: Add persistent scrollback buffers for all VGA consoles
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 (2): console: Move scrollback data into its own struct console: Add persistent scrollback buffers for all VGA consoles drivers/video/console/Kconfig | 25 ++- drivers/video/console/vgacon.c | 149 +++-- 2 files changed, 120 insertions(+), 54 deletions(-) -- 2.1.4
[PATCH v6 2/2] console: Add persistent scrollback buffers for all VGA consoles
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 --- drivers/video/console/Kconfig | 25 +++- drivers/video/console/vgacon.c | 134 +++-- 2 files changed, 111 insertions(+), 48 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 48b9764..896d02b 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,64 +171,107 @@ 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_init(int pitch) +static void vgacon_scrollback_reset(size_t reset_size) { - 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; + if (vgacon_scrollback_cur->data && reset_size > 0) + memset(vgacon_scrollback_cur->data, 0, reset_size); + + vgacon_scrollback_cur->cnt = 0; + vgacon_scrollback_cur->tail = 0; + vgacon_scrollback_cur->cur = 0; +} + +static void vgacon_scrollback_init(int vc_num) +{ + 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(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_scrollbac
Re: [PATCH v5 2/2] console: Add persistent scrollback buffers for all VGA consoles
Hi Adam, On Mo, 2016-11-21 at 21:17 +0100, Adam Borowski wrote: > On Sun, Nov 20, 2016 at 10:58:08PM +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. > First, big thanks for this fix, it's something that greatly annoyed me > since forever! Yeah, me too! ;) > The thing about clear_console is unfortunate: they abused the bug you're > fixing. I've asked to use \e[3J (https://bugs.debian.org/845177) so there's > hope it'll be applied in stretch; with Debian configuring its glibc to > support only kernels from two releases before (in jessie that's 2.6.32, in > stretch 3.2)[1] there's hope we can flip the default in several years. > > Do you suspect any other program relies on VT switch to clear the > scrollback? Not, AFAIK. Although I do not have a complete list of programs that are suppose to do that. > But alas, this commit breaks that very \e[3J. It does only a \e[2J, leaving > the scrollback uncleared. For comparison, both mainline and with just your > preparatory commit, \e[3J works as expected. Really? All my tests worked fine: I compiled the kernel with the latest patches, started the kernel in QEMU and then did $ openvt /bin/sh $ echo -e '\e[3J' # scrollback buffer was flushed correctly $ chvt 2 $ echo -e '\e[3J' # scrollback buffer was flushed correctly Can you tell me how you tested it? Maybe I can reproduce the bug. Thanks for spending the time to test it! Bye, Manuel
Re: [PATCH v6 2/2] console: Add persistent scrollback buffers for all VGA consoles
On Di, 2016-11-22 at 19:31 +, Andrey Utkin wrote: > I'm not sure my emails with review of previous submission reached you, but in > them I meant to mention that there are some style nits which are easy to > eliminate. I am afraid I did not get it. I will fix these style issues in the next patch: Adam Borowski found another issue with clearing the scrollback buffer, which I am finally able to reproduce. > P. S. Manuel, please fix your git-send-email workflow or apply some > workaround (check locale settings and such). Again your References > header contains illegal symbol: > > References: <201611210615.PPE1zXiO??ngguang...@intel.com> I finally found out where the issue came from: Evolution somehow reinterprets the Message-Id when you are copying it to the clipboard.
Re: [PATCH v5 2/2] console: Add persistent scrollback buffers for all VGA consoles
On Mo, 2016-11-21 at 21:17 +0100, Adam Borowski wrote: > On Sun, Nov 20, 2016 at 10:58:08PM +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 > > --- > But alas, this commit breaks that very \e[3J. It does only a \e[2J, leaving > the scrollback uncleared. For comparison, both mainline and with just your > preparatory commit, \e[3J works as expected. Thanks again for reporting this issue. I was finally able to reproduce it. Looks like the same problem arises when implementing persistent scrollback buffers for framebuffer consoles. I will have to think about the underlying issue a bit more, but I guess that the consw struct needs another field for a function that flushes the scrollback buffer. Before this was just done by switching the console, which is fine if you just have one buffer. But now each console has its own buffer, so simply calling vc_data's vc_sw->con_switch() won't be sufficient anymore.
[PATCH v8 3/3] console: Add persistent scrollback buffers for all VGA consoles
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 Reviewed-by: Andrey Utkin Tested-by: Andrey Utkin Tested-by: Adam Borowski --- 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(
[PATCH v8 2/3] console: Add callback to flush scrollback buffer to consw struct
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 Reviewed-by: Andrey Utkin Tested-by: Andrey Utkin Tested-by: Adam Borowski --- 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
[PATCH v8 1/3] console: Move scrollback data into its own struct
This refactoring is in preparation for persistent scrollback support for VGA console. Signed-off-by: Manuel Schölling Reviewed-by: Andrey Utkin Tested-by: Andrey Utkin Tested-by: Adam Borowski --- 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; + sta
[PATCH v8 0/3] console: Add persistent scrollback buffers for all VGA consoles
Reviewed-by: Andrey Utkin Tested-by: Andrey Utkin Tested-by: Adam Borowski -- 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 (kilob...@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
Re: [PATCH v10 3/4] console: Add persistent scrollback buffers for all VGA consoles
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 > > Reviewed-by: Andrey Utkin > > Tested-by: Andrey Utkin > > Tested-by: Adam Borowski > > --- > > 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
Re: [PATCH v9 4/4] console: Make persistent scrollback a boot parameter
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 > > Suggested-by: Bartlomiej Zolnierkiewicz > > +module_param_named(scrollback_persistent, scrollback_persistent, > > bool, ); > > +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
[PATCH v10 2/4] console: Add callback to flush scrollback buffer to consw struct
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 Reviewed-by: Andrey Utkin Tested-by: Andrey Utkin Tested-by: Adam Borowski --- 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
[PATCH v10 1/4] console: Move scrollback data into its own struct
This refactoring is in preparation for persistent scrollback support for VGA console. Signed-off-by: Manuel Schölling Reviewed-by: Andrey Utkin Tested-by: Andrey Utkin Tested-by: Adam Borowski --- 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; + sta
[PATCH v10 4/4] console: Make persistent scrollback a boot parameter
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 Suggested-by: Bartlomiej Zolnierkiewicz --- 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, ); +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
[PATCH v10 3/4] console: Add persistent scrollback buffers for all VGA consoles
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 Reviewed-by: Andrey Utkin Tested-by: Andrey Utkin Tested-by: Adam Borowski --- 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(
[PATCH v10 0/4] console: Add persistent scrollback buffers for all VGA consoles
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 (kilob...@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
Re: [PATCH v8 3/3] console: Add persistent scrollback buffers for all VGA consoles
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 > > > Reviewed-by: Andrey Utkin > > > Tested-by: Andrey Utkin > > > Tested-by: Adam Borowski > > > --- > > > 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 > > &g
[PATCH v4] console: Add persistent scrollback buffers for all VGA console
--- 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)
[PATCH v4 1/2] console: Move scrollback data into its own struct
This refactoring is in preparation for persistent scrollback support for VGA console. Signed-off-by: Manuel Schölling --- drivers/video/console/vgacon.c | 82 +- 1 file changed, 42 insertions(+), 40 deletions(-) diff --git a/drivers/video/console/vgacon.c b/drivers/video/console/vgacon.c index c22a562..d3f823a 100644 --- a/drivers/video/console/vgacon.c +++ b/drivers/video/console/vgacon.c @@ -162,31 +162,33 @@ 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 +196,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,17 +241,17 @@ 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) @@ -2
[PATCH v4 2/2] console: Add persistent scrollback buffers for all VGA consoles
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 --- drivers/video/console/Kconfig | 23 ++- drivers/video/console/vgacon.c | 134 + 2 files changed, 114 insertions(+), 43 deletions(-) diff --git a/drivers/video/console/Kconfig b/drivers/video/console/Kconfig index 38da6e2..8167540 100644 --- a/drivers/video/console/Kconfig +++ b/drivers/video/console/Kconfig @@ -43,9 +43,26 @@ 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 breaks legacy versions of tools like clear_console which + might cause security issues. + 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 d3f823a..90ec0c5 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,63 +171,116 @@ 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) +{ + if (vgacon_scrollback_cur->data && reset_size > 0) + memset(vgacon_scrollback_cur->data, 0, reset_size); + + vgacon_scrollback_cur->cnt = 0; + vgacon_scrollback_cur->tail = 0; + vgacon_scrollback_cur->cur = 0; +} + +static void vgacon_scrollback_init(int vc_num) +{ + int pitch = vga_video_num_columns * 2; + size_t size = CONFIG_VGACON_SOFT_SCROLLBACK_SIZE * 1024; + int rows = size/pitch; + void *data; + + data = kcalloc(CONFIG_VGACON_SOFT_SCROLLBACK_SIZE, 1024, GFP_NOWAIT); + if (data) { + 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; -static void vgacon_scrollback_init(int pitch) + vgacon_scrollback_reset(0); + } else { + pr_warn("VGAcon: failed to allocate memory for scrollback. Trying to reuse previous buffer.\n"); + /* Leave vgacon_scrollback_cur untouched but reset its content */ + vgacon_scrollback_reset(size); + } +} + +static void vgacon_switch_scrollback(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; +#ifdef CONFIG_VGACON_SOFT_SCROLLBACK_PERSISTENT + if (!vgacon_scrollbacks[vc_num].data) + vgacon_scrollback_init(vc_num); + else + vgacon_scrollback_cur = &vgacon_scrollbacks[vc_num]; +#else + vc_num = 0; + +
Re: [PATCH v3] console: Add persistent scrollback buffers for all VGA consoles
Hi, I finally found the time to rework the patches, but there are a few things I want to discuss: > > 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. > > Have never heard of such tool as clear_console. Why mention it at all, > where is it used, which are practical configurations which are broken in > this way? clear_console(1) is part of Debian's bash package and (I think) a inofficial 'downstream' patch developed by Ubuntu [1]. There has been security concerns (which is also why I disabled this feature by default). However, if there might be security issues, I would strongly suggest to keep this part in the documentation - it does no harm anyway, does it? > Does this break clear(1)? No, my tests with clear(1) worked fine. > > - 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. > > Indentation amended, I don't know which way it should be, please > double-check or mimic old indentation to stay on safe side. Double-checked! That's at least how I read the docs. > > +static struct vgacon_scrollback_info *vgacon_scrollback_cur; > > Could you use name vgacon_scrollback instead of new > vgacon_scrollback_cur? It doesn't change anything conceptually, but is a > bit shorter and seems to mean current scrollback context anyway, right? > > I think I see nothing to comment on below. There is a already an array called 'vgacon_scrollbacks[N]', so I would not like to have two variables named 'vgacon_scrollback' and 'vgacon_scrollbacks'. Either {'vgacon_scrollback_cur' and 'vgacon_scrollbacks'} or {'vgacon_scrollback' and 'vgacon_scrollback_list'}. You can make a suggestion, if you like. All other point you mentioned where fixed as you suggested. Thanks again for your help, Andrey! Best, Manuel [1] http://manpages.ubuntu.com/manpages/xenial/en/man1/clear_console.1.html
[PATCH v4.1 0/2] console: Add persistent scrollback buffers for all VGA console
Well, that's embarrassing: I changed the order of some local commits in the last minute, so my patches included a compiler error. 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 (2): console: Move scrollback data into its own struct console: Add persistent scrollback buffers for all VGA consoles drivers/video/console/Kconfig | 23 +- drivers/video/console/vgacon.c | 158 - 2 files changed, 127 insertions(+), 54 deletions(-) -- 2.1.4
[PATCH v4.1 2/2] console: Add persistent scrollback buffers for all VGA consoles
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 --- drivers/video/console/Kconfig | 23 ++- drivers/video/console/vgacon.c | 134 + 2 files changed, 114 insertions(+), 43 deletions(-) diff --git a/drivers/video/console/Kconfig b/drivers/video/console/Kconfig index 38da6e2..8167540 100644 --- a/drivers/video/console/Kconfig +++ b/drivers/video/console/Kconfig @@ -43,9 +43,26 @@ 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 breaks legacy versions of tools like clear_console which + might cause security issues. + 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 1fee18f..8314f69 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,63 +171,116 @@ 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) +{ + if (vgacon_scrollback_cur->data && reset_size > 0) + memset(vgacon_scrollback_cur->data, 0, reset_size); + + vgacon_scrollback_cur->cnt = 0; + vgacon_scrollback_cur->tail = 0; + vgacon_scrollback_cur->cur = 0; +} + +static void vgacon_scrollback_init(int vc_num) +{ + int pitch = vga_video_num_columns * 2; + size_t size = CONFIG_VGACON_SOFT_SCROLLBACK_SIZE * 1024; + int rows = size/pitch; + void *data; + + data = kcalloc(CONFIG_VGACON_SOFT_SCROLLBACK_SIZE, 1024, GFP_NOWAIT); + if (data) { + 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; -static void vgacon_scrollback_init(int pitch) + vgacon_scrollback_reset(0); + } else { + pr_warn("VGAcon: failed to allocate memory for scrollback. Trying to reuse previous buffer.\n"); + /* Leave vgacon_scrollback_cur untouched but reset its content */ + vgacon_scrollback_reset(size); + } +} + +static void vgacon_switch_scrollback(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; +#ifdef CONFIG_VGACON_SOFT_SCROLLBACK_PERSISTENT + if (!vgacon_scrollbacks[vc_num].data) + vgacon_scrollback_init(vc_num); + else + vgacon_scrollback_cur = &vgacon_scrollbacks[vc_num]; +#else + vc_num = 0; + +
[PATCH v4.1 1/2] console: Move scrollback data into its own struct
This refactoring is in preparation for persistent scrollback support for VGA console. Signed-off-by: Manuel Schölling --- drivers/video/console/vgacon.c | 90 +- 1 file changed, 46 insertions(+), 44 deletions(-) diff --git a/drivers/video/console/vgacon.c b/drivers/video/console/vgacon.c index c22a562..1fee18f 100644 --- a/drivers/video/console/vgacon.c +++ b/drivers/video/console/vgacon.c @@ -162,31 +162,33 @@ 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 +196,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 +241,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)
[PATCH v7 3/3] console: Add persistent scrollback buffers for all VGA consoles
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 --- 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 + +
[PATCH v7 0/3] console: Add persistent scrollback buffers for all VGA consoles
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 (kilob...@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
[PATCH v7 1/3] console: Move scrollback data into its own struct
This refactoring is in preparation for persistent scrollback support for VGA console. Signed-off-by: Manuel Schölling --- 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);
[PATCH v7 2/3] console: Add callback to flush scrollback buffer to consw struct
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 --- 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
Re: [PATCH v7 0/3] console: Add persistent scrollback buffers for all VGA consoles
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 Thanks, Adam, for spending all this time testing the patches!
Re: [PATCH v7 0/3] console: Add persistent scrollback buffers for all VGA consoles
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 +, 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
[PATCH RESEND v7 3/3] console: Add persistent scrollback buffers for all VGA consoles
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 Reviewed-by: Andrey Utkin Tested-by: Andrey Utkin Tested-by: Adam Borowski --- 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) +
[PATCH RESEND v7 1/3] console: Move scrollback data into its own struct
This refactoring is in preparation for persistent scrollback support for VGA console. Signed-off-by: Manuel Schölling Reviewed-by: Andrey Utkin Tested-by: Andrey Utkin Tested-by: Adam Borowski --- 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; + sta
[PATCH RESEND v7 0/3] console: Add persistent scrollback buffers for all VGA consoles
Reviewed-by: Andrey Utkin Tested-by: Andrey Utkin Tested-by: Adam Borowski -- 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 (kilob...@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
[PATCH RESEND v7 2/3] console: Add callback to flush scrollback buffer to consw struct
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 Reviewed-by: Andrey Utkin Tested-by: Andrey Utkin Tested-by: Adam Borowski --- 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
[PATCH RESEND v7 0/3] console: Add persistent scrollback buffers for all VGA consoles
Reviewed-by: Andrey Utkin Tested-by: Andrey Utkin Tested-by: Adam Borowski -- 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 (kilob...@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
[PATCH RESEND v7 3/3] console: Add persistent scrollback buffers for all VGA consoles
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 Reviewed-by: Andrey Utkin Tested-by: Andrey Utkin Tested-by: Adam Borowski --- 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) +
[PATCH RESEND v7 1/3] console: Move scrollback data into its own struct
This refactoring is in preparation for persistent scrollback support for VGA console. Signed-off-by: Manuel Schölling Reviewed-by: Andrey Utkin Tested-by: Andrey Utkin Tested-by: Adam Borowski --- 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; + sta
[PATCH RESEND v7 2/3] console: Add callback to flush scrollback buffer to consw struct
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 Reviewed-by: Andrey Utkin Tested-by: Andrey Utkin Tested-by: Adam Borowski --- 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