Commit 00961090 authored by Alex Bennée's avatar Alex Bennée
Browse files

ui/console: use exclusive mechanism directly



The previous commit (8bb93c6f) using async_safe_run_on_cpu() doesn't
work on graphics sub-system which restrict which threads can do GUI
updates. Rather the special casing MacOS we just directly call the
helper and move all the exclusive handling into do_dafe_dpy_refresh().

The unfortunate bouncing of the BQL is to ensure there is no deadlock
as vCPUs waiting on the BQL are kicked into their quiescent state.

Signed-off-by: default avatarAlex Bennée <alex.bennee@linaro.org>
Reviewed-by: default avatarPaolo Bonzini <pbonzini@redhat.com>
Reviewed-by: default avatarGerd Hoffmann <kraxel@redhat.com>
parent 85390939
Loading
Loading
Loading
Loading
+9 −7
Original line number Diff line number Diff line
@@ -1576,19 +1576,22 @@ bool dpy_gfx_check_format(QemuConsole *con,
}

/*
 * Safe DPY refresh for TCG guests. This runs when the TCG vCPUs are
 * quiescent so we can avoid races between dirty page tracking for
 * direct frame-buffer access by the guest.
 * Safe DPY refresh for TCG guests. We use the exclusive mechanism to
 * ensure the TCG vCPUs are quiescent so we can avoid races between
 * dirty page tracking for direct frame-buffer access by the guest.
 *
 * This is a temporary stopgap until we've fixed the dirty tracking
 * races in display adapters.
 */
static void do_safe_dpy_refresh(CPUState *cpu, run_on_cpu_data opaque)
static void do_safe_dpy_refresh(DisplayChangeListener *dcl)
{
    DisplayChangeListener *dcl = opaque.host_ptr;
    qemu_mutex_unlock_iothread();
    start_exclusive();
    qemu_mutex_lock_iothread();
    dcl->ops->dpy_refresh(dcl);
    qemu_mutex_unlock_iothread();
    end_exclusive();
    qemu_mutex_lock_iothread();
}

static void dpy_refresh(DisplayState *s)
@@ -1598,8 +1601,7 @@ static void dpy_refresh(DisplayState *s)
    QLIST_FOREACH(dcl, &s->listeners, next) {
        if (dcl->ops->dpy_refresh) {
            if (tcg_enabled()) {
                async_safe_run_on_cpu(first_cpu, do_safe_dpy_refresh,
                                      RUN_ON_CPU_HOST_PTR(dcl));
                do_safe_dpy_refresh(dcl);
            } else {
                dcl->ops->dpy_refresh(dcl);
            }