tty: flush linux local echo buffer

Linux has a buffer just for local echoes. It seems to have been a
design decision that characters are discarded from this buffer if it
overflows. This results in dropped characters for large echoes of
inputted characters. This commit does not address that issue as it
only causes issues pasting large amounts of text.

The local echo buffer also has an issue if the tty driver buffer is
full, in our case okl4-pipes buffer is only 32 bytes, and no
characters are received it is not flushed. This results in an
infinite delay of the echoed characters if no further characters are
received. If further characters are received then they are outputted
in chunks of the length of your tty driver buffer, in okl4_pipes
case 32 bytes, as you continue to type.

This commit continues to flush the echo buffer until empty with
small delays between attempts after buffer full.

Change-Id: Iaad7e52fdb025a7a6c3707b95321e79af6867bdd
Signed-off-by: Carl van Schaik <carl@cog.systems>
Git-commit: 90ec5ea60ba36b7f8eeea7696a92ce22e78f1f3a
Git-repo: https://github.com/CogSystems/linux-msm/commits/msm-4.9-hyp
[mnalajal@codeaurora: Resolve trivial merge conflicts in n_tty.c]
Signed-off-by: Murali Nalajala <mnalajal@codeaurora.org>
This commit is contained in:
Carl van Schaik 2018-07-03 12:02:30 +10:00 committed by Murali Nalajala
parent b87efc45e4
commit e808330dff
3 changed files with 36 additions and 1 deletions

View File

@ -41,6 +41,9 @@ config VT
If unsure, say Y, or else you won't be able to do much with your new
shiny Linux system :-)
config TTY_FLUSH_LOCAL_ECHO
bool
config CONSOLE_TRANSLATIONS
depends on VT
default y

View File

@ -128,6 +128,10 @@ struct n_tty_data {
#define MASK(x) ((x) & (N_TTY_BUF_SIZE - 1))
#if defined(CONFIG_TTY_FLUSH_LOCAL_ECHO)
static void continue_process_echoes(struct work_struct *work);
#endif
static inline size_t read_cnt(struct n_tty_data *ldata)
{
return ldata->read_head - ldata->read_tail;
@ -751,7 +755,17 @@ static size_t __process_echoes(struct tty_struct *tty)
tail++;
}
not_yet_stored:
#if defined(CONFIG_TTY_FLUSH_LOCAL_ECHO)
if (ldata->echo_commit != tail) {
if (!tty->delayed_work) {
INIT_DELAYED_WORK(&tty->echo_delayed_work, continue_process_echoes);
schedule_delayed_work(&tty->echo_delayed_work, 1);
}
tty->delayed_work = 1;
}
#endif
not_yet_stored:
ldata->echo_tail = tail;
return old_space - space;
}
@ -817,6 +831,20 @@ static void flush_echoes(struct tty_struct *tty)
mutex_unlock(&ldata->output_lock);
}
#if defined(CONFIG_TTY_FLUSH_LOCAL_ECHO)
static void continue_process_echoes(struct work_struct *work)
{
struct tty_struct *tty =
container_of(work, struct tty_struct, echo_delayed_work.work);
struct n_tty_data *ldata = tty->disc_data;
mutex_lock(&ldata->output_lock);
tty->delayed_work = 0;
__process_echoes(tty);
mutex_unlock(&ldata->output_lock);
}
#endif
/**
* add_echo_byte - add a byte to the echo buffer
* @c: unicode byte to echo

View File

@ -322,6 +322,10 @@ struct tty_struct {
wait_queue_head_t write_wait;
wait_queue_head_t read_wait;
struct work_struct hangup_work;
#if defined(CONFIG_TTY_FLUSH_LOCAL_ECHO)
int delayed_work;
struct delayed_work echo_delayed_work;
#endif
void *disc_data;
void *driver_data;
spinlock_t files_lock; /* protects tty_files list */