Skip to content

Commit

Permalink
virtio: remove event notifier cleanup call on de-assign
Browse files Browse the repository at this point in the history
The virtio_bus_set_host_notifier function no longer calls
event_notifier_cleanup when a event notifier is removed.

The commit updates the code to match the new behavior and calls
virtio_bus_cleanup_host_notifier after the notifier was de-assign
and no longer in use.

This change is a preparation to allow executing the
virtio_bus_set_host_notifier function in a memory region
transaction.

Signed-off-by: Gal Hammer <ghammer@redhat.com>
Reviewed-by: Greg Kurz <groug@kaod.org>
Tested-by: Greg Kurz <groug@kaod.org>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
  • Loading branch information
Gal Hammer authored and mstsirkin committed Feb 8, 2018
1 parent f41d912 commit 7614361
Show file tree
Hide file tree
Showing 6 changed files with 20 additions and 4 deletions.
2 changes: 2 additions & 0 deletions hw/block/dataplane/virtio-blk.c
Expand Up @@ -192,6 +192,7 @@ int virtio_blk_data_plane_start(VirtIODevice *vdev)
fprintf(stderr, "virtio-blk failed to set host notifier (%d)\n", r);
while (i--) {
virtio_bus_set_host_notifier(VIRTIO_BUS(qbus), i, false);
virtio_bus_cleanup_host_notifier(VIRTIO_BUS(qbus), i);
}
goto fail_guest_notifiers;
}
Expand Down Expand Up @@ -267,6 +268,7 @@ void virtio_blk_data_plane_stop(VirtIODevice *vdev)

for (i = 0; i < nvqs; i++) {
virtio_bus_set_host_notifier(VIRTIO_BUS(qbus), i, false);
virtio_bus_cleanup_host_notifier(VIRTIO_BUS(qbus), i);
}

/* Clean up guest notifier (irq) */
Expand Down
2 changes: 2 additions & 0 deletions hw/scsi/virtio-scsi-dataplane.c
Expand Up @@ -175,6 +175,7 @@ int virtio_scsi_dataplane_start(VirtIODevice *vdev)
aio_context_release(s->ctx);
for (i = 0; i < vs->conf.num_queues + 2; i++) {
virtio_bus_set_host_notifier(VIRTIO_BUS(qbus), i, false);
virtio_bus_cleanup_host_notifier(VIRTIO_BUS(qbus), i);
}
k->set_guest_notifiers(qbus->parent, vs->conf.num_queues + 2, false);
fail_guest_notifiers:
Expand Down Expand Up @@ -213,6 +214,7 @@ void virtio_scsi_dataplane_stop(VirtIODevice *vdev)

for (i = 0; i < vs->conf.num_queues + 2; i++) {
virtio_bus_set_host_notifier(VIRTIO_BUS(qbus), i, false);
virtio_bus_cleanup_host_notifier(VIRTIO_BUS(qbus), i);
}

/* Clean up guest notifier (irq) */
Expand Down
2 changes: 2 additions & 0 deletions hw/virtio/vhost.c
Expand Up @@ -1418,6 +1418,7 @@ int vhost_dev_enable_notifiers(struct vhost_dev *hdev, VirtIODevice *vdev)
error_report("vhost VQ %d notifier cleanup error: %d", i, -r);
}
assert (e >= 0);
virtio_bus_cleanup_host_notifier(VIRTIO_BUS(qbus), hdev->vq_index + i);
}
virtio_device_release_ioeventfd(vdev);
fail:
Expand All @@ -1441,6 +1442,7 @@ void vhost_dev_disable_notifiers(struct vhost_dev *hdev, VirtIODevice *vdev)
error_report("vhost VQ %d notifier cleanup failed: %d", i, -r);
}
assert (r >= 0);
virtio_bus_cleanup_host_notifier(VIRTIO_BUS(qbus), hdev->vq_index + i);
}
virtio_device_release_ioeventfd(vdev);
}
Expand Down
14 changes: 10 additions & 4 deletions hw/virtio/virtio-bus.c
Expand Up @@ -283,20 +283,26 @@ int virtio_bus_set_host_notifier(VirtioBusState *bus, int n, bool assign)
r = k->ioeventfd_assign(proxy, notifier, n, true);
if (r < 0) {
error_report("%s: unable to assign ioeventfd: %d", __func__, r);
goto cleanup_event_notifier;
virtio_bus_cleanup_host_notifier(bus, n);
}
return 0;
} else {
k->ioeventfd_assign(proxy, notifier, n, false);
}

cleanup_event_notifier:
return r;
}

void virtio_bus_cleanup_host_notifier(VirtioBusState *bus, int n)
{
VirtIODevice *vdev = virtio_bus_get_device(bus);
VirtQueue *vq = virtio_get_queue(vdev, n);
EventNotifier *notifier = virtio_queue_get_host_notifier(vq);

/* 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;
}

static char *virtio_bus_get_dev_path(DeviceState *dev)
Expand Down
2 changes: 2 additions & 0 deletions hw/virtio/virtio.c
Expand Up @@ -2608,6 +2608,7 @@ static int virtio_device_start_ioeventfd_impl(VirtIODevice *vdev)
event_notifier_set_handler(&vq->host_notifier, NULL);
r = virtio_bus_set_host_notifier(qbus, n, false);
assert(r >= 0);
virtio_bus_cleanup_host_notifier(qbus, n);
}
return err;
}
Expand All @@ -2634,6 +2635,7 @@ static void virtio_device_stop_ioeventfd_impl(VirtIODevice *vdev)
event_notifier_set_handler(&vq->host_notifier, NULL);
r = virtio_bus_set_host_notifier(qbus, n, false);
assert(r >= 0);
virtio_bus_cleanup_host_notifier(qbus, n);
}
}

Expand Down
2 changes: 2 additions & 0 deletions include/hw/virtio/virtio-bus.h
Expand Up @@ -148,5 +148,7 @@ int virtio_bus_grab_ioeventfd(VirtioBusState *bus);
void virtio_bus_release_ioeventfd(VirtioBusState *bus);
/* Switch from/to the generic ioeventfd handler */
int virtio_bus_set_host_notifier(VirtioBusState *bus, int n, bool assign);
/* Tell the bus that the ioeventfd handler is no longer required. */
void virtio_bus_cleanup_host_notifier(VirtioBusState *bus, int n);

#endif /* VIRTIO_BUS_H */

0 comments on commit 7614361

Please sign in to comment.