From patchwork Tue May 27 12:05:35 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nikolay Nikolaev X-Patchwork-Id: 352898 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 72B281400A3 for ; Tue, 27 May 2014 22:11:54 +1000 (EST) Received: from localhost ([::1]:33888 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1WpGES-0006ta-B3 for incoming@patchwork.ozlabs.org; Tue, 27 May 2014 08:11:52 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:43613) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1WpG8c-0006Ml-Lh for qemu-devel@nongnu.org; Tue, 27 May 2014 08:05:56 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1WpG8V-000800-Tt for qemu-devel@nongnu.org; Tue, 27 May 2014 08:05:50 -0400 Received: from mail-we0-f169.google.com ([74.125.82.169]:64485) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1WpG8V-0007zt-Jn for qemu-devel@nongnu.org; Tue, 27 May 2014 08:05:43 -0400 Received: by mail-we0-f169.google.com with SMTP id u56so9542383wes.28 for ; Tue, 27 May 2014 05:05:43 -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=Bxi+d9+DmnuwJAKPIlC9aC44GDSgF4b48gkbBedz7rc=; b=dY39n2cYn2OmDnNdKuNXaTVG44giZ0XOSgiXxffWRV0FQ0D1a6io3hnrCG2ffcReC3 kb44Anq4UV17fIIod4BJp8zm5aRLSz8GwhD4fjMCOn/qIh835K0uufenFrv8D3fH8TnR cXG19jOYBzUE9eDsX7TQg1K22uj0jtFbl8AdrqgyvXqSs5UJFRN3yBkX6bX4XrYxM7CV ymQfWcJR+Lm2qij528LbmsKTDJHXpVEfPMzh1YQP5ed35LwlmJgU1x1WUqMsbfeJ+wlZ Uj9e4CBg5WOfTK/gNS5meWr2ihXn3FYNrMJroqokLGzieDMEGKoHIEeERzjV4D6cwnXT la8Q== X-Gm-Message-State: ALoCoQlEPchdT/r3aox8t4g/fq8erdf09Mex3LjCWdvEaPWHnOEXLxJoi08q4yM9Kk8+DpF5IU/D X-Received: by 10.194.186.178 with SMTP id fl18mr7546547wjc.83.1401192342858; Tue, 27 May 2014 05:05:42 -0700 (PDT) Received: from [0.0.14.236] ([82.146.27.14]) by mx.google.com with ESMTPSA id em5sm7835438wic.23.2014.05.27.05.05.41 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 27 May 2014 05:05:42 -0700 (PDT) From: Nikolay Nikolaev To: snabb-devel@googlegroups.com, qemu-devel@nongnu.org Date: Tue, 27 May 2014 15:05:35 +0300 Message-ID: <20140527120530.15172.79120.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.169 Cc: a.motakis@virtualopensystems.com, luke@snabb.co, tech@virtualopensystems.com, n.nikolaev@virtualopensystems.com, mst@redhat.com Subject: [Qemu-devel] [PATCH v10 10/18] Add vhost_ops to vhost_dev struct and replace all relevant ioctls 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 Decouple vhost from the Linux kernel by introducing vhost_ops. The intention is to provide different backends - a 'kernel' backend based on the ioctl interface, and an 'user' backend based on a UNIX domain socket and shared memory interface. Signed-off-by: Antonios Motakis Signed-off-by: Nikolay Nikolaev --- hw/net/vhost_net.c | 10 +++++---- hw/scsi/vhost-scsi.c | 10 ++++++--- hw/virtio/vhost.c | 41 +++++++++++++++++++------------------ include/hw/virtio/vhost-backend.h | 27 ++++++++++++++++++++++++ include/hw/virtio/vhost.h | 2 ++ 5 files changed, 63 insertions(+), 27 deletions(-) create mode 100644 include/hw/virtio/vhost-backend.h diff --git a/hw/net/vhost_net.c b/hw/net/vhost_net.c index 7a5523f..402f37e 100644 --- a/hw/net/vhost_net.c +++ b/hw/net/vhost_net.c @@ -27,7 +27,6 @@ #include #include #include -#include #include #include #include @@ -177,7 +176,8 @@ static int vhost_net_start_one(struct vhost_net *net, qemu_set_fd_handler(net->backend, NULL, NULL, NULL); file.fd = net->backend; for (file.index = 0; file.index < net->dev.nvqs; ++file.index) { - r = ioctl(net->dev.control, VHOST_NET_SET_BACKEND, &file); + 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; @@ -187,7 +187,8 @@ static int vhost_net_start_one(struct vhost_net *net, fail: file.fd = -1; while (file.index-- > 0) { - int r = ioctl(net->dev.control, VHOST_NET_SET_BACKEND, &file); + 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) { @@ -210,7 +211,8 @@ static void vhost_net_stop_one(struct vhost_net *net, } for (file.index = 0; file.index < net->dev.nvqs; ++file.index) { - int r = ioctl(net->dev.control, VHOST_NET_SET_BACKEND, &file); + 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) { diff --git a/hw/scsi/vhost-scsi.c b/hw/scsi/vhost-scsi.c index 605548d..7bcbb4a 100644 --- a/hw/scsi/vhost-scsi.c +++ b/hw/scsi/vhost-scsi.c @@ -36,12 +36,13 @@ static const int kernel_feature_bits[] = { static int vhost_scsi_set_endpoint(VHostSCSI *s) { VirtIOSCSICommon *vs = VIRTIO_SCSI_COMMON(s); + const VhostOps *vhost_ops = s->dev.vhost_ops; struct vhost_scsi_target backend; int ret; memset(&backend, 0, sizeof(backend)); pstrcpy(backend.vhost_wwpn, sizeof(backend.vhost_wwpn), vs->conf.wwpn); - ret = ioctl(s->dev.control, VHOST_SCSI_SET_ENDPOINT, &backend); + ret = vhost_ops->vhost_call(&s->dev, VHOST_SCSI_SET_ENDPOINT, &backend); if (ret < 0) { return -errno; } @@ -52,10 +53,11 @@ static void vhost_scsi_clear_endpoint(VHostSCSI *s) { VirtIOSCSICommon *vs = VIRTIO_SCSI_COMMON(s); struct vhost_scsi_target backend; + const VhostOps *vhost_ops = s->dev.vhost_ops; memset(&backend, 0, sizeof(backend)); pstrcpy(backend.vhost_wwpn, sizeof(backend.vhost_wwpn), vs->conf.wwpn); - ioctl(s->dev.control, VHOST_SCSI_CLEAR_ENDPOINT, &backend); + vhost_ops->vhost_call(&s->dev, VHOST_SCSI_CLEAR_ENDPOINT, &backend); } static int vhost_scsi_start(VHostSCSI *s) @@ -64,13 +66,15 @@ static int vhost_scsi_start(VHostSCSI *s) VirtIODevice *vdev = VIRTIO_DEVICE(s); BusState *qbus = BUS(qdev_get_parent_bus(DEVICE(vdev))); VirtioBusClass *k = VIRTIO_BUS_GET_CLASS(qbus); + const VhostOps *vhost_ops = s->dev.vhost_ops; if (!k->set_guest_notifiers) { error_report("binding does not support guest notifiers"); return -ENOSYS; } - ret = ioctl(s->dev.control, VHOST_SCSI_GET_ABI_VERSION, &abi_version); + ret = vhost_ops->vhost_call(&s->dev, + VHOST_SCSI_GET_ABI_VERSION, &abi_version); if (ret < 0) { return -errno; } diff --git a/hw/virtio/vhost.c b/hw/virtio/vhost.c index 694c618..74f20a2 100644 --- a/hw/virtio/vhost.c +++ b/hw/virtio/vhost.c @@ -13,7 +13,6 @@ * GNU GPL, version 2 or (at your option) any later version. */ -#include #include "hw/virtio/vhost.h" #include "hw/hw.h" #include "qemu/atomic.h" @@ -291,7 +290,7 @@ static inline void vhost_dev_log_resize(struct vhost_dev* dev, uint64_t size) log = g_malloc0(size * sizeof *log); log_base = (uint64_t)(unsigned long)log; - r = ioctl(dev->control, VHOST_SET_LOG_BASE, &log_base); + r = dev->vhost_ops->vhost_call(dev, VHOST_SET_LOG_BASE, &log_base); assert(r >= 0); /* Sync only the range covered by the old log */ if (dev->log_size) { @@ -460,7 +459,7 @@ static void vhost_commit(MemoryListener *listener) } if (!dev->log_enabled) { - r = ioctl(dev->control, VHOST_SET_MEM_TABLE, dev->mem); + r = dev->vhost_ops->vhost_call(dev, VHOST_SET_MEM_TABLE, dev->mem); assert(r >= 0); dev->memory_changed = false; return; @@ -473,7 +472,7 @@ static void vhost_commit(MemoryListener *listener) if (dev->log_size < log_size) { vhost_dev_log_resize(dev, log_size + VHOST_LOG_BUFFER); } - r = ioctl(dev->control, VHOST_SET_MEM_TABLE, dev->mem); + r = dev->vhost_ops->vhost_call(dev, VHOST_SET_MEM_TABLE, dev->mem); assert(r >= 0); /* To log less, can only decrease log size after table update. */ if (dev->log_size > log_size + VHOST_LOG_BUFFER) { @@ -541,7 +540,7 @@ static int vhost_virtqueue_set_addr(struct vhost_dev *dev, .log_guest_addr = vq->used_phys, .flags = enable_log ? (1 << VHOST_VRING_F_LOG) : 0, }; - int r = ioctl(dev->control, VHOST_SET_VRING_ADDR, &addr); + int r = dev->vhost_ops->vhost_call(dev, VHOST_SET_VRING_ADDR, &addr); if (r < 0) { return -errno; } @@ -555,7 +554,7 @@ static int vhost_dev_set_features(struct vhost_dev *dev, bool enable_log) if (enable_log) { features |= 0x1 << VHOST_F_LOG_ALL; } - r = ioctl(dev->control, VHOST_SET_FEATURES, &features); + r = dev->vhost_ops->vhost_call(dev, VHOST_SET_FEATURES, &features); return r < 0 ? -errno : 0; } @@ -670,13 +669,13 @@ static int vhost_virtqueue_start(struct vhost_dev *dev, assert(idx >= dev->vq_index && idx < dev->vq_index + dev->nvqs); vq->num = state.num = virtio_queue_get_num(vdev, idx); - r = ioctl(dev->control, VHOST_SET_VRING_NUM, &state); + r = dev->vhost_ops->vhost_call(dev, VHOST_SET_VRING_NUM, &state); if (r) { return -errno; } state.num = virtio_queue_get_last_avail_idx(vdev, idx); - r = ioctl(dev->control, VHOST_SET_VRING_BASE, &state); + r = dev->vhost_ops->vhost_call(dev, VHOST_SET_VRING_BASE, &state); if (r) { return -errno; } @@ -718,7 +717,7 @@ static int vhost_virtqueue_start(struct vhost_dev *dev, } file.fd = event_notifier_get_fd(virtio_queue_get_host_notifier(vvq)); - r = ioctl(dev->control, VHOST_SET_VRING_KICK, &file); + r = dev->vhost_ops->vhost_call(dev, VHOST_SET_VRING_KICK, &file); if (r) { r = -errno; goto fail_kick; @@ -756,7 +755,7 @@ static void vhost_virtqueue_stop(struct vhost_dev *dev, }; int r; assert(idx >= dev->vq_index && idx < dev->vq_index + dev->nvqs); - r = ioctl(dev->control, VHOST_GET_VRING_BASE, &state); + r = dev->vhost_ops->vhost_call(dev, VHOST_GET_VRING_BASE, &state); if (r < 0) { fprintf(stderr, "vhost VQ %d ring restore failed: %d\n", idx, r); fflush(stderr); @@ -798,7 +797,7 @@ static int vhost_virtqueue_init(struct vhost_dev *dev, } file.fd = event_notifier_get_fd(&vq->masked_notifier); - r = ioctl(dev->control, VHOST_SET_VRING_CALL, &file); + r = dev->vhost_ops->vhost_call(dev, VHOST_SET_VRING_CALL, &file); if (r) { r = -errno; goto fail_call; @@ -819,14 +818,17 @@ int vhost_dev_init(struct vhost_dev *hdev, void *opaque, { uint64_t features; int i, r; - hdev->control = (uintptr_t) opaque;; - r = ioctl(hdev->control, VHOST_SET_OWNER, NULL); + if (hdev->vhost_ops->vhost_backend_init(hdev, opaque) < 0) { + return -errno; + } + + r = hdev->vhost_ops->vhost_call(hdev, VHOST_SET_OWNER, NULL); if (r < 0) { goto fail; } - r = ioctl(hdev->control, VHOST_GET_FEATURES, &features); + r = hdev->vhost_ops->vhost_call(hdev, VHOST_GET_FEATURES, &features); if (r < 0) { goto fail; } @@ -871,7 +873,7 @@ fail_vq: } fail: r = -errno; - close(hdev->control); + hdev->vhost_ops->vhost_backend_cleanup(hdev); return r; } @@ -884,7 +886,7 @@ void vhost_dev_cleanup(struct vhost_dev *hdev) memory_listener_unregister(&hdev->memory_listener); g_free(hdev->mem); g_free(hdev->mem_sections); - close(hdev->control); + hdev->vhost_ops->vhost_backend_cleanup(hdev); } bool vhost_dev_query(struct vhost_dev *hdev, VirtIODevice *vdev) @@ -986,7 +988,7 @@ void vhost_virtqueue_mask(struct vhost_dev *hdev, VirtIODevice *vdev, int n, } else { file.fd = event_notifier_get_fd(virtio_queue_get_guest_notifier(vvq)); } - r = ioctl(hdev->control, VHOST_SET_VRING_CALL, &file); + r = hdev->vhost_ops->vhost_call(hdev, VHOST_SET_VRING_CALL, &file); assert(r >= 0); } @@ -1028,7 +1030,7 @@ int vhost_dev_start(struct vhost_dev *hdev, VirtIODevice *vdev) if (r < 0) { goto fail_features; } - r = ioctl(hdev->control, VHOST_SET_MEM_TABLE, hdev->mem); + r = hdev->vhost_ops->vhost_call(hdev, VHOST_SET_MEM_TABLE, hdev->mem); if (r < 0) { r = -errno; goto fail_mem; @@ -1047,8 +1049,7 @@ int vhost_dev_start(struct vhost_dev *hdev, VirtIODevice *vdev) hdev->log_size = vhost_get_log_size(hdev); hdev->log = hdev->log_size ? g_malloc0(hdev->log_size * sizeof *hdev->log) : NULL; - r = ioctl(hdev->control, VHOST_SET_LOG_BASE, - (uint64_t)(unsigned long)hdev->log); + r = hdev->vhost_ops->vhost_call(hdev, VHOST_SET_LOG_BASE, hdev->log); if (r < 0) { r = -errno; goto fail_log; diff --git a/include/hw/virtio/vhost-backend.h b/include/hw/virtio/vhost-backend.h new file mode 100644 index 0000000..14e5878 --- /dev/null +++ b/include/hw/virtio/vhost-backend.h @@ -0,0 +1,27 @@ +/* + * 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. + * + */ + +#ifndef VHOST_BACKEND_H_ +#define VHOST_BACKEND_H_ + +struct vhost_dev; + +typedef int (*vhost_call)(struct vhost_dev *dev, unsigned long int request, + void *arg); +typedef int (*vhost_backend_init)(struct vhost_dev *dev, void *opaque); +typedef int (*vhost_backend_cleanup)(struct vhost_dev *dev); + +typedef struct VhostOps { + vhost_call vhost_call; + vhost_backend_init vhost_backend_init; + vhost_backend_cleanup vhost_backend_cleanup; +} VhostOps; + +#endif /* VHOST_BACKEND_H_ */ diff --git a/include/hw/virtio/vhost.h b/include/hw/virtio/vhost.h index 8afc6f9..4714277 100644 --- a/include/hw/virtio/vhost.h +++ b/include/hw/virtio/vhost.h @@ -2,6 +2,7 @@ #define VHOST_H #include "hw/hw.h" +#include "hw/virtio/vhost-backend.h" #include "hw/virtio/virtio.h" #include "exec/memory.h" @@ -49,6 +50,7 @@ struct vhost_dev { bool memory_changed; hwaddr mem_changed_start_addr; hwaddr mem_changed_end_addr; + const VhostOps *vhost_ops; }; int vhost_dev_init(struct vhost_dev *hdev, void *opaque,