From: "Michael S. Tsirkin" <mst@redhat.com>
To: marcandre.lureau@redhat.com
Cc: haifeng.lin@huawei.com, thibaut.collet@6wind.com,
jasowang@redhat.com, qemu-devel@nongnu.org, pbonzini@redhat.com
Subject: Re: [Qemu-devel] [PATCH v4 09/22] vhost: use a function for each call
Date: Mon, 21 Sep 2015 11:58:42 +0300 [thread overview]
Message-ID: <20150921115644-mutt-send-email-mst@redhat.com> (raw)
In-Reply-To: <1442657533-13030-10-git-send-email-marcandre.lureau@redhat.com>
On Sat, Sep 19, 2015 at 12:12:00PM +0200, marcandre.lureau@redhat.com wrote:
> From: Marc-André Lureau <marcandre.lureau@redhat.com>
>
> Replace the generic vhost_call() by specific functions for each
> function call to help with type safety and changing arguments.
>
> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
OK but I would rather not make logging feature depend on the
refactoring.
How about moving each call over from vhost_call by a separate patch?
Start with vhost_set_log_base as the 1st one, this way I can apply
logging support while we still review the larger refactorings.
> ---
> hw/net/vhost_net.c | 12 +-
> hw/scsi/vhost-scsi.c | 7 +-
> hw/virtio/vhost-backend.c | 140 +++++++++++--
> hw/virtio/vhost-user.c | 402 ++++++++++++++++++++++++++------------
> hw/virtio/vhost.c | 34 ++--
> include/hw/virtio/vhost-backend.h | 59 +++++-
> 6 files changed, 484 insertions(+), 170 deletions(-)
>
> diff --git a/hw/net/vhost_net.c b/hw/net/vhost_net.c
> index 9d32d76..d116fb3 100644
> --- a/hw/net/vhost_net.c
> +++ b/hw/net/vhost_net.c
> @@ -243,8 +243,7 @@ static int vhost_net_start_one(struct vhost_net *net,
> 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);
> + r = vhost_ops->vhost_net_set_backend(&net->dev, &file);
> if (r < 0) {
> r = -errno;
> goto fail;
> @@ -257,8 +256,7 @@ fail:
> 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);
> + int r = vhost_ops->vhost_net_set_backend(&net->dev, &file);
> assert(r >= 0);
> }
> }
> @@ -280,15 +278,13 @@ static void vhost_net_stop_one(struct vhost_net *net,
> 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);
> + int r = vhost_ops->vhost_net_set_backend(&net->dev, &file);
> assert(r >= 0);
> }
> } else if (net->nc->info->type == NET_CLIENT_OPTIONS_KIND_VHOST_USER) {
> 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_RESET_OWNER,
> - NULL);
> + int r = vhost_ops->vhost_reset_owner(&net->dev);
> assert(r >= 0);
> }
> }
> diff --git a/hw/scsi/vhost-scsi.c b/hw/scsi/vhost-scsi.c
> index bac9ddb..a0034ab 100644
> --- a/hw/scsi/vhost-scsi.c
> +++ b/hw/scsi/vhost-scsi.c
> @@ -45,7 +45,7 @@ static int vhost_scsi_set_endpoint(VHostSCSI *s)
>
> memset(&backend, 0, sizeof(backend));
> pstrcpy(backend.vhost_wwpn, sizeof(backend.vhost_wwpn), vs->conf.wwpn);
> - ret = vhost_ops->vhost_call(&s->dev, VHOST_SCSI_SET_ENDPOINT, &backend);
> + ret = vhost_ops->vhost_scsi_set_endpoint(&s->dev, &backend);
> if (ret < 0) {
> return -errno;
> }
> @@ -60,7 +60,7 @@ static void vhost_scsi_clear_endpoint(VHostSCSI *s)
>
> memset(&backend, 0, sizeof(backend));
> pstrcpy(backend.vhost_wwpn, sizeof(backend.vhost_wwpn), vs->conf.wwpn);
> - vhost_ops->vhost_call(&s->dev, VHOST_SCSI_CLEAR_ENDPOINT, &backend);
> + vhost_ops->vhost_scsi_clear_endpoint(&s->dev, &backend);
> }
>
> static int vhost_scsi_start(VHostSCSI *s)
> @@ -76,8 +76,7 @@ static int vhost_scsi_start(VHostSCSI *s)
> return -ENOSYS;
> }
>
> - ret = vhost_ops->vhost_call(&s->dev,
> - VHOST_SCSI_GET_ABI_VERSION, &abi_version);
> + ret = vhost_ops->vhost_scsi_get_abi_version(&s->dev, &abi_version);
> if (ret < 0) {
> return -errno;
> }
> diff --git a/hw/virtio/vhost-backend.c b/hw/virtio/vhost-backend.c
> index 4d68a27..bf2d1d4 100644
> --- a/hw/virtio/vhost-backend.c
> +++ b/hw/virtio/vhost-backend.c
> @@ -11,19 +11,10 @@
> #include "hw/virtio/vhost.h"
> #include "hw/virtio/vhost-backend.h"
> #include "qemu/error-report.h"
> +#include "linux/vhost.h"
>
> #include <sys/ioctl.h>
>
> -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);
> @@ -42,11 +33,136 @@ static int vhost_kernel_cleanup(struct vhost_dev *dev)
> return close(fd);
> }
>
> +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_net_set_backend(struct vhost_dev *dev,
> + struct vhost_vring_file *file)
> +{
> + return vhost_kernel_call(dev, VHOST_NET_SET_BACKEND, file);
> +}
> +
> +static int vhost_scsi_set_endpoint(struct vhost_dev *dev,
> + struct vhost_scsi_target *target)
> +{
> + return vhost_kernel_call(dev, VHOST_SCSI_SET_ENDPOINT, target);
> +}
> +
> +static int vhost_scsi_clear_endpoint(struct vhost_dev *dev,
> + struct vhost_scsi_target *target)
> +{
> + return vhost_kernel_call(dev, VHOST_SCSI_CLEAR_ENDPOINT, target);
> +}
> +
> +static int vhost_scsi_get_abi_version(struct vhost_dev *dev, int *version)
> +{
> + return vhost_kernel_call(dev, VHOST_SCSI_GET_ABI_VERSION, version);
> +}
> +
> +static int vhost_set_log_base(struct vhost_dev *dev, uint64_t base)
> +{
> + return vhost_kernel_call(dev, VHOST_SET_LOG_BASE, &base);
> +}
> +
> +static int vhost_set_mem_table(struct vhost_dev *dev,
> + struct vhost_memory *mem)
> +{
> + return vhost_kernel_call(dev, VHOST_SET_MEM_TABLE, mem);
> +}
> +
> +static int vhost_set_vring_addr(struct vhost_dev *dev,
> + struct vhost_vring_addr *addr)
> +{
> + return vhost_kernel_call(dev, VHOST_SET_VRING_ADDR, addr);
> +}
> +
> +static int vhost_set_vring_endian(struct vhost_dev *dev,
> + struct vhost_vring_state *ring)
> +{
> + return vhost_kernel_call(dev, VHOST_SET_VRING_ENDIAN, ring);
> +}
> +
> +static int vhost_set_vring_num(struct vhost_dev *dev,
> + struct vhost_vring_state *ring)
> +{
> + return vhost_kernel_call(dev, VHOST_SET_VRING_NUM, ring);
> +}
> +
> +static int vhost_set_vring_base(struct vhost_dev *dev,
> + struct vhost_vring_state *ring)
> +{
> + return vhost_kernel_call(dev, VHOST_SET_VRING_BASE, ring);
> +}
> +
> +static int vhost_get_vring_base(struct vhost_dev *dev,
> + struct vhost_vring_state *ring)
> +{
> + return vhost_kernel_call(dev, VHOST_GET_VRING_BASE, ring);
> +}
> +
> +static int vhost_set_vring_kick(struct vhost_dev *dev,
> + struct vhost_vring_file *file)
> +{
> + return vhost_kernel_call(dev, VHOST_SET_VRING_KICK, file);
> +}
> +
> +static int vhost_set_vring_call(struct vhost_dev *dev,
> + struct vhost_vring_file *file)
> +{
> + return vhost_kernel_call(dev, VHOST_SET_VRING_CALL, file);
> +}
> +
> +static int vhost_set_features(struct vhost_dev *dev,
> + uint64_t features)
> +{
> + return vhost_kernel_call(dev, VHOST_SET_FEATURES, &features);
> +}
> +
> +static int vhost_kernel_get_features(struct vhost_dev *dev,
> + uint64_t *features)
> +{
> + return vhost_kernel_call(dev, VHOST_GET_FEATURES, features);
> +}
> +
> +static int vhost_set_owner(struct vhost_dev *dev)
> +{
> + return vhost_kernel_call(dev, VHOST_SET_OWNER, NULL);
> +}
> +
> +static int vhost_reset_owner(struct vhost_dev *dev)
> +{
> + return vhost_kernel_call(dev, VHOST_RESET_OWNER, NULL);
> +}
> +
> 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
> + .vhost_backend_cleanup = vhost_kernel_cleanup,
> +
> + .vhost_net_set_backend = vhost_net_set_backend,
> + .vhost_scsi_set_endpoint = vhost_scsi_set_endpoint,
> + .vhost_scsi_clear_endpoint = vhost_scsi_clear_endpoint,
> + .vhost_scsi_get_abi_version = vhost_scsi_get_abi_version,
> + .vhost_set_log_base = vhost_set_log_base,
> + .vhost_set_mem_table = vhost_set_mem_table,
> + .vhost_set_vring_addr = vhost_set_vring_addr,
> + .vhost_set_vring_endian = vhost_set_vring_endian,
> + .vhost_set_vring_num = vhost_set_vring_num,
> + .vhost_set_vring_base = vhost_set_vring_base,
> + .vhost_get_vring_base = vhost_get_vring_base,
> + .vhost_set_vring_kick = vhost_set_vring_kick,
> + .vhost_set_vring_call = vhost_set_vring_call,
> + .vhost_set_features = vhost_set_features,
> + .vhost_get_features = vhost_kernel_get_features,
> + .vhost_set_owner = vhost_set_owner,
> + .vhost_reset_owner = vhost_reset_owner,
> };
>
> int vhost_set_backend_type(struct vhost_dev *dev, VhostBackendType backend_type)
> diff --git a/hw/virtio/vhost-user.c b/hw/virtio/vhost-user.c
> index de87562..d5b7951 100644
> --- a/hw/virtio/vhost-user.c
> +++ b/hw/virtio/vhost-user.c
> @@ -176,6 +176,7 @@ fail:
> return -1;
> }
>
> +/* most non-init callers ignore the error */
> static int vhost_user_write(struct vhost_dev *dev, VhostUserMsg *msg,
> int *fds, int fd_num)
> {
> @@ -190,148 +191,280 @@ static int vhost_user_write(struct vhost_dev *dev, VhostUserMsg *msg,
> 0 : -1;
> }
>
> -static int vhost_user_call(struct vhost_dev *dev, unsigned long int request,
> - void *arg)
> +static int vhost_net_set_backend(struct vhost_dev *dev,
> + struct vhost_vring_file *file)
> +{
> + error_report("vhost-user trying to send unhandled ioctl");
> + return -1;
> +}
> +
> +static int vhost_scsi_set_endpoint(struct vhost_dev *dev,
> + struct vhost_scsi_target *target)
> +{
> + error_report("vhost-user trying to send unhandled ioctl");
> + return -1;
> +}
> +
> +static int vhost_scsi_clear_endpoint(struct vhost_dev *dev,
> + struct vhost_scsi_target *target)
> +{
> + error_report("vhost-user trying to send unhandled ioctl");
> + return -1;
> +}
> +
> +static int vhost_scsi_get_abi_version(struct vhost_dev *dev, int *version)
> +{
> + error_report("vhost-user trying to send unhandled ioctl");
> + return -1;
> +}
> +
> +static int vhost_set_log_base(struct vhost_dev *dev, uint64_t base)
> +{
> + VhostUserMsg msg = {
> + .request = VHOST_USER_SET_LOG_BASE,
> + .flags = VHOST_USER_VERSION,
> + .u64 = base,
> + .size = sizeof(m.u64),
> + };
> +
> + vhost_user_write(dev, &msg, NULL, 0);
> +
> + return 0;
> +}
> +
> +static int vhost_set_mem_table(struct vhost_dev *dev,
> + struct vhost_memory *mem)
> {
> - VhostUserMsg msg;
> - VhostUserRequest msg_request;
> - struct vhost_vring_file *file = 0;
> - int need_reply = 0;
> int fds[VHOST_MEMORY_MAX_NREGIONS];
> int i, fd;
> size_t fd_num = 0;
> + VhostUserMsg msg = {
> + .request = VHOST_USER_SET_MEM_TABLE,
> + .flags = VHOST_USER_VERSION,
> + };
>
> - assert(dev->vhost_ops->backend_type == VHOST_BACKEND_TYPE_USER);
> + for (i = 0; i < dev->mem->nregions; ++i) {
> + struct vhost_memory_region *reg = dev->mem->regions + i;
> + ram_addr_t ram_addr;
> +
> + assert((uintptr_t)reg->userspace_addr == reg->userspace_addr);
> + qemu_ram_addr_from_host((void *)(uintptr_t)reg->userspace_addr,
> + &ram_addr);
> + fd = qemu_get_ram_fd(ram_addr);
> + if (fd > 0) {
> + msg.memory.regions[fd_num].userspace_addr = reg->userspace_addr;
> + msg.memory.regions[fd_num].memory_size = reg->memory_size;
> + msg.memory.regions[fd_num].guest_phys_addr = reg->guest_phys_addr;
> + msg.memory.regions[fd_num].mmap_offset = reg->userspace_addr -
> + (uintptr_t) qemu_get_ram_block_host_ptr(ram_addr);
> + assert(fd_num < VHOST_MEMORY_MAX_NREGIONS);
> + fds[fd_num++] = fd;
> + }
> + }
>
> - msg_request = vhost_user_request_translate(request);
> - msg.request = msg_request;
> - msg.flags = VHOST_USER_VERSION;
> - msg.size = 0;
> + msg.memory.nregions = fd_num;
>
> - switch (msg_request) {
> - case VHOST_USER_GET_FEATURES:
> - need_reply = 1;
> - break;
> -
> - case VHOST_USER_SET_FEATURES:
> - case VHOST_USER_SET_LOG_BASE:
> - msg.u64 = *((__u64 *) arg);
> - msg.size = sizeof(m.u64);
> - break;
> -
> - case VHOST_USER_SET_OWNER:
> - case VHOST_USER_RESET_OWNER:
> - break;
> -
> - case VHOST_USER_SET_MEM_TABLE:
> - for (i = 0; i < dev->mem->nregions; ++i) {
> - struct vhost_memory_region *reg = dev->mem->regions + i;
> - ram_addr_t ram_addr;
> -
> - assert((uintptr_t)reg->userspace_addr == reg->userspace_addr);
> - qemu_ram_addr_from_host((void *)(uintptr_t)reg->userspace_addr, &ram_addr);
> - fd = qemu_get_ram_fd(ram_addr);
> - if (fd > 0) {
> - msg.memory.regions[fd_num].userspace_addr = reg->userspace_addr;
> - msg.memory.regions[fd_num].memory_size = reg->memory_size;
> - msg.memory.regions[fd_num].guest_phys_addr = reg->guest_phys_addr;
> - msg.memory.regions[fd_num].mmap_offset = reg->userspace_addr -
> - (uintptr_t) qemu_get_ram_block_host_ptr(ram_addr);
> - assert(fd_num < VHOST_MEMORY_MAX_NREGIONS);
> - fds[fd_num++] = fd;
> - }
> - }
> + if (!fd_num) {
> + error_report("Failed initializing vhost-user memory map, "
> + "consider using -object memory-backend-file share=on");
> + return -1;
> + }
>
> - msg.memory.nregions = fd_num;
> + msg.size = sizeof(m.memory.nregions);
> + msg.size += sizeof(m.memory.padding);
> + msg.size += fd_num * sizeof(VhostUserMemoryRegion);
>
> - if (!fd_num) {
> - error_report("Failed initializing vhost-user memory map, "
> - "consider using -object memory-backend-file share=on");
> - return -1;
> - }
> + vhost_user_write(dev, &msg, fds, fd_num);
>
> - msg.size = sizeof(m.memory.nregions);
> - msg.size += sizeof(m.memory.padding);
> - msg.size += fd_num * sizeof(VhostUserMemoryRegion);
> -
> - break;
> -
> - case VHOST_USER_SET_LOG_FD:
> - fds[fd_num++] = *((int *) arg);
> - break;
> -
> - case VHOST_USER_SET_VRING_NUM:
> - case VHOST_USER_SET_VRING_BASE:
> - memcpy(&msg.state, arg, sizeof(struct vhost_vring_state));
> - msg.size = sizeof(m.state);
> - break;
> -
> - case VHOST_USER_GET_VRING_BASE:
> - memcpy(&msg.state, arg, sizeof(struct vhost_vring_state));
> - msg.size = sizeof(m.state);
> - need_reply = 1;
> - break;
> -
> - case VHOST_USER_SET_VRING_ADDR:
> - memcpy(&msg.addr, arg, sizeof(struct vhost_vring_addr));
> - msg.size = sizeof(m.addr);
> - break;
> -
> - case VHOST_USER_SET_VRING_KICK:
> - case VHOST_USER_SET_VRING_CALL:
> - case VHOST_USER_SET_VRING_ERR:
> - file = arg;
> - msg.u64 = file->index & VHOST_USER_VRING_IDX_MASK;
> - msg.size = sizeof(m.u64);
> - if (ioeventfd_enabled() && file->fd > 0) {
> - fds[fd_num++] = file->fd;
> - } else {
> - msg.u64 |= VHOST_USER_VRING_NOFD_MASK;
> - }
> - break;
> - default:
> - error_report("vhost-user trying to send unhandled ioctl");
> + return 0;
> +}
> +
> +static int vhost_set_vring_addr(struct vhost_dev *dev,
> + struct vhost_vring_addr *addr)
> +{
> + VhostUserMsg msg = {
> + .request = VHOST_USER_SET_VRING_ADDR,
> + .flags = VHOST_USER_VERSION,
> + .addr = *addr,
> + .size = sizeof(*addr),
> + };
> +
> + vhost_user_write(dev, &msg, NULL, 0);
> +
> + return 0;
> +}
> +
> +static int vhost_set_vring_endian(struct vhost_dev *dev,
> + struct vhost_vring_state *ring)
> +{
> + error_report("vhost-user trying to send unhandled ioctl");
> + return -1;
> +}
> +
> +static int vhost_set_vring_num(struct vhost_dev *dev,
> + struct vhost_vring_state *ring)
> +{
> + VhostUserMsg msg = {
> + .request = VHOST_USER_SET_VRING_NUM,
> + .flags = VHOST_USER_VERSION,
> + .state = *ring,
> + .size = sizeof(*ring),
> + };
> +
> + vhost_user_write(dev, &msg, NULL, 0);
> +
> + return 0;
> +}
> +
> +static int vhost_set_vring_base(struct vhost_dev *dev,
> + struct vhost_vring_state *ring)
> +{
> + VhostUserMsg msg = {
> + .request = VHOST_USER_SET_VRING_BASE,
> + .flags = VHOST_USER_VERSION,
> + .state = *ring,
> + .size = sizeof(*ring),
> + };
> +
> + vhost_user_write(dev, &msg, NULL, 0);
> +
> + return 0;
> +}
> +
> +static int vhost_get_vring_base(struct vhost_dev *dev,
> + struct vhost_vring_state *ring)
> +{
> + VhostUserMsg msg = {
> + .request = VHOST_USER_GET_VRING_BASE,
> + .flags = VHOST_USER_VERSION,
> + .state = *ring,
> + .size = sizeof(*ring),
> + };
> +
> + vhost_user_write(dev, &msg, NULL, 0);
> +
> + if (vhost_user_read(dev, &msg) < 0) {
> + return 0;
> + }
> +
> + if (msg.request != VHOST_USER_GET_VRING_BASE) {
> + error_report("Received unexpected msg type. Expected %d received %d",
> + VHOST_USER_GET_FEATURES, msg.request);
> return -1;
> - break;
> }
>
> - if (vhost_user_write(dev, &msg, fds, fd_num) < 0) {
> - return 0;
> + if (msg.size != sizeof(m.state)) {
> + error_report("Received bad msg size.");
> + return -1;
> }
>
> - if (need_reply) {
> - if (vhost_user_read(dev, &msg) < 0) {
> - return 0;
> - }
> + *ring = msg.state;
>
> - if (msg_request != msg.request) {
> - error_report("Received unexpected msg type."
> - " Expected %d received %d", msg_request, msg.request);
> - return -1;
> - }
> + return 0;
> +}
>
> - switch (msg_request) {
> - case VHOST_USER_GET_FEATURES:
> - if (msg.size != sizeof(m.u64)) {
> - error_report("Received bad msg size.");
> - return -1;
> - }
> - *((__u64 *) arg) = msg.u64;
> - break;
> - case VHOST_USER_GET_VRING_BASE:
> - if (msg.size != sizeof(m.state)) {
> - error_report("Received bad msg size.");
> - return -1;
> - }
> - memcpy(arg, &msg.state, sizeof(struct vhost_vring_state));
> - break;
> - default:
> - error_report("Received unexpected msg type.");
> - return -1;
> - break;
> - }
> +static int vhost_set_vring_file(struct vhost_dev *dev,
> + VhostUserRequest request,
> + struct vhost_vring_file *file)
> +{
> + int fds[VHOST_MEMORY_MAX_NREGIONS];
> + size_t fd_num = 0;
> + VhostUserMsg msg = {
> + .request = request,
> + .flags = VHOST_USER_VERSION,
> + .u64 = file->index & VHOST_USER_VRING_IDX_MASK,
> + .size = sizeof(m.u64),
> + };
> +
> + if (ioeventfd_enabled() && file->fd > 0) {
> + fds[fd_num++] = file->fd;
> + } else {
> + msg.u64 |= VHOST_USER_VRING_NOFD_MASK;
> }
>
> + vhost_user_write(dev, &msg, fds, fd_num);
> +
> + return 0;
> +}
> +
> +static int vhost_set_vring_kick(struct vhost_dev *dev,
> + struct vhost_vring_file *file)
> +{
> + return vhost_set_vring_file(dev, VHOST_USER_SET_VRING_KICK, file);
> +}
> +
> +static int vhost_set_vring_call(struct vhost_dev *dev,
> + struct vhost_vring_file *file)
> +{
> + return vhost_set_vring_file(dev, VHOST_USER_SET_VRING_CALL, file);
> +}
> +
> +static int vhost_set_features(struct vhost_dev *dev,
> + uint64_t features)
> +{
> + VhostUserMsg msg = {
> + .request = VHOST_USER_SET_FEATURES,
> + .flags = VHOST_USER_VERSION,
> + .u64 = features,
> + .size = sizeof(m.u64),
> + };
> +
> + vhost_user_write(dev, &msg, NULL, 0);
> +
> + return 0;
> +}
> +
> +static int vhost_user_get_features(struct vhost_dev *dev,
> + uint64_t *features)
> +{
> + VhostUserMsg msg = {
> + .request = VHOST_USER_GET_FEATURES,
> + .flags = VHOST_USER_VERSION,
> + };
> +
> + vhost_user_write(dev, &msg, NULL, 0);
> +
> + if (vhost_user_read(dev, &msg) < 0) {
> + return 0;
> + }
> +
> + if (msg.request != VHOST_USER_GET_FEATURES) {
> + error_report("Received unexpected msg type. Expected %d received %d",
> + VHOST_USER_GET_FEATURES, msg.request);
> + return -1;
> + }
> +
> + if (msg.size != sizeof(m.u64)) {
> + error_report("Received bad msg size.");
> + return -1;
> + }
> +
> + *features = msg.u64;
> +
> + return 0;
> +}
> +
> +static int vhost_set_owner(struct vhost_dev *dev)
> +{
> + VhostUserMsg msg = {
> + .request = VHOST_USER_SET_OWNER,
> + .flags = VHOST_USER_VERSION,
> + };
> +
> + vhost_user_write(dev, &msg, NULL, 0);
> +
> + return 0;
> +}
> +
> +static int vhost_reset_owner(struct vhost_dev *dev)
> +{
> + VhostUserMsg msg = {
> + .request = VHOST_USER_RESET_OWNER,
> + .flags = VHOST_USER_VERSION,
> + };
> +
> + vhost_user_write(dev, &msg, NULL, 0);
> +
> return 0;
> }
>
> @@ -402,7 +535,24 @@ static int vhost_user_cleanup(struct vhost_dev *dev)
>
> const VhostOps user_ops = {
> .backend_type = VHOST_BACKEND_TYPE_USER,
> - .vhost_call = vhost_user_call,
> .vhost_backend_init = vhost_user_init,
> - .vhost_backend_cleanup = vhost_user_cleanup
> - };
> + .vhost_backend_cleanup = vhost_user_cleanup,
> +
> + .vhost_net_set_backend = vhost_net_set_backend,
> + .vhost_scsi_set_endpoint = vhost_scsi_set_endpoint,
> + .vhost_scsi_clear_endpoint = vhost_scsi_clear_endpoint,
> + .vhost_scsi_get_abi_version = vhost_scsi_get_abi_version,
> + .vhost_set_log_base = vhost_set_log_base,
> + .vhost_set_mem_table = vhost_set_mem_table,
> + .vhost_set_vring_addr = vhost_set_vring_addr,
> + .vhost_set_vring_endian = vhost_set_vring_endian,
> + .vhost_set_vring_num = vhost_set_vring_num,
> + .vhost_set_vring_base = vhost_set_vring_base,
> + .vhost_get_vring_base = vhost_get_vring_base,
> + .vhost_set_vring_kick = vhost_set_vring_kick,
> + .vhost_set_vring_call = vhost_set_vring_call,
> + .vhost_set_features = vhost_set_features,
> + .vhost_get_features = vhost_user_get_features,
> + .vhost_set_owner = vhost_set_owner,
> + .vhost_reset_owner = vhost_reset_owner,
> +};
> diff --git a/hw/virtio/vhost.c b/hw/virtio/vhost.c
> index 81209ba..83ef164 100644
> --- a/hw/virtio/vhost.c
> +++ b/hw/virtio/vhost.c
> @@ -359,7 +359,7 @@ static inline void vhost_dev_log_resize(struct vhost_dev* dev, uint64_t size)
>
> /* inform backend of log switching, this must be done before
> releasing the current log, to ensure no logging is lost */
> - r = dev->vhost_ops->vhost_call(dev, VHOST_SET_LOG_BASE, &log_base);
> + r = dev->vhost_ops->vhost_set_log_base(dev, log_base);
> assert(r >= 0);
> vhost_log_put(dev, true);
> dev->log = log;
> @@ -525,7 +525,7 @@ static void vhost_commit(MemoryListener *listener)
> }
>
> if (!dev->log_enabled) {
> - r = dev->vhost_ops->vhost_call(dev, VHOST_SET_MEM_TABLE, dev->mem);
> + r = dev->vhost_ops->vhost_set_mem_table(dev, dev->mem);
> assert(r >= 0);
> dev->memory_changed = false;
> return;
> @@ -538,7 +538,7 @@ static void vhost_commit(MemoryListener *listener)
> if (dev->log_size < log_size) {
> vhost_dev_log_resize(dev, log_size + VHOST_LOG_BUFFER);
> }
> - r = dev->vhost_ops->vhost_call(dev, VHOST_SET_MEM_TABLE, dev->mem);
> + r = dev->vhost_ops->vhost_set_mem_table(dev, 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) {
> @@ -606,7 +606,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 = dev->vhost_ops->vhost_call(dev, VHOST_SET_VRING_ADDR, &addr);
> + int r = dev->vhost_ops->vhost_set_vring_addr(dev, &addr);
> if (r < 0) {
> return -errno;
> }
> @@ -620,7 +620,7 @@ static int vhost_dev_set_features(struct vhost_dev *dev, bool enable_log)
> if (enable_log) {
> features |= 0x1ULL << VHOST_F_LOG_ALL;
> }
> - r = dev->vhost_ops->vhost_call(dev, VHOST_SET_FEATURES, &features);
> + r = dev->vhost_ops->vhost_set_features(dev, features);
> return r < 0 ? -errno : 0;
> }
>
> @@ -725,7 +725,7 @@ static int vhost_virtqueue_set_vring_endian_legacy(struct vhost_dev *dev,
> .num = is_big_endian
> };
>
> - if (!dev->vhost_ops->vhost_call(dev, VHOST_SET_VRING_ENDIAN, &s)) {
> + if (!dev->vhost_ops->vhost_set_vring_endian(dev, &s)) {
> return 0;
> }
>
> @@ -756,13 +756,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 = dev->vhost_ops->vhost_call(dev, VHOST_SET_VRING_NUM, &state);
> + r = dev->vhost_ops->vhost_set_vring_num(dev, &state);
> if (r) {
> return -errno;
> }
>
> state.num = virtio_queue_get_last_avail_idx(vdev, idx);
> - r = dev->vhost_ops->vhost_call(dev, VHOST_SET_VRING_BASE, &state);
> + r = dev->vhost_ops->vhost_set_vring_base(dev, &state);
> if (r) {
> return -errno;
> }
> @@ -814,7 +814,7 @@ static int vhost_virtqueue_start(struct vhost_dev *dev,
> }
>
> file.fd = event_notifier_get_fd(virtio_queue_get_host_notifier(vvq));
> - r = dev->vhost_ops->vhost_call(dev, VHOST_SET_VRING_KICK, &file);
> + r = dev->vhost_ops->vhost_set_vring_kick(dev, &file);
> if (r) {
> r = -errno;
> goto fail_kick;
> @@ -853,7 +853,7 @@ static void vhost_virtqueue_stop(struct vhost_dev *dev,
> };
> int r;
> assert(idx >= dev->vq_index && idx < dev->vq_index + dev->nvqs);
> - r = dev->vhost_ops->vhost_call(dev, VHOST_GET_VRING_BASE, &state);
> + r = dev->vhost_ops->vhost_get_vring_base(dev, &state);
> if (r < 0) {
> fprintf(stderr, "vhost VQ %d ring restore failed: %d\n", idx, r);
> fflush(stderr);
> @@ -909,7 +909,7 @@ static int vhost_virtqueue_init(struct vhost_dev *dev,
> }
>
> file.fd = event_notifier_get_fd(&vq->masked_notifier);
> - r = dev->vhost_ops->vhost_call(dev, VHOST_SET_VRING_CALL, &file);
> + r = dev->vhost_ops->vhost_set_vring_call(dev, &file);
> if (r) {
> r = -errno;
> goto fail_call;
> @@ -941,12 +941,12 @@ int vhost_dev_init(struct vhost_dev *hdev, void *opaque,
> return -errno;
> }
>
> - r = hdev->vhost_ops->vhost_call(hdev, VHOST_SET_OWNER, NULL);
> + r = hdev->vhost_ops->vhost_set_owner(hdev);
> if (r < 0) {
> goto fail;
> }
>
> - r = hdev->vhost_ops->vhost_call(hdev, VHOST_GET_FEATURES, &features);
> + r = hdev->vhost_ops->vhost_get_features(hdev, &features);
> if (r < 0) {
> goto fail;
> }
> @@ -1102,7 +1102,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 = hdev->vhost_ops->vhost_call(hdev, VHOST_SET_VRING_CALL, &file);
> + r = hdev->vhost_ops->vhost_set_vring_call(hdev, &file);
> assert(r >= 0);
> }
>
> @@ -1144,7 +1144,7 @@ int vhost_dev_start(struct vhost_dev *hdev, VirtIODevice *vdev)
> if (r < 0) {
> goto fail_features;
> }
> - r = hdev->vhost_ops->vhost_call(hdev, VHOST_SET_MEM_TABLE, hdev->mem);
> + r = hdev->vhost_ops->vhost_set_mem_table(hdev, hdev->mem);
> if (r < 0) {
> r = -errno;
> goto fail_mem;
> @@ -1166,8 +1166,8 @@ int vhost_dev_start(struct vhost_dev *hdev, VirtIODevice *vdev)
> hdev->log_size = vhost_get_log_size(hdev);
> hdev->log = vhost_log_get(hdev->log_size, share);
> log_base = (uintptr_t)hdev->log->log;
> - r = hdev->vhost_ops->vhost_call(hdev, VHOST_SET_LOG_BASE,
> - hdev->log_size ? &log_base : NULL);
> + r = hdev->vhost_ops->vhost_set_log_base(hdev,
> + hdev->log_size ? log_base : 0);
> if (r < 0) {
> r = -errno;
> goto fail_log;
> diff --git a/include/hw/virtio/vhost-backend.h b/include/hw/virtio/vhost-backend.h
> index e472f29..42cfb87 100644
> --- a/include/hw/virtio/vhost-backend.h
> +++ b/include/hw/virtio/vhost-backend.h
> @@ -19,17 +19,70 @@ typedef enum VhostBackendType {
> } VhostBackendType;
>
> struct vhost_dev;
> +struct vhost_memory;
> +struct vhost_vring_file;
> +struct vhost_vring_state;
> +struct vhost_vring_addr;
> +struct vhost_scsi_target;
>
> -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 int (*vhost_net_set_backend_op)(struct vhost_dev *dev,
> + struct vhost_vring_file *file);
> +typedef int (*vhost_scsi_set_endpoint_op)(struct vhost_dev *dev,
> + struct vhost_scsi_target *target);
> +typedef int (*vhost_scsi_clear_endpoint_op)(struct vhost_dev *dev,
> + struct vhost_scsi_target *target);
> +typedef int (*vhost_scsi_get_abi_version_op)(struct vhost_dev *dev,
> + int *version);
> +typedef int (*vhost_set_log_base_op)(struct vhost_dev *dev, uint64_t base);
> +typedef int (*vhost_set_mem_table_op)(struct vhost_dev *dev,
> + struct vhost_memory *mem);
> +typedef int (*vhost_set_vring_addr_op)(struct vhost_dev *dev,
> + struct vhost_vring_addr *addr);
> +typedef int (*vhost_set_vring_endian_op)(struct vhost_dev *dev,
> + struct vhost_vring_state *ring);
> +typedef int (*vhost_set_vring_num_op)(struct vhost_dev *dev,
> + struct vhost_vring_state *ring);
> +typedef int (*vhost_set_vring_base_op)(struct vhost_dev *dev,
> + struct vhost_vring_state *ring);
> +typedef int (*vhost_get_vring_base_op)(struct vhost_dev *dev,
> + struct vhost_vring_state *ring);
> +typedef int (*vhost_set_vring_kick_op)(struct vhost_dev *dev,
> + struct vhost_vring_file *file);
> +typedef int (*vhost_set_vring_call_op)(struct vhost_dev *dev,
> + struct vhost_vring_file *file);
> +typedef int (*vhost_set_features_op)(struct vhost_dev *dev,
> + uint64_t features);
> +typedef int (*vhost_get_features_op)(struct vhost_dev *dev,
> + uint64_t *features);
> +typedef int (*vhost_set_owner_op)(struct vhost_dev *dev);
> +typedef int (*vhost_reset_owner_op)(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;
> +
> + vhost_net_set_backend_op vhost_net_set_backend;
> + vhost_scsi_set_endpoint_op vhost_scsi_set_endpoint;
> + vhost_scsi_clear_endpoint_op vhost_scsi_clear_endpoint;
> + vhost_scsi_get_abi_version_op vhost_scsi_get_abi_version;
> + vhost_set_log_base_op vhost_set_log_base;
> + vhost_set_mem_table_op vhost_set_mem_table;
> + vhost_set_vring_addr_op vhost_set_vring_addr;
> + vhost_set_vring_endian_op vhost_set_vring_endian;
> + vhost_set_vring_num_op vhost_set_vring_num;
> + vhost_set_vring_base_op vhost_set_vring_base;
> + vhost_get_vring_base_op vhost_get_vring_base;
> + vhost_set_vring_kick_op vhost_set_vring_kick;
> + vhost_set_vring_call_op vhost_set_vring_call;
> + vhost_set_features_op vhost_set_features;
> + vhost_get_features_op vhost_get_features;
> + vhost_set_owner_op vhost_set_owner;
> + vhost_reset_owner_op vhost_reset_owner;
> } VhostOps;
>
> extern const VhostOps user_ops;
> --
> 2.4.3
next prev parent reply other threads:[~2015-09-21 8:58 UTC|newest]
Thread overview: 41+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-09-19 10:11 [Qemu-devel] [PATCH v4 00/22] vhost-user: add migration support marcandre.lureau
2015-09-19 10:11 ` [Qemu-devel] [PATCH v4 01/22] vhost-user: refactor ioctl translation marcandre.lureau
2015-09-19 10:11 ` [Qemu-devel] [PATCH v4 02/22] vhost-user: add protocol feature negotiation marcandre.lureau
2015-09-19 10:11 ` [Qemu-devel] [PATCH v4 03/22] vhost-user: unit test for new messages marcandre.lureau
2015-09-19 10:11 ` [Qemu-devel] [PATCH v4 04/22] configure: probe for memfd marcandre.lureau
2015-09-19 10:11 ` [Qemu-devel] [PATCH v4 05/22] util: add linux-only memfd fallback marcandre.lureau
2015-09-19 10:11 ` [Qemu-devel] [PATCH v4 06/22] util: add memfd helpers marcandre.lureau
2015-09-19 10:11 ` [Qemu-devel] [PATCH v4 07/22] vhost: alloc shareable log marcandre.lureau
2015-09-21 8:44 ` Michael S. Tsirkin
2015-09-21 14:02 ` Marc-André Lureau
2015-09-21 19:29 ` Michael S. Tsirkin
2015-09-21 21:44 ` Marc-André Lureau
2015-09-22 10:12 ` Michael S. Tsirkin
2015-09-22 11:01 ` Marc-André Lureau
2015-09-22 11:41 ` Michael S. Tsirkin
2015-09-22 11:50 ` Marc-André Lureau
2015-09-22 11:54 ` Michael S. Tsirkin
2015-09-19 10:11 ` [Qemu-devel] [PATCH v4 08/22] vhost: document log resizing marcandre.lureau
2015-09-19 10:12 ` [Qemu-devel] [PATCH v4 09/22] vhost: use a function for each call marcandre.lureau
2015-09-21 7:33 ` Thibaut Collet
2015-09-21 8:56 ` Michael S. Tsirkin
2015-09-21 8:58 ` Michael S. Tsirkin [this message]
2015-09-21 14:05 ` Marc-André Lureau
2015-09-19 10:12 ` [Qemu-devel] [PATCH v4 10/22] vhost-user: remove vhost_user_request_translate() marcandre.lureau
2015-09-19 10:12 ` [Qemu-devel] [PATCH v4 11/22] vhost-user: send log shm fd along with log_base marcandre.lureau
2015-09-21 8:49 ` Michael S. Tsirkin
2015-09-21 14:05 ` Marc-André Lureau
2015-09-21 19:30 ` Michael S. Tsirkin
2015-09-19 10:12 ` [Qemu-devel] [PATCH v4 12/22] vhost: only use shared log if in use by backend marcandre.lureau
2015-09-21 8:46 ` Michael S. Tsirkin
2015-09-21 14:03 ` Marc-André Lureau
2015-09-19 10:12 ` [Qemu-devel] [PATCH v4 13/22] vhost-user: document migration log marcandre.lureau
2015-09-19 10:12 ` [Qemu-devel] [PATCH v4 14/22] net: add trace_vhost_user_event marcandre.lureau
2015-09-19 10:12 ` [Qemu-devel] [PATCH v4 15/22] vhost user: add support of live migration marcandre.lureau
2015-09-19 10:12 ` [Qemu-devel] [PATCH v4 16/22] vhost user: add rarp sending after live migration for legacy guest marcandre.lureau
2015-09-19 10:12 ` [Qemu-devel] [PATCH v4 17/22] vhost-user-test: move wait_for_fds() out marcandre.lureau
2015-09-19 10:12 ` [Qemu-devel] [PATCH v4 18/22] vhost-user-test: remove useless static check marcandre.lureau
2015-09-19 10:12 ` [Qemu-devel] [PATCH v4 19/22] vhost-user-test: wrap server in TestServer struct marcandre.lureau
2015-09-19 10:12 ` [Qemu-devel] [PATCH v4 20/22] vhost-user-test: learn to tweak various qemu arguments marcandre.lureau
2015-09-19 10:12 ` [Qemu-devel] [PATCH v4 21/22] vhost-user-test: add live-migration test marcandre.lureau
2015-09-19 10:12 ` [Qemu-devel] [PATCH v4 22/22] vhost-user-test: check ownership during migration marcandre.lureau
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20150921115644-mutt-send-email-mst@redhat.com \
--to=mst@redhat.com \
--cc=haifeng.lin@huawei.com \
--cc=jasowang@redhat.com \
--cc=marcandre.lureau@redhat.com \
--cc=pbonzini@redhat.com \
--cc=qemu-devel@nongnu.org \
--cc=thibaut.collet@6wind.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.