From patchwork Tue May 27 12:05:49 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nikolay Nikolaev X-Patchwork-Id: 352907 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 4B374140098 for ; Tue, 27 May 2014 22:36:01 +1000 (EST) Received: from localhost ([::1]:34038 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1WpGbn-0001zt-1F for incoming@patchwork.ozlabs.org; Tue, 27 May 2014 08:35:59 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:43669) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1WpG8p-0006iw-Lt for qemu-devel@nongnu.org; Tue, 27 May 2014 08:06:09 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1WpG8j-00081S-DS for qemu-devel@nongnu.org; Tue, 27 May 2014 08:06:03 -0400 Received: from mail-wg0-f43.google.com ([74.125.82.43]:55754) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1WpG8j-00081I-5B for qemu-devel@nongnu.org; Tue, 27 May 2014 08:05:57 -0400 Received: by mail-wg0-f43.google.com with SMTP id l18so9141258wgh.26 for ; Tue, 27 May 2014 05:05:56 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:subject:from:to:cc:date:message-id:in-reply-to :references:user-agent:mime-version:content-type :content-transfer-encoding; bh=SY11J3Eb9bGXJB9JUxciWNUwveavK8ASQXg2ZhqhyjM=; b=TL8uTMTC8Nz3/Gp3NkgEtdAt7xGnMruekg/9VUrLe68cBZB0YLHO2CWgEZCeanDBrB zQ27ILfM471HceJLGcQXmiu427AL1PoZwzNXwTH64iJLTj3QqG4AkUI7GFblXEfQe+gX RPZFz2qzNbe53qCPsbgYZhls4ASzlR9s5pbAlXBkByldjyC/tSeXYmhHBMqdsRsf9LSC P2mTlNRDhrl3u1nQTHtYwjw+7UOF06W6Sv55V24iG4l6azuJqKonBVAxREqeelMf8AK8 T7SRFu51wgil/YgSTggzkWFOVgxXMTm0DgO4rSwhgIXrAEumDvu++Qbhv8PhKu9gTT4q +m0Q== X-Gm-Message-State: ALoCoQmA1xIt8yKkcN2ZrK+NUVLfwHZNm0OZLz/r2ULKvlKnNG2NIQECBHeGAr5W0LPSeStaNg58 X-Received: by 10.180.72.15 with SMTP id z15mr24376289wiu.46.1401192356495; Tue, 27 May 2014 05:05:56 -0700 (PDT) Received: from [0.0.14.236] ([82.146.27.14]) by mx.google.com with ESMTPSA id nb8sm7833250wic.18.2014.05.27.05.05.54 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 27 May 2014 05:05:55 -0700 (PDT) From: Nikolay Nikolaev To: snabb-devel@googlegroups.com, qemu-devel@nongnu.org Date: Tue, 27 May 2014 15:05:49 +0300 Message-ID: <20140527120543.15172.19272.stgit@3820> In-Reply-To: <20140527120050.15172.94908.stgit@3820> References: <20140527120050.15172.94908.stgit@3820> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 74.125.82.43 Cc: a.motakis@virtualopensystems.com, luke@snabb.co, tech@virtualopensystems.com, n.nikolaev@virtualopensystems.com, mst@redhat.com Subject: [Qemu-devel] [PATCH v10 11/18] 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 | 75 +++++++++++++++++++++++-------------- 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, 135 insertions(+), 34 deletions(-) create mode 100644 hw/virtio/vhost-backend.c diff --git a/hw/net/vhost_net.c b/hw/net/vhost_net.c index 402f37e..2ec36d3 100644 --- a/hw/net/vhost_net.c +++ b/hw/net/vhost_net.c @@ -96,6 +96,7 @@ static int vhost_net_get_fd(NetClientState *backend) struct vhost_net *vhost_net_init(VhostNetOptions *options) { int r; + bool backend_kernel = options->backend_type == VHOST_BACKEND_TYPE_KERNEL; struct vhost_net *net = g_malloc(sizeof *net); if (!options->net_backend) { @@ -103,20 +104,25 @@ struct vhost_net *vhost_net_init(VhostNetOptions *options) goto fail; } - r = vhost_net_get_fd(options->net_backend); - if (r < 0) { - goto fail; + if (backend_kernel) { + r = vhost_net_get_fd(options->net_backend); + if (r < 0) { + goto fail; + } + net->dev.backend_features = qemu_has_vnet_hdr(options->net_backend) + ? 0 : (1 << VHOST_NET_F_VIRTIO_NET_HDR); + net->backend = r; + } else { + net->dev.backend_features = 0; + net->backend = -1; } net->nc = options->net_backend; - net->dev.backend_features = qemu_has_vnet_hdr(options->net_backend) ? 0 : - (1 << VHOST_NET_F_VIRTIO_NET_HDR); - net->backend = r; net->dev.nvqs = 2; net->dev.vqs = net->vqs; r = vhost_dev_init(&net->dev, options->opaque, - options->force); + options->backend_type, options->force); if (r < 0) { goto fail; } @@ -124,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 (backend_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; @@ -173,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); @@ -210,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 7bcbb4a..a9f8dd2 100644 --- a/hw/scsi/vhost-scsi.c +++ b/hw/scsi/vhost-scsi.c @@ -234,7 +234,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 74f20a2..c8d86bd 100644 --- a/hw/virtio/vhost.c +++ b/hw/virtio/vhost.c @@ -814,11 +814,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 4714277..33028ec 100644 --- a/include/hw/virtio/vhost.h +++ b/include/hw/virtio/vhost.h @@ -31,7 +31,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 2067ee2..b1c18a3 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 5789ff8..a40f7f0 100644 --- a/net/tap.c +++ b/net/tap.c @@ -627,6 +627,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;