From: Alon Levy <alevy@redhat.com>
To: "Marc-André Lureau" <marcandre.lureau@gmail.com>, qemu-devel@nongnu.org
Cc: kwolf@redhat.com, jcody@redhat.com, spice-devel@freedesktop.org
Subject: Re: [Qemu-devel] [Spice-devel] [PATCH 20/21] spice-core: allow an interface to be in AIO context
Date: Mon, 18 Nov 2013 14:53:26 +0200 [thread overview]
Message-ID: <528A0DC6.9050401@redhat.com> (raw)
In-Reply-To: <1384777531-14635-21-git-send-email-marcandre.lureau@gmail.com>
On 11/18/2013 02:25 PM, Marc-André Lureau wrote:
> The Spice block driver must be able complete operations within a AIO
> context only.
>
> Spice is currently only running within the main loop, and doesn't allow
> the block driver to complete operations, such as flush during migration.
>
> This patch allows a Spice interface to be associated with a different
> context. Currently, the interface user_data is simply used to
> differentiate main loop from AIO, but could later be used to associate
> an interface with a particular thread.
>
> Signed-off-by: Marc-André Lureau <marcandre.lureau@gmail.com>
> ---
> include/ui/qemu-spice.h | 2 +-
> qemu-char.c | 2 +-
> spice-qemu-char.c | 9 +++----
> ui/spice-core.c | 62 +++++++++++++++++++++++++++++++++++++++++++------
> 4 files changed, 62 insertions(+), 13 deletions(-)
>
> diff --git a/include/ui/qemu-spice.h b/include/ui/qemu-spice.h
> index a93b4b2..d5ba702 100644
> --- a/include/ui/qemu-spice.h
> +++ b/include/ui/qemu-spice.h
> @@ -48,7 +48,7 @@ int qemu_spice_migrate_info(const char *hostname, int port, int tls_port,
> void do_info_spice_print(Monitor *mon, const QObject *data);
> void do_info_spice(Monitor *mon, QObject **ret_data);
>
> -CharDriverState *qemu_chr_open_spice_vmc(const char *type);
> +CharDriverState *qemu_chr_open_spice_vmc(const char *type, bool aio);
> #if SPICE_SERVER_VERSION >= 0x000c02
> CharDriverState *qemu_chr_open_spice_port(const char *name);
> void qemu_spice_register_ports(void);
> diff --git a/qemu-char.c b/qemu-char.c
> index 418dc69..bfac7bf 100644
> --- a/qemu-char.c
> +++ b/qemu-char.c
> @@ -3747,7 +3747,7 @@ ChardevReturn *qmp_chardev_add(const char *id, ChardevBackend *backend,
> #endif
> #ifdef CONFIG_SPICE
> case CHARDEV_BACKEND_KIND_SPICEVMC:
> - chr = qemu_chr_open_spice_vmc(backend->spicevmc->type);
> + chr = qemu_chr_open_spice_vmc(backend->spicevmc->type, false);
> break;
> case CHARDEV_BACKEND_KIND_SPICEPORT:
> chr = qemu_chr_open_spice_port(backend->spiceport->fqdn);
> diff --git a/spice-qemu-char.c b/spice-qemu-char.c
> index 16439c5..421f7de 100644
> --- a/spice-qemu-char.c
> +++ b/spice-qemu-char.c
> @@ -248,7 +248,7 @@ static void print_allowed_subtypes(void)
> fprintf(stderr, "\n");
> }
>
> -static CharDriverState *chr_open(const char *subtype)
> +static CharDriverState *chr_open(const char *subtype, bool aio)
> {
> CharDriverState *chr;
> SpiceCharDriver *s;
> @@ -257,6 +257,7 @@ static CharDriverState *chr_open(const char *subtype)
> s = g_malloc0(sizeof(SpiceCharDriver));
> s->chr = chr;
> s->active = false;
> + s->sin.base.user_data = (void*)aio;
> s->sin.subtype = g_strdup(subtype);
> chr->opaque = s;
> chr->chr_write = spice_chr_write;
> @@ -271,7 +272,7 @@ static CharDriverState *chr_open(const char *subtype)
> return chr;
> }
>
> -CharDriverState *qemu_chr_open_spice_vmc(const char *type)
> +CharDriverState *qemu_chr_open_spice_vmc(const char *type, bool aio)
> {
> const char **psubtype = spice_server_char_device_recognized_subtypes();
>
> @@ -291,7 +292,7 @@ CharDriverState *qemu_chr_open_spice_vmc(const char *type)
> return NULL;
> }
>
> - return chr_open(type);
> + return chr_open(type, aio);
> }
>
> #if SPICE_SERVER_VERSION >= 0x000c02
> @@ -305,7 +306,7 @@ CharDriverState *qemu_chr_open_spice_port(const char *name)
> return NULL;
> }
>
> - chr = chr_open("port");
> + chr = chr_open("port", false);
> s = chr->opaque;
> s->sin.portname = g_strdup(name);
>
> diff --git a/ui/spice-core.c b/ui/spice-core.c
> index e4d533d..0f69630 100644
> --- a/ui/spice-core.c
> +++ b/ui/spice-core.c
> @@ -53,34 +53,64 @@ static QemuThread me;
>
> struct SpiceTimer {
> QEMUTimer *timer;
> + QEMUBH *bh;
> QTAILQ_ENTRY(SpiceTimer) next;
> };
> static QTAILQ_HEAD(, SpiceTimer) timers = QTAILQ_HEAD_INITIALIZER(timers);
>
> +#if SPICE_INTERFACE_CORE_MAJOR >= 2
> +static SpiceTimer *timer_add(SpiceTimerFunc func, void *opaque, SpiceBaseInstance *sin)
> +#else
> static SpiceTimer *timer_add(SpiceTimerFunc func, void *opaque)
> +#endif
> {
> SpiceTimer *timer;
>
> timer = g_malloc0(sizeof(*timer));
> - timer->timer = timer_new_ms(QEMU_CLOCK_REALTIME, func, opaque);
> +
> +#if SPICE_INTERFACE_CORE_MAJOR >= 2
> + bool aio = sin ? !!sin->user_data : false;
Shouldn't there be a cast there:
(bool)sin->user_data
?
> + if (aio) {
> + fprintf(stderr, "AIO doesn't have timers yet, using BH\n");
> + timer->bh = qemu_bh_new(func, opaque);
> + } else
> +#endif
> + {
> + timer->timer = timer_new_ms(QEMU_CLOCK_REALTIME, func, opaque);
> + }
> +
> QTAILQ_INSERT_TAIL(&timers, timer, next);
> +
> return timer;
> }
>
> static void timer_start(SpiceTimer *timer, uint32_t ms)
> {
> - timer_mod(timer->timer, qemu_clock_get_ms(QEMU_CLOCK_REALTIME) + ms);
> + if (timer->bh) {
> + qemu_bh_schedule_idle(timer->bh); /* at least every 10ms, see async.c */
> + } else {
> + timer_mod(timer->timer, qemu_clock_get_ms(QEMU_CLOCK_REALTIME) + ms);
> + }
> }
>
> static void timer_cancel(SpiceTimer *timer)
> {
> - timer_del(timer->timer);
> + if (timer->bh) {
> + qemu_bh_cancel(timer->bh);
> + } else {
> + timer_del(timer->timer);
> + }
> }
>
> static void timer_remove(SpiceTimer *timer)
> {
> - timer_del(timer->timer);
> - timer_free(timer->timer);
> + if (timer->bh) {
> + qemu_bh_delete(timer->bh);
> + } else {
> + timer_del(timer->timer);
> + timer_free(timer->timer);
> + }
> +
> QTAILQ_REMOVE(&timers, timer, next);
> g_free(timer);
> }
> @@ -89,6 +119,7 @@ struct SpiceWatch {
> int fd;
> int event_mask;
> SpiceWatchFunc func;
> + bool aio;
> void *opaque;
> QTAILQ_ENTRY(SpiceWatch) next;
> };
> @@ -118,10 +149,19 @@ static void watch_update_mask(SpiceWatch *watch, int event_mask)
> if (watch->event_mask & SPICE_WATCH_EVENT_WRITE) {
> on_write = watch_write;
> }
> - qemu_set_fd_handler(watch->fd, on_read, on_write, watch);
> +
> + if (watch->aio) {
> + qemu_aio_set_fd_handler(watch->fd, on_read, on_write, watch);
> + } else {
> + qemu_set_fd_handler(watch->fd, on_read, on_write, watch);
> + }
> }
>
> +#if SPICE_INTERFACE_CORE_MAJOR >= 2
> +static SpiceWatch *watch_add(int fd, int event_mask, SpiceWatchFunc func, void *opaque, SpiceBaseInstance *sin)
> +#else
> static SpiceWatch *watch_add(int fd, int event_mask, SpiceWatchFunc func, void *opaque)
> +#endif
> {
> SpiceWatch *watch;
>
> @@ -129,6 +169,10 @@ static SpiceWatch *watch_add(int fd, int event_mask, SpiceWatchFunc func, void *
> watch->fd = fd;
> watch->func = func;
> watch->opaque = opaque;
> +#if SPICE_INTERFACE_CORE_MAJOR >= 2
> + watch->aio = sin ? !!sin->user_data : false;
> +#endif
> +
> QTAILQ_INSERT_TAIL(&watches, watch, next);
>
> watch_update_mask(watch, event_mask);
> @@ -137,7 +181,11 @@ static SpiceWatch *watch_add(int fd, int event_mask, SpiceWatchFunc func, void *
>
> static void watch_remove(SpiceWatch *watch)
> {
> - qemu_set_fd_handler(watch->fd, NULL, NULL, NULL);
> + if (watch->aio) {
> + qemu_aio_set_fd_handler(watch->fd, NULL, NULL, NULL);
> + } else {
> + qemu_set_fd_handler(watch->fd, NULL, NULL, NULL);
> + }
> QTAILQ_REMOVE(&watches, watch, next);
> g_free(watch);
> }
>
next prev parent reply other threads:[~2013-11-18 12:53 UTC|newest]
Thread overview: 28+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-11-18 12:25 [Qemu-devel] [PATCH 00/21] RFCv2: add Spice block device Marc-André Lureau
2013-11-18 12:25 ` [Qemu-devel] [PATCH 01/21] vscclient: do not add a socket watch if there is not data to send Marc-André Lureau
2013-11-18 12:25 ` [Qemu-devel] [PATCH 02/21] spice-char: remove unused field Marc-André Lureau
2013-11-18 12:25 ` [Qemu-devel] [PATCH 03/21] qmp_change_blockdev() remove unused has_format Marc-André Lureau
2013-11-18 12:25 ` [Qemu-devel] [PATCH 04/21] include: add missing config-host.h include Marc-André Lureau
2013-11-18 12:25 ` [Qemu-devel] [PATCH 05/21] char: add qemu_chr_fe_event() Marc-André Lureau
2013-11-18 12:36 ` Alon Levy
2013-11-18 12:25 ` [Qemu-devel] [PATCH 06/21] Split nbd block client code Marc-André Lureau
2013-11-18 12:25 ` [Qemu-devel] [PATCH 07/21] nbd: don't change socket block during negotiate Marc-André Lureau
2013-11-18 12:25 ` [Qemu-devel] [PATCH 08/21] nbd: pass export name as init argument Marc-André Lureau
2013-11-18 12:25 ` [Qemu-devel] [PATCH 09/21] nbd: make session_close() idempotent Marc-André Lureau
2013-11-18 12:25 ` [Qemu-devel] [PATCH 10/21] nbd: finish any pending coroutine Marc-André Lureau
2013-11-18 12:25 ` [Qemu-devel] [PATCH 11/21] nbd: avoid uninitialized warnings Marc-André Lureau
2013-11-18 12:25 ` [Qemu-devel] [PATCH 12/21] block: save the associated child name in BlockDriverState Marc-André Lureau
2013-11-18 12:25 ` [Qemu-devel] [PATCH 13/21] blockdev: add qmp_change_blockdev_int() Marc-André Lureau
2013-11-18 12:25 ` [Qemu-devel] [PATCH 14/21] block: extract make_snapshot() from bdrv_open() Marc-André Lureau
2013-11-18 12:25 ` [Qemu-devel] [PATCH 15/21] block: add "snapshot.size" option to avoid extra bdrv_open() Marc-André Lureau
2013-11-18 12:25 ` [Qemu-devel] [PATCH 16/21] block: learn to open a driver with a given opaque Marc-André Lureau
2013-11-18 12:25 ` [Qemu-devel] [PATCH 17/21] block: allow to call bdrv_open() with an opaque Marc-André Lureau
2013-11-18 12:25 ` [Qemu-devel] [PATCH 18/21] block: do not notify change during migration Marc-André Lureau
2013-11-18 12:25 ` [Qemu-devel] [PATCH 19/21] sysemu: add vm_start_hold/release Marc-André Lureau
2013-11-29 10:30 ` Paolo Bonzini
2013-11-18 12:25 ` [Qemu-devel] [PATCH 20/21] spice-core: allow an interface to be in AIO context Marc-André Lureau
2013-11-18 12:53 ` Alon Levy [this message]
2013-11-18 12:25 ` [Qemu-devel] [PATCH 21/21] block: add spice block device backend Marc-André Lureau
2013-11-20 11:00 ` Marc-André Lureau
2013-11-22 13:28 ` [Qemu-devel] [PATCH 00/21] RFCv2: add Spice block device Marc-André Lureau
2013-11-29 9:51 ` Gerd Hoffmann
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=528A0DC6.9050401@redhat.com \
--to=alevy@redhat.com \
--cc=jcody@redhat.com \
--cc=kwolf@redhat.com \
--cc=marcandre.lureau@gmail.com \
--cc=qemu-devel@nongnu.org \
--cc=spice-devel@freedesktop.org \
/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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.