Skip to content

Commit 531295e

Browse files
amit3storvalds
authored andcommitted
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>
1 parent 30c2781 commit 531295e

File tree

1 file changed

+14
-3
lines changed

1 file changed

+14
-3
lines changed

drivers/char/virtio_console.c

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -459,9 +459,12 @@ static ssize_t send_buf(struct port *port, void *in_buf, size_t in_count,
459459

460460
/*
461461
* 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.
465468
*/
466469
while (!virtqueue_get_buf(out_vq, &len))
467470
cpu_relax();
@@ -626,6 +629,14 @@ static ssize_t port_fops_write(struct file *filp, const char __user *ubuf,
626629
goto free_buf;
627630
}
628631

632+
/*
633+
* We now ask send_buf() to not spin for generic ports -- we
634+
* can re-use the same code path that non-blocking file
635+
* descriptors take for blocking file descriptors since the
636+
* wait is already done and we're certain the write will go
637+
* through to the host.
638+
*/
639+
nonblock = true;
629640
ret = send_buf(port, buf, count, nonblock);
630641

631642
if (nonblock && ret > 0)

0 commit comments

Comments
 (0)