From patchwork Sun Sep 4 22:20:39 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Marc-Andr=C3=A9_Lureau?= X-Patchwork-Id: 9312917 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id BDC386075E for ; Sun, 4 Sep 2016 22:43:37 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id A88BB284B1 for ; Sun, 4 Sep 2016 22:43:37 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 8992F286B8; Sun, 4 Sep 2016 22:43:37 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.9 required=2.0 tests=BAYES_00,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id E8444284B1 for ; Sun, 4 Sep 2016 22:43:36 +0000 (UTC) Received: from localhost ([::1]:51324 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bgg8V-0003Pp-Pl for patchwork-qemu-devel@patchwork.kernel.org; Sun, 04 Sep 2016 18:43:35 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:43435) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bgfnc-0003Ms-Ii for qemu-devel@nongnu.org; Sun, 04 Sep 2016 18:22:03 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1bgfnV-0006U5-CX for qemu-devel@nongnu.org; Sun, 04 Sep 2016 18:21:59 -0400 Received: from mx1.redhat.com ([209.132.183.28]:43448) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bgfnV-0006Ty-4r for qemu-devel@nongnu.org; Sun, 04 Sep 2016 18:21:53 -0400 Received: from int-mx10.intmail.prod.int.phx2.redhat.com (int-mx10.intmail.prod.int.phx2.redhat.com [10.5.11.23]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id C954FC0467CF for ; Sun, 4 Sep 2016 22:21:52 +0000 (UTC) Received: from localhost (ovpn-116-72.phx2.redhat.com [10.3.116.72]) by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id u84MLo58012398; Sun, 4 Sep 2016 18:21:51 -0400 From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= To: qemu-devel@nongnu.org Date: Mon, 5 Sep 2016 02:20:39 +0400 Message-Id: <20160904222039.11460-19-marcandre.lureau@redhat.com> In-Reply-To: <20160904222039.11460-1-marcandre.lureau@redhat.com> References: <20160904222039.11460-1-marcandre.lureau@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.68 on 10.5.11.23 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.31]); Sun, 04 Sep 2016 22:21:52 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PATCH 18/18] virtio-gpu: start/stop the data-plane X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: airlied@redhat.com, kraxel@redhat.com, =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Virus-Scanned: ClamAV using ClamSMTP 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 --- 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 #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