[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH 18/18] virtio-gpu: start/stop the data-plane
From: |
Marc-André Lureau |
Subject: |
[Qemu-devel] [PATCH 18/18] virtio-gpu: start/stop the data-plane |
Date: |
Mon, 5 Sep 2016 02:20:39 +0400 |
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 <address@hidden>
---
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
- [Qemu-devel] [PATCH 07/18] gl: allow to keep current context in ctx-create, (continued)
- [Qemu-devel] [PATCH 07/18] gl: allow to keep current context in ctx-create, Marc-André Lureau, 2016/09/04
- [Qemu-devel] [PATCH 09/18] bitmap: add a simple foreach util, Marc-André Lureau, 2016/09/04
- [Qemu-devel] [PATCH 11/18] virtio-gpu: use a bh for cursor modifications, Marc-André Lureau, 2016/09/04
- [Qemu-devel] [PATCH 10/18] virtio-blk: use bitmap_foreach, Marc-André Lureau, 2016/09/04
- [Qemu-devel] [PATCH 12/18] virtio-gpu: save a pointer from virtio_gpu_ctrl_command, Marc-André Lureau, 2016/09/04
- [Qemu-devel] [PATCH 14/18] virtio-gpu: batch virtio_notify when using a data-plane, Marc-André Lureau, 2016/09/04
- [Qemu-devel] [PATCH 13/18] virtio-gpu: add a virgl data-plane, Marc-André Lureau, 2016/09/04
- [Qemu-devel] [PATCH 16/18] virtio-gpu: use virgl thread sync with the data-plane, Marc-André Lureau, 2016/09/04
- [Qemu-devel] [PATCH 15/18] virtio-gpu: dispatch to main thread for scanout & flush, Marc-André Lureau, 2016/09/04
- [Qemu-devel] [PATCH 17/18] virtio-gpu: schedule a bh to unblock the data-plane, Marc-André Lureau, 2016/09/04
- [Qemu-devel] [PATCH 18/18] virtio-gpu: start/stop the data-plane,
Marc-André Lureau <=
- Re: [Qemu-devel] [PATCH 00/18] virgl: use a seperate rendering thread, no-reply, 2016/09/04
- Re: [Qemu-devel] [PATCH 00/18] virgl: use a seperate rendering thread, no-reply, 2016/09/04
- Re: [Qemu-devel] [PATCH 00/18] virgl: use a seperate rendering thread, Gerd Hoffmann, 2016/09/08