Skip to content

Commit

Permalink
virtio: add aio handler
Browse files Browse the repository at this point in the history
In addition to handling IO in vcpu thread and in io thread, blk dataplane
introduces yet another mode: handling it by AioContext.

Currently, this reuses the same handler as previous modes,
which triggers races as these were not designed to be reentrant.
Add instead a separate handler just for aio; this will make
it possible to disable regular handlers when dataplane is active.

Signed-off-by: Michael S. Tsirkin <[email protected]>
Signed-off-by: Paolo Bonzini <[email protected]>
Reviewed-by: Michael S. Tsirkin <[email protected]>
Signed-off-by: Michael S. Tsirkin <[email protected]>
  • Loading branch information
mstsirkin committed Apr 7, 2016
1 parent 43c696a commit 344dc16
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 4 deletions.
36 changes: 32 additions & 4 deletions hw/virtio/virtio.c
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ struct VirtQueue

uint16_t vector;
void (*handle_output)(VirtIODevice *vdev, VirtQueue *vq);
void (*handle_aio_output)(VirtIODevice *vdev, VirtQueue *vq);
VirtIODevice *vdev;
EventNotifier guest_notifier;
EventNotifier host_notifier;
Expand Down Expand Up @@ -1088,6 +1089,16 @@ void virtio_queue_set_align(VirtIODevice *vdev, int n, int align)
virtio_queue_update_rings(vdev, n);
}

static void virtio_queue_notify_aio_vq(VirtQueue *vq)
{
if (vq->vring.desc && vq->handle_aio_output) {
VirtIODevice *vdev = vq->vdev;

trace_virtio_queue_notify(vdev, vq - vdev->vq, vq);
vq->handle_aio_output(vdev, vq);
}
}

static void virtio_queue_notify_vq(VirtQueue *vq)
{
if (vq->vring.desc && vq->handle_output) {
Expand Down Expand Up @@ -1143,10 +1154,19 @@ VirtQueue *virtio_add_queue(VirtIODevice *vdev, int queue_size,
vdev->vq[i].vring.num_default = queue_size;
vdev->vq[i].vring.align = VIRTIO_PCI_VRING_ALIGN;
vdev->vq[i].handle_output = handle_output;
vdev->vq[i].handle_aio_output = NULL;

return &vdev->vq[i];
}

void virtio_set_queue_aio(VirtQueue *vq,
void (*handle_output)(VirtIODevice *, VirtQueue *))
{
assert(vq->handle_output);

vq->handle_aio_output = handle_output;
}

void virtio_del_queue(VirtIODevice *vdev, int n)
{
if (n < 0 || n >= VIRTIO_QUEUE_MAX) {
Expand Down Expand Up @@ -1780,11 +1800,11 @@ EventNotifier *virtio_queue_get_guest_notifier(VirtQueue *vq)
return &vq->guest_notifier;
}

static void virtio_queue_host_notifier_read(EventNotifier *n)
static void virtio_queue_host_notifier_aio_read(EventNotifier *n)
{
VirtQueue *vq = container_of(n, VirtQueue, host_notifier);
if (event_notifier_test_and_clear(n)) {
virtio_queue_notify_vq(vq);
virtio_queue_notify_aio_vq(vq);
}
}

Expand All @@ -1793,14 +1813,22 @@ void virtio_queue_aio_set_host_notifier_handler(VirtQueue *vq, AioContext *ctx,
{
if (assign && set_handler) {
aio_set_event_notifier(ctx, &vq->host_notifier, true,
virtio_queue_host_notifier_read);
virtio_queue_host_notifier_aio_read);
} else {
aio_set_event_notifier(ctx, &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);
virtio_queue_host_notifier_aio_read(&vq->host_notifier);
}
}

static void virtio_queue_host_notifier_read(EventNotifier *n)
{
VirtQueue *vq = container_of(n, VirtQueue, host_notifier);
if (event_notifier_test_and_clear(n)) {
virtio_queue_notify_vq(vq);
}
}

Expand Down
3 changes: 3 additions & 0 deletions include/hw/virtio/virtio.h
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,9 @@ VirtQueue *virtio_add_queue(VirtIODevice *vdev, int queue_size,
void (*handle_output)(VirtIODevice *,
VirtQueue *));

void virtio_set_queue_aio(VirtQueue *vq,
void (*handle_output)(VirtIODevice *, VirtQueue *));

void virtio_del_queue(VirtIODevice *vdev, int n);

void *virtqueue_alloc_element(size_t sz, unsigned out_num, unsigned in_num);
Expand Down

0 comments on commit 344dc16

Please sign in to comment.