On Thu, 2017-03-30 at 05:10 +0200, Mike Galbraith wrote:

> WRT spin, you should need do nothing more than boot with threadirqs,
> that's 100% repeatable here in absolutely virgin source.

No idea why virtqueue_get_buf() in __send_control_msg() fails forever
with threadirqs, but marking that vq as being busted (it clearly is)
results in one gripe, and a vbox that seemingly cares not one whit that
something went missing.  CONFIG_DEBUG_SHIRQ OTOH notices, mutters
something that sounds like "idiot" when I hibernate the thing ;-)

diff --git a/drivers/char/virtio_console.c b/drivers/char/virtio_console.c
index e9b7e0b3cabe..831406dae1cb 100644
--- a/drivers/char/virtio_console.c
+++ b/drivers/char/virtio_console.c
@@ -567,6 +567,7 @@ static ssize_t __send_control_msg(struct ports_device 
*portdev, u32 port_id,
        struct scatterlist sg[1];
        struct virtqueue *vq;
        unsigned int len;
+       unsigned long deadline = jiffies+1;
 
        if (!use_multiport(portdev))
                return 0;
@@ -583,9 +584,13 @@ static ssize_t __send_control_msg(struct ports_device 
*portdev, u32 port_id,
 
        if (virtqueue_add_outbuf(vq, sg, 1, &portdev->cpkt, GFP_ATOMIC) == 0) {
                virtqueue_kick(vq);
-               while (!virtqueue_get_buf(vq, &len)
-                       && !virtqueue_is_broken(vq))
+               while (!virtqueue_get_buf(vq, &len) && 
!virtqueue_is_broken(vq)) {
                        cpu_relax();
+                       if (time_after(jiffies, deadline)) {
+                               trace_printk("Aw crap, I'm stuck.. breaking 
device\n");
+                               virtio_break_device(portdev->vdev);
+                       }
+               }
        }
 
        spin_unlock(&portdev->c_ovq_lock);

Reply via email to