All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Marc-André Lureau" <marcandre.lureau@redhat.com>
To: qemu-devel@nongnu.org
Cc: airlied@redhat.com, kraxel@redhat.com,
	"Marc-André Lureau" <marcandre.lureau@redhat.com>
Subject: [Qemu-devel] [PATCH 18/18] virtio-gpu: start/stop the data-plane
Date: Mon,  5 Sep 2016 02:20:39 +0400	[thread overview]
Message-ID: <20160904222039.11460-19-marcandre.lureau@redhat.com> (raw)
In-Reply-To: <20160904222039.11460-1-marcandre.lureau@redhat.com>

Use aio thread context to dispatch the queues.

This code has been written based on virtio-blk data-plane setup.

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
 hw/display/virtio-gpu.c        | 138 ++++++++++++++++++++++++++++++++++++++++-
 include/hw/virtio/virtio-gpu.h |   1 +
 2 files changed, 137 insertions(+), 2 deletions(-)

diff --git a/hw/display/virtio-gpu.c b/hw/display/virtio-gpu.c
index a37d5f2..c732607 100644
--- a/hw/display/virtio-gpu.c
+++ b/hw/display/virtio-gpu.c
@@ -22,12 +22,18 @@
 #include "migration/migration.h"
 #include "qemu/log.h"
 #include "qapi/error.h"
+#include "ui/egl-context.h"
 
 #define VIRTIO_GPU_VM_VERSION 1
 
 static struct virtio_gpu_simple_resource*
 virtio_gpu_find_resource(VirtIOGPU *g, uint32_t resource_id);
 
+static void
+virtio_gpu_handle_ctrl(VirtIODevice *vdev, VirtQueue *vq);
+static void
+virtio_gpu_handle_cursor(VirtIODevice *vdev, VirtQueue *vq);
+
 #ifdef CONFIG_VIRGL
 #include <virglrenderer.h>
 #define VIRGL(_g, _virgl, _simple, ...)                     \
@@ -824,9 +830,129 @@ static void virtio_gpu_simple_process_cmd(VirtIOGPU *g,
     }
 }
 
+static void data_plane_handle_ctrl_cb(VirtIODevice *vdev, VirtQueue *q)
+{
+    VirtIOGPU *g = VIRTIO_GPU(vdev);
+    virtio_gpu_handle_ctrl(&g->parent_obj, q);
+}
+
+static void data_plane_handle_cursor_cb(VirtIODevice *vdev, VirtQueue *q)
+{
+    VirtIOGPU *g = VIRTIO_GPU(vdev);
+    virtio_gpu_handle_cursor(&g->parent_obj, q);
+}
+
+static void virtio_gpu_data_plane_start(VirtIODevice *vdev)
+{
+    VirtIOGPU *g = VIRTIO_GPU(vdev);
+    VirtIOGPUDataPlane *dp = g->dp;
+    BusState *qbus = BUS(qdev_get_parent_bus(DEVICE(vdev)));
+    VirtioBusClass *k = VIRTIO_BUS_GET_CLASS(qbus);
+    int i, r;
+
+    if (dp->started || dp->starting) {
+        return;
+    }
+
+    dp->starting = true;
+
+    /* Set up guest notifier (irq) */
+    r = k->set_guest_notifiers(qbus->parent, 2, true);
+    if (r != 0) {
+        fprintf(stderr, "virtio-gpu failed to set guest notifier (%d), "
+                "ensure -enable-kvm is set\n", r);
+        goto fail_guest_notifiers;
+    }
+
+    /* Set up virtqueue notify */
+    for (i = 0; i < 2; i++) {
+        r = virtio_bus_set_host_notifier(VIRTIO_BUS(qbus), i, true);
+        if (r != 0) {
+            fprintf(stderr, "virtio-gpu failed to set host notifier (%d)\n", r);
+            while (i--) {
+                virtio_bus_set_host_notifier(VIRTIO_BUS(qbus), i, false);
+            }
+            goto fail_guest_notifiers;
+        }
+    }
+
+    dp->starting = false;
+    dp->started = true;
+
+    /* Kick right away to begin processing requests already in vring */
+    for (i = 0; i < 2; i++) {
+        VirtQueue *vq = virtio_get_queue(vdev, i);
+
+        event_notifier_set(virtio_queue_get_host_notifier(vq));
+    }
+
+    AioContext *ctx = iothread_get_aio_context(g->iothread);
+    /* Get this show started by hooking up our callbacks */
+    aio_context_acquire(ctx);
+    virtio_queue_aio_set_host_notifier_handler(virtio_get_queue(vdev, 0), ctx,
+                                               data_plane_handle_ctrl_cb);
+    virtio_queue_aio_set_host_notifier_handler(virtio_get_queue(vdev, 1), ctx,
+                                               data_plane_handle_cursor_cb);
+    aio_context_release(ctx);
+    return;
+
+fail_guest_notifiers:
+    dp->disabled = true;
+    dp->starting = false;
+    dp->started = true;
+}
+
+void virtio_gpu_data_plane_stop(VirtIOGPUDataPlane *dp)
+{
+    VirtIOGPU *g = dp->gpu;
+    BusState *qbus = BUS(qdev_get_parent_bus(DEVICE(g)));
+    VirtioBusClass *k = VIRTIO_BUS_GET_CLASS(qbus);
+    AioContext *ctx = iothread_get_aio_context(g->iothread);
+    unsigned i;
+
+    if (!dp->started || dp->stopping) {
+        return;
+    }
+
+    if (dp->disabled) {
+        dp->disabled = false;
+        dp->started = false;
+        return;
+    }
+    dp->stopping = true;
+
+    /* Get this show started by hooking up our callbacks */
+    aio_context_acquire(ctx);
+    /* Stop notifications for new requests from guest */
+    for (i = 0; i < 2; i++) {
+        VirtQueue *vq = virtio_get_queue(VIRTIO_DEVICE(g), i);
+
+        virtio_queue_aio_set_host_notifier_handler(vq, ctx, NULL);
+    }
+    aio_context_release(ctx);
+
+    for (i = 0; i < 2; i++) {
+        virtio_bus_set_host_notifier(VIRTIO_BUS(qbus), i, false);
+    }
+
+    /* Clean up guest notifier (irq) */
+    k->set_guest_notifiers(qbus->parent, 2, false);
+
+    dp->started = false;
+    dp->stopping = false;
+}
+
 static void virtio_gpu_handle_ctrl_cb(VirtIODevice *vdev, VirtQueue *vq)
 {
     VirtIOGPU *g = VIRTIO_GPU(vdev);
+
+    if (g->dp) {
+        virtio_gpu_data_plane_start(vdev);
+        if (!g->dp->disabled) {
+            return;
+        }
+    }
+
     qemu_bh_schedule(g->ctrl_bh);
 }
 
@@ -1210,9 +1336,13 @@ static void virtio_gpu_device_realize(DeviceState *qdev, Error **errp)
     }
 
     if (virtio_gpu_virgl_enabled(g->conf)) {
+        VirtQueue *(*add_queue)(VirtIODevice *vdev, int queue_size,
+                                  VirtIOHandleOutput handle_output) =
+            g->iothread ? virtio_add_queue_aio : virtio_add_queue;
+
         /* use larger control queue in 3d mode */
-        g->ctrl_vq   = virtio_add_queue(vdev, 256, virtio_gpu_handle_ctrl_cb);
-        g->cursor_vq = virtio_add_queue(vdev, 16, virtio_gpu_handle_cursor_cb);
+        g->ctrl_vq   = add_queue(vdev, 256, virtio_gpu_handle_ctrl_cb);
+        g->cursor_vq = add_queue(vdev, 16, virtio_gpu_handle_cursor_cb);
         g->virtio_config.num_capsets = 1;
 #if defined(CONFIG_VIRGL)
         {
@@ -1290,6 +1420,10 @@ static void virtio_gpu_reset(VirtIODevice *vdev)
     struct virtio_gpu_simple_resource *res, *tmp;
     int i;
 
+    if (g->dp) {
+        virtio_gpu_data_plane_stop(g->dp);
+    }
+
     g->enable = 0;
 
     QTAILQ_FOREACH_SAFE(res, &g->reslist, next, tmp) {
diff --git a/include/hw/virtio/virtio-gpu.h b/include/hw/virtio/virtio-gpu.h
index 82d1e45..26ff9d1 100644
--- a/include/hw/virtio/virtio-gpu.h
+++ b/include/hw/virtio/virtio-gpu.h
@@ -217,5 +217,6 @@ void virtio_gpu_virgl_reset(VirtIOGPU *g);
 int virtio_gpu_virgl_init(VirtIOGPU *g);
 int virtio_gpu_virgl_dp_create(VirtIOGPU *g, Error **errp);
 void virtio_gpu_virgl_dp_destroy(VirtIOGPU *g);
+void virtio_gpu_data_plane_stop(VirtIOGPUDataPlane *dp);
 
 #endif
-- 
2.9.0

  parent reply	other threads:[~2016-09-04 22:22 UTC|newest]

Thread overview: 23+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-09-04 22:20 [Qemu-devel] [PATCH 00/18] virgl: use a seperate rendering thread Marc-André Lureau
2016-09-04 22:20 ` [Qemu-devel] [PATCH 01/18] console: skip same-size resize Marc-André Lureau
2016-09-04 22:20 ` [Qemu-devel] [PATCH 02/18] console: add dpy_gl_ctx_is_mt_safe Marc-André Lureau
2016-09-04 22:20 ` [Qemu-devel] [PATCH 03/18] virtio-gpu: add "iothread" property Marc-André Lureau
2016-09-04 22:20 ` [Qemu-devel] [PATCH 04/18] virtio-gpu: start splitting scanout/resource flushing Marc-André Lureau
2016-09-04 22:20 ` [Qemu-devel] [PATCH 05/18] virtio-gpu: start introducing a lock around the display info Marc-André Lureau
2016-09-04 22:20 ` [Qemu-devel] [PATCH 06/18] virtio-gpu: create a thread context Marc-André Lureau
2016-09-04 22:20 ` [Qemu-devel] [PATCH 07/18] gl: allow to keep current context in ctx-create Marc-André Lureau
2016-09-04 22:20 ` [Qemu-devel] [PATCH 08/18] gl: bind GL api before context creation Marc-André Lureau
2016-09-04 22:20 ` [Qemu-devel] [PATCH 09/18] bitmap: add a simple foreach util Marc-André Lureau
2016-09-04 22:20 ` [Qemu-devel] [PATCH 10/18] virtio-blk: use bitmap_foreach Marc-André Lureau
2016-09-04 22:20 ` [Qemu-devel] [PATCH 11/18] virtio-gpu: use a bh for cursor modifications Marc-André Lureau
2016-09-04 22:20 ` [Qemu-devel] [PATCH 12/18] virtio-gpu: save a pointer from virtio_gpu_ctrl_command Marc-André Lureau
2016-09-04 22:20 ` [Qemu-devel] [PATCH 13/18] virtio-gpu: add a virgl data-plane Marc-André Lureau
2016-09-04 22:20 ` [Qemu-devel] [PATCH 14/18] virtio-gpu: batch virtio_notify when using a data-plane Marc-André Lureau
2016-09-04 22:20 ` [Qemu-devel] [PATCH 15/18] virtio-gpu: dispatch to main thread for scanout & flush Marc-André Lureau
2016-09-04 22:20 ` [Qemu-devel] [PATCH 16/18] virtio-gpu: use virgl thread sync with the data-plane Marc-André Lureau
2016-09-04 22:20 ` [Qemu-devel] [PATCH 17/18] virtio-gpu: schedule a bh to unblock " Marc-André Lureau
2016-09-04 22:20 ` Marc-André Lureau [this message]
2016-09-04 22:46 ` [Qemu-devel] [PATCH 00/18] virgl: use a seperate rendering thread no-reply
2016-09-04 22:48 ` no-reply
2016-09-08  6:01 ` Gerd Hoffmann
2016-09-08  6:38   ` Marc-André Lureau

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=20160904222039.11460-19-marcandre.lureau@redhat.com \
    --to=marcandre.lureau@redhat.com \
    --cc=airlied@redhat.com \
    --cc=kraxel@redhat.com \
    --cc=qemu-devel@nongnu.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.