[fedora-virt] qxl locking fixes round 2 (was: Re: spice and qemu 0.14)
Alon Levy
alevy at redhat.com
Mon Mar 14 19:48:44 UTC 2011
On Mon, Mar 14, 2011 at 05:00:46PM +0100, Gianluca Cecchi wrote:
> On Mon, Mar 14, 2011 at 4:08 PM, Alon Levy <alevy at redhat.com> wrote:
> > On Mon, Mar 14, 2011 at 02:59:30PM +0100, Gianluca Cecchi wrote:
> >> On Mon, Mar 14, 2011 at 12:42 PM, Gianluca Cecchi
> >> <gianluca.cecchi at gmail.com> wrote:
> >> >
> >> > I'm going to test...
> >> > Gianluca
> >> >
> >>
> >> If I run the w2k3 vm with vga as video adapter I get normal behaviour.
> >> If I set qxl and spice, the vm enters the initial black screen with
> >> bars at bottom and then shutdowns:
> >
> > shutdowns? anyway, this patchset is not good enough for qemu-kvm, will
> > reply to thread when we have something working.
> >
>
> Ok.
> shutdowns in log file.
> From a console point of view it powers off directly...
here is a new patchset, it's basically the old plus first patch of reverting gerd's
(cpu_single_env hackage) and last one removing all the locks, after being
convinced by hans (cc'ed) and uri that it should work. Tested with rhel
qemu-kvm, which should be identical (tm) to fedora qemu-kvm. On account of
being too lame to figure out how to add the patches to qemu.spec and doing a
scratch build right now..
Happy testing,
Alon
-------------- next part --------------
>From fb0b57bf9857ce22bcf805d7e23b82301563b76c Mon Sep 17 00:00:00 2001
From: Alon Levy <alevy at redhat.com>
Date: Mon, 14 Mar 2011 21:34:14 +0200
Subject: [PATCH 1/6] Revert "spice/qxl: locking fix for qemu-kvm"
This reverts commit 15ba0114aa3ddedbeb2519cb0a8755a05f0a1d38.
---
hw/qxl.c | 37 ++++++++-----------------------------
ui/spice-display.c | 12 ++++++------
ui/spice-display.h | 6 ------
3 files changed, 14 insertions(+), 41 deletions(-)
diff --git a/hw/qxl.c b/hw/qxl.c
index 58d6222..61fd1fc 100644
--- a/hw/qxl.c
+++ b/hw/qxl.c
@@ -125,27 +125,6 @@ static void qxl_reset_memslots(PCIQXLDevice *d);
static void qxl_reset_surfaces(PCIQXLDevice *d);
static void qxl_ring_set_dirty(PCIQXLDevice *qxl);
-/* qemu-kvm locking ... */
-void qxl_unlock_iothread(SimpleSpiceDisplay *ssd)
-{
- if (cpu_single_env) {
- assert(ssd->env == NULL);
- ssd->env = cpu_single_env;
- cpu_single_env = NULL;
- }
- qemu_mutex_unlock_iothread();
-}
-
-void qxl_lock_iothread(SimpleSpiceDisplay *ssd)
-{
- qemu_mutex_lock_iothread();
- if (ssd->env) {
- assert(cpu_single_env == NULL);
- cpu_single_env = ssd->env;
- ssd->env = NULL;
- }
-}
-
static inline uint32_t msb_mask(uint32_t val)
{
uint32_t mask;
@@ -683,10 +662,10 @@ static void qxl_hard_reset(PCIQXLDevice *d, int loadvm)
dprint(d, 1, "%s: start%s\n", __FUNCTION__,
loadvm ? " (loadvm)" : "");
- qxl_unlock_iothread(&d->ssd);
+ qemu_mutex_unlock_iothread();
d->ssd.worker->reset_cursor(d->ssd.worker);
d->ssd.worker->reset_image_cache(d->ssd.worker);
- qxl_lock_iothread(&d->ssd);
+ qemu_mutex_lock_iothread();
qxl_reset_surfaces(d);
qxl_reset_memslots(d);
@@ -816,9 +795,9 @@ static void qxl_reset_surfaces(PCIQXLDevice *d)
{
dprint(d, 1, "%s:\n", __FUNCTION__);
d->mode = QXL_MODE_UNDEFINED;
- qxl_unlock_iothread(&d->ssd);
+ qemu_mutex_unlock_iothread();
d->ssd.worker->destroy_surfaces(d->ssd.worker);
- qxl_lock_iothread(&d->ssd);
+ qemu_mutex_lock_iothread();
memset(&d->guest_surfaces.cmds, 0, sizeof(d->guest_surfaces.cmds));
}
@@ -887,9 +866,9 @@ static void qxl_destroy_primary(PCIQXLDevice *d)
dprint(d, 1, "%s\n", __FUNCTION__);
d->mode = QXL_MODE_UNDEFINED;
- qxl_unlock_iothread(&d->ssd);
+ qemu_mutex_unlock_iothread();
d->ssd.worker->destroy_primary_surface(d->ssd.worker, 0);
- qxl_lock_iothread(&d->ssd);
+ qemu_mutex_lock_iothread();
}
static void qxl_set_mode(PCIQXLDevice *d, int modenr, int loadvm)
@@ -959,10 +938,10 @@ static void ioport_write(void *opaque, uint32_t addr, uint32_t val)
case QXL_IO_UPDATE_AREA:
{
QXLRect update = d->ram->update_area;
- qxl_unlock_iothread(&d->ssd);
+ qemu_mutex_unlock_iothread();
d->ssd.worker->update_area(d->ssd.worker, d->ram->update_surface,
&update, NULL, 0, 0);
- qxl_lock_iothread(&d->ssd);
+ qemu_mutex_lock_iothread();
break;
}
case QXL_IO_NOTIFY_CMD:
diff --git a/ui/spice-display.c b/ui/spice-display.c
index 3f978e5..99d9fd6 100644
--- a/ui/spice-display.c
+++ b/ui/spice-display.c
@@ -187,18 +187,18 @@ void qemu_spice_create_host_primary(SimpleSpiceDisplay *ssd)
surface.mem = (intptr_t)ssd->buf;
surface.group_id = MEMSLOT_GROUP_HOST;
- qxl_unlock_iothread(ssd);
+ qemu_mutex_unlock_iothread();
ssd->worker->create_primary_surface(ssd->worker, 0, &surface);
- qxl_lock_iothread(ssd);
+ qemu_mutex_lock_iothread();
}
void qemu_spice_destroy_host_primary(SimpleSpiceDisplay *ssd)
{
dprint(1, "%s:\n", __FUNCTION__);
- qxl_unlock_iothread(ssd);
+ qemu_mutex_unlock_iothread();
ssd->worker->destroy_primary_surface(ssd->worker, 0);
- qxl_lock_iothread(ssd);
+ qemu_mutex_lock_iothread();
}
void qemu_spice_vm_change_state_handler(void *opaque, int running, int reason)
@@ -208,9 +208,9 @@ void qemu_spice_vm_change_state_handler(void *opaque, int running, int reason)
if (running) {
ssd->worker->start(ssd->worker);
} else {
- qxl_unlock_iothread(ssd);
+ qemu_mutex_unlock_iothread();
ssd->worker->stop(ssd->worker);
- qxl_lock_iothread(ssd);
+ qemu_mutex_lock_iothread();
}
ssd->running = running;
}
diff --git a/ui/spice-display.h b/ui/spice-display.h
index df74828..aef0464 100644
--- a/ui/spice-display.h
+++ b/ui/spice-display.h
@@ -43,9 +43,6 @@ typedef struct SimpleSpiceDisplay {
QXLRect dirty;
int notify;
int running;
-
- /* qemu-kvm locking ... */
- void *env;
} SimpleSpiceDisplay;
typedef struct SimpleSpiceUpdate {
@@ -55,9 +52,6 @@ typedef struct SimpleSpiceUpdate {
uint8_t *bitmap;
} SimpleSpiceUpdate;
-void qxl_unlock_iothread(SimpleSpiceDisplay *ssd);
-void qxl_lock_iothread(SimpleSpiceDisplay *ssd);
-
int qemu_spice_rect_is_empty(const QXLRect* r);
void qemu_spice_rect_union(QXLRect *dest, const QXLRect *r);
--
1.7.4.1
-------------- next part --------------
>From a844bf615a17b26e0a62856c4cabf72ffed705b1 Mon Sep 17 00:00:00 2001
From: Uri Lublin <uril at redhat.com>
Date: Sun, 13 Mar 2011 19:45:45 +0200
Subject: [PATCH 2/6] qxl: fix locking, do not lock from spice server thread
instead request iothread to do the operation, and wait for its response.
---
hw/qxl.c | 70 +++++++++++++++++++++++++++++++++++++++++++++------
hw/qxl.h | 3 +-
ui/spice-display.c | 7 +++--
ui/spice-display.h | 5 +++
4 files changed, 72 insertions(+), 13 deletions(-)
diff --git a/hw/qxl.c b/hw/qxl.c
index 61fd1fc..d36c06c 100644
--- a/hw/qxl.c
+++ b/hw/qxl.c
@@ -28,6 +28,8 @@
#include "qxl.h"
+#define ASSERT assert
+
#undef SPICE_RING_PROD_ITEM
#define SPICE_RING_PROD_ITEM(r, ret) { \
typeof(r) start = r; \
@@ -117,6 +119,15 @@ static QXLMode qxl_modes[] = {
#endif
};
+
+/*
+ * commands/requests from server thread to iothread.
+ */
+enum {
+ QXL_SERVER_SET_IRQ = 1,
+ QXL_SERVER_CREATE_UPDATE,
+};
+
static PCIQXLDevice *qxl0;
static void qxl_send_events(PCIQXLDevice *d, uint32_t events);
@@ -344,11 +355,24 @@ static int interface_get_command(QXLInstance *sin, struct QXLCommandExt *ext)
QXLCommandRing *ring;
QXLCommand *cmd;
int notify;
+ int r;
+ unsigned char req, ack;
switch (qxl->mode) {
case QXL_MODE_VGA:
dprint(qxl, 2, "%s: vga\n", __FUNCTION__);
- update = qemu_spice_create_update(&qxl->ssd);
+
+ /* TODO -- 1. check write+read return codes. retry upon e.g. EINTR */
+ /* TODO -- 2. change the imlpementation inside qemu_spice_create_update (option rename+add functions) */
+ req = QXL_SERVER_CREATE_UPDATE;
+ r = write(qxl->pipe[1], &req , 1);
+ ASSERT(r == 1);
+ ack = 0;
+ r = read(qxl->pipe_out[0], &ack, 1);
+ ASSERT(r == 1);
+ ASSERT(ack == QXL_SERVER_CREATE_UPDATE); // ack==req
+ update = qxl->ssd.update;
+ //update = qemu_spice_create_update(&qxl->ssd);
if (update == NULL) {
return false;
}
@@ -1058,16 +1082,27 @@ static void qxl_map(PCIDevice *pci, int region_num,
static void pipe_read(void *opaque)
{
PCIQXLDevice *d = opaque;
- char dummy;
+ unsigned char cmd;
int len;
do {
- len = read(d->pipe[0], &dummy, sizeof(dummy));
- } while (len == sizeof(dummy));
- qxl_set_irq(d);
+ len = read(d->pipe[0], &cmd, sizeof(cmd));
+ } while (len == sizeof(cmd));
+ switch (cmd) {
+ case QXL_SERVER_SET_IRQ:
+ qxl_set_irq(d);
+ break;
+ case QXL_SERVER_CREATE_UPDATE:
+ d->ssd.update = qemu_spice_create_update(&d->ssd);
+ len = write(d->pipe_out[1], &cmd, 1);
+ ASSERT(len == 1);
+ break;
+ default:
+ fprintf(stderr, "%s: unknown cmd %u\n", __FUNCTION__, cmd);
+ abort();
+ }
}
-/* called from spice server thread context only */
static void qxl_send_events(PCIQXLDevice *d, uint32_t events)
{
uint32_t old_pending;
@@ -1079,10 +1114,17 @@ static void qxl_send_events(PCIQXLDevice *d, uint32_t events)
return;
}
if (pthread_self() == d->main) {
+ /* running in io_thread thread */
qxl_set_irq(d);
} else {
- if (write(d->pipe[1], d, 1) != 1) {
- dprint(d, 1, "%s: write to pipe failed\n", __FUNCTION__);
+ /* called from spice-server thread */
+ int ret;
+ unsigned char ack = QXL_SERVER_SET_IRQ;
+ ret = write(d->pipe[1], &ack, 1);
+ if (ret != 1) {
+ fprintf(stderr, "%s: write to iothread pipe failed (%d) %m\n",
+ __FUNCTION__, ret);
+ perror("");
}
}
}
@@ -1090,19 +1132,29 @@ static void qxl_send_events(PCIQXLDevice *d, uint32_t events)
static void init_pipe_signaling(PCIQXLDevice *d)
{
if (pipe(d->pipe) < 0) {
- dprint(d, 1, "%s: pipe creation failed\n", __FUNCTION__);
+ fprintf(stderr, "%s: pipe creation failed\n", __FUNCTION__);
return;
}
+
+#if 0 // why non-blocking ? code does not check that case
#ifdef CONFIG_IOTHREAD
fcntl(d->pipe[0], F_SETFL, O_NONBLOCK);
#else
fcntl(d->pipe[0], F_SETFL, O_NONBLOCK /* | O_ASYNC */);
#endif
fcntl(d->pipe[1], F_SETFL, O_NONBLOCK);
+#endif //(if 0)
+
fcntl(d->pipe[0], F_SETOWN, getpid());
d->main = pthread_self();
qemu_set_fd_handler(d->pipe[0], pipe_read, NULL, d);
+
+
+ if (pipe(d->pipe_out) < 0) {
+ fprintf(stderr, "%s: pipe creation failed\n", __FUNCTION__);
+ return;
+ }
}
/* graphics console */
diff --git a/hw/qxl.h b/hw/qxl.h
index f6c450d..b153e4b 100644
--- a/hw/qxl.h
+++ b/hw/qxl.h
@@ -57,7 +57,8 @@ typedef struct PCIQXLDevice {
/* thread signaling */
pthread_t main;
- int pipe[2];
+ int pipe[2]; /* to iothread */
+ int pipe_out[2]; /* from iothread */
/* ram pci bar */
QXLRam *ram;
diff --git a/ui/spice-display.c b/ui/spice-display.c
index 99d9fd6..c7cf3b8 100644
--- a/ui/spice-display.c
+++ b/ui/spice-display.c
@@ -79,9 +79,9 @@ SimpleSpiceUpdate *qemu_spice_create_update(SimpleSpiceDisplay *ssd)
uint8_t *src, *dst;
int by, bw, bh;
- qemu_mutex_lock_iothread();
+ /* qemu_mutex_lock_iothread(); */
if (qemu_spice_rect_is_empty(&ssd->dirty)) {
- qemu_mutex_unlock_iothread();
+ /* qemu_mutex_unlock_iothread(); */
return NULL;
};
@@ -142,7 +142,7 @@ SimpleSpiceUpdate *qemu_spice_create_update(SimpleSpiceDisplay *ssd)
cmd->data = (intptr_t)drawable;
memset(&ssd->dirty, 0, sizeof(ssd->dirty));
- qemu_mutex_unlock_iothread();
+ /* qemu_mutex_unlock_iothread(); */
return update;
}
@@ -301,6 +301,7 @@ static int interface_get_command(QXLInstance *sin, struct QXLCommandExt *ext)
SimpleSpiceUpdate *update;
dprint(3, "%s:\n", __FUNCTION__);
+ assert((const char *)"TODO -- fixme" == NULL);
update = qemu_spice_create_update(ssd);
if (update == NULL) {
return false;
diff --git a/ui/spice-display.h b/ui/spice-display.h
index aef0464..e1fc398 100644
--- a/ui/spice-display.h
+++ b/ui/spice-display.h
@@ -31,6 +31,8 @@
#define NUM_SURFACES 1024
+struct SimpleSpiceUpdate;
+
typedef struct SimpleSpiceDisplay {
DisplayState *ds;
void *buf;
@@ -43,6 +45,9 @@ typedef struct SimpleSpiceDisplay {
QXLRect dirty;
int notify;
int running;
+
+ /* ssd updates (one request/command at a time) */
+ struct SimpleSpiceUpdate *update;
} SimpleSpiceDisplay;
typedef struct SimpleSpiceUpdate {
--
1.7.4.1
-------------- next part --------------
>From 9b18471b053b80a12f64bf65d5e12ba590edc208 Mon Sep 17 00:00:00 2001
From: Uri Lublin <uril at redhat.com>
Date: Sun, 13 Mar 2011 19:45:46 +0200
Subject: [PATCH 3/6] qxl: read_pipe: keep reading as long as there are things in the queue
---
hw/qxl.c | 39 ++++++++++++++++++++++++---------------
1 files changed, 24 insertions(+), 15 deletions(-)
diff --git a/hw/qxl.c b/hw/qxl.c
index d36c06c..d040bee 100644
--- a/hw/qxl.c
+++ b/hw/qxl.c
@@ -1083,24 +1083,33 @@ static void pipe_read(void *opaque)
{
PCIQXLDevice *d = opaque;
unsigned char cmd;
- int len;
+ int len, again = 1, set_irq_done = 0;
do {
+ cmd = 0;
len = read(d->pipe[0], &cmd, sizeof(cmd));
- } while (len == sizeof(cmd));
- switch (cmd) {
- case QXL_SERVER_SET_IRQ:
- qxl_set_irq(d);
- break;
- case QXL_SERVER_CREATE_UPDATE:
- d->ssd.update = qemu_spice_create_update(&d->ssd);
- len = write(d->pipe_out[1], &cmd, 1);
- ASSERT(len == 1);
- break;
- default:
- fprintf(stderr, "%s: unknown cmd %u\n", __FUNCTION__, cmd);
- abort();
- }
+ if ((len < 0) && (errno == EINTR)) {
+ continue;
+ }
+ switch (cmd) {
+ case QXL_SERVER_SET_IRQ:
+ if (set_irq_done == 0) {
+ /* no need to do it more than once */
+ set_irq_done = 1;
+ qxl_set_irq(d);
+ }
+ break;
+ case QXL_SERVER_CREATE_UPDATE:
+ again = 0;
+ d->ssd.update = qemu_spice_create_update(&d->ssd);
+ len = write(d->pipe_out[1], &cmd, 1);
+ ASSERT(len == 1);
+ break;
+ default:
+ fprintf(stderr, "%s: unknown cmd %u\n", __FUNCTION__, cmd);
+ abort();
+ }
+ } while (again);
}
static void qxl_send_events(PCIQXLDevice *d, uint32_t events)
--
1.7.4.1
-------------- next part --------------
>From 861be2ff3c860e180db90f7f6928fbb427d7971a Mon Sep 17 00:00:00 2001
From: Alon Levy <alevy at redhat.com>
Date: Sun, 13 Mar 2011 21:58:24 +0200
Subject: [PATCH 4/6] qxl vga update: don't read, preventing pipe loop of death
---
hw/qxl.c | 44 +++++++++++++++++++++++++-------------------
ui/spice-display.h | 1 +
2 files changed, 26 insertions(+), 19 deletions(-)
diff --git a/hw/qxl.c b/hw/qxl.c
index d040bee..dfbb740 100644
--- a/hw/qxl.c
+++ b/hw/qxl.c
@@ -356,7 +356,7 @@ static int interface_get_command(QXLInstance *sin, struct QXLCommandExt *ext)
QXLCommand *cmd;
int notify;
int r;
- unsigned char req, ack;
+ unsigned char req;
switch (qxl->mode) {
case QXL_MODE_VGA:
@@ -364,21 +364,21 @@ static int interface_get_command(QXLInstance *sin, struct QXLCommandExt *ext)
/* TODO -- 1. check write+read return codes. retry upon e.g. EINTR */
/* TODO -- 2. change the imlpementation inside qemu_spice_create_update (option rename+add functions) */
- req = QXL_SERVER_CREATE_UPDATE;
- r = write(qxl->pipe[1], &req , 1);
- ASSERT(r == 1);
- ack = 0;
- r = read(qxl->pipe_out[0], &ack, 1);
- ASSERT(r == 1);
- ASSERT(ack == QXL_SERVER_CREATE_UPDATE); // ack==req
update = qxl->ssd.update;
- //update = qemu_spice_create_update(&qxl->ssd);
- if (update == NULL) {
+ if (update != NULL) {
+ qxl->ssd.update = NULL;
+ *ext = update->ext;
+ qxl_log_command(qxl, "vga", ext);
+ return true;
+ } else {
+ if (!qxl->ssd.waiting_for_update) {
+ qxl->ssd.waiting_for_update = 1;
+ req = QXL_SERVER_CREATE_UPDATE;
+ r = write(qxl->pipe[1], &req , 1);
+ ASSERT(r == 1);
+ }
return false;
}
- *ext = update->ext;
- qxl_log_command(qxl, "vga", ext);
- return true;
case QXL_MODE_COMPAT:
case QXL_MODE_NATIVE:
case QXL_MODE_UNDEFINED:
@@ -611,6 +611,7 @@ static void qxl_enter_vga_mode(PCIQXLDevice *d)
qemu_spice_create_host_primary(&d->ssd);
d->mode = QXL_MODE_VGA;
memset(&d->ssd.dirty, 0, sizeof(d->ssd.dirty));
+ d->ssd.waiting_for_update = 0;
}
static void qxl_exit_vga_mode(PCIQXLDevice *d)
@@ -1084,6 +1085,7 @@ static void pipe_read(void *opaque)
PCIQXLDevice *d = opaque;
unsigned char cmd;
int len, again = 1, set_irq_done = 0;
+ int create_update = 0;
do {
cmd = 0;
@@ -1091,6 +1093,9 @@ static void pipe_read(void *opaque)
if ((len < 0) && (errno == EINTR)) {
continue;
}
+ if (len <= 0) {
+ break;
+ }
switch (cmd) {
case QXL_SERVER_SET_IRQ:
if (set_irq_done == 0) {
@@ -1100,16 +1105,19 @@ static void pipe_read(void *opaque)
}
break;
case QXL_SERVER_CREATE_UPDATE:
- again = 0;
- d->ssd.update = qemu_spice_create_update(&d->ssd);
- len = write(d->pipe_out[1], &cmd, 1);
- ASSERT(len == 1);
+ create_update = 1;
break;
default:
fprintf(stderr, "%s: unknown cmd %u\n", __FUNCTION__, cmd);
abort();
}
} while (again);
+ if (create_update) {
+ if (d->ssd.update == NULL) {
+ d->ssd.update = qemu_spice_create_update(&d->ssd);
+ }
+ d->ssd.waiting_for_update = 0;
+ }
}
static void qxl_send_events(PCIQXLDevice *d, uint32_t events)
@@ -1145,14 +1153,12 @@ static void init_pipe_signaling(PCIQXLDevice *d)
return;
}
-#if 0 // why non-blocking ? code does not check that case
#ifdef CONFIG_IOTHREAD
fcntl(d->pipe[0], F_SETFL, O_NONBLOCK);
#else
fcntl(d->pipe[0], F_SETFL, O_NONBLOCK /* | O_ASYNC */);
#endif
fcntl(d->pipe[1], F_SETFL, O_NONBLOCK);
-#endif //(if 0)
fcntl(d->pipe[0], F_SETOWN, getpid());
diff --git a/ui/spice-display.h b/ui/spice-display.h
index e1fc398..37ce297 100644
--- a/ui/spice-display.h
+++ b/ui/spice-display.h
@@ -48,6 +48,7 @@ typedef struct SimpleSpiceDisplay {
/* ssd updates (one request/command at a time) */
struct SimpleSpiceUpdate *update;
+ int waiting_for_update;
} SimpleSpiceDisplay;
typedef struct SimpleSpiceUpdate {
--
1.7.4.1
-------------- next part --------------
>From 19a69e023bf4eeb02070c14576c1964af5feaa8d Mon Sep 17 00:00:00 2001
From: Alon Levy <alevy at redhat.com>
Date: Mon, 14 Mar 2011 21:36:53 +0200
Subject: [PATCH 5/6] hw/qxl-render: add TODO's for cursor updated
when server calls get_cursor_command, and we have an active ds
cursor related callback in non vga mode, we need to lock to prevent
the iothread (via sdl/vnc) from touching the ds as well.
This is currently untested, since it requires running spice with sdl/vnc
at the same time. It appears it will be broken unless we use the same
pipe we pass QXL_SERVER_* stuff to (SET_IRQ and CREATE_UPDATE) atm.
---
hw/qxl-render.c | 4 ++++
1 files changed, 4 insertions(+), 0 deletions(-)
diff --git a/hw/qxl-render.c b/hw/qxl-render.c
index 58965e0..643b924 100644
--- a/hw/qxl-render.c
+++ b/hw/qxl-render.c
@@ -209,6 +209,8 @@ void qxl_render_cursor(PCIQXLDevice *qxl, QXLCommandExt *ext)
if (c == NULL) {
c = cursor_builtin_left_ptr();
}
+ /* TODO LOCK: move to pipe via QXL_SERVER_CURSOR_SET?
+ * can this be fire and forget (i.e. can be async)? */
qemu_mutex_lock_iothread();
qxl->ssd.ds->cursor_define(c);
qxl->ssd.ds->mouse_set(x, y, 1);
@@ -218,6 +220,8 @@ void qxl_render_cursor(PCIQXLDevice *qxl, QXLCommandExt *ext)
case QXL_CURSOR_MOVE:
x = cmd->u.position.x;
y = cmd->u.position.y;
+ /* TODO LOCK: move to pipe via QXL_SERVER_MOUSE_SET?
+ * can this be fire and forget (i.e. can be async)? */
qemu_mutex_lock_iothread();
qxl->ssd.ds->mouse_set(x, y, 1);
qemu_mutex_unlock_iothread();
--
1.7.4.1
-------------- next part --------------
>From 7a91084fa2515070787c454dc9a998de0ba4eff9 Mon Sep 17 00:00:00 2001
From: Alon Levy <alevy at redhat.com>
Date: Mon, 14 Mar 2011 21:39:10 +0200
Subject: [PATCH 6/6] qxl/spice: remove left lock dropping
now that we don't need the lock in the spice-server thread, there
is no reason to drop it in the first place. This means we no longer
need to keep track of cpu_single_env either.
---
hw/qxl.c | 8 --------
ui/spice-display.c | 6 ------
2 files changed, 0 insertions(+), 14 deletions(-)
diff --git a/hw/qxl.c b/hw/qxl.c
index dfbb740..c26f6df 100644
--- a/hw/qxl.c
+++ b/hw/qxl.c
@@ -687,10 +687,8 @@ static void qxl_hard_reset(PCIQXLDevice *d, int loadvm)
dprint(d, 1, "%s: start%s\n", __FUNCTION__,
loadvm ? " (loadvm)" : "");
- qemu_mutex_unlock_iothread();
d->ssd.worker->reset_cursor(d->ssd.worker);
d->ssd.worker->reset_image_cache(d->ssd.worker);
- qemu_mutex_lock_iothread();
qxl_reset_surfaces(d);
qxl_reset_memslots(d);
@@ -820,9 +818,7 @@ static void qxl_reset_surfaces(PCIQXLDevice *d)
{
dprint(d, 1, "%s:\n", __FUNCTION__);
d->mode = QXL_MODE_UNDEFINED;
- qemu_mutex_unlock_iothread();
d->ssd.worker->destroy_surfaces(d->ssd.worker);
- qemu_mutex_lock_iothread();
memset(&d->guest_surfaces.cmds, 0, sizeof(d->guest_surfaces.cmds));
}
@@ -891,9 +887,7 @@ static void qxl_destroy_primary(PCIQXLDevice *d)
dprint(d, 1, "%s\n", __FUNCTION__);
d->mode = QXL_MODE_UNDEFINED;
- qemu_mutex_unlock_iothread();
d->ssd.worker->destroy_primary_surface(d->ssd.worker, 0);
- qemu_mutex_lock_iothread();
}
static void qxl_set_mode(PCIQXLDevice *d, int modenr, int loadvm)
@@ -963,10 +957,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_mutex_unlock_iothread();
d->ssd.worker->update_area(d->ssd.worker, d->ram->update_surface,
&update, NULL, 0, 0);
- qemu_mutex_lock_iothread();
break;
}
case QXL_IO_NOTIFY_CMD:
diff --git a/ui/spice-display.c b/ui/spice-display.c
index c7cf3b8..33760e6 100644
--- a/ui/spice-display.c
+++ b/ui/spice-display.c
@@ -187,18 +187,14 @@ void qemu_spice_create_host_primary(SimpleSpiceDisplay *ssd)
surface.mem = (intptr_t)ssd->buf;
surface.group_id = MEMSLOT_GROUP_HOST;
- qemu_mutex_unlock_iothread();
ssd->worker->create_primary_surface(ssd->worker, 0, &surface);
- qemu_mutex_lock_iothread();
}
void qemu_spice_destroy_host_primary(SimpleSpiceDisplay *ssd)
{
dprint(1, "%s:\n", __FUNCTION__);
- qemu_mutex_unlock_iothread();
ssd->worker->destroy_primary_surface(ssd->worker, 0);
- qemu_mutex_lock_iothread();
}
void qemu_spice_vm_change_state_handler(void *opaque, int running, int reason)
@@ -208,9 +204,7 @@ void qemu_spice_vm_change_state_handler(void *opaque, int running, int reason)
if (running) {
ssd->worker->start(ssd->worker);
} else {
- qemu_mutex_unlock_iothread();
ssd->worker->stop(ssd->worker);
- qemu_mutex_lock_iothread();
}
ssd->running = running;
}
--
1.7.4.1
More information about the virt
mailing list