> > > > Ping? I would like to move forward with having this fix temporarily in > > spice-server even if in the long run, we'll be fixing QEMU too. > > This would ease the upgrade path, as having this patch means we don't > > tie upgrades to spice-server 0.14 with QEMU upgrades, it does not matter > > if you upgrade both at once or not, spice-server will have the same > > behaviour as in the 0.12 branch. > > > > Christophe > > > > When do you plan to remove this patch from spice-server? > > > On Thu, Apr 05, 2018 at 10:36:27AM +0200, Christophe Fergeau wrote: > > > There's an implicit API/ABI contract between QEMU and SPICE that SPICE > > > will keep the guest QXL resources alive as long as QEMU can hold a > > > pointer to them. This implicit contract was broken in 1c6e7cf7 "Release > > > cursor as soon as possible", causing crashes at migration time. > > > While the proper fix would be in QEMU so that spice-server does not need > > > to have that kind of knowledge regarding QEMU internal implementation, > > > this commit reverts to the pre-1c6e7cf7 behaviour to avoid a regression > > > while QEMU is being fixed. > > > > > > https://bugzilla.redhat.com/show_bug.cgi?id=1540919 > > > > > > Signed-off-by: Christophe Fergeau <cfergeau@xxxxxxxxxx> > > Would not be better to add a qxl field in RedCursorCmd and free the resource > in red_put_cursor_cmd? > This patch looks pretty invasive. > Like: diff --git a/server/red-parse-qxl.c b/server/red-parse-qxl.c index 69748698..f421a35b 100644 --- a/server/red-parse-qxl.c +++ b/server/red-parse-qxl.c @@ -26,6 +26,7 @@ #include "red-common.h" #include "memslot.h" #include "red-parse-qxl.h" +#include "red-qxl.h" /* Max size in bytes for any data field used in a QXL command. * This will for example be useful to prevent the guest from saturating the @@ -1495,6 +1496,9 @@ void red_put_cursor_cmd(RedCursorCmd *red) { switch (red->type) { case QXL_CURSOR_SET: + if (red->qxl) { + red_qxl_release_resource(red->qxl, red->release_info_ext); + } red_put_cursor(&red->u.set.shape); break; } diff --git a/server/red-parse-qxl.h b/server/red-parse-qxl.h index ce7d8b05..a33f36ad 100644 --- a/server/red-parse-qxl.h +++ b/server/red-parse-qxl.h @@ -99,6 +99,7 @@ typedef struct RedSurfaceCmd { } RedSurfaceCmd; typedef struct RedCursorCmd { + QXLInstance *qxl; QXLReleaseInfoExt release_info_ext; uint8_t type; union { diff --git a/server/red-worker.c b/server/red-worker.c index 387f500e..eb927f3e 100644 --- a/server/red-worker.c +++ b/server/red-worker.c @@ -118,7 +118,7 @@ static gboolean red_process_cursor_cmd(RedWorker *worker, const QXLCommandExt *e g_free(cursor_cmd); return FALSE; } - red_qxl_release_resource(worker->qxl, cursor_cmd->release_info_ext); + cursor_cmd->qxl = worker->qxl; cursor_channel_process_cmd(worker->cursor_channel, cursor_cmd); return TRUE; } Frediano > > > --- > > > server/cursor-channel.c | 16 +++++++++++++--- > > > server/cursor-channel.h | 5 ++++- > > > server/red-stream-device.c | 4 ++-- > > > server/red-worker.c | 10 ++++++++-- > > > 4 files changed, 27 insertions(+), 8 deletions(-) > > > > > > diff --git a/server/cursor-channel.c b/server/cursor-channel.c > > > index 522261e3f..a7bee9815 100644 > > > --- a/server/cursor-channel.c > > > +++ b/server/cursor-channel.c > > > @@ -31,6 +31,8 @@ > > > typedef struct RedCursorPipeItem { > > > RedPipeItem base; > > > RedCursorCmd *red_cursor; > > > + ReleaseCommandCb release_command_cb; > > > + gpointer user_data; > > > } RedCursorPipeItem; > > > > > > struct CursorChannel > > > @@ -54,7 +56,9 @@ G_DEFINE_TYPE(CursorChannel, cursor_channel, > > > TYPE_COMMON_GRAPHICS_CHANNEL) > > > > > > static void cursor_pipe_item_free(RedPipeItem *pipe_item); > > > > > > -static RedCursorPipeItem *cursor_pipe_item_new(RedCursorCmd *cmd) > > > +static RedCursorPipeItem *cursor_pipe_item_new(RedCursorCmd *cmd, > > > + ReleaseCommandCb > > > release_command_cb, > > > + gpointer user_data) > > > { > > > RedCursorPipeItem *item = g_new0(RedCursorPipeItem, 1); > > > > > > @@ -63,6 +67,8 @@ static RedCursorPipeItem > > > *cursor_pipe_item_new(RedCursorCmd *cmd) > > > red_pipe_item_init_full(&item->base, RED_PIPE_ITEM_TYPE_CURSOR, > > > cursor_pipe_item_free); > > > item->red_cursor = cmd; > > > + item->release_command_cb = release_command_cb; > > > + item->user_data = user_data; > > > > > > return item; > > > } > > > @@ -73,6 +79,9 @@ static void cursor_pipe_item_free(RedPipeItem *base) > > > RedCursorPipeItem *pipe_item = SPICE_UPCAST(RedCursorPipeItem, > > > base); > > > > > > cursor_cmd = pipe_item->red_cursor; > > > + if (pipe_item->release_command_cb) { > > > + pipe_item->release_command_cb(cursor_cmd, pipe_item->user_data); > > > + } > > > red_put_cursor_cmd(cursor_cmd); > > > g_free(cursor_cmd); > > > > > > @@ -246,7 +255,8 @@ CursorChannel* cursor_channel_new(RedsState *server, > > > int id, > > > NULL); > > > } > > > > > > -void cursor_channel_process_cmd(CursorChannel *cursor, RedCursorCmd > > > *cursor_cmd) > > > +void cursor_channel_process_cmd(CursorChannel *cursor, RedCursorCmd > > > *cursor_cmd, > > > + ReleaseCommandCb release_command_cb, > > > gpointer user_data) > > > { > > > RedCursorPipeItem *cursor_pipe_item; > > > bool cursor_show = false; > > > @@ -254,7 +264,7 @@ void cursor_channel_process_cmd(CursorChannel > > > *cursor, > > > RedCursorCmd *cursor_cmd) > > > spice_return_if_fail(cursor); > > > spice_return_if_fail(cursor_cmd); > > > > > > - cursor_pipe_item = cursor_pipe_item_new(cursor_cmd); > > > + cursor_pipe_item = cursor_pipe_item_new(cursor_cmd, > > > release_command_cb, user_data); > > > > > > switch (cursor_cmd->type) { > > > case QXL_CURSOR_SET: > > > diff --git a/server/cursor-channel.h b/server/cursor-channel.h > > > index 603c2c0ac..e41e52438 100644 > > > --- a/server/cursor-channel.h > > > +++ b/server/cursor-channel.h > > > @@ -44,6 +44,8 @@ typedef struct CursorChannelClass CursorChannelClass; > > > > > > GType cursor_channel_get_type(void) G_GNUC_CONST; > > > > > > +typedef void (*ReleaseCommandCb)(RedCursorCmd *command, gpointer > > > user_data); > > > + > > > /** > > > * Create CursorChannel. > > > * Since CursorChannel is intended to be run in a separate thread, > > > @@ -61,7 +63,8 @@ CursorChannel* cursor_channel_new(RedsState *server, > > > int > > > id, > > > > > > void cursor_channel_reset (CursorChannel *cursor); > > > void cursor_channel_do_init (CursorChannel *cursor); > > > -void cursor_channel_process_cmd (CursorChannel *cursor, > > > RedCursorCmd *cursor_cmd); > > > +void cursor_channel_process_cmd(CursorChannel *cursor, > > > RedCursorCmd *cursor_cmd, > > > + ReleaseCommandCb > > > release_command_cb, gpointer user_data); > > > void cursor_channel_set_mouse_mode(CursorChannel > > > *cursor, > > > uint32_t mode); > > > > > > /** > > > diff --git a/server/red-stream-device.c b/server/red-stream-device.c > > > index e151de367..36f8b4b61 100644 > > > --- a/server/red-stream-device.c > > > +++ b/server/red-stream-device.c > > > @@ -386,7 +386,7 @@ handle_msg_cursor_set(StreamDevice *dev, > > > SpiceCharDeviceInstance *sin) > > > if (!cmd) { > > > return handle_msg_invalid(dev, sin, NULL); > > > } > > > - cursor_channel_process_cmd(dev->cursor_channel, cmd); > > > + cursor_channel_process_cmd(dev->cursor_channel, cmd, NULL, NULL); > > > > > > return true; > > > } > > > @@ -413,7 +413,7 @@ handle_msg_cursor_move(StreamDevice *dev, > > > SpiceCharDeviceInstance *sin) > > > cmd->u.position.x = move->x; > > > cmd->u.position.y = move->y; > > > > > > - cursor_channel_process_cmd(dev->cursor_channel, cmd); > > > + cursor_channel_process_cmd(dev->cursor_channel, cmd, NULL, NULL); > > > > > > return true; > > > } > > > diff --git a/server/red-worker.c b/server/red-worker.c > > > index 387f500e8..a549becf0 100644 > > > --- a/server/red-worker.c > > > +++ b/server/red-worker.c > > > @@ -109,6 +109,13 @@ void red_drawable_unref(RedDrawable *red_drawable) > > > g_free(red_drawable); > > > } > > > > > > +static void release_cursor_cmd_cb(RedCursorCmd *cursor_cmd, gpointer > > > user_data) > > > +{ > > > + QXLInstance *qxl = user_data; > > > + > > > + red_qxl_release_resource(qxl, cursor_cmd->release_info_ext); > > > +} > > > + > > > static gboolean red_process_cursor_cmd(RedWorker *worker, const > > > QXLCommandExt *ext) > > > { > > > RedCursorCmd *cursor_cmd; > > > @@ -118,8 +125,7 @@ static gboolean red_process_cursor_cmd(RedWorker > > > *worker, const QXLCommandExt *e > > > g_free(cursor_cmd); > > > return FALSE; > > > } > > > - red_qxl_release_resource(worker->qxl, cursor_cmd->release_info_ext); > > > - cursor_channel_process_cmd(worker->cursor_channel, cursor_cmd); > > > + cursor_channel_process_cmd(worker->cursor_channel, cursor_cmd, > > > release_cursor_cmd_cb, worker->qxl); > > > return TRUE; > > > } > > > _______________________________________________ Spice-devel mailing list Spice-devel@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/spice-devel