diff mbox

[RFC] dataplane: Fix startup race.

Message ID 1378296975-17661-1-git-send-email-cornelia.huck@de.ibm.com
State New
Headers show

Commit Message

Cornelia Huck Sept. 4, 2013, 12:16 p.m. UTC
Avoid trying to setup dataplane again if dataplane setup is already in
progress. This may happen if an eventfd is triggered during setup.

I saw this occasionally with an experimental s390 irqfd implementation:

virtio_blk_handle_output
-> virtio_blk_data_plane_start
-> virtio_ccw_set_host_notifier
...
-> virtio_queue_set_host_notifier_fd_handler
-> virtio_queue_host_notifier_read
-> virtio_queue_notify_vq
-> virtio_blk_handle_output
-> virtio_blk_data_plane_start
-> vring_setup
-> hostmem_init
-> memory_listener_register
-> BOOM

As virtio-ccw tries to follow what virtio-pci does, it might be triggerable
for other platforms as well.

Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
---
 hw/block/dataplane/virtio-blk.c | 9 +++++++++
 1 file changed, 9 insertions(+)

Comments

Stefan Hajnoczi Sept. 5, 2013, 1:58 p.m. UTC | #1
On Wed, Sep 04, 2013 at 02:16:15PM +0200, Cornelia Huck wrote:
> Avoid trying to setup dataplane again if dataplane setup is already in
> progress. This may happen if an eventfd is triggered during setup.
> 
> I saw this occasionally with an experimental s390 irqfd implementation:
> 
> virtio_blk_handle_output
> -> virtio_blk_data_plane_start
> -> virtio_ccw_set_host_notifier
> ...
> -> virtio_queue_set_host_notifier_fd_handler
> -> virtio_queue_host_notifier_read
> -> virtio_queue_notify_vq
> -> virtio_blk_handle_output
> -> virtio_blk_data_plane_start
> -> vring_setup
> -> hostmem_init
> -> memory_listener_register
> -> BOOM
> 
> As virtio-ccw tries to follow what virtio-pci does, it might be triggerable
> for other platforms as well.
> 
> Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
> ---
>  hw/block/dataplane/virtio-blk.c | 9 +++++++++
>  1 file changed, 9 insertions(+)

Thanks, applied to my block tree:
https://github.com/stefanha/qemu/commits/block

Stefan
diff mbox

Patch

diff --git a/hw/block/dataplane/virtio-blk.c b/hw/block/dataplane/virtio-blk.c
index 5a96ccd..f2d7350 100644
--- a/hw/block/dataplane/virtio-blk.c
+++ b/hw/block/dataplane/virtio-blk.c
@@ -42,6 +42,7 @@  typedef struct {
 
 struct VirtIOBlockDataPlane {
     bool started;
+    bool starting;
     bool stopping;
     QEMUBH *start_bh;
     QemuThread thread;
@@ -451,8 +452,15 @@  void virtio_blk_data_plane_start(VirtIOBlockDataPlane *s)
         return;
     }
 
+    if (s->starting) {
+        return;
+    }
+
+    s->starting = true;
+
     vq = virtio_get_queue(s->vdev, 0);
     if (!vring_setup(&s->vring, s->vdev, 0)) {
+        s->starting = false;
         return;
     }
 
@@ -482,6 +490,7 @@  void virtio_blk_data_plane_start(VirtIOBlockDataPlane *s)
     s->io_notifier = *ioq_get_notifier(&s->ioqueue);
     aio_set_event_notifier(s->ctx, &s->io_notifier, handle_io);
 
+    s->starting = false;
     s->started = true;
     trace_virtio_blk_data_plane_start(s);