From patchwork Tue Mar 4 18:22:57 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Antonios Motakis X-Patchwork-Id: 326466 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id BD2442C009C for ; Wed, 5 Mar 2014 06:44:35 +1100 (EST) Received: from localhost ([::1]:48155 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1WKvGT-0003AR-Cx for incoming@patchwork.ozlabs.org; Tue, 04 Mar 2014 14:44:33 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:54471) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1WKu9w-0003Hu-GN for qemu-devel@nongnu.org; Tue, 04 Mar 2014 13:33:50 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1WKu9q-0007gm-3G for qemu-devel@nongnu.org; Tue, 04 Mar 2014 13:33:44 -0500 Received: from mail-wg0-f45.google.com ([74.125.82.45]:40232) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1WKu9p-0007gJ-RY for qemu-devel@nongnu.org; Tue, 04 Mar 2014 13:33:38 -0500 Received: by mail-wg0-f45.google.com with SMTP id m15so5432598wgh.28 for ; Tue, 04 Mar 2014 10:33:37 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=vRND8YWHjZJVbwB20DGJx0TOyMFBPbhherTlSx6f2og=; b=hsidSHUIiUgGynrSUD7WV7U3TAXmYCMBNjaVRkZ87NYTC5FKDXC1dJQ9NGgzahMhYR +o66amcLneyUc30Tn29C6PXZFGS0gdDieUKs5ZmBSoGMaXg5QdpORhWgBwOZ1cjOYXRE UB+ID22KBuUyWG2xoiKcyXk1p61zu5xtkMxibfUNT3g55bR012Iha/G263XwQR/eQyJF 139T1BRyGU9DK5R5zqUxe6jZDpXcqmhfDW5/MG6CJ7P6XO4b4sQirTIu8wgDdt2e/QId NADDrxR9U3IVxkmnDMXmTjF0WLBoFLvfPRMvdyKivBweEfwgA32Pp3K+Yzu9jnp7GLgD V2yw== X-Gm-Message-State: ALoCoQknGWVJcdpm5CFJQcq3UdLYtvDnM+lD56xyKJ6fqXytz83AlJJAEGBw/vdDgmc6jSZUrF4P X-Received: by 10.194.108.162 with SMTP id hl2mr1553412wjb.84.1393957522234; Tue, 04 Mar 2014 10:25:22 -0800 (PST) Received: from localhost.localdomain (home.tvelocity.eu. [82.67.68.96]) by mx.google.com with ESMTPSA id br10sm55666369wjb.3.2014.03.04.10.25.18 for (version=TLSv1.1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Tue, 04 Mar 2014 10:25:21 -0800 (PST) From: Antonios Motakis To: qemu-devel@nongnu.org, snabb-devel@googlegroups.com Date: Tue, 4 Mar 2014 19:22:57 +0100 Message-Id: <1393957383-16685-15-git-send-email-a.motakis@virtualopensystems.com> X-Mailer: git-send-email 1.8.3.2 In-Reply-To: <1393957383-16685-1-git-send-email-a.motakis@virtualopensystems.com> References: <1393957383-16685-1-git-send-email-a.motakis@virtualopensystems.com> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 74.125.82.45 Cc: Peter Maydell , Stefan Hajnoczi , mst@redhat.com, n.nikolaev@virtualopensystems.com, Nicholas Bellinger , Anthony Liguori , Paolo Bonzini , lukego@gmail.com, Antonios Motakis , tech@virtualopensystems.com, KONRAD Frederic Subject: [Qemu-devel] [PATCH v9 14/20] Add vhost-backend and VhostBackendType X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Use vhost_set_backend_type to initialise a proper vhost_ops structure. In vhost_net_init and vhost_net_start_one call conditionally TAP related initialisation depending on the vhost backend type. Signed-off-by: Antonios Motakis Signed-off-by: Nikolay Nikolaev --- hw/net/vhost_net.c | 67 +++++++++++++++++++++++---------------- hw/scsi/vhost-scsi.c | 2 +- hw/virtio/Makefile.objs | 2 +- hw/virtio/vhost-backend.c | 66 ++++++++++++++++++++++++++++++++++++++ hw/virtio/vhost.c | 6 +++- include/hw/virtio/vhost-backend.h | 11 +++++++ include/hw/virtio/vhost.h | 4 +-- include/net/vhost_net.h | 2 ++ net/tap.c | 1 + 9 files changed, 129 insertions(+), 32 deletions(-) create mode 100644 hw/virtio/vhost-backend.c diff --git a/hw/net/vhost_net.c b/hw/net/vhost_net.c index 38e1e8a..48cfda7 100644 --- a/hw/net/vhost_net.c +++ b/hw/net/vhost_net.c @@ -98,7 +98,7 @@ static int vhost_net_get_fd(NetClientState *backend) struct vhost_net *vhost_net_init(VhostNetOptions *options) { - int r; + int r = -1; struct vhost_net *net = g_malloc(sizeof *net); if (!options->net_backend) { @@ -106,9 +106,11 @@ struct vhost_net *vhost_net_init(VhostNetOptions *options) goto fail; } - r = vhost_net_get_fd(options->net_backend); - if (r < 0) { - goto fail; + if (options->backend_type == VHOST_BACKEND_TYPE_KERNEL) { + r = vhost_net_get_fd(options->net_backend); + if (r < 0) { + goto fail; + } } net->nc = options->net_backend; net->dev.backend_features = qemu_has_vnet_hdr(options->net_backend) ? 0 : @@ -120,7 +122,7 @@ struct vhost_net *vhost_net_init(VhostNetOptions *options) net->dev.mandatory_features = options->mandatory_features; r = vhost_dev_init(&net->dev, options->opaque, - options->force); + options->backend_type, options->force); if (r < 0) { goto fail; } @@ -128,13 +130,15 @@ struct vhost_net *vhost_net_init(VhostNetOptions *options) sizeof(struct virtio_net_hdr_mrg_rxbuf))) { net->dev.features &= ~(1 << VIRTIO_NET_F_MRG_RXBUF); } - if (~net->dev.features & net->dev.backend_features) { - fprintf(stderr, "vhost lacks feature mask %" PRIu64 " for backend\n", - (uint64_t)(~net->dev.features & net->dev.backend_features)); - vhost_dev_cleanup(&net->dev); - goto fail; + if (options->backend_type == VHOST_BACKEND_TYPE_KERNEL) { + if (~net->dev.features & net->dev.backend_features) { + fprintf(stderr, "vhost lacks feature mask %" PRIu64 + " for backend\n", + (uint64_t)(~net->dev.features & net->dev.backend_features)); + vhost_dev_cleanup(&net->dev); + goto fail; + } } - /* Set sane init value. Override when guest acks. */ vhost_net_ack_features(net, 0); return net; @@ -177,23 +181,29 @@ static int vhost_net_start_one(struct vhost_net *net, net->nc->info->poll(net->nc, false); } - qemu_set_fd_handler(net->backend, NULL, NULL, NULL); - file.fd = net->backend; - for (file.index = 0; file.index < net->dev.nvqs; ++file.index) { - const VhostOps *vhost_ops = net->dev.vhost_ops; - r = vhost_ops->vhost_call(&net->dev, VHOST_NET_SET_BACKEND, &file); - if (r < 0) { - r = -errno; - goto fail; + if (net->nc->info->type == NET_CLIENT_OPTIONS_KIND_TAP) { + qemu_set_fd_handler(net->backend, NULL, NULL, NULL); + file.fd = net->backend; + for (file.index = 0; file.index < net->dev.nvqs; ++file.index) { + const VhostOps *vhost_ops = net->dev.vhost_ops; + r = vhost_ops->vhost_call(&net->dev, VHOST_NET_SET_BACKEND, + &file); + if (r < 0) { + r = -errno; + goto fail; + } } } return 0; fail: file.fd = -1; - while (file.index-- > 0) { - const VhostOps *vhost_ops = net->dev.vhost_ops; - int r = vhost_ops->vhost_call(&net->dev, VHOST_NET_SET_BACKEND, &file); - assert(r >= 0); + if (net->nc->info->type == NET_CLIENT_OPTIONS_KIND_TAP) { + while (file.index-- > 0) { + const VhostOps *vhost_ops = net->dev.vhost_ops; + int r = vhost_ops->vhost_call(&net->dev, VHOST_NET_SET_BACKEND, + &file); + assert(r >= 0); + } } if (net->nc->info->poll) { net->nc->info->poll(net->nc, true); @@ -214,10 +224,13 @@ static void vhost_net_stop_one(struct vhost_net *net, return; } - for (file.index = 0; file.index < net->dev.nvqs; ++file.index) { - const VhostOps *vhost_ops = net->dev.vhost_ops; - int r = vhost_ops->vhost_call(&net->dev, VHOST_NET_SET_BACKEND, &file); - assert(r >= 0); + if (net->nc->info->type == NET_CLIENT_OPTIONS_KIND_TAP) { + for (file.index = 0; file.index < net->dev.nvqs; ++file.index) { + const VhostOps *vhost_ops = net->dev.vhost_ops; + int r = vhost_ops->vhost_call(&net->dev, VHOST_NET_SET_BACKEND, + &file); + assert(r >= 0); + } } if (net->nc->info->poll) { net->nc->info->poll(net->nc, true); diff --git a/hw/scsi/vhost-scsi.c b/hw/scsi/vhost-scsi.c index 48a9ced..c099fb6 100644 --- a/hw/scsi/vhost-scsi.c +++ b/hw/scsi/vhost-scsi.c @@ -239,7 +239,7 @@ static void vhost_scsi_realize(DeviceState *dev, Error **errp) s->dev.vq_index = 0; ret = vhost_dev_init(&s->dev, (void *)(uintptr_t)vhostfd, - true); + VHOST_BACKEND_TYPE_KERNEL, true); if (ret < 0) { error_setg(errp, "vhost-scsi: vhost initialization failed: %s", strerror(-ret)); diff --git a/hw/virtio/Makefile.objs b/hw/virtio/Makefile.objs index 1ba53d9..51e5bdb 100644 --- a/hw/virtio/Makefile.objs +++ b/hw/virtio/Makefile.objs @@ -5,4 +5,4 @@ common-obj-y += virtio-mmio.o common-obj-$(CONFIG_VIRTIO_BLK_DATA_PLANE) += dataplane/ obj-y += virtio.o virtio-balloon.o -obj-$(CONFIG_LINUX) += vhost.o +obj-$(CONFIG_LINUX) += vhost.o vhost-backend.o diff --git a/hw/virtio/vhost-backend.c b/hw/virtio/vhost-backend.c new file mode 100644 index 0000000..509e103 --- /dev/null +++ b/hw/virtio/vhost-backend.c @@ -0,0 +1,66 @@ +/* + * vhost-backend + * + * Copyright (c) 2013 Virtual Open Systems Sarl. + * + * This work is licensed under the terms of the GNU GPL, version 2 or later. + * See the COPYING file in the top-level directory. + * + */ + +#include "hw/virtio/vhost.h" +#include "hw/virtio/vhost-backend.h" +#include "qemu/error-report.h" + +#include + +static int vhost_kernel_call(struct vhost_dev *dev, unsigned long int request, + void *arg) +{ + int fd = (uintptr_t) dev->opaque; + + assert(dev->vhost_ops->backend_type == VHOST_BACKEND_TYPE_KERNEL); + + return ioctl(fd, request, arg); +} + +static int vhost_kernel_init(struct vhost_dev *dev, void *opaque) +{ + assert(dev->vhost_ops->backend_type == VHOST_BACKEND_TYPE_KERNEL); + + dev->opaque = opaque; + + return 0; +} + +static int vhost_kernel_cleanup(struct vhost_dev *dev) +{ + int fd = (uintptr_t) dev->opaque; + + assert(dev->vhost_ops->backend_type == VHOST_BACKEND_TYPE_KERNEL); + + return close(fd); +} + +static const VhostOps kernel_ops = { + .backend_type = VHOST_BACKEND_TYPE_KERNEL, + .vhost_call = vhost_kernel_call, + .vhost_backend_init = vhost_kernel_init, + .vhost_backend_cleanup = vhost_kernel_cleanup +}; + +int vhost_set_backend_type(struct vhost_dev *dev, VhostBackendType backend_type) +{ + int r = 0; + + switch (backend_type) { + case VHOST_BACKEND_TYPE_KERNEL: + dev->vhost_ops = &kernel_ops; + break; + default: + error_report("Unknown vhost backend type\n"); + r = -1; + } + + return r; +} diff --git a/hw/virtio/vhost.c b/hw/virtio/vhost.c index 346193f..6dacee2 100644 --- a/hw/virtio/vhost.c +++ b/hw/virtio/vhost.c @@ -815,11 +815,15 @@ static void vhost_virtqueue_cleanup(struct vhost_virtqueue *vq) } int vhost_dev_init(struct vhost_dev *hdev, void *opaque, - bool force) + VhostBackendType backend_type, bool force) { uint64_t features; int i, r; + if (vhost_set_backend_type(hdev, backend_type) < 0) { + return -1; + } + if (hdev->vhost_ops->vhost_backend_init(hdev, opaque) < 0) { return -errno; } diff --git a/include/hw/virtio/vhost-backend.h b/include/hw/virtio/vhost-backend.h index 14e5878..d31768a 100644 --- a/include/hw/virtio/vhost-backend.h +++ b/include/hw/virtio/vhost-backend.h @@ -11,6 +11,13 @@ #ifndef VHOST_BACKEND_H_ #define VHOST_BACKEND_H_ +typedef enum VhostBackendType { + VHOST_BACKEND_TYPE_NONE = 0, + VHOST_BACKEND_TYPE_KERNEL = 1, + VHOST_BACKEND_TYPE_USER = 2, + VHOST_BACKEND_TYPE_MAX = 3, +} VhostBackendType; + struct vhost_dev; typedef int (*vhost_call)(struct vhost_dev *dev, unsigned long int request, @@ -19,9 +26,13 @@ typedef int (*vhost_backend_init)(struct vhost_dev *dev, void *opaque); typedef int (*vhost_backend_cleanup)(struct vhost_dev *dev); typedef struct VhostOps { + VhostBackendType backend_type; vhost_call vhost_call; vhost_backend_init vhost_backend_init; vhost_backend_cleanup vhost_backend_cleanup; } VhostOps; +int vhost_set_backend_type(struct vhost_dev *dev, + VhostBackendType backend_type); + #endif /* VHOST_BACKEND_H_ */ diff --git a/include/hw/virtio/vhost.h b/include/hw/virtio/vhost.h index 0068d40..e5718da 100644 --- a/include/hw/virtio/vhost.h +++ b/include/hw/virtio/vhost.h @@ -30,7 +30,6 @@ typedef unsigned long vhost_log_chunk_t; struct vhost_memory; struct vhost_dev { MemoryListener memory_listener; - int control; struct vhost_memory *mem; int n_mem_sections; MemoryRegionSection *mem_sections; @@ -51,10 +50,11 @@ struct vhost_dev { hwaddr mem_changed_start_addr; hwaddr mem_changed_end_addr; const VhostOps *vhost_ops; + void *opaque; }; int vhost_dev_init(struct vhost_dev *hdev, void *opaque, - bool force); + VhostBackendType backend_type, bool force); void vhost_dev_cleanup(struct vhost_dev *hdev); bool vhost_dev_query(struct vhost_dev *hdev, VirtIODevice *vdev); int vhost_dev_start(struct vhost_dev *hdev, VirtIODevice *vdev); diff --git a/include/net/vhost_net.h b/include/net/vhost_net.h index b39bb45..5d99b37 100644 --- a/include/net/vhost_net.h +++ b/include/net/vhost_net.h @@ -2,11 +2,13 @@ #define VHOST_NET_H #include "net/net.h" +#include "hw/virtio/vhost-backend.h" struct vhost_net; typedef struct vhost_net VHostNetState; typedef struct VhostNetOptions { + VhostBackendType backend_type; NetClientState *net_backend; void *opaque; bool force; diff --git a/net/tap.c b/net/tap.c index fb50106..4311f88 100644 --- a/net/tap.c +++ b/net/tap.c @@ -630,6 +630,7 @@ static int net_init_tap_one(const NetdevTapOptions *tap, NetClientState *peer, vhostfdname || (tap->has_vhostforce && tap->vhostforce)) { VhostNetOptions options; + options.backend_type = VHOST_BACKEND_TYPE_KERNEL; options.net_backend = &s->nc; options.force = tap->has_vhostforce && tap->vhostforce;