virtio: console: Unlock vqs while freeing buffers
[cascardo/linux.git] / drivers / char / virtio_console.c
index d433b1d..5649234 100644 (file)
@@ -1539,19 +1539,29 @@ static void remove_port_data(struct port *port)
        spin_lock_irq(&port->inbuf_lock);
        /* Remove unused data this port might have received. */
        discard_port_data(port);
+       spin_unlock_irq(&port->inbuf_lock);
 
        /* Remove buffers we queued up for the Host to send us data in. */
-       while ((buf = virtqueue_detach_unused_buf(port->in_vq)))
-               free_buf(buf, true);
-       spin_unlock_irq(&port->inbuf_lock);
+       do {
+               spin_lock_irq(&port->inbuf_lock);
+               buf = virtqueue_detach_unused_buf(port->in_vq);
+               spin_unlock_irq(&port->inbuf_lock);
+               if (buf)
+                       free_buf(buf, true);
+       } while (buf);
 
        spin_lock_irq(&port->outvq_lock);
        reclaim_consumed_buffers(port);
+       spin_unlock_irq(&port->outvq_lock);
 
        /* Free pending buffers from the out-queue. */
-       while ((buf = virtqueue_detach_unused_buf(port->out_vq)))
-               free_buf(buf, true);
-       spin_unlock_irq(&port->outvq_lock);
+       do {
+               spin_lock_irq(&port->outvq_lock);
+               buf = virtqueue_detach_unused_buf(port->out_vq);
+               spin_unlock_irq(&port->outvq_lock);
+               if (buf)
+                       free_buf(buf, true);
+       } while (buf);
 }
 
 /*