aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/char/virtio_console.c17
1 files changed, 14 insertions, 3 deletions
diff --git a/drivers/char/virtio_console.c b/drivers/char/virtio_console.c
index c810481a5bc2..0f69c5ec0ecd 100644
--- a/drivers/char/virtio_console.c
+++ b/drivers/char/virtio_console.c
@@ -459,9 +459,12 @@ static ssize_t send_buf(struct port *port, void *in_buf, size_t in_count,
459 459
460 /* 460 /*
461 * Wait till the host acknowledges it pushed out the data we 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 462 * sent. This is done for data from the hvc_console; the tty
463 * from the hvc_console; the tty operations are performed with 463 * operations are performed with spinlocks held so we can't
464 * spinlocks held so we can't sleep here. 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 while (!virtqueue_get_buf(out_vq, &len)) 469 while (!virtqueue_get_buf(out_vq, &len))
467 cpu_relax(); 470 cpu_relax();
@@ -626,6 +629,14 @@ static ssize_t port_fops_write(struct file *filp, const char __user *ubuf,
626 goto free_buf; 629 goto free_buf;
627 } 630 }
628 631
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;
629 ret = send_buf(port, buf, count, nonblock); 640 ret = send_buf(port, buf, count, nonblock);
630 641
631 if (nonblock && ret > 0) 642 if (nonblock && ret > 0)