Hi,

Yes. My current thinking (and I'm continuing with UPDATE_AREA as the example,
but like you noted this needs to be done for any of the other IO's that are
causing possible delays, like DESTROY_PRIMARY, CREATE_PRIMARY) is to add
UPDATE_AREA_ASYNC to not break current drivers and be able to do the change
in steps (qemu update, win driver update, lin driver update). Regarding the 
linux
driver, we would need to have one for this to work - currently we don't have an
interrupt handler at all.

One can poll QXLRam->int_pending ...

One issue is if we want to handle multiple outstanding update area requests or
not. Doing a single one would be just adding a field for surface_id in the
QXLRam, and adding an interrupt value (we use two out of 32 bits, so we have
quite a few left).

At least for how it is currently used (primary surface only) it doesn't make sense to have multiple outstanding requests.

In general I think we should be aiming to eliminate update_area usage as much 
as possible (because
it requires a vmexit), so I guess maybe 1 will be enough in the long run.

This too.

I've started hacking up something.  qemu bits are here:
http://cgit.freedesktop.org/spice/qemu/log/?h=bz700134

spice-protocol and xf86-video-qxl patches are attached.

Not fully working yet, qemu dies with
validate_surface: panic !worker->surfaces[surface_id].context.canvas
to be investigated next week.

cheers,
  Gerd
>From d5834cd1c3ebb8283c644aba04f9f6b535fb79d1 Mon Sep 17 00:00:00 2001
From: Gerd Hoffmann <kra...@redhat.com>
Date: Fri, 17 Jun 2011 17:13:29 +0200
Subject: [PATCH] iofix

Signed-off-by: Gerd Hoffmann <kra...@redhat.com>
---
 spice/qxl_dev.h |    9 +++++++++
 1 files changed, 9 insertions(+), 0 deletions(-)

diff --git a/spice/qxl_dev.h b/spice/qxl_dev.h
index e3e0696..ccb2e4c 100644
--- a/spice/qxl_dev.h
+++ b/spice/qxl_dev.h
@@ -80,6 +80,14 @@ enum {
     QXL_IO_DESTROY_PRIMARY,
     QXL_IO_DESTROY_SURFACE_WAIT,
     QXL_IO_DESTROY_ALL_SURFACES,
+    /* appended for qxl-3 */
+    QXL_IO_UPDATE_AREA_ASYNC,
+    QXL_IO_NOIFY_OOM_ASYNC,
+    QXL_IO_MEMSLOT_ADD_ASYNC,
+    QXL_IO_CREATE_PRIMARY_ASYNC,
+    QXL_IO_DESTROY_PRIMARY_ASYNC,
+    QXL_IO_DESTROY_SURFACE_ASYNC,
+    QXL_IO_DESTROY_ALL_SURFACES_ASYNC,
 
     QXL_IO_RANGE_SIZE
 };
@@ -213,6 +221,7 @@ SPICE_RING_DECLARE(QXLReleaseRing, uint64_t, 
QXL_RELEASE_RING_SIZE);
 
 #define QXL_INTERRUPT_DISPLAY (1 << 0)
 #define QXL_INTERRUPT_CURSOR (1 << 1)
+#define QXL_INTERRUPT_IO_CMD (1 << 2)
 
 /* qxl-1 compat: append only */
 typedef struct SPICE_ATTR_PACKED QXLRam {
-- 
1.7.1

>From b6b8395bc8292dfe8906845d691b595f069dd6db Mon Sep 17 00:00:00 2001
From: Gerd Hoffmann <kra...@redhat.com>
Date: Fri, 17 Jun 2011 17:13:55 +0200
Subject: [PATCH] iofix

Signed-off-by: Gerd Hoffmann <kra...@redhat.com>
---
 src/qxl.h         |    5 +++++
 src/qxl_driver.c  |   23 ++++++++++++++++++++++-
 src/qxl_surface.c |    2 +-
 3 files changed, 28 insertions(+), 2 deletions(-)

diff --git a/src/qxl.h b/src/qxl.h
index a2daa8b..6f2c93d 100644
--- a/src/qxl.h
+++ b/src/qxl.h
@@ -335,4 +335,9 @@ void *            qxl_allocnf          (qxl_screen_t        
   *qxl,
                                        unsigned long           size);
 int               qxl_garbage_collect (qxl_screen_t *qxl);
 
+/*
+ * I/O port commands
+ */
+void qxl_update_area(qxl_screen_t *qxl);
+
 #endif // QXL_H
diff --git a/src/qxl_driver.c b/src/qxl_driver.c
index 08bf2d8..c06642e 100644
--- a/src/qxl_driver.c
+++ b/src/qxl_driver.c
@@ -143,6 +143,27 @@ qxl_handle_oom (qxl_screen_t *qxl)
     return qxl_garbage_collect (qxl);
 }
 
+static void qxl_wait_for_io_command(qxl_screen_t *qxl)
+{
+    struct QXLRam *ram_header = (void *)(
+        (unsigned long)qxl->ram + qxl->rom->ram_header_offset);
+
+    while (!(ram_header->int_pending & QXL_INTERRUPT_IO_CMD)) {
+        usleep(1000);
+    }
+    ram_header->int_pending &= QXL_INTERRUPT_IO_CMD;
+}
+
+void qxl_update_area(qxl_screen_t *qxl)
+{
+    if (qxl->pci->revision >= 3) {
+        outb (qxl->io_base + QXL_IO_UPDATE_AREA_ASYNC, 0);
+        qxl_wait_for_io_command(qxl);
+    } else {
+        outb (qxl->io_base + QXL_IO_UPDATE_AREA, 0);
+    }
+}
+
 void *
 qxl_allocnf (qxl_screen_t *qxl, unsigned long size)
 {
@@ -168,7 +189,7 @@ qxl_allocnf (qxl_screen_t *qxl, unsigned long size)
        ram_header->update_area.right = qxl->virtual_x;
        ram_header->update_surface = 0;         /* Only primary for now */
        
-       outb (qxl->io_base + QXL_IO_UPDATE_AREA, 0);
+        qxl_update_area(qxl);
        
 #if 0
        ErrorF ("eliminated memory (%d)\n", nth_oom++);
diff --git a/src/qxl_surface.c b/src/qxl_surface.c
index bf91483..433ef97 100644
--- a/src/qxl_surface.c
+++ b/src/qxl_surface.c
@@ -920,7 +920,7 @@ download_box (qxl_surface_t *surface, int x1, int y1, int 
x2, int y2)
     ErrorF ("Issuing update command for %d\n", surface->id);
 #endif
 
-    outb (surface->cache->qxl->io_base + QXL_IO_UPDATE_AREA, 0);
+    qxl_update_area(surface->cache->qxl);
 
     pixman_image_composite (PIXMAN_OP_SRC,
                            surface->dev_image,
-- 
1.7.1

_______________________________________________
Spice-devel mailing list
Spice-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/spice-devel

Reply via email to