render / rpms / qemu

Forked from rpms/qemu 9 months ago
Clone

Blame 0022-qxl-async-io-support-using-new-spice-api.patch

Justin M. Forbes 13f703
>From b25a2a169340f70b29d47d0598df1ac525a87bf9 Mon Sep 17 00:00:00 2001
Justin M. Forbes 13f703
From: Alon Levy <alevy@redhat.com>
Justin M. Forbes 13f703
Date: Thu, 23 Jun 2011 20:02:18 +0200
Justin M. Forbes 13f703
Subject: [PATCH 22/25] qxl: async io support using new spice api
Justin M. Forbes 13f703
Justin M. Forbes 13f703
Some of the QXL port i/o commands are waiting for the spice server to
Justin M. Forbes 13f703
complete certain actions.  Add async versions for these commands, so we
Justin M. Forbes 13f703
don't block the vcpu while the spice server processses the command.
Justin M. Forbes 13f703
Instead the qxl device will raise an IRQ when done.
Justin M. Forbes 13f703
Justin M. Forbes 13f703
The async command processing relies on an added QXLInterface::async_complete
Justin M. Forbes 13f703
and added QXLWorker::*_async additions, in spice server qxl >= 3.1
Justin M. Forbes 13f703
Justin M. Forbes 13f703
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Justin M. Forbes 13f703
Signed-off-by: Alon Levy     <alevy@redhat.com>
Justin M. Forbes 13f703
---
Justin M. Forbes 13f703
 hw/qxl-render.c    |    2 +-
Justin M. Forbes 13f703
 hw/qxl.c           |  240 ++++++++++++++++++++++++++++++++++++++++++++--------
Justin M. Forbes 13f703
 hw/qxl.h           |   16 +++-
Justin M. Forbes 13f703
 ui/spice-display.c |   47 ++++++++--
Justin M. Forbes 13f703
 ui/spice-display.h |   23 +++++-
Justin M. Forbes 13f703
 5 files changed, 274 insertions(+), 54 deletions(-)
Justin M. Forbes 13f703
Justin M. Forbes 13f703
diff --git a/hw/qxl-render.c b/hw/qxl-render.c
Justin M. Forbes 13f703
index 60b822d..643ff2d 100644
Justin M. Forbes 13f703
--- a/hw/qxl-render.c
Justin M. Forbes 13f703
+++ b/hw/qxl-render.c
Justin M. Forbes 13f703
@@ -125,7 +125,7 @@ void qxl_render_update(PCIQXLDevice *qxl)
Justin M. Forbes 13f703
 
Justin M. Forbes 13f703
     memset(dirty, 0, sizeof(dirty));
Justin M. Forbes 13f703
     qxl_spice_update_area(qxl, 0, &update,
Justin M. Forbes 13f703
-                          dirty, ARRAY_SIZE(dirty), 1);
Justin M. Forbes 13f703
+                          dirty, ARRAY_SIZE(dirty), 1, QXL_SYNC);
Justin M. Forbes 13f703
 
Justin M. Forbes 13f703
     for (i = 0; i < ARRAY_SIZE(dirty); i++) {
Justin M. Forbes 13f703
         if (qemu_spice_rect_is_empty(dirty+i)) {
Justin M. Forbes 13f703
diff --git a/hw/qxl.c b/hw/qxl.c
Justin M. Forbes 13f703
index 23e3240..d3109e4 100644
Justin M. Forbes 13f703
--- a/hw/qxl.c
Justin M. Forbes 13f703
+++ b/hw/qxl.c
Justin M. Forbes 13f703
@@ -120,7 +120,7 @@ static QXLMode qxl_modes[] = {
Justin M. Forbes 13f703
 static PCIQXLDevice *qxl0;
Justin M. Forbes 13f703
 
Justin M. Forbes 13f703
 static void qxl_send_events(PCIQXLDevice *d, uint32_t events);
Justin M. Forbes 13f703
-static void qxl_destroy_primary(PCIQXLDevice *d);
Justin M. Forbes 13f703
+static int qxl_destroy_primary(PCIQXLDevice *d, qxl_async_io async);
Justin M. Forbes 13f703
 static void qxl_reset_memslots(PCIQXLDevice *d);
Justin M. Forbes 13f703
 static void qxl_reset_surfaces(PCIQXLDevice *d);
Justin M. Forbes 13f703
 static void qxl_ring_set_dirty(PCIQXLDevice *qxl);
Justin M. Forbes 13f703
@@ -144,22 +144,47 @@ void qxl_guest_bug(PCIQXLDevice *qxl, const char *msg, ...)
Justin M. Forbes 13f703
 void qxl_spice_update_area(PCIQXLDevice *qxl, uint32_t surface_id,
Justin M. Forbes 13f703
                            struct QXLRect *area, struct QXLRect *dirty_rects,
Justin M. Forbes 13f703
                            uint32_t num_dirty_rects,
Justin M. Forbes 13f703
-                           uint32_t clear_dirty_region)
Justin M. Forbes 13f703
+                           uint32_t clear_dirty_region,
Justin M. Forbes 13f703
+                           qxl_async_io async)
Justin M. Forbes 13f703
 {
Justin M. Forbes 13f703
-    qxl->ssd.worker->update_area(qxl->ssd.worker, surface_id, area, dirty_rects,
Justin M. Forbes 13f703
-                             num_dirty_rects, clear_dirty_region);
Justin M. Forbes 13f703
+    if (async == QXL_SYNC) {
Justin M. Forbes 13f703
+        qxl->ssd.worker->update_area(qxl->ssd.worker, surface_id, area,
Justin M. Forbes 13f703
+                        dirty_rects, num_dirty_rects, clear_dirty_region);
Justin M. Forbes 13f703
+    } else {
Justin M. Forbes 13f703
+#if SPICE_INTERFACE_QXL_MINOR >= 1
Justin M. Forbes 13f703
+        spice_qxl_update_area_async(&qxl->ssd.qxl, surface_id, area,
Justin M. Forbes 13f703
+                                    clear_dirty_region, 0);
Justin M. Forbes 13f703
+#else
Justin M. Forbes 13f703
+        abort();
Justin M. Forbes 13f703
+#endif
Justin M. Forbes 13f703
+    }
Justin M. Forbes 13f703
 }
Justin M. Forbes 13f703
 
Justin M. Forbes 13f703
-void qxl_spice_destroy_surface_wait(PCIQXLDevice *qxl, uint32_t id)
Justin M. Forbes 13f703
+static void qxl_spice_destroy_surface_wait_complete(PCIQXLDevice *qxl,
Justin M. Forbes 13f703
+                                                    uint32_t id)
Justin M. Forbes 13f703
 {
Justin M. Forbes 13f703
     qemu_mutex_lock(&qxl->track_lock);
Justin M. Forbes 13f703
-    PANIC_ON(id >= NUM_SURFACES);
Justin M. Forbes 13f703
-    qxl->ssd.worker->destroy_surface_wait(qxl->ssd.worker, id);
Justin M. Forbes 13f703
     qxl->guest_surfaces.cmds[id] = 0;
Justin M. Forbes 13f703
     qxl->guest_surfaces.count--;
Justin M. Forbes 13f703
     qemu_mutex_unlock(&qxl->track_lock);
Justin M. Forbes 13f703
 }
Justin M. Forbes 13f703
 
Justin M. Forbes 13f703
+static void qxl_spice_destroy_surface_wait(PCIQXLDevice *qxl, uint32_t id,
Justin M. Forbes 13f703
+                                           qxl_async_io async)
Justin M. Forbes 13f703
+{
Justin M. Forbes 13f703
+    if (async) {
Justin M. Forbes 13f703
+#if SPICE_INTERFACE_QXL_MINOR < 1
Justin M. Forbes 13f703
+        abort();
Justin M. Forbes 13f703
+#else
Justin M. Forbes 13f703
+        spice_qxl_destroy_surface_async(&qxl->ssd.qxl, id,
Justin M. Forbes 13f703
+                                        (uint64_t)id);
Justin M. Forbes 13f703
+#endif
Justin M. Forbes 13f703
+    } else {
Justin M. Forbes 13f703
+        qxl->ssd.worker->destroy_surface_wait(qxl->ssd.worker, id);
Justin M. Forbes 13f703
+        qxl_spice_destroy_surface_wait_complete(qxl, id);
Justin M. Forbes 13f703
+    }
Justin M. Forbes 13f703
+}
Justin M. Forbes 13f703
+
Justin M. Forbes 13f703
 void qxl_spice_loadvm_commands(PCIQXLDevice *qxl, struct QXLCommandExt *ext,
Justin M. Forbes 13f703
                                uint32_t count)
Justin M. Forbes 13f703
 {
Justin M. Forbes 13f703
@@ -176,15 +201,28 @@ void qxl_spice_reset_memslots(PCIQXLDevice *qxl)
Justin M. Forbes 13f703
     qxl->ssd.worker->reset_memslots(qxl->ssd.worker);
Justin M. Forbes 13f703
 }
Justin M. Forbes 13f703
 
Justin M. Forbes 13f703
-void qxl_spice_destroy_surfaces(PCIQXLDevice *qxl)
Justin M. Forbes 13f703
+static void qxl_spice_destroy_surfaces_complete(PCIQXLDevice *qxl)
Justin M. Forbes 13f703
 {
Justin M. Forbes 13f703
     qemu_mutex_lock(&qxl->track_lock);
Justin M. Forbes 13f703
-    qxl->ssd.worker->destroy_surfaces(qxl->ssd.worker);
Justin M. Forbes 13f703
     memset(&qxl->guest_surfaces.cmds, 0, sizeof(qxl->guest_surfaces.cmds));
Justin M. Forbes 13f703
     qxl->guest_surfaces.count = 0;
Justin M. Forbes 13f703
     qemu_mutex_unlock(&qxl->track_lock);
Justin M. Forbes 13f703
 }
Justin M. Forbes 13f703
 
Justin M. Forbes 13f703
+static void qxl_spice_destroy_surfaces(PCIQXLDevice *qxl, qxl_async_io async)
Justin M. Forbes 13f703
+{
Justin M. Forbes 13f703
+    if (async) {
Justin M. Forbes 13f703
+#if SPICE_INTERFACE_QXL_MINOR < 1
Justin M. Forbes 13f703
+        abort();
Justin M. Forbes 13f703
+#else
Justin M. Forbes 13f703
+        spice_qxl_destroy_surfaces_async(&qxl->ssd.qxl, 0);
Justin M. Forbes 13f703
+#endif
Justin M. Forbes 13f703
+    } else {
Justin M. Forbes 13f703
+        qxl->ssd.worker->destroy_surfaces(qxl->ssd.worker);
Justin M. Forbes 13f703
+        qxl_spice_destroy_surfaces_complete(qxl);
Justin M. Forbes 13f703
+    }
Justin M. Forbes 13f703
+}
Justin M. Forbes 13f703
+
Justin M. Forbes 13f703
 void qxl_spice_reset_image_cache(PCIQXLDevice *qxl)
Justin M. Forbes 13f703
 {
Justin M. Forbes 13f703
     qxl->ssd.worker->reset_image_cache(qxl->ssd.worker);
Justin M. Forbes 13f703
@@ -689,6 +727,38 @@ static int interface_flush_resources(QXLInstance *sin)
Justin M. Forbes 13f703
     return ret;
Justin M. Forbes 13f703
 }
Justin M. Forbes 13f703
 
Justin M. Forbes 13f703
+static void qxl_create_guest_primary_complete(PCIQXLDevice *d);
Justin M. Forbes 13f703
+
Justin M. Forbes 13f703
+#if SPICE_INTERFACE_QXL_MINOR >= 1
Justin M. Forbes 13f703
+
Justin M. Forbes 13f703
+/* called from spice server thread context only */
Justin M. Forbes 13f703
+static void interface_async_complete(QXLInstance *sin, uint64_t cookie)
Justin M. Forbes 13f703
+{
Justin M. Forbes 13f703
+    PCIQXLDevice *qxl = container_of(sin, PCIQXLDevice, ssd.qxl);
Justin M. Forbes 13f703
+    uint32_t current_async;
Justin M. Forbes 13f703
+
Justin M. Forbes 13f703
+    qemu_mutex_lock(&qxl->async_lock);
Justin M. Forbes 13f703
+    current_async = qxl->current_async;
Justin M. Forbes 13f703
+    qxl->current_async = QXL_UNDEFINED_IO;
Justin M. Forbes 13f703
+    qemu_mutex_unlock(&qxl->async_lock);
Justin M. Forbes 13f703
+
Justin M. Forbes 13f703
+    dprint(qxl, 2, "async_complete: %d (%ld) done\n", current_async, cookie);
Justin M. Forbes 13f703
+    switch (current_async) {
Justin M. Forbes 13f703
+    case QXL_IO_CREATE_PRIMARY_ASYNC:
Justin M. Forbes 13f703
+        qxl_create_guest_primary_complete(qxl);
Justin M. Forbes 13f703
+        break;
Justin M. Forbes 13f703
+    case QXL_IO_DESTROY_ALL_SURFACES_ASYNC:
Justin M. Forbes 13f703
+        qxl_spice_destroy_surfaces_complete(qxl);
Justin M. Forbes 13f703
+        break;
Justin M. Forbes 13f703
+    case QXL_IO_DESTROY_SURFACE_ASYNC:
Justin M. Forbes 13f703
+        qxl_spice_destroy_surface_wait_complete(qxl, (uint32_t)cookie);
Justin M. Forbes 13f703
+        break;
Justin M. Forbes 13f703
+    }
Justin M. Forbes 13f703
+    qxl_send_events(qxl, QXL_INTERRUPT_IO_CMD);
Justin M. Forbes 13f703
+}
Justin M. Forbes 13f703
+
Justin M. Forbes 13f703
+#endif
Justin M. Forbes 13f703
+
Justin M. Forbes 13f703
 static const QXLInterface qxl_interface = {
Justin M. Forbes 13f703
     .base.type               = SPICE_INTERFACE_QXL,
Justin M. Forbes 13f703
     .base.description        = "qxl gpu",
Justin M. Forbes 13f703
@@ -708,6 +778,9 @@ static const QXLInterface qxl_interface = {
Justin M. Forbes 13f703
     .req_cursor_notification = interface_req_cursor_notification,
Justin M. Forbes 13f703
     .notify_update           = interface_notify_update,
Justin M. Forbes 13f703
     .flush_resources         = interface_flush_resources,
Justin M. Forbes 13f703
+#if SPICE_INTERFACE_QXL_MINOR >= 1
Justin M. Forbes 13f703
+    .async_complete          = interface_async_complete,
Justin M. Forbes 13f703
+#endif
Justin M. Forbes 13f703
 };
Justin M. Forbes 13f703
 
Justin M. Forbes 13f703
 static void qxl_enter_vga_mode(PCIQXLDevice *d)
Justin M. Forbes 13f703
@@ -727,7 +800,7 @@ static void qxl_exit_vga_mode(PCIQXLDevice *d)
Justin M. Forbes 13f703
         return;
Justin M. Forbes 13f703
     }
Justin M. Forbes 13f703
     dprint(d, 1, "%s\n", __FUNCTION__);
Justin M. Forbes 13f703
-    qxl_destroy_primary(d);
Justin M. Forbes 13f703
+    qxl_destroy_primary(d, QXL_SYNC);
Justin M. Forbes 13f703
 }
Justin M. Forbes 13f703
 
Justin M. Forbes 13f703
 static void qxl_set_irq(PCIQXLDevice *d)
Justin M. Forbes 13f703
@@ -824,13 +897,14 @@ static void qxl_vga_ioport_write(void *opaque, uint32_t addr, uint32_t val)
Justin M. Forbes 13f703
 
Justin M. Forbes 13f703
     if (qxl->mode != QXL_MODE_VGA) {
Justin M. Forbes 13f703
         dprint(qxl, 1, "%s\n", __FUNCTION__);
Justin M. Forbes 13f703
-        qxl_destroy_primary(qxl);
Justin M. Forbes 13f703
+        qxl_destroy_primary(qxl, QXL_SYNC);
Justin M. Forbes 13f703
         qxl_soft_reset(qxl);
Justin M. Forbes 13f703
     }
Justin M. Forbes 13f703
     vga_ioport_write(opaque, addr, val);
Justin M. Forbes 13f703
 }
Justin M. Forbes 13f703
 
Justin M. Forbes 13f703
-static void qxl_add_memslot(PCIQXLDevice *d, uint32_t slot_id, uint64_t delta)
Justin M. Forbes 13f703
+static void qxl_add_memslot(PCIQXLDevice *d, uint32_t slot_id, uint64_t delta,
Justin M. Forbes 13f703
+                            qxl_async_io async)
Justin M. Forbes 13f703
 {
Justin M. Forbes 13f703
     static const int regions[] = {
Justin M. Forbes 13f703
         QXL_RAM_RANGE_INDEX,
Justin M. Forbes 13f703
@@ -900,7 +974,7 @@ static void qxl_add_memslot(PCIQXLDevice *d, uint32_t slot_id, uint64_t delta)
Justin M. Forbes 13f703
            __FUNCTION__, memslot.slot_id,
Justin M. Forbes 13f703
            memslot.virt_start, memslot.virt_end);
Justin M. Forbes 13f703
 
Justin M. Forbes 13f703
-    qemu_spice_add_memslot(&d->ssd, &memslot);
Justin M. Forbes 13f703
+    qemu_spice_add_memslot(&d->ssd, &memslot, async);
Justin M. Forbes 13f703
     d->guest_slots[slot_id].ptr = (void*)memslot.virt_start;
Justin M. Forbes 13f703
     d->guest_slots[slot_id].size = memslot.virt_end - memslot.virt_start;
Justin M. Forbes 13f703
     d->guest_slots[slot_id].delta = delta;
Justin M. Forbes 13f703
@@ -925,7 +999,7 @@ static void qxl_reset_surfaces(PCIQXLDevice *d)
Justin M. Forbes 13f703
 {
Justin M. Forbes 13f703
     dprint(d, 1, "%s:\n", __FUNCTION__);
Justin M. Forbes 13f703
     d->mode = QXL_MODE_UNDEFINED;
Justin M. Forbes 13f703
-    qxl_spice_destroy_surfaces(d);
Justin M. Forbes 13f703
+    qxl_spice_destroy_surfaces(d, QXL_SYNC);
Justin M. Forbes 13f703
 }
Justin M. Forbes 13f703
 
Justin M. Forbes 13f703
 /* called from spice server thread context only */
Justin M. Forbes 13f703
@@ -950,7 +1024,14 @@ void *qxl_phys2virt(PCIQXLDevice *qxl, QXLPHYSICAL pqxl, int group_id)
Justin M. Forbes 13f703
     }
Justin M. Forbes 13f703
 }
Justin M. Forbes 13f703
 
Justin M. Forbes 13f703
-static void qxl_create_guest_primary(PCIQXLDevice *qxl, int loadvm)
Justin M. Forbes 13f703
+static void qxl_create_guest_primary_complete(PCIQXLDevice *qxl)
Justin M. Forbes 13f703
+{
Justin M. Forbes 13f703
+    /* for local rendering */
Justin M. Forbes 13f703
+    qxl_render_resize(qxl);
Justin M. Forbes 13f703
+}
Justin M. Forbes 13f703
+
Justin M. Forbes 13f703
+static void qxl_create_guest_primary(PCIQXLDevice *qxl, int loadvm,
Justin M. Forbes 13f703
+                                     qxl_async_io async)
Justin M. Forbes 13f703
 {
Justin M. Forbes 13f703
     QXLDevSurfaceCreate surface;
Justin M. Forbes 13f703
     QXLSurfaceCreate *sc = &qxl->guest_primary.surface;
Justin M. Forbes 13f703
@@ -978,22 +1059,26 @@ static void qxl_create_guest_primary(PCIQXLDevice *qxl, int loadvm)
Justin M. Forbes 13f703
 
Justin M. Forbes 13f703
     qxl->mode = QXL_MODE_NATIVE;
Justin M. Forbes 13f703
     qxl->cmdflags = 0;
Justin M. Forbes 13f703
-    qemu_spice_create_primary_surface(&qxl->ssd, 0, &surface);
Justin M. Forbes 13f703
+    qemu_spice_create_primary_surface(&qxl->ssd, 0, &surface, async);
Justin M. Forbes 13f703
 
Justin M. Forbes 13f703
-    /* for local rendering */
Justin M. Forbes 13f703
-    qxl_render_resize(qxl);
Justin M. Forbes 13f703
+    if (async == QXL_SYNC) {
Justin M. Forbes 13f703
+        qxl_create_guest_primary_complete(qxl);
Justin M. Forbes 13f703
+    }
Justin M. Forbes 13f703
 }
Justin M. Forbes 13f703
 
Justin M. Forbes 13f703
-static void qxl_destroy_primary(PCIQXLDevice *d)
Justin M. Forbes 13f703
+/* return 1 if surface destoy was initiated (in QXL_ASYNC case) or
Justin M. Forbes 13f703
+ * done (in QXL_SYNC case), 0 otherwise. */
Justin M. Forbes 13f703
+static int qxl_destroy_primary(PCIQXLDevice *d, qxl_async_io async)
Justin M. Forbes 13f703
 {
Justin M. Forbes 13f703
     if (d->mode == QXL_MODE_UNDEFINED) {
Justin M. Forbes 13f703
-        return;
Justin M. Forbes 13f703
+        return 0;
Justin M. Forbes 13f703
     }
Justin M. Forbes 13f703
 
Justin M. Forbes 13f703
     dprint(d, 1, "%s\n", __FUNCTION__);
Justin M. Forbes 13f703
 
Justin M. Forbes 13f703
     d->mode = QXL_MODE_UNDEFINED;
Justin M. Forbes 13f703
-    qemu_spice_destroy_primary_surface(&d->ssd, 0);
Justin M. Forbes 13f703
+    qemu_spice_destroy_primary_surface(&d->ssd, 0, async);
Justin M. Forbes 13f703
+    return 1;
Justin M. Forbes 13f703
 }
Justin M. Forbes 13f703
 
Justin M. Forbes 13f703
 static void qxl_set_mode(PCIQXLDevice *d, int modenr, int loadvm)
Justin M. Forbes 13f703
@@ -1023,10 +1108,10 @@ static void qxl_set_mode(PCIQXLDevice *d, int modenr, int loadvm)
Justin M. Forbes 13f703
     }
Justin M. Forbes 13f703
 
Justin M. Forbes 13f703
     d->guest_slots[0].slot = slot;
Justin M. Forbes 13f703
-    qxl_add_memslot(d, 0, devmem);
Justin M. Forbes 13f703
+    qxl_add_memslot(d, 0, devmem, QXL_SYNC);
Justin M. Forbes 13f703
 
Justin M. Forbes 13f703
     d->guest_primary.surface = surface;
Justin M. Forbes 13f703
-    qxl_create_guest_primary(d, 0);
Justin M. Forbes 13f703
+    qxl_create_guest_primary(d, 0, QXL_SYNC);
Justin M. Forbes 13f703
 
Justin M. Forbes 13f703
     d->mode = QXL_MODE_COMPAT;
Justin M. Forbes 13f703
     d->cmdflags = QXL_COMMAND_FLAG_COMPAT;
Justin M. Forbes 13f703
@@ -1044,6 +1129,10 @@ static void ioport_write(void *opaque, uint32_t addr, uint32_t val)
Justin M. Forbes 13f703
 {
Justin M. Forbes 13f703
     PCIQXLDevice *d = opaque;
Justin M. Forbes 13f703
     uint32_t io_port = addr - d->io_base;
Justin M. Forbes 13f703
+    qxl_async_io async = QXL_SYNC;
Justin M. Forbes 13f703
+#if SPICE_INTERFACE_QXL_MINOR >= 1
Justin M. Forbes 13f703
+    uint32_t orig_io_port = io_port;
Justin M. Forbes 13f703
+#endif
Justin M. Forbes 13f703
 
Justin M. Forbes 13f703
     switch (io_port) {
Justin M. Forbes 13f703
     case QXL_IO_RESET:
Justin M. Forbes 13f703
@@ -1053,6 +1142,10 @@ static void ioport_write(void *opaque, uint32_t addr, uint32_t val)
Justin M. Forbes 13f703
     case QXL_IO_CREATE_PRIMARY:
Justin M. Forbes 13f703
     case QXL_IO_UPDATE_IRQ:
Justin M. Forbes 13f703
     case QXL_IO_LOG:
Justin M. Forbes 13f703
+#if SPICE_INTERFACE_QXL_MINOR >= 1
Justin M. Forbes 13f703
+    case QXL_IO_MEMSLOT_ADD_ASYNC:
Justin M. Forbes 13f703
+    case QXL_IO_CREATE_PRIMARY_ASYNC:
Justin M. Forbes 13f703
+#endif
Justin M. Forbes 13f703
         break;
Justin M. Forbes 13f703
     default:
Justin M. Forbes 13f703
         if (d->mode != QXL_MODE_VGA) {
Justin M. Forbes 13f703
@@ -1060,15 +1153,61 @@ static void ioport_write(void *opaque, uint32_t addr, uint32_t val)
Justin M. Forbes 13f703
         }
Justin M. Forbes 13f703
         dprint(d, 1, "%s: unexpected port 0x%x (%s) in vga mode\n",
Justin M. Forbes 13f703
             __func__, io_port, io_port_to_string(io_port));
Justin M. Forbes 13f703
+#if SPICE_INTERFACE_QXL_MINOR >= 1
Justin M. Forbes 13f703
+        /* be nice to buggy guest drivers */
Justin M. Forbes 13f703
+        if (io_port >= QXL_IO_UPDATE_AREA_ASYNC &&
Justin M. Forbes 13f703
+            io_port <= QXL_IO_DESTROY_ALL_SURFACES_ASYNC) {
Justin M. Forbes 13f703
+            qxl_send_events(d, QXL_INTERRUPT_IO_CMD);
Justin M. Forbes 13f703
+        }
Justin M. Forbes 13f703
+#endif
Justin M. Forbes 13f703
         return;
Justin M. Forbes 13f703
     }
Justin M. Forbes 13f703
 
Justin M. Forbes 13f703
+#if SPICE_INTERFACE_QXL_MINOR >= 1
Justin M. Forbes 13f703
+    /* we change the io_port to avoid ifdeffery in the main switch */
Justin M. Forbes 13f703
+    orig_io_port = io_port;
Justin M. Forbes 13f703
+    switch (io_port) {
Justin M. Forbes 13f703
+    case QXL_IO_UPDATE_AREA_ASYNC:
Justin M. Forbes 13f703
+        io_port = QXL_IO_UPDATE_AREA;
Justin M. Forbes 13f703
+        goto async_common;
Justin M. Forbes 13f703
+    case QXL_IO_MEMSLOT_ADD_ASYNC:
Justin M. Forbes 13f703
+        io_port = QXL_IO_MEMSLOT_ADD;
Justin M. Forbes 13f703
+        goto async_common;
Justin M. Forbes 13f703
+    case QXL_IO_CREATE_PRIMARY_ASYNC:
Justin M. Forbes 13f703
+        io_port = QXL_IO_CREATE_PRIMARY;
Justin M. Forbes 13f703
+        goto async_common;
Justin M. Forbes 13f703
+    case QXL_IO_DESTROY_PRIMARY_ASYNC:
Justin M. Forbes 13f703
+        io_port = QXL_IO_DESTROY_PRIMARY;
Justin M. Forbes 13f703
+        goto async_common;
Justin M. Forbes 13f703
+    case QXL_IO_DESTROY_SURFACE_ASYNC:
Justin M. Forbes 13f703
+        io_port = QXL_IO_DESTROY_SURFACE_WAIT;
Justin M. Forbes 13f703
+        goto async_common;
Justin M. Forbes 13f703
+    case QXL_IO_DESTROY_ALL_SURFACES_ASYNC:
Justin M. Forbes 13f703
+        io_port = QXL_IO_DESTROY_ALL_SURFACES;
Justin M. Forbes 13f703
+async_common:
Justin M. Forbes 13f703
+        async = QXL_ASYNC;
Justin M. Forbes 13f703
+        qemu_mutex_lock(&d->async_lock);
Justin M. Forbes 13f703
+        if (d->current_async != QXL_UNDEFINED_IO) {
Justin M. Forbes 13f703
+            qxl_guest_bug(d, "%d async started before last (%d) complete",
Justin M. Forbes 13f703
+                io_port, d->current_async);
Justin M. Forbes 13f703
+            qemu_mutex_unlock(&d->async_lock);
Justin M. Forbes 13f703
+            return;
Justin M. Forbes 13f703
+        }
Justin M. Forbes 13f703
+        d->current_async = orig_io_port;
Justin M. Forbes 13f703
+        qemu_mutex_unlock(&d->async_lock);
Justin M. Forbes 13f703
+        dprint(d, 2, "start async %d (%d)\n", io_port, val);
Justin M. Forbes 13f703
+        break;
Justin M. Forbes 13f703
+    default:
Justin M. Forbes 13f703
+        break;
Justin M. Forbes 13f703
+    }
Justin M. Forbes 13f703
+#endif
Justin M. Forbes 13f703
+
Justin M. Forbes 13f703
     switch (io_port) {
Justin M. Forbes 13f703
     case QXL_IO_UPDATE_AREA:
Justin M. Forbes 13f703
     {
Justin M. Forbes 13f703
         QXLRect update = d->ram->update_area;
Justin M. Forbes 13f703
         qxl_spice_update_area(d, d->ram->update_surface,
Justin M. Forbes 13f703
-                              &update, NULL, 0, 0);
Justin M. Forbes 13f703
+                              &update, NULL, 0, 0, async);
Justin M. Forbes 13f703
         break;
Justin M. Forbes 13f703
     }
Justin M. Forbes 13f703
     case QXL_IO_NOTIFY_CMD:
Justin M. Forbes 13f703
@@ -1116,7 +1255,7 @@ static void ioport_write(void *opaque, uint32_t addr, uint32_t val)
Justin M. Forbes 13f703
             break;
Justin M. Forbes 13f703
         }
Justin M. Forbes 13f703
         d->guest_slots[val].slot = d->ram->mem_slot;
Justin M. Forbes 13f703
-        qxl_add_memslot(d, val, 0);
Justin M. Forbes 13f703
+        qxl_add_memslot(d, val, 0, async);
Justin M. Forbes 13f703
         break;
Justin M. Forbes 13f703
     case QXL_IO_MEMSLOT_DEL:
Justin M. Forbes 13f703
         if (val >= NUM_MEMSLOTS) {
Justin M. Forbes 13f703
@@ -1127,31 +1266,56 @@ static void ioport_write(void *opaque, uint32_t addr, uint32_t val)
Justin M. Forbes 13f703
         break;
Justin M. Forbes 13f703
     case QXL_IO_CREATE_PRIMARY:
Justin M. Forbes 13f703
         if (val != 0) {
Justin M. Forbes 13f703
-            qxl_guest_bug(d, "QXL_IO_CREATE_PRIMARY: val != 0");
Justin M. Forbes 13f703
-            break;
Justin M. Forbes 13f703
+            qxl_guest_bug(d, "QXL_IO_CREATE_PRIMARY (async=%d): val != 0",
Justin M. Forbes 13f703
+                          async);
Justin M. Forbes 13f703
+            goto cancel_async;
Justin M. Forbes 13f703
         }
Justin M. Forbes 13f703
-        dprint(d, 1, "QXL_IO_CREATE_PRIMARY\n");
Justin M. Forbes 13f703
+        dprint(d, 1, "QXL_IO_CREATE_PRIMARY async=%d\n", async);
Justin M. Forbes 13f703
         d->guest_primary.surface = d->ram->create_surface;
Justin M. Forbes 13f703
-        qxl_create_guest_primary(d, 0);
Justin M. Forbes 13f703
+        qxl_create_guest_primary(d, 0, async);
Justin M. Forbes 13f703
         break;
Justin M. Forbes 13f703
     case QXL_IO_DESTROY_PRIMARY:
Justin M. Forbes 13f703
         if (val != 0) {
Justin M. Forbes 13f703
-            qxl_guest_bug(d, "QXL_IO_DESTROY_PRIMARY: val != 0");
Justin M. Forbes 13f703
-            break;
Justin M. Forbes 13f703
+            qxl_guest_bug(d, "QXL_IO_DESTROY_PRIMARY (async=%d): val != 0",
Justin M. Forbes 13f703
+                          async);
Justin M. Forbes 13f703
+            goto cancel_async;
Justin M. Forbes 13f703
+        }
Justin M. Forbes 13f703
+        dprint(d, 1, "QXL_IO_DESTROY_PRIMARY (async=%d) (%s)\n", async,
Justin M. Forbes 13f703
+               qxl_mode_to_string(d->mode));
Justin M. Forbes 13f703
+        if (!qxl_destroy_primary(d, async)) {
Justin M. Forbes 13f703
+            dprint(d, 1, "QXL_IO_DESTROY_PRIMARY_ASYNC in %s, ignored\n",
Justin M. Forbes 13f703
+                    qxl_mode_to_string(d->mode));
Justin M. Forbes 13f703
+            goto cancel_async;
Justin M. Forbes 13f703
         }
Justin M. Forbes 13f703
-        dprint(d, 1, "QXL_IO_DESTROY_PRIMARY (%s)\n", qxl_mode_to_string(d->mode));
Justin M. Forbes 13f703
-        qxl_destroy_primary(d);
Justin M. Forbes 13f703
         break;
Justin M. Forbes 13f703
     case QXL_IO_DESTROY_SURFACE_WAIT:
Justin M. Forbes 13f703
-        qxl_spice_destroy_surface_wait(d, val);
Justin M. Forbes 13f703
+        if (val >= NUM_SURFACES) {
Justin M. Forbes 13f703
+            qxl_guest_bug(d, "QXL_IO_DESTROY_SURFACE (async=%d):"
Justin M. Forbes 13f703
+                             "%d >= NUM_SURFACES", async, val);
Justin M. Forbes 13f703
+            goto cancel_async;
Justin M. Forbes 13f703
+        }
Justin M. Forbes 13f703
+        qxl_spice_destroy_surface_wait(d, val, async);
Justin M. Forbes 13f703
         break;
Justin M. Forbes 13f703
     case QXL_IO_DESTROY_ALL_SURFACES:
Justin M. Forbes 13f703
-        qxl_spice_destroy_surfaces(d);
Justin M. Forbes 13f703
+        d->mode = QXL_MODE_UNDEFINED;
Justin M. Forbes 13f703
+        qxl_spice_destroy_surfaces(d, async);
Justin M. Forbes 13f703
         break;
Justin M. Forbes 13f703
     default:
Justin M. Forbes 13f703
         fprintf(stderr, "%s: ioport=0x%x, abort()\n", __FUNCTION__, io_port);
Justin M. Forbes 13f703
         abort();
Justin M. Forbes 13f703
     }
Justin M. Forbes 13f703
+    return;
Justin M. Forbes 13f703
+cancel_async:
Justin M. Forbes 13f703
+#if SPICE_INTERFACE_QXL_MINOR >= 1
Justin M. Forbes 13f703
+    if (async) {
Justin M. Forbes 13f703
+        qxl_send_events(d, QXL_INTERRUPT_IO_CMD);
Justin M. Forbes 13f703
+        qemu_mutex_lock(&d->async_lock);
Justin M. Forbes 13f703
+        d->current_async = QXL_UNDEFINED_IO;
Justin M. Forbes 13f703
+        qemu_mutex_unlock(&d->async_lock);
Justin M. Forbes 13f703
+    }
Justin M. Forbes 13f703
+#else
Justin M. Forbes 13f703
+    return;
Justin M. Forbes 13f703
+#endif
Justin M. Forbes 13f703
 }
Justin M. Forbes 13f703
 
Justin M. Forbes 13f703
 static uint32_t ioport_read(void *opaque, uint32_t addr)
Justin M. Forbes 13f703
@@ -1364,6 +1528,8 @@ static int qxl_init_common(PCIQXLDevice *qxl)
Justin M. Forbes 13f703
     qxl->num_memslots = NUM_MEMSLOTS;
Justin M. Forbes 13f703
     qxl->num_surfaces = NUM_SURFACES;
Justin M. Forbes 13f703
     qemu_mutex_init(&qxl->track_lock);
Justin M. Forbes 13f703
+    qemu_mutex_init(&qxl->async_lock);
Justin M. Forbes 13f703
+    qxl->current_async = QXL_UNDEFINED_IO;
Justin M. Forbes 13f703
 
Justin M. Forbes 13f703
     switch (qxl->revision) {
Justin M. Forbes 13f703
     case 1: /* spice 0.4 -- qxl-1 */
Justin M. Forbes 13f703
@@ -1528,9 +1694,9 @@ static int qxl_post_load(void *opaque, int version)
Justin M. Forbes 13f703
             if (!d->guest_slots[i].active) {
Justin M. Forbes 13f703
                 continue;
Justin M. Forbes 13f703
             }
Justin M. Forbes 13f703
-            qxl_add_memslot(d, i, 0);
Justin M. Forbes 13f703
+            qxl_add_memslot(d, i, 0, QXL_SYNC);
Justin M. Forbes 13f703
         }
Justin M. Forbes 13f703
-        qxl_create_guest_primary(d, 1);
Justin M. Forbes 13f703
+        qxl_create_guest_primary(d, 1, QXL_SYNC);
Justin M. Forbes 13f703
 
Justin M. Forbes 13f703
         /* replay surface-create and cursor-set commands */
Justin M. Forbes 13f703
         cmds = qemu_mallocz(sizeof(QXLCommandExt) * (NUM_SURFACES + 1));
Justin M. Forbes 13f703
diff --git a/hw/qxl.h b/hw/qxl.h
Justin M. Forbes 13f703
index 32ca5a0..1046205 100644
Justin M. Forbes 13f703
--- a/hw/qxl.h
Justin M. Forbes 13f703
+++ b/hw/qxl.h
Justin M. Forbes 13f703
@@ -15,6 +15,8 @@ enum qxl_mode {
Justin M. Forbes 13f703
     QXL_MODE_NATIVE,
Justin M. Forbes 13f703
 };
Justin M. Forbes 13f703
 
Justin M. Forbes 13f703
+#define QXL_UNDEFINED_IO UINT32_MAX
Justin M. Forbes 13f703
+
Justin M. Forbes 13f703
 typedef struct PCIQXLDevice {
Justin M. Forbes 13f703
     PCIDevice          pci;
Justin M. Forbes 13f703
     SimpleSpiceDisplay ssd;
Justin M. Forbes 13f703
@@ -30,6 +32,9 @@ typedef struct PCIQXLDevice {
Justin M. Forbes 13f703
     int32_t            num_memslots;
Justin M. Forbes 13f703
     int32_t            num_surfaces;
Justin M. Forbes 13f703
 
Justin M. Forbes 13f703
+    uint32_t           current_async;
Justin M. Forbes 13f703
+    QemuMutex          async_lock;
Justin M. Forbes 13f703
+
Justin M. Forbes 13f703
     struct guest_slots {
Justin M. Forbes 13f703
         QXLMemSlot     slot;
Justin M. Forbes 13f703
         void           *ptr;
Justin M. Forbes 13f703
@@ -104,13 +109,12 @@ void qxl_guest_bug(PCIQXLDevice *qxl, const char *msg, ...);
Justin M. Forbes 13f703
 void qxl_spice_update_area(PCIQXLDevice *qxl, uint32_t surface_id,
Justin M. Forbes 13f703
                            struct QXLRect *area, struct QXLRect *dirty_rects,
Justin M. Forbes 13f703
                            uint32_t num_dirty_rects,
Justin M. Forbes 13f703
-                           uint32_t clear_dirty_region);
Justin M. Forbes 13f703
-void qxl_spice_destroy_surface_wait(PCIQXLDevice *qxl, uint32_t id);
Justin M. Forbes 13f703
+                           uint32_t clear_dirty_region,
Justin M. Forbes 13f703
+                           qxl_async_io async);
Justin M. Forbes 13f703
 void qxl_spice_loadvm_commands(PCIQXLDevice *qxl, struct QXLCommandExt *ext,
Justin M. Forbes 13f703
                                uint32_t count);
Justin M. Forbes 13f703
 void qxl_spice_oom(PCIQXLDevice *qxl);
Justin M. Forbes 13f703
 void qxl_spice_reset_memslots(PCIQXLDevice *qxl);
Justin M. Forbes 13f703
-void qxl_spice_destroy_surfaces(PCIQXLDevice *qxl);
Justin M. Forbes 13f703
 void qxl_spice_reset_image_cache(PCIQXLDevice *qxl);
Justin M. Forbes 13f703
 void qxl_spice_reset_cursor(PCIQXLDevice *qxl);
Justin M. Forbes 13f703
 
Justin M. Forbes 13f703
@@ -122,3 +126,9 @@ void qxl_log_command(PCIQXLDevice *qxl, const char *ring, QXLCommandExt *ext);
Justin M. Forbes 13f703
 void qxl_render_resize(PCIQXLDevice *qxl);
Justin M. Forbes 13f703
 void qxl_render_update(PCIQXLDevice *qxl);
Justin M. Forbes 13f703
 void qxl_render_cursor(PCIQXLDevice *qxl, QXLCommandExt *ext);
Justin M. Forbes 13f703
+#if SPICE_INTERFACE_QXL_MINOR >= 1
Justin M. Forbes 13f703
+void qxl_spice_update_area_async(PCIQXLDevice *qxl, uint32_t surface_id,
Justin M. Forbes 13f703
+                                 struct QXLRect *area,
Justin M. Forbes 13f703
+                                 uint32_t clear_dirty_region,
Justin M. Forbes 13f703
+                                 int is_vga);
Justin M. Forbes 13f703
+#endif
Justin M. Forbes 13f703
diff --git a/ui/spice-display.c b/ui/spice-display.c
Justin M. Forbes 13f703
index af10ae8..683d454 100644
Justin M. Forbes 13f703
--- a/ui/spice-display.c
Justin M. Forbes 13f703
+++ b/ui/spice-display.c
Justin M. Forbes 13f703
@@ -62,10 +62,18 @@ void qemu_spice_rect_union(QXLRect *dest, const QXLRect *r)
Justin M. Forbes 13f703
     dest->right = MAX(dest->right, r->right);
Justin M. Forbes 13f703
 }
Justin M. Forbes 13f703
 
Justin M. Forbes 13f703
-
Justin M. Forbes 13f703
-void qemu_spice_add_memslot(SimpleSpiceDisplay *ssd, QXLDevMemSlot *memslot)
Justin M. Forbes 13f703
-{
Justin M. Forbes 13f703
-    ssd->worker->add_memslot(ssd->worker, memslot);
Justin M. Forbes 13f703
+void qemu_spice_add_memslot(SimpleSpiceDisplay *ssd, QXLDevMemSlot *memslot,
Justin M. Forbes 13f703
+                            qxl_async_io async)
Justin M. Forbes 13f703
+{
Justin M. Forbes 13f703
+    if (async != QXL_SYNC) {
Justin M. Forbes 13f703
+#if SPICE_INTERFACE_QXL_MINOR >= 1
Justin M. Forbes 13f703
+        spice_qxl_add_memslot_async(&ssd->qxl, memslot, 0);
Justin M. Forbes 13f703
+#else
Justin M. Forbes 13f703
+        abort();
Justin M. Forbes 13f703
+#endif
Justin M. Forbes 13f703
+    } else {
Justin M. Forbes 13f703
+        ssd->worker->add_memslot(ssd->worker, memslot);
Justin M. Forbes 13f703
+    }
Justin M. Forbes 13f703
 }
Justin M. Forbes 13f703
 
Justin M. Forbes 13f703
 void qemu_spice_del_memslot(SimpleSpiceDisplay *ssd, uint32_t gid, uint32_t sid)
Justin M. Forbes 13f703
@@ -74,14 +82,33 @@ void qemu_spice_del_memslot(SimpleSpiceDisplay *ssd, uint32_t gid, uint32_t sid)
Justin M. Forbes 13f703
 }
Justin M. Forbes 13f703
 
Justin M. Forbes 13f703
 void qemu_spice_create_primary_surface(SimpleSpiceDisplay *ssd, uint32_t id,
Justin M. Forbes 13f703
-                                       QXLDevSurfaceCreate *surface)
Justin M. Forbes 13f703
-{
Justin M. Forbes 13f703
-    ssd->worker->create_primary_surface(ssd->worker, id, surface);
Justin M. Forbes 13f703
+                                       QXLDevSurfaceCreate *surface,
Justin M. Forbes 13f703
+                                       qxl_async_io async)
Justin M. Forbes 13f703
+{
Justin M. Forbes 13f703
+    if (async != QXL_SYNC) {
Justin M. Forbes 13f703
+#if SPICE_INTERFACE_QXL_MINOR >= 1
Justin M. Forbes 13f703
+        spice_qxl_create_primary_surface_async(&ssd->qxl, id, surface, 0);
Justin M. Forbes 13f703
+#else
Justin M. Forbes 13f703
+        abort();
Justin M. Forbes 13f703
+#endif
Justin M. Forbes 13f703
+    } else {
Justin M. Forbes 13f703
+        ssd->worker->create_primary_surface(ssd->worker, id, surface);
Justin M. Forbes 13f703
+    }
Justin M. Forbes 13f703
 }
Justin M. Forbes 13f703
 
Justin M. Forbes 13f703
-void qemu_spice_destroy_primary_surface(SimpleSpiceDisplay *ssd, uint32_t id)
Justin M. Forbes 13f703
+
Justin M. Forbes 13f703
+void qemu_spice_destroy_primary_surface(SimpleSpiceDisplay *ssd,
Justin M. Forbes 13f703
+                                        uint32_t id, qxl_async_io async)
Justin M. Forbes 13f703
 {
Justin M. Forbes 13f703
-    ssd->worker->destroy_primary_surface(ssd->worker, id);
Justin M. Forbes 13f703
+    if (async != QXL_SYNC) {
Justin M. Forbes 13f703
+#if SPICE_INTERFACE_QXL_MINOR >= 1
Justin M. Forbes 13f703
+        spice_qxl_destroy_primary_surface_async(&ssd->qxl, id, 0);
Justin M. Forbes 13f703
+#else
Justin M. Forbes 13f703
+        abort();
Justin M. Forbes 13f703
+#endif
Justin M. Forbes 13f703
+    } else {
Justin M. Forbes 13f703
+        ssd->worker->destroy_primary_surface(ssd->worker, id);
Justin M. Forbes 13f703
+    }
Justin M. Forbes 13f703
 }
Justin M. Forbes 13f703
 
Justin M. Forbes 13f703
 void qemu_spice_wakeup(SimpleSpiceDisplay *ssd)
Justin M. Forbes 13f703
@@ -198,7 +225,7 @@ void qemu_spice_create_host_memslot(SimpleSpiceDisplay *ssd)
Justin M. Forbes 13f703
     memset(&memslot, 0, sizeof(memslot));
Justin M. Forbes 13f703
     memslot.slot_group_id = MEMSLOT_GROUP_HOST;
Justin M. Forbes 13f703
     memslot.virt_end = ~0;
Justin M. Forbes 13f703
-    qemu_spice_add_memslot(ssd, &memslot);
Justin M. Forbes 13f703
+    qemu_spice_add_memslot(ssd, &memslot, QXL_SYNC);
Justin M. Forbes 13f703
 }
Justin M. Forbes 13f703
 
Justin M. Forbes 13f703
 void qemu_spice_create_host_primary(SimpleSpiceDisplay *ssd)
Justin M. Forbes 13f703
@@ -218,14 +245,14 @@ void qemu_spice_create_host_primary(SimpleSpiceDisplay *ssd)
Justin M. Forbes 13f703
     surface.mem        = (intptr_t)ssd->buf;
Justin M. Forbes 13f703
     surface.group_id   = MEMSLOT_GROUP_HOST;
Justin M. Forbes 13f703
 
Justin M. Forbes 13f703
-    qemu_spice_create_primary_surface(ssd, 0, &surface);
Justin M. Forbes 13f703
+    qemu_spice_create_primary_surface(ssd, 0, &surface, QXL_SYNC);
Justin M. Forbes 13f703
 }
Justin M. Forbes 13f703
 
Justin M. Forbes 13f703
 void qemu_spice_destroy_host_primary(SimpleSpiceDisplay *ssd)
Justin M. Forbes 13f703
 {
Justin M. Forbes 13f703
     dprint(1, "%s:\n", __FUNCTION__);
Justin M. Forbes 13f703
 
Justin M. Forbes 13f703
-    qemu_spice_destroy_primary_surface(ssd, 0);
Justin M. Forbes 13f703
+    qemu_spice_destroy_primary_surface(ssd, 0, QXL_SYNC);
Justin M. Forbes 13f703
 }
Justin M. Forbes 13f703
 
Justin M. Forbes 13f703
 void qemu_spice_vm_change_state_handler(void *opaque, int running, int reason)
Justin M. Forbes 13f703
diff --git a/ui/spice-display.h b/ui/spice-display.h
Justin M. Forbes 13f703
index abe99c7..1388641 100644
Justin M. Forbes 13f703
--- a/ui/spice-display.h
Justin M. Forbes 13f703
+++ b/ui/spice-display.h
Justin M. Forbes 13f703
@@ -33,6 +33,20 @@
Justin M. Forbes 13f703
 
Justin M. Forbes 13f703
 #define NUM_SURFACES 1024
Justin M. Forbes 13f703
 
Justin M. Forbes 13f703
+/*
Justin M. Forbes 13f703
+ * Internal enum to differenciate between options for
Justin M. Forbes 13f703
+ * io calls that have a sync (old) version and an _async (new)
Justin M. Forbes 13f703
+ * version:
Justin M. Forbes 13f703
+ *  QXL_SYNC: use the old version
Justin M. Forbes 13f703
+ *  QXL_ASYNC: use the new version and make sure there are no two
Justin M. Forbes 13f703
+ *   happening at the same time. This is used for guest initiated
Justin M. Forbes 13f703
+ *   calls
Justin M. Forbes 13f703
+ */
Justin M. Forbes 13f703
+typedef enum qxl_async_io {
Justin M. Forbes 13f703
+    QXL_SYNC,
Justin M. Forbes 13f703
+    QXL_ASYNC,
Justin M. Forbes 13f703
+} qxl_async_io;
Justin M. Forbes 13f703
+
Justin M. Forbes 13f703
 typedef struct SimpleSpiceDisplay SimpleSpiceDisplay;
Justin M. Forbes 13f703
 typedef struct SimpleSpiceUpdate SimpleSpiceUpdate;
Justin M. Forbes 13f703
 
Justin M. Forbes 13f703
@@ -82,12 +96,15 @@ void qemu_spice_display_update(SimpleSpiceDisplay *ssd,
Justin M. Forbes 13f703
 void qemu_spice_display_resize(SimpleSpiceDisplay *ssd);
Justin M. Forbes 13f703
 void qemu_spice_display_refresh(SimpleSpiceDisplay *ssd);
Justin M. Forbes 13f703
 
Justin M. Forbes 13f703
-void qemu_spice_add_memslot(SimpleSpiceDisplay *ssd, QXLDevMemSlot *memslot);
Justin M. Forbes 13f703
+void qemu_spice_add_memslot(SimpleSpiceDisplay *ssd, QXLDevMemSlot *memslot,
Justin M. Forbes 13f703
+                            qxl_async_io async);
Justin M. Forbes 13f703
 void qemu_spice_del_memslot(SimpleSpiceDisplay *ssd, uint32_t gid,
Justin M. Forbes 13f703
                             uint32_t sid);
Justin M. Forbes 13f703
 void qemu_spice_create_primary_surface(SimpleSpiceDisplay *ssd, uint32_t id,
Justin M. Forbes 13f703
-                                       QXLDevSurfaceCreate *surface);
Justin M. Forbes 13f703
-void qemu_spice_destroy_primary_surface(SimpleSpiceDisplay *ssd, uint32_t id);
Justin M. Forbes 13f703
+                                       QXLDevSurfaceCreate *surface,
Justin M. Forbes 13f703
+                                       qxl_async_io async);
Justin M. Forbes 13f703
+void qemu_spice_destroy_primary_surface(SimpleSpiceDisplay *ssd,
Justin M. Forbes 13f703
+                                        uint32_t id, qxl_async_io async);
Justin M. Forbes 13f703
 void qemu_spice_wakeup(SimpleSpiceDisplay *ssd);
Justin M. Forbes 13f703
 void qemu_spice_start(SimpleSpiceDisplay *ssd);
Justin M. Forbes 13f703
 void qemu_spice_stop(SimpleSpiceDisplay *ssd);
Justin M. Forbes 13f703
-- 
Justin M. Forbes 13f703
1.7.5.1
Justin M. Forbes 13f703