diff options
author | Keir Fraser <keir.fraser@citrix.com> | 2007-12-08 15:46:04 +0000 |
---|---|---|
committer | Keir Fraser <keir.fraser@citrix.com> | 2007-12-08 15:46:04 +0000 |
commit | 0d6aee7d684194be380fe1646f971dd87c432501 (patch) | |
tree | e1d89efd224f8bf2d9471ae7f84ef15766bea42e | |
parent | e028ead54447be95f5de9680a85f38fef3d70d79 (diff) | |
download | xen-0d6aee7d684194be380fe1646f971dd87c432501.tar.gz xen-0d6aee7d684194be380fe1646f971dd87c432501.tar.bz2 xen-0d6aee7d684194be380fe1646f971dd87c432501.zip |
qemu 16550 uart: Fast-drop bursts of transmitted characters to avoid
stalling due to a disconnected pipe or pty.
Signed-off-by: Trolle Selander <trolle.selander@gmail.com>
-rw-r--r-- | tools/ioemu/hw/serial.c | 18 |
1 files changed, 12 insertions, 6 deletions
diff --git a/tools/ioemu/hw/serial.c b/tools/ioemu/hw/serial.c index 952f5b955c..af6aa64ee3 100644 --- a/tools/ioemu/hw/serial.c +++ b/tools/ioemu/hw/serial.c @@ -359,7 +359,7 @@ static void serial_xmit(void *opaque) { SerialState *s = opaque; uint64_t new_xmit_ts = qemu_get_clock(vm_clock); - if ( s->tsr_retry == 0 ) { + if ( s->tsr_retry <= 0 ) { if (s->fcr & UART_FCR_FE) { s->tsr = fifo_get(s,XMIT_FIFO); if ( !s->xmit_fifo.count ) @@ -371,16 +371,22 @@ static void serial_xmit(void *opaque) { } if ( qemu_chr_write(s->chr, &s->tsr, 1) != 1 ) { - s->tsr_retry++; - if ( s->tsr_retry <= MAX_XMIT_RETRY ) { + if ( ( s->tsr_retry > 0 ) && ( s->tsr_retry <= MAX_XMIT_RETRY ) ) { + s->tsr_retry++; qemu_mod_timer(s->transmit_timer, new_xmit_ts + s->char_transmit_time ); return; + } else if ( s->poll_msl < 0 ) { + /* If we exceed MAX_XMIT_RETRY and the backend is not a real serial port, then + drop any further failed writes instantly, until we get one that goes through. + This is to prevent guests that log to unconnected pipes or pty's from stalling. */ + s->tsr_retry = -1; } } - - s->tsr_retry = 0; - s->last_xmit_ts = qemu_get_clock(vm_clock); + else { + s->tsr_retry = 0; + } + s->last_xmit_ts = qemu_get_clock(vm_clock); if ( !(s->lsr & UART_LSR_THRE) ) qemu_mod_timer(s->transmit_timer, s->last_xmit_ts + s->char_transmit_time ); |