[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Qemu-devel] [PATCH 2/4] spice: don't create updates in spice server
From: |
Alon Levy |
Subject: |
Re: [Qemu-devel] [PATCH 2/4] spice: don't create updates in spice server context. |
Date: |
Fri, 29 Apr 2011 14:18:54 +0300 |
User-agent: |
Mutt/1.5.21 (2010-09-15) |
On Fri, Apr 29, 2011 at 11:38:30AM +0200, Gerd Hoffmann wrote:
> This patch moves the creation of spice screen updates from the spice
> server context to qemu iothread context (display refresh timer to be
> exact). This way we avoid accessing qemu internals (display surface)
> from spice thread context which in turn allows us to simplify locking.
>
> Signed-off-by: Gerd Hoffmann <address@hidden>
> ---
> hw/qxl.c | 17 +++++++++++------
> ui/spice-display.c | 45 ++++++++++++++++++++++++++++-----------------
> ui/spice-display.h | 21 ++++++++++++++++-----
> 3 files changed, 55 insertions(+), 28 deletions(-)
>
> diff --git a/hw/qxl.c b/hw/qxl.c
> index fe4212b..bd250db 100644
> --- a/hw/qxl.c
> +++ b/hw/qxl.c
> @@ -343,18 +343,22 @@ static int interface_get_command(QXLInstance *sin,
> struct QXLCommandExt *ext)
> SimpleSpiceUpdate *update;
> QXLCommandRing *ring;
> QXLCommand *cmd;
> - int notify;
> + int notify, ret;
>
> switch (qxl->mode) {
> case QXL_MODE_VGA:
> dprint(qxl, 2, "%s: vga\n", __FUNCTION__);
> - update = qemu_spice_create_update(&qxl->ssd);
> - if (update == NULL) {
> - return false;
> + ret = false;
> + qemu_mutex_lock(&qxl->ssd.lock);
> + if (qxl->ssd.update != NULL) {
> + update = qxl->ssd.update;
> + qxl->ssd.update = NULL;
> + *ext = update->ext;
> + ret = true;
> }
> - *ext = update->ext;
> + qemu_mutex_unlock(&qxl->ssd.lock);
> qxl_log_command(qxl, "vga", ext);
> - return true;
> + return ret;
> case QXL_MODE_COMPAT:
> case QXL_MODE_NATIVE:
> case QXL_MODE_UNDEFINED:
> @@ -1304,6 +1308,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.bufsize = (16 * 1024 * 1024);
> qxl->ssd.buf = qemu_malloc(qxl->ssd.bufsize);
>
> diff --git a/ui/spice-display.c b/ui/spice-display.c
> index 020b423..39c0ba1 100644
> --- a/ui/spice-display.c
> +++ b/ui/spice-display.c
> @@ -27,7 +27,7 @@
>
> #include "spice-display.h"
>
> -static int debug = 0;
> +static int debug = 1;
Accident?
>
> static void GCC_FMT_ATTR(2, 3) dprint(int level, const char *fmt, ...)
> {
> @@ -62,14 +62,7 @@ void qemu_spice_rect_union(QXLRect *dest, const QXLRect *r)
> dest->right = MAX(dest->right, r->right);
> }
>
> -/*
> - * Called from spice server thread context (via interface_get_command).
> - *
> - * We must aquire the global qemu mutex here to make sure the
> - * DisplayState (+DisplaySurface) we are accessing doesn't change
> - * underneath us.
> - */
> -SimpleSpiceUpdate *qemu_spice_create_update(SimpleSpiceDisplay *ssd)
> +static SimpleSpiceUpdate *qemu_spice_create_update(SimpleSpiceDisplay *ssd)
> {
> SimpleSpiceUpdate *update;
> QXLDrawable *drawable;
> @@ -78,9 +71,7 @@ SimpleSpiceUpdate
> *qemu_spice_create_update(SimpleSpiceDisplay *ssd)
> uint8_t *src, *dst;
> int by, bw, bh;
>
> - qemu_mutex_lock_iothread();
> if (qemu_spice_rect_is_empty(&ssd->dirty)) {
> - qemu_mutex_unlock_iothread();
> return NULL;
> };
>
> @@ -141,7 +132,6 @@ SimpleSpiceUpdate
> *qemu_spice_create_update(SimpleSpiceDisplay *ssd)
> cmd->data = (intptr_t)drawable;
>
> memset(&ssd->dirty, 0, sizeof(ssd->dirty));
> - qemu_mutex_unlock_iothread();
> return update;
> }
>
> @@ -241,6 +231,12 @@ void qemu_spice_display_resize(SimpleSpiceDisplay *ssd)
> qemu_pf_conv_put(ssd->conv);
> ssd->conv = NULL;
>
> + qemu_mutex_lock(&ssd->lock);
> + if (ssd->update != NULL) {
> + qemu_spice_destroy_update(ssd, ssd->update);
> + ssd->update = NULL;
> + }
> + qemu_mutex_unlock(&ssd->lock);
> qemu_spice_destroy_host_primary(ssd);
> qemu_spice_create_host_primary(ssd);
>
> @@ -252,6 +248,14 @@ void qemu_spice_display_refresh(SimpleSpiceDisplay *ssd)
> {
> dprint(3, "%s:\n", __FUNCTION__);
> vga_hw_update();
> +
> + qemu_mutex_lock(&ssd->lock);
> + if (ssd->update == NULL) {
> + ssd->update = qemu_spice_create_update(ssd);
> + ssd->notify++;
> + }
> + qemu_mutex_unlock(&ssd->lock);
> +
> if (ssd->notify) {
> ssd->notify = 0;
> ssd->worker->wakeup(ssd->worker);
> @@ -298,14 +302,20 @@ static int interface_get_command(QXLInstance *sin,
> struct QXLCommandExt *ext)
> {
> SimpleSpiceDisplay *ssd = container_of(sin, SimpleSpiceDisplay, qxl);
> SimpleSpiceUpdate *update;
> + int ret = false;
>
> dprint(3, "%s:\n", __FUNCTION__);
> - update = qemu_spice_create_update(ssd);
> - if (update == NULL) {
> - return false;
> +
> + qemu_mutex_lock(&ssd->lock);
> + if (ssd->update != NULL) {
> + update = ssd->update;
> + ssd->update = NULL;
> + *ext = update->ext;
> + ret = true;
> }
> - *ext = update->ext;
> - return true;
> + qemu_mutex_unlock(&ssd->lock);
> +
> + return ret;
> }
>
> static int interface_req_cmd_notification(QXLInstance *sin)
> @@ -398,6 +408,7 @@ void qemu_spice_display_init(DisplayState *ds)
> {
> assert(sdpy.ds == NULL);
> sdpy.ds = ds;
> + qemu_mutex_init(&sdpy.lock);
> sdpy.bufsize = (16 * 1024 * 1024);
> sdpy.buf = qemu_malloc(sdpy.bufsize);
> register_displaychangelistener(ds, &display_listener);
> diff --git a/ui/spice-display.h b/ui/spice-display.h
> index aef0464..e0cc46e 100644
> --- a/ui/spice-display.h
> +++ b/ui/spice-display.h
> @@ -19,6 +19,7 @@
> #include <spice/enums.h>
> #include <spice/qxl_dev.h>
>
> +#include "qemu-thread.h"
> #include "pflib.h"
>
> #define NUM_MEMSLOTS 8
> @@ -31,7 +32,10 @@
>
> #define NUM_SURFACES 1024
>
> -typedef struct SimpleSpiceDisplay {
> +typedef struct SimpleSpiceDisplay SimpleSpiceDisplay;
> +typedef struct SimpleSpiceUpdate SimpleSpiceUpdate;
> +
> +struct SimpleSpiceDisplay {
> DisplayState *ds;
> void *buf;
> int bufsize;
> @@ -43,19 +47,26 @@ typedef struct SimpleSpiceDisplay {
> QXLRect dirty;
> int notify;
> int running;
> -} SimpleSpiceDisplay;
>
> -typedef struct SimpleSpiceUpdate {
> + /*
> + * All struct members below this comment can be accessed from
> + * both spice server and qemu (iothread) context and any access
> + * to them must be protected by the lock.
> + */
> + QemuMutex lock;
> + SimpleSpiceUpdate *update;
> +};
> +
> +struct SimpleSpiceUpdate {
> QXLDrawable drawable;
> QXLImage image;
> QXLCommandExt ext;
> uint8_t *bitmap;
> -} SimpleSpiceUpdate;
> +};
>
> int qemu_spice_rect_is_empty(const QXLRect* r);
> void qemu_spice_rect_union(QXLRect *dest, const QXLRect *r);
>
> -SimpleSpiceUpdate *qemu_spice_create_update(SimpleSpiceDisplay *sdpy);
> void qemu_spice_destroy_update(SimpleSpiceDisplay *sdpy, SimpleSpiceUpdate
> *update);
> void qemu_spice_create_host_memslot(SimpleSpiceDisplay *ssd);
> void qemu_spice_create_host_primary(SimpleSpiceDisplay *ssd);
> --
> 1.7.1
>
>
- [Qemu-devel] [PATCH 0/4] spice: fix locking, Gerd Hoffmann, 2011/04/29
- [Qemu-devel] [PATCH 1/4] Make spice dummy functions inline to fix calls not checking return values, Gerd Hoffmann, 2011/04/29
- [Qemu-devel] [PATCH 2/4] spice: don't create updates in spice server context., Gerd Hoffmann, 2011/04/29
- Re: [Qemu-devel] [PATCH 2/4] spice: don't create updates in spice server context.,
Alon Levy <=
- [Qemu-devel] [PATCH 4/4] spice: drop obsolete iothread locking, Gerd Hoffmann, 2011/04/29
- [Qemu-devel] [PATCH 3/4] spice: don't call displaystate callbacks from spice server context., Gerd Hoffmann, 2011/04/29
- Re: [Qemu-devel] [PATCH 0/4] spice: fix locking, Alon Levy, 2011/04/29