diff options
author | Heinz Graalfs <graalfs@linux.vnet.ibm.com> | 2013-10-29 09:40:39 +1030 |
---|---|---|
committer | Rusty Russell <rusty@rustcorp.com.au> | 2013-10-29 11:28:18 +1030 |
commit | 40e4dc530118dbb79e270d5554ac8415588378d2 (patch) | |
tree | 06582a56e89dc9cb3654de1bdcb9afa6adb5ce94 /drivers/char | |
parent | 7f03b17d5c3f3b63dcacf0e481cf94c9d07267ab (diff) |
virtio_console: verify if queue is broken after virtqueue_get_buf()
If virtqueue_get_buf() returns with a NULL pointer it should be verified
if the virtqueue is broken, in order to avoid loop calling cpu_relax().
Signed-off-by: Heinz Graalfs <graalfs@linux.vnet.ibm.com>
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Diffstat (limited to 'drivers/char')
-rw-r--r-- | drivers/char/virtio_console.c | 6 |
1 files changed, 4 insertions, 2 deletions
diff --git a/drivers/char/virtio_console.c b/drivers/char/virtio_console.c index 2a8d9a7a1834..feea87cc6b8f 100644 --- a/drivers/char/virtio_console.c +++ b/drivers/char/virtio_console.c @@ -577,7 +577,8 @@ static ssize_t __send_control_msg(struct ports_device *portdev, u32 port_id, spin_lock(&portdev->c_ovq_lock); if (virtqueue_add_outbuf(vq, sg, 1, &cpkt, GFP_ATOMIC) == 0) { virtqueue_kick(vq); - while (!virtqueue_get_buf(vq, &len)) + while (!virtqueue_get_buf(vq, &len) + && !virtqueue_is_broken(vq)) cpu_relax(); } spin_unlock(&portdev->c_ovq_lock); @@ -650,7 +651,8 @@ static ssize_t __send_to_port(struct port *port, struct scatterlist *sg, * we need to kmalloc a GFP_ATOMIC buffer each time the * console driver writes something out. */ - while (!virtqueue_get_buf(out_vq, &len)) + while (!virtqueue_get_buf(out_vq, &len) + && !virtqueue_is_broken(out_vq)) cpu_relax(); done: spin_unlock_irqrestore(&port->outvq_lock, flags); |