aboutsummaryrefslogtreecommitdiff
path: root/hw
diff options
context:
space:
mode:
Diffstat (limited to 'hw')
-rw-r--r--hw/virtio/virtio-bus.c19
-rw-r--r--hw/virtio/virtio.c27
2 files changed, 20 insertions, 26 deletions
diff --git a/hw/virtio/virtio-bus.c b/hw/virtio/virtio-bus.c
index fd105b8..670746c 100644
--- a/hw/virtio/virtio-bus.c
+++ b/hw/virtio/virtio-bus.c
@@ -163,19 +163,22 @@ static int set_host_notifier_internal(DeviceState *proxy, VirtioBusState *bus,
__func__, strerror(-r), r);
return r;
}
- virtio_queue_set_host_notifier_fd_handler(vq, true, false);
- r = k->ioeventfd_assign(proxy, notifier, n, assign);
+ r = k->ioeventfd_assign(proxy, notifier, n, true);
if (r < 0) {
error_report("%s: unable to assign ioeventfd: %d", __func__, r);
- virtio_queue_set_host_notifier_fd_handler(vq, false, false);
- event_notifier_cleanup(notifier);
- return r;
+ goto cleanup_event_notifier;
}
+ return 0;
} else {
- k->ioeventfd_assign(proxy, notifier, n, assign);
- virtio_queue_set_host_notifier_fd_handler(vq, false, false);
- event_notifier_cleanup(notifier);
+ k->ioeventfd_assign(proxy, notifier, n, false);
}
+
+cleanup_event_notifier:
+ /* Test and clear notifier after disabling event,
+ * in case poll callback didn't have time to run.
+ */
+ virtio_queue_host_notifier_read(notifier);
+ event_notifier_cleanup(notifier);
return r;
}
diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c
index b738163..bcbcfe0 100644
--- a/hw/virtio/virtio.c
+++ b/hw/virtio/virtio.c
@@ -2042,7 +2042,7 @@ void virtio_queue_aio_set_host_notifier_handler(VirtQueue *vq, AioContext *ctx,
}
}
-static void virtio_queue_host_notifier_read(EventNotifier *n)
+void virtio_queue_host_notifier_read(EventNotifier *n)
{
VirtQueue *vq = container_of(n, VirtQueue, host_notifier);
if (event_notifier_test_and_clear(n)) {
@@ -2050,22 +2050,6 @@ static void virtio_queue_host_notifier_read(EventNotifier *n)
}
}
-void virtio_queue_set_host_notifier_fd_handler(VirtQueue *vq, bool assign,
- bool set_handler)
-{
- if (assign && set_handler) {
- event_notifier_set_handler(&vq->host_notifier, true,
- virtio_queue_host_notifier_read);
- } else {
- event_notifier_set_handler(&vq->host_notifier, true, NULL);
- }
- if (!assign) {
- /* Test and clear notifier before after disabling event,
- * in case poll callback didn't have time to run. */
- virtio_queue_host_notifier_read(&vq->host_notifier);
- }
-}
-
EventNotifier *virtio_queue_get_host_notifier(VirtQueue *vq)
{
return &vq->host_notifier;
@@ -2148,6 +2132,7 @@ static int virtio_device_start_ioeventfd_impl(VirtIODevice *vdev)
int n, r, err;
for (n = 0; n < VIRTIO_QUEUE_MAX; n++) {
+ VirtQueue *vq = &vdev->vq[n];
if (!virtio_queue_get_num(vdev, n)) {
continue;
}
@@ -2156,7 +2141,8 @@ static int virtio_device_start_ioeventfd_impl(VirtIODevice *vdev)
err = r;
goto assign_error;
}
- virtio_queue_set_host_notifier_fd_handler(&vdev->vq[n], true, true);
+ event_notifier_set_handler(&vq->host_notifier, true,
+ virtio_queue_host_notifier_read);
}
for (n = 0; n < VIRTIO_QUEUE_MAX; n++) {
@@ -2171,10 +2157,12 @@ static int virtio_device_start_ioeventfd_impl(VirtIODevice *vdev)
assign_error:
while (--n >= 0) {
+ VirtQueue *vq = &vdev->vq[n];
if (!virtio_queue_get_num(vdev, n)) {
continue;
}
+ event_notifier_set_handler(&vq->host_notifier, true, NULL);
r = virtio_bus_set_host_notifier(qbus, n, false);
assert(r >= 0);
}
@@ -2195,9 +2183,12 @@ static void virtio_device_stop_ioeventfd_impl(VirtIODevice *vdev)
int n, r;
for (n = 0; n < VIRTIO_QUEUE_MAX; n++) {
+ VirtQueue *vq = &vdev->vq[n];
+
if (!virtio_queue_get_num(vdev, n)) {
continue;
}
+ event_notifier_set_handler(&vq->host_notifier, true, NULL);
r = virtio_bus_set_host_notifier(qbus, n, false);
assert(r >= 0);
}