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