From patchwork Thu Feb 13 12:03:22 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Antonios Motakis X-Patchwork-Id: 319990 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 024312C00B0 for ; Thu, 13 Feb 2014 23:07:17 +1100 (EST) Received: from localhost ([::1]:45741 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1WDv4U-0003Ny-Go for incoming@patchwork.ozlabs.org; Thu, 13 Feb 2014 07:07:14 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:39808) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1WDv1l-00080l-OI for qemu-devel@nongnu.org; Thu, 13 Feb 2014 07:04:31 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1WDv1f-00018U-GJ for qemu-devel@nongnu.org; Thu, 13 Feb 2014 07:04:25 -0500 Received: from mail-wi0-f181.google.com ([209.85.212.181]:53744) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1WDv1f-00018N-79 for qemu-devel@nongnu.org; Thu, 13 Feb 2014 07:04:19 -0500 Received: by mail-wi0-f181.google.com with SMTP id hi5so8434880wib.14 for ; Thu, 13 Feb 2014 04:04:18 -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=0XrRzG9UNJoeiB22MT4G/j69vem+KxstqEkmdd0h4vg=; b=T6QIbYXFxw/Gs3Snf5Baj4AlAG6CB7dAorTFIgtNUnKRNMBOTUJfU0aiJUK7BMp2I7 Q5uD9drjzPl8Fao48Zoivxv1pKkdqZPVcqLklWTWuaCSSUFu968XFFMsLGiKdrEcH27k gayZ+pJUYqz9f8+suQweWMA5/2NUsgPicFGQuGEngQhbbSRu+CQcFF3ZvUjjF9ZHLFQQ nSMBIJ29Xj+pNkNwst9UUOKRABKuSgz14lB/VLf2SKXuN85HnbDE63+W0tqHcAYSC3Rz o+PKnMuryNVU/9errP7OWaQ+HtHyjzbWbpvOrowpuEzXEYJxswARXPITz839S+vQ8o0t 9n7w== X-Gm-Message-State: ALoCoQnXlqpOmbwJ+ptgAmhQKn7V01aXRPwifUQ33/obVq7zRCVa4VAk/lu72z6o2XyaBlANBMv5 X-Received: by 10.180.37.178 with SMTP id z18mr6153317wij.46.1392293058466; Thu, 13 Feb 2014 04:04:18 -0800 (PST) Received: from localhost.localdomain (home.tvelocity.eu. [82.67.68.96]) by mx.google.com with ESMTPSA id bj3sm4039419wjb.14.2014.02.13.04.04.15 for (version=TLSv1.1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Thu, 13 Feb 2014 04:04:17 -0800 (PST) From: Antonios Motakis To: qemu-devel@nongnu.org, snabb-devel@googlegroups.com Date: Thu, 13 Feb 2014 13:03:22 +0100 Message-Id: <1392293009-13812-12-git-send-email-a.motakis@virtualopensystems.com> X-Mailer: git-send-email 1.8.3.2 In-Reply-To: <1392293009-13812-1-git-send-email-a.motakis@virtualopensystems.com> References: <1392293009-13812-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: 209.85.212.181 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 v8 11/17] 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 | 81 +++++++++++++++++++++++---------------- 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, 137 insertions(+), 38 deletions(-) create mode 100644 hw/virtio/vhost-backend.c diff --git a/hw/net/vhost_net.c b/hw/net/vhost_net.c index 4490173..cc27426 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,14 +106,18 @@ 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->dev.backend_features = + tap_has_vnet_hdr(options->net_backend) ? 0 : + (1 << VHOST_NET_F_VIRTIO_NET_HDR); } net->nc = options->net_backend; - net->dev.backend_features = tap_has_vnet_hdr(options->net_backend) ? 0 : - (1 << VHOST_NET_F_VIRTIO_NET_HDR); net->backend = r; net->dev.nvqs = 2; @@ -121,21 +125,23 @@ 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; } - if (!tap_has_vnet_hdr_len(options->net_backend, - 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 (!tap_has_vnet_hdr_len(options->net_backend, + 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; + } } - /* Set sane init value. Override when guest acks. */ vhost_net_ack_features(net, 0); return net; @@ -178,23 +184,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); @@ -215,10 +227,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 a2c76a4..d572a4e 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 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 0840093..eda4039 100644 --- a/net/tap.c +++ b/net/tap.c @@ -624,6 +624,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;