From: "Daniel P. Berrangé" <berrange@redhat.com>
To: Christophe de Dinechin <dinechin@redhat.com>
Cc: "Eduardo Habkost" <ehabkost@redhat.com>,
"Michael S. Tsirkin" <mst@redhat.com>,
qemu-trivial@nongnu.org, "Michael Tokarev" <mjt@tls.msk.ru>,
"Laurent Vivier" <laurent@vivier.eu>,
qemu-devel@nongnu.org,
"Marc-André Lureau" <marcandre.lureau@redhat.com>,
"Gerd Hoffmann" <kraxel@redhat.com>,
"Cleber Rosa" <crosa@redhat.com>,
"Paolo Bonzini" <pbonzini@redhat.com>,
"Dr. David Alan Gilbert" <dgilbert@redhat.com>,
"Richard Henderson" <rth@twiddle.net>
Subject: Re: [PATCH 09/10] spice: Put spice functions in a separate load module
Date: Mon, 29 Jun 2020 18:30:35 +0100 [thread overview]
Message-ID: <20200629173035.GA1298906@redhat.com> (raw)
In-Reply-To: <lyo8p1dc2a.fsf@redhat.com>
On Mon, Jun 29, 2020 at 07:19:41PM +0200, Christophe de Dinechin wrote:
>
> On 2020-06-26 at 19:35 CEST, Daniel P. Berrangé wrote...
> > On Fri, Jun 26, 2020 at 06:43:06PM +0200, Christophe de Dinechin wrote:
> >> Use the MODIFACE and MODIMPL macros to to redirect the highest-level
> >> qemu_spice functions into the spice-app.so load module when SPICE is
> >> compiled as a module.
> >>
> >> With these changes, the following shared libraries are no longer
> >> necessary in the top-level qemu binary:
> >>
> >> libspice-server.so.1 => /lib64/libspice-server.so.1 (HEX)
> >> libopus.so.0 => /lib64/libopus.so.0 (HEX)
> >> liblz4.so.1 => /lib64/liblz4.so.1 (HEX)
> >> libgstapp-1.0.so.0 => /lib64/libgstapp-1.0.so.0 (HEX)
> >> libgstvideo-1.0.so.0 => /lib64/libgstvideo-1.0.so.0 (HEX)
> >> libgstbase-1.0.so.0 => /lib64/libgstbase-1.0.so.0 (HEX)
> >> libgstreamer-1.0.so.0 => /lib64/libgstreamer-1.0.so.0 (HEX)
> >> libssl.so.1.1 => /lib64/libssl.so.1.1 (HEX)
> >> liborc-0.4.so.0 => /lib64/liborc-0.4.so.0 (HEX)
> >>
> >> Signed-off-by: Christophe de Dinechin <dinechin@redhat.com>
> >> ---
> >> include/ui/qemu-spice.h | 24 +++++++++++++++---------
> >> monitor/hmp-cmds.c | 6 ++++++
> >> softmmu/vl.c | 1 +
> >> ui/spice-core.c | 31 +++++++++++++++++++++----------
> >> ui/spice-display.c | 2 +-
> >> 5 files changed, 44 insertions(+), 20 deletions(-)
> >>
> >> diff --git a/include/ui/qemu-spice.h b/include/ui/qemu-spice.h
> >> index 8c23dfe717..0f7e139da5 100644
> >> --- a/include/ui/qemu-spice.h
> >> +++ b/include/ui/qemu-spice.h
> >> @@ -24,22 +24,28 @@
> >>
> >> #include <spice.h>
> >> #include "qemu/config-file.h"
> >> +#include "qemu/module.h"
> >>
> >> -extern int using_spice;
> >> +#define using_spice (qemu_is_using_spice())
> >>
> >> -void qemu_spice_init(void);
> >> +MODIFACE(bool, qemu_is_using_spice,(void));
> >> +MODIFACE(void, qemu_start_using_spice, (void));
> >> +MODIFACE(void, qemu_spice_init, (void));
> >> void qemu_spice_input_init(void);
> >> void qemu_spice_audio_init(void);
> >> -void qemu_spice_display_init(void);
> >> -int qemu_spice_display_add_client(int csock, int skipauth, int tls);
> >> +MODIFACE(void, qemu_spice_display_init, (void));
> >> +MODIFACE(int, qemu_spice_display_add_client, (int csock, int skipauth, int tls));
> >> int qemu_spice_add_interface(SpiceBaseInstance *sin);
> >> bool qemu_spice_have_display_interface(QemuConsole *con);
> >> int qemu_spice_add_display_interface(QXLInstance *qxlin, QemuConsole *con);
> >> -int qemu_spice_set_passwd(const char *passwd,
> >> - bool fail_if_connected, bool disconnect_if_connected);
> >> -int qemu_spice_set_pw_expire(time_t expires);
> >> -int qemu_spice_migrate_info(const char *hostname, int port, int tls_port,
> >> - const char *subject);
> >> +MODIFACE(int, qemu_spice_set_passwd, (const char *passwd,
> >> + bool fail_if_connected,
> >> + bool disconnect_if_connected));
> >> +MODIFACE(int, qemu_spice_set_pw_expire,(time_t expires));
> >> +MODIFACE(int, qemu_spice_migrate_info,(const char *hostname,
> >> + int port, int tls_port,
> >> + const char *subject));
> >> +MODIFACE(struct SpiceInfo *,qemu_spice_query, (Error **errp));
> >
> > This macro usage looks kind of unpleasant and its hard to understand
> > just what is going on, especially why some methods are changed but
> > others are not.
>
> The functions that are changed are the module interface between qemu and the
> DSO. For example, qemu_spice_init is called from vl.c, i.e. the main binary,
> but qemu_spice_audio_init is called from ui/spice-core.c and
> ui/spice-input.c, which are both in the DSO after the commit.
>
> The existing function-based interface in qemu-spice.h was not really
> carefully designed for modularization, so this list was determined by
> following the initialization path. It may not be the smallest possible cut.
> It may be neat to add a patch to reorder functions based on whether they are
> inside the DSO or exported from it.
>
> As for the macro syntax, I see it as somewhat transient. I wanted to propose
> a working and scalable mechanism before adding some nice syntactic sugar
> tooling to it. I expect the syntax to turn into something like:
>
> MODIFACE void qemu_spice_display_init (void);
> MODIIMPL void qemu_spice_display_init (void) { ... }
>
> But it feels a bit too early to do that. I prefer to experiment with a
> simple macro for now.
>
> >
> > IIUC, the goal is to turn all these into weak symbols so they don't
> > need to be resolved immediately at startup, and instead have an
> > impl of them provided dynamically at runtime.
>
> My very first approach was indeed to use weak symbols, but then I learned
> that ld.so no longer deals with weak symbols, apparently for security
> reasons. See LD_DYNAMIC_WEAK in ld.so(8).
>
> >
> > If so the more normal approach would be to have a struct defining
> > a set of callbacks, that can be registered. Or if there's a natural
> > fit with QOM, then a QOM interface that can then have a QOM object
> > impl registered as a singleton.
>
> That was my second attempt (after the weak symbols). I cleaned it up a bit
> and put it here: https://github.com/c3d/qemu/commits/spice-vtable.
>
> What made me switch to the approach in this series is the following
> considerations:
>
> - A vtable is useful if there can be multiple values for a method, e.g. to
> implement inheritance, or if you have multiple instances. This is not the
> case here.
IMHO a vtable is fine for singleton objects. It is a generic way to
remove tight coupling between caller(s) and an implementation. Just
having 1 implementation doesn't invalidate the model.
> - A vtable adds one level of indirection, which does not seem to be
> particularly useful or helpful for this particular use case.
>
> - Overloading QOM for that purpose looked more confusing than anything else.
> It looked like I was mixing unrelated concepts. Maybe that's just me.
>
> - The required change with a vtable ends up being more extensive. Instead of
> changing a single line to put an entry point in a DSO, you need to create
> the vtable, add functions to it, add a register function, etc. I was
> looking for an easier and more scalable way.
>
> - In particular, with a vtable, you cannot take advantage of the syntactic
> trick I used here, which is that foo(x) is a shortcut for (*foo)(x).
> So for a vtable, you need to manually write wrappers.
>
> This could be automated, of course, but so far I did not find any clear
> benefit, and many drawbacks to using the vtable approach. As a quantitative
> comparison point, the commit that does this same connection using the vtable
> approach is:
>
> include/ui/qemu-spice.h | 104 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-----
> monitor/hmp-cmds.c | 6 +++++
> softmmu/vl.c | 10 +++++++
> ui/spice-core.c | 38 ++++++++++++++++++++++++---
> 4 files changed, 148 insertions(+), 10 deletions(-)
>
> as opposed to what is presented in this series:
>
> include/ui/qemu-spice.h | 24 +++++++++++++++---------
> monitor/hmp-cmds.c | 6 ++++++
> softmmu/vl.c | 1 +
> ui/spice-core.c | 31 +++++++++++++++++++++----------
> ui/spice-display.c | 2 +-
> 5 files changed, 44 insertions(+), 20 deletions(-)
I much prefer the code in the vtable patch version. The larger number of
lines of code doesn't bother me, because the code is really simple and
clear to read. IOW I prefer the clarity of the longer code, over the
shorter code with magic hidden behind it.
Regards,
Daniel
--
|: https://berrange.com -o- https://www.flickr.com/photos/dberrange :|
|: https://libvirt.org -o- https://fstop138.berrange.com :|
|: https://entangle-photo.org -o- https://www.instagram.com/dberrange :|
next prev parent reply other threads:[~2020-06-29 17:32 UTC|newest]
Thread overview: 33+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-06-26 16:42 [PATCH 00/10] RFC: Move SPICE to a load module Christophe de Dinechin
2020-06-26 16:42 ` [PATCH 01/10] modules: Provide macros making it easier to identify module exports Christophe de Dinechin
2020-06-29 10:13 ` Claudio Fontana
2020-06-30 13:48 ` Christophe de Dinechin
2020-06-30 9:38 ` Michael S. Tsirkin
2020-06-30 13:39 ` Christophe de Dinechin
2020-06-26 16:42 ` [PATCH 02/10] minikconf: Pass variables for modules Christophe de Dinechin
2020-06-26 16:43 ` [PATCH 03/10] spice: Make spice a module configuration Christophe de Dinechin
2020-06-26 16:43 ` [PATCH 04/10] spice: Move all the spice-related code in spice-app.so Christophe de Dinechin
2020-06-26 17:20 ` Daniel P. Berrangé
2020-06-29 9:22 ` Christophe de Dinechin
2020-06-29 9:47 ` Daniel P. Berrangé
2020-06-29 23:37 ` Gerd Hoffmann
2020-06-26 16:43 ` [PATCH 05/10] build: Avoid build failure when building drivers as modules Christophe de Dinechin
2020-06-26 17:23 ` Daniel P. Berrangé
2020-06-29 23:26 ` Gerd Hoffmann
2020-06-26 16:43 ` [PATCH 06/10] trivial: Remove extra trailing whitespace Christophe de Dinechin
2020-06-29 9:56 ` Philippe Mathieu-Daudé
2020-06-26 16:43 ` [PATCH 07/10] qxl - FIXME: Build as module Christophe de Dinechin
2020-06-26 16:43 ` [PATCH 08/10] build: Add SPICE_CFLAGS and SPICE_LIBS to relevant files Christophe de Dinechin
2020-06-26 17:26 ` Daniel P. Berrangé
2020-06-29 9:27 ` Christophe de Dinechin
2020-06-29 23:08 ` Gerd Hoffmann
2020-06-30 13:56 ` Christophe de Dinechin
2020-06-26 16:43 ` [PATCH 09/10] spice: Put spice functions in a separate load module Christophe de Dinechin
2020-06-26 17:35 ` Daniel P. Berrangé
2020-06-29 17:19 ` Christophe de Dinechin
2020-06-29 17:30 ` Daniel P. Berrangé [this message]
2020-06-29 23:00 ` Gerd Hoffmann
2020-06-30 12:54 ` Christophe de Dinechin
2020-06-26 16:43 ` [PATCH 10/10] REMOVE: Instrumentation to show the module functions being replaced Christophe de Dinechin
2020-06-26 17:29 ` Daniel P. Berrangé
2020-06-30 12:48 ` Christophe de Dinechin
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20200629173035.GA1298906@redhat.com \
--to=berrange@redhat.com \
--cc=crosa@redhat.com \
--cc=dgilbert@redhat.com \
--cc=dinechin@redhat.com \
--cc=ehabkost@redhat.com \
--cc=kraxel@redhat.com \
--cc=laurent@vivier.eu \
--cc=marcandre.lureau@redhat.com \
--cc=mjt@tls.msk.ru \
--cc=mst@redhat.com \
--cc=pbonzini@redhat.com \
--cc=qemu-devel@nongnu.org \
--cc=qemu-trivial@nongnu.org \
--cc=rth@twiddle.net \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).