Re: [Spice-devel] [spice-server] cursor: Delay release of QXL guest cursor resources
Hey, On Tue, Apr 10, 2018 at 08:16:32AM -0400, Frediano Ziglio wrote: > > > > > > 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 > > > > 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: Yes, definitely a very good suggestion, I'll try that, thanks ! Christophe signature.asc Description: PGP signature ___ Spice-devel mailing list Spice-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/spice-devel
Re: [Spice-devel] [spice-server] cursor: Delay release of QXL guest cursor resources
> > > > 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 > > 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(
Re: [Spice-devel] [spice-server] cursor: Delay release of QXL guest cursor resources
> > 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 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. 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 (CursorChann
Re: [Spice-devel] [spice-server] cursor: Delay release of QXL guest cursor resources
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 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 > --- > 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