From 6daa77e0014e702c64dbee7ae6ec4c27eb7a39fe Mon Sep 17 00:00:00 2001 From: Alon Levy Date: Sun, 18 Mar 2012 12:17:50 +0100 Subject: [PATCH 7/9] qxl: introduce QXLCookie RH-Author: Alon Levy Message-id: <1332073072-27934-7-git-send-email-alevy@redhat.com> Patchwork-id: 38604 O-Subject: [PATCHv2 RHEL-6.3 qemu-kvm 6/8] qxl: introduce QXLCookie Bugzilla: 747011 RH-Acked-by: Gerd Hoffmann RH-Acked-by: Hans de Goede RH-Acked-by: Yonit Halperin Will be used in the next patch. Signed-off-by: Alon Levy Signed-off-by: Gerd Hoffmann (cherry picked from commit 2e1a98c9c1b90ca093278c6b43244dc46604d7b7) Conflicts: hw/qxl.c RHEL changes: minor conflict on dprint format string change (%ld in RHEL, got fixed to PRId64 in upstream) --- hw/qxl-render.c | 2 +- hw/qxl.c | 60 ++++++++++++++++++++++++++++++++++++++++------------ hw/qxl.h | 2 +- ui/spice-display.c | 22 ++++++++++++++++--- ui/spice-display.h | 14 ++++++++++++ 5 files changed, 82 insertions(+), 18 deletions(-) Signed-off-by: Michal Novotny --- hw/qxl-render.c | 2 +- hw/qxl.c | 60 ++++++++++++++++++++++++++++++++++++++++----------- hw/qxl.h | 2 +- ui/spice-display.c | 22 ++++++++++++++++-- ui/spice-display.h | 14 ++++++++++++ 5 files changed, 82 insertions(+), 18 deletions(-) diff --git a/hw/qxl-render.c b/hw/qxl-render.c index 3f46306..19c9449 100644 --- a/hw/qxl-render.c +++ b/hw/qxl-render.c @@ -127,7 +127,7 @@ void qxl_render_update(PCIQXLDevice *qxl) if (runstate_is_running() && qxl->guest_primary.commands) { qxl->guest_primary.commands = 0; qxl_spice_update_area(qxl, 0, &update, - dirty, ARRAY_SIZE(dirty), 1, QXL_SYNC); + dirty, ARRAY_SIZE(dirty), 1, QXL_SYNC, NULL); } if (redraw) { memset(dirty, 0, sizeof(dirty)); diff --git a/hw/qxl.c b/hw/qxl.c index b2bdd3b..899bb07 100644 --- a/hw/qxl.c +++ b/hw/qxl.c @@ -144,14 +144,15 @@ 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, - qxl_async_io async) + qxl_async_io async, struct QXLCookie *cookie) { if (async == QXL_SYNC) { qxl->ssd.worker->update_area(qxl->ssd.worker, surface_id, area, dirty_rects, num_dirty_rects, clear_dirty_region); } else { + assert(cookie != NULL); spice_qxl_update_area_async(&qxl->ssd.qxl, surface_id, area, - clear_dirty_region, 0); + clear_dirty_region, (uint64_t)cookie); } } @@ -167,9 +168,13 @@ static void qxl_spice_destroy_surface_wait_complete(PCIQXLDevice *qxl, static void qxl_spice_destroy_surface_wait(PCIQXLDevice *qxl, uint32_t id, qxl_async_io async) { + QXLCookie *cookie; + if (async) { - spice_qxl_destroy_surface_async(&qxl->ssd.qxl, id, - (uint64_t)id); + cookie = qxl_cookie_new(QXL_COOKIE_TYPE_IO, + QXL_IO_DESTROY_SURFACE_ASYNC); + cookie->u.surface_id = id; + spice_qxl_destroy_surface_async(&qxl->ssd.qxl, id, (uint64_t)cookie); } else { qxl->ssd.worker->destroy_surface_wait(qxl->ssd.worker, id); qxl_spice_destroy_surface_wait_complete(qxl, id); @@ -178,7 +183,9 @@ static void qxl_spice_destroy_surface_wait(PCIQXLDevice *qxl, uint32_t id, static void qxl_spice_flush_surfaces_async(PCIQXLDevice *qxl) { - spice_qxl_flush_surfaces_async(&qxl->ssd.qxl, 0); + spice_qxl_flush_surfaces_async(&qxl->ssd.qxl, + (uint64_t)qxl_cookie_new(QXL_COOKIE_TYPE_IO, + QXL_IO_FLUSH_SURFACES_ASYNC)); } void qxl_spice_loadvm_commands(PCIQXLDevice *qxl, struct QXLCommandExt *ext, @@ -208,7 +215,9 @@ static void qxl_spice_destroy_surfaces_complete(PCIQXLDevice *qxl) static void qxl_spice_destroy_surfaces(PCIQXLDevice *qxl, qxl_async_io async) { if (async) { - spice_qxl_destroy_surfaces_async(&qxl->ssd.qxl, 0); + spice_qxl_destroy_surfaces_async(&qxl->ssd.qxl, + (uint64_t)qxl_cookie_new(QXL_COOKIE_TYPE_IO, + QXL_IO_DESTROY_ALL_SURFACES_ASYNC)); } else { qxl->ssd.worker->destroy_surfaces(qxl->ssd.worker); qxl_spice_destroy_surfaces_complete(qxl); @@ -726,9 +735,8 @@ static int interface_flush_resources(QXLInstance *sin) static void qxl_create_guest_primary_complete(PCIQXLDevice *d); /* called from spice server thread context only */ -static void interface_async_complete(QXLInstance *sin, uint64_t cookie) +static void interface_async_complete_io(PCIQXLDevice *qxl, QXLCookie *cookie) { - PCIQXLDevice *qxl = container_of(sin, PCIQXLDevice, ssd.qxl); uint32_t current_async; qemu_mutex_lock(&qxl->async_lock); @@ -736,7 +744,16 @@ static void interface_async_complete(QXLInstance *sin, uint64_t cookie) qxl->current_async = QXL_UNDEFINED_IO; qemu_mutex_unlock(&qxl->async_lock); - dprint(qxl, 2, "async_complete: %d (%ld) done\n", current_async, cookie); + dprint(qxl, 2, "async_complete: %d (%p) done\n", current_async, cookie); + if (!cookie) { + fprintf(stderr, "qxl: %s: error, cookie is NULL\n", __func__); + return; + } + if (cookie && current_async != cookie->io) { + fprintf(stderr, + "qxl: %s: error: current_async = %d != %ld = cookie->io\n", + __func__, current_async, cookie->io); + } switch (current_async) { case QXL_IO_CREATE_PRIMARY_ASYNC: qxl_create_guest_primary_complete(qxl); @@ -745,12 +762,29 @@ static void interface_async_complete(QXLInstance *sin, uint64_t cookie) qxl_spice_destroy_surfaces_complete(qxl); break; case QXL_IO_DESTROY_SURFACE_ASYNC: - qxl_spice_destroy_surface_wait_complete(qxl, (uint32_t)cookie); + qxl_spice_destroy_surface_wait_complete(qxl, cookie->u.surface_id); break; } qxl_send_events(qxl, QXL_INTERRUPT_IO_CMD); } +/* called from spice server thread context only */ +static void interface_async_complete(QXLInstance *sin, uint64_t cookie_token) +{ + PCIQXLDevice *qxl = container_of(sin, PCIQXLDevice, ssd.qxl); + QXLCookie *cookie = (QXLCookie *)cookie_token; + + switch (cookie->type) { + case QXL_COOKIE_TYPE_IO: + interface_async_complete_io(qxl, cookie); + break; + default: + fprintf(stderr, "qxl: %s: unexpected cookie type %d\n", + __func__, cookie->type); + } + g_free(cookie); +} + static const QXLInterface qxl_interface = { .base.type = SPICE_INTERFACE_QXL, .base.description = "qxl gpu", @@ -1061,9 +1095,7 @@ static int qxl_destroy_primary(PCIQXLDevice *d, qxl_async_io async) if (d->mode == QXL_MODE_UNDEFINED) { return 0; } - dprint(d, 1, "%s\n", __FUNCTION__); - d->mode = QXL_MODE_UNDEFINED; qemu_spice_destroy_primary_surface(&d->ssd, 0, async); qxl_spice_reset_cursor(d); @@ -1190,7 +1222,9 @@ async_common: { QXLRect update = d->ram->update_area; qxl_spice_update_area(d, d->ram->update_surface, - &update, NULL, 0, 0, async); + &update, NULL, 0, 0, async, + qxl_cookie_new(QXL_COOKIE_TYPE_IO, + QXL_IO_UPDATE_AREA_ASYNC)); break; } case QXL_IO_NOTIFY_CMD: diff --git a/hw/qxl.h b/hw/qxl.h index bccf2b5..dd47395 100644 --- a/hw/qxl.h +++ b/hw/qxl.h @@ -113,7 +113,7 @@ 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, - qxl_async_io async); + qxl_async_io async, QXLCookie *cookie); void qxl_spice_loadvm_commands(PCIQXLDevice *qxl, struct QXLCommandExt *ext, uint32_t count); void qxl_spice_oom(PCIQXLDevice *qxl); diff --git a/ui/spice-display.c b/ui/spice-display.c index 267e5f8..2fe1ba9 100644 --- a/ui/spice-display.c +++ b/ui/spice-display.c @@ -63,11 +63,23 @@ void qemu_spice_rect_union(QXLRect *dest, const QXLRect *r) dest->right = MAX(dest->right, r->right); } +QXLCookie *qxl_cookie_new(int type, uint64_t io) +{ + QXLCookie *cookie; + + cookie = g_malloc0(sizeof(*cookie)); + cookie->type = type; + cookie->io = io; + return cookie; +} + void qemu_spice_add_memslot(SimpleSpiceDisplay *ssd, QXLDevMemSlot *memslot, qxl_async_io async) { if (async != QXL_SYNC) { - spice_qxl_add_memslot_async(&ssd->qxl, memslot, 0); + spice_qxl_add_memslot_async(&ssd->qxl, memslot, + (uint64_t)qxl_cookie_new(QXL_COOKIE_TYPE_IO, + QXL_IO_MEMSLOT_ADD_ASYNC)); } else { ssd->worker->add_memslot(ssd->worker, memslot); } @@ -83,7 +95,9 @@ void qemu_spice_create_primary_surface(SimpleSpiceDisplay *ssd, uint32_t id, qxl_async_io async) { if (async != QXL_SYNC) { - spice_qxl_create_primary_surface_async(&ssd->qxl, id, surface, 0); + spice_qxl_create_primary_surface_async(&ssd->qxl, id, surface, + (uint64_t)qxl_cookie_new(QXL_COOKIE_TYPE_IO, + QXL_IO_CREATE_PRIMARY_ASYNC)); } else { ssd->worker->create_primary_surface(ssd->worker, id, surface); } @@ -94,7 +108,9 @@ void qemu_spice_destroy_primary_surface(SimpleSpiceDisplay *ssd, uint32_t id, qxl_async_io async) { if (async != QXL_SYNC) { - spice_qxl_destroy_primary_surface_async(&ssd->qxl, id, 0); + spice_qxl_destroy_primary_surface_async(&ssd->qxl, id, + (uint64_t)qxl_cookie_new(QXL_COOKIE_TYPE_IO, + QXL_IO_DESTROY_PRIMARY_ASYNC)); } else { ssd->worker->destroy_primary_surface(ssd->worker, id); } diff --git a/ui/spice-display.h b/ui/spice-display.h index 85a3622..8b11f27 100644 --- a/ui/spice-display.h +++ b/ui/spice-display.h @@ -48,6 +48,20 @@ typedef enum qxl_async_io { QXL_ASYNC, } qxl_async_io; +enum { + QXL_COOKIE_TYPE_IO, +}; + +typedef struct QXLCookie { + int type; + uint64_t io; + union { + uint32_t surface_id; + } u; +} QXLCookie; + +QXLCookie *qxl_cookie_new(int type, uint64_t io); + typedef struct SimpleSpiceDisplay SimpleSpiceDisplay; typedef struct SimpleSpiceUpdate SimpleSpiceUpdate; -- 1.7.7.6