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>
master
Konstantin Khlebnikov 2022-06-23 19:13:25 +03:00 committed by Michael S. Tsirkin
parent 60dc3c5be9
commit ae50ae0b91
2 changed files with 38 additions and 0 deletions

View File

@ -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,

View File

@ -29,6 +29,7 @@ struct vhost_virtqueue {
unsigned long long used_phys;
unsigned used_size;
EventNotifier masked_notifier;
EventNotifier error_notifier;
struct vhost_dev *dev;
};