diff options
author | Konstantin Khlebnikov <khlebnikov@yandex-team.ru> | 2022-06-23 19:13:25 +0300 |
---|---|---|
committer | Michael S. Tsirkin <mst@redhat.com> | 2022-06-27 18:53:18 -0400 |
commit | ae50ae0b91bb5bebb0d074afaecba027d8da16a1 (patch) | |
tree | 93f8cb1f2a146a1d5f36ed5dbaa71fb830ab8b68 /hw/virtio | |
parent | 60dc3c5be9ce67f4195c432b22a88d8af6429d80 (diff) | |
download | qemu-ae50ae0b91bb5bebb0d074afaecba027d8da16a1.zip qemu-ae50ae0b91bb5bebb0d074afaecba027d8da16a1.tar.gz qemu-ae50ae0b91bb5bebb0d074afaecba027d8da16a1.tar.bz2 |
vhost: setup error eventfd and dump errors
Vhost has error notifications, let's log them like other errors.
For each virt-queue setup eventfd for vring error notifications.
Signed-off-by: Konstantin Khlebnikov <khlebnikov@yandex-team.ru>
[vsementsov: rename patch, change commit message and dump error like
other errors in the file]
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru>
Message-Id: <20220623161325.18813-3-vsementsov@yandex-team.ru>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Reviewed-by: Roman Kagan <rvkagan@yandex-team.ru>
Diffstat (limited to 'hw/virtio')
-rw-r--r-- | hw/virtio/vhost.c | 37 |
1 files changed, 37 insertions, 0 deletions
diff --git a/hw/virtio/vhost.c b/hw/virtio/vhost.c index 6c41fa1..0827d63 100644 --- a/hw/virtio/vhost.c +++ b/hw/virtio/vhost.c @@ -1278,6 +1278,19 @@ static int vhost_virtqueue_set_busyloop_timeout(struct vhost_dev *dev, return 0; } +static void vhost_virtqueue_error_notifier(EventNotifier *n) +{ + struct vhost_virtqueue *vq = container_of(n, struct vhost_virtqueue, + error_notifier); + struct vhost_dev *dev = vq->dev; + int index = vq - dev->vqs; + + if (event_notifier_test_and_clear(n) && dev->vdev) { + VHOST_OPS_DEBUG(-EINVAL, "vhost vring error in virtqueue %d", + dev->vq_index + index); + } +} + static int vhost_virtqueue_init(struct vhost_dev *dev, struct vhost_virtqueue *vq, int n) { @@ -1299,7 +1312,27 @@ static int vhost_virtqueue_init(struct vhost_dev *dev, vq->dev = dev; + if (dev->vhost_ops->vhost_set_vring_err) { + r = event_notifier_init(&vq->error_notifier, 0); + if (r < 0) { + goto fail_call; + } + + file.fd = event_notifier_get_fd(&vq->error_notifier); + r = dev->vhost_ops->vhost_set_vring_err(dev, &file); + if (r) { + VHOST_OPS_DEBUG(r, "vhost_set_vring_err failed"); + goto fail_err; + } + + event_notifier_set_handler(&vq->error_notifier, + vhost_virtqueue_error_notifier); + } + return 0; + +fail_err: + event_notifier_cleanup(&vq->error_notifier); fail_call: event_notifier_cleanup(&vq->masked_notifier); return r; @@ -1308,6 +1341,10 @@ fail_call: static void vhost_virtqueue_cleanup(struct vhost_virtqueue *vq) { event_notifier_cleanup(&vq->masked_notifier); + if (vq->dev->vhost_ops->vhost_set_vring_err) { + event_notifier_set_handler(&vq->error_notifier, NULL); + event_notifier_cleanup(&vq->error_notifier); + } } int vhost_dev_init(struct vhost_dev *hdev, void *opaque, |