diff options
Diffstat (limited to 'hw/virtio')
-rw-r--r-- | hw/virtio/vhost-backend.c | 8 | ||||
-rw-r--r-- | hw/virtio/vhost.c | 40 |
2 files changed, 47 insertions, 1 deletions
diff --git a/hw/virtio/vhost-backend.c b/hw/virtio/vhost-backend.c index b35890289f..d62372e597 100644 --- a/hw/virtio/vhost-backend.c +++ b/hw/virtio/vhost-backend.c @@ -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, diff --git a/hw/virtio/vhost.c b/hw/virtio/vhost.c index a01394d5ac..ec3abda9d5 100644 --- a/hw/virtio/vhost.c +++ b/hw/virtio/vhost.c @@ -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); |