virtualization.lists.linux-foundation.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] virtio: console: Unlock vqs while freeing buffers
@ 2016-10-11 11:05 Matt Redfearn
  0 siblings, 0 replies; 3+ messages in thread
From: Matt Redfearn @ 2016-10-11 11:05 UTC (permalink / raw)
  To: Amit Shah
  Cc: Arnd Bergmann, Greg Kroah-Hartman, linux-kernel, stable,
	virtualization, Matt Redfearn

Commit c6017e793b93 ("virtio: console: add locks around buffer removal
in port unplug path") added locking around the freeing of buffers in the
vq. However, when free_buf() is called with can_sleep = true and rproc
is enabled, it calls dma_free_coherent() directly, requiring interrupts
to be enabled. Currently a WARNING is triggered due to the spin locking
around free_buf, with a call stack like this:

WARNING: CPU: 3 PID: 121 at ./include/linux/dma-mapping.h:433
free_buf+0x1a8/0x288
Call Trace:
[<8040c538>] show_stack+0x74/0xc0
[<80757240>] dump_stack+0xd0/0x110
[<80430d98>] __warn+0xfc/0x130
[<80430ee0>] warn_slowpath_null+0x2c/0x3c
[<807e7c6c>] free_buf+0x1a8/0x288
[<807ea590>] remove_port_data+0x50/0xac
[<807ea6a0>] unplug_port+0xb4/0x1bc
[<807ea858>] virtcons_remove+0xb0/0xfc
[<807b6734>] virtio_dev_remove+0x58/0xc0
[<807f918c>] __device_release_driver+0xac/0x134
[<807f924c>] device_release_driver+0x38/0x50
[<807f7edc>] bus_remove_device+0xfc/0x130
[<807f4b74>] device_del+0x17c/0x21c
[<807f4c38>] device_unregister+0x24/0x38
[<807b6b50>] unregister_virtio_device+0x28/0x44

Fix this by restructuring the loops to allow the locks to only be taken
where it is necessary to protect the vqs, and release it while the
buffer is being freed.

Fixes: c6017e793b93 ("virtio: console: add locks around buffer removal in port unplug path")
Cc: stable@vger.kernel.org
Signed-off-by: Matt Redfearn <matt.redfearn@imgtec.com>
---

 drivers/char/virtio_console.c | 22 ++++++++++++++++------
 1 file changed, 16 insertions(+), 6 deletions(-)

diff --git a/drivers/char/virtio_console.c b/drivers/char/virtio_console.c
index 5da47e26a012..4aae0d27e382 100644
--- a/drivers/char/virtio_console.c
+++ b/drivers/char/virtio_console.c
@@ -1540,19 +1540,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);
 }
 
 /*
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 3+ messages in thread

* Re: [PATCH] virtio: console: Unlock vqs while freeing buffers
       [not found] <1476183915-13625-1-git-send-email-matt.redfearn@imgtec.com>
@ 2016-10-25  7:18 ` Amit Shah
       [not found] ` <20161025071803.GG2138@amit-lp.rh>
  1 sibling, 0 replies; 3+ messages in thread
From: Amit Shah @ 2016-10-25  7:18 UTC (permalink / raw)
  To: Matt Redfearn
  Cc: Arnd Bergmann, Michael S. Tsirkin, Greg Kroah-Hartman,
	linux-kernel, stable, virtualization

On (Tue) 11 Oct 2016 [12:05:15], Matt Redfearn wrote:
> Commit c6017e793b93 ("virtio: console: add locks around buffer removal
> in port unplug path") added locking around the freeing of buffers in the
> vq. However, when free_buf() is called with can_sleep = true and rproc
> is enabled, it calls dma_free_coherent() directly, requiring interrupts
> to be enabled. Currently a WARNING is triggered due to the spin locking
> around free_buf, with a call stack like this:
> 
> WARNING: CPU: 3 PID: 121 at ./include/linux/dma-mapping.h:433
> free_buf+0x1a8/0x288
> Call Trace:
> [<8040c538>] show_stack+0x74/0xc0
> [<80757240>] dump_stack+0xd0/0x110
> [<80430d98>] __warn+0xfc/0x130
> [<80430ee0>] warn_slowpath_null+0x2c/0x3c
> [<807e7c6c>] free_buf+0x1a8/0x288
> [<807ea590>] remove_port_data+0x50/0xac
> [<807ea6a0>] unplug_port+0xb4/0x1bc
> [<807ea858>] virtcons_remove+0xb0/0xfc
> [<807b6734>] virtio_dev_remove+0x58/0xc0
> [<807f918c>] __device_release_driver+0xac/0x134
> [<807f924c>] device_release_driver+0x38/0x50
> [<807f7edc>] bus_remove_device+0xfc/0x130
> [<807f4b74>] device_del+0x17c/0x21c
> [<807f4c38>] device_unregister+0x24/0x38
> [<807b6b50>] unregister_virtio_device+0x28/0x44
> 
> Fix this by restructuring the loops to allow the locks to only be taken
> where it is necessary to protect the vqs, and release it while the
> buffer is being freed.
> 
> Fixes: c6017e793b93 ("virtio: console: add locks around buffer removal in port unplug path")
> Cc: stable@vger.kernel.org
> Signed-off-by: Matt Redfearn <matt.redfearn@imgtec.com>

Reviewed-by: Amit Shah <amit.shah@redhat.com>

Michael, can you pick this up?

Thanks,

		Amit

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH] virtio: console: Unlock vqs while freeing buffers
       [not found] ` <20161025071803.GG2138@amit-lp.rh>
@ 2016-10-25 13:19   ` Michael S. Tsirkin
  0 siblings, 0 replies; 3+ messages in thread
From: Michael S. Tsirkin @ 2016-10-25 13:19 UTC (permalink / raw)
  To: Amit Shah
  Cc: Arnd Bergmann, Greg Kroah-Hartman, linux-kernel, stable,
	virtualization, Matt Redfearn

On Tue, Oct 25, 2016 at 12:48:03PM +0530, Amit Shah wrote:
> On (Tue) 11 Oct 2016 [12:05:15], Matt Redfearn wrote:
> > Commit c6017e793b93 ("virtio: console: add locks around buffer removal
> > in port unplug path") added locking around the freeing of buffers in the
> > vq. However, when free_buf() is called with can_sleep = true and rproc
> > is enabled, it calls dma_free_coherent() directly, requiring interrupts
> > to be enabled. Currently a WARNING is triggered due to the spin locking
> > around free_buf, with a call stack like this:
> > 
> > WARNING: CPU: 3 PID: 121 at ./include/linux/dma-mapping.h:433
> > free_buf+0x1a8/0x288
> > Call Trace:
> > [<8040c538>] show_stack+0x74/0xc0
> > [<80757240>] dump_stack+0xd0/0x110
> > [<80430d98>] __warn+0xfc/0x130
> > [<80430ee0>] warn_slowpath_null+0x2c/0x3c
> > [<807e7c6c>] free_buf+0x1a8/0x288
> > [<807ea590>] remove_port_data+0x50/0xac
> > [<807ea6a0>] unplug_port+0xb4/0x1bc
> > [<807ea858>] virtcons_remove+0xb0/0xfc
> > [<807b6734>] virtio_dev_remove+0x58/0xc0
> > [<807f918c>] __device_release_driver+0xac/0x134
> > [<807f924c>] device_release_driver+0x38/0x50
> > [<807f7edc>] bus_remove_device+0xfc/0x130
> > [<807f4b74>] device_del+0x17c/0x21c
> > [<807f4c38>] device_unregister+0x24/0x38
> > [<807b6b50>] unregister_virtio_device+0x28/0x44
> > 
> > Fix this by restructuring the loops to allow the locks to only be taken
> > where it is necessary to protect the vqs, and release it while the
> > buffer is being freed.
> > 
> > Fixes: c6017e793b93 ("virtio: console: add locks around buffer removal in port unplug path")
> > Cc: stable@vger.kernel.org
> > Signed-off-by: Matt Redfearn <matt.redfearn@imgtec.com>
> 
> Reviewed-by: Amit Shah <amit.shah@redhat.com>
> 
> Michael, can you pick this up?
> 
> Thanks,
> 
> 		Amit

Sure.

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2016-10-25 13:19 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
     [not found] <1476183915-13625-1-git-send-email-matt.redfearn@imgtec.com>
2016-10-25  7:18 ` [PATCH] virtio: console: Unlock vqs while freeing buffers Amit Shah
     [not found] ` <20161025071803.GG2138@amit-lp.rh>
2016-10-25 13:19   ` Michael S. Tsirkin
2016-10-11 11:05 Matt Redfearn

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).