All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH] async + suspend reworked
@ 2011-07-06 12:19 Alon Levy
  2011-07-06 12:19 ` [Qemu-devel] [PATCH] qxl: add defines from latest spice-protocol Alon Levy
                   ` (16 more replies)
  0 siblings, 17 replies; 26+ messages in thread
From: Alon Levy @ 2011-07-06 12:19 UTC (permalink / raw)
  To: qemu-devel; +Cc: yhalperi, kraxel

Counting suspend this is v4, counting async this is v1 (after Gerd's RfC, iirc).

Everything is based on spice.v38 from git://anongit.freedesktop.org/spice/qemu

Gerd, there are some changes to your patches:
 qxl: add defines from latest spice-protocol:
  I redefined QXL_IO_RANGE_SIZE in the same time, so no need to change
  the msb_mask line later.
 qxl: async I/O
  this is the main change, I removed the thread like we discussed, using the new api
  available from the spice patches here 1309952376-29961-1-git-send-email-alevy@redhat.com
  ([PATCH] async and s3 support)

The last patch is questionable, "qxl: use QXL_REVISION_*" and I don't feel too strongly about
it, if there is a good reason why qxl->revision should not be == pci_revision.

Alon Levy (5):
  qxl: add io_port_to_string
  qxl: make qxl_guest_bug take variable arguments
  qxl: only disallow specific io's in vga mode
  qxl: add QXL_IO_FLUSH_{SURFACES,RELEASE} for guest S3&S4 support
  qxl: use QXL_REVISION_*

Gerd Hoffmann (12):
  qxl: add defines from latest spice-protocol.
  spice: add worker wrapper functions.
  spice: add qemu_spice_display_init_common
  spice: lock spice worker calls
  qxl: move qemu_spice_add_memslot call out of qxl_add_memslot
  qxl: move qemu_spice_create_primary_surface call out of
    qxl_create_guest_primary
  qxl: remove qxl_destroy_primary()
  spice/qxl: move worker wrappers
  qxl: fix surface tracking & locking
  qxl: error handling fixes and cleanups.
  qxl: async I/O
  qxl: bump pci rev

 hw/qxl-render.c    |    4 +-
 hw/qxl.c           |  480 ++++++++++++++++++++++++++++++++++++++++++----------
 hw/qxl.h           |   29 +++-
 ui/spice-display.c |  109 +++++++++++--
 ui/spice-display.h |   15 ++
 5 files changed, 534 insertions(+), 103 deletions(-)

-- 
1.7.5.4

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

* [Qemu-devel] [PATCH] qxl: add defines from latest spice-protocol.
  2011-07-06 12:19 [Qemu-devel] [PATCH] async + suspend reworked Alon Levy
@ 2011-07-06 12:19 ` Alon Levy
  2011-07-07  7:33   ` Gerd Hoffmann
  2011-07-06 12:19 ` [Qemu-devel] [PATCH] spice: add worker wrapper functions Alon Levy
                   ` (15 subsequent siblings)
  16 siblings, 1 reply; 26+ messages in thread
From: Alon Levy @ 2011-07-06 12:19 UTC (permalink / raw)
  To: qemu-devel; +Cc: yhalperi, kraxel

From: Gerd Hoffmann <kraxel@redhat.com>

Allows to build with older spice-protocol versions.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 hw/qxl.c |   15 +++++++++++++++
 1 files changed, 15 insertions(+), 0 deletions(-)

diff --git a/hw/qxl.c b/hw/qxl.c
index 0b9a4c7..6be54c4 100644
--- a/hw/qxl.c
+++ b/hw/qxl.c
@@ -28,6 +28,21 @@
 
 #include "qxl.h"
 
+/* old spice-protocol */
+#ifndef QXL_INTERRUPT_IO_CMD
+#define QXL_INTERRUPT_IO_CMD               (1 << 2)
+#define QXL_INTERRUPT_ERROR                (1 << 3)
+#define QXL_IO_UPDATE_AREA_ASYNC           (QXL_IO_DESTROY_ALL_SURFACES +1)
+#define QXL_IO_NOTIFY_OOM_ASYNC            (QXL_IO_DESTROY_ALL_SURFACES +2)
+#define QXL_IO_MEMSLOT_ADD_ASYNC           (QXL_IO_DESTROY_ALL_SURFACES +3)
+#define QXL_IO_CREATE_PRIMARY_ASYNC        (QXL_IO_DESTROY_ALL_SURFACES +4)
+#define QXL_IO_DESTROY_PRIMARY_ASYNC       (QXL_IO_DESTROY_ALL_SURFACES +5)
+#define QXL_IO_DESTROY_SURFACE_ASYNC       (QXL_IO_DESTROY_ALL_SURFACES +6)
+#define QXL_IO_DESTROY_ALL_SURFACES_ASYNC  (QXL_IO_DESTROY_ALL_SURFACES +7)
+#undef QXL_IO_RANGE_SIZE
+#define QXL_IO_RANGE_SIZE (QXL_IO_DESTROY_ALL_SURFACES + 8)
+#endif
+
 #undef SPICE_RING_PROD_ITEM
 #define SPICE_RING_PROD_ITEM(r, ret) {                                  \
         typeof(r) start = r;                                            \
-- 
1.7.5.4

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

* [Qemu-devel] [PATCH] spice: add worker wrapper functions.
  2011-07-06 12:19 [Qemu-devel] [PATCH] async + suspend reworked Alon Levy
  2011-07-06 12:19 ` [Qemu-devel] [PATCH] qxl: add defines from latest spice-protocol Alon Levy
@ 2011-07-06 12:19 ` Alon Levy
  2011-07-06 12:19 ` [Qemu-devel] [PATCH] spice: add qemu_spice_display_init_common Alon Levy
                   ` (14 subsequent siblings)
  16 siblings, 0 replies; 26+ messages in thread
From: Alon Levy @ 2011-07-06 12:19 UTC (permalink / raw)
  To: qemu-devel; +Cc: yhalperi, kraxel

From: Gerd Hoffmann <kraxel@redhat.com>

Add wrapper functions for all spice worker calls.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 hw/qxl-render.c    |    4 +-
 hw/qxl.c           |   32 +++++++++---------
 ui/spice-display.c |   94 ++++++++++++++++++++++++++++++++++++++++++++++++---
 ui/spice-display.h |   20 +++++++++++
 4 files changed, 126 insertions(+), 24 deletions(-)

diff --git a/hw/qxl-render.c b/hw/qxl-render.c
index 1316066..bef5f14 100644
--- a/hw/qxl-render.c
+++ b/hw/qxl-render.c
@@ -124,8 +124,8 @@ void qxl_render_update(PCIQXLDevice *qxl)
     update.bottom = qxl->guest_primary.surface.height;
 
     memset(dirty, 0, sizeof(dirty));
-    qxl->ssd.worker->update_area(qxl->ssd.worker, 0, &update,
-                                 dirty, ARRAY_SIZE(dirty), 1);
+    qemu_spice_update_area(&qxl->ssd, 0, &update,
+                           dirty, ARRAY_SIZE(dirty), 1);
 
     for (i = 0; i < ARRAY_SIZE(dirty); i++) {
         if (qemu_spice_rect_is_empty(dirty+i)) {
diff --git a/hw/qxl.c b/hw/qxl.c
index 6be54c4..7dac93c 100644
--- a/hw/qxl.c
+++ b/hw/qxl.c
@@ -699,8 +699,8 @@ static void qxl_hard_reset(PCIQXLDevice *d, int loadvm)
     dprint(d, 1, "%s: start%s\n", __FUNCTION__,
            loadvm ? " (loadvm)" : "");
 
-    d->ssd.worker->reset_cursor(d->ssd.worker);
-    d->ssd.worker->reset_image_cache(d->ssd.worker);
+    qemu_spice_reset_cursor(&d->ssd);
+    qemu_spice_reset_image_cache(&d->ssd);
     qxl_reset_surfaces(d);
     qxl_reset_memslots(d);
 
@@ -805,7 +805,7 @@ static void qxl_add_memslot(PCIQXLDevice *d, uint32_t slot_id, uint64_t delta)
            __FUNCTION__, memslot.slot_id,
            memslot.virt_start, memslot.virt_end);
 
-    d->ssd.worker->add_memslot(d->ssd.worker, &memslot);
+    qemu_spice_add_memslot(&d->ssd, &memslot);
     d->guest_slots[slot_id].ptr = (void*)memslot.virt_start;
     d->guest_slots[slot_id].size = memslot.virt_end - memslot.virt_start;
     d->guest_slots[slot_id].delta = delta;
@@ -815,14 +815,14 @@ static void qxl_add_memslot(PCIQXLDevice *d, uint32_t slot_id, uint64_t delta)
 static void qxl_del_memslot(PCIQXLDevice *d, uint32_t slot_id)
 {
     dprint(d, 1, "%s: slot %d\n", __FUNCTION__, slot_id);
-    d->ssd.worker->del_memslot(d->ssd.worker, MEMSLOT_GROUP_HOST, slot_id);
+    qemu_spice_del_memslot(&d->ssd, MEMSLOT_GROUP_HOST, slot_id);
     d->guest_slots[slot_id].active = 0;
 }
 
 static void qxl_reset_memslots(PCIQXLDevice *d)
 {
     dprint(d, 1, "%s:\n", __FUNCTION__);
-    d->ssd.worker->reset_memslots(d->ssd.worker);
+    qemu_spice_reset_memslots(&d->ssd);
     memset(&d->guest_slots, 0, sizeof(d->guest_slots));
 }
 
@@ -830,7 +830,7 @@ static void qxl_reset_surfaces(PCIQXLDevice *d)
 {
     dprint(d, 1, "%s:\n", __FUNCTION__);
     d->mode = QXL_MODE_UNDEFINED;
-    d->ssd.worker->destroy_surfaces(d->ssd.worker);
+    qemu_spice_destroy_surfaces(&d->ssd);
     memset(&d->guest_surfaces.cmds, 0, sizeof(d->guest_surfaces.cmds));
 }
 
@@ -884,7 +884,7 @@ static void qxl_create_guest_primary(PCIQXLDevice *qxl, int loadvm)
 
     qxl->mode = QXL_MODE_NATIVE;
     qxl->cmdflags = 0;
-    qxl->ssd.worker->create_primary_surface(qxl->ssd.worker, 0, &surface);
+    qemu_spice_create_primary_surface(&qxl->ssd, 0, &surface);
 
     /* for local rendering */
     qxl_render_resize(qxl);
@@ -899,7 +899,7 @@ static void qxl_destroy_primary(PCIQXLDevice *d)
     dprint(d, 1, "%s\n", __FUNCTION__);
 
     d->mode = QXL_MODE_UNDEFINED;
-    d->ssd.worker->destroy_primary_surface(d->ssd.worker, 0);
+    qemu_spice_destroy_primary_surface(&d->ssd, 0);
 }
 
 static void qxl_set_mode(PCIQXLDevice *d, int modenr, int loadvm)
@@ -971,15 +971,15 @@ static void ioport_write(void *opaque, uint32_t addr, uint32_t val)
     case QXL_IO_UPDATE_AREA:
     {
         QXLRect update = d->ram->update_area;
-        d->ssd.worker->update_area(d->ssd.worker, d->ram->update_surface,
-                                   &update, NULL, 0, 0);
+        qemu_spice_update_area(&d->ssd, d->ram->update_surface,
+                               &update, NULL, 0, 0);
         break;
     }
     case QXL_IO_NOTIFY_CMD:
-        d->ssd.worker->wakeup(d->ssd.worker);
+        qemu_spice_wakeup(&d->ssd);
         break;
     case QXL_IO_NOTIFY_CURSOR:
-        d->ssd.worker->wakeup(d->ssd.worker);
+        qemu_spice_wakeup(&d->ssd);
         break;
     case QXL_IO_UPDATE_IRQ:
         qxl_set_irq(d);
@@ -993,7 +993,7 @@ static void ioport_write(void *opaque, uint32_t addr, uint32_t val)
             break;
         }
         d->oom_running = 1;
-        d->ssd.worker->oom(d->ssd.worker);
+        qemu_spice_oom(&d->ssd);
         d->oom_running = 0;
         break;
     case QXL_IO_SET_MODE:
@@ -1031,10 +1031,10 @@ static void ioport_write(void *opaque, uint32_t addr, uint32_t val)
         qxl_destroy_primary(d);
         break;
     case QXL_IO_DESTROY_SURFACE_WAIT:
-        d->ssd.worker->destroy_surface_wait(d->ssd.worker, val);
+        qemu_spice_destroy_surface_wait(&d->ssd, val);
         break;
     case QXL_IO_DESTROY_ALL_SURFACES:
-        d->ssd.worker->destroy_surfaces(d->ssd.worker);
+        qemu_spice_destroy_surfaces(&d->ssd);
         break;
     default:
         fprintf(stderr, "%s: ioport=0x%x, abort()\n", __FUNCTION__, io_port);
@@ -1439,7 +1439,7 @@ static int qxl_post_load(void *opaque, int version)
         cmds[out].cmd.type = QXL_CMD_CURSOR;
         cmds[out].group_id = MEMSLOT_GROUP_GUEST;
         out++;
-        d->ssd.worker->loadvm_commands(d->ssd.worker, cmds, out);
+        qemu_spice_loadvm_commands(&d->ssd, cmds, out);
         qemu_free(cmds);
 
         break;
diff --git a/ui/spice-display.c b/ui/spice-display.c
index feeee73..0433ea8 100644
--- a/ui/spice-display.c
+++ b/ui/spice-display.c
@@ -62,6 +62,88 @@ void qemu_spice_rect_union(QXLRect *dest, const QXLRect *r)
     dest->right = MAX(dest->right, r->right);
 }
 
+
+void qemu_spice_update_area(SimpleSpiceDisplay *ssd, uint32_t surface_id,
+                            struct QXLRect *area, struct QXLRect *dirty_rects,
+                            uint32_t num_dirty_rects, uint32_t clear_dirty_region)
+{
+    ssd->worker->update_area(ssd->worker, surface_id, area, dirty_rects,
+                             num_dirty_rects, clear_dirty_region);
+}
+
+void qemu_spice_add_memslot(SimpleSpiceDisplay *ssd, QXLDevMemSlot *memslot)
+{
+    ssd->worker->add_memslot(ssd->worker, memslot);
+}
+
+void qemu_spice_del_memslot(SimpleSpiceDisplay *ssd, uint32_t gid, uint32_t sid)
+{
+    ssd->worker->del_memslot(ssd->worker, gid, sid);
+}
+
+void qemu_spice_create_primary_surface(SimpleSpiceDisplay *ssd, uint32_t id,
+                                       QXLDevSurfaceCreate *surface)
+{
+    ssd->worker->create_primary_surface(ssd->worker, id, surface);
+}
+
+void qemu_spice_destroy_primary_surface(SimpleSpiceDisplay *ssd, uint32_t id)
+{
+    ssd->worker->destroy_primary_surface(ssd->worker, id);
+}
+
+void qemu_spice_destroy_surface_wait(SimpleSpiceDisplay *ssd, uint32_t id)
+{
+    ssd->worker->destroy_surface_wait(ssd->worker, id);
+}
+
+void qemu_spice_loadvm_commands(SimpleSpiceDisplay *ssd, struct QXLCommandExt *ext,
+                                uint32_t count)
+{
+    ssd->worker->loadvm_commands(ssd->worker, ext, count);
+}
+
+void qemu_spice_wakeup(SimpleSpiceDisplay *ssd)
+{
+    ssd->worker->wakeup(ssd->worker);
+}
+
+void qemu_spice_oom(SimpleSpiceDisplay *ssd)
+{
+    ssd->worker->oom(ssd->worker);
+}
+
+void qemu_spice_start(SimpleSpiceDisplay *ssd)
+{
+    ssd->worker->start(ssd->worker);
+}
+
+void qemu_spice_stop(SimpleSpiceDisplay *ssd)
+{
+    ssd->worker->stop(ssd->worker);
+}
+
+void qemu_spice_reset_memslots(SimpleSpiceDisplay *ssd)
+{
+    ssd->worker->reset_memslots(ssd->worker);
+}
+
+void qemu_spice_destroy_surfaces(SimpleSpiceDisplay *ssd)
+{
+    ssd->worker->destroy_surfaces(ssd->worker);
+}
+
+void qemu_spice_reset_image_cache(SimpleSpiceDisplay *ssd)
+{
+    ssd->worker->reset_image_cache(ssd->worker);
+}
+
+void qemu_spice_reset_cursor(SimpleSpiceDisplay *ssd)
+{
+    ssd->worker->reset_cursor(ssd->worker);
+}
+
+
 static SimpleSpiceUpdate *qemu_spice_create_update(SimpleSpiceDisplay *ssd)
 {
     SimpleSpiceUpdate *update;
@@ -161,7 +243,7 @@ void qemu_spice_create_host_memslot(SimpleSpiceDisplay *ssd)
     memset(&memslot, 0, sizeof(memslot));
     memslot.slot_group_id = MEMSLOT_GROUP_HOST;
     memslot.virt_end = ~0;
-    ssd->worker->add_memslot(ssd->worker, &memslot);
+    qemu_spice_add_memslot(ssd, &memslot);
 }
 
 void qemu_spice_create_host_primary(SimpleSpiceDisplay *ssd)
@@ -181,14 +263,14 @@ void qemu_spice_create_host_primary(SimpleSpiceDisplay *ssd)
     surface.mem        = (intptr_t)ssd->buf;
     surface.group_id   = MEMSLOT_GROUP_HOST;
 
-    ssd->worker->create_primary_surface(ssd->worker, 0, &surface);
+    qemu_spice_create_primary_surface(ssd, 0, &surface);
 }
 
 void qemu_spice_destroy_host_primary(SimpleSpiceDisplay *ssd)
 {
     dprint(1, "%s:\n", __FUNCTION__);
 
-    ssd->worker->destroy_primary_surface(ssd->worker, 0);
+    qemu_spice_destroy_primary_surface(ssd, 0);
 }
 
 void qemu_spice_vm_change_state_handler(void *opaque, int running, int reason)
@@ -196,9 +278,9 @@ void qemu_spice_vm_change_state_handler(void *opaque, int running, int reason)
     SimpleSpiceDisplay *ssd = opaque;
 
     if (running) {
-        ssd->worker->start(ssd->worker);
+        qemu_spice_start(ssd);
     } else {
-        ssd->worker->stop(ssd->worker);
+        qemu_spice_stop(ssd);
     }
     ssd->running = running;
 }
@@ -267,7 +349,7 @@ void qemu_spice_display_refresh(SimpleSpiceDisplay *ssd)
 
     if (ssd->notify) {
         ssd->notify = 0;
-        ssd->worker->wakeup(ssd->worker);
+        qemu_spice_wakeup(ssd);
         dprint(2, "%s: notify\n", __FUNCTION__);
     }
 }
diff --git a/ui/spice-display.h b/ui/spice-display.h
index 2f95f68..0effdfa 100644
--- a/ui/spice-display.h
+++ b/ui/spice-display.h
@@ -80,3 +80,23 @@ void qemu_spice_display_update(SimpleSpiceDisplay *ssd,
                                int x, int y, int w, int h);
 void qemu_spice_display_resize(SimpleSpiceDisplay *ssd);
 void qemu_spice_display_refresh(SimpleSpiceDisplay *ssd);
+
+void qemu_spice_update_area(SimpleSpiceDisplay *ssd, uint32_t surface_id,
+                            struct QXLRect *area, struct QXLRect *dirty_rects,
+                            uint32_t num_dirty_rects, uint32_t clear_dirty_region);
+void qemu_spice_add_memslot(SimpleSpiceDisplay *ssd, QXLDevMemSlot *memslot);
+void qemu_spice_del_memslot(SimpleSpiceDisplay *ssd, uint32_t gid, uint32_t sid);
+void qemu_spice_create_primary_surface(SimpleSpiceDisplay *ssd, uint32_t id,
+                                       QXLDevSurfaceCreate *surface);
+void qemu_spice_destroy_primary_surface(SimpleSpiceDisplay *ssd, uint32_t id);
+void qemu_spice_destroy_surface_wait(SimpleSpiceDisplay *ssd, uint32_t id);
+void qemu_spice_loadvm_commands(SimpleSpiceDisplay *ssd, struct QXLCommandExt *ext,
+                                uint32_t count);
+void qemu_spice_wakeup(SimpleSpiceDisplay *ssd);
+void qemu_spice_oom(SimpleSpiceDisplay *ssd);
+void qemu_spice_start(SimpleSpiceDisplay *ssd);
+void qemu_spice_stop(SimpleSpiceDisplay *ssd);
+void qemu_spice_reset_memslots(SimpleSpiceDisplay *ssd);
+void qemu_spice_destroy_surfaces(SimpleSpiceDisplay *ssd);
+void qemu_spice_reset_image_cache(SimpleSpiceDisplay *ssd);
+void qemu_spice_reset_cursor(SimpleSpiceDisplay *ssd);
-- 
1.7.5.4

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

* [Qemu-devel] [PATCH] spice: add qemu_spice_display_init_common
  2011-07-06 12:19 [Qemu-devel] [PATCH] async + suspend reworked Alon Levy
  2011-07-06 12:19 ` [Qemu-devel] [PATCH] qxl: add defines from latest spice-protocol Alon Levy
  2011-07-06 12:19 ` [Qemu-devel] [PATCH] spice: add worker wrapper functions Alon Levy
@ 2011-07-06 12:19 ` Alon Levy
  2011-07-06 12:19 ` [Qemu-devel] [PATCH] spice: lock spice worker calls Alon Levy
                   ` (13 subsequent siblings)
  16 siblings, 0 replies; 26+ messages in thread
From: Alon Levy @ 2011-07-06 12:19 UTC (permalink / raw)
  To: qemu-devel; +Cc: yhalperi, kraxel

From: Gerd Hoffmann <kraxel@redhat.com>

Factor out SimpleSpiceDisplay initialization into
qemu_spice_display_init_common() and call it from
both qxl.c (for vga mode) and spice-display.c

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 hw/qxl.c           |    7 +------
 ui/spice-display.c |   17 +++++++++++------
 ui/spice-display.h |    1 +
 3 files changed, 13 insertions(+), 12 deletions(-)

diff --git a/hw/qxl.c b/hw/qxl.c
index 7dac93c..bbba25d 100644
--- a/hw/qxl.c
+++ b/hw/qxl.c
@@ -1330,12 +1330,7 @@ static int qxl_init_primary(PCIDevice *dev)
 
     vga->ds = graphic_console_init(qxl_hw_update, qxl_hw_invalidate,
                                    qxl_hw_screen_dump, qxl_hw_text_update, qxl);
-    qxl->ssd.ds = vga->ds;
-    qemu_mutex_init(&qxl->ssd.lock);
-    qxl->ssd.mouse_x = -1;
-    qxl->ssd.mouse_y = -1;
-    qxl->ssd.bufsize = (16 * 1024 * 1024);
-    qxl->ssd.buf = qemu_malloc(qxl->ssd.bufsize);
+    qemu_spice_display_init_common(&qxl->ssd, vga->ds);
 
     qxl0 = qxl;
     register_displaychangelistener(vga->ds, &display_listener);
diff --git a/ui/spice-display.c b/ui/spice-display.c
index 0433ea8..fef1758 100644
--- a/ui/spice-display.c
+++ b/ui/spice-display.c
@@ -285,6 +285,16 @@ void qemu_spice_vm_change_state_handler(void *opaque, int running, int reason)
     ssd->running = running;
 }
 
+void qemu_spice_display_init_common(SimpleSpiceDisplay *ssd, DisplayState *ds)
+{
+    ssd->ds = ds;
+    qemu_mutex_init(&ssd->lock);
+    ssd->mouse_x = -1;
+    ssd->mouse_y = -1;
+    ssd->bufsize = (16 * 1024 * 1024);
+    ssd->buf = qemu_malloc(ssd->bufsize);
+}
+
 /* display listener callbacks */
 
 void qemu_spice_display_update(SimpleSpiceDisplay *ssd,
@@ -498,12 +508,7 @@ static DisplayChangeListener display_listener = {
 void qemu_spice_display_init(DisplayState *ds)
 {
     assert(sdpy.ds == NULL);
-    sdpy.ds = ds;
-    qemu_mutex_init(&sdpy.lock);
-    sdpy.mouse_x = -1;
-    sdpy.mouse_y = -1;
-    sdpy.bufsize = (16 * 1024 * 1024);
-    sdpy.buf = qemu_malloc(sdpy.bufsize);
+    qemu_spice_display_init_common(&sdpy, ds);
     register_displaychangelistener(ds, &display_listener);
 
     sdpy.qxl.base.sif = &dpy_interface.base;
diff --git a/ui/spice-display.h b/ui/spice-display.h
index 0effdfa..a39b19d 100644
--- a/ui/spice-display.h
+++ b/ui/spice-display.h
@@ -75,6 +75,7 @@ void qemu_spice_create_host_memslot(SimpleSpiceDisplay *ssd);
 void qemu_spice_create_host_primary(SimpleSpiceDisplay *ssd);
 void qemu_spice_destroy_host_primary(SimpleSpiceDisplay *ssd);
 void qemu_spice_vm_change_state_handler(void *opaque, int running, int reason);
+void qemu_spice_display_init_common(SimpleSpiceDisplay *ssd, DisplayState *ds);
 
 void qemu_spice_display_update(SimpleSpiceDisplay *ssd,
                                int x, int y, int w, int h);
-- 
1.7.5.4

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

* [Qemu-devel] [PATCH] spice: lock spice worker calls
  2011-07-06 12:19 [Qemu-devel] [PATCH] async + suspend reworked Alon Levy
                   ` (2 preceding siblings ...)
  2011-07-06 12:19 ` [Qemu-devel] [PATCH] spice: add qemu_spice_display_init_common Alon Levy
@ 2011-07-06 12:19 ` Alon Levy
  2011-07-07  7:40   ` Gerd Hoffmann
  2011-07-06 12:19 ` [Qemu-devel] [PATCH] qxl: move qemu_spice_add_memslot call out of qxl_add_memslot Alon Levy
                   ` (12 subsequent siblings)
  16 siblings, 1 reply; 26+ messages in thread
From: Alon Levy @ 2011-07-06 12:19 UTC (permalink / raw)
  To: qemu-devel; +Cc: yhalperi, kraxel

From: Gerd Hoffmann <kraxel@redhat.com>

... so we can call them from a thread.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 ui/spice-display.c |   31 +++++++++++++++++++++++++++++++
 ui/spice-display.h |    1 +
 2 files changed, 32 insertions(+), 0 deletions(-)

diff --git a/ui/spice-display.c b/ui/spice-display.c
index fef1758..93ebc19 100644
--- a/ui/spice-display.c
+++ b/ui/spice-display.c
@@ -67,80 +67,110 @@ void qemu_spice_update_area(SimpleSpiceDisplay *ssd, uint32_t surface_id,
                             struct QXLRect *area, struct QXLRect *dirty_rects,
                             uint32_t num_dirty_rects, uint32_t clear_dirty_region)
 {
+    qemu_mutex_lock(&ssd->wlock);
     ssd->worker->update_area(ssd->worker, surface_id, area, dirty_rects,
                              num_dirty_rects, clear_dirty_region);
+    qemu_mutex_unlock(&ssd->wlock);
 }
 
 void qemu_spice_add_memslot(SimpleSpiceDisplay *ssd, QXLDevMemSlot *memslot)
 {
+    qemu_mutex_lock(&ssd->wlock);
     ssd->worker->add_memslot(ssd->worker, memslot);
+    qemu_mutex_unlock(&ssd->wlock);
 }
 
 void qemu_spice_del_memslot(SimpleSpiceDisplay *ssd, uint32_t gid, uint32_t sid)
 {
+    qemu_mutex_lock(&ssd->wlock);
     ssd->worker->del_memslot(ssd->worker, gid, sid);
+    qemu_mutex_unlock(&ssd->wlock);
 }
 
 void qemu_spice_create_primary_surface(SimpleSpiceDisplay *ssd, uint32_t id,
                                        QXLDevSurfaceCreate *surface)
 {
+    qemu_mutex_lock(&ssd->wlock);
     ssd->worker->create_primary_surface(ssd->worker, id, surface);
+    qemu_mutex_unlock(&ssd->wlock);
 }
 
 void qemu_spice_destroy_primary_surface(SimpleSpiceDisplay *ssd, uint32_t id)
 {
+    qemu_mutex_lock(&ssd->wlock);
     ssd->worker->destroy_primary_surface(ssd->worker, id);
+    qemu_mutex_unlock(&ssd->wlock);
 }
 
 void qemu_spice_destroy_surface_wait(SimpleSpiceDisplay *ssd, uint32_t id)
 {
+    qemu_mutex_lock(&ssd->wlock);
     ssd->worker->destroy_surface_wait(ssd->worker, id);
+    qemu_mutex_unlock(&ssd->wlock);
 }
 
 void qemu_spice_loadvm_commands(SimpleSpiceDisplay *ssd, struct QXLCommandExt *ext,
                                 uint32_t count)
 {
+    qemu_mutex_lock(&ssd->wlock);
     ssd->worker->loadvm_commands(ssd->worker, ext, count);
+    qemu_mutex_unlock(&ssd->wlock);
 }
 
 void qemu_spice_wakeup(SimpleSpiceDisplay *ssd)
 {
+    qemu_mutex_lock(&ssd->wlock);
     ssd->worker->wakeup(ssd->worker);
+    qemu_mutex_unlock(&ssd->wlock);
 }
 
 void qemu_spice_oom(SimpleSpiceDisplay *ssd)
 {
+    qemu_mutex_lock(&ssd->wlock);
     ssd->worker->oom(ssd->worker);
+    qemu_mutex_unlock(&ssd->wlock);
 }
 
 void qemu_spice_start(SimpleSpiceDisplay *ssd)
 {
+    qemu_mutex_lock(&ssd->wlock);
     ssd->worker->start(ssd->worker);
+    qemu_mutex_unlock(&ssd->wlock);
 }
 
 void qemu_spice_stop(SimpleSpiceDisplay *ssd)
 {
+    qemu_mutex_lock(&ssd->wlock);
     ssd->worker->stop(ssd->worker);
+    qemu_mutex_unlock(&ssd->wlock);
 }
 
 void qemu_spice_reset_memslots(SimpleSpiceDisplay *ssd)
 {
+    qemu_mutex_lock(&ssd->wlock);
     ssd->worker->reset_memslots(ssd->worker);
+    qemu_mutex_unlock(&ssd->wlock);
 }
 
 void qemu_spice_destroy_surfaces(SimpleSpiceDisplay *ssd)
 {
+    qemu_mutex_lock(&ssd->wlock);
     ssd->worker->destroy_surfaces(ssd->worker);
+    qemu_mutex_unlock(&ssd->wlock);
 }
 
 void qemu_spice_reset_image_cache(SimpleSpiceDisplay *ssd)
 {
+    qemu_mutex_lock(&ssd->wlock);
     ssd->worker->reset_image_cache(ssd->worker);
+    qemu_mutex_unlock(&ssd->wlock);
 }
 
 void qemu_spice_reset_cursor(SimpleSpiceDisplay *ssd)
 {
+    qemu_mutex_lock(&ssd->wlock);
     ssd->worker->reset_cursor(ssd->worker);
+    qemu_mutex_unlock(&ssd->wlock);
 }
 
 
@@ -289,6 +319,7 @@ void qemu_spice_display_init_common(SimpleSpiceDisplay *ssd, DisplayState *ds)
 {
     ssd->ds = ds;
     qemu_mutex_init(&ssd->lock);
+    qemu_mutex_init(&ssd->wlock);
     ssd->mouse_x = -1;
     ssd->mouse_y = -1;
     ssd->bufsize = (16 * 1024 * 1024);
diff --git a/ui/spice-display.h b/ui/spice-display.h
index a39b19d..3968d75 100644
--- a/ui/spice-display.h
+++ b/ui/spice-display.h
@@ -41,6 +41,7 @@ struct SimpleSpiceDisplay {
     void *buf;
     int bufsize;
     QXLWorker *worker;
+    QemuMutex wlock;
     QXLInstance qxl;
     uint32_t unique;
     QemuPfConv *conv;
-- 
1.7.5.4

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

* [Qemu-devel] [PATCH] qxl: move qemu_spice_add_memslot call out of qxl_add_memslot
  2011-07-06 12:19 [Qemu-devel] [PATCH] async + suspend reworked Alon Levy
                   ` (3 preceding siblings ...)
  2011-07-06 12:19 ` [Qemu-devel] [PATCH] spice: lock spice worker calls Alon Levy
@ 2011-07-06 12:19 ` Alon Levy
  2011-07-07  7:39   ` Gerd Hoffmann
  2011-07-06 12:19 ` [Qemu-devel] [PATCH] qxl: move qemu_spice_create_primary_surface call out of qxl_create_guest_primary Alon Levy
                   ` (11 subsequent siblings)
  16 siblings, 1 reply; 26+ messages in thread
From: Alon Levy @ 2011-07-06 12:19 UTC (permalink / raw)
  To: qemu-devel; +Cc: yhalperi, kraxel

From: Gerd Hoffmann <kraxel@redhat.com>

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 hw/qxl.c |   40 ++++++++++++++++++++++++----------------
 1 files changed, 24 insertions(+), 16 deletions(-)

diff --git a/hw/qxl.c b/hw/qxl.c
index bbba25d..26f80d5 100644
--- a/hw/qxl.c
+++ b/hw/qxl.c
@@ -735,7 +735,8 @@ static void qxl_vga_ioport_write(void *opaque, uint32_t addr, uint32_t val)
     vga_ioport_write(opaque, addr, val);
 }
 
-static void qxl_add_memslot(PCIQXLDevice *d, uint32_t slot_id, uint64_t delta)
+static void qxl_add_memslot(PCIQXLDevice *d, uint32_t slot_id, uint64_t delta,
+                            QXLDevMemSlot *memslot)
 {
     static const int regions[] = {
         QXL_RAM_RANGE_INDEX,
@@ -747,7 +748,6 @@ static void qxl_add_memslot(PCIQXLDevice *d, uint32_t slot_id, uint64_t delta)
     pcibus_t pci_start;
     pcibus_t pci_end;
     intptr_t virt_start;
-    QXLDevMemSlot memslot;
     int i;
 
     guest_start = le64_to_cpu(d->guest_slots[slot_id].slot.mem_start);
@@ -793,21 +793,20 @@ static void qxl_add_memslot(PCIQXLDevice *d, uint32_t slot_id, uint64_t delta)
         abort();
     }
 
-    memslot.slot_id = slot_id;
-    memslot.slot_group_id = MEMSLOT_GROUP_GUEST; /* guest group */
-    memslot.virt_start = virt_start + (guest_start - pci_start);
-    memslot.virt_end   = virt_start + (guest_end   - pci_start);
-    memslot.addr_delta = memslot.virt_start - delta;
-    memslot.generation = d->rom->slot_generation = 0;
+    memslot->slot_id = slot_id;
+    memslot->slot_group_id = MEMSLOT_GROUP_GUEST; /* guest group */
+    memslot->virt_start = virt_start + (guest_start - pci_start);
+    memslot->virt_end   = virt_start + (guest_end   - pci_start);
+    memslot->addr_delta = memslot->virt_start - delta;
+    memslot->generation = d->rom->slot_generation = 0;
     qxl_rom_set_dirty(d);
 
     dprint(d, 1, "%s: slot %d: host virt 0x%" PRIx64 " - 0x%" PRIx64 "\n",
-           __FUNCTION__, memslot.slot_id,
-           memslot.virt_start, memslot.virt_end);
+           __FUNCTION__, memslot->slot_id,
+           memslot->virt_start, memslot->virt_end);
 
-    qemu_spice_add_memslot(&d->ssd, &memslot);
-    d->guest_slots[slot_id].ptr = (void*)memslot.virt_start;
-    d->guest_slots[slot_id].size = memslot.virt_end - memslot.virt_start;
+    d->guest_slots[slot_id].ptr = (void*)memslot->virt_start;
+    d->guest_slots[slot_id].size = memslot->virt_end - memslot->virt_start;
     d->guest_slots[slot_id].delta = delta;
     d->guest_slots[slot_id].active = 1;
 }
@@ -912,6 +911,7 @@ static void qxl_set_mode(PCIQXLDevice *d, int modenr, int loadvm)
         .mem_start = start,
         .mem_end = end
     };
+    QXLDevMemSlot memslot;
     QXLSurfaceCreate surface = {
         .width      = mode->x_res,
         .height     = mode->y_res,
@@ -929,7 +929,8 @@ static void qxl_set_mode(PCIQXLDevice *d, int modenr, int loadvm)
     }
 
     d->guest_slots[0].slot = slot;
-    qxl_add_memslot(d, 0, devmem);
+    qxl_add_memslot(d, 0, devmem, &memslot);
+    qemu_spice_add_memslot(&d->ssd, &memslot);
 
     d->guest_primary.surface = surface;
     qxl_create_guest_primary(d, 0);
@@ -1011,11 +1012,16 @@ static void ioport_write(void *opaque, uint32_t addr, uint32_t val)
         qxl_hard_reset(d, 0);
         break;
     case QXL_IO_MEMSLOT_ADD:
+    {
+        QXLDevMemSlot memslot;
+
         PANIC_ON(val >= NUM_MEMSLOTS);
         PANIC_ON(d->guest_slots[val].active);
         d->guest_slots[val].slot = d->ram->mem_slot;
-        qxl_add_memslot(d, val, 0);
+        qxl_add_memslot(d, val, 0, &memslot);
+        qemu_spice_add_memslot(&d->ssd, &memslot);
         break;
+    }
     case QXL_IO_MEMSLOT_DEL:
         qxl_del_memslot(d, val);
         break;
@@ -1387,6 +1393,7 @@ static int qxl_post_load(void *opaque, int version)
     PCIQXLDevice* d = opaque;
     uint8_t *ram_start = d->vga.vram_ptr;
     QXLCommandExt *cmds;
+    QXLDevMemSlot memslot;
     int in, out, i, newmode;
 
     dprint(d, 1, "%s: start\n", __FUNCTION__);
@@ -1415,7 +1422,8 @@ static int qxl_post_load(void *opaque, int version)
             if (!d->guest_slots[i].active) {
                 continue;
             }
-            qxl_add_memslot(d, i, 0);
+            qxl_add_memslot(d, i, 0, &memslot);
+            qemu_spice_add_memslot(&d->ssd, &memslot);
         }
         qxl_create_guest_primary(d, 1);
 
-- 
1.7.5.4

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

* [Qemu-devel] [PATCH] qxl: move qemu_spice_create_primary_surface call out of qxl_create_guest_primary
  2011-07-06 12:19 [Qemu-devel] [PATCH] async + suspend reworked Alon Levy
                   ` (4 preceding siblings ...)
  2011-07-06 12:19 ` [Qemu-devel] [PATCH] qxl: move qemu_spice_add_memslot call out of qxl_add_memslot Alon Levy
@ 2011-07-06 12:19 ` Alon Levy
  2011-07-06 12:19 ` [Qemu-devel] [PATCH] qxl: remove qxl_destroy_primary() Alon Levy
                   ` (10 subsequent siblings)
  16 siblings, 0 replies; 26+ messages in thread
From: Alon Levy @ 2011-07-06 12:19 UTC (permalink / raw)
  To: qemu-devel; +Cc: yhalperi, kraxel

From: Gerd Hoffmann <kraxel@redhat.com>

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 hw/qxl.c |   44 ++++++++++++++++++++++++++------------------
 1 files changed, 26 insertions(+), 18 deletions(-)

diff --git a/hw/qxl.c b/hw/qxl.c
index 26f80d5..22714bb 100644
--- a/hw/qxl.c
+++ b/hw/qxl.c
@@ -855,9 +855,9 @@ void *qxl_phys2virt(PCIQXLDevice *qxl, QXLPHYSICAL pqxl, int group_id)
     }
 }
 
-static void qxl_create_guest_primary(PCIQXLDevice *qxl, int loadvm)
+static void qxl_create_guest_primary(PCIQXLDevice *qxl, int loadvm,
+                                     QXLDevSurfaceCreate *surface)
 {
-    QXLDevSurfaceCreate surface;
     QXLSurfaceCreate *sc = &qxl->guest_primary.surface;
 
     assert(qxl->mode != QXL_MODE_NATIVE);
@@ -866,24 +866,23 @@ static void qxl_create_guest_primary(PCIQXLDevice *qxl, int loadvm)
     dprint(qxl, 1, "%s: %dx%d\n", __FUNCTION__,
            le32_to_cpu(sc->width), le32_to_cpu(sc->height));
 
-    surface.format     = le32_to_cpu(sc->format);
-    surface.height     = le32_to_cpu(sc->height);
-    surface.mem        = le64_to_cpu(sc->mem);
-    surface.position   = le32_to_cpu(sc->position);
-    surface.stride     = le32_to_cpu(sc->stride);
-    surface.width      = le32_to_cpu(sc->width);
-    surface.type       = le32_to_cpu(sc->type);
-    surface.flags      = le32_to_cpu(sc->flags);
-
-    surface.mouse_mode = true;
-    surface.group_id   = MEMSLOT_GROUP_GUEST;
+    surface->format     = le32_to_cpu(sc->format);
+    surface->height     = le32_to_cpu(sc->height);
+    surface->mem        = le64_to_cpu(sc->mem);
+    surface->position   = le32_to_cpu(sc->position);
+    surface->stride     = le32_to_cpu(sc->stride);
+    surface->width      = le32_to_cpu(sc->width);
+    surface->type       = le32_to_cpu(sc->type);
+    surface->flags      = le32_to_cpu(sc->flags);
+
+    surface->mouse_mode = true;
+    surface->group_id   = MEMSLOT_GROUP_GUEST;
     if (loadvm) {
-        surface.flags |= QXL_SURF_FLAG_KEEP_DATA;
+        surface->flags |= QXL_SURF_FLAG_KEEP_DATA;
     }
 
     qxl->mode = QXL_MODE_NATIVE;
     qxl->cmdflags = 0;
-    qemu_spice_create_primary_surface(&qxl->ssd, 0, &surface);
 
     /* for local rendering */
     qxl_render_resize(qxl);
@@ -921,6 +920,7 @@ static void qxl_set_mode(PCIQXLDevice *d, int modenr, int loadvm)
         .mouse_mode = true,
         .mem        = devmem + d->shadow_rom.draw_area_offset,
     };
+    QXLDevSurfaceCreate s;
 
     dprint(d, 1, "%s: mode %d  [ %d x %d @ %d bpp devmem 0x%lx ]\n", __FUNCTION__,
            modenr, mode->x_res, mode->y_res, mode->bits, devmem);
@@ -933,7 +933,8 @@ static void qxl_set_mode(PCIQXLDevice *d, int modenr, int loadvm)
     qemu_spice_add_memslot(&d->ssd, &memslot);
 
     d->guest_primary.surface = surface;
-    qxl_create_guest_primary(d, 0);
+    qxl_create_guest_primary(d, 0, &s);
+    qemu_spice_create_primary_surface(&d->ssd, 0, &s);
 
     d->mode = QXL_MODE_COMPAT;
     d->cmdflags = QXL_COMMAND_FLAG_COMPAT;
@@ -1026,11 +1027,16 @@ static void ioport_write(void *opaque, uint32_t addr, uint32_t val)
         qxl_del_memslot(d, val);
         break;
     case QXL_IO_CREATE_PRIMARY:
+    {
+        QXLDevSurfaceCreate surface;
+
         PANIC_ON(val != 0);
         dprint(d, 1, "QXL_IO_CREATE_PRIMARY\n");
         d->guest_primary.surface = d->ram->create_surface;
-        qxl_create_guest_primary(d, 0);
+        qxl_create_guest_primary(d, 0, &surface);
+        qemu_spice_create_primary_surface(&d->ssd, 0, &surface);
         break;
+    }
     case QXL_IO_DESTROY_PRIMARY:
         PANIC_ON(val != 0);
         dprint(d, 1, "QXL_IO_DESTROY_PRIMARY (%s)\n", qxl_mode_to_string(d->mode));
@@ -1394,6 +1400,7 @@ static int qxl_post_load(void *opaque, int version)
     uint8_t *ram_start = d->vga.vram_ptr;
     QXLCommandExt *cmds;
     QXLDevMemSlot memslot;
+    QXLDevSurfaceCreate surface;
     int in, out, i, newmode;
 
     dprint(d, 1, "%s: start\n", __FUNCTION__);
@@ -1425,7 +1432,8 @@ static int qxl_post_load(void *opaque, int version)
             qxl_add_memslot(d, i, 0, &memslot);
             qemu_spice_add_memslot(&d->ssd, &memslot);
         }
-        qxl_create_guest_primary(d, 1);
+        qxl_create_guest_primary(d, 1, &surface);
+        qemu_spice_create_primary_surface(&d->ssd, 0, &surface);
 
         /* replay surface-create and cursor-set commands */
         cmds = qemu_mallocz(sizeof(QXLCommandExt) * (NUM_SURFACES + 1));
-- 
1.7.5.4

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

* [Qemu-devel] [PATCH] qxl: remove qxl_destroy_primary()
  2011-07-06 12:19 [Qemu-devel] [PATCH] async + suspend reworked Alon Levy
                   ` (5 preceding siblings ...)
  2011-07-06 12:19 ` [Qemu-devel] [PATCH] qxl: move qemu_spice_create_primary_surface call out of qxl_create_guest_primary Alon Levy
@ 2011-07-06 12:19 ` Alon Levy
  2011-07-06 12:19 ` [Qemu-devel] [PATCH] spice/qxl: move worker wrappers Alon Levy
                   ` (9 subsequent siblings)
  16 siblings, 0 replies; 26+ messages in thread
From: Alon Levy @ 2011-07-06 12:19 UTC (permalink / raw)
  To: qemu-devel; +Cc: yhalperi, kraxel

From: Gerd Hoffmann <kraxel@redhat.com>

We'll have to move qemu_spice_destroy_primary_surface() out of
qxl_destroy_primary().  That makes the function pretty pointless,
so zap it and open code the two lines instead.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 hw/qxl.c |   28 ++++++++++++----------------
 1 files changed, 12 insertions(+), 16 deletions(-)

diff --git a/hw/qxl.c b/hw/qxl.c
index 22714bb..018ed54 100644
--- a/hw/qxl.c
+++ b/hw/qxl.c
@@ -135,7 +135,6 @@ static QXLMode qxl_modes[] = {
 static PCIQXLDevice *qxl0;
 
 static void qxl_send_events(PCIQXLDevice *d, uint32_t events);
-static void qxl_destroy_primary(PCIQXLDevice *d);
 static void qxl_reset_memslots(PCIQXLDevice *d);
 static void qxl_reset_surfaces(PCIQXLDevice *d);
 static void qxl_ring_set_dirty(PCIQXLDevice *qxl);
@@ -632,7 +631,10 @@ static void qxl_exit_vga_mode(PCIQXLDevice *d)
         return;
     }
     dprint(d, 1, "%s\n", __FUNCTION__);
-    qxl_destroy_primary(d);
+    if (d->mode != QXL_MODE_UNDEFINED) {
+        d->mode = QXL_MODE_UNDEFINED;
+        qemu_spice_destroy_primary_surface(&d->ssd, 0);
+    }
 }
 
 static void qxl_set_irq(PCIQXLDevice *d)
@@ -729,7 +731,10 @@ static void qxl_vga_ioport_write(void *opaque, uint32_t addr, uint32_t val)
 
     if (qxl->mode != QXL_MODE_VGA) {
         dprint(qxl, 1, "%s\n", __FUNCTION__);
-        qxl_destroy_primary(qxl);
+        if (qxl->mode != QXL_MODE_UNDEFINED) {
+            qxl->mode = QXL_MODE_UNDEFINED;
+            qemu_spice_destroy_primary_surface(&qxl->ssd, 0);
+        }
         qxl_soft_reset(qxl);
     }
     vga_ioport_write(opaque, addr, val);
@@ -888,18 +893,6 @@ static void qxl_create_guest_primary(PCIQXLDevice *qxl, int loadvm,
     qxl_render_resize(qxl);
 }
 
-static void qxl_destroy_primary(PCIQXLDevice *d)
-{
-    if (d->mode == QXL_MODE_UNDEFINED) {
-        return;
-    }
-
-    dprint(d, 1, "%s\n", __FUNCTION__);
-
-    d->mode = QXL_MODE_UNDEFINED;
-    qemu_spice_destroy_primary_surface(&d->ssd, 0);
-}
-
 static void qxl_set_mode(PCIQXLDevice *d, int modenr, int loadvm)
 {
     pcibus_t start = d->pci.io_regions[QXL_RAM_RANGE_INDEX].addr;
@@ -1040,7 +1033,10 @@ static void ioport_write(void *opaque, uint32_t addr, uint32_t val)
     case QXL_IO_DESTROY_PRIMARY:
         PANIC_ON(val != 0);
         dprint(d, 1, "QXL_IO_DESTROY_PRIMARY (%s)\n", qxl_mode_to_string(d->mode));
-        qxl_destroy_primary(d);
+        if (d->mode != QXL_MODE_UNDEFINED) {
+            d->mode = QXL_MODE_UNDEFINED;
+            qemu_spice_destroy_primary_surface(&d->ssd, 0);
+        }
         break;
     case QXL_IO_DESTROY_SURFACE_WAIT:
         qemu_spice_destroy_surface_wait(&d->ssd, val);
-- 
1.7.5.4

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

* [Qemu-devel] [PATCH] spice/qxl: move worker wrappers
  2011-07-06 12:19 [Qemu-devel] [PATCH] async + suspend reworked Alon Levy
                   ` (6 preceding siblings ...)
  2011-07-06 12:19 ` [Qemu-devel] [PATCH] qxl: remove qxl_destroy_primary() Alon Levy
@ 2011-07-06 12:19 ` Alon Levy
  2011-07-06 12:19 ` [Qemu-devel] [PATCH] qxl: fix surface tracking & locking Alon Levy
                   ` (8 subsequent siblings)
  16 siblings, 0 replies; 26+ messages in thread
From: Alon Levy @ 2011-07-06 12:19 UTC (permalink / raw)
  To: qemu-devel; +Cc: yhalperi, kraxel

From: Gerd Hoffmann <kraxel@redhat.com>

Move the wrapper functions which are used by qxl only to qxl.c.
Rename them from qemu_spice_* to qxl_spice_*.  Also pass in a
qxl state pointer instead of a SimpleSpiceDisplay pointer.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 hw/qxl-render.c    |    4 +-
 hw/qxl.c           |   82 +++++++++++++++++++++++++++++++++++++++++++++------
 hw/qxl.h           |   12 +++++++
 ui/spice-display.c |   60 --------------------------------------
 ui/spice-display.h |   11 -------
 5 files changed, 86 insertions(+), 83 deletions(-)

diff --git a/hw/qxl-render.c b/hw/qxl-render.c
index bef5f14..60b822d 100644
--- a/hw/qxl-render.c
+++ b/hw/qxl-render.c
@@ -124,8 +124,8 @@ void qxl_render_update(PCIQXLDevice *qxl)
     update.bottom = qxl->guest_primary.surface.height;
 
     memset(dirty, 0, sizeof(dirty));
-    qemu_spice_update_area(&qxl->ssd, 0, &update,
-                           dirty, ARRAY_SIZE(dirty), 1);
+    qxl_spice_update_area(qxl, 0, &update,
+                          dirty, ARRAY_SIZE(dirty), 1);
 
     for (i = 0; i < ARRAY_SIZE(dirty); i++) {
         if (qemu_spice_rect_is_empty(dirty+i)) {
diff --git a/hw/qxl.c b/hw/qxl.c
index 018ed54..830ddae 100644
--- a/hw/qxl.c
+++ b/hw/qxl.c
@@ -139,6 +139,68 @@ static void qxl_reset_memslots(PCIQXLDevice *d);
 static void qxl_reset_surfaces(PCIQXLDevice *d);
 static void qxl_ring_set_dirty(PCIQXLDevice *qxl);
 
+
+void qxl_spice_update_area(PCIQXLDevice *qxl, uint32_t surface_id,
+                           struct QXLRect *area, struct QXLRect *dirty_rects,
+                           uint32_t num_dirty_rects, uint32_t clear_dirty_region)
+{
+    qemu_mutex_lock(&qxl->ssd.wlock);
+    qxl->ssd.worker->update_area(qxl->ssd.worker, surface_id, area, dirty_rects,
+                             num_dirty_rects, clear_dirty_region);
+    qemu_mutex_unlock(&qxl->ssd.wlock);
+}
+
+void qxl_spice_destroy_surface_wait(PCIQXLDevice *qxl, uint32_t id)
+{
+    qemu_mutex_lock(&qxl->ssd.wlock);
+    qxl->ssd.worker->destroy_surface_wait(qxl->ssd.worker, id);
+    qemu_mutex_unlock(&qxl->ssd.wlock);
+}
+
+void qxl_spice_loadvm_commands(PCIQXLDevice *qxl, struct QXLCommandExt *ext,
+                               uint32_t count)
+{
+    qemu_mutex_lock(&qxl->ssd.wlock);
+    qxl->ssd.worker->loadvm_commands(qxl->ssd.worker, ext, count);
+    qemu_mutex_unlock(&qxl->ssd.wlock);
+}
+
+void qxl_spice_oom(PCIQXLDevice *qxl)
+{
+    qemu_mutex_lock(&qxl->ssd.wlock);
+    qxl->ssd.worker->oom(qxl->ssd.worker);
+    qemu_mutex_unlock(&qxl->ssd.wlock);
+}
+
+void qxl_spice_reset_memslots(PCIQXLDevice *qxl)
+{
+    qemu_mutex_lock(&qxl->ssd.wlock);
+    qxl->ssd.worker->reset_memslots(qxl->ssd.worker);
+    qemu_mutex_unlock(&qxl->ssd.wlock);
+}
+
+void qxl_spice_destroy_surfaces(PCIQXLDevice *qxl)
+{
+    qemu_mutex_lock(&qxl->ssd.wlock);
+    qxl->ssd.worker->destroy_surfaces(qxl->ssd.worker);
+    qemu_mutex_unlock(&qxl->ssd.wlock);
+}
+
+void qxl_spice_reset_image_cache(PCIQXLDevice *qxl)
+{
+    qemu_mutex_lock(&qxl->ssd.wlock);
+    qxl->ssd.worker->reset_image_cache(qxl->ssd.worker);
+    qemu_mutex_unlock(&qxl->ssd.wlock);
+}
+
+void qxl_spice_reset_cursor(PCIQXLDevice *qxl)
+{
+    qemu_mutex_lock(&qxl->ssd.wlock);
+    qxl->ssd.worker->reset_cursor(qxl->ssd.worker);
+    qemu_mutex_unlock(&qxl->ssd.wlock);
+}
+
+
 static inline uint32_t msb_mask(uint32_t val)
 {
     uint32_t mask;
@@ -701,8 +763,8 @@ static void qxl_hard_reset(PCIQXLDevice *d, int loadvm)
     dprint(d, 1, "%s: start%s\n", __FUNCTION__,
            loadvm ? " (loadvm)" : "");
 
-    qemu_spice_reset_cursor(&d->ssd);
-    qemu_spice_reset_image_cache(&d->ssd);
+    qxl_spice_reset_cursor(d);
+    qxl_spice_reset_image_cache(d);
     qxl_reset_surfaces(d);
     qxl_reset_memslots(d);
 
@@ -826,7 +888,7 @@ static void qxl_del_memslot(PCIQXLDevice *d, uint32_t slot_id)
 static void qxl_reset_memslots(PCIQXLDevice *d)
 {
     dprint(d, 1, "%s:\n", __FUNCTION__);
-    qemu_spice_reset_memslots(&d->ssd);
+    qxl_spice_reset_memslots(d);
     memset(&d->guest_slots, 0, sizeof(d->guest_slots));
 }
 
@@ -834,7 +896,7 @@ static void qxl_reset_surfaces(PCIQXLDevice *d)
 {
     dprint(d, 1, "%s:\n", __FUNCTION__);
     d->mode = QXL_MODE_UNDEFINED;
-    qemu_spice_destroy_surfaces(&d->ssd);
+    qxl_spice_destroy_surfaces(d);
     memset(&d->guest_surfaces.cmds, 0, sizeof(d->guest_surfaces.cmds));
 }
 
@@ -966,8 +1028,8 @@ static void ioport_write(void *opaque, uint32_t addr, uint32_t val)
     case QXL_IO_UPDATE_AREA:
     {
         QXLRect update = d->ram->update_area;
-        qemu_spice_update_area(&d->ssd, d->ram->update_surface,
-                               &update, NULL, 0, 0);
+        qxl_spice_update_area(d, d->ram->update_surface,
+                              &update, NULL, 0, 0);
         break;
     }
     case QXL_IO_NOTIFY_CMD:
@@ -988,7 +1050,7 @@ static void ioport_write(void *opaque, uint32_t addr, uint32_t val)
             break;
         }
         d->oom_running = 1;
-        qemu_spice_oom(&d->ssd);
+        qxl_spice_oom(d);
         d->oom_running = 0;
         break;
     case QXL_IO_SET_MODE:
@@ -1039,10 +1101,10 @@ static void ioport_write(void *opaque, uint32_t addr, uint32_t val)
         }
         break;
     case QXL_IO_DESTROY_SURFACE_WAIT:
-        qemu_spice_destroy_surface_wait(&d->ssd, val);
+        qxl_spice_destroy_surface_wait(d, val);
         break;
     case QXL_IO_DESTROY_ALL_SURFACES:
-        qemu_spice_destroy_surfaces(&d->ssd);
+        qxl_spice_destroy_surfaces(d);
         break;
     default:
         fprintf(stderr, "%s: ioport=0x%x, abort()\n", __FUNCTION__, io_port);
@@ -1446,7 +1508,7 @@ static int qxl_post_load(void *opaque, int version)
         cmds[out].cmd.type = QXL_CMD_CURSOR;
         cmds[out].group_id = MEMSLOT_GROUP_GUEST;
         out++;
-        qemu_spice_loadvm_commands(&d->ssd, cmds, out);
+        qxl_spice_loadvm_commands(d, cmds, out);
         qemu_free(cmds);
 
         break;
diff --git a/hw/qxl.h b/hw/qxl.h
index f6c450d..489d518 100644
--- a/hw/qxl.h
+++ b/hw/qxl.h
@@ -98,6 +98,18 @@ typedef struct PCIQXLDevice {
 /* qxl.c */
 void *qxl_phys2virt(PCIQXLDevice *qxl, QXLPHYSICAL phys, int group_id);
 
+void qxl_spice_update_area(PCIQXLDevice *qxl, uint32_t surface_id,
+                           struct QXLRect *area, struct QXLRect *dirty_rects,
+                           uint32_t num_dirty_rects, uint32_t clear_dirty_region);
+void qxl_spice_destroy_surface_wait(PCIQXLDevice *qxl, uint32_t id);
+void qxl_spice_loadvm_commands(PCIQXLDevice *qxl, struct QXLCommandExt *ext,
+                               uint32_t count);
+void qxl_spice_oom(PCIQXLDevice *qxl);
+void qxl_spice_reset_memslots(PCIQXLDevice *qxl);
+void qxl_spice_destroy_surfaces(PCIQXLDevice *qxl);
+void qxl_spice_reset_image_cache(PCIQXLDevice *qxl);
+void qxl_spice_reset_cursor(PCIQXLDevice *qxl);
+
 /* qxl-logger.c */
 void qxl_log_cmd_cursor(PCIQXLDevice *qxl, QXLCursorCmd *cmd, int group_id);
 void qxl_log_command(PCIQXLDevice *qxl, const char *ring, QXLCommandExt *ext);
diff --git a/ui/spice-display.c b/ui/spice-display.c
index 93ebc19..5bd7460 100644
--- a/ui/spice-display.c
+++ b/ui/spice-display.c
@@ -63,16 +63,6 @@ void qemu_spice_rect_union(QXLRect *dest, const QXLRect *r)
 }
 
 
-void qemu_spice_update_area(SimpleSpiceDisplay *ssd, uint32_t surface_id,
-                            struct QXLRect *area, struct QXLRect *dirty_rects,
-                            uint32_t num_dirty_rects, uint32_t clear_dirty_region)
-{
-    qemu_mutex_lock(&ssd->wlock);
-    ssd->worker->update_area(ssd->worker, surface_id, area, dirty_rects,
-                             num_dirty_rects, clear_dirty_region);
-    qemu_mutex_unlock(&ssd->wlock);
-}
-
 void qemu_spice_add_memslot(SimpleSpiceDisplay *ssd, QXLDevMemSlot *memslot)
 {
     qemu_mutex_lock(&ssd->wlock);
@@ -102,21 +92,6 @@ void qemu_spice_destroy_primary_surface(SimpleSpiceDisplay *ssd, uint32_t id)
     qemu_mutex_unlock(&ssd->wlock);
 }
 
-void qemu_spice_destroy_surface_wait(SimpleSpiceDisplay *ssd, uint32_t id)
-{
-    qemu_mutex_lock(&ssd->wlock);
-    ssd->worker->destroy_surface_wait(ssd->worker, id);
-    qemu_mutex_unlock(&ssd->wlock);
-}
-
-void qemu_spice_loadvm_commands(SimpleSpiceDisplay *ssd, struct QXLCommandExt *ext,
-                                uint32_t count)
-{
-    qemu_mutex_lock(&ssd->wlock);
-    ssd->worker->loadvm_commands(ssd->worker, ext, count);
-    qemu_mutex_unlock(&ssd->wlock);
-}
-
 void qemu_spice_wakeup(SimpleSpiceDisplay *ssd)
 {
     qemu_mutex_lock(&ssd->wlock);
@@ -124,13 +99,6 @@ void qemu_spice_wakeup(SimpleSpiceDisplay *ssd)
     qemu_mutex_unlock(&ssd->wlock);
 }
 
-void qemu_spice_oom(SimpleSpiceDisplay *ssd)
-{
-    qemu_mutex_lock(&ssd->wlock);
-    ssd->worker->oom(ssd->worker);
-    qemu_mutex_unlock(&ssd->wlock);
-}
-
 void qemu_spice_start(SimpleSpiceDisplay *ssd)
 {
     qemu_mutex_lock(&ssd->wlock);
@@ -145,34 +113,6 @@ void qemu_spice_stop(SimpleSpiceDisplay *ssd)
     qemu_mutex_unlock(&ssd->wlock);
 }
 
-void qemu_spice_reset_memslots(SimpleSpiceDisplay *ssd)
-{
-    qemu_mutex_lock(&ssd->wlock);
-    ssd->worker->reset_memslots(ssd->worker);
-    qemu_mutex_unlock(&ssd->wlock);
-}
-
-void qemu_spice_destroy_surfaces(SimpleSpiceDisplay *ssd)
-{
-    qemu_mutex_lock(&ssd->wlock);
-    ssd->worker->destroy_surfaces(ssd->worker);
-    qemu_mutex_unlock(&ssd->wlock);
-}
-
-void qemu_spice_reset_image_cache(SimpleSpiceDisplay *ssd)
-{
-    qemu_mutex_lock(&ssd->wlock);
-    ssd->worker->reset_image_cache(ssd->worker);
-    qemu_mutex_unlock(&ssd->wlock);
-}
-
-void qemu_spice_reset_cursor(SimpleSpiceDisplay *ssd)
-{
-    qemu_mutex_lock(&ssd->wlock);
-    ssd->worker->reset_cursor(ssd->worker);
-    qemu_mutex_unlock(&ssd->wlock);
-}
-
 
 static SimpleSpiceUpdate *qemu_spice_create_update(SimpleSpiceDisplay *ssd)
 {
diff --git a/ui/spice-display.h b/ui/spice-display.h
index 3968d75..e84847f 100644
--- a/ui/spice-display.h
+++ b/ui/spice-display.h
@@ -83,22 +83,11 @@ void qemu_spice_display_update(SimpleSpiceDisplay *ssd,
 void qemu_spice_display_resize(SimpleSpiceDisplay *ssd);
 void qemu_spice_display_refresh(SimpleSpiceDisplay *ssd);
 
-void qemu_spice_update_area(SimpleSpiceDisplay *ssd, uint32_t surface_id,
-                            struct QXLRect *area, struct QXLRect *dirty_rects,
-                            uint32_t num_dirty_rects, uint32_t clear_dirty_region);
 void qemu_spice_add_memslot(SimpleSpiceDisplay *ssd, QXLDevMemSlot *memslot);
 void qemu_spice_del_memslot(SimpleSpiceDisplay *ssd, uint32_t gid, uint32_t sid);
 void qemu_spice_create_primary_surface(SimpleSpiceDisplay *ssd, uint32_t id,
                                        QXLDevSurfaceCreate *surface);
 void qemu_spice_destroy_primary_surface(SimpleSpiceDisplay *ssd, uint32_t id);
-void qemu_spice_destroy_surface_wait(SimpleSpiceDisplay *ssd, uint32_t id);
-void qemu_spice_loadvm_commands(SimpleSpiceDisplay *ssd, struct QXLCommandExt *ext,
-                                uint32_t count);
 void qemu_spice_wakeup(SimpleSpiceDisplay *ssd);
-void qemu_spice_oom(SimpleSpiceDisplay *ssd);
 void qemu_spice_start(SimpleSpiceDisplay *ssd);
 void qemu_spice_stop(SimpleSpiceDisplay *ssd);
-void qemu_spice_reset_memslots(SimpleSpiceDisplay *ssd);
-void qemu_spice_destroy_surfaces(SimpleSpiceDisplay *ssd);
-void qemu_spice_reset_image_cache(SimpleSpiceDisplay *ssd);
-void qemu_spice_reset_cursor(SimpleSpiceDisplay *ssd);
-- 
1.7.5.4

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

* [Qemu-devel] [PATCH] qxl: fix surface tracking & locking
  2011-07-06 12:19 [Qemu-devel] [PATCH] async + suspend reworked Alon Levy
                   ` (7 preceding siblings ...)
  2011-07-06 12:19 ` [Qemu-devel] [PATCH] spice/qxl: move worker wrappers Alon Levy
@ 2011-07-06 12:19 ` Alon Levy
  2011-07-06 12:19 ` [Qemu-devel] [PATCH] qxl: add io_port_to_string Alon Levy
                   ` (7 subsequent siblings)
  16 siblings, 0 replies; 26+ messages in thread
From: Alon Levy @ 2011-07-06 12:19 UTC (permalink / raw)
  To: qemu-devel; +Cc: yhalperi, kraxel

From: Gerd Hoffmann <kraxel@redhat.com>

Surface tracking needs proper locking with some commands affecting
surfaces running in a thread, add it.  Also reset the surface counter
when zapping all surfaces.

[ alon: use track_lock instead of wlock for guest_surfaces ]

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 hw/qxl.c |   13 ++++++++++++-
 hw/qxl.h |    2 ++
 2 files changed, 14 insertions(+), 1 deletions(-)

diff --git a/hw/qxl.c b/hw/qxl.c
index 830ddae..241c27c 100644
--- a/hw/qxl.c
+++ b/hw/qxl.c
@@ -153,7 +153,12 @@ void qxl_spice_update_area(PCIQXLDevice *qxl, uint32_t surface_id,
 void qxl_spice_destroy_surface_wait(PCIQXLDevice *qxl, uint32_t id)
 {
     qemu_mutex_lock(&qxl->ssd.wlock);
+    qemu_mutex_lock(&qxl->track_lock);
+    PANIC_ON(id >= NUM_SURFACES);
     qxl->ssd.worker->destroy_surface_wait(qxl->ssd.worker, id);
+    qxl->guest_surfaces.cmds[id] = 0;
+    qxl->guest_surfaces.count--;
+    qemu_mutex_unlock(&qxl->track_lock);
     qemu_mutex_unlock(&qxl->ssd.wlock);
 }
 
@@ -182,7 +187,11 @@ void qxl_spice_reset_memslots(PCIQXLDevice *qxl)
 void qxl_spice_destroy_surfaces(PCIQXLDevice *qxl)
 {
     qemu_mutex_lock(&qxl->ssd.wlock);
+    qemu_mutex_lock(&qxl->track_lock);
     qxl->ssd.worker->destroy_surfaces(qxl->ssd.worker);
+    memset(&qxl->guest_surfaces.cmds, 0, sizeof(qxl->guest_surfaces.cmds));
+    qxl->guest_surfaces.count = 0;
+    qemu_mutex_unlock(&qxl->track_lock);
     qemu_mutex_unlock(&qxl->ssd.wlock);
 }
 
@@ -346,6 +355,7 @@ static void qxl_track_command(PCIQXLDevice *qxl, struct QXLCommandExt *ext)
         QXLSurfaceCmd *cmd = qxl_phys2virt(qxl, ext->cmd.data, ext->group_id);
         uint32_t id = le32_to_cpu(cmd->surface_id);
         PANIC_ON(id >= NUM_SURFACES);
+        qemu_mutex_lock(&qxl->track_lock);
         if (cmd->type == QXL_SURFACE_CMD_CREATE) {
             qxl->guest_surfaces.cmds[id] = ext->cmd.data;
             qxl->guest_surfaces.count++;
@@ -356,6 +366,7 @@ static void qxl_track_command(PCIQXLDevice *qxl, struct QXLCommandExt *ext)
             qxl->guest_surfaces.cmds[id] = 0;
             qxl->guest_surfaces.count--;
         }
+        qemu_mutex_unlock(&qxl->track_lock);
         break;
     }
     case QXL_CMD_CURSOR:
@@ -897,7 +908,6 @@ static void qxl_reset_surfaces(PCIQXLDevice *d)
     dprint(d, 1, "%s:\n", __FUNCTION__);
     d->mode = QXL_MODE_UNDEFINED;
     qxl_spice_destroy_surfaces(d);
-    memset(&d->guest_surfaces.cmds, 0, sizeof(d->guest_surfaces.cmds));
 }
 
 /* called from spice server thread context only */
@@ -1321,6 +1331,7 @@ static int qxl_init_common(PCIQXLDevice *qxl)
     qxl->generation = 1;
     qxl->num_memslots = NUM_MEMSLOTS;
     qxl->num_surfaces = NUM_SURFACES;
+    qemu_mutex_init(&qxl->track_lock);
 
     switch (qxl->revision) {
     case 1: /* spice 0.4 -- qxl-1 */
diff --git a/hw/qxl.h b/hw/qxl.h
index 489d518..087ef6b 100644
--- a/hw/qxl.h
+++ b/hw/qxl.h
@@ -55,6 +55,8 @@ typedef struct PCIQXLDevice {
     } guest_surfaces;
     QXLPHYSICAL        guest_cursor;
 
+    QemuMutex          track_lock;
+
     /* thread signaling */
     pthread_t          main;
     int                pipe[2];
-- 
1.7.5.4

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

* [Qemu-devel] [PATCH] qxl: add io_port_to_string
  2011-07-06 12:19 [Qemu-devel] [PATCH] async + suspend reworked Alon Levy
                   ` (8 preceding siblings ...)
  2011-07-06 12:19 ` [Qemu-devel] [PATCH] qxl: fix surface tracking & locking Alon Levy
@ 2011-07-06 12:19 ` Alon Levy
  2011-07-06 12:19 ` [Qemu-devel] [PATCH] qxl: error handling fixes and cleanups Alon Levy
                   ` (6 subsequent siblings)
  16 siblings, 0 replies; 26+ messages in thread
From: Alon Levy @ 2011-07-06 12:19 UTC (permalink / raw)
  To: qemu-devel; +Cc: yhalperi, kraxel

---
 hw/qxl.c |   64 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 63 insertions(+), 1 deletions(-)

diff --git a/hw/qxl.c b/hw/qxl.c
index 241c27c..4f77001 100644
--- a/hw/qxl.c
+++ b/hw/qxl.c
@@ -438,6 +438,67 @@ static const char *qxl_mode_to_string(int mode)
     return "INVALID";
 }
 
+static const char *io_port_to_string(uint32_t io_port)
+{
+    if (io_port >= QXL_IO_RANGE_SIZE) {
+        return "out of range";
+    }
+    switch(io_port) {
+    case QXL_IO_NOTIFY_CMD:
+        return "QXL_IO_NOTIFY_CMD";
+    case QXL_IO_NOTIFY_CURSOR:
+        return "QXL_IO_NOTIFY_CURSOR";
+    case QXL_IO_UPDATE_AREA:
+        return "QXL_IO_UPDATE_AREA";
+    case QXL_IO_UPDATE_IRQ:
+        return "QXL_IO_UPDATE_IRQ";
+    case QXL_IO_NOTIFY_OOM:
+        return "QXL_IO_NOTIFY_OOM";
+    case QXL_IO_RESET:
+        return "QXL_IO_RESET";
+    case QXL_IO_SET_MODE:
+        return "QXL_IO_SET_MODE";
+    case QXL_IO_LOG:
+        return "QXL_IO_LOG";
+    case QXL_IO_MEMSLOT_ADD:
+        return "QXL_IO_MEMSLOT_ADD";
+    case QXL_IO_MEMSLOT_DEL:
+        return "QXL_IO_MEMSLOT_DEL";
+    case QXL_IO_DETACH_PRIMARY:
+        return "QXL_IO_DETACH_PRIMARY";
+    case QXL_IO_ATTACH_PRIMARY:
+        return "QXL_IO_ATTACH_PRIMARY";
+    case QXL_IO_CREATE_PRIMARY:
+        return "QXL_IO_CREATE_PRIMARY";
+    case QXL_IO_DESTROY_PRIMARY:
+        return "QXL_IO_DESTROY_PRIMARY";
+    case QXL_IO_DESTROY_SURFACE_WAIT:
+        return "QXL_IO_DESTROY_SURFACE_WAIT";
+    case QXL_IO_DESTROY_ALL_SURFACES:
+        return "QXL_IO_DESTROY_ALL_SURFACES";
+    case QXL_IO_UPDATE_AREA_ASYNC:
+        return "QXL_IO_UPDATE_AREA_ASYNC";
+    case QXL_IO_NOTIFY_OOM_ASYNC:
+        return "QXL_IO_NOTIFY_OOM_ASYNC";
+    case QXL_IO_MEMSLOT_ADD_ASYNC:
+        return "QXL_IO_MEMSLOT_ADD_ASYNC";
+    case QXL_IO_CREATE_PRIMARY_ASYNC:
+        return "QXL_IO_CREATE_PRIMARY_ASYNC";
+    case QXL_IO_DESTROY_PRIMARY_ASYNC:
+        return "QXL_IO_DESTROY_PRIMARY_ASYNC";
+    case QXL_IO_DESTROY_SURFACE_ASYNC:
+        return "QXL_IO_DESTROY_SURFACE_ASYNC";
+    case QXL_IO_DESTROY_ALL_SURFACES_ASYNC:
+        return "QXL_IO_DESTROY_ALL_SURFACES_ASYNC";
+    case QXL_IO_FLUSH_SURFACES_ASYNC:
+        return "QXL_IO_FLUSH_SURFACES_ASYNC";
+    case QXL_IO_FLUSH_RELEASE:
+        return "QXL_IO_FLUSH_RELEASE";
+    }
+    // not reached?
+    return "error in io_port_to_string";
+}
+
 /* called from spice server thread context only */
 static int interface_get_command(QXLInstance *sin, struct QXLCommandExt *ext)
 {
@@ -1030,7 +1091,8 @@ static void ioport_write(void *opaque, uint32_t addr, uint32_t val)
     default:
         if (d->mode == QXL_MODE_NATIVE || d->mode == QXL_MODE_COMPAT)
             break;
-        dprint(d, 1, "%s: unexpected port 0x%x in vga mode\n", __FUNCTION__, io_port);
+        dprint(d, 1, "%s: unexpected port 0x%x (%s) in vga mode\n",
+            __FUNCTION__, io_port, io_port_to_string(io_port));
         return;
     }
 
-- 
1.7.5.4

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

* [Qemu-devel] [PATCH] qxl: error handling fixes and cleanups.
  2011-07-06 12:19 [Qemu-devel] [PATCH] async + suspend reworked Alon Levy
                   ` (9 preceding siblings ...)
  2011-07-06 12:19 ` [Qemu-devel] [PATCH] qxl: add io_port_to_string Alon Levy
@ 2011-07-06 12:19 ` Alon Levy
  2011-07-06 12:19 ` [Qemu-devel] [PATCH] qxl: make qxl_guest_bug take variable arguments Alon Levy
                   ` (5 subsequent siblings)
  16 siblings, 0 replies; 26+ messages in thread
From: Alon Levy @ 2011-07-06 12:19 UTC (permalink / raw)
  To: qemu-devel; +Cc: yhalperi, kraxel

From: Gerd Hoffmann <kraxel@redhat.com>

Add qxl_guest_bug() function which is supposed to be called in case
sanity checks of guest requests fail.  It raises an error IRQ and
logs a message in case guest debugging is enabled.

Make PANIC_ON() abort instead of exit.  That macro should be used
for qemu bugs only, any guest-triggerable stuff should use the new
qxl_guest_bug() function instead.

Convert a few easy cases from PANIC_ON() to qxl_guest_bug() to
show intended usage.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 hw/qxl.c |   32 ++++++++++++++++++++++++++++----
 hw/qxl.h |    3 ++-
 2 files changed, 30 insertions(+), 5 deletions(-)

diff --git a/hw/qxl.c b/hw/qxl.c
index 4f77001..36cc9af 100644
--- a/hw/qxl.c
+++ b/hw/qxl.c
@@ -139,6 +139,14 @@ static void qxl_reset_memslots(PCIQXLDevice *d);
 static void qxl_reset_surfaces(PCIQXLDevice *d);
 static void qxl_ring_set_dirty(PCIQXLDevice *qxl);
 
+void qxl_guest_bug(PCIQXLDevice *qxl, const char *msg)
+{
+    qxl_send_events(qxl, QXL_INTERRUPT_ERROR);
+    if (qxl->guestdebug) {
+        fprintf(stderr, "qxl-%d: guest bug: %s\n", qxl->id, msg);
+    }
+}
+
 
 void qxl_spice_update_area(PCIQXLDevice *qxl, uint32_t surface_id,
                            struct QXLRect *area, struct QXLRect *dirty_rects,
@@ -1143,21 +1151,34 @@ static void ioport_write(void *opaque, uint32_t addr, uint32_t val)
     {
         QXLDevMemSlot memslot;
 
-        PANIC_ON(val >= NUM_MEMSLOTS);
-        PANIC_ON(d->guest_slots[val].active);
+        if (val >= NUM_MEMSLOTS) {
+            qxl_guest_bug(d, "QXL_IO_MEMSLOT_ADD: val out of range");
+            break;
+        }
+        if (d->guest_slots[val].active) {
+            qxl_guest_bug(d, "QXL_IO_MEMSLOT_ADD: memory slot already active");
+            break;
+        }
         d->guest_slots[val].slot = d->ram->mem_slot;
         qxl_add_memslot(d, val, 0, &memslot);
         qemu_spice_add_memslot(&d->ssd, &memslot);
         break;
     }
     case QXL_IO_MEMSLOT_DEL:
+        if (val >= NUM_MEMSLOTS) {
+            qxl_guest_bug(d, "QXL_IO_MEMSLOT_DEL: val out of range");
+            break;
+        }
         qxl_del_memslot(d, val);
         break;
     case QXL_IO_CREATE_PRIMARY:
     {
         QXLDevSurfaceCreate surface;
 
-        PANIC_ON(val != 0);
+        if (val != 0) {
+            qxl_guest_bug(d, "QXL_IO_CREATE_PRIMARY: val != 0");
+            break;
+        }
         dprint(d, 1, "QXL_IO_CREATE_PRIMARY\n");
         d->guest_primary.surface = d->ram->create_surface;
         qxl_create_guest_primary(d, 0, &surface);
@@ -1165,7 +1186,10 @@ static void ioport_write(void *opaque, uint32_t addr, uint32_t val)
         break;
     }
     case QXL_IO_DESTROY_PRIMARY:
-        PANIC_ON(val != 0);
+        if (val != 0) {
+            qxl_guest_bug(d, "QXL_IO_DESTROY_PRIMARY: val != 0");
+            break;
+        }
         dprint(d, 1, "QXL_IO_DESTROY_PRIMARY (%s)\n", qxl_mode_to_string(d->mode));
         if (d->mode != QXL_MODE_UNDEFINED) {
             d->mode = QXL_MODE_UNDEFINED;
diff --git a/hw/qxl.h b/hw/qxl.h
index 087ef6b..88393c2 100644
--- a/hw/qxl.h
+++ b/hw/qxl.h
@@ -86,7 +86,7 @@ typedef struct PCIQXLDevice {
 
 #define PANIC_ON(x) if ((x)) {                         \
     printf("%s: PANIC %s failed\n", __FUNCTION__, #x); \
-    exit(-1);                                          \
+    abort();                                           \
 }
 
 #define dprint(_qxl, _level, _fmt, ...)                                 \
@@ -99,6 +99,7 @@ typedef struct PCIQXLDevice {
 
 /* qxl.c */
 void *qxl_phys2virt(PCIQXLDevice *qxl, QXLPHYSICAL phys, int group_id);
+void qxl_guest_bug(PCIQXLDevice *qxl, const char *msg);
 
 void qxl_spice_update_area(PCIQXLDevice *qxl, uint32_t surface_id,
                            struct QXLRect *area, struct QXLRect *dirty_rects,
-- 
1.7.5.4

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

* [Qemu-devel] [PATCH] qxl: make qxl_guest_bug take variable arguments
  2011-07-06 12:19 [Qemu-devel] [PATCH] async + suspend reworked Alon Levy
                   ` (10 preceding siblings ...)
  2011-07-06 12:19 ` [Qemu-devel] [PATCH] qxl: error handling fixes and cleanups Alon Levy
@ 2011-07-06 12:19 ` Alon Levy
  2011-07-06 12:19 ` [Qemu-devel] [PATCH] qxl: async I/O Alon Levy
                   ` (4 subsequent siblings)
  16 siblings, 0 replies; 26+ messages in thread
From: Alon Levy @ 2011-07-06 12:19 UTC (permalink / raw)
  To: qemu-devel; +Cc: yhalperi, kraxel

---
 hw/qxl.c |   18 +++++++++++-------
 hw/qxl.h |    2 +-
 2 files changed, 12 insertions(+), 8 deletions(-)

diff --git a/hw/qxl.c b/hw/qxl.c
index 36cc9af..a5c2d69 100644
--- a/hw/qxl.c
+++ b/hw/qxl.c
@@ -139,11 +139,15 @@ static void qxl_reset_memslots(PCIQXLDevice *d);
 static void qxl_reset_surfaces(PCIQXLDevice *d);
 static void qxl_ring_set_dirty(PCIQXLDevice *qxl);
 
-void qxl_guest_bug(PCIQXLDevice *qxl, const char *msg)
+void qxl_guest_bug(PCIQXLDevice *qxl, const char *msg, ...)
 {
     qxl_send_events(qxl, QXL_INTERRUPT_ERROR);
     if (qxl->guestdebug) {
-        fprintf(stderr, "qxl-%d: guest bug: %s\n", qxl->id, msg);
+        va_list ap;
+        va_start(ap, msg);
+        fprintf(stderr, "qxl-%d: guest bug: ", qxl->id);
+        vfprintf(stderr, msg, ap);
+        va_end(ap);
     }
 }
 
@@ -1152,11 +1156,11 @@ static void ioport_write(void *opaque, uint32_t addr, uint32_t val)
         QXLDevMemSlot memslot;
 
         if (val >= NUM_MEMSLOTS) {
-            qxl_guest_bug(d, "QXL_IO_MEMSLOT_ADD: val out of range");
+            qxl_guest_bug(d, "QXL_IO_MEMSLOT_ADD: val out of range\n");
             break;
         }
         if (d->guest_slots[val].active) {
-            qxl_guest_bug(d, "QXL_IO_MEMSLOT_ADD: memory slot already active");
+            qxl_guest_bug(d, "QXL_IO_MEMSLOT_ADD: memory slot already active\n");
             break;
         }
         d->guest_slots[val].slot = d->ram->mem_slot;
@@ -1166,7 +1170,7 @@ static void ioport_write(void *opaque, uint32_t addr, uint32_t val)
     }
     case QXL_IO_MEMSLOT_DEL:
         if (val >= NUM_MEMSLOTS) {
-            qxl_guest_bug(d, "QXL_IO_MEMSLOT_DEL: val out of range");
+            qxl_guest_bug(d, "QXL_IO_MEMSLOT_DEL: val out of range\n");
             break;
         }
         qxl_del_memslot(d, val);
@@ -1176,7 +1180,7 @@ static void ioport_write(void *opaque, uint32_t addr, uint32_t val)
         QXLDevSurfaceCreate surface;
 
         if (val != 0) {
-            qxl_guest_bug(d, "QXL_IO_CREATE_PRIMARY: val != 0");
+            qxl_guest_bug(d, "QXL_IO_CREATE_PRIMARY: val != 0\n");
             break;
         }
         dprint(d, 1, "QXL_IO_CREATE_PRIMARY\n");
@@ -1187,7 +1191,7 @@ static void ioport_write(void *opaque, uint32_t addr, uint32_t val)
     }
     case QXL_IO_DESTROY_PRIMARY:
         if (val != 0) {
-            qxl_guest_bug(d, "QXL_IO_DESTROY_PRIMARY: val != 0");
+            qxl_guest_bug(d, "QXL_IO_DESTROY_PRIMARY: val != 0\n");
             break;
         }
         dprint(d, 1, "QXL_IO_DESTROY_PRIMARY (%s)\n", qxl_mode_to_string(d->mode));
diff --git a/hw/qxl.h b/hw/qxl.h
index 88393c2..e361bc6 100644
--- a/hw/qxl.h
+++ b/hw/qxl.h
@@ -99,7 +99,7 @@ typedef struct PCIQXLDevice {
 
 /* qxl.c */
 void *qxl_phys2virt(PCIQXLDevice *qxl, QXLPHYSICAL phys, int group_id);
-void qxl_guest_bug(PCIQXLDevice *qxl, const char *msg);
+void qxl_guest_bug(PCIQXLDevice *qxl, const char *msg, ...);
 
 void qxl_spice_update_area(PCIQXLDevice *qxl, uint32_t surface_id,
                            struct QXLRect *area, struct QXLRect *dirty_rects,
-- 
1.7.5.4

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

* [Qemu-devel] [PATCH] qxl: async I/O
  2011-07-06 12:19 [Qemu-devel] [PATCH] async + suspend reworked Alon Levy
                   ` (11 preceding siblings ...)
  2011-07-06 12:19 ` [Qemu-devel] [PATCH] qxl: make qxl_guest_bug take variable arguments Alon Levy
@ 2011-07-06 12:19 ` Alon Levy
  2011-07-07  7:47   ` Gerd Hoffmann
  2011-07-06 12:19 ` [Qemu-devel] [PATCH] qxl: bump pci rev Alon Levy
                   ` (3 subsequent siblings)
  16 siblings, 1 reply; 26+ messages in thread
From: Alon Levy @ 2011-07-06 12:19 UTC (permalink / raw)
  To: qemu-devel; +Cc: yhalperi, kraxel

From: Gerd Hoffmann <kraxel@redhat.com>

Some of the QXL port i/o commands are waiting for the spice server to
complete certain actions.  Add async versions for these commands, so we
don't block the vcpu while the spice server processses the command.
Instead the qxl device will raise an IRQ when done.

The async command processing relies on an added QXLInterface::async_complete.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Alon Levy     <alevy@redhat.com>
---
 hw/qxl.c           |  130 ++++++++++++++++++++++++++++++++++++++++++++--------
 hw/qxl.h           |   11 ++++
 ui/spice-display.c |   41 ++++++++++++++---
 ui/spice-display.h |    4 ++
 4 files changed, 159 insertions(+), 27 deletions(-)

diff --git a/hw/qxl.c b/hw/qxl.c
index a5c2d69..54e28b9 100644
--- a/hw/qxl.c
+++ b/hw/qxl.c
@@ -151,29 +151,51 @@ void qxl_guest_bug(PCIQXLDevice *qxl, const char *msg, ...)
     }
 }
 
+void qxl_spice_update_area_async(PCIQXLDevice *qxl, uint32_t surface_id,
+                           struct QXLRect *area, struct QXLRect *dirty_rects,
+                           uint32_t num_dirty_rects, uint32_t clear_dirty_region,
+                           int async)
+{
+    qemu_mutex_lock(&qxl->ssd.wlock);
+    if (async) {
+        qxl->ssd.worker->update_area_async(qxl->ssd.worker, surface_id, area, dirty_rects,
+                                 num_dirty_rects, clear_dirty_region);
+    } else {
+        qxl->ssd.worker->update_area(qxl->ssd.worker, surface_id, area, dirty_rects,
+                                 num_dirty_rects, clear_dirty_region);
+    }
+    qemu_mutex_unlock(&qxl->ssd.wlock);
+}
 
 void qxl_spice_update_area(PCIQXLDevice *qxl, uint32_t surface_id,
                            struct QXLRect *area, struct QXLRect *dirty_rects,
                            uint32_t num_dirty_rects, uint32_t clear_dirty_region)
 {
-    qemu_mutex_lock(&qxl->ssd.wlock);
-    qxl->ssd.worker->update_area(qxl->ssd.worker, surface_id, area, dirty_rects,
-                             num_dirty_rects, clear_dirty_region);
-    qemu_mutex_unlock(&qxl->ssd.wlock);
+    qxl_spice_update_area_async(qxl, surface_id, area, dirty_rects, num_dirty_rects,
+                          clear_dirty_region, 0);
 }
 
-void qxl_spice_destroy_surface_wait(PCIQXLDevice *qxl, uint32_t id)
+void qxl_spice_destroy_surface_wait_async(PCIQXLDevice *qxl, uint32_t id, int async)
 {
     qemu_mutex_lock(&qxl->ssd.wlock);
     qemu_mutex_lock(&qxl->track_lock);
     PANIC_ON(id >= NUM_SURFACES);
-    qxl->ssd.worker->destroy_surface_wait(qxl->ssd.worker, id);
+    if (async) {
+        qxl->ssd.worker->destroy_surface_wait_async(qxl->ssd.worker, id);
+    } else {
+        qxl->ssd.worker->destroy_surface_wait(qxl->ssd.worker, id);
+    }
     qxl->guest_surfaces.cmds[id] = 0;
     qxl->guest_surfaces.count--;
     qemu_mutex_unlock(&qxl->track_lock);
     qemu_mutex_unlock(&qxl->ssd.wlock);
 }
 
+void qxl_spice_destroy_surface_wait(PCIQXLDevice *qxl, uint32_t id)
+{
+    qxl_spice_destroy_surface_wait_async(qxl, id, 0);
+}
+
 void qxl_spice_loadvm_commands(PCIQXLDevice *qxl, struct QXLCommandExt *ext,
                                uint32_t count)
 {
@@ -182,13 +204,22 @@ void qxl_spice_loadvm_commands(PCIQXLDevice *qxl, struct QXLCommandExt *ext,
     qemu_mutex_unlock(&qxl->ssd.wlock);
 }
 
-void qxl_spice_oom(PCIQXLDevice *qxl)
+void qxl_spice_oom_async(PCIQXLDevice *qxl, int async)
 {
     qemu_mutex_lock(&qxl->ssd.wlock);
-    qxl->ssd.worker->oom(qxl->ssd.worker);
+    if (async) {
+        qxl->ssd.worker->oom_async(qxl->ssd.worker);
+    } else {
+        qxl->ssd.worker->oom(qxl->ssd.worker);
+    }
     qemu_mutex_unlock(&qxl->ssd.wlock);
 }
 
+void qxl_spice_oom(PCIQXLDevice *qxl)
+{
+    qxl_spice_oom_async(qxl, 0);
+}
+
 void qxl_spice_reset_memslots(PCIQXLDevice *qxl)
 {
     qemu_mutex_lock(&qxl->ssd.wlock);
@@ -196,17 +227,26 @@ void qxl_spice_reset_memslots(PCIQXLDevice *qxl)
     qemu_mutex_unlock(&qxl->ssd.wlock);
 }
 
-void qxl_spice_destroy_surfaces(PCIQXLDevice *qxl)
+void qxl_spice_destroy_surfaces_async(PCIQXLDevice *qxl, int async)
 {
     qemu_mutex_lock(&qxl->ssd.wlock);
     qemu_mutex_lock(&qxl->track_lock);
-    qxl->ssd.worker->destroy_surfaces(qxl->ssd.worker);
+    if (async) {
+        qxl->ssd.worker->destroy_surfaces_async(qxl->ssd.worker);
+    } else {
+        qxl->ssd.worker->destroy_surfaces(qxl->ssd.worker);
+    }
     memset(&qxl->guest_surfaces.cmds, 0, sizeof(qxl->guest_surfaces.cmds));
     qxl->guest_surfaces.count = 0;
     qemu_mutex_unlock(&qxl->track_lock);
     qemu_mutex_unlock(&qxl->ssd.wlock);
 }
 
+void qxl_spice_destroy_surfaces(PCIQXLDevice *qxl)
+{
+    qxl_spice_destroy_surfaces_async(qxl, 0);
+}
+
 void qxl_spice_reset_image_cache(PCIQXLDevice *qxl)
 {
     qemu_mutex_lock(&qxl->ssd.wlock);
@@ -739,6 +779,16 @@ static int interface_flush_resources(QXLInstance *sin)
     return ret;
 }
 
+/* called from spice server thread context only */
+static void interface_async_complete(QXLInstance *sin)
+{
+    PCIQXLDevice *qxl = container_of(sin, PCIQXLDevice, ssd.qxl);
+
+    dprint(qxl, 1, "async_complete: %d done\n", qxl->current_async);
+    qxl->current_async = QXL_UNDEFINED_IO;
+    qxl_send_events(qxl, QXL_INTERRUPT_IO_CMD);
+}
+
 static const QXLInterface qxl_interface = {
     .base.type               = SPICE_INTERFACE_QXL,
     .base.description        = "qxl gpu",
@@ -758,6 +808,7 @@ static const QXLInterface qxl_interface = {
     .req_cursor_notification = interface_req_cursor_notification,
     .notify_update           = interface_notify_update,
     .flush_resources         = interface_flush_resources,
+    .async_complete          = interface_async_complete,
 };
 
 static void qxl_enter_vga_mode(PCIQXLDevice *d)
@@ -1090,13 +1141,16 @@ static void ioport_write(void *opaque, uint32_t addr, uint32_t val)
 {
     PCIQXLDevice *d = opaque;
     uint32_t io_port = addr - d->io_base;
+    int async = 0;
 
     switch (io_port) {
     case QXL_IO_RESET:
     case QXL_IO_SET_MODE:
     case QXL_IO_MEMSLOT_ADD:
+    case QXL_IO_MEMSLOT_ADD_ASYNC:
     case QXL_IO_MEMSLOT_DEL:
     case QXL_IO_CREATE_PRIMARY:
+    case QXL_IO_CREATE_PRIMARY_ASYNC:
     case QXL_IO_UPDATE_IRQ:
     case QXL_IO_LOG:
         break;
@@ -1105,15 +1159,40 @@ static void ioport_write(void *opaque, uint32_t addr, uint32_t val)
             break;
         dprint(d, 1, "%s: unexpected port 0x%x (%s) in vga mode\n",
             __FUNCTION__, io_port, io_port_to_string(io_port));
+        /* be nice to buggy guest drivers */
+        if (io_port >= QXL_IO_UPDATE_AREA_ASYNC &&
+            io_port <= QXL_IO_DESTROY_ALL_SURFACES_ASYNC) {
+            qxl_send_events(d, QXL_INTERRUPT_IO_CMD);
+        }
         return;
     }
 
     switch (io_port) {
+    case QXL_IO_UPDATE_AREA_ASYNC:
+    case QXL_IO_NOTIFY_OOM_ASYNC:
+    case QXL_IO_MEMSLOT_ADD_ASYNC:
+    case QXL_IO_CREATE_PRIMARY_ASYNC:
+    case QXL_IO_DESTROY_PRIMARY_ASYNC:
+    case QXL_IO_DESTROY_SURFACE_ASYNC:
+    case QXL_IO_DESTROY_ALL_SURFACES_ASYNC:
+        async = 1;
+        if (d->current_async != QXL_UNDEFINED_IO) {
+            qxl_guest_bug(d, "%d async started before last (%d) complete\n",
+                io_port, d->current_async);
+        }
+        d->current_async = io_port;
+        dprint(d, 1, "start async %d\n", d->current_async);
+        break;
+    default:
+        break;
+    }
+
+    switch (io_port) {
+    case QXL_IO_UPDATE_AREA_ASYNC:
     case QXL_IO_UPDATE_AREA:
     {
-        QXLRect update = d->ram->update_area;
-        qxl_spice_update_area(d, d->ram->update_surface,
-                              &update, NULL, 0, 0);
+        qxl_spice_update_area_async(d, d->ram->update_surface,
+                              &d->ram->update_area, NULL, 0, 0, async);
         break;
     }
     case QXL_IO_NOTIFY_CMD:
@@ -1125,6 +1204,7 @@ static void ioport_write(void *opaque, uint32_t addr, uint32_t val)
     case QXL_IO_UPDATE_IRQ:
         qxl_set_irq(d);
         break;
+    case QXL_IO_NOTIFY_OOM_ASYNC:
     case QXL_IO_NOTIFY_OOM:
         if (!SPICE_RING_IS_EMPTY(&d->ram->release_ring)) {
             break;
@@ -1134,7 +1214,7 @@ static void ioport_write(void *opaque, uint32_t addr, uint32_t val)
             break;
         }
         d->oom_running = 1;
-        qxl_spice_oom(d);
+        qxl_spice_oom_async(d, async);
         d->oom_running = 0;
         break;
     case QXL_IO_SET_MODE:
@@ -1151,6 +1231,7 @@ static void ioport_write(void *opaque, uint32_t addr, uint32_t val)
         dprint(d, 1, "QXL_IO_RESET\n");
         qxl_hard_reset(d, 0);
         break;
+    case QXL_IO_MEMSLOT_ADD_ASYNC:
     case QXL_IO_MEMSLOT_ADD:
     {
         QXLDevMemSlot memslot;
@@ -1165,7 +1246,7 @@ static void ioport_write(void *opaque, uint32_t addr, uint32_t val)
         }
         d->guest_slots[val].slot = d->ram->mem_slot;
         qxl_add_memslot(d, val, 0, &memslot);
-        qemu_spice_add_memslot(&d->ssd, &memslot);
+        qemu_spice_add_memslot_async(&d->ssd, &memslot, async);
         break;
     }
     case QXL_IO_MEMSLOT_DEL:
@@ -1175,6 +1256,7 @@ static void ioport_write(void *opaque, uint32_t addr, uint32_t val)
         }
         qxl_del_memslot(d, val);
         break;
+    case QXL_IO_CREATE_PRIMARY_ASYNC:
     case QXL_IO_CREATE_PRIMARY:
     {
         QXLDevSurfaceCreate surface;
@@ -1183,12 +1265,13 @@ static void ioport_write(void *opaque, uint32_t addr, uint32_t val)
             qxl_guest_bug(d, "QXL_IO_CREATE_PRIMARY: val != 0\n");
             break;
         }
-        dprint(d, 1, "QXL_IO_CREATE_PRIMARY\n");
+        dprint(d, 1, "QXL_IO_CREATE_PRIMARY async=%d\n", async);
         d->guest_primary.surface = d->ram->create_surface;
         qxl_create_guest_primary(d, 0, &surface);
-        qemu_spice_create_primary_surface(&d->ssd, 0, &surface);
+        qemu_spice_create_primary_surface_async(&d->ssd, 0, &surface, async);
         break;
     }
+    case QXL_IO_DESTROY_PRIMARY_ASYNC:
     case QXL_IO_DESTROY_PRIMARY:
         if (val != 0) {
             qxl_guest_bug(d, "QXL_IO_DESTROY_PRIMARY: val != 0\n");
@@ -1197,14 +1280,21 @@ static void ioport_write(void *opaque, uint32_t addr, uint32_t val)
         dprint(d, 1, "QXL_IO_DESTROY_PRIMARY (%s)\n", qxl_mode_to_string(d->mode));
         if (d->mode != QXL_MODE_UNDEFINED) {
             d->mode = QXL_MODE_UNDEFINED;
-            qemu_spice_destroy_primary_surface(&d->ssd, 0);
+            qemu_spice_destroy_primary_surface_async(&d->ssd, 0, async);
+        } else {
+            if (async) {
+                qxl_send_events(d, QXL_INTERRUPT_IO_CMD);
+            }
         }
         break;
+    case QXL_IO_DESTROY_SURFACE_ASYNC:
     case QXL_IO_DESTROY_SURFACE_WAIT:
-        qxl_spice_destroy_surface_wait(d, val);
+        qxl_spice_destroy_surface_wait_async(d, val, async);
         break;
+    case QXL_IO_DESTROY_ALL_SURFACES_ASYNC:
     case QXL_IO_DESTROY_ALL_SURFACES:
-        qxl_spice_destroy_surfaces(d);
+        d->mode = QXL_MODE_UNDEFINED;
+        qxl_spice_destroy_surfaces_async(d, async);
         break;
     default:
         fprintf(stderr, "%s: ioport=0x%x, abort()\n", __FUNCTION__, io_port);
diff --git a/hw/qxl.h b/hw/qxl.h
index e361bc6..e4134b9 100644
--- a/hw/qxl.h
+++ b/hw/qxl.h
@@ -15,6 +15,8 @@ enum qxl_mode {
     QXL_MODE_NATIVE,
 };
 
+#define QXL_UNDEFINED_IO UINT32_MAX
+
 typedef struct PCIQXLDevice {
     PCIDevice          pci;
     SimpleSpiceDisplay ssd;
@@ -30,6 +32,8 @@ typedef struct PCIQXLDevice {
     int32_t            num_memslots;
     int32_t            num_surfaces;
 
+    uint32_t           current_async;
+
     struct guest_slots {
         QXLMemSlot     slot;
         void           *ptr;
@@ -104,12 +108,19 @@ void qxl_guest_bug(PCIQXLDevice *qxl, const char *msg, ...);
 void qxl_spice_update_area(PCIQXLDevice *qxl, uint32_t surface_id,
                            struct QXLRect *area, struct QXLRect *dirty_rects,
                            uint32_t num_dirty_rects, uint32_t clear_dirty_region);
+void qxl_spice_update_area_async(PCIQXLDevice *qxl, uint32_t surface_id,
+                           struct QXLRect *area, struct QXLRect *dirty_rects,
+                           uint32_t num_dirty_rects, uint32_t clear_dirty_region,
+                           int async);
 void qxl_spice_destroy_surface_wait(PCIQXLDevice *qxl, uint32_t id);
+void qxl_spice_destroy_surface_wait_async(PCIQXLDevice *qxl, uint32_t id, int async);
 void qxl_spice_loadvm_commands(PCIQXLDevice *qxl, struct QXLCommandExt *ext,
                                uint32_t count);
 void qxl_spice_oom(PCIQXLDevice *qxl);
+void qxl_spice_oom_async(PCIQXLDevice *qxl, int async);
 void qxl_spice_reset_memslots(PCIQXLDevice *qxl);
 void qxl_spice_destroy_surfaces(PCIQXLDevice *qxl);
+void qxl_spice_destroy_surfaces_async(PCIQXLDevice *qxl, int async);
 void qxl_spice_reset_image_cache(PCIQXLDevice *qxl);
 void qxl_spice_reset_cursor(PCIQXLDevice *qxl);
 
diff --git a/ui/spice-display.c b/ui/spice-display.c
index 5bd7460..8cbdd0a 100644
--- a/ui/spice-display.c
+++ b/ui/spice-display.c
@@ -62,14 +62,22 @@ void qemu_spice_rect_union(QXLRect *dest, const QXLRect *r)
     dest->right = MAX(dest->right, r->right);
 }
 
-
-void qemu_spice_add_memslot(SimpleSpiceDisplay *ssd, QXLDevMemSlot *memslot)
+void qemu_spice_add_memslot_async(SimpleSpiceDisplay *ssd, QXLDevMemSlot *memslot, int async)
 {
     qemu_mutex_lock(&ssd->wlock);
-    ssd->worker->add_memslot(ssd->worker, memslot);
+    if (async) {
+        ssd->worker->add_memslot_async(ssd->worker, memslot);
+    } else {
+        ssd->worker->add_memslot(ssd->worker, memslot);
+    }
     qemu_mutex_unlock(&ssd->wlock);
 }
 
+void qemu_spice_add_memslot(SimpleSpiceDisplay *ssd, QXLDevMemSlot *memslot)
+{
+    qemu_spice_add_memslot_async(ssd, memslot, 0);
+}
+
 void qemu_spice_del_memslot(SimpleSpiceDisplay *ssd, uint32_t gid, uint32_t sid)
 {
     qemu_mutex_lock(&ssd->wlock);
@@ -77,19 +85,38 @@ void qemu_spice_del_memslot(SimpleSpiceDisplay *ssd, uint32_t gid, uint32_t sid)
     qemu_mutex_unlock(&ssd->wlock);
 }
 
+void qemu_spice_create_primary_surface_async(SimpleSpiceDisplay *ssd, uint32_t id,
+                                       QXLDevSurfaceCreate *surface, int async)
+{
+    qemu_mutex_lock(&ssd->wlock);
+    if (async) {
+        ssd->worker->create_primary_surface_async(ssd->worker, id, surface);
+    } else {
+        ssd->worker->create_primary_surface(ssd->worker, id, surface);
+    }
+    qemu_mutex_unlock(&ssd->wlock);
+}
+
 void qemu_spice_create_primary_surface(SimpleSpiceDisplay *ssd, uint32_t id,
                                        QXLDevSurfaceCreate *surface)
 {
+    qemu_spice_create_primary_surface_async(ssd, id, surface, 0);
+}
+
+void qemu_spice_destroy_primary_surface_async(SimpleSpiceDisplay *ssd, uint32_t id, int async)
+{
     qemu_mutex_lock(&ssd->wlock);
-    ssd->worker->create_primary_surface(ssd->worker, id, surface);
+    if (async) {
+        ssd->worker->destroy_primary_surface_async(ssd->worker, id);
+    } else {
+        ssd->worker->destroy_primary_surface(ssd->worker, id);
+    }
     qemu_mutex_unlock(&ssd->wlock);
 }
 
 void qemu_spice_destroy_primary_surface(SimpleSpiceDisplay *ssd, uint32_t id)
 {
-    qemu_mutex_lock(&ssd->wlock);
-    ssd->worker->destroy_primary_surface(ssd->worker, id);
-    qemu_mutex_unlock(&ssd->wlock);
+    qemu_spice_destroy_primary_surface_async(ssd, id, 0);
 }
 
 void qemu_spice_wakeup(SimpleSpiceDisplay *ssd)
diff --git a/ui/spice-display.h b/ui/spice-display.h
index e84847f..5696e0c 100644
--- a/ui/spice-display.h
+++ b/ui/spice-display.h
@@ -84,10 +84,14 @@ void qemu_spice_display_resize(SimpleSpiceDisplay *ssd);
 void qemu_spice_display_refresh(SimpleSpiceDisplay *ssd);
 
 void qemu_spice_add_memslot(SimpleSpiceDisplay *ssd, QXLDevMemSlot *memslot);
+void qemu_spice_add_memslot_async(SimpleSpiceDisplay *ssd, QXLDevMemSlot *memslot, int async);
 void qemu_spice_del_memslot(SimpleSpiceDisplay *ssd, uint32_t gid, uint32_t sid);
 void qemu_spice_create_primary_surface(SimpleSpiceDisplay *ssd, uint32_t id,
                                        QXLDevSurfaceCreate *surface);
+void qemu_spice_create_primary_surface_async(SimpleSpiceDisplay *ssd, uint32_t id,
+                                       QXLDevSurfaceCreate *surface, int async);
 void qemu_spice_destroy_primary_surface(SimpleSpiceDisplay *ssd, uint32_t id);
+void qemu_spice_destroy_primary_surface_async(SimpleSpiceDisplay *ssd, uint32_t id, int async);
 void qemu_spice_wakeup(SimpleSpiceDisplay *ssd);
 void qemu_spice_start(SimpleSpiceDisplay *ssd);
 void qemu_spice_stop(SimpleSpiceDisplay *ssd);
-- 
1.7.5.4

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

* [Qemu-devel] [PATCH] qxl: bump pci rev
  2011-07-06 12:19 [Qemu-devel] [PATCH] async + suspend reworked Alon Levy
                   ` (12 preceding siblings ...)
  2011-07-06 12:19 ` [Qemu-devel] [PATCH] qxl: async I/O Alon Levy
@ 2011-07-06 12:19 ` Alon Levy
  2011-07-06 12:19 ` [Qemu-devel] [PATCH] qxl: only disallow specific io's in vga mode Alon Levy
                   ` (2 subsequent siblings)
  16 siblings, 0 replies; 26+ messages in thread
From: Alon Levy @ 2011-07-06 12:19 UTC (permalink / raw)
  To: qemu-devel; +Cc: yhalperi, kraxel

From: Gerd Hoffmann <kraxel@redhat.com>

Inform guest drivers about the new features I/O commands we have
now (async commands, S3 support).

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 hw/qxl.c |    9 ++++++---
 1 files changed, 6 insertions(+), 3 deletions(-)

diff --git a/hw/qxl.c b/hw/qxl.c
index 54e28b9..2a90fa3 100644
--- a/hw/qxl.c
+++ b/hw/qxl.c
@@ -1518,9 +1518,12 @@ static int qxl_init_common(PCIQXLDevice *qxl)
         pci_device_rev = QXL_REVISION_STABLE_V04;
         break;
     case 2: /* spice 0.6 -- qxl-2 */
-    default:
         pci_device_rev = QXL_REVISION_STABLE_V06;
         break;
+    case 3: /* qxl-3 */
+    default:
+        pci_device_rev = 3;
+        break;
     }
 
     pci_set_byte(&config[PCI_REVISION_ID], pci_device_rev);
@@ -1788,7 +1791,7 @@ static PCIDeviceInfo qxl_info_primary = {
     .qdev.props = (Property[]) {
         DEFINE_PROP_UINT32("ram_size", PCIQXLDevice, vga.vram_size, 64 * 1024 * 1024),
         DEFINE_PROP_UINT32("vram_size", PCIQXLDevice, vram_size, 64 * 1024 * 1024),
-        DEFINE_PROP_UINT32("revision", PCIQXLDevice, revision, 2),
+        DEFINE_PROP_UINT32("revision", PCIQXLDevice, revision, 3),
         DEFINE_PROP_UINT32("debug", PCIQXLDevice, debug, 0),
         DEFINE_PROP_UINT32("guestdebug", PCIQXLDevice, guestdebug, 0),
         DEFINE_PROP_UINT32("cmdlog", PCIQXLDevice, cmdlog, 0),
@@ -1809,7 +1812,7 @@ static PCIDeviceInfo qxl_info_secondary = {
     .qdev.props = (Property[]) {
         DEFINE_PROP_UINT32("ram_size", PCIQXLDevice, vga.vram_size, 64 * 1024 * 1024),
         DEFINE_PROP_UINT32("vram_size", PCIQXLDevice, vram_size, 64 * 1024 * 1024),
-        DEFINE_PROP_UINT32("revision", PCIQXLDevice, revision, 2),
+        DEFINE_PROP_UINT32("revision", PCIQXLDevice, revision, 3),
         DEFINE_PROP_UINT32("debug", PCIQXLDevice, debug, 0),
         DEFINE_PROP_UINT32("guestdebug", PCIQXLDevice, guestdebug, 0),
         DEFINE_PROP_UINT32("cmdlog", PCIQXLDevice, cmdlog, 0),
-- 
1.7.5.4

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

* [Qemu-devel] [PATCH] qxl: only disallow specific io's in vga mode
  2011-07-06 12:19 [Qemu-devel] [PATCH] async + suspend reworked Alon Levy
                   ` (13 preceding siblings ...)
  2011-07-06 12:19 ` [Qemu-devel] [PATCH] qxl: bump pci rev Alon Levy
@ 2011-07-06 12:19 ` Alon Levy
  2011-07-06 12:19 ` [Qemu-devel] [PATCH] qxl: add QXL_IO_FLUSH_{SURFACES, RELEASE} for guest S3&S4 support Alon Levy
  2011-07-06 12:19 ` [Qemu-devel] [PATCH] qxl: use QXL_REVISION_* Alon Levy
  16 siblings, 0 replies; 26+ messages in thread
From: Alon Levy @ 2011-07-06 12:19 UTC (permalink / raw)
  To: qemu-devel; +Cc: yhalperi, kraxel

Since the driver is still in operation even after moving to UNDEFINED, i.e.
by destroying primary in any way.
---
 hw/qxl.c |    3 ++-
 1 files changed, 2 insertions(+), 1 deletions(-)

diff --git a/hw/qxl.c b/hw/qxl.c
index 2a90fa3..438c6ee 100644
--- a/hw/qxl.c
+++ b/hw/qxl.c
@@ -1155,8 +1155,9 @@ static void ioport_write(void *opaque, uint32_t addr, uint32_t val)
     case QXL_IO_LOG:
         break;
     default:
-        if (d->mode == QXL_MODE_NATIVE || d->mode == QXL_MODE_COMPAT)
+        if (d->mode != QXL_MODE_VGA) {
             break;
+        }
         dprint(d, 1, "%s: unexpected port 0x%x (%s) in vga mode\n",
             __FUNCTION__, io_port, io_port_to_string(io_port));
         /* be nice to buggy guest drivers */
-- 
1.7.5.4

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

* [Qemu-devel] [PATCH] qxl: add QXL_IO_FLUSH_{SURFACES, RELEASE} for guest S3&S4 support
  2011-07-06 12:19 [Qemu-devel] [PATCH] async + suspend reworked Alon Levy
                   ` (14 preceding siblings ...)
  2011-07-06 12:19 ` [Qemu-devel] [PATCH] qxl: only disallow specific io's in vga mode Alon Levy
@ 2011-07-06 12:19 ` Alon Levy
  2011-07-06 12:19 ` [Qemu-devel] [PATCH] qxl: use QXL_REVISION_* Alon Levy
  16 siblings, 0 replies; 26+ messages in thread
From: Alon Levy @ 2011-07-06 12:19 UTC (permalink / raw)
  To: qemu-devel; +Cc: yhalperi, kraxel

Add two new IOs.
 QXL_IO_FLUSH_SURFACES - equivalent to update area for all surfaces, used
  to reduce vmexits from NumSurfaces to 1 on guest S3, S4 and resolution change (windows
  driver implementation is such that this is done on each of those occasions).
 QXL_IO_FLUSH_RELEASE - used to ensure anything on last_release is put on the release ring
  for the client to free.

Cc: Yonit Halperin <yhalperi@redhat.com>
---
 hw/qxl.c |   27 +++++++++++++++++++++++++++
 hw/qxl.h |    1 +
 2 files changed, 28 insertions(+), 0 deletions(-)

diff --git a/hw/qxl.c b/hw/qxl.c
index 438c6ee..8c7b03b 100644
--- a/hw/qxl.c
+++ b/hw/qxl.c
@@ -196,6 +196,13 @@ void qxl_spice_destroy_surface_wait(PCIQXLDevice *qxl, uint32_t id)
     qxl_spice_destroy_surface_wait_async(qxl, id, 0);
 }
 
+void qxl_spice_flush_surfaces_async(PCIQXLDevice *qxl)
+{
+    qemu_mutex_lock(&qxl->ssd.wlock);
+    qxl->ssd.worker->flush_surfaces_async(qxl->ssd.worker);
+    qemu_mutex_unlock(&qxl->ssd.wlock);
+}
+
 void qxl_spice_loadvm_commands(PCIQXLDevice *qxl, struct QXLCommandExt *ext,
                                uint32_t count)
 {
@@ -1176,6 +1183,7 @@ static void ioport_write(void *opaque, uint32_t addr, uint32_t val)
     case QXL_IO_DESTROY_PRIMARY_ASYNC:
     case QXL_IO_DESTROY_SURFACE_ASYNC:
     case QXL_IO_DESTROY_ALL_SURFACES_ASYNC:
+    case QXL_IO_FLUSH_SURFACES_ASYNC:
         async = 1;
         if (d->current_async != QXL_UNDEFINED_IO) {
             qxl_guest_bug(d, "%d async started before last (%d) complete\n",
@@ -1292,6 +1300,25 @@ static void ioport_write(void *opaque, uint32_t addr, uint32_t val)
     case QXL_IO_DESTROY_SURFACE_WAIT:
         qxl_spice_destroy_surface_wait_async(d, val, async);
         break;
+    case QXL_IO_FLUSH_RELEASE: {
+        QXLReleaseRing *ring = &d->ram->release_ring;
+        if (ring->prod - ring->cons + 1 == ring->num_items) {
+            fprintf(stderr,
+                "ERROR: no flush, full release ring [p%d,%dc]\n",
+                ring->prod, ring->cons);
+        }
+        qxl_push_free_res(d, 1 /* flush */);
+        dprint(d, 1, "QXL_IO_FLUSH_RELEASE exit (%s, s#=%d, res#=%d,%p)\n",
+            qxl_mode_to_string(d->mode), d->guest_surfaces.count,
+            d->num_free_res, d->last_release);
+        break;
+    }
+    case QXL_IO_FLUSH_SURFACES_ASYNC:
+        dprint(d, 1, "QXL_IO_FLUSH_SURFACES_ASYNC (%d) (%s, s#=%d, res#=%d)\n",
+        val, qxl_mode_to_string(d->mode), d->guest_surfaces.count,
+        d->num_free_res);
+        qxl_spice_flush_surfaces_async(d);
+        break;
     case QXL_IO_DESTROY_ALL_SURFACES_ASYNC:
     case QXL_IO_DESTROY_ALL_SURFACES:
         d->mode = QXL_MODE_UNDEFINED;
diff --git a/hw/qxl.h b/hw/qxl.h
index e4134b9..d0cf77d 100644
--- a/hw/qxl.h
+++ b/hw/qxl.h
@@ -123,6 +123,7 @@ void qxl_spice_destroy_surfaces(PCIQXLDevice *qxl);
 void qxl_spice_destroy_surfaces_async(PCIQXLDevice *qxl, int async);
 void qxl_spice_reset_image_cache(PCIQXLDevice *qxl);
 void qxl_spice_reset_cursor(PCIQXLDevice *qxl);
+void qxl_spice_flush_surfaces_async(PCIQXLDevice *qxl);
 
 /* qxl-logger.c */
 void qxl_log_cmd_cursor(PCIQXLDevice *qxl, QXLCursorCmd *cmd, int group_id);
-- 
1.7.5.4

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

* [Qemu-devel] [PATCH] qxl: use QXL_REVISION_*
  2011-07-06 12:19 [Qemu-devel] [PATCH] async + suspend reworked Alon Levy
                   ` (15 preceding siblings ...)
  2011-07-06 12:19 ` [Qemu-devel] [PATCH] qxl: add QXL_IO_FLUSH_{SURFACES, RELEASE} for guest S3&S4 support Alon Levy
@ 2011-07-06 12:19 ` Alon Levy
  16 siblings, 0 replies; 26+ messages in thread
From: Alon Levy @ 2011-07-06 12:19 UTC (permalink / raw)
  To: qemu-devel; +Cc: yhalperi, kraxel

---
 hw/qxl.c |   24 +++++++++++-------------
 1 files changed, 11 insertions(+), 13 deletions(-)

diff --git a/hw/qxl.c b/hw/qxl.c
index 8c7b03b..05dfc10 100644
--- a/hw/qxl.c
+++ b/hw/qxl.c
@@ -1532,7 +1532,6 @@ static DisplayChangeListener display_listener = {
 static int qxl_init_common(PCIQXLDevice *qxl)
 {
     uint8_t* config = qxl->pci.config;
-    uint32_t pci_device_rev;
     uint32_t io_size;
 
     qxl->mode = QXL_MODE_UNDEFINED;
@@ -1542,19 +1541,18 @@ static int qxl_init_common(PCIQXLDevice *qxl)
     qemu_mutex_init(&qxl->track_lock);
 
     switch (qxl->revision) {
-    case 1: /* spice 0.4 -- qxl-1 */
-        pci_device_rev = QXL_REVISION_STABLE_V04;
+    case QXL_REVISION_STABLE_V04: /* spice 0.4 -- qxl-1 */
+    case QXL_REVISION_STABLE_V06: /* spice 0.6 -- qxl-2 */
+    case QXL_REVISION_STABLE_V10: /* spice 0.10? -- qxl-3 */
         break;
-    case 2: /* spice 0.6 -- qxl-2 */
-        pci_device_rev = QXL_REVISION_STABLE_V06;
-        break;
-    case 3: /* qxl-3 */
     default:
-        pci_device_rev = 3;
+        fprintf(stderr, "invalid revision %d, resetting to %d\n", qxl->revision,
+            QXL_REVISION_STABLE_V10);
+        qxl->revision = QXL_REVISION_STABLE_V10;
         break;
     }
 
-    pci_set_byte(&config[PCI_REVISION_ID], pci_device_rev);
+    pci_set_byte(&config[PCI_REVISION_ID], qxl->revision);
     pci_set_byte(&config[PCI_INTERRUPT_PIN], 1);
 
     qxl->rom_size = qxl_rom_size();
@@ -1565,14 +1563,14 @@ static int qxl_init_common(PCIQXLDevice *qxl)
     if (qxl->vram_size < 16 * 1024 * 1024) {
         qxl->vram_size = 16 * 1024 * 1024;
     }
-    if (qxl->revision == 1) {
+    if (qxl->revision == QXL_REVISION_STABLE_V04) {
         qxl->vram_size = 4096;
     }
     qxl->vram_size = msb_mask(qxl->vram_size * 2 - 1);
     qxl->vram_offset = qemu_ram_alloc(&qxl->pci.qdev, "qxl.vram", qxl->vram_size);
 
     io_size = msb_mask(QXL_IO_RANGE_SIZE * 2 - 1);
-    if (qxl->revision == 1) {
+    if (qxl->revision == QXL_REVISION_STABLE_V04) {
         io_size = 8;
     }
 
@@ -1819,7 +1817,7 @@ static PCIDeviceInfo qxl_info_primary = {
     .qdev.props = (Property[]) {
         DEFINE_PROP_UINT32("ram_size", PCIQXLDevice, vga.vram_size, 64 * 1024 * 1024),
         DEFINE_PROP_UINT32("vram_size", PCIQXLDevice, vram_size, 64 * 1024 * 1024),
-        DEFINE_PROP_UINT32("revision", PCIQXLDevice, revision, 3),
+        DEFINE_PROP_UINT32("revision", PCIQXLDevice, revision, QXL_REVISION_STABLE_V10),
         DEFINE_PROP_UINT32("debug", PCIQXLDevice, debug, 0),
         DEFINE_PROP_UINT32("guestdebug", PCIQXLDevice, guestdebug, 0),
         DEFINE_PROP_UINT32("cmdlog", PCIQXLDevice, cmdlog, 0),
@@ -1840,7 +1838,7 @@ static PCIDeviceInfo qxl_info_secondary = {
     .qdev.props = (Property[]) {
         DEFINE_PROP_UINT32("ram_size", PCIQXLDevice, vga.vram_size, 64 * 1024 * 1024),
         DEFINE_PROP_UINT32("vram_size", PCIQXLDevice, vram_size, 64 * 1024 * 1024),
-        DEFINE_PROP_UINT32("revision", PCIQXLDevice, revision, 3),
+        DEFINE_PROP_UINT32("revision", PCIQXLDevice, revision, QXL_REVISION_STABLE_V10),
         DEFINE_PROP_UINT32("debug", PCIQXLDevice, debug, 0),
         DEFINE_PROP_UINT32("guestdebug", PCIQXLDevice, guestdebug, 0),
         DEFINE_PROP_UINT32("cmdlog", PCIQXLDevice, cmdlog, 0),
-- 
1.7.5.4

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

* Re: [Qemu-devel] [PATCH] qxl: add defines from latest spice-protocol.
  2011-07-06 12:19 ` [Qemu-devel] [PATCH] qxl: add defines from latest spice-protocol Alon Levy
@ 2011-07-07  7:33   ` Gerd Hoffmann
  2011-07-07  7:43     ` Alon Levy
  0 siblings, 1 reply; 26+ messages in thread
From: Gerd Hoffmann @ 2011-07-07  7:33 UTC (permalink / raw)
  To: Alon Levy; +Cc: yhalperi, qemu-devel

On 07/06/11 14:19, Alon Levy wrote:
> From: Gerd Hoffmann<kraxel@redhat.com>
>
> Allows to build with older spice-protocol versions.

Given that we can't get away with changing the protocol only but require 
a new libspices-server for the new features this is pointless ...

cheers,
   Gerd

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

* Re: [Qemu-devel] [PATCH] qxl: move qemu_spice_add_memslot call out of qxl_add_memslot
  2011-07-06 12:19 ` [Qemu-devel] [PATCH] qxl: move qemu_spice_add_memslot call out of qxl_add_memslot Alon Levy
@ 2011-07-07  7:39   ` Gerd Hoffmann
  2011-07-07  8:45     ` Alon Levy
  0 siblings, 1 reply; 26+ messages in thread
From: Gerd Hoffmann @ 2011-07-07  7:39 UTC (permalink / raw)
  To: Alon Levy; +Cc: yhalperi, qemu-devel

   Hi,

> -static void qxl_add_memslot(PCIQXLDevice *d, uint32_t slot_id, uint64_t delta)
> +static void qxl_add_memslot(PCIQXLDevice *d, uint32_t slot_id, uint64_t delta,
> +                            QXLDevMemSlot *memslot)

> -        qxl_add_memslot(d, val, 0);
> +        qxl_add_memslot(d, val, 0,&memslot);
> +        qemu_spice_add_memslot(&d->ssd,&memslot);

Do we still need this and the simliar patches?  Given that we don't call 
qemu_spice_add_memslot() from another thread any more we could just pass 
in a async flag to qxl_add_memslot().

cheers,
   Gerd

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

* Re: [Qemu-devel] [PATCH] spice: lock spice worker calls
  2011-07-06 12:19 ` [Qemu-devel] [PATCH] spice: lock spice worker calls Alon Levy
@ 2011-07-07  7:40   ` Gerd Hoffmann
  2011-07-07  7:52     ` Alon Levy
  0 siblings, 1 reply; 26+ messages in thread
From: Gerd Hoffmann @ 2011-07-07  7:40 UTC (permalink / raw)
  To: Alon Levy; +Cc: yhalperi, qemu-devel

On 07/06/11 14:19, Alon Levy wrote:
> From: Gerd Hoffmann<kraxel@redhat.com>
>
> ... so we can call them from a thread.

Still needed?  I don't think so.

cheers,
   Gerd

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

* Re: [Qemu-devel] [PATCH] qxl: add defines from latest spice-protocol.
  2011-07-07  7:33   ` Gerd Hoffmann
@ 2011-07-07  7:43     ` Alon Levy
  0 siblings, 0 replies; 26+ messages in thread
From: Alon Levy @ 2011-07-07  7:43 UTC (permalink / raw)
  To: Gerd Hoffmann; +Cc: yhalperi, qemu-devel

On Thu, Jul 07, 2011 at 09:33:05AM +0200, Gerd Hoffmann wrote:
> On 07/06/11 14:19, Alon Levy wrote:
> >From: Gerd Hoffmann<kraxel@redhat.com>
> >
> >Allows to build with older spice-protocol versions.
> 
> Given that we can't get away with changing the protocol only but
> require a new libspices-server for the new features this is
> pointless ...
> 

right. wasn't thinking.

> cheers,
>   Gerd
> 

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

* Re: [Qemu-devel] [PATCH] qxl: async I/O
  2011-07-06 12:19 ` [Qemu-devel] [PATCH] qxl: async I/O Alon Levy
@ 2011-07-07  7:47   ` Gerd Hoffmann
  2011-07-07  8:11     ` Alon Levy
  0 siblings, 1 reply; 26+ messages in thread
From: Gerd Hoffmann @ 2011-07-07  7:47 UTC (permalink / raw)
  To: Alon Levy; +Cc: yhalperi, qemu-devel

   Hi,

> +void qxl_spice_update_area_async(PCIQXLDevice *qxl, uint32_t surface_id,
> +                           struct QXLRect *area, struct QXLRect *dirty_rects,
> +                           uint32_t num_dirty_rects, uint32_t clear_dirty_region,
> +                           int async)
> +{
> +    qemu_mutex_lock(&qxl->ssd.wlock);
> +    if (async) {
> +        qxl->ssd.worker->update_area_async(qxl->ssd.worker, surface_id, area, dirty_rects,
> +                                 num_dirty_rects, clear_dirty_region);
> +    } else {
> +        qxl->ssd.worker->update_area(qxl->ssd.worker, surface_id, area, dirty_rects,
> +                                 num_dirty_rects, clear_dirty_region);
> +    }
> +    qemu_mutex_unlock(&qxl->ssd.wlock);
> +}

We need a plan to handle backward compatibility here.  Older 
libspice-server versions don't have the update_area_async op.  Option 
one is to just not support async mode with older libraries.  Option two 
is to handle the request syncronously even though the guest has asked 
for async.  I'd tend to pick option one, that makes things easier with 
S3 support because we just can't do that in any way with an older 
libspice-server.

>       switch (io_port) {
> +    case QXL_IO_UPDATE_AREA_ASYNC:
> +    case QXL_IO_NOTIFY_OOM_ASYNC:
> +    case QXL_IO_MEMSLOT_ADD_ASYNC:
> +    case QXL_IO_CREATE_PRIMARY_ASYNC:
> +    case QXL_IO_DESTROY_PRIMARY_ASYNC:
> +    case QXL_IO_DESTROY_SURFACE_ASYNC:
> +    case QXL_IO_DESTROY_ALL_SURFACES_ASYNC:
> +        async = 1;
> +        if (d->current_async != QXL_UNDEFINED_IO) {
> +            qxl_guest_bug(d, "%d async started before last (%d) complete\n",
> +                io_port, d->current_async);

Better return here, ignoring the invalid request?

cheers,
   Gerd

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

* Re: [Qemu-devel] [PATCH] spice: lock spice worker calls
  2011-07-07  7:40   ` Gerd Hoffmann
@ 2011-07-07  7:52     ` Alon Levy
  0 siblings, 0 replies; 26+ messages in thread
From: Alon Levy @ 2011-07-07  7:52 UTC (permalink / raw)
  To: Gerd Hoffmann; +Cc: yhalperi, qemu-devel

On Thu, Jul 07, 2011 at 09:40:15AM +0200, Gerd Hoffmann wrote:
> On 07/06/11 14:19, Alon Levy wrote:
> >From: Gerd Hoffmann<kraxel@redhat.com>
> >
> >... so we can call them from a thread.
> 
> Still needed?  I don't think so.
> 

Will drop (I wasn't sure we won't want this at a distant future, so I kept it).

> cheers,
>   Gerd
> 

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

* Re: [Qemu-devel] [PATCH] qxl: async I/O
  2011-07-07  7:47   ` Gerd Hoffmann
@ 2011-07-07  8:11     ` Alon Levy
  0 siblings, 0 replies; 26+ messages in thread
From: Alon Levy @ 2011-07-07  8:11 UTC (permalink / raw)
  To: Gerd Hoffmann; +Cc: yhalperi, qemu-devel

On Thu, Jul 07, 2011 at 09:47:52AM +0200, Gerd Hoffmann wrote:
>   Hi,
> 
> >+void qxl_spice_update_area_async(PCIQXLDevice *qxl, uint32_t surface_id,
> >+                           struct QXLRect *area, struct QXLRect *dirty_rects,
> >+                           uint32_t num_dirty_rects, uint32_t clear_dirty_region,
> >+                           int async)
> >+{
> >+    qemu_mutex_lock(&qxl->ssd.wlock);
> >+    if (async) {
> >+        qxl->ssd.worker->update_area_async(qxl->ssd.worker, surface_id, area, dirty_rects,
> >+                                 num_dirty_rects, clear_dirty_region);
> >+    } else {
> >+        qxl->ssd.worker->update_area(qxl->ssd.worker, surface_id, area, dirty_rects,
> >+                                 num_dirty_rects, clear_dirty_region);
> >+    }
> >+    qemu_mutex_unlock(&qxl->ssd.wlock);
> >+}
> 
> We need a plan to handle backward compatibility here.  Older
> libspice-server versions don't have the update_area_async op.
> Option one is to just not support async mode with older libraries.
> Option two is to handle the request syncronously even though the
> guest has asked for async.  I'd tend to pick option one, that makes
> things easier with S3 support because we just can't do that in any
> way with an older libspice-server.

will do.

> 
> >      switch (io_port) {
> >+    case QXL_IO_UPDATE_AREA_ASYNC:
> >+    case QXL_IO_NOTIFY_OOM_ASYNC:
> >+    case QXL_IO_MEMSLOT_ADD_ASYNC:
> >+    case QXL_IO_CREATE_PRIMARY_ASYNC:
> >+    case QXL_IO_DESTROY_PRIMARY_ASYNC:
> >+    case QXL_IO_DESTROY_SURFACE_ASYNC:
> >+    case QXL_IO_DESTROY_ALL_SURFACES_ASYNC:
> >+        async = 1;
> >+        if (d->current_async != QXL_UNDEFINED_IO) {
> >+            qxl_guest_bug(d, "%d async started before last (%d) complete\n",
> >+                io_port, d->current_async);
> 
> Better return here, ignoring the invalid request?

I wasn't sure. Both are bound to be buggy. But yeah, I guess returning at least
makes qemu correct (especially if I don't use the cookies to remember all outstanding
operations).

> 
> cheers,
>   Gerd

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

* Re: [Qemu-devel] [PATCH] qxl: move qemu_spice_add_memslot call out of qxl_add_memslot
  2011-07-07  7:39   ` Gerd Hoffmann
@ 2011-07-07  8:45     ` Alon Levy
  0 siblings, 0 replies; 26+ messages in thread
From: Alon Levy @ 2011-07-07  8:45 UTC (permalink / raw)
  To: Gerd Hoffmann; +Cc: yhalperi, qemu-devel

On Thu, Jul 07, 2011 at 09:39:34AM +0200, Gerd Hoffmann wrote:
>   Hi,
> 
> >-static void qxl_add_memslot(PCIQXLDevice *d, uint32_t slot_id, uint64_t delta)
> >+static void qxl_add_memslot(PCIQXLDevice *d, uint32_t slot_id, uint64_t delta,
> >+                            QXLDevMemSlot *memslot)
> 
> >-        qxl_add_memslot(d, val, 0);
> >+        qxl_add_memslot(d, val, 0,&memslot);
> >+        qemu_spice_add_memslot(&d->ssd,&memslot);
> 
> Do we still need this and the simliar patches?  Given that we don't
> call qemu_spice_add_memslot() from another thread any more we could
> just pass in a async flag to qxl_add_memslot().

I will. The most changes needed are to split the part after calling worker to a complete call,
I'm storing the io data inside PCIQXLDevice.

> 
> cheers,
>   Gerd
> 
> 

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

end of thread, other threads:[~2011-07-07  8:45 UTC | newest]

Thread overview: 26+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-07-06 12:19 [Qemu-devel] [PATCH] async + suspend reworked Alon Levy
2011-07-06 12:19 ` [Qemu-devel] [PATCH] qxl: add defines from latest spice-protocol Alon Levy
2011-07-07  7:33   ` Gerd Hoffmann
2011-07-07  7:43     ` Alon Levy
2011-07-06 12:19 ` [Qemu-devel] [PATCH] spice: add worker wrapper functions Alon Levy
2011-07-06 12:19 ` [Qemu-devel] [PATCH] spice: add qemu_spice_display_init_common Alon Levy
2011-07-06 12:19 ` [Qemu-devel] [PATCH] spice: lock spice worker calls Alon Levy
2011-07-07  7:40   ` Gerd Hoffmann
2011-07-07  7:52     ` Alon Levy
2011-07-06 12:19 ` [Qemu-devel] [PATCH] qxl: move qemu_spice_add_memslot call out of qxl_add_memslot Alon Levy
2011-07-07  7:39   ` Gerd Hoffmann
2011-07-07  8:45     ` Alon Levy
2011-07-06 12:19 ` [Qemu-devel] [PATCH] qxl: move qemu_spice_create_primary_surface call out of qxl_create_guest_primary Alon Levy
2011-07-06 12:19 ` [Qemu-devel] [PATCH] qxl: remove qxl_destroy_primary() Alon Levy
2011-07-06 12:19 ` [Qemu-devel] [PATCH] spice/qxl: move worker wrappers Alon Levy
2011-07-06 12:19 ` [Qemu-devel] [PATCH] qxl: fix surface tracking & locking Alon Levy
2011-07-06 12:19 ` [Qemu-devel] [PATCH] qxl: add io_port_to_string Alon Levy
2011-07-06 12:19 ` [Qemu-devel] [PATCH] qxl: error handling fixes and cleanups Alon Levy
2011-07-06 12:19 ` [Qemu-devel] [PATCH] qxl: make qxl_guest_bug take variable arguments Alon Levy
2011-07-06 12:19 ` [Qemu-devel] [PATCH] qxl: async I/O Alon Levy
2011-07-07  7:47   ` Gerd Hoffmann
2011-07-07  8:11     ` Alon Levy
2011-07-06 12:19 ` [Qemu-devel] [PATCH] qxl: bump pci rev Alon Levy
2011-07-06 12:19 ` [Qemu-devel] [PATCH] qxl: only disallow specific io's in vga mode Alon Levy
2011-07-06 12:19 ` [Qemu-devel] [PATCH] qxl: add QXL_IO_FLUSH_{SURFACES, RELEASE} for guest S3&S4 support Alon Levy
2011-07-06 12:19 ` [Qemu-devel] [PATCH] qxl: use QXL_REVISION_* Alon Levy

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.