Commit 69e87b32 authored by Jason Wang's avatar Jason Wang
Browse files

tap: vhost busy polling support



This patch add the capability of basic vhost net busy polling which is
supported by recent kernel. User could configure the maximum number of
us that could be spent on busy polling through a new property of tap
"poll-us".

Cc: Greg Kurz <groug@kaod.org>
Reviewed-by: default avatarMichael S. Tsirkin <mst@redhat.com>
Signed-off-by: default avatarJason Wang <jasowang@redhat.com>
parent 91d35509
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -172,7 +172,7 @@ struct vhost_net *vhost_net_init(VhostNetOptions *options)
    }

    r = vhost_dev_init(&net->dev, options->opaque,
                       options->backend_type);
                       options->backend_type, options->busyloop_timeout);
    if (r < 0) {
        goto fail;
    }
+1 −1
Original line number Diff line number Diff line
@@ -248,7 +248,7 @@ static void vhost_scsi_realize(DeviceState *dev, Error **errp)
    s->dev.backend_features = 0;

    ret = vhost_dev_init(&s->dev, (void *)(uintptr_t)vhostfd,
                         VHOST_BACKEND_TYPE_KERNEL);
                         VHOST_BACKEND_TYPE_KERNEL, 0);
    if (ret < 0) {
        error_setg(errp, "vhost-scsi: vhost initialization failed: %s",
                   strerror(-ret));
+8 −0
Original line number Diff line number Diff line
@@ -138,6 +138,12 @@ static int vhost_kernel_set_vring_call(struct vhost_dev *dev,
    return vhost_kernel_call(dev, VHOST_SET_VRING_CALL, file);
}

static int vhost_kernel_set_vring_busyloop_timeout(struct vhost_dev *dev,
                                                   struct vhost_vring_state *s)
{
    return vhost_kernel_call(dev, VHOST_SET_VRING_BUSYLOOP_TIMEOUT, s);
}

static int vhost_kernel_set_features(struct vhost_dev *dev,
                                     uint64_t features)
{
@@ -185,6 +191,8 @@ static const VhostOps kernel_ops = {
        .vhost_get_vring_base = vhost_kernel_get_vring_base,
        .vhost_set_vring_kick = vhost_kernel_set_vring_kick,
        .vhost_set_vring_call = vhost_kernel_set_vring_call,
        .vhost_set_vring_busyloop_timeout =
                                vhost_kernel_set_vring_busyloop_timeout,
        .vhost_set_features = vhost_kernel_set_features,
        .vhost_get_features = vhost_kernel_get_features,
        .vhost_set_owner = vhost_kernel_set_owner,
+39 −1
Original line number Diff line number Diff line
@@ -960,6 +960,28 @@ static void vhost_eventfd_del(MemoryListener *listener,
{
}

static int vhost_virtqueue_set_busyloop_timeout(struct vhost_dev *dev,
                                                int n, uint32_t timeout)
{
    int vhost_vq_index = dev->vhost_ops->vhost_get_vq_index(dev, n);
    struct vhost_vring_state state = {
        .index = vhost_vq_index,
        .num = timeout,
    };
    int r;

    if (!dev->vhost_ops->vhost_set_vring_busyloop_timeout) {
        return -EINVAL;
    }

    r = dev->vhost_ops->vhost_set_vring_busyloop_timeout(dev, &state);
    if (r) {
        return r;
    }

    return 0;
}

static int vhost_virtqueue_init(struct vhost_dev *dev,
                                struct vhost_virtqueue *vq, int n)
{
@@ -990,7 +1012,7 @@ static void vhost_virtqueue_cleanup(struct vhost_virtqueue *vq)
}

int vhost_dev_init(struct vhost_dev *hdev, void *opaque,
                   VhostBackendType backend_type)
                   VhostBackendType backend_type, uint32_t busyloop_timeout)
{
    uint64_t features;
    int i, r;
@@ -1031,6 +1053,17 @@ int vhost_dev_init(struct vhost_dev *hdev, void *opaque,
            goto fail_vq;
        }
    }

    if (busyloop_timeout) {
        for (i = 0; i < hdev->nvqs; ++i) {
            r = vhost_virtqueue_set_busyloop_timeout(hdev, hdev->vq_index + i,
                                                     busyloop_timeout);
            if (r < 0) {
                goto fail_busyloop;
            }
        }
    }

    hdev->features = features;

    hdev->memory_listener = (MemoryListener) {
@@ -1073,6 +1106,11 @@ int vhost_dev_init(struct vhost_dev *hdev, void *opaque,
    hdev->memory_changed = false;
    memory_listener_register(&hdev->memory_listener, &address_space_memory);
    return 0;
fail_busyloop:
    while (--i >= 0) {
        vhost_virtqueue_set_busyloop_timeout(hdev, hdev->vq_index + i, 0);
    }
    i = hdev->nvqs;
fail_vq:
    while (--i >= 0) {
        vhost_virtqueue_cleanup(hdev->vqs + i);
+3 −0
Original line number Diff line number Diff line
@@ -57,6 +57,8 @@ 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_vring_busyloop_timeout_op)(struct vhost_dev *dev,
                                                   struct vhost_vring_state *r);
typedef int (*vhost_set_features_op)(struct vhost_dev *dev,
                                     uint64_t features);
typedef int (*vhost_get_features_op)(struct vhost_dev *dev,
@@ -91,6 +93,7 @@ typedef struct VhostOps {
    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_vring_busyloop_timeout_op vhost_set_vring_busyloop_timeout;
    vhost_set_features_op vhost_set_features;
    vhost_get_features_op vhost_get_features;
    vhost_set_owner_op vhost_set_owner;
Loading