Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

virtio: console: Don't block entire guest if host doesn't read data

If the host is slow in reading data or doesn't read data at all,
blocking write calls not only blocked the program that called write()
but the entire guest itself.

To overcome this, let's not block till the host signals it has given
back the virtio ring element we passed it. Instead, send the buffer to
the host and return to userspace. This operation then becomes similar
to how non-blocking writes work, so let's use the existing code for this
path as well.

This code change also ensures blocking write calls do get blocked if
there's not enough room in the virtio ring as well as they don't return
-EAGAIN to userspace.

Signed-off-by: Amit Shah <amit.shah@redhat.com>
Acked-by: Hans de Goede <hdegoede@redhat.com>
CC: stable@kernel.org
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

authored by

Amit Shah and committed by
Linus Torvalds
531295e6 30c27819

+14 -3
+14 -3
drivers/char/virtio_console.c
··· 459 459 460 460 /* 461 461 * Wait till the host acknowledges it pushed out the data we 462 - * sent. This is done for ports in blocking mode or for data 463 - * from the hvc_console; the tty operations are performed with 464 - * spinlocks held so we can't sleep here. 462 + * sent. This is done for data from the hvc_console; the tty 463 + * operations are performed with spinlocks held so we can't 464 + * sleep here. An alternative would be to copy the data to a 465 + * buffer and relax the spinning requirement. The downside is 466 + * we need to kmalloc a GFP_ATOMIC buffer each time the 467 + * console driver writes something out. 465 468 */ 466 469 while (!virtqueue_get_buf(out_vq, &len)) 467 470 cpu_relax(); ··· 629 626 goto free_buf; 630 627 } 631 628 629 + /* 630 + * We now ask send_buf() to not spin for generic ports -- we 631 + * can re-use the same code path that non-blocking file 632 + * descriptors take for blocking file descriptors since the 633 + * wait is already done and we're certain the write will go 634 + * through to the host. 635 + */ 636 + nonblock = true; 632 637 ret = send_buf(port, buf, count, nonblock); 633 638 634 639 if (nonblock && ret > 0)